内嵌补丁(Embedded patch)

内嵌补丁(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>

image-20230523155641278

他会对经过两次解密后的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 |
0040124A-00401280 ^0x17

image-20230523161559913

这里调用getmodulehadle返回一个句柄,这个句柄值其实就是模块加载的虚拟内存的基地址,之前学win32时一直不知道这个句柄具体值。。。

DialogBoxParamA的第四个参数lpDialogFunc就是用来处理对话框消息的回调函数即为004010F5

image-20230523164357610

发现代码段里掺杂着数据区,估计这程序是用纯汇编写的,反正我不知道还有什么其他方法可以这样掺杂(还是太菜了)

方法1

这个时候其实可以去改掉加密的字符串数据为我们想要的,然后去改掉校验和的硬编码

方法2

用内嵌补丁,在完成检查校验和,jmp到入口点40121e之前,去劫持到我们的补丁,补丁做修改操作后,再jmp到入口点

看一下区段

image-20230523165512284

代码段文件大小0x400,内存大小0x280(内存对齐后一般会变为0x1000)

有空余部分供我们写补丁代码,

直接用会汇编把数据改了就行

image-20230523172707047

在去改下jmp到补丁的地方

image-20230523173024075

改掉

image-20230523173139510

但是这里是要经过加密的

00401007 - 00401007+0x7f(40 1086) ^0x7
>>> hex(0xE9^7)
'0xee'
>>> hex(0x05^7)
'0x2'
>>> hex(0x02^7)
'0x5'

image-20230523173624190

patch保存一下就好了,ok