|
第二步: BP WaitForDebugEvent寻找API report
这一步并非必要,但却是一个好的选择,当它停止时在dump区看到API report。
首先我们需要在命令行输入BP WaitForDebugEvent,现在运行它,当它停下时我们可以在Stack 窗口看到关于这个API的所有参数信息。
0012DAC4 00984B44 /CALL to WaitForDebugEvent
0012DAC8 0012EB74 |pDebugEvent = 0012EB74
0012DACC 000003E8 \Timeout = 1000. ms
看一下第二行。那儿我们可以看到它将在哪儿显示report,所以到dump窗口, 右键选择 "前往 表达"= 12EB74。注意这个值在一些机器上可能会不同,所以前往你的机器显示的值。
0012EB74 9C EB 12 00 C0 EB 12 00 滊.离.12
0012EB7C 00 00 00 00 90 FE 12 00 ....慆.0
0012EB84 9C 00 00 00 89 46 99 00 ?..塅? 00
0012EB8C 00 00 00 00 D8 EC 12 00 ....仂.0
0012EB94 F7 C6 E5 77 D0 EC 12 00 髌鍂徐. E5
0012EB9C 00 00 00 00 00 00 00 00 ........
我们在上面的图中看到的是我们将要称之为"API report"的东西。父进程通过那里得知子进程发生了什么。现在我们可以很容易地通过在命令行输入BC WaitForDebugEvent来删除这个断点。所有的操作都是为了在dump窗口看到report,在这个report中我们可以看到入口点OEP。
第三步: 寻找子进程入口点
[方法一],BP WRITEPROCESSMEMORY(使用OLLYDBG)
Bp WriteProcessMemory停下时在STACK窗口看到:
0012D964 0098867F /CALL to WriteProcessMemory from Konverto.00988679
0012D968 00000050 |hProcess = 00000050
0012D96C 004BA000 |Address = 4BA000
0012D970 003B51D0 |Buffer = 003B51D0
0012D974 00001000 |BytesToWrite = 1000 (4096.)
0012D978 0012DA80 \pBytesWritten = 0012DA80
这些信息被保存在父进程的一个缓冲区从3B51D0开始,然后它会复制给子进程一个从4BA000开始的 1000 bytes的块,所以如果我们到了这一步,我们可以很容易理解子进程的第一个section是完全空的,所以当它试图执行到OEP时,它报告一个错误因为那儿没有任何东西,所以父进程得到了通知正如我们可以在父进程的report中看到的,所以它停止了运行,复制必要的数据块,然后继续运行直到下一个错误。被复制的数据块的大小是1000 bytes,所以当程序试图执行任何超过这个大小的块外的指令时, 另一个错误将会发生,然后这个错误会被通知给父进程, 父进程会复制另外1000 bytes的块然后继续。
顺便说一下,我们可以假设第一个错误发生是因为子进程call了它的入口点OEP,它的值应该就在API report上。显然OEP的值必定在第一个块,父进程复制过去来解决子进程报告的错误。
这个块从4BA000开始直到4BAFFF。OEP值必定在这些值中。 让我们看一下API report。看dump窗口我们先前已经知道了指向report的指针12EB74。
0012EB74 01 00 00 00 98 03 00 00 ...?..0
0012EB7C D4 05 00 00 01 00 00 80 ?....0
0012EB84 00 00 00 00 00 00 00 00 ........
0012EB8C 97 A6 4B 00 02 00 00 00 棪K.[1]...B
0012EB94 00 00 00 00 97 A6 4B 00 ....棪K.0
0012EB9C 97 A6 4B 00 00 00 00 00 棪K.....B
0012EBA4 01 85 54 E1 10 01 00 00 匱?..54
太好了!在那儿我们至少看到了三次这个值: 4BA697。数学课告诉我4BA697比4BA000大,比4BAFFF小 (那些是父进程试图拷贝给子进程的那个块的起止值)所以我可以确信4BA697就是子进程的OEP。
[方法二],bpx SetProcessWorkingSetSize(使用DriverSuite2.7中的softice4.2.7)
标准的流程,下bpx SetProcessWorkingSetSize去找OEP 一旦softice中断了,检查softice是否在Get Right的领空,如果不在则按F5直到softice在Get Right 的领空中断。然后按F12辅之以F10跟踪过去一些指令,直到你看到一个"call edi"指令,停在那儿,然后写下edi的值。那就是OEP。
按三下F12 返回
……
001B:00981739 PUSH EAX
001B:0098173A CALL [009B1EA8] ;这个CALL进入
001B:00981740 MOV EAX,[EBP-1C]
……
……
001B:0109EEE2 XOR ECX,[EAX+6C]
001B:0109EEE5 XOR ECX,[EAX]
001B:0109EEE7 SUB EDI,ECX
001B:0109EEE9 CALL EDI ;到了这里,EDI的值就是OEP=004BA697
001B:0109EEEB MOV EBX,EAX
001B:0109EEED POP EDI
001B:0109EEEE MOV EAX,EBX
001B:0109EEF0 POP ESI
001B:0109EEF1 POP EBX
001B:0109EEF2 RET
注意:copy-mem II加壳方式找OEP有三种方法,标准加壳只有两种,标准加壳不能用CreateProcessA方法。因为只有copy-mem II加壳方式的父进程通过CreateProcessA产生另外一个进程即子进程。
上一页 1 2 3 下一页 |