2

I'm trying make a hook in MessageBoxA api in a remote process made by me using IAT hook tecnique. I'm using Process Hacker software for inject my dll file into my process and until here works fine.

My unique trouble is that MessageBoxA never is intercepted when i will call this api from my application.

I have discovered that this api don't can be found in table of import of my process.

So, i want know any suggestion about how i can find this api on table.

Here is code that i use:

#include <windows.h>
#include <string.h>
#include <stdio.h>

void HookFunction(char* funcName, LPDWORD function);
LPDWORD FoundIAT(char* funcName);

int WINAPI HookMessageBoxA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);  

BOOL APIENTRY DllMain (HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) 
{
    if(dwReason == DLL_PROCESS_ATTACH)
    {
        MessageBox(NULL, "Injeted with success!", "Hello", NULL);
        HookFunction("MessageBoxA", (LPDWORD)&HookMessageBoxA);
    }
    return TRUE;
}

void HookFunction(char* funcName, LPDWORD function)
{
    LPDWORD pOldFunction = FoundIAT(funcName);

    DWORD accessProtectionValue , accessProtec;

    int vProtect = VirtualProtect(pOldFunction, sizeof(LPDWORD), PAGE_EXECUTE_READWRITE, &accessProtectionValue);

    *pOldFunction = (DWORD)function;

    vProtect = VirtualProtect(pOldFunction, sizeof(LPDWORD), accessProtectionValue, &accessProtec);
}

int WINAPI HookMessageBoxA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
    return MessageBoxA(hWnd, "Hello", "DLL answering here!", uType);
}

LPDWORD FoundIAT(char* funcName)
{
    DWORD test = 0;

    LPVOID pMapping = GetModuleHandle(NULL);

    if (pMapping == NULL)

        exit(-1);

    PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER) pMapping;

    if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)

        exit(-1);

    PIMAGE_NT_HEADERS NtHeaders = (PIMAGE_NT_HEADERS) ((char*) DosHeader + DosHeader->e_lfanew);

    if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)

        exit(-1);

    PIMAGE_DATA_DIRECTORY DataDirectory = &NtHeaders->OptionalHeader.DataDirectory[1];

    PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR) ((char*) DosHeader + DataDirectory->VirtualAddress);

    PIMAGE_THUNK_DATA32 OriginalFirstThunk = (PIMAGE_THUNK_DATA32)((char*) DosHeader + ImportDescriptor->OriginalFirstThunk);

    while(OriginalFirstThunk != 0)
    {
        DWORD name = (DWORD)((char*) pMapping + ImportDescriptor->Name);

        OriginalFirstThunk = (PIMAGE_THUNK_DATA32)((char*) DosHeader + ImportDescriptor->OriginalFirstThunk);

        PIMAGE_THUNK_DATA32 FirstThunk = (PIMAGE_THUNK_DATA32)((char*) DosHeader + ImportDescriptor->FirstThunk);

        while(OriginalFirstThunk->u1.AddressOfData != 0)
        {
            PIMAGE_IMPORT_BY_NAME NameImg = (PIMAGE_IMPORT_BY_NAME)((char*) DosHeader + (DWORD)OriginalFirstThunk->u1.AddressOfData);

            test = (DWORD)OriginalFirstThunk->u1.Function & (DWORD)IMAGE_ORDINAL_FLAG32;

            if (test == 0)
            {
                if(strcmp(funcName, (const char*)NameImg->Name) == 0)
                {
                    MessageBox(NULL, NameImg->Name, "", NULL);
                    return (LPDWORD)&(FirstThunk->u1.Function);
                }
            }
            OriginalFirstThunk++;
            FirstThunk++;
        }
        ImportDescriptor++;
    }
    return 0;
}

Source

EDIT 1:

I have seen with more datails, that now this code is able to find MessageBoxA api :D, but still when i'll call this api from my application (made in Delphi), the hook don't work. :-(

My Delphi code here:

procedure TForm1.btn1Click(Sender: TObject);
begin
 MessageBoxA(Application.Handle, 'Delphi application here!', 'Hello',0);
end;

EDIT 2:

This can be a definitive solution, but link is offline. Someone can help me about how it can be adapted to my code above please?

Community
  • 1
  • 1
  • Where did you read that Windows maps PIMAGE_DOS_HEADER into the process space? – Serge Sep 07 '16 at 18:46
  • @Serge, i edited my question above. –  Sep 07 '16 at 20:35
  • Could you run equivalent of `printf("%04x\n", *(WORD*)pMapping)` for me please (I have no windows) – Serge Sep 07 '16 at 21:16
  • @Serge, my dll code not have a Console Window. So how stays this in a `MessageBox`? –  Sep 07 '16 at 21:26
  • just simple console app that get a handle of any library, say msvcrt.dll (I might be incorrect with that particular name) – Serge Sep 07 '16 at 21:28
  • But if you want know if `pMapping` is `== NULL`. No, it's not. –  Sep 07 '16 at 21:35
  • I want to know the content of two bytes at address that is numericaly equal to a handle returned by GetModuleHandle() call for any dll mapped into the process – Serge Sep 07 '16 at 21:37
  • @Serge, I have done: `char *charData = (char*)pMapping; MessageBox(NULL, charData, "Hello", NULL);` and this returns the string `MZP` –  Sep 07 '16 at 22:00
  • Strange. Indeed dos-header. It seems I started to forget the things. Ok, sorry for confusing you. Anyway, why do you expect the hooked func to be called by every process while you injected it into a single process using virt mem write? – Serge Sep 07 '16 at 22:05
  • @Serge, The idea here is inject a dll with this code above in my app, and when i call `MessageBoxA` from my Delphi application not appear "Delphi application here!" :D. But without success for make it works until now. –  Sep 07 '16 at 22:11
  • So you are pretty sure that you inject the module into your Delphi app, the function get hooked but then not activated by the call to MessageBoxA from with this delphi app. correct? – Serge Sep 07 '16 at 22:14
  • @Serge, Yes, So, this line here `MessageBoxA(hWnd, "Hello", "DLL answering here!", uType);` that should be executed when call `MessageBoxA` from my Delphi app. This is api hooking tecnique :D. I'll test now on Windows XP and see if works, because don't is working on Windows 7 here. –  Sep 07 '16 at 22:21
  • @Serge, your last suggestion not worked :-( –  Sep 07 '16 at 22:28
  • @Serge, on my code above, in this line: `MessageBox(NULL, NameImg->Name, "", NULL); ` is returned `MessageBoxA` and dll is injected with sucess on my Delphi app :D –  Sep 07 '16 at 22:39
  • Sorry, I misread you – Serge Sep 07 '16 at 22:43
  • @Serge, I think that `FoundIAT` method, before of close the last `}` is retuning always 0 and not `(LPDWORD)&(FirstThunk->u1.Function);`. This could be a error? –  Sep 07 '16 at 22:48
  • Hardly. If it returns 0, the HookFunction does not check the returned value and it would set the IAT enntry at zero, so any attempt to access that address should cause GP fault – Serge Sep 07 '16 at 22:55
  • Do you see `"Injeted with success!", "Hello"` dialog on win7? – Serge Sep 07 '16 at 22:56
  • @Serge, Yes, I see :D –  Sep 07 '16 at 23:03
  • Then it looks strange. Unfortunatelly, I can't help, as I already mentioned I have no windows, thank god! – Serge Sep 07 '16 at 23:08

0 Answers0