我在IDA中看到了很多输入和输出指令。我知道这些命令应该做什么,但是我不知道如何对待它们,并且在理解代码方面也没有任何进展。

简短的示例:
我当前的第一条说明作业是:

seg000:00000000                 mov     edx, 61666A1Fh
seg000:00000005                 fincstp
seg000:00000007                 fnstenv byte ptr [esp-0Ch]
seg000:0000000B                 pop     esi             ; EIP
seg000:0000000C                 sub     ecx, ecx
seg000:0000000E                 mov     cl, 33h ; '3'
seg000:00000010                 xor     [esi+12h], edx
seg000:00000013                 add     edx, [esi+12h]  ; 
seg000:00000016                 xor     ecx, 0FFFFFF96h
seg000:00000019                 test    [ecx+esi*8+957C08Fh], dl
seg000:00000020                 push    eax             ; ??????
seg000:00000021                 mov     bl, 0DEh ; '¦'
seg000:00000023                 in      al, dx
seg000:00000024                 popa
seg000:00000025                 loope   near ptr 0FFFFFFACh


我第一次遇到FPU指令时就迷失在05h-0Bh上,但我认为ESI应该指向哪里EIP指向。

我的主要问题是关于23h

in al, dx


应该从端口AL加载6A1Fh中的一个字节吗?这有什么关系吗?还是这样的代码会使我的工作更加努力或隐藏某些东西?也许它是加密的,并且在某个时候将采用某种解密算法。或者那不应该被视为代码?

评论

您确定这是(32位)代码吗?对我来说似乎有点随机-好像在分解数据或16位代码。您可以在清单中添加实际的操作码字节以进行验证吗?

您可以将二进制文件本身发布到某个地方,以便我们进行查看吗?

这是您要找的东西吗? .686p .mmx .model flat seg000段字节公共'CODE'use32另外,这不是CS,而是EIP

99%的人确定这不是代码。如果您的.686p .mmx .model平面seg000段字节公共'CODE'use32由IDA生成,则启动ida时可能未正确初始化-如果将ARM对象文件提供给ida,并告诉它它是32位的Intel代码,会很乐意尝试将其反汇编为intel代码,但只会产生垃圾。这似乎就是这里发生的事情。发布十六进制代码或二进制代码(如果二进制代码不太大),如其他人所建议的那样,可能会帮助某人识别该格式并提供进一步的线索。

#1 楼

这是自修改代码。您看到的垃圾指令将通过以下方式动态更改:

seg000:00000000                 mov     edx, 61666A1Fh
seg000:00000005                 fincstp
seg000:00000007                 fnstenv byte ptr [esp-0Ch]
seg000:0000000B                 pop     esi             ; EIP


现在esi指向fincstp指令(00000005)的位置。

seg000:0000000C                 sub     ecx, ecx
seg000:0000000E                 mov     cl, 33h ; loop counter
seg000:00000010                 xor     [esi+12h], edx
seg000:00000013                 add     edx, [esi+12h]  ;sliding key


esi+1200000017)被更改,将其更改为:

seg000:00000016                 xor     ecx, 0FFFFFF96h
seg000:00000019                 test    [ecx+esi*8+957C08Fh], dl


更改为:

seg000:00000016                 sub     esi, 0FFFFFFFCh
seg000:00000019                 loop    near ptr 00000010


ie esi = esi + 4,现在是00000009(然后是0x0000000d0x00000011,...),循环通过ecx中的值继续。
这是一个shellcode样式的解密器。可以在此处和此处找到有关此技术的更详细说明。

评论


我以为EIP将指向07h。问题:如果esi + 12是17h,为什么修改后的代码从16h开始?我想如果我想手动发现在17h用61666A1Fh对XOR进行什么指令,我应该自己进行XOR运算,然后看看有什么新指令。这些链接不起作用。

–user3002428
2014年7月22日在16:30



16h处的字节未更改,只是碰巧具有相同的操作码(0x83)。是要更改的参数。我已经修复了链接。

–彼得·弗里
14年7月22日在17:14

谢谢:)是否有任何工具可以使我更轻松地进行解密,或者最好的方法是尝试在C程序(或python脚本)中重新创建解密循环?

–user3002428
14年7月22日在17:54

在调试器中单步执行代码将使您可以更轻松地对其进行解密。如果不能将给定文件直接加载到调试器中,则可以复制机器代码并将其粘贴到可以加载到调试器中的文件中,然后将EIP设置为粘贴代码的开头。

–詹森·格夫纳(Jason Geffner)
2014年7月22日在18:24

至于为什么EIP指向05h而不是07h的原因,这是因为在发生异常的情况下,FPU会记住FPU指令的确切位置(如果可以通过异常处理程序解决问题,则可以继续执行)。

–彼得·弗里
2014年7月22日在18:28