-3

I`m trying to inject a DLL in a process and call a exported function in my DLL.

The DLL is injected alright with that code:

HANDLE Proc;
char buf[50] = { 0 };
LPVOID RemoteString, LoadLibAddy;
if (!pID)
    return false;
Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
if (!Proc)
{
    sprintf_s(buf, "OpenProcess() failed: %d", GetLastError());
    printf(buf);
    return false;
}

LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
// Allocate space in the process for our DLL 
RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(DLL_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
// Write the string name of our DLL in the memory allocated 
WriteProcessMemory(Proc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME), NULL);
// Load our DLL 
HANDLE hThread = CreateRemoteThread(Proc, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL);

The module of my DLL is created OK, like you see in that image of Process Hacker (BootstrapDLL.exe):

enter image description here

My exported functions is ok too, like you see in the list of functions exported on Process Hacker (ImplantDotNetAssembly):

enter image description here

The problems, I think, happens on the offset calculation to get the address of the "ImplantDotNetAssembly", because everything above is alright and when I do the calculation I get the address of the "ImplantDotNetAssembly", but when I call CreateRemoteThread again to call it, the window "Has stopped working..." of the windows is showed and the process stoped. What`s happening?

Here is the code of the calculation of the offset:

DWORD_PTR hBootstrap = GetRemoteModuleHandle(ProcId, L"BootstrapDLL.exe");
DWORD_PTR offset = GetFunctionOffset(L"C:\\Users\\Acaz\\Documents\\Visual Studio 2013\\Projects\\Contoso\\Debug\\BootstrapDLL.exe", "ImplantDotNetAssembly");
DWORD_PTR fnImplant = hBootstrap + offset;

HANDLE hThread2 = CreateRemoteThread(Proc, NULL, 0, (LPTHREAD_START_ROUTINE)fnImplant, NULL, 0, NULL);

Here are the functions GetRemoteModuleHandle and GetFunctionOffset:

DWORD_PTR GetFunctionOffset(const wstring& library, const char* functionName)
{
    // load library into this process
    HMODULE hLoaded = LoadLibrary(library.c_str());

    // get address of function to invoke
    void* lpInject = GetProcAddress(hLoaded, functionName);

    // compute the distance between the base address and the function to invoke
    DWORD_PTR offset = (DWORD_PTR)lpInject - (DWORD_PTR)hLoaded;

    // unload library from this process
    FreeLibrary(hLoaded);

    // return the offset to the function
    return offset;
}

DWORD_PTR GetRemoteModuleHandle(const int processId, const wchar_t* moduleName)
{
    MODULEENTRY32 me32;
    HANDLE hSnapshot = INVALID_HANDLE_VALUE;

    // get snapshot of all modules in the remote process 
    me32.dwSize = sizeof(MODULEENTRY32);
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processId);

    // can we start looking?
    if (!Module32First(hSnapshot, &me32))
    {
        CloseHandle(hSnapshot);
        return 0;
    }

    // enumerate all modules till we find the one we are looking for or until every one of them is checked
    while (wcscmp(me32.szModule, moduleName) != 0 && Module32Next(hSnapshot, &me32));

    // close the handle
    CloseHandle(hSnapshot);

    // check if module handle was found and return it
    if (wcscmp(me32.szModule, moduleName) == 0)
        return (DWORD_PTR)me32.modBaseAddr;

    return 0;
}

If someone know what is happening, I'll be very grateful!

I cant`t even debug the "has stopped work.." error. When I clik in the DEBUG button on the window, the error throw again and everything stop.

Thank you.

Acaz Souza
  • 8,311
  • 11
  • 54
  • 97
  • This looks like hacker crap. If it winds up on my computer, who shall I send the bill to for getting it removed? – Robert Harvey Jul 14 '14 at 16:43
  • To start with, your allocation and `WriteProcessMemory` didn't account for the terminating `\0` character. – T.C. Jul 14 '14 at 16:43
  • @T.C. terminating \0? How? – Acaz Souza Jul 14 '14 at 16:48
  • @AcazSouza A C-style string is \0-terminated, which `strlen` doesn't count. – T.C. Jul 14 '14 at 16:49
  • @T.C. but my dll is loaded alright, like you see in the process hacker image. The module of the dll is loaded OK. – Acaz Souza Jul 14 '14 at 16:56
  • The terminating \0 is already there because the VM allocation allocated a page of zeros. It is disturbing you are trying this and don't know even the right question to ask when the \0 is referenced. – Joshua Jul 14 '14 at 18:11
  • @Joshua this is C++, i saw that C++ string refers to std::string which is different from C. – Acaz Souza Jul 15 '14 at 12:59

1 Answers1

0

NEVER inject managed assemblies. If for some reason you must inject code into another process, use native code with either NO C library or a STATIC C library.

Joshua
  • 40,822
  • 8
  • 72
  • 132
  • Could you explain why Joshua? I saw a lot of examples injecting managed assemblies?! – Acaz Souza Jul 14 '14 at 16:55
  • @AcazSouza: If you own this managed assembly, there's almost certainly a better way than code injection to do what you are attempting. – Robert Harvey Jul 14 '14 at 17:00
  • Can you tell me what ways? I found this example here: http://www.codeproject.com/Articles/607352/Injecting-Net-Assemblies-Into-Unmanaged-Processes?fid=1835473&df=90&mpp=25&noise=3&prof=False&sort=Position&view=Normal&spc=Relaxed – Acaz Souza Jul 14 '14 at 17:02
  • 1
    What happens if the EXE you are injecting wants a different version of the framework than you do? – Joshua Jul 14 '14 at 17:13
  • Thank you @Joshua the function is calling right. The problem is in my ImplantDotNetAssembly method. – Acaz Souza Jul 14 '14 at 17:32
  • @Joshua but, about your answer. I have to inject a managed assembly because Ill have to write a lot of code in that assembly, I dont know C/c++, I have to write this code in c#. What you say? – Acaz Souza Jul 14 '14 at 17:33
  • I say if you don't know an unmanaged languate than you have no business injecting code. Learning C is easier than learning how to inject into somebody else's process and reliably not screw it up. You need to know the principles of memory management, thread race, deadlock, and the loader lock to even begin playing with this. – Joshua Jul 14 '14 at 18:09
  • 1
    @Joshua Oh man, I don't want to discuss with you if C is easy or not. What I want is to discuss why my code is not working, but nobody wants to help. – Acaz Souza Jul 15 '14 at 13:01
  • Your code doesn't work as a direct consequence of injecting a managed DLL rather than an unmanaged one. You tried to call GetProcAddress on a managed function and apply the result to another process. That cannot and does not work. – Joshua Jul 15 '14 at 15:14
  • @Joshua Why this link is saying otherwise? http://codingthewheel.com/archives/how-to-inject-a-managed-assembly-dll/ And why that is saying otherwise too? http://www.codeproject.com/Articles/607352/Injecting-Net-Assemblies-Into-Unmanaged-Processes#LoadTheCLRFundamentals Why these guys manage to do that? – Acaz Souza Jul 17 '14 at 13:05
  • Because they inject a native DLL that then loads .NET and the managed .DLL normally. – Joshua Jul 17 '14 at 15:08
  • @Joshua I'm doing the same man! I'm getting a error trying to initializing the .Net Runtime now. My BootstrapDLL.exe is a native C++ application. – Acaz Souza Jul 18 '14 at 14:31