我正在尝试运行 Android check_ota_package_signature.py https://android.googlesource.com/platform/build/+/refs/heads/main/tools/releasetools/check_ota_package_signature.py
在低端计算机上。该程序用于检查 Android OTA 更新的签名。不幸的是该程序正在被杀死。恕我直言,相关部分是:
with open(package, 'rb') as package_file:
package_bytes = package_file.read()
length = len(package_bytes)
footer = bytearray(package_bytes[-6:])
signature_start_from_end = (footer[1] << 8) + footer[0]
signature_start = length - signature_start_from_end
comment_len = (footer[5] << 8) + footer[4]
signed_len = length - comment_len - 2
comment_len = (footer[5] << 8) + footer[4]
signed_len = length - comment_len - 2
print('Package length: %d' % (length,))
print('Comment length: %d' % (comment_len,))
print('Signed data length: %d' % (signed_len,))
print('Signature start: %d' % (signature_start,))
use_sha256 = CertUsesSha256(cert)
print('Use SHA-256: %s' % (use_sha256,))
h = sha256() if use_sha256 else sha1()
h.update(package_bytes[:signed_len])
package_digest = h.hexdigest().lower()
h.update(package_bytes[:signed_len]) 被杀死。我的理解是,这是由于内存不足而发生的,因为大约的文件。一次读取1.1GB。如何更改程序以小块读取文件,这样我就不会遇到这个问题?
我希望验证签名。相反,我收到以下消息:
Package length: 1182903653
Comment length: 1983
Signed data length: 1182901668
Signature start: 1182901688
Use SHA-256: True
Killed
使用
mmap()
将文件映射到虚拟内存,然后让操作系统将虚拟内存分页进出物理内存,是减少内存需求的一种方法(与运行大型 read()
的原始行为相比)将整个文件复制到新分配的内存中,该内存没有磁盘支持,并且除非定义了足够的交换区,否则无法调出)。
#!/usr/bin/env python3
import mmap
import sys
from hashlib import sha256, sha1
with open(sys.argv[1], 'rb') as f:
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm:
length = len(mm)
footer = bytearray(mm[-6:])
signature_start_from_end = (footer[1] << 8) + footer[0]
signature_start = length - signature_start_from_end
comment_len = (footer[5] << 8) + footer[4]
signed_len = length - comment_len - 2
comment_len = (footer[5] << 8) + footer[4]
signed_len = length - comment_len - 2
print('Package length: %d' % (length,))
print('Comment length: %d' % (comment_len,))
print('Signed data length: %d' % (signed_len,))
print('Signature start: %d' % (signature_start,))
h = sha256()
## slower, but more explicit about only dealing with small chunks at a time
current_pos=0
block_size=4096
while current_pos < signed_len:
block_end = min(current_pos+block_size, signed_len)
h.update(mm[current_pos:block_end])
current_pos = block_end
gc.collect()
## faster but depends on CPython implementation details
# h.update(mm[:signed_len])
print(h.hexdigest().lower())