<转>挣扎的菜鸟

<转>挣扎的菜鸟

原方转自 http://www.unpack.cn/thread-65647-1-1.html

【文章标题】: 挣扎的菜鸟 - 当OD不能装载也不能附加程序时【文章作者】: justlovemm【作者邮箱】: 无【作者主页】: 无【作者QQ号】: 无【下载地址】: 自己搜索下载【保护方式】: VMP2.07【使用工具】: OD,LoadPE,CE,Exception Monitor【作者声明】: 只是感兴趣,没有其他目的。只是一个菜鸟对几年前大牛们就搞定的问题的一次练习,请大牛们无视本文。------------------------------------------------------------------------------------------------------------------------------------------前几天拿到一个程序X,用PEiD查不到任何信息,用exeinfope说是VMP2.07。于是先用OD载入,结果OD立即直接被关闭。开始认为TLS在作怪,用LoadPE,删除掉TLS,保存。再用od 载入,还是一样。下来先直接运行程序,然后用OD附加,结果OD也是立即直接被关闭。检查OD的选项,first pause是在system breakpoint处(其实自TMD利用那个浮点漏洞关闭OD以后,我的OD一直是启动时停在system breakpoint的)。打开StrongOD的选项,break On TLS也是打上了勾的。这时仔细一想,不对啊,现在的设置应该能截获TLS的运行,这说明不是TLS的问题。下来考虑是否plugin有问题,于是删除了plugin目录下的所有文件,结果还是一样。现在菜鸟有点失望了,于是开始在论坛里找关于VMP2.07的资料,无果。查找OD被关闭,基本上就2条参考意见,一个是删除plugin试试,另一个是删除掉OD目录下的dbghelp.dll文件。于是直接试第二个方法,删除掉了OD目录下修改时间为2001年11月12日的dbghelp.dll文件,测试,结果还是一样。于是又把system32目录下的修改时间为2005年5月26日的dbghelp.dll拷贝到OD目录下,其实菜鸟心里也很清楚,这和刚试过的方法没有什么不同的,不过这个时候菜鸟已经有点绝望了,所以这样明知道不会有任何作用的方法菜鸟也要去试试。结果就不说了。也许是这个时候命不好,菜鸟竟然没有搜索到海风大牛关于dbghelp.dll文件的那个原帖,如果当时看到那个帖子,直接下载帖子里的dbghelp.dll,就不会有这些问题了。接着菜鸟在UPK发了一个帖子求助,热心人很多,不过菜鸟太菜,没能搞定。下来改用CE装载,OK,可以装载。然后运行,提示发现调试器。菜鸟据此判断,此anti一定是针对OD的。不过菜鸟不会用CE调试程序,至少是不会象用OD那样去用CE调试程序。现在,菜鸟已经绝望了。以前TMD不能加载的时候,菜鸟只能等待,不过很快,大牛们就给出了解决方法,菜鸟只是照着去做就OK了。可是现在菜鸟觉得很无助,不知道去哪里寻找帮助,觉得四周一片漆黑。绝望的菜鸟只能一个人在那儿苦苦思索,过了几个小时,菜鸟突然想到一个方法,可以用OD来调试OD,然后用被调试的OD去装载程序X,这样应该就能知道OD是怎么被关闭的了。菜鸟当时心里还有点激动,心想,也许一个新的anti OD的方法就要让本菜鸟给搞定了,哈哈。立即动手,用OllyICE加载一个OllyDbg,用OllyDbg加载程序X,OllyDbg立即被关闭,去OllyICE中查看OllyDbg退出时的栈,没有得到任何有用的线索。再试,用OllyICE加载一个OllyDbg,然后在CreateProcessA和ResumeThread处下断,用OllyDbg加载程序X,断在CreateProcessA处,F8过去,OllyDbg正常,再Shift+F9,断到ResumeThread处,再F8过去,然后调出任务管理器,看到进程X已经有一点CPU的占用率了,这时OllyDbg还未被关闭,再Shift+F9,OllyDbg直接被关闭,查看退出的栈,还是没有任何线索。这时候先推理到,OllyDbg当时是一被调试的进程,除了调试进程以外,其它进程是无法关闭OllyDbg的,菜鸟猜想是否给OllyDbg窗口发送了WM_QUIT或者WM_CLOSE消息。于是在OD中查找GetMessage,未发现,查找PeekMessage,找到好几个,根据传入的消息的上下限,找到了OllyDbg的窗口过程中使用的PeekMessage,在PeekMessage返回后的一个地方下条件断点,当消息ID是WM_QUIT或者WM_CLOSE时触发断点。再次载入程序X,OllyDbg同样被关掉,并未触发任何条件断点。这样就排除了程序X发送消息给OllyDbug窗口的可能性。这时菜鸟认定OllyDbg在装入程序X的时候本身产生了什么不可捕获的异常,导致程序直接被关闭了。问题是怎么才能知道这个异常发生在什么地方呢?此时的菜鸟又一次陷入了绝望,又觉得四周一片漆黑。在黑暗中孤独的思索了几个小时后,菜鸟突然想起以前用过的Exception Monitor,是M$的产品,当时是为了调试服务进程而推出的东东。用这个东西能捕获最后一次异常发生时的线程信息,包括各个寄存器和栈数据。上网搜索,还是命不好,竟然找不到MS的Exception Monitor的下载地点。不过,也意外的发现还有好几个类似的产品,一个叫EMon.exe的还是开源的,于是下载了这个EMon.exe。打开OllyDbg,用EMon.exe去attach,在进程列表里没有发现OllyDbg。呵呵,是StrongOD隐藏了OllyDbg进程,删除掉SOD,OK,用EMon.exe attach OllyDbg,再用OllyDbg载入程序X,然后看到EMon.exe的Log窗口哗哗哗的闪,计算机不停的叫"叭嗒叭嗒",过了有2、3分钟,停了下来,OllyDbg已经不见踪影了。EMon.exe最后的Log是这样的:

