【问题标题】:Trying to figure out the following disassembly listing试图找出以下反汇编清单
【发布时间】:2013-02-09 14:26:45
【问题描述】:

我正在 IDA pro 中查看 Win32 可执行文件的以下反汇编并获得 snwprintf 部分,但我不明白这里 mov ecx, [eax+4] 指令的目的(他们是否在这里丢弃了部分字符串?) .

loc_4018E7:
mov     eax, 0DEEDh
push    eax
push    offset asc_402270 ; "%X"
push    4               ; size_t no. chars
lea     ecx, [ebp+var_inpPassStr]
push    ecx             ; wchar_t * opBuffer
call    ds:_snwprintf   ; convert number to HEX string
add     esp, 10h
xor     edx, edx
mov     [ebp+var_8], dx
mov     eax, [ebp+arg_inpPass]
mov     ecx, [eax+4]
mov     [ebp+var_14], ecx
lea     edx, [ebp+var_inpPassStr]
push    edx             ; wchar_t *
call    ds:wcslen
add     esp, 4
mov     esi, eax
mov     eax, [ebp+var_14]
push    eax             ; wchar_t *
call    ds:wcslen
add     esp, 4
cmp     esi, eax
jnz     short loc_401984; this prints "invalid pass"

对此的任何见解都会很棒。

【问题讨论】:

  • call ds:wcslen 是通过数据段中的函数指针间接调用,对吧?所以在 NASM 语法中它将是 call [wcslen]?

标签: assembly x86 disassembly wchar-t ida


【解决方案1】:

这个

mov     eax, [ebp+arg_inpPass]
mov     ecx, [eax+4]

用函数参数的值(反汇编程序命名为arg_inpPass)加载eax,该值恰好是一个指针,然后取消引用它,跳过前4个字节。

如果不知道代码在做什么或查看更多代码,就不可能知道为什么会跳过前 4 个字节。可能是指针指向一个结构,而函数有兴趣访问其偏移量 4 处的成员。也可能是别的东西。

【讨论】:

    【解决方案2】:

    首先,ebp 在这个反汇编块中没有被设置,可能它在这个反汇编块之前已经完成了一些行。如果这是用汇编编写的,它可能指向其他地方而不是堆栈,因为它通常用于高级语言(C、C++ 等)。

    mov     eax, [ebp+arg_inpPass]    ; read a dword variable (it's a pointer)
                                      ; from the stack into eax
    mov     ecx, [eax+4]              ; use that pointer plus 4 to read a dword value
                                      ; from memory into ecx
    mov     [ebp+var_14], ecx         ; store the value read into ecx into
                                      ; a local variable (in the stack)
    

    【讨论】:

    • 它的使用方式几乎可以肯定这是启用帧指针编译的函数的一部分。反汇编程序在为 ebp 的偏移量选择像 arg_inPass 这样的名称时可能完全是错误的,但我对此表示怀疑。如果它在序言中看到通常的堆栈帧设置,它可能只会这样做。在这种情况下,它看起来甚至有足够的调试信息来命名 arg。
    【解决方案3】:
    mov     eax, [ebp+arg_inpPass]
    mov     ecx, [eax+4]
    mov     [ebp+var_14], ecx
    

    第一行,从 [ebp+arg_inpPass] 指向的地址加载 4 个字节(32 位或 DWORD)

    第二行从上一行地址加载32位值加4,意思是如果eax是12345678h,那么ecx变成地址1234567Ch指向的32位值

    第三行将ecx的值移动到[ebp+var_14]指向的地址,

    你确定第一行不是 LEA 指令吗?如果它真的是 mov 那么代码提供了一种访问用户提供的内存位置的方法。

    【讨论】:

    • 为什么任何理智的编译器都会使用lea eax, [ebp+arg_inPass] / mov ecx, [eax+4] 而不是mov ecx, [ebp+arg_inPass+4]?这是相同的寻址模式([base_reg + disp8])。
    • if eax is 12345678h, then ecx becomes 1234567Ch。错误的。 eax 被取消引用,eax 和 ecx 之间的区别取决于内存的内容。这是一个负载,而不是 LEA。 (和术​​语:使用“加载”而不是“提取”)
    • 更重要的是,仅仅解释每条指令本身的作用并不能帮助回答编译器为什么会使用它们的问题;即代码作为全局的一部分实际上在做什么。即使它是正确的,这也不是一个有用的答案。
    猜你喜欢
    • 2018-09-22
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    • 2010-10-10
    相关资源
    最近更新 更多