当我看到装配线时:
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
设置为。NULL
char *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,但有时您需要了解其余代码中使用的类型以正确转换它。