c++visual-c++api-hook

Anti dll Injection with API Hooking "Access Violation writing location 0x0000000000"


I'm using the JMP instruction tecnique for try make a Anti-Dll Injection with detour when LdrLoadDll api is called inside my program. I found a Delphi code that works perfectly, but this VC++ 2013 version for this code, crashes with a

"Access Violation writing location 0x0000000000"

with showed below.

So, how I can solve this trouble? Someone can help me please?

Thanks in advance.

Delphi version:

procedure hook(target, newfunc:pointer); 
var 
  jmpto:dword; 
    OldProtect: Cardinal; // old protect in memory 
begin 
  jmpto:=dword(newfunc)-dword(target)-5; 
  VirtualProtect(target, 5, PAGE_EXECUTE_READWRITE, @OldProtect); 
  pbyte(target)^:=$e9; 
  pdword(dword(target)+1)^:=jmpto; 
end; 

procedure myLdrLoadDll(PathToFile:PAnsiChar; Flags:variant; ModuleFileName:PAnsiChar; var ModuleHandle:THandle); 
begin 
  MessageBox(0, 'I have blocked your attempt to inject a dll file!!', 'WARNING!', MB_OK); 
  ModuleHandle:=0; 
end; 

procedure Main; 
begin 
Hook(GetProcAddress(GetModuleHandle('ntdll.dll'), 'LdrLoadDll'), @myLdrLoadDll); 
end; 

begin 
end.

Trying translate for VC++ 2013 version:

 BOOL TrampolineAPI(HMODULE hModule, LPCWSTR DllName, LPCSTR ProcName, DWORD dwReplaced)
    {
        DWORD dwReturn;
        DWORD dwOldProtect;
        DWORD dwAddressToHook = (DWORD)GetProcAddress(GetModuleHandle(DllName), ProcName);
        BYTE *pbTargetCode = (BYTE *)dwAddressToHook;
        BYTE *pbReplaced = (BYTE *)dwReplaced;
        VirtualProtect((LPVOID)dwAddressToHook, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
        *pbTargetCode++ = 0xE9;   // My trouble is here
        *((signed int*)(pbTargetCode)) = pbReplaced - (pbTargetCode + 4);
        VirtualProtect((LPVOID)dwAddressToHook, 5, PAGE_EXECUTE, &dwOldProtect);
        dwReturn = dwAddressToHook + 5;
        FlushInstructionCache(GetCurrentProcess(), NULL, NULL);
        return TRUE;
    }

    void WINAPI Replaced(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
    {
        printf("Invasion!!");
    }



    int _tmain(int argc, _TCHAR* argv[])
    {

        while (true)
        {
 TrampolineAPI(GetModuleHandle(0), (LPCWSTR)"ntdll.DLL","LdrLoadDLL"(DWORD)Replaced);


        }


        return 0;
    }

Solution

  • At least one problem you are having is a mix between ANSI and Unicode strings.

    In Win32, there are two types of encodings you'll find - Unicode (2-byte characters) and ANSI (1-byte characters). String types you'll encounter for ANSI are LPSTR, LPCSTR, etc. Wide character Unicode types are LPWSTR, LPCWSTR, etc.

    There are also two types of functions in Win32 - for instance, GetModuleHandleA, and GetModuleHandleW. The way you determine which one is used is easy:

    #ifdef UNICODE
    #define GetModuleHandle GetModuleHandleW
    #else
    #define GetModuleHandle GetModuleHandleA
    #endif //!UNICODE
    

    In your particular case, you are casting a string constant with ANSI encoding to a wide-character Unicode string. This is undefined behavior. Change TrampolineAPI(...); in your main function to the following:

    TrampolineAPI(GetModuleHandle(0), L"ntdll.DLL", "LdrLoadDLL", (DWORD)Replaced);
    

    The L"ntdll.DLL" is how you define a wide-character string constant. This also avoids the typecast.

    I would also recommend using the same string encoding throughout your program. This would require you to also change the signature of TrampolineAPI to

    BOOL TrampolineAPI(HMODULE hModule, LPCWSTR DllName, LPCWSTR ProcName, DWORD dwReplaced) { ... }
    

    And change the call in main to

    TrampolineAPI(GetModuleHandle(0), L"ntdll.DLL", L"LdrLoadDLL", (DWORD)Replaced);