2016-12-07 4 views
2

Я новичок в отладке. Я пришел через этот код, который утверждает, что при запуске он запускает приглашение оболочки.Может ли кто-нибудь ясно объяснить эту разборку?

0:  31 c0                   xor    eax,eax 
2:  50                      push   eax 
3:  68 2f 2f 73 68          push   0x68732f2f 
8:  68 2f 62 69 6e          push   0x6e69622f 
d:  89 e3                   mov    ebx,esp 
f:  50                      push   eax 
10: 53                      push   ebx 
11: 89 e1                   mov    ecx,esp 
13: b0 0b                   mov    al,0xb 
15: cd 80                   int    0x80 

Пожалуйста, ясно объясните, что на самом деле происходит в регистрах и памяти здесь.

+1

Подумайте, какие символы ASCII вставляются в стек путем нажатия кнопки «0x68732f2f» и «push 0x6e69622f' ... –

+1

Обратите также внимание на то, что syscall 11 является' execve'. –

+2

Полное объяснение всего: http://www.kernel-panic.it/security/shellcode/shellcode5.html – Gerhard

ответ

3
; Push 0 onto the stack 
xor eax,eax  ; a classic x86 optimization trick to clear/zero a register 
push eax   ; push that zeroed register onto the stack 

; Push two constant values onto the stack 
push 0x68732f2f ; 0x68732f2f == 1,752,379,183 
push 0x6e69622f ; 0x6e69622f == 1,852,400,175 

; Save the current value of the stack pointer (ESP) in the EBX register. 
mov ebx,esp 

; Push another 0 onto the stack (remember, EAX still contains 0). 
push eax 

; Push the value of the previous stack pointer onto the stack. 
; (This is the same as pushing ESP+4, since the previous PUSH instruction 
; implicitly decremented the stack pointer by 32 bits.) 
push ebx 

; Save the current value of the stack pointer (ESP) in the ECX register. 
; (Presumably, it is either used again later in the function, or the interrupt 
; that we're about to call requires some input value to be passed in ECX.) 
mov ecx,esp 

.

Теперь стек выглядит следующим образом (на x86, стек растет вниз, так что старое значение находится в верхней части):

╔═════════════════╗   direction of growth 
║  0  ║     | 
╠═════════════════╣     | 
║ 0x68732F2F ║     V 
╠═════════════════╣ 
║ 0x6E69622F ║ <---- 
╠═════════════════╣  | 
║  0  ║  | 
╠═════════════════╣  | 
║ pointer to ... ║ ---- 
╚═════════════════╝   (lowest address) 

; Place the value 0xB (11) in the AL register, which is the bottom 8 bits of EAX. 
; The value in EAX specifies the sub-function to be executed when the interrupt is raised. 
; (Note that setting only the bottom 8 bits is safe because we already zeroed EAX.) 
mov al,0xb 

; Raise an interrupt, passing control to interrupt vector 0x80. 
; On Unix systems, this is how you make a system call. 
; This is why we went through all the trouble of pushing those values onto 
; the stack: this is how parameters are passed through to the system call. 
int 0x80 

Не будучи гуру Unix, я d необходимо найти номер системного вызова (в данном случае 0xB), чтобы узнать, что он делает. Оказывается, 0xB сопоставляется с sys_execve, который выполняет указанный двоичный код. Он ожидает, что указатель на файл будет выполнен в EBX, указатель на параметры командной строки в ECX и указатель на блок среды в EDX. Напомним, что в предыдущем коде эти регистры были инициализированы, чтобы содержать указатели в разных местах стека.

+0

Константы, которые помещаются в стек, образуют строку: '/ bin // sh'. –

3

Несколько жестко закодированных значений вставляются в стек, а затем помещается указатель на стек. Наконец, регистр EAX остается с окончательным загруженным значением, а EBX, ECX и ESP остаются указателями на местоположения в стеке.

STACK (from highest address to lowest): 
            0 
            0x68732f2f 
         /->  /-> 0x6e69622f 
         |  | 0    (arg[1]) 
         | /-> \-- arg[0] 
         | | 
    EAX = 0xb   | | 
    EBX(arg[0]) = ------/ | 
    ECX(&arg[0]) = --------/ 
    ESP = Same as ECX 

Как следует @PaulR, что должно быть execve и поэтому было бы что-то близкое к этому в C:.

char *arg[2] = { "/bin//sh", 0 }; 
execve(arg[0], &arg[0], envp); 

(Значение envp не доступен в этом фрагменте кода Это . было бы то, что в EDX Если это целая программа, предположительно EDX равна нулю на входе - и на Linux, нулевой указатель интерпретируется как пустой список среды)

Смежные вопросы