Changeset 4650 for zzuf


Ignore:
Timestamp:
Sep 21, 2010, 1:32:40 AM (9 years ago)
Author:
Sam Hocevar
Message:

Full support for ASLR in the Win32 loader.

Location:
zzuf/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • zzuf/trunk/msvc/zznop.vcxproj

    r4647 r4650  
    7070      <SubSystem>Console</SubSystem>
    7171      <TargetMachine>MachineX86</TargetMachine>
    72       <RandomizedBaseAddress>false</RandomizedBaseAddress>
    7372    </Link>
    7473  </ItemDefinitionGroup>
     
    9291      <EnableCOMDATFolding>true</EnableCOMDATFolding>
    9392      <TargetMachine>MachineX86</TargetMachine>
    94       <RandomizedBaseAddress>false</RandomizedBaseAddress>
    9593    </Link>
    9694  </ItemDefinitionGroup>
  • zzuf/trunk/src/myfork.c

    r4648 r4650  
    7474#if defined HAVE_WINDOWS_H
    7575static void rep32(uint8_t *buf, void *addr);
    76 static int dll_inject(PROCESS_INFORMATION *, void *, char const *);
    77 static intptr_t get_base_address(DWORD);
    78 static intptr_t get_entry_point(char const *name, DWORD pid);
     76static int dll_inject(PROCESS_INFORMATION *, char const *);
    7977static intptr_t get_proc_address(void *, DWORD, char const *);
    8078#endif
     
    159157    STARTUPINFO sinfo;
    160158    HANDLE pid;
    161     void *epaddr;
    162159    int ret;
    163160#endif
     
    276273        return -1;
    277274
    278     /* Get the child process's entry point address */
    279     epaddr = (void *)get_entry_point(child->newargv[0],
    280                                      pinfo.dwProcessId);
    281     if(!epaddr)
    282         return -1;
    283 
    284275    /* Insert the replacement code */
    285     ret = dll_inject(&pinfo, epaddr, SONAME);
     276    ret = dll_inject(&pinfo, SONAME);
    286277    if(ret < 0)
    287278    {
     
    297288    }
    298289
    299 Sleep(5000);
    300290    return (long int)pinfo.hProcess;
    301291#endif
     
    313303}
    314304
    315 static int dll_inject(PROCESS_INFORMATION *pinfo,
    316                       void *epaddr, char const *lib)
     305static int dll_inject(PROCESS_INFORMATION *pinfo, char const *lib)
    317306{
    318307    static uint8_t const loader[] =
     
    348337        "\xff\xe0";      /* jmp eax */
    349338
     339    CONTEXT ctx;
    350340    void *process = pinfo->hProcess;
    351341    void *thread = pinfo->hThread;
     342    void *epaddr;
    352343    DWORD pid = pinfo->dwProcessId;
    353344
     
    397388    memcpy(code + loaderlen + jumperlen, lib, liblen);
    398389
     390    /* Find the entry point address. It's simply in EAX. */
     391    ctx.ContextFlags = CONTEXT_FULL;
     392    GetThreadContext(thread, &ctx);
     393    epaddr = (void *)(uintptr_t)ctx.Eax;
     394
    399395    /* Backup the old entry point code */
    400396    ReadProcessMemory(process, epaddr, code + loaderlen, jumperlen, &tmp);
     
    429425     * the target's execution to the entry point. */
    430426    rep32(code, loaderaddr + loaderlen + jumperlen);
    431     rep32(code, (uintptr_t)get_proc_address(process, pid, "LoadLibraryA"));
     427    rep32(code, (void *)get_proc_address(process, pid, "LoadLibraryA"));
    432428    rep32(code, (void *)(uintptr_t)jumperlen);
    433429    rep32(code, loaderaddr + loaderlen);
    434430    rep32(code, epaddr);
    435     rep32(code, (uintptr_t)get_proc_address(process, pid, "GetCurrentProcess"));
    436     rep32(code, (uintptr_t)get_proc_address(process, pid, "WriteProcessMemory"));
     431    rep32(code, (void *)get_proc_address(process, pid, "GetCurrentProcess"));
     432    rep32(code, (void *)get_proc_address(process, pid, "WriteProcessMemory"));
    437433    rep32(code, epaddr);
    438434
     
    452448}
    453449
    454 /* Find the process's entry point address offset. The information is in
    455  * the file's PE header. */
    456 static intptr_t get_entry_point(char const *name, DWORD pid)
    457 {
    458     PIMAGE_DOS_HEADER dos;
    459     PIMAGE_NT_HEADERS nt;
    460     intptr_t ret = 0;
    461     void *file, *map, *base;
    462 
    463     file = CreateFile(name, GENERIC_READ, FILE_SHARE_READ,
    464                       NULL, OPEN_EXISTING, 0, NULL);
    465     if(file == INVALID_HANDLE_VALUE)
    466         return ret;
    467 
    468     map = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
    469     if(!map)
    470     {
    471         CloseHandle(file);
    472         return ret;
    473     }
    474 
    475     base = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
    476     if(!base)
    477     {
    478         CloseHandle(map);
    479         CloseHandle(file);
    480         return ret;
    481     }
    482 
    483     /* Sanity checks */
    484     dos = (PIMAGE_DOS_HEADER)base;
    485     nt = (PIMAGE_NT_HEADERS)((char *)base + dos->e_lfanew);
    486     if(dos->e_magic == IMAGE_DOS_SIGNATURE /* 0x5A4D */
    487       && nt->Signature == IMAGE_NT_SIGNATURE /* 0x00004550 */
    488       && nt->FileHeader.Machine == IMAGE_FILE_MACHINE_I386
    489       && nt->OptionalHeader.Magic == 0x10b /* IMAGE_NT_OPTIONAL_HDR32_MAGIC */)
    490     {
    491         ret = get_base_address(pid);
    492         /* Base address not found in the running process. Falling back
    493          * to the header's information, which is unreliable because of
    494          * Vista's address space randomisation. */
    495         if (!ret)
    496             ret = (intptr_t)nt->OptionalHeader.ImageBase;
    497 
    498         ret += (intptr_t)nt->OptionalHeader.AddressOfEntryPoint;
    499     }
    500 
    501     UnmapViewOfFile(base);
    502     CloseHandle(map);
    503     CloseHandle(file);
    504 
    505     return ret;
    506 }
    507 
    508 /* FIXME: this could probably be merged with get_entry_point */
    509450static intptr_t get_proc_address(void *process, DWORD pid, const char *func)
    510451{
     
    573514}
    574515
    575 /* Find the process's base address once it is loaded in memory (the header
    576  * information is unreliable because of Vista's ASLR).
    577  * FIXME: this does not work properly because CreateToolhelp32Snapshot()
    578  * requires a certain level of initialisation. */
    579 static intptr_t get_base_address(DWORD pid)
    580 {
    581     MODULEENTRY32 entry;
    582     intptr_t ret = 0;
    583 
    584     void *list;
    585     int k;
    586 
    587     list = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
    588     entry.dwSize = sizeof(entry);
    589     for(k = Module32First(list, &entry); k; k = Module32Next(list, &entry))
    590     {
    591         /* FIXME: how do we select the correct module? */
    592         ret = (intptr_t)entry.modBaseAddr;
    593     }
    594     CloseHandle(list);
    595 
    596     return ret;
    597 }
    598 
    599 #endif
     516#endif
Note: See TracChangeset for help on using the changeset viewer.