我刚开始看这本书 实用逆向工程 由Bruce Dang等人所著,对第一章最后的一部分 "演练 "感到困惑。这就是相关部分代码。
65: ...
66: loc_10001d16:
67: mov eax, [ebp-118h]
68: mov ecx, [ebp-128h]
69: jmp short loc_10001d2a (line 73)
70: loc_10001d24:
71: mov eax, [ebp+0ch]
72: mov ecx, [ebp+0ch]
73: loc_10001d2a:
74: cmp eax, ecx
75: pop esi
76: jnz short loc_10001D38 (line 82)
77: xor eax, eax
78: pop edi
79: mov esp, ebp
80: pop ebp
81: retn 0ch
82: ...
以及作者的注释:
"循环退出后,在第66行重新开始执行。第67-68行保存匹配的
PROCESSENTRY32
’sth32ParentProcessID/th32ProcessID
在EAX/ECX
并在73行继续执行。注意66行也是43行的跳转目标。 第70-74行读取fdwReason
的参数DllMain
(EBP+C
),并检查其是否为0 (DLL_PROCESS_DETACH
). 如果是,则将返回值设为0,并返回;否则,转到第82行。"
我在阅读代码时不是这样理解的,肯定是任何跳转至 loc_10001d24
(第70行)将导致函数终止,返回值为0。无条件的值,而且不仅是在 ebp+0x0c
是0?(我假设 pop
进入 esi
不影响 eflags
寄存器,并且第76行的跳转条件是在 cmp eax, ecx
在第74行?) 这也与代码中前面的部分一致,这些部分跳转到了 loc_10001d24
如果各种被调用的函数返回的值表示失败。
此外,我认为从第66行开始的这一节的重点是,如果在以下情况下,也用0值返回 PROCESSENTRY32
(前面定义的结构,从 ebp-0x130
在内存中)相当于 th32ParentProcessID
(ebp-0x118
记忆中的)和 th32ProcessID
(ebp-0x128
在记忆中)的条目;这是否正确?作者的评注似乎没有说明这一点。
作为一个更普遍的问题,即使只是本书的第1章似乎也有相当多的错别字;有谁知道哪里有收集该书勘误表的网页?
是的,ECX和EAX都是从同一个内存位置加载的,所以除非有其他东西有指针指向它,并且异步改变它。cmp x,x
jne
将永远是不取值。 与浮点不同,任何可能的整数都等于自己。
你说的没错。pop
不改变EFLAGS,根据Intel的手册。https:/www.felixcloutier.comx86pop.
要检查一个内存位置是否为零,你可以将它加载到一个reg中,以便于进行 test eax,eax
jnz
或 cmp dword ptr [ebp + 0xc], 0
jne
.
(JNE和JNZ是同一条指令,不同的口令让你在ZF根据值本身设置的基础上,表达出平等或直接为0的语义)。
第70-74行读取DllMain(EBP+C)的fdwReason参数,并检查其是否为0(DLL_PROCESS_DETACH)
这是假的。 如果书中都是这样的东西,那就不像是一本好书。
那... cmp eax,ecx
只有从加载了2个不同值的路径到达时才有意义。 (而且不能使用 test
为此。x & y != 0
并没有告诉你它们是否相等)。) 这似乎不太可能是真正的编译器输出。