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
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.