首页 > 解决方案 > 这个汇编代码是做什么的,C 代码会是什么样子?

问题描述

我正在尝试反汇编一个文件,其中一个部分包含此文件。这是在做什么?在 C 中会是什么样子?

我相信它将 40 复制到 ebp-8 并将 20 复制到 ebp-4。然后它调用 func: 函数。通过将 edx 添加到 eax 然后从中减去 4 来执行一些命令。在它退出 func: 函数后,它将 8 添加到 esp。我在正确的轨道上吗?

func:
push ebp
mov ebp, esp
mov edx, DWORD PTR [ebp+8]
mov eax, DWORD PTR [ebp+12]
add eax, edx
sub eax, 4
pop ebp
ret
main:
push ebp
mov ebp, esp
sub esp, 16
mov DWORD PTR [ebp-8], 40
mov DWORD PTR [ebp-4], 20
push DWORD PTR [ebp-4]
push DWORD PTR [ebp-8]
call func
add esp, 8
leave
ret

编辑:那么您是否同意 C 的结果如下?

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

int func(int d, int e)
{
    int sum = d + e;
    int result = sum - 4;
    return result;
}

int main(void)
{
    int a = 40;
    int b = 20;
    int c = func(a,b);
    printf("Result is: %d\n", c);
}

标签: assemblyx86reverse-engineeringdisassembly

解决方案


分解后,代码如下所示:

func:
; enter 0, 0
push ebp
mov ebp, esp
; entered func with no local variables

; get first param in edx
mov edx, DWORD PTR [ebp+8]
; get second param in eax
mov eax, DWORD PTR [ebp+12]

add eax, edx    ; eax += edx
sub eax, 4      ; eax -= 4

; to avoid segfault, you should first `mov esp, ebp` 
; but works here, since ESP was not changed, so getting back ESP's old value is not required
pop ebp
ret

main:
; enter 16, 0
push ebp
mov ebp, esp
sub esp, 16    ; adds 4 elements on the stack
; entered main with 4 local variables on stack

; writing on 2 local variables
mov DWORD PTR [ebp-8], 40
mov DWORD PTR [ebp-4], 20

; push 2 params on the stack and call `func`
push DWORD PTR [ebp-4]    ; second param
push DWORD PTR [ebp-8]    ; first param
call func                 ; calls `func(first, second)`, returns EAX = 56

; delete 2 elements off the stack
add esp, 8

; leave entered function (get back ESP from before entering)
leave

; return to caller
ret

我认为根据注释中的解释(用 标记;),您自己应该很容易将其翻译成 C 代码。


编辑:正如 Peter Cordes 所指出的,Assembly 不知道任何数据类型,例如intor long int。在 x86 汇编中,您使用通用寄存器并使用 C 约定,在 中返回任何 32 位值EAX,而在 中返回 64位值EDX:EAX,这意味着 的内容EDX将是高 32 位。

但是如果main标签是int main()C 中的经典函数和程序的入口点,我们可以假设,在 C 中func看起来也一样int func(int p1, int p2),我相信,因为返回EDX的从未使用过,并且函数似乎以56 inint main()结尾。return 56;EAX


推荐阅读