主页 PC知识 网管技术 黑客帝国 安全技术 开放系统 程序设计 搜索 技术论坛

 

相关联接
 
RHU本级分类

新手入门
入侵实例
工具使用
安全防范
黑客人物
软件破解
漏洞研究

 
RHU阅读排行
·直面"拿来主义"—浅谈共享软件的破解方法
·《疯狂单词》“中级”教程
·ACCESS密码查看器算法分析[简单]
·goldeneye使用教程
·网络验证——Nok2Phone V3.41 (VB)(算法分析)
·软件狗[Dongles]的加密与解密技术
·加密算法之BLOWFISH算法
·新版aspr脱壳方法(完全版)
·凯撒密文的破解编程实现
·逆向追踪+模拟跟踪方法寻找暗桩 解除脱UPX后的校验

 
 
RHU最新文章
·Tray.Commander.v2.3 注册算法分析
·带壳分析易语言+简单浮点算法
·WinKawaks 1.45脱壳笔记
·破解高手常用的破解工具介绍
·用内存注册机方式破解X-NetStat
·<好帮手进销存>算法分析
·解密宝典——十招教你学会软件破解
·对付自校验的杀手锏 -- 偷天换日
·简单分析"冰狐浪子下载运行512生成器
·脱壳高级篇之认识Import表

 
 
RHU相关搜索









 
 
RHU广而告之

 
 
>您的位置:首页 -> 黑客帝国-> 软件破解
逆向追踪+模拟跟踪方法寻找暗桩 解除脱UPX后的校验

作者:www.asmcc.com 来自:RHU网络编辑 时间:2005-3-5 双击滚屏 收藏本页 字体:


点击 查看RHU2004全年文章


 

【脱文标题】 逆向追踪+TC(模拟跟踪)方法寻找暗桩--解除脱UPX后的校验

【脱文作者】 Lenus

【作者邮箱】 Lenus_M@163.com

【作者主页】 www.popbase.net & bbs.asmcc.com

【使用工具】 Ollydbg,Loadpe,PEID,Import_Rec 1.6

【破解平台】 WinXp(SP2)

【软件名称】 在DFCG上逛的时候找到的一个小外挂,好象是玩升级游戏可以看其他人的牌的工具。

   
【加壳方式】 UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo [Overlay]

【脱壳声明】 我是一个考古人,在软件的土地上,发掘未知的宝藏!


----------------------------------------------------------------------

【脱壳内容】

1.寻找OEP+dump+修复IAT。

UPX的壳,脱壳过程我就不再重复。用ESP定律可以马上找到,或者直接往下找到0000000前面的JMP。用LORDPE dump下来,用Import_Rec修复。

注意到这个壳有OVERLAY,所以脱壳修复后,不求他马上能运行(如果马上就能运行那这篇文章就太垃圾了^^)

本来这个壳不想写什么的,但是看到论坛上很多人在问,对于UPX脱壳后的修复问题。所以在这里我打算整理一次一些基本的方法。供大家参考,当然还有很多修复的方法,在这里不可能全讲完。而且随着自己的脱壳经验的增长慢慢的也会懂一些技巧!

2.修复暗桩

I.逆向跟踪法

运行修复好了IAT的程序,发现什么反应都没有!

从这里我们可以有两个结论:

1.壳的不能正常运行不是关于overlay的。因为,如果是因为没读到附加的数据应该有非法操作和警告的对话窗弹出。

2.壳应该是有校验的地方发现壳被脱掉了就直接退出了程序。

得到上面的结论我们不难得出我们的下一步是什么:找校验的地方。

但是代码茫茫我们该如何去寻找呢?我用我的逆向追踪法!

因为程序的退出一般用的是这个API:ExitProcess

于是我们从最后的函数开始向前追踪程序!

用OD载入脱壳后的代码我的是DUMP_.EXE,来到这里
0040F765 d> 55             push ebp           //这里是OEP
0040F766   8BEC           mov ebp,esp
0040F768   6A FF           push -1
0040F76A   68 903A4100       push dumped_.00413A90

在命令行下断BP ExitProcess ,F9运行,断下


