一骑当千

我愿陪你走遍整个艾泽拉斯.

Python计算Dex头中的checksum和signature

| Comments

前言

本文主要编写修改Android程序DEX头中checksum、signature 和file_size头信息的Python脚本,修改checksum、signature的场景一般出现在加壳以及逆向之后重签名之后对文件完整性进行修改

我们先看一下文件头记录了dex文件的一些基本信息 :

1
2
3
4
5
6
magic     : dex魔术字, 固定信息: dex\n035
checksum  : alder32算法, 去除了magicchecksum字段之外的所有内容的校验码
signature : sha-1签名, 去除了magicchecksumsignature字段之外的所有内容的签名
fileSize  : 整个dex的文件大小
headerSize: 整个dex文件头的大小 (固定大小为0x70)
endianTag : 字节序 (大尾方式、小尾方式)默认为小尾方式 <--> 0x12345678

首先导入修改Dex所需要的python库

1
2
3
import os,sys
import zlib,hashlib
import struct

Checksum

Dex文件头中的checksum是用来校验文件的完整性,使用adler32算法。在python中的zlib库中有该算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def repairChecksum(self):
  self.seek(8)
  sourceData = self.read(4)
  self.seek(12)
  checkdata = self.read()
  checksum = zlib.adler32(checkdata)
  checkInt = checksum & 0xffffffff
  bytes = struct.pack('i',checksum)
  print "头部原checksum:",sourceData
  print "计算checksum:",checkInt
  
  if bytes == sourceData:
      print 'checksum效验正常'
  else:
      print 'checksum效验异常'
      file_object.seek(8)
      file_object.write(bytes)
      #byte1 = struct.unpack('i',byte0)
      print 'checksum修复成功'

Signature

Dex头中的Signature是对dex文件的签名,签名signature字段之后的数据(32字节之后),在hashlib中有该算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def repairSignature(self):
  #4 + 4 + 4 + 20
  self.seek(12)
  sourceData = self.read(20)
  self.seek(32)
  sigdata = self.read()
  sha1 = hashlib.sha1()
  sha1.update(sigdata)
  sha0 = sha1.hexdigest()
  sha2 = sha1.digest()
  print "signature:",sha0
  print "现signature:",sha2
  print "原signature:",sourceData
  
  if sourceData == sha2:
        print 'SHA1效验正常'
    else:
        print 'SHA1效验异常
        for i in xrange(len(sha2)):
            salt = sha2[i]
            file_object.seek(i)
            bytes = struct.pack('c',salt)
            file_object.write(bytes)

        print 'SHA1效验修复成功'

我在方法中加入了效验跟修复功能,为了方便查看,使用010 Editor打开刚刚生成的Dex文件,在官网下载一个Dex模板的脚本,然后运行修改之后可以用此python做完整性效验修复…

参考资料

Comments