我正在对一些代码进行逆向工程,并且遇到了一些似乎没有意义的代码
例如
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, 0x0
或xor 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], eax
与push eax
相同。最后我完成的部分是通过Image_Base来抵消地址数组,这是一种重新定位的形式我猜。当我查看重定位的地址时,它们指向代码段,看起来像程序的开始。我很难看到有人编写了数千行代码,这些代码似乎让我感到奇怪......
有没有人知道这样做的工具。是否有人创建了一个程序,它接受代码并用废话掩盖它以防止逆向工程。
答案 0 :(得分:1)
这些指令序列最合理的来源是它们被手工制作为混淆,可能是inline-asm。
正如我之前评论过的那样,如果是这样的话,那么这段代码就完全符合预期的工作:它使你感到困惑/困惑,并导致你花费大量时间而不仅仅是逆向工程实际的程序逻辑。
这些序列都没有崩溃或弄乱堆栈这一事实清楚地表明,它绝对不会意外地将数据作为代码执行。
您在此代码中实际设置断点以查看实际执行的测试在此处也很有用。反汇编输出包含存储在代码段中的一些数据并不罕见。但是看到它被执行,我们知道它不仅仅是数据。
2。)某种形式的优化超出了我的头脑(我很难看到这个)
你对这个想法持怀疑态度,但是你总是需要考虑这种可能性。
有时存在次优代码,因为有人认为它会快,至少在某些特定的CPU上。但这在这里甚至都不合理。我无法相信任何人会认为这些长卷曲序列在任何x86 CPU上都会比xor ebx,ebx
,push imm32
或mov r32, imm32
更快。这些说明都是快速的,并且相当于push imm32
的序列实际使用一个push imm32
+一些死商店,所以它是显然没有试图避免push imm32
某个假设的CPU那个指令很慢。
特别是在NOP情况下,零指令总是更好。如果需要填充,英特尔和AMD会发布推荐的长NOP序列,这些序列的开销最小。 pusha
/ popa
在所有内容上都很慢,很明显他们做了很多工作,所以有人故意将它们用作填充,这没有任何意义。< / p>
除了混淆之外,另一个看似合理的目的是故意拖延。这是一种性能原因,但如果时间是程序正确性的一部分,那么这样的固定序列并不是在一系列不同的x86微体系结构中实现它的可靠方法!
但是我可以相信,其中一些/所有这些都是错误的实施,并在这里浪费了几个周期&#34;。特别是pusha
/ popa
在很少的指令字节中花费了很多时间。
有没有人知道这样做的工具。是否有人创建了一个程序,它接受代码并用废话掩盖它以防止逆向工程。
好问题。插入疯狂的NOP或将push imm32
或xor
- 归零为模糊序列是工具可能自动执行的操作。但通常你想避免在任何对整体性能有重要影响的循环中,所以IDK。