混乱的C/asm“你好,世界!”程序,我不明白

混乱的C/asm“你好,世界!”程序,我不明白,c,assembly,obfuscation,C,Assembly,Obfuscation,为什么下面的代码打印Hello,world!在我的系统上 .file "test.c" .globl main .data .align 32 .type main, @object .size main, 56 main: .value 3816 .value 0 .value 18432 .value 27749

为什么下面的代码打印Hello,world!在我的系统上

        .file   "test.c"
.globl main
        .data
        .align 32
        .type   main, @object
        .size   main, 56
main:
        .value  3816
        .value  0
        .value  18432
        .value  27749
        .value  28524
        .value  8236
        .value  28535
        .value  27762
        .value  8548
        .value  -29942
        .value  9228
        .value  7305
        .value  -17884
        .value  14
        .value  0
        .value  20818
        .value  443
        .value  0
        .value  21248
        .value  1208
        .value  0
        .value  -32000
        .value  1260
        .value  -32563
        .value  -15229
        .value  23312
        .value  -16335
        .value  -28477

另外,.value是什么意思?它将如何转换为机器代码?

.value是原始内存数据。它们本身就是机器代码。该文件包含的程序不是人类可读的助记符,而是十进制数看起来像两字节有符号的数字。如果您想将程序视为可读代码,请编译它并使用任何反汇编程序。

这看起来像汇编代码。需要指出的一些关键问题是

.globl main:此指令告诉assmbler使main的符号在此程序集文件外部可见。 main::这将创建符号main,链接器在链接时知道要查找该符号 .value:这会导致汇编程序发出一个具有相应值的字节。
考虑到这一点,剩下的技巧是将emmite的字节转换为它们对应的指令。这可以使用《英特尔64和IA-32体系结构软件开发人员手册:第2B卷》中的操作码映射来完成,该手册可从

获得。我组装了它,然后将其分解,下面是我得到的。不过我没有运行它,因为我知道不必运行我在网上找到的随机汇编语言

代码从分支到打印代码开始:

00000000 <main>:
   0:   e8 0e 00 00 00          call   13 <main+0x13>
代码在第一条指令中跳转到:

  13:   8b 0c 24                mov    (%esp),%ecx
  16:   89 1c 24                mov    %ebx,(%esp)
  19:   ba 0e 00 00 00          mov    $0xe,%edx
  1e:   52                      push   %edx
  1f:   51                      push   %ecx
  20:   bb 01 00 00 00          mov    $0x1,%ebx
  25:   53                      push   %ebx
  26:   b8 04 00 00 00          mov    $0x4,%eax
  2b:   83 ec 04                sub    $0x4,%esp
  2e:   cd 80                   int    $0x80
  30:   83 c4 10                add    $0x10,%esp
  33:   5b                      pop    %ebx
  34:   31 c0                   xor    %eax,%eax
  36:   c3                      ret
  37:   90                      nop
FWIW,使用的方法是将代码粘贴到文件foo.S中,然后:


.值未转换为机器代码。这是一个汇编指令

.globl指令导出主符号。这是典型的,因为main需要对链接器公开可见。.data指令开始可执行文件的数据段,然后将main声明为大小为56的对象,因为有28个.value语句,每个语句表示一个16位的值

在.value之后指定的数字似乎是表示已翻译指令的原始二进制值。这需要了解操作系统和处理器,才能进一步确定它们的含义


希望这会有所帮助。

看起来好像有人预先组装了代码,并将实际字节值作为.values放入文件中。
  13:   8b 0c 24                mov    (%esp),%ecx
  16:   89 1c 24                mov    %ebx,(%esp)
  19:   ba 0e 00 00 00          mov    $0xe,%edx
  1e:   52                      push   %edx
  1f:   51                      push   %ecx
  20:   bb 01 00 00 00          mov    $0x1,%ebx
  25:   53                      push   %ebx
  26:   b8 04 00 00 00          mov    $0x4,%eax
  2b:   83 ec 04                sub    $0x4,%esp
  2e:   cd 80                   int    $0x80
  30:   83 c4 10                add    $0x10,%esp
  33:   5b                      pop    %ebx
  34:   31 c0                   xor    %eax,%eax
  36:   c3                      ret
  37:   90                      nop
gcc -S foo.S
objdump -D foo.o