【问题标题】:How to "understand" (manually interpret) a tiny binary executable written in NASM for Linux如何“理解”(手动解释)用 NASM for Linux 编写的小型二进制可执行文件
【发布时间】:2017-07-22 23:17:31
【问题描述】:

最近我开始学习 NASM,我想深入了解编译器、VM 和计算机通常如何工作的理论。我编写了一个小而简单的 NASM 程序,只是为了观察它在使用 NASM 编译器构建后生成的二进制代码。

ASM 代码在这里:

    section .data
            c: db 420

    section .text
            global _start:
            _start:
            mov ecx, 1337

            mov eax, eax
            mov eax, ebx
            mov eax, ecx
            mov eax, edx
            mov eax, ebp
            mov eax, esp

            mov ebx, eax
            mov ebx, ebx
            mov ebx, ecx
            mov ebx, edx
            mov ebx, ebp
            mov ebx, esp

            mov ecx, eax
            mov ecx, ebx
            mov ecx, ecx
            mov ecx, edx
            mov ecx, ebp
            mov ecx, esp

            mov edx, eax
            mov edx, ebx
            mov edx, ecx
            mov edx, edx
            mov edx, ebp
            mov edx, esp


            ; exit
            mov eax, 1
            mov ebx, 2
            int 80h

所以基本上,在这里我只是将每个寄存器移到其他每个寄存器中。我知道输出将重载“mov”命令,因此带有寄存器的 mov 看起来与带有寄存器和常量的 mov 不同。上面程序的objdump显然也很简单:

    ./program:     file format elf64-x86-64
    Disassembly of section .text:

    00000000004000b0 <.text>:
    4000b0: b9 39 05 00 00          mov    $0x539,%ecx
    4000b5: 89 c0                   mov    %eax,%eax
    4000b7: 89 d8                   mov    %ebx,%eax
    4000b9: 89 c8                   mov    %ecx,%eax
    4000bb: 89 d0                   mov    %edx,%eax
    4000bd: 89 e8                   mov    %ebp,%eax
    4000bf: 89 e0                   mov    %esp,%eax

    4000c1: 89 c3                   mov    %eax,%ebx
    4000c3: 89 db                   mov    %ebx,%ebx
    4000c5: 89 cb                   mov    %ecx,%ebx
    4000c7: 89 d3                   mov    %edx,%ebx
    4000c9: 89 eb                   mov    %ebp,%ebx
    4000cb: 89 e3                   mov    %esp,%ebx

    4000cd: 89 c1                   mov    %eax,%ecx
    4000cf: 89 d9                   mov    %ebx,%ecx
    4000d1: 89 c9                   mov    %ecx,%ecx
    4000d3: 89 d1                   mov    %edx,%ecx
    4000d5: 89 e9                   mov    %ebp,%ecx
    4000d7: 89 e1                   mov    %esp,%ecx

    4000d9: 89 c2                   mov    %eax,%edx
    4000db: 89 da                   mov    %ebx,%edx
    4000dd: 89 ca                   mov    %ecx,%edx
    4000df: 89 d2                   mov    %edx,%edx
    4000e1: 89 ea                   mov    %ebp,%edx
    4000e3: 89 e2                   mov    %esp,%edx


    4000e5: b8 01 00 00 00          mov    $0x1,%eax
    4000ea: bb 02 00 00 00          mov    $0x2,%ebx
    4000ef: cd 80                   int    $0x80

我们可以看到“0x4000b5”-“0x4000e3”上的89指令表示将寄存器移动到其他寄存器。但是令我困惑的是,指令行上的第二个字节不是我所期望的。我该如何解释这个?我的“重载”部分有什么问题吗?

谢谢大家的时间,请原谅我的英语不好。我尽可能地改进它! :)

【问题讨论】:

  • 您可能希望使用objdump -M intel -D file.o 来获得更类似于原始来源的内容,除非您真的对气体语法感到好奇。

标签: assembly nasm executable binary-data


【解决方案1】:

您知道您不需要对此进行逆向工程,因为它在官方手册中有详细记录,对吧? :) 见表 2-2。 英特尔® 64 和 IA-32 架构软件开发人员手册第 2 卷(2A、2B 和 2C)中的 ModR/M 字节的 32 位寻址形式:指令集参考,AZ .

请注意,x86 寄存器没有按照您期望的顺序编号。无论出于何种原因,顺序是:eaxecxedxebxespebpesiedi

在称为modr/m的第二个字节中,#0-2 和#3-5 位用于编码寄存器操作数。这在十六进制中不是很明显,但会在八进制中。一些例子:

211 300 mov %eax,%eax ; move from register #0 to #0
211 330 mov %ebx,%eax ; move from register #3 to #0
211 313 mov %ecx,%ebx ; move from register #1 to #3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-27
    • 1970-01-01
    • 2012-03-21
    • 2018-10-28
    • 2016-04-06
    • 1970-01-01
    • 2023-03-07
    相关资源
    最近更新 更多