当我看到装配线时:
MOV ESI, DWORD PTR DS:[EBP+0x8]
而且,当 Ollydbg 向我展示那个时[EBP+0x8] = 00000000,我可以像这样用 C 编写它:
int *esi = NULL;
或者,我应该使用堆栈地址EBP + 0x8是0x0012FF43与写一样的东西:
int *esi = &0012FF43
我会说第一个是正确的答案,但我对此感到非常困惑。
当我看到装配线时:
MOV ESI, DWORD PTR DS:[EBP+0x8]
而且,当 Ollydbg 向我展示那个时[EBP+0x8] = 00000000,我可以像这样用 C 编写它:
int *esi = NULL;
或者,我应该使用堆栈地址EBP + 0x8是0x0012FF43与写一样的东西:
int *esi = &0012FF43
我会说第一个是正确的答案,但我对此感到非常困惑。
括号的意思是“内容”......所以它更像是:
int esi = 0;
-或者-
int esi = *(ebp+8); /* assuming ebp is correct */
-或者-
int esi = (int)*(ebp+8); /* assuming ebp is (void*) or (char*)
we need to pull 4 bytes to get value */
我希望(EBP+0x8)会不会是0x12FF43,因为堆栈指针应该对齐到4个或8个字节的地址(4对32位CPU的,8 64位,一般为16个字节的64位,虽然对齐)。
奇怪的是看到DS:EBP 寄存器的修饰符,因为它通常是SS:,只有当DS=SS或两者都是时才有效0。吹毛求疵,但你必须在接近金属的时候演奏。
[EBX+8]是dword此堆栈帧的第二个变量。如果它被放入esi它可能是一个指针操作所以可能memcpy(dest,src,0x100)会包括该行 if在被声明之后
src设置为。NULLchar *src = argument;
这是最现实的,因为您通常不会直接从 C 访问 esi。
当然在我的例子中,memcpy当NULL被取消引用时会出现段错误。
我认为这里有一个误解。ESI是寄存器而不是变量,所以:
int *esi = NULL;
如果你想esi在 C 中赋值,你应该使用内联汇编括号asm {}。
此外,通常在 OllyDbgMOV ESI, DWORD PTR DS:[EBP+0x8]行中出现这样的函数的开头:
push ebp
mov ebp, esp
push esi
mov esi, [ebp +8]
...
这意味着esi将获得函数的第一个参数的指针。因此,要使用 C 语言编写代码行,您应该编写一个至少带有一个参数的函数。您传递给此函数的第一个参数将是 value of esi。
MOV ESI, DWORD PTR DS:[EBP+0x8]
从加载4个字节EBP+0x8成ESI。
ESI除非[EBP+0x8]持有地址,否则不会成为指针,因此在不知道这一点的情况下,您无法真正知道是否应该设置ESI为NULL.
它有助于在阅读汇编时将每一行转换为 C,但有时您需要了解其余代码中使用的类型以正确转换它。