【问题标题】:obfuscated C/asm "Hello, world!" program, I don't understand混淆 C/asm “你好,世界!”程序,看不懂
【发布时间】:2011-03-06 09:50:33
【问题描述】:

为什么下面的代码会打印“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 是什么意思,如何翻译成机器码?

【问题讨论】:

  • 看起来有人预先组装了代码,只是将实际的字节值作为.values 放入文件中。

标签: c assembly obfuscation


【解决方案1】:

我组装了它,然后又拆开了它,这就是我得到的。不过我没有运行它,因为我知道最好不要运行我在网上找到的随机汇编语言。

代码从跳转到打印代码开始:

00000000 <main>:
   0:   e8 0e 00 00 00          call   13 <main+0x13>

然后是“Hello, World!\n”的 ASCII:

   5:   48 65 6c 6c 6f 2c 20
   c:   77 6f 72 6c 64 21 0a

第一条指令跳转到的代码:

  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,然后:

gcc -S foo.S
objdump -D foo.o

【讨论】:

    【解决方案2】:

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

    1. ".globl main" :该指令告诉汇编器使 main 的符号在此汇编文件之外可见。
    2. "main:" :这将创建符号 main,链接器知道在链接时要查找该符号
    3. ".value" :这会导致汇编器发出一个具有相应值的字节。

    鉴于此,剩下的技巧是将发出的字节转换为它们对应的指令。这可以使用“英特尔 64 和 IA-32 架构软件开发人员手册:第 2B 卷”中的操作码映射来完成,可从here 获得

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        .value 不会被翻译成机器码。这是一个汇编指令。

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

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

        希望对您有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多