从给定的x86程序集编写一个C函数 [英] Writing a C function from given x86 assembly

查看:155
本文介绍了从给定的x86程序集编写一个C函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图扭转这个神秘功能。
这个函数返回一个整数,并将一个struct节点作为参数

  #includemystery.h
int mystery(struct e4_struct * s){}

头文件是一个简单的struct声明

  struct my_struct {
int a;
int b;
};

我想要反向工程的程序集是
$ b $ (%rax,%rax,2),%eax
40059b:89 07 mov%eax,(%rdi)
40059d:83 47 04 07 addl $ 0x7,0x4(%rdi)
4005a1:c3 retq



到目前为止,我认为这个函数就像:

  int mystery(struct m_struct * s){
int i = s-> a;
i = 3 * i;
int j = s-> b;
j + = 7;
返回i;
}

但这是不正确的。我不明白什么 mov%eax,(%rdi)完全相同,并且函数返回的结果是因为它应该返回并且是整数。

解决方案

由于 RDI 是指向结构开始的指针(函数的第一个参数)下面一行是获取 s-> a 的值并将其放入临时寄存器 EAX 中。

  mov(%rdi),%eax 

合理的可能是 int x = s-> a 。这一行:

  lea(%rax,%rax,2),%eax 

与从RAX + RAX * 2 = 3 * RAX(因此s-> a * 3)开始,将温度值乘以3相同。因此,前两行的程序集可以表示为:

  int x = s-> a * 3; 

mov%eax,(%rdi)将取临时值 x 并将其存储回s-> a以便可以表示为:

  s-> a = x; 

addl $ 0x7,0x4(%rdi)将4添加到7(RDI)。 4(RDI)是s-> b的地址。这条线可以表示为 s-> b + = 7;

一个值?由于在上面分析的代码之后没有其他的东西用于EAX ,所以EAX 仍然是我们前面做的 x = s-> gt时的值; a * 3; 。这意味着函数返回临时值 x



然后代码如下所示: p>

  int mystery(struct my_struct * s)
{
int x = s-> a * 3;
s-> a = x;
s-> b + = 7;
return x;

$



如果你在

优化级别, 神秘:
movl(%rdi),%eax
leal(%rax,%rax, 2),%eax
movl%eax,(%rdi)
addl $ 7,4(%rdi)
ret

具有不同优化级别的不同编译器会生成不同的程序集,这些程序集都会执行相同的操作。 GCC 4.9.x恰好可以产生我们最初反向设计的精确汇编代码。




注意:由于最近发布了 SO问题与我找到的 mystery 函数不同具有优化级别 -O1 的GCC 4.9.x生成了我正在寻找的确切代码。看起来,为这些神秘练习生成装配文件的人使用了这样的设置和类似的编译器。


I'm trying to reverse engineer this mystery function. This function returns an integer and takes a struct node as an argument

#include "mystery.h"
int mystery(struct e4_struct *s){}

The header file is a simple struct declaration

struct my_struct {
    int a;
    int b; 
};

The assembly I'm trying to reverse engineer is

400596:    8b 07                    mov    (%rdi),%eax
400598:    8d 04 40                 lea    (%rax,%rax,2),%eax
40059b:    89 07                    mov    %eax,(%rdi)
40059d:    83 47 04 07              addl   $0x7,0x4(%rdi)
4005a1:    c3                       retq  

So far I think the function is like:

int mystery(struct m_struct *s){
    int i = s->a;
    i = 3*i;
    int j = s->b;
    j += 7;
    return i;
}

But this isn't correct. I don't understand what mov %eax,(%rdi)does exactly and what the function returns in the end because its supposed to return and integer.

解决方案

Given that RDI is the pointer to the beginning of the structure (first parameter of function) the following line is getting the value of s->aand placing it in a temporary register EAX.

mov    (%rdi),%eax

Reasonably that might be int x = s->a. This line:

lea    (%rax,%rax,2),%eax

Is the same as multiplying the temp value by 3 since RAX+RAX*2=3*RAX (thus s->a * 3). So the first two lines of assembly could be represented as:

int x = s->a * 3;

The line mov %eax,(%rdi) would be taking the temporary value x and storing it back to s->a so that could be represented as:

s->a = x;

The line addl $0x7,0x4(%rdi) is adding 7 to the value at 4(RDI). 4(RDI) is the address of s->b. This line could be represented as s->b += 7;.

So what is being returned as a value? Since nothing else is done with EAX after the code analyzed above, EAX is is still the value it had earlier when we did x = s->a * 3;. This means that the function is returning the temporary value x.

The code then would look like this:

int mystery(struct my_struct *s)
{
    int x = s->a * 3;
    s->a = x;
    s->b += 7;
    return x;    
}

If you compile this code with GCC 4.9.x on godbolt with -O1 optimization level we get this generated assembly:

mystery:
        movl    (%rdi), %eax
        leal    (%rax,%rax,2), %eax
        movl    %eax, (%rdi)
        addl    $7, 4(%rdi)
        ret

Different compilers with different optimizations levels will produce different assembly that will all do the same thing. GCC 4.9.x just so happens to produce the exact assembly code we originally reverse engineered.


Note: I guessed on the version of compiler and optimization level because of a recent SO question with a different mystery function where I had found GCC 4.9.x with optimization level -O1 generated the exact code I was looking for. It seems whoever generated the assembly files for these mystery exercises was using such settings and similar compiler.

这篇关于从给定的x86程序集编写一个C函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