7C81CAA2 k> 8BFF           mov edi,edi                     ; ntdll.7C930738     //停在这里
7C81CAA4   55             push ebp
7C81CAA5   8BEC           mov ebp,esp
7C81CAA7   6A FF           push -1
7C81CAA9   68 B0F3E877       push 77E8F3B0

这里是系统领空,看看堆栈。

0012FF04   77C09D45 /CALL 到 ExitProcess 来自 msvcrt.77C09D3F   //还记得我写的ESP定律的预备知识吗?(没看过的去补补课^^)
0012FF08   00000000 \ExitCode = 0

很明显77C09D45是call ExitProcess的时候,压入堆栈的地址。

好了我们到77C09D45处去看看,ctrl+g 输入77C09D45,来到77C09D45处。

77C09D3F   FF15 1C12BE77     call dword ptr ds:[<&KERNEL32.ExitProcess>; kernel32.ExitProcess //这里call ExitProcess
77C09D45   CC             int3                                         //这里是返回地址          
这里还是系统的领空,向上面找找是什么地方call到这里来的?


77C09D11   CC             int3
77C09D12   CC             int3
77C09D13   8BFF           mov edi,edi               //上面是int 3 估计这个系统函数的入口是这里,F2下断。
77C09D15   55             push ebp
77C09D16   8BEC           mov ebp,esp
77C09D18   68 A440BE77       push msvcrt.77BE40A4               ; ASCII "mscoree.dll"
77C09D1D   FF15 E810BE77     call dword ptr ds:[<&KERNEL32.GetModuleHa>; kernel32.GetModuleHandleA

找到了新的入口,那就从来一遍ctrl+F2 ,F9 , 断下!看堆栈!

0012FF10   77C09E78 返回到 msvcrt.77C09E78 来自 msvcrt.77C09D13
0012FF14   00000000

继续找,到77C09E78处!!

77C09E73   E8 9BFEFFFF       call msvcrt.77C09D13   //这里是call向77C09D13的地方
77C09E78   CC             int3

再想上找入口

77C09E54   E8 0EFFFFFF       call msvcrt._initterm
77C09E59   59             pop ecx
77C09E5A   59             pop ecx
77C09E5B   85DB           test ebx,ebx
77C09E5D   74 0B           je short msvcrt.77C09E6A           //第3处
77C09E5F   6A 08           push 8
77C09E61   E8 B3060000       call msvcrt._unlock
77C09E66   59             pop ecx
77C09E67   5E             pop esi
77C09E68   5D             pop ebp
77C09E69   C3             retn                       //第2处
77C09E6A   FF75 08         push dword ptr ss:[ebp+8]       // 第1处
77C09E6D   8935 541AC377     mov dword ptr ds:[77C31A54],esi
77C09E73   E8 9BFEFFFF       call msvcrt.77C09D13

看到前面有个RETN 第一个可能的入口是77C09E6A,可能有一个call从什么地方call过来;然而我们知道有些RETN也可能是变形JMP(不过这个不太可能,但我们对他也不可掉以轻心);第3个地方是77C09E5D他JMP过了RETN。所以为了保险我们3个一起下断!!

好了重来一次!F9,断在了77C09E5D 处,果然是JMP过了RETN

好了继续向上找吧!

77C09DD8   CC             int3
77C09DD9   CC             int3
77C09DDA   CC             int3
77C09DDB   8BFF           mov edi,edi     //找到这里,估计有是一个call吧!下断,重来!
77C09DDD   55             push ebp

重来后断在这里看堆栈:

0012FF20   77C09E90 返回到 msvcrt.77C09E90 来自 msvcrt.77C09DDB //还没回到程序领空(真累,但是一路能断下来说明我们的方向是正确的!!)
0012FF24   00000000

继续

来到77C09E90向上找

77C09E7C   CC             int3
77C09E7D   CC             int3
77C09E7E m> 8BFF           mov edi,edi   //是这里 下断,重来
77C09E80   55             push ebp


F9 后断到这里,看堆栈!

0012FF34   0040F8A3 /CALL 到 exit 来自 dumped_.0040F89D   //终于回到程序领空了!庆祝一下吧!
0012FF38   00000000 \status = 0

好了,到程序领空去吧!

0040F884   ^\EB F5           jmp short dumped_.0040F87B
0040F886   6A 0A           push 0A
0040F888   58             pop eax
0040F889   50             push eax
0040F88A   56             push esi
0040F88B   53             push ebx
0040F88C   53             push ebx
0040F88D   FF15 F4804200     call dword ptr ds:[<&kernel32.#374>]     ; kernel32.GetModuleHandleA
0040F893   50             push eax
0040F894   E8 17040000       call dumped_.0040FCB0
0040F899   8945 98         mov dword ptr ss:[ebp-68],eax
0040F89C   50             push eax
0040F89D   FF15 BC864200     call dword ptr ds:[<&msvcrt.#657>]     ; msvcrt.exit   //从这里开始call向ExitProcess


逆向追踪现在全部完毕了,呵呵,很累是吗?其实做一个好的crack,想不累是不可能的,关键是这一路下来我们在系统的领空玩得挺高兴的,而且多学会了一种方法,呵呵,值了!!

II.TC模拟跟踪法

下面我们的工作就是什么地方是校验了(一般的程序在exitprocess的前面不远就会有一个关键比较可以跳过,但是这个程序却没有。)于是我们在这里先停一停。来看看原未脱壳的程序它在这里是怎么运行的。呵呵我们发现原来这个地址离OEP还不是很远!

于是,我们用OD载入未脱壳的程序,用ESP定律来到OEP处!(这里请格外注意一下,一定要关掉原来的程序,因为这个程序会检查在内存中是否还有另一个同样的进程,如果有就直接退出,这个也是我后来才知道的,但是这个东西却不是校验,所以,曾经影响了我的判断!)

向下找到0040F89D地址,在他的前面的JMP和CALL全部下断(不要太多了^^)

我们会发现程序在(用F8)步过0040F894这里的时候,程序就运行了。

所以我们又得到了以下的结论:
1.程序的校验一定在0040F894里面的某个地方。因为我们的脱壳后的程序也步过了这一句但是什么都没反映就出来了!

2.程序0040F89D是正个程序的终点。上面的call里面一定有个校验比较。如果发现程序被脱壳就直接跳出来结束。(难怪我们运行程序的时候什么反应都没有)

知道上面的结论我们就再来一次。

F7进入0040F894 的call

0040FCB0   FF7424 10       push dword ptr ss:[esp+10]             //到这里
0040FCB4   FF7424 10       push dword ptr ss:[esp+10]            
0040FCB8   FF7424 10       push dword ptr ss:[esp+10]
0040FCBC   FF7424 10       push dword ptr ss:[esp+10]
0040FCC0   E8 43000000       call               //这个call没什么东西啊,F7继续跟进!
0040FCC5   C2 1000         retn 10                         //返回就挂了

0040FD08   - FF25 28864200     jmp dword ptr ds:[<&mfc42.#1576>]       ; mfc42.#1576 //到这里,啊跳转表,原来这个是一个api啊!
0040FD0E   CC             int3

跳到这里:

73D3CF2B m> 8BFF           mov edi,edi                     ; ntdll.7C930738   //到这里了
73D3CF2D   53             push ebx
73D3CF2E   56             push esi

哎,又是系统领空了!真是累,如果各位还想在里面玩玩我可不想在奉陪了,这里祭出OD强大的模拟跟踪命令TC,在命令行键入 TC EIP<7000000(只要不在系统领空的时候就断下来!)

回车后,马上到了这里:

0040F062   - FF25 98814200     jmp dword ptr ds:[<&mfc42.#3922>]       ; mfc42.#3922   //又是一个api -_-!
0040F068   - FF25 9C814200     jmp dword ptr ds:[<&mfc42.#1089>]       ; mfc42.#1089

到这里

73DC9FED m> 8B15 9404E173     mov edx,dword ptr ds:[73E10494]   //又来到系统领空。
73DC9FF3   85D2           test edx,edx
73DC9FF5   74 14           je short mfc42.73DCA00B

再来TC EIP<7000000,回车后到这里

00402300   64:A1 00000000     mov eax,dword ptr fs:[0]         //哈哈,终于找到了。小样,别以为用了api我就认不出你了。
00402306   6A FF           push -1
00402308   68 38FF4000       push dumped_.0040FF38
0040230D   50             push eax
0040230E   64:8925 00000000   mov dword ptr fs:[0],esp
00402315   81EC 30020000     sub esp,230
0040231B   53             push ebx
0040231C   56             push esi
0040231D   57             push edi
0040231E   68 FC714100       push dumped_.004171FC               ; ASCII "OLDWORM_GLUPGRADE_HELPER_APP"
00402323   6A 00           push 0
00402325   8BF1           mov esi,ecx
00402327   68 01001F00       push 1F0001
0040232C   FF15 CC804200     call dword ptr ds:[<&kernel32.#627>]     ; kernel32.OpenMutexA
00402332   85C0           test eax,eax
00402334   8986 C4000000     mov dword ptr ds:[esi+C4],eax
0040233A   75 56           jnz short dumped_.00402392
0040233C   68 FC714100       push dumped_.004171FC               ; ASCII "OLDWORM_GLUPGRADE_HELPER_APP"
00402341   6A 01           push 1
00402343   50             push eax
00402344   FF15 D0804200     call dword ptr ds:[<&kernel32.#93>]     ; kernel32.CreateMutexA

上面的0040233A有一个跳转,但是这个不是的哦,看到前面的OpenMutexA了吗?这个估计是判断内存里面还有同样的进程,然后决定新建一个新的进程CreateMutexA(如果哪位兄弟觉得这个功能很多余也可以暴掉,不过我还算是比较尊重原创的^-^)

向下面找

0040236F   E8 ACD60000       call dumped_.0040FA20
00402374   83C4 04         add esp,4
00402377   85C0           test eax,eax
00402379   74 17           je short dumped_.00402392           //可疑目标1
0040237B   E8 80A40000       call dumped_.0040C800
00402380   85C0           test eax,eax
00402382   74 28           je short dumped_.004023AC           //可以目标2
00402384   6A FF           push -1

上面的两个都是可能关键跳转,为了确定我们在这里分别下断,考察未脱壳程序在这里是否跳转。

考察结果:

未脱壳程序:目标1没跳,目标2跳了。

脱壳后的程序:目标1跳了,直接跳过了目标2。

所以只要把00402379 nop掉就可以了。

再次友情提醒,如果那位兄弟没有修改上面的判断进程的跳转的话,那么在考察两个程序关键跳的时候,一定要一个一个的看,不能开两个OD!!
OK,暴掉后程序正常运行。
----------------------------------------------------------------------

【脱壳总结】

      1.如果说逆向跟踪是大概确定校验地址的办法,那么正向跟踪(TC法)就是进一步确定精确校验的地址的办法。

      2.找校验的时候,多次用到CTRL+F2&F9的办法,这是一个cracker的必修课,你如果觉得我上面写的CTRL+F2&F9已经很多了,那么我可以告诉你,我在调试的时候,比这里用到的CTRL+F2&F9多了10倍!

      3.耐性很重要,一定要坚持

----------------------------------------------------------------------

【后话】  

      关于寻找校验的办法还有很多,有些我也不是很懂。但是,我们可以慢慢的积累经验,以后就会好了。谢谢你能看完。

      如果有什么不足欢迎指出,如果要转载请保持文章的完整!



OVER

[1] 页 RedHyphone.Union 投稿邮箱
[特别声明]:
本站文章大多搜索转载自网络中,如果侵犯了您的权利,请告之我们。本站将立即删除。
本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
查看评论】【向上滚屏】【关闭窗口】【 打印
-相关文章
-文章评论 (关闭)
·还没有相关的评论!

网上大名:
红旋风网络技术联盟 RHUTech.Union
 
Copyright © 2000-2007 RedHyphone.Union All Rights Reserved. 红旋风联盟版权所有.皖ICP备05011033号
中国红旋风网络技术联盟 | www.RedHyphone.net
Mailto:Redhyphone@gamil.com