好友
阅读权限10
听众
最后登录1970-1-1
|
patch:
import struct
import sys
def va_to_fo(data, va):
"""Map a virtual address to a file offset using the PE section table."""
e_lfanew = struct.unpack_from('<I', data, 0x3C)[0]
n = struct.unpack_from('<H', data, e_lfanew + 6)[0]
opt_size = struct.unpack_from('<H', data, e_lfanew + 20)[0]
magic = struct.unpack_from('<H', data, e_lfanew + 24)[0]
image_base = struct.unpack_from('<Q', data, e_lfanew + 24 + 24)[0]
rva = va - image_base
sect = e_lfanew + 24 + opt_size
for i in range(n):
off = sect + i * 40
vsize, vaddr, rawsize, rawptr = struct.unpack_from('<IIII', data, off + 8)
if vaddr <= rva < vaddr + max(vsize, rawsize):
return rawptr + (rva - vaddr)
raise ValueError('VA 0x%X not in any section' % va)
def main():
src = 'crackme.exe'
dst = 'crackme_patched.exe'
data = bytearray(open(src, 'rb').read())
patches = [
# (VA, old bytes, new bytes, description)
(0x1400024BD, bytes.fromhex('0F 85 52 04 00 00'), bytes.fromhex('90 90 90 90 90 90'),
'force "Access granted" branch'),
(0x140002FFC, bytes.fromhex('0F 95 C3'), bytes.fromhex('31 DB 90'),
'force ExitProcess(0)'),
]
for va, old, new, desc in patches:
fo = va_to_fo(data, va)
if bytes(data[fo:fo + len(old)]) != old:
print('warning: bytes at 0x%X do not match expected (%s)' % (va, old.hex()))
continue
data[fo:fo + len(old)] = new
print('patched 0x%X (%s)' % (va, desc))
with open(dst, 'wb') as f:
f.write(data)
print('wrote', dst)
if __name__ == '__main__':
main()
来源dsv4 f |
|