我在这里阅读了一篇关于编写 shellcode(使用堆栈方法执行)的基本文章:http: //hackoftheday.securitytube.net/2013/04/demystifying-execve-shellcode-stack.html
在第 6 步中:它推送一个空字符,因为字符串“/bin/sh”是空终止的。之后,它以相反的顺序推送字符串“/bin/sh”
为什么字符串以相反的顺序推入堆栈,为什么终止字符串的空字符在将字符串推入堆栈“之前”被推入?
我在这里阅读了一篇关于编写 shellcode(使用堆栈方法执行)的基本文章:http: //hackoftheday.securitytube.net/2013/04/demystifying-execve-shellcode-stack.html
在第 6 步中:它推送一个空字符,因为字符串“/bin/sh”是空终止的。之后,它以相反的顺序推送字符串“/bin/sh”
为什么字符串以相反的顺序推入堆栈,为什么终止字符串的空字符在将字符串推入堆栈“之前”被推入?
应放入堆栈的字符串如下:
//bin/sh + '\0'(null terminator) + alignment(3 additional null characters) - gives 3 DWORDs (12 bytes)
为此,我们必须以正确的顺序执行一组指令:
xor eax, eax ;zero out full 32 bits of eax register
push eax ;0x00000000
push 0x68732f6e ;hs/n
push 0x69622f2f ;ib//
为什么会有这样的顺序?
由于堆栈性质。元素应该以相反的顺序放入其中,以便将来正确读出。堆栈是一种具有先进后出(FILO) 顺序的数据结构(与堆相反)。这意味着放入堆栈的第一个项目是最后一个出来的项目。随着堆栈大小的变化,它会朝着较低的内存地址向上增长:
memory
.---------------.-- 00 <-- top / low addresses
| . | x+1
| /|\ | x+2
| | | .
| stack | .
|grows up toward| .
|lower addresses| x+n
'---------------'-- FF <-- bottom / high addresses
现在,这两个双字怎么样:0x68732f6e (hs/n)
和0x69622f2f (ib//)
?它们有什么关系//bin/sh
?
看0x68732f6e
我们可以看到逐字节显示的字节反转效果,实际存储在内存中,4字节:0x6e 0x2f 0x73 0x68 (n/sh)
。它与IA-32架构特定的字节序连接,在手动将字节放入堆栈时必须考虑这一点。在 x86 处理器上,值以little-endian(与 SPARC 处理器上的 big endian 相反)字节顺序存储,这意味着首先存储最低有效字节(小端在前):
byte3 byte2 byte1 byte0
将在内存中排列如下:
base address+0 byte0
base address+1 byte1
base address+2 byte2
base address+3 byte3
所以最后,要可视化内存空间是如何填充的,请看下面:
.--------- push eax ;0x00000000
| .----- push 0x68732f6e ;hs/n bytes reversed
| | .- push 0x69622f2f ;ib// bytes reversed
| | |
| | | register
| | '> |69|62|2f|2f| (ib//) memory
| | | | | | ..
| | | | | '-------> x: 2f '/'
| | | | '----------> x+1: 2f '/'
| | | '-------------> x+2: 62 'b'
| | '----------------> x+3: 69 'i'
| | little endian
| |
| '----> |68|73|2f|6e| (hs/n)
| | | | |
| | | | '-------> x+4: 6e 'n'
| | | '----------> x+5: 2f '/'
| | '-------------> x+6: 73 's'
| '----------------> x+7: 68 'h'
|
'--------> |00|00|00|00| (\0\0\0\0)
| | | |
| | | '-------> x+8: 00 '\0'
| | '----------> x+9: 00 '\0'
| '-------------> x+10: 00 '\0'
'----------------> x+11: 00 '\0'
..
您可以使用gdb检查它:
(gdb) x/12b $sp
0xbfb530b0: 0x2f 0x2f 0x62 0x69 0x6e 0x2f 0x73 0x68
0xbfb530b8: 0x00 0x00 0x00 0x00
(gdb) x/12c $sp
0xbfb530b0: 47 '/' 47 '/' 98 'b' 105 'i' 110 'n' 47 '/' 115 's' 104 'h'
0xbfb530b8: 0 '\0' 0 '\0' 0 '\0' 0 '\0'
(gdb) x/3w $sp
0xbfb530b0: 0x69622f2f 0x68732f6e 0x00000000