0

我试图弄清楚反汇编程序是如何工作的。具体来说,内存中的内容如何映射到相应的汇编语言操作码。

下面是内存中的内容,第一列地址:

773eed5c  50 ff 15 0c 17 3a 77 90-90 90 90 90 8b ff 55 8b  P....:w.......U.
773eed6c  ec 51 51 83 7d 10 00 74-38 ff 75 10 8d 45 f8 50  .QQ.}..t8.u..E.P
773eed7c  e8 14 d7 ff ff 85 c0 74-24 56 ff 75 fc ff 75 0c  .......t$V.u..u.
773eed8c  ff 75 08 e8 ab ff ff ff-83 7d 10 00 8b f0 74 0a  .u.......}....t.
773eed9c  8d 45 f8 50 ff 15 9c 15-3a 77 8b c6 5e c9 c2 0c  .E.P....:w..^...
773eedac  00 83 65 fc 00 eb d2 90-90 90 90 90 8b ff 55 8b  ..e...........U.
773eedbc  ec 57 e8 c7 d6 ff ff 8b-4d 0c 6a 34 5f 03 c7 0f  .W......M.j4_...
773eedcc  b7 00 40 40 03 c9 3b c8-0f 82 07 e5 00 00 56 e8  ..@@..;.......V.

以及对应的反汇编结果,第一列内存地址,第二列指令操作码,其余列汇编指令:

0x773eed5c 50 push    eax
0x773eed63 90 nop
0x773eed65 90 nop
0x773eed67 90 nop
0x773eed6a 55 push    ebp
0x773eed6d 51 push    ecx
0x773eed6f 837d1000 cmp     dword ptr [ebp+10h],0 ss:0023:056cfa8c=778237eb
0x773eed7c e814d7ffff call    kernel32!Basep8BitStringToDynamicUnicodeString (773ec495)

现在我可以看到操作码e814d7ffff字面意思是(e8 14 d7 ff ff

但是如何解释内存地址中的内容0x773eed5c呢?操作码push eax和连续nop的 s 如何映射到内存内容0c15ff50 90773a17 90909090 8b55ff8b

更新:

我上面给出的反汇编结果是不正确的。正确的结果,如下所示,很好地适合内存中的内容:

0x773eed5c 50 push    eax
0x773eed5d ff150c173a77 call    dword ptr [kernel32+0x170c (773a170c)] ds:0023:773a170c={ntdll!RtlExitUserThread (777ef608)}
0x773eed63 90 nop
0x773eed64 90 nop
0x773eed65 90 nop
0x773eed66 90 nop
0x773eed67 90 nop
0x773eed68 8bff mov     edi,edi
0x773eed6a 55 push    ebp
0x773eed6b 8bec mov     ebp,esp
0x773eed6d 51 push    ecx
0x773eed6e 51 push    ecx
0x773eed6f 837d1000 cmp     dword ptr [ebp+10h],0 ss:0023:0447fc24=778237eb
0x773eed73 7438 je      kernel32!OpenFileMappingA+0x45 (773eedad) [br=1]
0x773eed75 ff7510 push    dword ptr [ebp+10h]  ss:0023:0447fc24=778237eb
0x773eed78 8d45f8 lea     eax,[ebp-8]
0x773eed7b 50 push    eax
0x773eed7c e814d7ffff call    kernel32!Basep8BitStringToDynamicUnicodeString (773ec495)

有关我的错误的详细信息:我正在使用pykd围绕 WinDbg 开发工具。关于其disasm模块的文档没有详细介绍,所以我对disasm.jumprel函数使用了错误的参数,导致反汇编结果不完整。

4

2 回答 2

2

其实很简单。

看: http: //www.mathemainzel.info/files/x86asmref.html

这是一个 x86 指令集参考。

如果您查找“PUSH AX”,您会看到操作码是50. 如果你寻找“NOP”,你会看到它的操作码是90.

因此,发生的情况是您拥有每个操作码的集合(50== PUSH AX90==NOP等)。一些操作码需要比其他操作码更多的参数。CALL操作码有 4 种模式,第一种模式 ,用于E8“近指针”。

现在,x86 具有不同的操作模式(16b、32b、64b),因此它重用相同的操作码,但会针对不同的模式调整参数。这是反汇编程序需要提前知道的。因为“近指针”在 16b、32b 和 64b 模式中是不同的(它们占用更多空间等)。

但最后,一个简单的反汇编程序会查找它当前的操作码,根据操作码消耗所需的字节数,然后为那块内存创建适当的汇编指令。

更复杂的反汇编程序可以理解更高级别的语言,可以指出代码无法访问的区域(例如,它可以跟踪跳转、调用和分支,并知道哪些代码没有被反汇编)。

反汇编程序可以变得非常复杂,但简单的反汇编程序很简单。

于 2014-03-23T19:13:24.920 回答
2

似乎确实缺少一些东西。

50                push eax
ff 15 0c 17 3a 77 call [0x0c173a77] ; where did this thing go?
90                nop
90                nop
90                nop
90                nop
90                nop
8b ff             mov edi, edi  ; wut?
55                push ebp      ; this looks like the beginning of a function
8b ec             mov ebp, esp
51                push ecx
51                push ecx
83 7d 10 00       cmp [ebp + 10], 0

我手动拆了这个,我可能犯了错误。这段代码很奇怪。你对它的拆解更奇怪,我不知道它是怎么发生的。

于 2014-03-23T19:19:36.720 回答