-3

I wrote a program that writes a function to a file, then loads said file and executes the function. This code works without a problem when I compile for 32bit, but when I set my compiler to 64bit the program crashes.

    #include <stdio.h>
    #include <windows.h>
    #include <Filez.h>

    void shellc(FARPROC p,char* x)
    {
    (int (WINAPI *)(HWND,LPCSTR,LPCSTR,UINT))p(NULL,x,x,MB_OK);
    }
    void stub()
    {
    
    }
    
    int main(int argc, char **argv)
    {
    int size = stub - shellc;
    CryptMemoryToFile(shellc,size,"somepassword","shellcodefile");
    int sz;
    char * x = DeCryptFileToMemory("shellcodefile","somepassword",&sz);
    void (*shellcode)(FARPROC,char*) = x;
    FARPROC p = GetProcAddress(LoadLibraryA("user32.dll"),"MessageBoxA");
    shellcode(p,"test");
    
    getchar();
    }

The 2 (De)Cryption functions that are defined in Filez.h

    char * DeCryptFileToMemory(char * File,char * Pw,int * Size)
    {
    int PWL = strlen(Pw);
    char * Data = LoadFile(File,Size);
    if (Data == NULL) return 0;

    int y = 0;
    for (int x = 0; x <= *Size;x++)
    {
    Data[x] = Data[x] - Pw[y];
    y++;
    if (y > PWL) y = 0;
    }

    return Data;
    }

    int CryptMemoryToFile(char * Memory,int Size,char * Pw,char *                 File)
    {
    int PWL = strlen(Pw);
    char * Memory2 = malloc(Size);
    memcpy(Memory2,Memory,Size);
        
    if (Memory2 == NULL) return 0;
    
    int y = 0;
    for (int x = 0; x <= Size;x++)
    {
    Memory2[x] = Memory2[x] + Pw[y];
    y++;
    if (y > PWL) y = 0;
    }
    
    FILE * f = fopen(File,"wb");
    if (f == NULL) return 0;
    int w = fwrite(Memory2,1,Size,f); 
    if (w != Size) return 0;
    fclose(f);
    free(Memory2);
    return 1;
    
    }
  • 1
    When you drop this into a debugger and step through do you see anything unusual? What kind of crash happens? – tadman Oct 28 '20 at 22:09

1 Answers1

1

You can't just take x86 shellcode move it to x64 and expect it to work, naturally. There's a lot difference between x86 assembly and x64 assembly. Specifically to do with how arguments are passed on stack/registers as well as which registers are used.

The reason your shellcode isn't working in x64 could have to do with misallignment of the stack or incorrect register usage. You might be saving the x86 portion then trying use that same shellcode in x64. You might also be trying to execute region of memory that's not executable. Could be many reasons.

I wrote you a simple shellcode in x64. The first argument is the address while the second argument is the message to be displayed. Just note this will not work in x86.

unsigned char shellcode[] = {
0x56, 0x48, 0x8B, 0xF1, 0x48, 0xC7, 0xC1, 0x00, 0x00, 0x00, 0x00, 
0x4C, 0x8B, 0xC2, 0x49, 0xC7, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x48, 
0x83, 0xEC, 0x20, 0xFF, 0xD6, 0x48, 0x83, 0xC4, 0x20, 0x5E, 0xC3
};
void CallMB(FARPROC MessageBoxAddress,char* Message){
//here make a function pointer to shellcode which takes two argumenst
//the address and the buffer.
//call the pointer
}

I also don't know how you're saving your shell-code to your file. If it's a binary file or text file. But that shellcode can be called directly within your code as well so long as the region of memory is executable.

Jade
  • 51
  • 4
  • Im not trying to use the 32bit shellcode, I recompile the entire program for 64 bit so the function that gets written to the file should also be 64bit – Sinnlosername Oct 29 '20 at 21:01
  • Update: I got it to work now, this time I used VirtualAlloc with PAGE_EXECUTE_READWRITE and then copied the shellcode from the file to the newly allocated memory, only thing I wonder is why I only need to do this when compiling a 64bit executeable and not for both 32 and 64bit – Sinnlosername Oct 29 '20 at 21:25
  • You need to set page protection on region of memory without execute permissions. Why didn't need to do that in x86 is beyond me, and seems like undefined behavior or you just got lucky.. – Jade Dec 03 '20 at 00:29