下午 04:00:09: Process terminated with exit code 3221225477

下午 04:00:09: End of Process: 4076 - OllyDBG.EXE

下午 04:00:09: End of Process: 2380 - X.exe

接着往上看,最后出错信息是这样的:

下午 04:00:09: ACCESS_VIOLATION at address 7C92EDDD

** The thread tried to read from or write to a virtual address

for which it does not have the appropriate access.

** Thread ID=00000F34

** Access violation writing address 00030FFC

** First chance

** Register Dump:

EAX=0000000C

EBX=7C920000 : 00905A4D 00000003 00000004 0000FFFF

ECX=7C930833 : 900004C2 FFFFFF90 95C5FEFF 95C6077C

EDX=000000E0

EDI=7C9237D8 : 04244C8B 060441F7 B8000000 00000001

ESI=7C920000 : 00905A4D 00000003 00000004 0000FFFF

ESP=00031000 : 7C920000 00000000 00000000 00000000

EBP=00031020 : 00031030 7C93086E 7C920000 00031400

EIP=7C92EDDD : 458B5756 E86589F8 FC458B50 FFFC45C7

** Stack Dump:

00031000: 7C920000 : 00905A4D 00000003 00000004 0000FFFF

00031004: 00000000

00031008: 00000000

0003100C: 00000000

00031010: 00031464 : 00031834 7C9237D8 0012B060 00031520

00031014: 7C92EE18 : 83EC8B55 565308EC 8BFC5557 458B0C5D

00031018: 7C9307F5 : 4D8BC033 74C98508 FFF98330 45212B74

0003101C: 7C930838 : FFFFFFFF 7C95C5FE 7C95C607 90909090

00031020: 00031030 : 0003104C 7C9579F0 7C920000 00000001

00031024: 7C93086E : 840FC085 000025BC 18488B66 0BF98166

00031028: 7C920000 : 00905A4D 00000003 00000004 0000FFFF

0003102C: 00031400 : C0000034 00000000 00000018 00E8DAA0

00031030: 0003104C : 00031080 7C95799C 7C920000 0003107C

00031034: 7C9579F0 : 840FC085 000001D8 85FC4D8B CD840FC9

00031038: 7C920000 : 00905A4D 00000003 00000004 0000FFFF

0003103C: 00000001

** Disassembly listing

7C92EDDD: 56 push esi

7C92EDDE: 57 push edi

7C92EDDF: 8B45F8 mov eax, [ebp-0x08]

7C92EDE2: 8965E8 mov [ebp-0x18], esp

7C92EDE5: 50 push eax

7C92EDE6: 8B45FC mov eax, [ebp-0x04]

7C92EDE9: C745FCFFFFFFFF mov [ebp-0x04], 0xFFFFFFFF

