Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading raw code from C program

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
like image 639
Alexey Avatar asked Feb 23 '11 18:02

Alexey


3 Answers

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.

like image 197
Christoph Avatar answered Nov 20 '22 15:11

Christoph


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.

like image 40
NPE Avatar answered Nov 20 '22 14:11

NPE


One thing: you should open the file as binary.

FILE* fp = fopen(argv[1],"rb"); 
like image 2
AShelly Avatar answered Nov 20 '22 14:11

AShelly