Crashes after Injecting std functions in a process

339 views Asked by At

i am currently trying out PE injection and noticed that as soon as i use stuff like std::cout or std::string my target process which i injected in crashes. Messageboxes or even printf() works fine. The code compiles without an error and i read about the import table not being at the same location in the injected process could cause it to crash but i have no idea what to do in order to fix it (re load the import table). Thanks in advance and here is the injection example:

#include <iostream>
#include <stdio.h>
#include <Windows.h>

void ThreadProc(PVOID p)
{
    MessageBox(NULL,"Message from injected code!","Message",MB_ICONINFORMATION); //funktioniert einwandfrei
    RedirectOutput();
    std::cout << "hi"; //crashed
}

int main(int argc,char* argv[])
{
    PIMAGE_DOS_HEADER pIDH;
    PIMAGE_NT_HEADERS pINH;
    PIMAGE_BASE_RELOCATION pIBR;

    HANDLE hProcess,hThread;
    PUSHORT TypeOffset;

    PVOID ImageBase,Buffer,mem;
    ULONG i,Count,Delta,*p;

    printf("\nOpening target process\n");

    hProcess=OpenProcess(
        PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE,
        FALSE,
       13371337);

    if(!hProcess)
    {
        printf("\nError: Unable to open target process (%u)\n",GetLastError());
        return -1;
    }

    ImageBase=GetModuleHandle(NULL);
    printf("\nImage base in current process: %#x\n",ImageBase);

    pIDH=(PIMAGE_DOS_HEADER)ImageBase;
    pINH=(PIMAGE_NT_HEADERS)((PUCHAR)ImageBase+pIDH->e_lfanew);

    printf("\nAllocating memory in target process\n");
    mem=VirtualAllocEx(hProcess,NULL,pINH->OptionalHeader.SizeOfImage,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);

    if(!mem)
    {
        printf("\nError: Unable to allocate memory in target process (%u)\n",GetLastError());

        CloseHandle(hProcess);
        return 0;
    }

    printf("\nMemory allocated at %#x\n",mem);

    Buffer=VirtualAlloc(NULL,pINH->OptionalHeader.SizeOfImage,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
    memcpy(Buffer,ImageBase,pINH->OptionalHeader.SizeOfImage);

    printf("\nRelocating image\n");

    pIBR=(PIMAGE_BASE_RELOCATION)((PUCHAR)Buffer+pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
    Delta=(ULONG)mem-(ULONG)ImageBase;

    printf("\nDelta: %#x\n",Delta);

    while(pIBR->VirtualAddress)
    {
        if(pIBR->SizeOfBlock>=sizeof(IMAGE_BASE_RELOCATION))
        {
            Count=(pIBR->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/sizeof(USHORT);
            TypeOffset=(PUSHORT)(pIBR+1);

            for(i=0;i<Count;i++)
            {
                if(TypeOffset[i])
                {
                    p=(PULONG)((PUCHAR)Buffer+pIBR->VirtualAddress+(TypeOffset[i] & 0xFFF));
                    *p+=Delta;
                }
            }
        }

        pIBR=(PIMAGE_BASE_RELOCATION)((PUCHAR)pIBR+pIBR->SizeOfBlock);
    }

    printf("\nWriting relocated image into target process\n");

    if(!WriteProcessMemory(hProcess,mem,Buffer,pINH->OptionalHeader.SizeOfImage,NULL))
    {
        printf("\nError: Unable to write process memory (%u)\n",GetLastError());

        VirtualFreeEx(hProcess,mem,0,MEM_RELEASE);
        CloseHandle(hProcess);

        return -1;
    }

    VirtualFree(Buffer,0,MEM_RELEASE);

    printf("\nCreating thread in target process\n");
    hThread=CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)((PUCHAR)ThreadProc+Delta),NULL,0,NULL);

    if(!hThread)
    {
        printf("\nError: Unable to create thread in target process (%u)\n",GetLastError());

        VirtualFreeEx(hProcess,mem,0,MEM_RELEASE);
        CloseHandle(hProcess);

        return -1;
    }

    printf("\nWaiting for the thread to terminate\n");
    WaitForSingleObject(hThread,INFINITE);

    printf("\nThread terminated\n\nFreeing allocated memory\n");

    VirtualFreeEx(hProcess,mem,0,MEM_RELEASE);
    CloseHandle(hProcess);

    return 0;
}
2

There are 2 answers

2
Aso On

I think that answer simple - STL library request some initializations of global data. Via constructors of global objects, for example. But you just copy your code to target process. It don't invoke any initializations, that normally performed before call main function. Just try DLL injection instead.

0
user2073973 On

You don't seem to be loading the CRT dll in the target process, so what I'm assuming is that when you try to call the cout function, you are jumping to unallocated memory.

If the DLL is in fact loaded in the target process, make sure it's loaded at the same address as it is in your own process. Otherwise you'll have to patch your import table to match that of the target process.