Загрузка исходного кода из программы C
Я пишу программу, которая загружает и выполняет код из файла.
Но у меня проблема: "написать" syscall не работает.
Код успешно загружается и выполняется, но не отображает текст на экране.
Программа, загружающая код:
#include < stdio.h >
#include < stdlib.h >
int main(int argc,char* argv[])
{
unsigned int f_size = 0;
unsigned char* code_buf = NULL;
void (*func_call)(void) = NULL;
if(argc < 2)
{
printf("Usage: %s <FILE>\n",argv[0]);
return 1;
}
FILE* fp = fopen(argv[1],"rb");
if(!fp)
{
printf("Error while opening this file: %s\n",argv[1]);
return 1;
}
unsigned int fsize = 0;
fseek(fp,0,SEEK_END);
fsize = ftell(fp);
fseek(fp,0,SEEK_SET);
if(fsize < 4)
{
printf("Code size must be > 4 bytes\n");
return 1;
}
code_buf = (unsigned char*) malloc(sizeof(unsigned char)*fsize);
if(fread(code_buf,fsize,1,fp)<1)
{
printf("Error while reading file: %s\n",argv[1]);
free(code_buf);
return 1;
}
func_call = (void (*)(void)) code_buf;
printf("[EXEC] Binary is loaded\n"
"\tFirst 2 bytes: 0x%x 0x%x\n"
"\tLast 2 bytes: 0x%x 0x%x\n",
code_buf[0],code_buf[1],
code_buf[fsize-2],code_buf[fsize-1]);
printf("[EXEC] Starting code...\n");
(*func_call)();
printf("[EXEC] Code executed!\n");
free(code_buf);
return 0;
}
который я пытаюсь выполнить этой программой (test.s):
.text
movl $4, %eax
movl $1, %ebx
movl $str, %ecx
movl $5, %edx
int $0x80
jmp end
str:
.string "test\n"
end:
ret
Вот как я скомпилирую его:
gcc -c test.s
objcopy -O binary test.o test.bin
Решено, благодаря @Christoph
Есть рабочий код:
.text
call start
str:
.string "test\n"
start:
movl $4, %eax
movl $1, %ebx
pop %ecx
movl $5, %edx
int $0x80
ret
Ответы
Ответ 1
Ваш подход не может работать: шеллкод должен быть независим от позиции, но ваш код относится к абсолютному адресу str
. Безусловный переход может быть либо относительным, либо абсолютным: убедитесь, что вы получили относительную проверку (коды операций EB и E9 на x86).
Подробнее см. "Техника написания портативного кода оболочки" .
Ответ 2
Вы не указываете детали своего процессора, но вы можете столкнуться с NX bit. Я бы ожидал, что ваш код будет SEGFAULT, а не запущен.
Это именно то, что происходит на моем ящике (Linux 2.6.32-28-generiС# 55-Ubuntu SMP Mon Jan 10 23:42:43 UTC 2011 x86_64 GNU/Linux), работающий на Intel Xeon E5410.
Ответ 3
Одно дело: вы должны открыть файл как двоичный.
FILE* fp = fopen(argv[1],"rb");
Ответ 4
Почему вы не используете файлы .so для динамической загрузки вашего кода? Вы тестируете сценарий безопасности или действительно пытаетесь динамически загружать и запускать код?
Читайте здесь, как компилировать код как .so, загружать его динамически в программу и выполнять экспортированные функции из него.
http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html