可执行文件中常见字符串的含义是什么?

34

在 Mach-O 64 位可执行文件和 ELF 64 位 LSB 可执行文件中,似乎存在一些长的类似字母数字串,它们与其他非字母数字符号一起出现:

cat /bin/bash | grep -c "AWAVAUATSH"

有181个结果,以及

cat /usr/bin/gzip | grep -c "AWAVAUATSH"

有9个结果。

在此输入图片描述

这些字符串是什么?

1个回答

52

有趣的问题。由于我不知道答案,所以这里是我采取的步骤:

该字符串在文件中出现在哪里?

strings -otx /bin/gzip | grep AWAVAUATUSH
   35e0 AWAVAUATUSH
   69a0 AWAVAUATUSH
   7920 AWAVAUATUSH
   8900 AWAVAUATUSH
   92a0 AWAVAUATUSH

那是哪个部分?

readelf -WS /bin/gzip

There are 28 section headers, starting at offset 0x16860:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        0000000000400238 000238 00001c 00   A  0   0  1
  [ 2] .note.ABI-tag     NOTE            0000000000400254 000254 000020 00   A  0   0  4
  [ 3] .note.gnu.build-id NOTE            0000000000400274 000274 000024 00   A  0   0  4
  [ 4] .gnu.hash         GNU_HASH        0000000000400298 000298 000038 00   A  5   0  8
  [ 5] .dynsym           DYNSYM          00000000004002d0 0002d0 000870 18   A  6   1  8
  [ 6] .dynstr           STRTAB          0000000000400b40 000b40 000360 00   A  0   0  1
  [ 7] .gnu.version      VERSYM          0000000000400ea0 000ea0 0000b4 02   A  5   0  2
  [ 8] .gnu.version_r    VERNEED         0000000000400f58 000f58 000080 00   A  6   1  8
  [ 9] .rela.dyn         RELA            0000000000400fd8 000fd8 000090 18   A  5   0  8
  [10] .rela.plt         RELA            0000000000401068 001068 0007e0 18   A  5  12  8
  [11] .init             PROGBITS        0000000000401848 001848 00001a 00  AX  0   0  4
  [12] .plt              PROGBITS        0000000000401870 001870 000550 10  AX  0   0 16
  [13] .text             PROGBITS        0000000000401dc0 001dc0 00f1ba 00  AX  0   0 16
  [14] .fini             PROGBITS        0000000000410f7c 010f7c 000009 00  AX  0   0  4
... etc.

从上面的输出中,我们可以看到所有AWAVAUATUSH实例都在.text部分(覆盖文件的[0x1dc0, 0x10f7a)偏移量)。

由于这是.text,我们期望在那里找到可执行指令。 我们感兴趣的地址是0x401dc0.text地址)+0x35e0(文件中AWAVAUATUSH的偏移量)-0x1dc0(文件中.text的偏移量)== 0x4035e0

首先,让我们检查上述算术是否正确:

gdb -q /bin/gzip

(gdb) x/s 0x4035e0
0x4035e0:       "AWAVAUATUSH\203\354HdH\213\004%("
是的,没错。接下来,那里的指示是什么?
(gdb) x/20i 0x4035e0
   0x4035e0:    push   %r15
   0x4035e2:    push   %r14
   0x4035e4:    push   %r13
   0x4035e6:    push   %r12
   0x4035e8:    push   %rbp
   0x4035e9:    push   %rbx
   0x4035ea:    sub    $0x48,%rsp
   0x4035ee:    mov    %fs:0x28,%rax
   0x4035f7:    mov    %rax,0x38(%rsp)
   0x4035fc:    xor    %eax,%eax
   0x4035fe:    mov    0x213363(%rip),%rax        # 0x616968
   0x403605:    mov    %rdi,(%rsp)
   0x403609:    mov    %rax,0x212cf0(%rip)        # 0x616300
   0x403610:    cmpb   $0x7a,(%rax)
   0x403613:    je     0x403730
   0x403619:    mov    $0x616300,%ebx
   0x40361e:    mov    (%rsp),%rdi
   0x403622:    callq  0x4019f0 <strlen@plt>
   0x403627:    cmp    $0x20,%eax
   0x40362a:    mov    %rax,0x8(%rsp)

这些指令看起来确实像是正常的可执行指令。 push %r15 的操作码是什么?这个表格 显示,0x410x57 确实是 push %r15 的操作码,这些操作码刚好在 ASCII 中拼出了 AW。同样地,push %r14 的操作码编码为 0x410x56,刚好拼出了 AV。等等。

附言:我的 gzip 版本已经完全剥离,所以 GDB 在上面反汇编中没有显示任何符号。如果我使用未剥离的版本,则会显示:

strings -o -tx gzip | grep AWAVAUATUSH | head -1
   6be0 AWAVAUATUSH

readelf -WS gzip | grep text
  [13] .text             PROGBITS        0000000000401b00 001b00 00d102 00  AX  0   0 16

因此,字符串仍然在 .text 中。

gdb -q ./gzip
(gdb) p/a 0x0000000000401b00 + 0x6be0 - 0x001b00
$1 = 0x406be0 <inflate_dynamic>

(gdb) disas/r 0x406be0
Dump of assembler code for function inflate_dynamic:
   0x0000000000406be0 <+0>:     41 57   push   %r15
   0x0000000000406be2 <+2>:     41 56   push   %r14
   0x0000000000406be4 <+4>:     41 55   push   %r13
   0x0000000000406be6 <+6>:     41 54   push   %r12
   0x0000000000406be8 <+8>:     55      push   %rbp
   0x0000000000406be9 <+9>:     53      push   %rbx
   0x0000000000406bea <+10>:    48 81 ec 38 05 00 00    sub    $0x538,%rsp
...

现在您可以清楚地看到操作码序列ASCII 0x4157415641554154...

P.P.S. 原问题涉及到AWAVAUATSH,它出现在我的Mach-O bashgzip中,但不出现在Linux版本中。相反,AWAVAUATUSH在我的Mach-O二进制文件中不存在。

然而,答案是相同的。AWAVAUATSH序列与AWAVAUATUSH相同,只是省略了push %rbp

P.P.P.S 这里有一些其他的“有趣”的字符串:

strings /bin/bash | grep '^A.A.A.' | sort | uniq -c | sort -nr | head
     44 AWAVAUATUSH
     27 AVAUATUSH
     16 AWAVAUA
     15 AVAUATUH
     14 AWAVAUI
     14 AWAVAUATUH
     12 AWAVAUATI
      8 AWAVAUE1
      8 AVAUATI
      6 AWAVAUATU

4
希望您的答案能够被广泛阅读,这个答案让我对检查可执行文件有了很多了解。 - seewalker
1
谷歌搜索显示其他人知道这个答案:https://plus.google.com/+EmilMikulic/posts/L13sdZNRhL9 和 https://www.jwz.org/blog/2014/10/we-live-in-a-magical-future-where-strings-is-exploitable/#comment-158250 所以这是另一种解决方法:只需谷歌一下就行了;-) - Employed Russian
5
echo -n AWAVAUATUSH | rasm2 -B -a x86 -b 64 -Df - 这段命令非常方便地将该序列反汇编。 - ysdx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接