bsd*_*anm 2 c x86 assembly decompiling reverse-engineering
此代码将字符串的每个字符(位于ebp+arg_0)与不同的常量(ASCII 字符)进行比较,例如“I”、“o”和“S”。我猜,基于其他代码部分,这段代码最初是用 C 编写的。

这个比较代码部分看起来效率很低。我的问题是,你认为这段代码在 C 中看起来如何?最初使用什么代码结构?到目前为止我的想法
这不是for 循环。因为我没有看到任何向上跳跃和停止条件。
这不是一个 while/case/switch 代码构造
我最好的猜测是,这是很多连续的 if/else 语句。你能帮我吗?
是的,这是挑战的一部分,我已经有了标志/解决方案,不用担心。只是想更好地理解代码。
这不是 for 循环。因为我没有看到任何向上跳跃和停止条件。
正确的。
这不是 while/case/switch 代码构造
不可能,它比较了数组的不同索引。
我最好的猜测是,这是很多连续的 if/else。你能帮我吗?
看起来可能是这样的代码:
void f(const char* arg_0) {
if(arg_0[4] == 'I' && arg_0[5] == 'o' && arg_0[6] == 'S') {
printf("Gratz man :)");
exit(0); //noreturn, hence your control flow ends here in the assembly
}
puts("Wrong password"); // Or `printf("Wrong password\n");` which gets optimized to `puts`
// leave, retn
}
Run Code Online (Sandbox Code Playgroud)
.LC0:
.string "Gratz man :)"
.LC1:
.string "Wrong password"
f(char const*):
push ebp
mov ebp, esp
sub esp, 8
mov eax, DWORD PTR [ebp+8]
add eax, 4
movzx eax, BYTE PTR [eax]
cmp al, 73
jne .L2
mov eax, DWORD PTR [ebp+8]
add eax, 5
movzx eax, BYTE PTR [eax]
cmp al, 111
jne .L2
mov eax, DWORD PTR [ebp+8]
add eax, 6
movzx eax, BYTE PTR [eax]
cmp al, 83
jne .L2
sub esp, 12
push OFFSET FLAT:.LC0
call printf
add esp, 16
sub esp, 12
push 0
call exit
.L2:
sub esp, 12
push OFFSET FLAT:.LC1
call puts
add esp, 16
nop
leave
ret
Run Code Online (Sandbox Code Playgroud)
看起来与您的反汇编代码非常相似。
这个比较代码部分看起来效率很低
看起来它是在没有优化的情况下编译的。启用优化后,gcc 将代码编译为:
.LC0:
.string "Gratz man :)"
.LC1:
.string "Wrong password"
f(char const*):
sub esp, 12
mov eax, DWORD PTR [esp+16]
cmp BYTE PTR [eax+4], 73
jne .L2
cmp BYTE PTR [eax+5], 111
je .L5
.L2:
mov DWORD PTR [esp+16], OFFSET FLAT:.LC1
add esp, 12
jmp puts
.L5:
cmp BYTE PTR [eax+6], 83
jne .L2
sub esp, 12
push OFFSET FLAT:.LC0
call printf
mov DWORD PTR [esp], 0
call exit
Run Code Online (Sandbox Code Playgroud)
不知道为什么 gcc 决定跳下来并再次备份而不是直线jnes。此外, theret不见了,你printf得到了尾调用优化,即 a jmp printfi 而不是 acall printf后跟 a ret。