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


DWORD GetBaseAddress( DWORD dwPID, char* name ) 
{ 
    HANDLE hModuleSnap = INVALID_HANDLE_VALUE; 
    MODULEENTRY32 me32; 
  
    hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID ); 
    if( hModuleSnap == INVALID_HANDLE_VALUE ) 
    { 
        printf( "CreateToolhelp32Snapshot (of modules)" ); 
        return( 0 ); 
    } 
  
    me32.dwSize = sizeof( MODULEENTRY32 ); 
  
    if( !Module32First( hModuleSnap, &me32 ) ) 
    { 
        printf( "Module32First" ); 
        CloseHandle( hModuleSnap ); 
        return( 0 ); 
    } 
  
    do 
    { 
        if (strstr(me32.szModule,name)) return((DWORD) me32.modBaseAddr); 
    } while( Module32Next( hModuleSnap, &me32 ) ); 
    CloseHandle( hModuleSnap ); 
    return( 1 ); 
} 

char hexToAscii(char first, char second) 
{ 
    char hex[5], *stop; 
    sprintf(hex,"0x%c%c",first,second); 
    return strtol(hex, &stop, 16); 
} 
  
int hook(DWORD proc_id, DWORD base, HWND sendHere, DWORD signal) 
{ 
    char address[10]; 
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_id); 
    if(!hProcess) 
    { 
        printf("Cannot open process!\n"); 
        return 0; 
    }      
    byte data[] = {0xE9,0xAA,0xAA,0xAA,0xAA}; 
    DWORD dataSize = sizeof(data),jump,retn; 
    HANDLE hModule = VirtualAllocEx( hProcess, 0, 100, MEM_COMMIT, PAGE_EXECUTE_READWRITE );    
    
    jump=(DWORD)hModule-base-0x5; 
    printf("CodeCave: %x %x\n",hModule,jump); 
    sprintf(address,"%08x",jump); 
    
    for (int i=0; i<4; i++) data[1+i]=hexToAscii(address[8-((i+1)*2)],address[8-((i*2)+1)]); 
    for(int i=0; i<dataSize; i++) printf("%02x ",data[i]); 
    
    printf("\n\nWrite Hook to:%08x\nSizeofData %d\n",base,dataSize); 
    for(int i=0; i<dataSize; i++) printf("%x ",data[i]); 
    printf("\n\nFunction we're hooking: %x\n",base); 
    WriteProcessMemory(hProcess, (LPVOID)base, &data, dataSize, NULL); 
    
    unsigned char data2[] = "\x60\x6A\x00\x6A\x00\x68\x37\x04\x00\x00" 
             "\x68\xFF\xFF\xFF\xFF\xB8\x21\x43\x65\x87\xFF\xD0\x61\x8B" 
             "\xFF\x55\x8B\xEC\xE9\x57\x56\xAD\x11"; 
    DWORD dataSize2 = sizeof(data2); 
    
    printf("Sending stuffs to %x\n",sendHere); 
    sprintf(address,"%08x",sendHere); 
    for (int i=0; i<4; i++) data2[11+i]=hexToAscii(address[8-((i+1)*2)],address[8-((i*2)+1)]); 
    
    DWORD sendMessage=(DWORD)GetProcAddress(GetModuleHandle("User32"), "SendMessageA"); 
    printf("SendMessage %x\n",sendMessage); 
    sprintf(address,"%08x",sendMessage); 
    for (int i=0; i<4; i++) data2[16+i]=hexToAscii(address[8-((i+1)*2)],address[8-((i*2)+1)]); 
    
    retn=base-(DWORD)hModule-0x1C; 
    printf("Jump Back: %x-%x=%x\n",base,hModule,retn); 
    sprintf(address,"%08x",retn); 
    for (int i=0; i<4; i++) data2[29+i]=hexToAscii(address[8-((i+1)*2)],address[8-((i*2)+1)]); 
    
    signal=0x400+signal; 
    printf("Signal: %x",signal); 
    sprintf(address,"%08x",signal); 
    for (int i=0; i<4; i++) data2[6+i]=hexToAscii(address[8-((i+1)*2)],address[8-((i*2)+1)]); 
    
    printf("\n\nWrite CodeCave to:%08x\n\nOur data: ",hModule); 
    for(int i=0; i<dataSize2; i++) printf("%02x ",data2[i]); 
    WriteProcessMemory(hProcess, (LPVOID)hModule, &data2, dataSize2, NULL); 
    CloseHandle(hProcess); 
    printf("\n"); 
} 

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch (message) 
    { 
        case WM_DESTROY: 
            PostQuitMessage (0); 
            break; 
        default:    
            if (message>=0x400 && message<=0x7FFF) printf("%x %x %x\n",message,wParam,lParam); 
            return DefWindowProc (hwnd, message, wParam, lParam); 
    } 
    return 0; 
} 

int WINAPI WinMain (HINSTANCE hThis,HINSTANCE hPrev,LPSTR lpszArg,int nFunsterStil) 
{ 
    DWORD hookthis,proc_id,base; 
    HWND Found; 
    
    HWND hWnd = FindWindow("Notepad", NULL); 
    if(hWnd == NULL) 
    { 
        printf("Error cannot find window!\n"); 
        return 0; 
    } 
    else 
    { 
         GetWindowThreadProcessId(hWnd, &proc_id);    
         base=GetBaseAddress(proc_id,"notepad.exe"); 
    } 
    DWORD CreateF=(DWORD)GetProcAddress(GetModuleHandle("Kernel32"), "CreateFileW"); 
    DWORD ROpenK=(DWORD)GetProcAddress(GetModuleHandle("Advapi32"), "RegOpenKeyExW"); 
    hookthis=GetBaseAddress(proc_id,"notepad.exe"); 
    hookthis=hookthis+0x57FD; 

    HWND hwnd; 
    MSG messages; 
    WNDCLASSEX wincl; 

    wincl.hInstance = hThis; 
    wincl.lpszClassName = "Hook Phone Home"; 
    wincl.lpfnWndProc = WindowProcedure; 
    wincl.style = CS_DBLCLKS; 
    wincl.cbSize = sizeof (WNDCLASSEX); 
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); 
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); 
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW); 
    wincl.lpszMenuName = NULL; 
    wincl.cbClsExtra = 0; 
    wincl.cbWndExtra = 0; 
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; 


    if (!RegisterClassEx (&wincl)) return 0; 

    hwnd = CreateWindowEx (0,"Hook Phone Home","Find me",0, 
           CW_USEDEFAULT,CW_USEDEFAULT,230,100,HWND_DESKTOP,NULL,hThis,NULL); 
    while ((Found = FindWindowEx(NULL,NULL,"Hook Phone Home","Find me"))==NULL) Sleep(500); 
    ShowWindow (hwnd, SW_HIDE); 
    printf("%x %x",Found,hwnd); 
    hook(proc_id,CreateF,Found,0x37); 
    hook(proc_id,ROpenK,Found,0x13); 
    hook(proc_id,hookthis,Found,0x69); 
    printf("waiting...\n"); 
    while (GetMessage (&messages, 0, 0, 0)) 
    { 
        TranslateMessage(&messages); 
        DispatchMessage(&messages); 
    } 
    printf("%x",Found); 
} 
