如何解决这个反反汇编技巧?

逆向工程 艾达 C 反调试
2021-07-08 20:47:10

我在 C 代码中有这个 __asm 指令:

int func_0x8b4c55a0()
{
    __asm
    {
        call $ +5
        add[esp],5
        ret
    }

}
int main()
{
    char cVar1;
    if ((cVar1 = func_0x8b4c55a0(), cVar1 == -0xe) || 1)
    {
        int a = 5;
        int b = 3;
        int c = 0;
        c = a + b;
    }
    return 0;
}

这就是它在 IDA 中的样子: 在此处输入图片说明

怎么可能解决这个ret把戏?

2个回答

我不确定“解决”这个问题是什么意思,但代码的含义很明显,在您提供的屏幕截图中更是如此。简化版:

call $+5
add [esp], 5
ret
xor eax, eax
ret

并带有注释:

_main:
  call $+5     ; call address of next instruction, placing return address on stack (esp)
  add [esp], 5 ; add 5 bytes to the return address
  ret          ; return to the address from the stack ... which happens to be
  xor eax, eax ; ... this instruction
  ret          ; return for good from _main ...

所以它所做的就是从_main.

鉴于(反编译)条件:

if ((cVar1 = func_0x8b4c55a0(), cVar1 == -0xe) || 1)

... 然而,这不会改变任何事情,因为|| 1将确保此条件始终为真,cVar1并且随后不会被使用。

因此,就您提供的上下文而言,这纯粹是分散注意力。

在条件语句中

if ((cVar1 = func_0x8b4c55a0(), cVar1 == -0xe) || 1)

CVar1 被初始化,然后被评估

func_0x8b4c55a0() 返回随机垃圾(基本上它会在调用函数之前返回 eax 寄存器中的内容

现在这可以是 -0xe 或从 0x0 到 0xffffffff 的任何其他内容

因此 if 将导致 True 或 False 并且 or (||) 运算符将始终使其成为 TRUE

所以所有本地人 a,b,c 都将被初始化和评估

但看起来您的二进制文件是在启用优化的情况下编译的,
并且所有这些死代码都已消除,并且
__asm 功能块已内联到您的 main() 中。

所以基本上你可以简单地排除整个垃圾块。