0

I'm still working on my same project (in case you wondering why I ask so many questions.) Anyway I switched from compiler, from mingw32 (mingw.org) to MinGW-w64 (mingw-w64.sourceforge.net/)

While the project compiles fine without any error, the injector doesn't work, without giving any errors or something. Here is the source:

int Inject(DWORD pID) 
{ 
    HANDLE hProcess;
    if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID)))
        return 0;

    char* szDllName = "subclass64.dll";

    LPVOID LoadLibraryAddress;
    if ((LoadLibraryAddress = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA")) == NULL)
    {
        char buf[32];
        sprintf(buf, "%d", GetLastError());
        MessageBox(0, buf, "", 0);

        CloseHandle(hProcess);
        return 0;
    }

    LPVOID lpStringAddress;
    if ((lpStringAddress = (LPVOID)VirtualAllocEx(hProcess, NULL, strlen(szDllName), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)) == NULL)
    {
        char buf[32];
        sprintf(buf, "%d", GetLastError());
        MessageBox(0, buf, "", 0);

        CloseHandle(hProcess);
        return 0;
    }

    if (WriteProcessMemory(hProcess, lpStringAddress, szDllName, strlen(szDllName), NULL) == 0)
    {
        char buf[32];
        sprintf(buf, "%d", GetLastError());
        MessageBox(0, buf, "", 0);

        CloseHandle(hProcess);
        return 0;
    }

    HANDLE hThread;
    if ((hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryAddress, lpStringAddress, 0, NULL)) == NULL)
    {
        char buf[32];
        sprintf(buf, "%d", GetLastError());
        MessageBox(0, buf, "", 0);

        CloseHandle(hProcess);
        return 0;
    }

    CloseHandle(hProcess); 
    return 1; 
}

I debugged as well, but I didn't get any weird values:

(gdb) p hProcess
$1 = (HANDLE) 0xec
(gdb) p LoadLibraryAddress
$2 = (LPVOID) 0x7f9de0528ac <LoadLibraryA>
(gdb) p lpStringAddress
$3 = (LPVOID) 0x8a4d10000
(gdb) p hThread
$4 = (HANDLE) 0xf0
(gdb) p GetLastError()
$5 = 0

Nothing is wrong with the DLL because it works fine with another DLL Injector (from the internet)

Edit: It works fine with a dummy/test application, but it doesn't with notepad for example (which works with using an third party injector.)

Hopefully someone could help me, regards

joell
  • 396
  • 6
  • 17
  • You are debugging the wrong process, the GetLastError return value will be only valid on the thread that you started. Attach the debugger to the injected process just before your program calls CreateRemoteThread. Forgetting the zero terminator is an obvious bug, so is not specifying the full path of the DLL. – Hans Passant Jan 07 '13 at 16:50
  • 1
    You've another problem - kernel32.dll can (and will) likely be loaded at a different address in your target process if ASLR is enabled. This means that the address of LoadLibraryA() in your application won't be the same in your target process.., – Bukes Jan 07 '13 at 21:47
  • [The addresses of modules like kernel32.dll are randomized when the machine boots but are the same for all processes.](http://stackoverflow.com/questions/8568901/would-aslr-cause-friction-for-the-address-with-dll-injection) – joell Jan 07 '13 at 21:59

2 Answers2

2

One problem is that the name of the DLL in the target process is not null terminated, as only strlen(szDllName) bytes are being allocated and written. Change the the string handling logic to allocate and write strlen(szDllName) + 1 to ensure the string is null terminated.

Note that the DLL to be injected, subclass64.dll, must be in the same directory as the target process or its PATH environment variable must include the directory were the DLL resides.

hmjd
  • 120,187
  • 20
  • 207
  • 252
  • It probably didn't compile right but it does work, but it only works for a dummy application, injecting in notepad doesn't work. (Which does with a third party injector.) – joell Jan 07 '13 at 17:46
  • VirtualAllocEx() zero-initializes the memory so NULL termination is not strictly necessary, but it should be done for the sake of correctness. Also, just a nitpick: the DLL needs to be in the target's current directory which is not necessarily the same directory where it exists on disk. – Luke Jan 08 '13 at 16:00
  • @Luke, without the `+ 1` there is not enough memory for the null terminator and you are correct bout the DLL location but I stated _in the same directory as the target process_, not the _target executable_. – hmjd Jan 08 '13 at 16:06
0

I switched from compiler to Visual Studio, in there it didn't worked at first but then it did. The answer for this is not to debug. So you navigate to the path of the application and then start the program manually.

joell
  • 396
  • 6
  • 17