7C92EDF0: 8945F8 mov [ebp-0x08], eax

7C92EDF3: 8D45F0 lea eax, [ebp-0x10]

7C92EDF6: 64A300000000 mov 0x00000000, eax

** End of exception report

7C92EDDD是在ntdll中的,菜鸟不知道这个是怎么调用来的。不过在OllyICE中看了一下fs:[8],是00031000,而上面的出错信息的ESP也是这个值,这说明线程栈已经已经用光了,程序无法再运行了。再往上看,下来的出错信息好像都一样,都是下面这个样子的:

下午 04:00:09: ACCESS_VIOLATION at address 32C21FAE

** The thread tried to read from or write to a virtual address

for which it does not have the appropriate access.

** Thread ID=00000F34

** Access violation reading address 32C21FAE

** First chance

** Register Dump:

EAX=00000000

EBX=00000000

ECX=32C21FAE

EDX=7C9237D8 : 04244C8B 060441F7 B8000000 00000001

EDI=00000000

ESI=00000000

ESP=00031450 : 7C9237BF 00031538 0012B060 00031554

EBP=00031470 : 00031520 7C92378B 00031538 0012B060

EIP=32C21FAE

** Stack Dump:

00031450: 7C9237BF : 00258B64 64000000 0000058F E58B0000

00031454: 00031538 : C0000005 00000010 00000000 32C21FAE

00031458: 0012B060 : 8525521F 32C21FAE 1D2F676B ABC87504

0003145C: 00031554 : 0001003F 00000000 00000000 00000000

00031460: 0003150C : 0012B060 00000000 00130000 00031000

00031464: 00031834 : 00031C04 7C9237D8 0012B060 000318F0

00031468: 7C9237D8 : 04244C8B 060441F7 B8000000 00000001

0003146C: 0012B060 : 8525521F 32C21FAE 1D2F676B ABC87504

00031470: 00031520 : 00031840 7C92EAFA 0012B060 00031554

00031474: 7C92378B : C25B5E5F 8B900014 909090FF 8B559090

00031478: 00031538 : C0000005 00000010 00000000 32C21FAE

0003147C: 0012B060 : 8525521F 32C21FAE 1D2F676B ABC87504

00031480: 00031554 : 0001003F 00000000 00000000 00000000

00031484: 0003150C : 0012B060 00000000 00130000 00031000

00031488: 32C21FAE

0003148C: 00000002

** End of exception report

每次出错的地址都是32C21FAE,用上面的OllyICE调试OllyDbg并断在ResumeThread之后,查看,这个地址是空的。菜鸟觉得很怪异。继续向上看,都是32C21FAE。于是直接翻到到最上面的Log,才发现只有第一个不是32C21FAE,第一个出错的地址是68D808BF,信息如下:

下午 03:57:58: ACCESS_VIOLATION at address 68D808BF

** The thread tried to read from or write to a virtual address

for which it does not have the appropriate access.

** Thread ID=00000F34

** Access violation reading address 8C699B73

** First chance

** Register Dump:

EAX=8C699B73

EBX=023FBF58 : 00000000 00000000 00000000 0040B987

ECX=8C291638

EDX=73A90925

EDI=023F9160 : 00000000 00000000 00400000 00000000

ESI=023FA090 : 023FAA48 00000000 00400000 00000000

ESP=0012A460 : 023F9160 80000000 023FA090 023FC3E4

EBP=0012ACAC : A1A8ECCE E2B7A856 9C91972D C09558D3

EIP=68D808BF : 0C88088A C9844002 8D38F675 FFFFF7EC

** Stack Dump:

0012A460: 023F9160 : 00000000 00000000 00400000 00000000

0012A464: 80000000

0012A468: 023FA090 : 023FAA48 00000000 00400000 00000000

0012A46C: 023FC3E4 : 000A0118 00040006 00020008 001A000F

0012A470: 023FC616 : 0040791E 0040853B 0040855D 00408581

0012A474: 023FBF58 : 00000000 00000000 00000000 0040B987

0012A478: 023FBF80 : 0000158D 00001F0C 0000D640 0000D778

0012A47C: 023FBF58 : 00000000 00000000 00000000 0040B987

0012A480: 00343158 : 00580058 0070002E 00620064 00000000

0012A484: 00000124

0012A488: 02400AF8 : 00000000 00000000 00000000 00000000

0012A48C: 000000B8

0012A490: 00000001

