A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about user-mode development.
 #10450  by __fastcall
 Sun Dec 18, 2011 1:21 pm
Hello guys,
I've got an little question ...

So i'v written an little app with this injection module i found on the web
Code: Select all
#include <windows.h>
#include <tlhelp32.h>

DWORD GetProcessIdByName(LPWSTR name)
{
    PROCESSENTRY32 pe32;
    HANDLE snapshot = NULL;
    DWORD pid = 0;

    snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (snapshot != INVALID_HANDLE_VALUE) {
        pe32.dwSize = sizeof(PROCESSENTRY32);

        if (Process32First(snapshot, &pe32)) {
            do {
                if (!lstrcmp(pe32.szExeFile, name)) {
        pid = pe32.th32ProcessID;
        break;
                }
            } while (Process32Next(snapshot, &pe32));
        }

        CloseHandle(snapshot);
    }

    return pid;
}

LPVOID CopyModule(HANDLE proc, LPVOID image)
{
    PIMAGE_NT_HEADERS headers = (PIMAGE_NT_HEADERS)((LPBYTE)image + ((PIMAGE_DOS_HEADER)image)->e_lfanew);
    PIMAGE_DATA_DIRECTORY datadir;
    DWORD size = headers->OptionalHeader.SizeOfImage;
    LPVOID mem = NULL;
    LPBYTE buf = NULL;
    BOOL ok = FALSE;

    if (headers->Signature != IMAGE_NT_SIGNATURE)
        return NULL;

    if (IsBadReadPtr(image, size))
        return NULL;

    mem = VirtualAllocEx(proc, NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    if (mem != NULL) {
        buf = (LPBYTE)VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

        if (buf != NULL) {
            RtlCopyMemory(buf, image, size);

            datadir = &headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];

            if (datadir->Size > 0 && datadir->VirtualAddress > 0) {
                DWORD_PTR delta = (DWORD_PTR)((LPBYTE)mem - headers->OptionalHeader.ImageBase);
                DWORD_PTR olddelta = (DWORD_PTR)((LPBYTE)image - headers->OptionalHeader.ImageBase);
                PIMAGE_BASE_RELOCATION reloc = (PIMAGE_BASE_RELOCATION)(buf + datadir->VirtualAddress);

                while(reloc->VirtualAddress != 0) {
        if (reloc->SizeOfBlock >= sizeof(IMAGE_BASE_RELOCATION)) {
        DWORD count = (reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
        LPWORD list = (LPWORD)((LPBYTE)reloc + sizeof(IMAGE_BASE_RELOCATION));
        DWORD i;

        for (i = 0; i < count; i++) {
        if (list[i] > 0) {
        DWORD_PTR *p = (DWORD_PTR *)(buf + (reloc->VirtualAddress + (0x0FFF & (list[i]))));

        *p -= olddelta;
        *p += delta;
        }
        }
        }

        reloc = (PIMAGE_BASE_RELOCATION)((LPBYTE)reloc + reloc->SizeOfBlock);
                }

                ok = WriteProcessMemory(proc, mem, buf, size, NULL);
            }

            VirtualFree(buf, 0, MEM_RELEASE); // release buf
        }

        if (!ok) {
            VirtualFreeEx(proc, mem, 0, MEM_RELEASE);
            mem = NULL;
        }
    }

    return mem;
}

BOOL EnableDebugPrivileges(void)
{
    HANDLE token;
    TOKEN_PRIVILEGES priv;
    BOOL ret = FALSE;

    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) {
        priv.PrivilegeCount = 1;
        priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

        if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid) != FALSE &&
            AdjustTokenPrivileges(token, FALSE, &priv, 0, NULL, NULL) != FALSE) {
                ret = TRUE;
        }

        CloseHandle(token);
    }

    return ret;
}

BOOL BeginInject(DWORD pid, LPTHREAD_START_ROUTINE start)
{
    HANDLE proc, thread;
    HMODULE module, newmodule;
    BOOL ok = FALSE;

    proc = OpenProcess(PROCESS_QUERY_INFORMATION |
           PROCESS_VM_OPERATION |
           PROCESS_VM_WRITE |
          PROCESS_VM_READ |
          PROCESS_CREATE_THREAD |
          PROCESS_DUP_HANDLE,
          FALSE, pid);

    if (proc != NULL) {
        module = GetModuleHandle(NULL);

        newmodule = (HMODULE)CopyModule(proc, module);

        if (newmodule != NULL) {
            LPTHREAD_START_ROUTINE entry = (LPTHREAD_START_ROUTINE)((LPBYTE)newmodule + (DWORD_PTR)((LPBYTE)start - (LPBYTE)module));

            thread = CreateRemoteThread(proc, NULL, 0, entry, NULL, 0, NULL);

            if (thread != NULL) {
                CloseHandle(thread);
                ok = TRUE;
            }
            else {
                VirtualFreeEx(proc, module, 0, MEM_RELEASE);
            }
        }

        CloseHandle(proc);
    }

    return ok;
}

DWORD WINAPI ThreadProc(LPVOID param)
{
    MessageBox(NULL, L"well look at that :O", NULL, 0);

    return 0;
}

int wmain(void)
{
    // EnableDebugPrivileges(); attempt to aquire debugging privileges
    BeginInject(GetProcessIdByName(L"explorer.exe"), ThreadProc);

    return 0;
}

after that i tried to hook with this injection and it failed ..
I tried MsDetours , libMinHook and some other snippets from the web.
Does somebody know why , or what i can do to get it working ??

My Current Code :
Code: Select all
#include <Windows.h>
#include <detours.h>
#include "cInstall.h"
#include "cInjection.h"

typedef int (__stdcall * MBW) (
							   __in_opt HWND hWnd,
							   __in_opt LPCWSTR lpText,
							   __in_opt LPCWSTR lpCaption,
							   __in UINT uType);

static MBW MBW_O = NULL;

int MBW_N (
		   __in_opt HWND hWnd,
		   __in_opt LPCWSTR lpText,
		   __in_opt LPCWSTR lpCaption,
		   __in UINT uType)
{
	return MBW_O ( hWnd , L"Hooked." , lpCaption , uType);
}


DWORD __stdcall NewMain ( LPVOID param )
{
	
    MBW_O =(MBW)DetourFunction( (PBYTE)GetProcAddress(GetModuleHandleA("user32.dll"),"MessageBoxW"),(PBYTE)MBW_N );

	MessageBox( 0 , L"Gotcha.", L"" , 0);
	return 0;
}


int __stdcall WinMain ( HINSTANCE hInstance , HINSTANCE hPrevInstance , PSTR szCmdLine , int nShow )
{
	
	cInjection Injector;
	
    Injector.EnableDebugPrivileges();
	Injector.InjectAll( NewMain );

	return 0;
}


After the execution crashes all Processes which got injected.
Thanx for all replys :)
 #10451  by rkhunter
 Sun Dec 18, 2011 2:51 pm
You can use debugger for this purpose and look into target process. Or use ProcMon for get stack trace of application that was crashed.
 #10726  by Brock
 Sat Dec 31, 2011 11:27 am
__fastcall,

I am glad that you have figured out your dilemma but I don't see why obtaining the debug privilege is so lengthy, why not direct RtlAdjustPrivilege(0x14, ...); ? If you want the 100% documented way then this is fine. Also, CreateRemoteThread is limited when it comes to process session isolation, not to mention that it mainly prefers processes which are already initialized or it can be problematic i.e> uninitialized processes. Your injection method needs much refining for stability and reliability