#!/usr/bin/env python3 """通用解密合并 (v3): 按 PT_LOAD 映射 vaddr<->文件偏移, 把 FULL dump 的解密内存 合入 ORIGINAL .so 的正确文件位置; 数据段内陈旧运行期指针清掉. 用法: python3 merge_decrypted.py """ from __future__ import annotations import struct, sys def phdrs(data): e_phoff = struct.unpack_from(' len(dd) or foff + sz > len(od): print(f"[!] skip {s['name']}: out of bounds vaddr={vaddr:#x} off={foff:#x} sz={sz:#x}") continue if dd[vaddr:vaddr+sz] != od[foff:foff+sz]: od[foff:foff+sz] = dd[vaddr:vaddr+sz] n_copied += sz print(f"[*] merged {n_copied:#x} bytes via section mapping") for a, b in dyn_ranges: od[a:b] = orig_raw[a:b] print(f"[*] kept original .dynamic [{a:#x}:{b:#x})") for a, b in zero_ranges: od[a:b] = b'\x00' * (b - a) print(f"[*] zeroed [{a:#x}:{b:#x})") # 清理只作用于重定位目标槽: vaddr->文件偏移, 越界运行期指针清零/模块内回退 R_AARCH64_RELATIVE, R_AARCH64_ABS64 = 1027, 257 R_AARCH64_GLOB_DAT, R_AARCH64_JUMP_SLOT = 1025, 1026 def v2foff(vaddr): for s_ in secs: if s_['type'] == 8 or s_['size'] == 0: continue if s_['addr'] <= vaddr < s_['addr'] + s_['size']: return s_['offset'] + (vaddr - s_['addr']) return None n_zero = n_rebase = 0 for s_ in secs: if s_['name'] not in ('.rela.dyn', '.rela.plt') or s_['type'] == 8: continue for i in range(0, s_['size'], 24): r_off, r_info, _ = struct.unpack_from(' len(od): continue v = struct.unpack_from(' {out}") if __name__ == '__main__': main()