|
E DX 又一次指向了report,让我们看看那儿有什么。

又是80000003 这个值,然后是新的INT 3的地址值在40622E。 这回下来那一行的跳转跳了,跳过了tables被解码的代码段。
当我们停在GetThreadContext我们看到它给子进程赋EIP值为40622F,标志寄存器的值是246。

正如我们从PUSH ECX看到的,这次INT 3类型号是06。

进入CALL 去研究INT 3类型号为 06的跳转的类型。
到达我们曾经标记过的地方。

在第二行付给EAX标志寄存器的值246,所以这将是一个条件跳转。这一行暗示标志寄存器的值将回被检测。
005C75DB |。 83E0 40 AND EAX,40
让我们看看40对于标志寄存器的意义。这次父进程标志寄存器的值EFL为287。我把它写下来,因为一会儿会用到的。

右击鼠标把它改为40。我可以看到标志已经改变了。

Z 是唯一起作用的标志,所以如果我们把任何一个值和40相“与” ,只有当两个操作数都为1时结果才为1,40的二进制如图,只有当另一个操作数对应位为1或者同样的Z标志时结果才不为0, 因为在40中其它位的值都为0。
这样的解释很抽象,还是看图比较清楚一点。


这个跳转只取决于标志的状态,如果跳则是JZ,如果不跳则是JNZ。如果我们稍加跟踪在最后一行EAX=1,所以它一定是 JZ 或则 JE。我测试了所有的INT 3 类型号对应的跳转类型,得出下表。
INT 3 类型号对应的跳转类型表
|
Value |
Jump |
Hexa Value |
|
1 |
JO |
70 |
|
2 |
JNS |
79 |
|
3 |
JNL |
7D |
|
4 |
JMP |
EB |
|
5 |
JNC |
73 |
|
6 |
JE/JZ |
74 |
|
7 |
JNA |
76 |
|
8 |
JS |
78 |
|
9 |
Don’t Know |
|
|
A |
JNE |
75 |
|
B |
JNO |
71 |
|
C |
JA |
77 |
|
D |
JP |
7A |
|
E |
JNP |
7B |
|
F |
JG |
7F |
|
10 |
Don’t Know |
|
|
11 |
Special Case |
|
漏掉了一些跳转,它们在这个软件中没有被使用。11H号是一个很特殊的号,因为跳转与否取决于和11的比较,如果为真则跳向循环尾部,并修改EAX为0,所以它变成了NOP。
005C74FA |。 837D F4 11 CMP DWORD PTR SS:[EBP-C],11
我们找到了Table 2 和跳转类型的关系,我们可以很容易的扫清一切道路。把我们先前记下的值重新写入EFL,我的机器里是 287,走出那个call 然后我们到达 test。
005C5EF5 > 。 85C0 TEST EAX,EAX
EAX 的值为1 所以它跳了。在Table 3 中找它跳向何方。我忘记提醒了,如果这里不跳,则它前往一个循环,在那里它读取Table 4获得它该跳向何方。
005C5EF9 。 8B95 20F3FFFF MOV EDX,DWORD PTR SS:[EBP-CE0]
在第一行把位移2B 赋给EDX,在接下来的一行 EAX 指向Table 3的起始值。
005C5EFF 。 A1 881A5E00 MOV EAX,DWORD PTR DS:[5E1A88]
这一行把子进程中INT 3的EIP 40622F和 Table 3 对应于这个INT 3的值27相加。新的 EIP是EIP=406256
我们可以在子进程中写入JE 406256。

这些就是子进程中被修复的INT 3。我们可以从Table 1中找到跳转的首字节, 然后我们前往Table 2找对应的值,第二个字节是table 3 中的值减去1。
如果你记住这一点,你将会看到对应于第一个INT 3 Table 3中的值是0000004 ,只取04 然后减1,所以变为03 这就是第二个字节 03 。
第二个INT 3,Table 3中对应值为 00000027 27-1=26 所以第二个字节是26。
所以我们可以修复所有的INT 3,第一个字节到“INT 3 类型号对应的跳转类型表”中去找对应值,然后第二个字节到Table 3中去找对应值。我希望你看懂了这篇教程,因为在第二部分我们将打patch代码让它自动修复。
原著:Ricardo Narvaja
翻译:FTBirthday
译者注:
一字一句翻译好累,还得理解,用准用好每一个词,希望对大家有帮助。 上一页 1 2 3 4 5 6 |