executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
re-patching补丁制作:字节级 patch、指令重写。触发词:打补丁、patch、修改跳转、绕过验证、crack
Independent GitHub snapshot · Automated classification · Original documentation governs
apt install hexedit / dnf install hexedit / pacman -S hexedit,验证 hexedit --version(交互式按 F2 保存)brew install hexeditapt install gdb,验证 gdb --version;Wine 直读:wine sample.exe 后 gdb -p <pid> attach([[re-analyze/platform-tips]] Linux 分支)brew install lldb);Windows 目标走 Wine + gdb 或 VMwx 写字节,命令行 patch 主力)apt install rizin 会失败,改用官方 release 二进制或 rz-pm)rizin -vwx 90 @ 0x401234(把 0x401234 处一个字节写成 0x90)、wx 909090 @ 0x401234(连写三个)rz-diff(rizin 自带,二进制 diff 对比)/ radiff2(radare2 自带,命令兼容)bsdiff / bspatch:Linux apt install bsdiff / macOS brew install bsdiff,验证 bsdiff -hxdelta3:Linux apt install xdelta3,验证 xdelta3 -Vllvm-objdump(LLVM 套件)对比原始字节段按顺序执行,每步记录结果(原始字节 → 修改字节 → 偏移,证据路径见 [[re-triage]])。修改前 cp sample.exe sample.bak 并 sha256sum 存档(见坑 1)。
定位 patch 点(失败跳转 → 改 jz / jnz):
jz fail / jnz fail)是把校验失败当成立即跳走的分支jz 0x401300 → nop)字节修改(nop / 跳转重写):
jz ↔ jnz(x86 短跳 74 ↔ 75,近跳 0F 84 ↔ 0F 85);无条件跳转 EB(rel8)/ E9(rel32)直接落到成功路径nop 掉(90);或让校验函数直接返回成功:把函数开头的 push ebp 改成 mov eax,1; ret(B8 01 00 00 00 C3,按栈平衡调整)rizin -w sample.exe
[0x00401000]> wx 90 90 @ 0x00401234 # nop 掉两个字节的失败跳转
[0x00401000]> wx 0f 85 00 00 00 00 @ 0x00401230 # jz(0F84) 改 jnz(0F85),注意 rel32 需重算
[0x00401000]> q
hexedit sample.exe,Ctrl+S 跳地址 → 改字节 → F2 保存sha256sum sample.exe 存档中间产物校验和 / 自校验处理:
CheckSumMappedFile 等);反编译确认比对对象(文件字节 vs 期望值)mov eax,1; ret 提前返回);或按新字节重算校验值写回补丁导出(二进制 diff / patch 文件):
bsdiff sample.bak sample.exe sample.patch(分发时 bspatch sample.exe sample_patched.exe sample.patch);或 xdelta3 -e -s sample.bak sample.exe sample.patchrz-diff -D sample.bak sample.exe 输出逐字节差异供报告引用(radare2 用等价的 radiff2 -D)多架构(ARM 改 B 指令等):
B = EA(后接 24 位偏移);条件分支 BEQ = 0A、BNE = 1A(互改即取反);NOP = 00 00 A0 E1(条件前缀可调)B 编码 E000 起;条件分支取反改 cond 高半字节(D0 EQ ↔ D1 NE)B = 0x14000000 | (imm26 << 0)(±128MB);B.EQ = 0x54000000 | (cond<<12)(EQ 即 cond=0x0);NOP = D503201F验证:sha256sum 记录产物 → 沙箱内复跑([[re-sandbox]])——补丁版必须通过全部校验点([[re-license]] 清单),且功能行为与原始样本一致;再静态反编译确认 patch 点指令形态正确。
xxd / hexedit 抽查),不一致说明版本不对,不要硬写pesign -S -i signed.exe 先看签名数(-u N 可指定第 N 个);pesign -r [-u N] -i in.exe -o out.exe 移除签名并输出新文件(保留原文件)。这是两种不同操作:-r 重写 PE 移除 WIN_CERTIFICATE 证书表条目;若只想让 loader 不再查签名,也可仅把 PE Security 目录项(DataDirectory[SECURITY])的 offset+size 清 0,证书表仍留在文件里。注意 -d/--digest-type 是给 --hash 指定摘要算法,不是删除签名。签名不可恢复,勿伪造jmp 时目标偏移没重算(相对偏移 = 目标 − 下一条指令地址);对策——用 rizin / Ghidra 反汇编验证 patch 点指令解析与跳转目标正确,短距离优先保留 rel8 形态,超范围才用 rel32