反向工程代码似乎毫无意义

时间:2018-01-30 00:07:59

标签: assembly x86 reverse-engineering

我正在对一些代码进行逆向工程,并且遇到了一些似乎没有意义的代码

例如

push 0x3C2D1C06
mov [esp], ebx
mov[esp], edx
mov dword ptr[esp], 0x7D0B46E7`

这背后是否有逻辑,或者这是源于编译器生成的东西。在我看来,这将与

相同

push 0x7D0B46E7

另一个例子是

pusha
push ecx
pop ecx
pusha
popa
popa
push eax
push edx
rdtsc
pusha
popa
pop edx
pop eax

我不理解所有推/弹组合

编辑:

我现在真的很感兴趣了。我不得不相信这是少数几个来源之一:

1。)如前所述,这可能是为了掩盖逆向工程

2。)某种形式的优化超出了我的头脑(我很难看到这个)

3.)某种形式的编译器操作可能链接可能的多平台库或其他东西

我确信代码被正确反汇编,因为序列可能是奇怪的,不会破坏堆栈等。我很好奇某些序列,如

push edi
push eax
push eax
mov eax, 0x577D25CD
mov [esp], eax
push eax
pop edi
and edi, 0x3F7BEBDC
shl edi, 0x3
xor edi, 0x6E778451
sub edi, 0x0D5BE8A31
mov ebx, edi
push [esp]
pop edi

开始
push edi
push eax
push eax
mov eax, 0x577D25CD
mov [esp], eax
pop eax
pop edi

我认为和写作一样

push edi
push 0x577D25CD
pop edi

或者甚至

push edi
mov edi, 0x577D25CD

但更令人困惑的是,

and edi(0x577D25CD), 0x3F7BEBDC ->edi=0x177921CC

shl edi(0x177921CC), 3 ->edi=0xBBC90E60

xor edi(0xBBC90E0), 0x6e778451 -> edi=0xD5BE8A31

sub edi(0x0D5BE8A31), 0x0D5BE8A31 -> edi=0x0

mov ebx, edi

所以可以用

代替

mov ebx, 0x0xor ebx, ebx

所以这给我留下了一些新问题。对于一种逆向工程保护形式,这一点是否更加坚定,是否有工具可以做到这一点。是否有任何其他逻辑上的原因来执行这样的流。是否公平地假设编译器不会执行操作来设置ESP以下的值,我没有发现使用ESP下面的任何值的迹象

最后几点,我已经开始将代码提炼到有效的结果,到目前为止,一切都像以前一样工作,我已经删除了 超过200bytes的代码。这进一步指出了我正确解释代码的想法。我也发现很难相信错误的反汇编代码会产生一系列xor,并且shl操作完全等于0x00

编辑2:

我可以肯定地说这是我正在解释的代码。我专注于一个部分,我在我的第一个编辑中发布了一部分,当我通过86 asm指令排序时,我发现结果只是这个

start:
 test ebx, ebx
 jz end
 add [eax], ecx
 add eax, 0x04
 sub ebx, 0x1
 jmp start
end:

其余的如前所述" clobbering"特别是推送,弹出,xchgs和算术组合的堆栈。有时类似于add esp, 0x4然后mov [esp], eaxpush eax相同。最后我完成的部分是通过Image_Base来抵消地址数组,这是一种重新定位的形式我猜。当我查看重定位的地址时,它们指向代码段,看起来像程序的开始。我很难看到有人编写了数千行代码,这些代码似乎让我感到奇怪......

有没有人知道这样做的工具。是否有人创建了一个程序,它接受代码并用废话掩盖它以防止逆向工程。

1 个答案:

答案 0 :(得分:1)

这些指令序列最合理的来源是它们被手工制作为混淆,可能是inline-asm。

正如我之前评论过的那样,如果是这样的话,那么这段代码就完全符合预期的工作:它使你感到困惑/困惑,并导致你花费大量时间而不仅仅是逆向工程实际的程序逻辑。

这些序列都没有崩溃或弄乱堆栈这一事实清楚地表明,它绝对不会意外地将数据作为代码执行。

您在此代码中实际设置断点以查看实际执行的测试在此处也很有用。反汇编输出包含存储在代码段中的一些数据并不罕见。但是看到它被执行,我们知道它不仅仅是数据。

  

2。)某种形式的优化超出了我的头脑(我很难看到这个)

你对这个想法持怀疑态度,但是你总是需要考虑这种可能性。

有时存在次优代码,因为有人认为它快,至少在某些特定的CPU上。但这在这里甚至都不合理。我无法相信任何人会认为这些长卷曲序列在任何x86 CPU上都会比xor ebx,ebxpush imm32mov r32, imm32更快。这些说明都是快速的,并且相当于push imm32的序列实际使用一个push imm32 +一些死商店,所以它是显然没有试图避免push imm32某个假设的CPU那个指令很慢。

特别是在NOP情况下,零指令总是更好。如果需要填充,英特尔和AMD会发布推荐的长NOP序列,这些序列的开销最小。 pusha / popa在所有内容上都很慢,很明显他们做了很多工作,所以有人故意将它们用作填充,这没有任何意义。< / p>

除了混淆之外,另一个看似合理的目的是故意拖延。这是一种性能原因,但如果时间是程序正确性的一部分,那么这样的固定序列并不是在一系列不同的x86微体系结构中实现它的可靠方法!

但是我可以相信,其中一些/所有这些都是错误的实施,并在这里浪费了几个周期&#34;。特别是pusha / popa在很少的指令字节中花费了很多时间。

  

有没有人知道这样做的工具。是否有人创建了一个程序,它接受代码并用废话掩盖它以防止逆向工程。

好问题。插入疯狂的NOP或将push imm32xor - 归零为模糊序列是工具可能自动执行的操作。但通常你想避免在任何对整体性能有重要影响的循环中,所以IDK。