【文章标题】: Aspr2.1 inline patching _Chord Pickout
【文章作者】: clide2000[DFCG]
【作者邮箱】: 54armai@sina.com
【软件名称】: chordpickout v1.6
【下载地址】: 自己搜索下载
【加壳方式】: ASProtect 2.1x SKE -> Alexey Solodovnikov
【保护方式】: 20天试用
【使用工具】: OD,LordPE,WinHex
【操作平台】: Xp_sp2
【作者声明】: 在完成了此次Inline Patching后才发现,这个程序并不是直接修改此Pre-Dip后就可以注册的,和和fly兄的试练品"Tag&Rename V3.2 RC3 "比较像,所以还得找出其他的暗桩才能正式注册。但这并不影响下面讨论的方法。
(因为比较懒,还未找出其他限制的暗桩,所以在Patching后,得到仍是个“试用已过期”的程序。)
失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【简单说明】
在正式开始前,讲下自已对Aspr1.X与Aspr2.x的Inline patching不同点:
对于Aspr1.X:
1、需要找到"获得ASProtect注册名Pre-Dip处理的地址"(并找出其代码地址在文件中的偏移,和有关数据运算数据 + 求逆);
2、得到壳重定位后的基址;
3、RegOpenKeyExA,要得到壳通过读取注册表中的信息判断是否过期的地方。
4、Patch最终处理。
对于Aspr2.X:
1、需要找到"获得ASProtect注册名Pre-Dip处理的地址"(但已经无法直接在文件中找到其对应的偏移了,因为壳用了循环解码,所以在这增
加了难度)(第一处不同点)▲
2、增加了对内存代码的检验。(第二处不同点)▲
2、得到壳重定位后的基址;
3、RegOpenKeyExA,要得到壳通过读取注册表中的信息判断是否过期的地方。
4、所以在Patch时,不会像Aspr1.X时那么容易了。必须从壳第一次循环解码时开始Patch(直接修改文件中的相应代码),像传递接力棒一
样。一直Patch到最终完全解码,之后的操作就和Aspr1.X比较相似了,只是要多处理一个CRC校验( MapViewOfFileEx)(第三处不同点)▲
5、对于Patch代码的存放地也不一样了。像Aspr1.X时的400080那地方太小,已经不够用了。所在一般都要事先用WinHex之类的工具,在文件
尾部增加定量的字节,同进还要用LordPe之类的修改一下文件最后.data段的VSize和RSize都改为对应的新值。(第四处不同点)▲
以上只是个人的感觉,如果错误之处,还请各位兄弟指正。
这次的文章是参考了"Inline Patch ASProtect 2.X 学习笔记 by temerata"和"Inline Patch注册AsPrtect V2.X保护程序――Tag&Rename
V3.2 RC3 by fly"。算是对这两篇文章的理解与实际运用,文中依然会有多处这两脱文的影子,包括原文的引用和书写风格:)
------------------------------------------------------------------------------------------------------------
一点建议:
如果对Aspr1.X的Inline Patching还有没完全掌握的朋友,建议先补下课。(推荐:fly老大的“Patch注册ASProtect V1.X壳保护程序的方
法”),这样再来玩Aspr2.X的Inline Patching就可以循序渐进,轻松一些。
-------------------------------------------------------------------------------------------------------------
【详细过程】
一、用OllyDbg打开chordpickout.exe,隐藏OllyDbg(以下不再赘述),寻找注册名的Pre-dip和那三个跳转(方法请参考fly老大的“Patch注
册ASProtect V1.X壳保护程序的方法”)。
0103CAB9 50 push eax ;; 01023A29
//◆ 记住这里
0103CABA 8B47 04 mov eax, dword ptr ds:[edi+4]
//◆ 记住这里
0103CABD FFD0 call eax ;;Pre-dip
0048C6C8 55 push ebp
0048C6C9 8BEC mov ebp, esp
0048C6CB A1 78D74A00 mov eax, dword ptr ds:[4AD778]
0048C6D0 8B55 08 mov edx, dword ptr ss:[ebp+8] ; 01023A29,存放注册名
0048C6D3 E8 7883F7FF call chordpic.00404A50
0048C6D8 5D pop ebp
0048C6D9 C2 0400 retn 4
0048C6D9 处返回到壳的代码之后查找全部命令――>push 20019,可以找到6个跳转:
地址 反汇编 注释
0102A299 call 010256D4 (初始 CPU 选择)
0102A376 call 010256D4 jmp 到 advapi32.RegOpenKeyExA
0102A3E2 call 010256D4 jmp 到 advapi32.RegOpenKeyExA
0102A495 call 010256D4 jmp 到 advapi32.RegOpenKeyExA
0102A57D call 010256D4 jmp 到 advapi32.RegOpenKeyExA
0103E1C3 call 010256D4 jmp 到 advapi32.RegOpenKeyExA
0103E260 call 010256D4 jmp 到 advapi32.RegOpenKeyExA
一般修改后面3个CALL后的跳转就行了,记住这几个地方
//◆ 记住这里
0102A57D E8 52B1FFFF call 010256D4 ; jmp 到 advapi32.RegOpenKeyExA
0102A582 85C0 test eax, eax
0102A584 75 30 jnz short 0102A5B6
//⑴☆修改成
//0102A584 eb 30 jmp short 0102A5B6
0103E1C3 E8 0C75FEFF call 010256D4 ; jmp 到 advapi32.RegOpenKeyExA
0103E1C8 85C0 test eax, eax
0103E1CA 75 42 jnz short 0103E20E
//⑵☆修改成
//0103E1CA eb 42 jmp short 0103E20E
0103E260 E8 6F74FEFF call 010256D4 ; jmp 到 advapi32.RegOpenKeyExA
0103E265 85C0 test eax, eax
0103E267 0F85 88000000 jnz 0103E2F5
//⑶☆修改成
//0103E267 /E9 89000000 jmp 0103E2F5
//0103E26C |90 nop
----------------------------------------------------------------------------
二、获取壳代码重定位基址,设置OD忽略所有异常+壳代码完全解压
Ctrl+F2重新载入
HE VirtualAlloc Shift+F9,中断2次后取消断点,Alt+F9返回
0052F496 68 00100000 push 1000
0052F49B FFB5 08040000 push dword ptr ss:[ebp+408]
0052F4A1 6A 00 push 0
0052F4A3 FF95 F0030000 call dword ptr ss:[ebp+3F0]
0052F4A9 8985 CC010000 mov dword ptr ss:[ebp+1CC], eax
0052F4AF 8B9D 00040000 mov ebx, dword ptr ss:[ebp+400]
0052F4B5 039D 0D040000 add ebx, dword ptr ss:[ebp+40D]
0052F4BB 50 push eax
0052F4BC 53 push ebx
0052F4BD E8 04010000 call chordpic.0052F5C6
0052F4C2 6A 40 push 40
0052F4C4 68 00100000 push 1000
0052F4C9 FFB5 08040000 push dword ptr ss:[ebp+408]
0052F4CF 6A 00 push 0
0052F4D1 FF95 F0030000 call dword ptr ss:[ebp+3F0]
0052F4D7 8985 31040000 mov dword ptr ss:[ebp+431], eax
//返回到这里
//[ebp+431]=[0052F823]=01020000 壳代码重定位基址 ★与aspr1.x的一样
0052F4DD 8985 D0010000 mov dword ptr ss:[ebp+1D0], eax
0052F4E3 64:67:A1 0000 mov eax, dword ptr fs:[0]
0052F4E8 8985 2D040000 mov dword ptr ss:[ebp+42D], eax
0052F4EE 8B55 5B mov edx, dword ptr ss:[ebp+5B]
0052F4F1 8B85 D0010000 mov eax, dword ptr ss:[ebp+1D0]
0052F4F7 8902 mov dword ptr ds:[edx], eax
0052F4F9 8B85 08040000 mov eax, dword ptr ss:[ebp+408]
0052F4FF 8942 04 mov dword ptr ds:[edx+4], eax
0052F502 8D85 9F030000 lea eax, dword ptr ss:[ebp+39F]
0052F508 8B40 55 mov eax, dword ptr ds:[eax+55]
0052F50B 8942 08 mov dword ptr ds:[edx+8], eax
0052F50E 8B85 EC030000 mov eax, dword ptr ss:[ebp+3EC]
0052F514 8942 10 mov dword ptr ds:[edx+10], eax
0052F517 8B85 E8030000 mov eax, dword ptr ss:[ebp+3E8]
0052F51D 8942 14 mov dword ptr ds:[edx+14], eax
0052F520 8B95 CC010000 mov edx, dword ptr ss:[ebp+1CC]
0052F526 BB F8010000 mov ebx, 1F8
0052F52B 8B7C1A 0C mov edi, dword ptr ds:[edx+ebx+C]
0052F52F 0BFF or edi, edi
0052F531 74 1E je short chordpic.0052F551
0052F533 8B4C1A 10 mov ecx, dword ptr ds:[edx+ebx+10]
0052F537 0BC9 or ecx, ecx
0052F539 74 11 je short chordpic.0052F54C
0052F53B 03BD D0010000 add edi, dword ptr ss:[ebp+1D0]
0052F541 8B741A 14 mov esi, dword ptr ds:[edx+ebx+14]
0052F545 03F2 add esi, edx
0052F547 C1F9 02 sar ecx, 2
0052F54A F3:A5 rep movs dword ptr es:[edi], dword ptr ds:[esi]
0052F54C 83C3 28 add ebx, 28
0052F54F ^ EB DA jmp short chordpic.0052F52B
0052F551 8B85 CC010000 mov eax, dword ptr ss:[ebp+1CC]
0052F557 50 push eax
0052F558 8B95 D0010000 mov edx, dword ptr ss:[ebp+1D0]
0052F55E 52 push edx
0052F55F 8B18 mov ebx, dword ptr ds:[eax]
0052F561 03DA add ebx, edx
0052F563 8B85 E4030000 mov eax, dword ptr ss:[ebp+3E4]
0052F569 8903 mov dword ptr ds:[ebx], eax
0052F56B 8B85 E8030000 mov eax, dword ptr ss:[ebp+3E8]
0052F571 8943 04 mov dword ptr ds:[ebx+4], eax
0052F574 8B85 EC030000 mov eax, dword ptr ss:[ebp+3EC]
0052F57A 8943 08 mov dword ptr ds:[ebx+8], eax
0052F57D 5F pop edi
0052F57E 5E pop esi
0052F57F 8B46 04 mov eax, dword ptr ds:[esi+4]
0052F582 03C7 add eax, edi
0052F584 8985 C7010000 mov dword ptr ss:[ebp+1C7], eax
0052F58A 8B55 5B mov edx, dword ptr ss:[ebp+5B]
0052F58D 8B85 C7010000 mov eax, dword ptr ss:[ebp+1C7]
0052F593 8942 0C mov dword ptr ds:[edx+C], eax
0052F596 8D9D 0D040000 lea ebx, dword ptr ss:[ebp+40D]
0052F59C 53 push ebx
0052F59D 6A 00 push 0
0052F59F 6A 00 push 0
0052F5A1 6A 01 push 1
0052F5A3 57 push edi
0052F5A4 8B5E 08 mov ebx, dword ptr ds:[esi+8]
0052F5A7 03DF add ebx, edi
0052F5A9 53 push ebx
0052F5AA 68 00800000 push 8000
//◆ 记住这里
0052F4A3和0052F4D1 分别是第1次和第2次调用VirtualAlloc,在第2次调用以后可以Patch以获得壳的基址,这里我沿用JohnWho的方法,选
择0052F5AA处作为Patch点,EDI保存了基址。
壳代码完全解压
(需要在第3次调用以后VirtualAlloc,先找个patch点,接着才能patch壳代码完全解压后的地方,原因在下边有提示)
此时F9继续运行,中断后,Alt+F9,F8 返回到:
010510CA 8985 75294400 mov dword ptr ss:[ebp+442975], eax
//返回到这
010510D0 8D9D 452A4400 lea ebx, dword ptr ss:[ebp+442A45]
010510D6 50 push eax
010510D7 53 push ebx
010510D8 E8 74050000 call 01051651
010510DD 8BC8 mov ecx, eax
010510DF 8DBD 452A4400 lea edi, dword ptr ss:[ebp+442A45]
010510E5 8BB5 75294400 mov esi, dword ptr ss:[ebp+442975]
010510EB F3:A4 rep movs byte ptr es:[edi], byte ptr ds:[esi]
010510ED 8B85 75294400 mov eax, dword ptr ss:[ebp+442975]
010510F3 68 00800000 push 8000
//我选择在这里patch,用于在得到基址后,而在壳代码完全解压前的一个patch点,承上启下。
//◆ 记住这里
010510F8 6A 00 push 0
010510FA 50 push eax
010510FB FF95 7D294400 call dword ptr ss:[ebp+44297D]
01051101 8D0E lea ecx, dword ptr ds:[esi]
01051103 8551 2C test dword ptr ds:[ecx+2C], edx
01051106 44 inc esp
01051107 07 pop es ; 段寄存器更改
01051108 50 push eax
01051109 C3 retn
继续,再次Alt+f9,F8后返回到:
0105130D 8B9D 552A4400 mov ebx, dword ptr ss:[ebp+442A55]
//返回到这
01051313 0BDB or ebx, ebx
01051315 74 0A je short 01051321
01051317 8B03 mov eax, dword ptr ds:[ebx]
01051319 8785 592A4400 xchg dword ptr ss:[ebp+442A59], eax
0105131F 8903 mov dword ptr ds:[ebx], eax
01051321 8DB5 712A4400 lea esi, dword ptr ss:[ebp+442A71]
01051327 833E 00 cmp dword ptr ds:[esi], 0
0105132A 0F84 D3000000 je 01051403
01051330 8DB5 712A4400 lea esi, dword ptr ss:[ebp+442A71]
Ctrl+B向下找B8 01 00 00 00 C2 0C 00,看到AsPrtect解压壳代码的那个循环
010515C1 61 popad
//◆ 记住这里
010515C2 75 08 jnz short 010515CC
010515C4 B8 01000000 mov eax, 1
//找到了这里
010515C9 C2 0C00 retn 0C
010515CC 68 00000000 push 0
010515D1 C3 retn
{
//这是fly兄快速度定位到"壳代码完全解压"的方法。
壳代码完全解压,设置OD忽略所有异常.
Ctrl+F2重新载入
HE GetModuleHandleA Shift+F9,中断2次后取消断点,Alt+F9返回
010514A6 FF95 EC314400 call dword ptr ss:[ebp+4431EC]
010514AC 85C0 test eax, eax ; kernel32.7C800000
//返回到这里
010514AE 75 07 jnz short 010514B7
010514B0 53 push ebx
Ctrl+F向下找popad,看到AsPrtect解压壳代码的那个循环
010515C1 61 popad
//记住这里 ★
010515C2 75 08 jnz short 010515CC
010515C4 B8 01000000 mov eax, 1
//找到了这里
010515C9 C2 0C00 retn 0C
010515CC 68 00000000 push 0
010515D1 C3 retn
提示:做到这里时,我产生了一些疑问,因为在fly主脱文中,在对上边这个010515C1 popad的patch之前,也就是其文中第七点的patch是
如何确定的,好像没有交代清楚(也可能是我漏掉了吧)。
结合temerata的文章得知,在第2次调用VirtualAlloc后,可以得到基址,但上面010515C1 popad这段代码还没有解码,而是等到第3次调用
VirtualAlloc后,才得到完全解码。所以得在第3次调用VirtualAlloc后找个地patch一下。
这里我找的patch点是:
010510F3 68 00800000 push 8000
}
----------------------------------------------------------------------------------------------------
四、自校验:
接下来一步是要逃过CRC检验,清除VirtualAlloc处的断点,然后bp MapViewOfFileEx,断下后返回到壳代码:
01038668 6A 04 push 4
0103866A A1 14B40401 mov eax, dword ptr ds:[104B414]
0103866F 50 push eax
01038670 A1 E4970401 mov eax, dword ptr ds:[10497E4]
01038675 8B40 08 mov eax, dword ptr ds:[eax+8]
01038678 FFD0 call eax
0103867A 8BD8 mov ebx, eax ; 返回到这里
//记住这里 ★
只要修改01038668处的4改为1,EXE文件的内存映像就会是可写的;
而返回到0103867A后,EAX保存了EXE文件内存映像的开始地址,在我这里是01230000 ★★★,因而选择这一行作为Patch点。
最后一个Patch点我选择了0103CAB9 ,就是进入注册名Pre-dip前的地方。
所有的Patch点都清楚了。下面要开妈patch了。
五、Patch
1、准备工作
将源chordpickout.exe复制一份为其它名字,我这里复制为clide.exe。用WinHex
打开chordpickout.exe,在文件最后添加大小为1000H的90H,用PE Editor将.adata区段的RSize改为1000H。这是因为chordpickout.exe文件
内没
有什么区段间的空隙放置Patch代码,而JohnWho的文章中就是采用这种方法。我想如果有区段间空隙,将Patch代码放在那些空隙里应该也是
可
以的。
2、写Patch代码的地址
OD载入clide.exe,忽略所有异常,F9运行,会弹出消息框说文件损坏云云,不用管它,定位到.adata段,可以发现那片本应全是Nop的代码
前面有一块被壳覆盖为0了,往下看没有被覆盖的地方,那里就是我们可以写入Patch代码的地方了。我这里选择00556400。
3、修复文件第一处解码循环
Ctrl+F2重新载入
00401000 > 68 01F05200 push clide.0052F001
//OD载入后
00401005 E8 01000000 call clide.0040100B
0040100A C3 retn
0040100B C3 retn
F7单步走,看ASProtect解压壳代码
0052F164 81FF 9CF8FFFF cmp edi, -764
0052F16A 0F85 1E000000 jnz chordpic.0052F18E
0052F170 66:81E8 8E89 sub ax, 898E
//解码循环 第1个点 接口 ★
0052F16A - E9 91720200 jmp clide.00556400
0052F16F 90 nop
在0052F170 处F4,可以看到下面的代码发生了变化,我想这个可以作为是否是解码循环的判断依据吧。0052F16A处是最先要Patch的地方。
可以用LordPe的FLC功能查出,0052F16A对应的偏移为:0008516A。
现在关闭OD,用WinHex打开cldie.exe,定位到偏移:0008516A,修改原内容0F85 1E000000为E9 9172020090,保存。
4、开始正式编写patch代码
打开OD,载入刚才修改好的clide.exe
(从现在开始将像接力赛跑一样,从第一处“解码循环”开始,一直patch到“壳的代码完全解码”。
Ctrl+G:00556400
Patch代码:
00556400 - 0F85 888DFDFF jnz clide.0052F18E
//0052F16A 代码挪这里执行
00556406 C705 6AF15200 0F85>mov dword ptr ds:[52F16A], 1E850F
00556410 66:C705 6EF15200 0>mov word ptr ds:[52F16E], 0
//还原0052F16A处修改的代码
mov dword ptr ds:[52F26F], 271B5
//Patch 0052F26E处跳转
00556423 - E9 488DFDFF jmp clide.0052F170
// 返回原处继续
第二个解码循环
0052F256 5E pop esi
0052F257 81FA 80F9FFFF cmp edx, -680
0052F25D 0F85 19000000 jnz chordpic.0052F27C
0052F263 50 push eax
0052F264 68 0FBCAC15 push 15ACBC0F
0052F269 0FB7CF movzx ecx, di
0052F26C 59 pop ecx
0052F26D 5B pop ebx
0052F26E E9 23000000 jmp chordpic.0052F296
//解码循环 Patch 点 ★
改成:
0052F26E - E9 B5710200 jmp clide.00556428
Patch代码:
00556428 C705 6FF25200 2300>mov dword ptr ds:[52F26F], 23
//还原0052F26E处修改的代码
00556432 C705 36F35200 E90F>mov dword ptr ds:[52F336], 2710FE9
0055643C 66:C705 3AF35200 0>mov word ptr ds:[52F33A], 9000
////Patch 0052F336处跳转
00556445 - E9 248EFDFF jmp clide.0052F26E
// 返回原处继续
第三个解码循环
0052F311 BE 530C100D mov esi, 0D100C53
0052F316 81C6 BCDE271F add esi, 1F27DEBC
0052F31C 81EA 9A892B02 sub edx, 22B899A
0052F322 66:8BCB mov cx, bx
0052F325 81C2 96892B02 add edx, 22B8996
0052F32B 66:81E7 9F0D and di, 0D9F
0052F330 81FA 34FAFFFF cmp edx, -5CC
0052F336 ^ 0F85 8DFFFFFF jnz chordpic.0052F2C9
//解码循环 Patch 点 ★
0052F33C 53 push ebx
改成:
//0052F336 - E9 0F710200 jmp clide.0055644A
//0052F33B 90 nop
Patch代码:
0055644A - 0F85 798EFDFF jnz clide.0052F2C9
//00052F336 代码挪这里执行
00556450 C705 36F35200 0F85>mov dword ptr ds:[52F336], FF8D850F
0055645A 66:C705 3AF35200 F>mov word ptr ds:[52F33A], 0FFFF
//还原0052F336处修改的代码
00556432 C705 36F35200 E90F>mov dword ptr ds:[52F3e4], 27092E9
0055643C 66:C705 3AF35200 0>mov word ptr ds:[52F3e8], 9000
//Patch 0052F3e4处跳转
00556476 - E9 C18EFDFF jmp clide.0052F33C
// 返回原处继续
第四个解码循环:
0052F3D9 66:81E3 510A and bx, 0A51
0052F3DE 81FA D8FAFFFF cmp edx, -528
0052F3E4 ^ 0F85 ADFFFFFF jnz chordpic.0052F397
//解码循环 Patch 点 ★
0052F3EA 66:8BCF mov cx, di
//改成:
0052F3E4 - E9 92700200 jmp clide.0055647B
0052F3E9 90 nop
Patch代码:
0055647B - 0F85 168FFDFF jnz clide.0052F397
//0052F3E4 代码挪这里执行
00556481 C705 E4F35200 0F85ADFF mov dword ptr ds:[52F3E4], FFAD850F
0055648B 66:C705 E8F35200 FFFF mov word ptr ds:[52F3E8], 0FFFF
//还原0052F3e4处修改的代码
00556494 C705 51F55200 E9566F02 mov dword ptr ds:[0052F5AA], 26F56E9
//Patch 0052F5AA处
0055649E - E9 478FFDFF jmp clide.0052F3EA
// 返回原处继续
第五个点:获取壳代码重定位基址
0052F5A4 8B5E 08 mov ebx, dword ptr ds:[esi+8]
0052F5A7 03DF add ebx, edi
0052F5A9 53 push ebx
0052F5AA 68 00800000 push 8000
//此时,edi中存放着基址 Patch 点 ★
0052F5AF 6A 00 push 0
0052F5B1 56 push esi
改成:
0052F5AA - E9 F46E0200 jmp clide.005564A3
Patch代码:
005564A3 C705 AAF55200 68008000 mov dword ptr ds:[52F5AA], 800068
//还原0052F5AA处修改的代码
005564AD 893D 00655500 mov dword ptr ds:[556700], edi
//找个位置存放壳的基址,我这里选择556700
005564B3 60 pushad
005564B4 9C pushfd
005564B5 A1 00655500 mov eax, dword ptr ds:[556700]
005564BA C780 F3100300 E9DA5350 mov dword ptr ds:[eax+310F3], 5053DAE9
//; 每台机器由于生成的壳的基址不同,所以像这样jmp xxxx修改,每台机器有可能都不同,需要个别对待
005564C4 C680 F7100300 FF mov byte ptr ds:[eax+310F7], 0FF
//Patch 010510F3 处,当执行到这里时,程序就已经完全解码了
005564CB 9D popfd
005564CC 61 popad
005564CD - E9 D890FDFF jmp clide.0052F5AA
第六个点:程序已经完全解码
010510EB F3:A4 rep movs byte ptr es:[edi], b>
010510ED 8B85 75294400 mov eax, dword ptr ss:[ebp+44>
010510F3 68 00800000 push 8000
//承上启下 Patch 点 ★
//我选择在这里patch,用于在得到基址后,而在壳代码完全解压前的一个patch点,承上启下。
010510F8 6A 00 push 0
010510FA 50 push eax
改成:
010510F3 - E9 DA5350FF jmp clide.005564D2
Patch代码:
005564D2 60 pushad ; 保存现场
005564D3 9C pushfd
005564D4 A1 00675500 mov eax, dword ptr ds:[556700] ; 取得基址
005564D9 C780 F3100300 68008000 mov dword ptr ds:[eax+310F3], 800068 ; 还原Patch点代码
005564E3 C680 F7100300 00 mov byte ptr ds:[eax+310F7], 0
005564EA C780 C1150300 68146555 mov dword ptr ds:[eax+315C1], 55651468 ; Patch 010515C1处的代码
005564F4 C680 C5150300 00 mov byte ptr ds:[eax+315C5], 0
005564FB C680 C6150300 C3 mov byte ptr ds:[eax+315C6], 0C3
00556502 05 F3100300 add eax, 310F3 ; 取得Patch点地址
00556507 A3 0F655500 mov dword ptr ds:[55650F], eax ; 修改下面Push的地址
0055650C 9D popfd ; 恢复现场
0055650D 61 popad
0055650E 68 00000000 push 0 ; Push 返回地址,由00556507处设定
00556513 C3 retn
第七个点:
00F415C1 61 popad
//patch点,此时壳已经完全解码了
00F415C2 75 08 jnz short 00F415CC
00F415C4 B8 01000000 mov eax, 1
00F415C9 C2 0C00 retn 0C
00F415CC 68 00000000 push 0
00F415D1 C3 retn
改成:
00F415C1 68 14655500 push 556514
00F415C6 C3 retn
Patch代码:
00556514 60 pushad ; 保存现场
00556515 9C pushfd
00556516 A1 00675500 mov eax, dword ptr ds:[556700] ; 取得基址
0055651B C780 C1150300 617508B8 mov dword ptr ds:[eax+315C1], B8087561 ; 还原Patch点代码
00556525 C680 C5150300 01 mov byte ptr ds:[eax+315C5], 1
0055652C C680 C6150300 00 mov byte ptr ds:[eax+315C6], 0
00556533 C680 69860100 01 mov byte ptr ds:[eax+18669], 1 ; 修改01038668处的Push 4为Push 1,使内存映
像可写
0055653A C780 7A860100 68646555 mov dword ptr ds:[eax+1867A], 55656468 ; Patch 0103867A处的代码
00556544 C680 7E860100 00 mov byte ptr ds:[eax+1867E], 0
0055654B C680 7F860100 C3 mov byte ptr ds:[eax+1867F], 0C3
00556552 05 C1150300 add eax, 315C1 ; 取得Patch点地址
00556557 A3 5F655500 mov dword ptr ds:[55655F], eax ; 修改下面Push的地址
0055655C 9D popfd ; 恢复现场
0055655D 61 popad
0055655E 68 00000000 push 0 ; Push 返回地址,由00556557处设定
00556563 C3 retn
第八个点:
01038668 6A 01 push 1
0103866A A1 14B40401 mov eax, dword ptr ds:[104B414]
0103866F 50 push eax
01038670 A1 E4970401 mov eax, dword ptr ds:[10497E4]
01038675 8B40 08 mov eax, dword ptr ds:[eax+8]
01038678 FFD0 call eax
0103867A 8BD8 mov ebx, eax ; 返回到这里
//patch点,在执行完 MapViewOfFileEx后,恢复这前的push 4
改成:
01038668 6A 04 push 4
Patch代码:
00556564 C780 6A510800 0F851E00 mov dword ptr ds:[eax+8516A], 1E850F ; 还原0052F16A 在内存映像中相应位置的代码,
即是之前直接修改文件中偏移:0008516A的代码
0055656E 66:C780 6E510800 0000 mov word ptr ds:[eax+8516E], 0
00556577 C680 99030000 00 mov byte ptr ds:[eax+399], 0 ; 还原内存映像中.adata段的RSize为0,这两句
是为了逃过CRC校验
0055657E 60 pushad
0055657F 9C pushfd
00556580 A1 00675500 mov eax, dword ptr ds:[556700] ; 取得基址
00556585 C680 69860100 04 mov byte ptr ds:[eax+18669], 4 ; 还原01038668处的代码
0055658C C780 7A860100 8BD850E8 mov dword ptr ds:[eax+1867A], E850D88B ; 还原0103867A的代码
00556596 66:C780 7E860100 4A01 mov word ptr ds:[eax+1867E], 14A
0055659F C780 B9CA0100 E9069B62 mov dword ptr ds:[eax+1CAB9], 629B06E9 ; Patch 0103CAB9,即Pre-dip前的位置
//; 每台机器由于生成的壳的基址不同,所以像这样jmp xxxx修改,每台机器有可能都不同,需要个别对待
005565A9 66:C780 BDCA0100 FF90 mov word ptr ds:[eax+1CABD], 90FF
005565B2 05 7A860100 add eax, 1867A ; 取得Patch点地址
005565B7 A3 BF655500 mov dword ptr ds:[5565BF], eax ; 修改下面Push的地址
005565BC 9D popfd ; 恢复现场
005565BD 61 popad
005565BE 68 00000000 push 0 ; Push 返回地址,由005565B7处设定
005565C3 C3 retn
第九个点:Pre-dip前的位置
0103CAB9 50 push eax ;; 01023A29
//Patch点,这是最后一次patch了
0103CABA 8B47 04 mov eax, dword ptr ds:[edi+4]
0103CABD FFD0 call eax ;;Pre-dip
改成:
00F2CAB9 - E9 069B62FF jmp test_cli.005565C4
00F2CABE 90 nop
Patch代码:
005565C4 68 60665500 push clide.00556660 ; ASCII "clide2000[DFCG]"
//; Push 注册名的存放位置,取代原来的Push eax,这个可以在这些Patch代码后面找个地方,并填上自己的大名。
005565C9 60 pushad
005565CA 9C pushfd
005565CB A1 00675500 mov eax, dword ptr ds:[556700]
005565D0 C780 B9CA0100 508B4704 mov dword ptr ds:[eax+1CAB9], 4478B50 ; 还原0103CAB9处代码
005565DA 66:C780 BDCA0100 FFD0 mov word ptr ds:[eax+1CABD], 0D0FF
005565E3 C680 7DA30000 EB mov byte ptr ds:[eax+A37D], 0EB ; Patch试用信息读写跳转
005565EA C680 E9A30000 EB mov byte ptr ds:[eax+A3E9], 0EB
005565F1 C780 9CA40000 E9940000 mov dword ptr ds:[eax+A49C], 94E9
005565FB C680 A1A40000 90 mov byte ptr ds:[eax+A4A1], 90
00556602 C680 84A50000 EB mov byte ptr ds:[eax+A584], 0EB
00556609 C680 CAE10100 EB mov byte ptr ds:[eax+1E1CA], 0EB
00556610 C780 67E20100 E9890000 mov dword ptr ds:[eax+1E267], 89E9
0055661A C680 6CE20100 90 mov byte ptr ds:[eax+1E26C], 90
00556621 C780 A0A20000 E9850000 mov dword ptr ds:[eax+A2A0], 85E9
0055662B C680 A5A20000 90 mov byte ptr ds:[eax+A2A5], 90
00556632 05 BACA0100 add eax, 1CABA
00556637 A3 3F665500 mov dword ptr ds:[55663F], eax
0055663C 9D popfd
0055663D 61 popad
0055663E 68 00000000 push 0
00556643 C3 retn
这里要说明一下,按照前人的经验,一般的Aspr只需要修改用"查找全部命令――>push 20019"找到的跳转中的后3个即可。但我这次有点郁
闷,我上面尝试修改了所有找到的跳转后,
结果发现程序还是未注册,且提示已经过试用期了。估计这个可能和fly兄的试练品"Tag&Rename V3.2 RC3 "比较像,并不是直接修改此Pre
-Dip后就可以注册的。
但这并不影响之前我们讨论的Aspr2.X的 Inline Patching方法。
―――――――――――――――――――――――――――――――――
六、Patch代码汇总
00556400 - 0F85 888DFDFF jnz clide.0052F18E
00556406 C705 6AF15200 0F851E00 mov dword ptr ds:[52F16A], 1E850F
00556410 66:C705 6EF15200 0000 mov word ptr ds:[52F16E], 0
00556419 C705 6FF25200 B5710200 mov dword ptr ds:[52F26F], 271B5
00556423 - E9 488DFDFF jmp clide.0052F170
00556428 C705 6FF25200 23000000 mov dword ptr ds:[52F26F], 23
00556432 C705 36F35200 E90F7102 mov dword ptr ds:[52F336], 2710FE9
0055643C 66:C705 3AF35200 0090 mov word ptr ds:[52F33A], 9000
00556445 - E9 248EFDFF jmp clide.0052F26E
0055644A - 0F85 798EFDFF jnz clide.0052F2C9
00556450 C705 36F35200 0F858DFF mov dword ptr ds:[52F336], FF8D850F
0055645A 66:C705 3AF35200 FFFF mov word ptr ds:[52F33A], 0FFFF
00556463 C705 E4F35200 E9927002 mov dword ptr ds:[52F3E4], 27092E9
0055646D 66:C705 E8F35200 0090 mov word ptr ds:[52F3E8], 9000
00556476 - E9 C18EFDFF jmp clide.0052F33C
0055647B - 0F85 168FFDFF jnz clide.0052F397
00556481 C705 E4F35200 0F85ADFF mov dword ptr ds:[52F3E4], FFAD850F
0055648B 66:C705 E8F35200 FFFF mov word ptr ds:[52F3E8], 0FFFF
00556494 C705 AAF55200 E9F46E02 mov dword ptr ds:[52F5AA], 26EF4E9
0055649E - E9 478FFDFF jmp clide.0052F3EA
005564A3 C705 AAF55200 68008000 mov dword ptr ds:[52F5AA], 800068
005564AD 893D 00675500 mov dword ptr ds:[556700], edi
005564B3 60 pushad
005564B4 9C pushfd
005564B5 A1 00675500 mov eax, dword ptr ds:[556700]
005564BA C780 F3100300 E9DA5361 mov dword ptr ds:[eax+310F3], 6153DAE9
//; 每台机器由于生成的壳的基址不同,所以像这样jmp xxxx修改,每台机器有可能都不同,需要个别对待
005564C4 C680 F7100300 FF mov byte ptr ds:[eax+310F7], 0FF
005564CB 9D popfd
005564CC 61 popad
005564CD - E9 D890FDFF jmp clide.0052F5AA
005564D2 60 pushad
005564D3 9C pushfd
005564D4 A1 00675500 mov eax, dword ptr ds:[556700]
005564D9 C780 F3100300 68008000 mov dword ptr ds:[eax+310F3], 800068
005564E3 C680 F7100300 00 mov byte ptr ds:[eax+310F7], 0
005564EA C780 C1150300 68146555 mov dword ptr ds:[eax+315C1], 55651468
005564F4 C680 C5150300 00 mov byte ptr ds:[eax+315C5], 0
005564FB C680 C6150300 C3 mov byte ptr ds:[eax+315C6], 0C3
00556502 05 F3100300 add eax, 310F3
00556507 A3 0F655500 mov dword ptr ds:[55650F], eax
0055650C 9D popfd
0055650D 61 popad
0055650E 68 00000000 push 0
00556513 C3 retn
00556514 60 pushad
00556515 9C pushfd
00556516 A1 00675500 mov eax, dword ptr ds:[556700]
0055651B C780 C1150300 617508B8 mov dword ptr ds:[eax+315C1], B8087561
00556525 C680 C5150300 01 mov byte ptr ds:[eax+315C5], 1
0055652C C680 C6150300 00 mov byte ptr ds:[eax+315C6], 0
00556533 C680 69860100 01 mov byte ptr ds:[eax+18669], 1
0055653A C780 7A860100 68646555 mov dword ptr ds:[eax+1867A], 55656468
00556544 C680 7E860100 00 mov byte ptr ds:[eax+1867E], 0
0055654B C680 7F860100 C3 mov byte ptr ds:[eax+1867F], 0C3
00556552 05 C1150300 add eax, 315C1
00556557 A3 5F655500 mov dword ptr ds:[55655F], eax
0055655C 9D popfd
0055655D 61 popad
0055655E 68 00000000 push 0
00556563 C3 retn
00556564 C780 6A510800 0F851E00 mov dword ptr ds:[eax+8516A], 1E850F
0055656E 66:C780 6E510800 0000 mov word ptr ds:[eax+8516E], 0
00556577 C680 99030000 00 mov byte ptr ds:[eax+399], 0
0055657E 60 pushad
0055657F 9C pushfd
00556580 A1 00675500 mov eax, dword ptr ds:[556700]
00556585 C680 69860100 04 mov byte ptr ds:[eax+18669], 4
0055658C C780 7A860100 8BD850E8 mov dword ptr ds:[eax+1867A], E850D88B
00556596 66:C780 7E860100 4A01 mov word ptr ds:[eax+1867E], 14A
0055659F C780 B9CA0100 E9069B62 mov dword ptr ds:[eax+1CAB9], 629B06E9
//; 每台机器由于生成的壳的基址不同,所以像这样jmp xxxx修改,每台机器有可能都不同,需要个别对待
005565A9 66:C780 BDCA0100 FF90 mov word ptr ds:[eax+1CABD], 90FF
005565B2 05 7A860100 add eax, 1867A
005565B7 A3 BF655500 mov dword ptr ds:[5565BF], eax
005565BC 9D popfd
005565BD 61 popad
005565BE 68 00000000 push 0
005565C3 C3 retn
005565C4 68 60665500 push clide.00556660 ; ASCII
"clide2000[DFCG]"
005565C9 60 pushad
005565CA 9C pushfd
005565CB A1 00675500 mov eax, dword ptr ds:[556700]
005565D0 C780 B9CA0100 508B4704 mov dword ptr ds:[eax+1CAB9], 4478B50
005565DA 66:C780 BDCA0100 FFD0 mov word ptr ds:[eax+1CABD], 0D0FF
005565E3 C680 7DA30000 EB mov byte ptr ds:[eax+A37D], 0EB
005565EA C680 E9A30000 EB mov byte ptr ds:[eax+A3E9], 0EB
005565F1 C780 9CA40000 E9940000 mov dword ptr ds:[eax+A49C], 94E9
005565FB C680 A1A40000 90 mov byte ptr ds:[eax+A4A1], 90
00556602 C680 84A50000 EB mov byte ptr ds:[eax+A584], 0EB
00556609 C680 CAE10100 EB mov byte ptr ds:[eax+1E1CA], 0EB
00556610 C780 67E20100 E9890000 mov dword ptr ds:[eax+1E267], 89E9
0055661A C680 6CE20100 90 mov byte ptr ds:[eax+1E26C], 90
00556621 C780 A0A20000 E9850000 mov dword ptr ds:[eax+A2A0], 85E9
0055662B C680 A5A20000 90 mov byte ptr ds:[eax+A2A5], 90
00556632 05 BACA0100 add eax, 1CABA
00556637 A3 3F665500 mov dword ptr ds:[55663F], eax
0055663C 9D popfd
0055663D 61 popad
0055663E 68 00000000 push 0
00556643 C3 retn
00556644 90 nop
00556645 90 nop
00556646 90 nop
00556647 90 nop
00556648 90 nop
00556649 90 nop
0055664A 90 nop
0055664B 90 nop
0055664C 90 nop
0055664D 90 nop
0055664E 90 nop
0055664F 90 nop
00556650 90 nop
00556651 90 nop
00556652 90 nop
00556653 90 nop
00556654 90 nop
00556655 90 nop
00556656 90 nop
00556657 90 nop
00556658 90 nop
00556659 90 nop
0055665A 90 nop
0055665B 90 nop
0055665C 90 nop
0055665D 90 nop
0055665E 90 nop
0055665F 90 nop
00556660 636C69 64 arpl word ptr ds:[ecx+ebp*2+64], bp
00556664 65:3230 xor dh, byte ptr gs:[eax]
00556667 3030 xor byte ptr ds:[eax], dh
00556669 5B pop ebx
0055666A 44 inc esp
0055666B 46 inc esi
0055666C 43 inc ebx
0055666D 47 inc edi
0055666E 5D pop ebp
0055666F 0000 add byte ptr ds:[eax], al
0F 85 88 8D FD FF C7 05 6A F1 52 00 0F 85 1E 00 66 C7 05 6E F1 52 00 00 00 C7 05 6F F2
52 00 B5
71 02 00 E9 48 8D FD FF C7 05 6F F2 52 00 23 00 00 00 C7 05 36 F3 52 00 E9 0F 71 02 66
C7 05 3A
F3 52 00 00 90 E9 24 8E FD FF 0F 85 79 8E FD FF C7 05 36 F3 52 00 0F 85 8D FF 66 C7 05
3A F3 52
00 FF FF C7 05 E4 F3 52 00 E9 92 70 02 66 C7 05 E8 F3 52 00 00 90 E9 C1 8E FD FF 0F 85
16 8F FD
FF C7 05 E4 F3 52 00 0F 85 AD FF 66 C7 05 E8 F3 52 00 FF FF C7 05 AA F5 52 00 E9 F4 6E
02 E9 47
8F FD FF C7 05 AA F5 52 00 68 00 80 00 89 3D 00 67 55 00 60 9C A1 00 67 55 00 C7 80 F3
10 03 00
E9 DA 53 61 C6 80 F7 10 03 00 FF 9D 61 E9 D8 90 FD FF 60 9C A1 00 67 55 00 C7 80 F3 10
03 00 68
00 80 00 C6 80 F7 10 03 00 00 C7 80 C1 15 03 00 68 14 65 55 C6 80 C5 15 03 00 00 C6 80
C6 15 03
00 C3 05 F3 10 03 00 A3 0F 65 55 00 9D 61 68 00 00 00 00 C3 60 9C A1 00 67 55 00 C7 80
C1 15 03
00 61 75 08 B8 C6 80 C5 15 03 00 01 C6 80 C6 15 03 00 00 C6 80 69 86 01 00 01 C7 80 7A
86 01 00
68 64 65 55 C6 80 7E 86 01 00 00 C6 80 7F 86 01 00 C3 05 C1 15 03 00 A3 5F 65 55 00 9D
61 68 00
00 00 00 C3 C7 80 6A 51 08 00 0F 85 1E 00 66 C7 80 6E 51 08 00 00 00 C6 80 99 03 00 00
00 60 9C
A1 00 67 55 00 C6 80 69 86 01 00 04 C7 80 7A 86 01 00 8B D8 50 E8 66 C7 80 7E 86 01 00
4A 01 C7
80 B9 CA 01 00 E9 06 9B 62 66 C7 80 BD CA 01 00 FF 90 05 7A 86 01 00 A3 BF 65 55 00 9D
61 68 00
00 00 00 C3 68 60 66 55 00 60 9C A1 00 67 55 00 C7 80 B9 CA 01 00 50 8B 47 04 66 C7 80
BD CA 01
00 FF D0 C6 80 7D A3 00 00 EB C6 80 E9 A3 00 00 EB C7 80 9C A4 00 00 E9 94 00 00 C6 80
A1 A4 00
00 90 C6 80 84 A5 00 00 EB C6 80 CA E1 01 00 EB C7 80 67 E2 01 00 E9 89 00 00 C6 80 6C
E2 01 00
90 C7 80 A0 A2 00 00 E9 85 00 00 C6 80 A5 A2 00 00 90 05 BA CA 01 00 A3 3F 66 55 00 9D
61 68 00
00 00 00 C3 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90
63 6C 69 64 65 32 30 30 30 5B 44 46 43 47 5D 00 00
--------------------------------------------------------------------------------
【经验总结】
一篇个人关于Aspr2.X的Inline Patching的学习笔记。
在此对temerata和fly表示感谢,同时也感谢你能看完这篇冗长的脱文。
另:为了验证其方法的可行性,可换个直接修改Pre-Dip后就可以注册的练习。(现在尝试找出其他的暗桩中...)
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2008年01月07日 10:52:39
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!