2011-12-17 3 views
8

Привет всем,Разница между объявлением shellcode как char [] array и char *?

Я пытаюсь изучить базовую оболочку, и я столкнулся с чем-то любопытным, что, надеюсь, кто-то может мне объяснить. Я скомпилировал следующий код двумя способами: объявить шеллкод как массив и как char *. Когда я объявляю shellcode как массив, linux обнаруживает, что я пытаюсь выполнить данные, и я получаю segfault в первой инструкции. Однако, когда я объявляю shellcode как char *, весь шеллкод выполняется, и я получаю «Hello world!». Как компилятор обрабатывает эти два объявления по-разному и почему один конец в шеллкоде, который живет в незащищенной памяти? Заранее спасибо.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

/* This declaration ends in a segfault */ 
//char shellcode[] = 

/* This declaration ends in successful execution */ 
char* shellcode = 

/* Shellcode prints "Hello world!" and exits */  
"\xeb\x1f\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x0c\xcd\x80\x48\x31\xc0\xb0\x01\x48\x31\xdb\xcd\x80\xe8\xdc\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21"; 

int main() 
{ 
    void (*f)(); 
    f = (void (*)())shellcode; 
    (void)(*f)(); 
} 

ответ

8

Когда вы объявляете его как char[], память на стеке. Когда вы объявляете его как char* и присваиваете ему строковый литерал, память находится в самом исполняемом изображении. Linux не нравится, когда вы выполняете код в стеке, но отлично справляется с выполнением памяти в этой части исполняемого изображения. Это связано с тем, что он пытается избежать определенного типа переполнения стека, где люди могут переполнять стек с помощью каких-то произвольных инструкций, а затем выполнять их.

Вы можете использовать mprotect на Linux, чтобы установить разрешения для области памяти или VirtualProtectEx на Windows. Таким образом, вы можете явно указать права доступа к исполняемому файлу.

3

В своем первом случае:

char shellcode[] = 

Это помещает строку буквального в стеке в качестве локального массива. В стеке и памяти кучи обычно нет разрешений на выполнение (по понятным причинам безопасности).

В вашем втором случае:

char* shellcode = 

Строка живет в статической памяти - как правило, в том же регионе, что и остальные программы двоичном - который является исполняемым.

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