gpt4 book ai didi

c - 从汇编逆向工程优化的 C 代码

转载 作者:太空狗 更新时间:2023-10-29 17:09:56 25 4
gpt4 key购买 nike

这个问题的重点是对运行具有 2 级优化的编译器后生成的 C 代码进行逆向工程。原c代码如下(计算最大公约数):

int gcd(int a, int b){
int returnValue = 0;
if (a != 0 && b != 0){
int r;
int flag = 0;
while (flag == 0){
r = a % b;
if (r ==0){
flag = 1;
} else {
a = b;
b = r;
}
}
returnValue = b;
}
return(returnValue);
}

当我运行优化编译时,我从命令行运行了这个:

gcc -O2 -S Problem04b.c

获取此优化代码的程序集文件

.gcd:
.LFB12:
.cfi_startproc
testl %esi, %esi
je .L2
testl %edi, %edi
je .L2
.L7:
movl %edi, %edx
movl %edi, %eax
movl %esi, %edi
sarl $31, %edx
idivl %esi
testl %edx, %edx
jne .L9
movl %esi, %eax
ret
.p2align 4,,10
.p2align 3
.L2:
xorl %esi, %esi
movl %esi, %eax
ret
.p2align 4,,10
.p2align 3
.L9:
movl %edx, %esi
jmp .L7
.cfi_endproc

我需要将此汇编代码转换回 C 代码,这是我现在所在的位置:

int gcd(int a int b){
/*
testl %esi %esi
sets zero flag if a is 0 (ZF) but doesn't store anything
*/
if (a == 0){
/*
xorl %esi %esi
sets the value of a variable to 0. More compact than movl
*/
int returnValue = 0;
/*
movl %esi %eax
ret

return the value just assigned
*/
return(returnValue);
}
/*
testl %edi %edi
sets zero flag if b is 0 (ZF) but doesn't store anything
*/
if (b == 0){
/*
xorl %esi %esi
sets the value of a variable to 0. More compact than movl
*/
int returnValue = 0;
/*
movl %esi %eax
ret

return the value just assigned
*/
return(returnValue);
}

do{
int r = b;
int returnValue = b;

}while();


}

谁能帮我把它写回 C 代码?我几乎迷路了。

最佳答案

首先,您的代码中混合了这些值。 %esi以值 b 开头和 %edi以值 a 开头.

testl %edx, %edx可以推断行 %edx用作以 .L7 开头的循环的条件变量(如果 %edx 与 0 不同,则控制转移到 .L9 block ,然后返回到 .L7 )。我们会引用%edx作为remainder在我们的逆向工程代码中。


让我们开始对主循环进行逆向工程:

movl    %edi, %edx

%edi商店 a , 这相当于初始化 remainder 的值与 a : int remainder = a; .

movl    %edi, %eax

店铺 int temp = a;

movl    %esi, %edi

执行 int a = b; (记住 %edia%esib)。

sarl $31, %edx

这个算术移位指令将我们的 remainder 移位向右可变 31 位,同时保持数字的符号。通过移动 31 位,您正在设置 remainder如果为正(或零)则为 0,如果为负则为 -1。所以它相当于remainder = (remainder < 0) ? -1 : 0 .

idivl %esi

划分%edx:%eax通过 %esi ,或者在我们的例子中,除以 remainder * temp通过 b (变量)。 剩余 将存储在 %edx 中,或者在我们的代码中,remainder .将其与之前的指令结合使用时:if remainder < 0然后remainder = -1 * temp % b , 否则 remainder = temp % b .

testl   %edx, %edx
jne .L9

检查是否remainder等于 0 - 如果不是,跳转到 .L9 .那里的代码只是设置 b = remainder;在回到 .L7 之前.为了在 C 中实现这一点,我们将保留一个 count。将存储循环迭代次数的变量。我们将执行 b = remainder在循环的开始但仅在第一次迭代之后,意思是当 count != 0 时.

我们现在准备构建完整的 C 循环:

int count = 0;
do {
if (count != 0)
b = remainder;
remainder = a;
temp = a;
a = b;
if (remainder < 0){
remainder = -1 * temp % b;
} else {
remainder = temp % b;
}

count++;
} while (remainder != 0)

循环结束后,

movl    %esi, %eax
ret

将返回程序计算的 GCD(在我们的代码中它将存储在 b 变量中)。

关于c - 从汇编逆向工程优化的 C 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28611361/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com