内嵌补丁(Embedded patch)
链接:https://pan.baidu.com/s/1sOzl2CaOaEMCoEJZTVrU-g
提取码:57g8
从入口点开始跟到0040109B
0040109B <unpackme#1.ac | 50 | push eax | 0040109C | 8BD8 | mov ebx,eax | 0040109E | B9 54010000 | mov ecx,0x154 | ecx:"`桡" 004010A3 | 8033 44 | xor byte ptr ds:[ebx],0x44 | 004010A6 | 83E9 01 | sub ecx,0x1 | ecx:"`桡" 004010A9 | 43 | inc ebx | 004010AA | 83F9 00 | cmp ecx,0x0 | ecx:"`桡" 004010AD | 75 F4 | jne unpackme#1.ac.4010A3 | 004010AF | 50 | push eax | 004010B0 | E8 08000000 | call <unpackme#1.ac.sub_4010BD> | 004010B5 | 50 | push eax | 004010B6 | E8 7EFFFFFF | call <unpackme#1.ac.sub_401039> | 004010BB | 58 | pop eax | 004010BC | C3 | ret |
|
此时eax为004010F5,所以会对004010F5 - 004010F5+0x154区域进行一次异或解密
004010F5 - 004010F5+0x154 ^0x44
|
跟进去call <unpackme#1.ac.sub_4010BD>
004010BD <unpackme#1.ac | 50 | push eax | 004010BE | BB 07104000 | mov ebx,unpackme#1.ac.401007 | 004010C3 | B9 7F000000 | mov ecx,0x7F | 004010C8 | 8033 07 | xor byte ptr ds:[ebx],0x7 | 004010CB | 83E9 01 | sub ecx,0x1 | 004010CE | 43 | inc ebx | 004010CF | 83F9 00 | cmp ecx,0x0 | 004010D2 | 75 F4 | jne unpackme#1.ac.4010C8 | 004010D4 | 8BD8 | mov ebx,eax | 004010D6 | B9 54010000 | mov ecx,0x154 | 004010DB | 8033 11 | xor byte ptr ds:[ebx],0x11 | 004010DE | 83E9 01 | sub ecx,0x1 | 004010E1 | 43 | inc ebx | 004010E2 | 83F9 00 | cmp ecx,0x0 | 004010E5 | 75 F4 | jne unpackme#1.ac.4010DB | 004010E7 | 58 | pop eax | 004010E8 | C3 | ret |
|
继续解密
00401007 - 00401007+0x7f ^0x7 004010F5 - 004010F5+0x154 ^0x11
|
跟进去call <unpackme#1.ac.sub_401039>
他会对经过两次解密后的004010F5 - 004010F5+0x154区域一次移动一字节,一次四个字节,累加到ebx中与0x31EB8DB0的校验和比对,不一致就调用exitprocess退出进程,否则就跳到
中间还会调用0040108A去做解密40121e执行
0040108A <unpackme#1.ac | 50 | push eax | 0040108B | 56 | push esi | esi:"`桡" 0040108C | 8BD8 | mov ebx,eax | 0040108E | 8BCE | mov ecx,esi | esi:"`桡" 00401090 | 8033 17 | xor byte ptr ds:[ebx],0x17 | 00401093 | 43 | inc ebx | 00401094 | 3BD9 | cmp ebx,ecx | 00401096 | 75 F8 | jne unpackme#1.ac.401090 | 00401098 | 58 | pop eax | 00401099 | 5E | pop esi | esi:"`桡" 0040109A | C3 | ret |
|
这里调用getmodulehadle返回一个句柄,这个句柄值其实就是模块加载的虚拟内存的基地址,之前学win32时一直不知道这个句柄具体值。。。
DialogBoxParamA的第四个参数lpDialogFunc就是用来处理对话框消息的回调函数即为004010F5
发现代码段里掺杂着数据区,估计这程序是用纯汇编写的,反正我不知道还有什么其他方法可以这样掺杂(还是太菜了)
方法1
这个时候其实可以去改掉加密的字符串数据为我们想要的,然后去改掉校验和的硬编码
方法2
用内嵌补丁,在完成检查校验和,jmp到入口点40121e之前,去劫持到我们的补丁,补丁做修改操作后,再jmp到入口点
看一下区段
代码段文件大小0x400,内存大小0x280(内存对齐后一般会变为0x1000)
有空余部分供我们写补丁代码,
直接用会汇编把数据改了就行
在去改下jmp到补丁的地方
改掉
但是这里是要经过加密的
00401007 - 00401007+0x7f(40 1086) ^0x7
|
>>> hex(0xE9^7) '0xee' >>> hex(0x05^7) '0x2' >>> hex(0x02^7) '0x5'
|
patch保存一下就好了,ok