0012A494: 00000001

0012A498: 7EA7BC00

0012A49C: F11FC1BF

** Disassembly listing

68D808BF: 8A08 mov cl, [eax]

68D808C1: 880C02 mov [edx+eax], cl

68D808C4: 40 inc eax

68D808C5: 84C9 test cl, cl

68D808C7: 75F6 jnz +0x000000F6

68D808C9: 388DECF7FFFF cmp [ebp-0x00000814]

68D808CF: 7473 jz +0x00000073

68D808D1: F6059804DF6802 test 0x68DF0498, 0x00000002

68D808D8: 8D85ECF7FFFF lea eax, [ebp-0x00000814]

68D808DE: 8D5001 lea edx, [eax+0x01]

** End of exception report

在OllyICE中查看了一下68D808BF,在DbgHelp.dll中。OK,重新用OllyICE装载OllyDbg,在68D808BF处下断,然后装载程序X,成功断下。在数据窗口跳到eax,eax地址有效,看了一下代码,这个应该是一个字符串拷贝的循环,删除68D808BF处的断点,在循环结束后的68D808C9下断,F9正常运行到68D808C9,然后再F9,就跑飞了。为了捕获异常不让OllyDbg跑飞,再重新来一次,在68D808BF断下后,取消断点,跳到fs:[0],对当前SEH的handler 68D90888 下硬件断点,F9,还是跑飞了。跑飞的时候好像还提示了那个不存在的地址32C21FAE,一看log,是"32C21FAE|访问违规: 正在执行 [32C21FAE]",很奇怪,为什么在跳到这个不存在的地址之前没有去执行SEH的hander 68D90888。无奈,再来,再次断到68D808BF处,F9了几次,每次都又断到68D808BF,这时查看了一下后面一行代码中的edx+eax竟然等于12A498,哈哈字符串拷贝的目标地址在当前栈上,在数据窗口跳到EAX(02363102),看一下,没有发现00,二进制搜索00,在02363D1E,原来EAX指向的字符串长达0xC1C,就是3100字节长,而根据前面的代码68D808B7 8D95 ECF7FFFF lea edx, dword ptr [ebp-814]edx在栈上最大的可用空间也只能是0x814,这肯定是把线程的栈数据给覆盖了。重新测试一下,当断到68D808BF处时,在数据窗口跳去fs:[0],然后F4到68D808C9,这时数据窗口的数据已经完全改变了,就是说SEH的链和hander已经被覆盖了,而hander就是被修改为那个不存在的32C21FAE。这时,菜鸟已经明白了,那个字符串拷贝的循环应该就是一个inline化的strcpy,由于没有限制拷贝长度,造成栈数据被覆盖掉了,而新生成的Exception Handler是无效的,结果就又触发了新的异常,进入了一个异常循环,直到栈被用光,OD就结束了,连错误提示都没有,让人以为OD是被正常关闭了。搞清楚这个以后,菜鸟又在想,这个分明就是一个异常,为什么用OllyICE调试OllyDbg时没有捕获这个异常呢,查看了一下OD的设置,发现是忽略了非法的内存访问异常。设置成不忽略非法的内存访问,用OllyICE装载OllyDbg,然后OllyDbg装载程序X,在OllyICE中就断到了68D808BF,OK,确定了就是这个异常。分析到这一步,本来应该再分析一下DbgHelp.dll,看看是在拷贝什么信息的时候造成的栈溢出,可是这个时候菜鸟又去搜索了一下DbgHelp.dll,找到了海风大牛的那个帖子,下载了那个DbgHelp.dll,用OD加载程序X,正常的停到了系统入口。这时菜鸟才发现自己的确成不了大牛,因为菜鸟这个时候已经不愿意再去分析DbgHelp.dll了。最后再说一下,菜鸟因为自己在OD不能装载和附加时,经过思考发现了如何去寻找不能装载和附加的方法,菜鸟自己非常高兴,所以写了此文,为自己庆贺一下!对DbgHelp.dll溢出时的分析在25楼,请大家指正。

相关推荐

什么时候开服刺激战场 —— 各大新区齐上阵
beat365唯一网址

什么时候开服刺激战场 —— 各大新区齐上阵

08-15 👁️ 8754
3DS《口袋妖怪银行》ORAS如何使用与联机交换图文详细教程
助攻什么意思
365提款

助攻什么意思

09-03 👁️ 4473