I'm writing a program that loads and executes code from file. But i got a problem: "write" syscall does not work. Code successfully loads and executes, but does not display any text on the screen.
Program that loads code:
#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;
}
code that i trying to execute by this program (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
Here is how i compile it:
gcc -c test.s
objcopy -O binary test.o test.bin
Solved, thanks to @Christoph
There are working code:
.text
call start
str:
.string "test\n"
start:
movl $4, %eax
movl $1, %ebx
pop %ecx
movl $5, %edx
int $0x80
ret
Why are you not using .so files to dynamically load your code? Are you testing a security scenario or really trying to dynamically load and run code?
Read here on how to compile code as a .so, load it dynamically within a program, and execute exported functions out of it.
http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
Your approach can't work: shellcode must be position-independant, but your code refers to the absolute address
str
. The unconditional jump can also be either relative or absolute: make sure you get the relative verison (opcodes EB and E9 on x86).See The Technique of Writing Portable Shell Code for more information.
One thing: you should open the file as binary.
You don't specify the details of your CPU, but you might be running afoul of the NX bit. I would expect your code to SEGFAULT though rather than run to completion.
This is precisely what happens on my box (Linux 2.6.32-28-generic #55-Ubuntu SMP Mon Jan 10 23:42:43 UTC 2011 x86_64 GNU/Linux) running on Intel Xeon E5410.