C语言 IAT钩子上的MessageBoxA -函数不断调用对方



我不太明白发生了什么,但我会解释这个问题。我正在尝试编写一个IAT钩子程序,它在IAT中切换MessageBoxA函数的地址,使其指向我的函数,一个恶意的函数。

下面是我的代码,注释:
#include <Windows.h>
#include <stdio.h>
typedef int(__stdcall* FunctionLikeMessageBoxA) (HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
FunctionLikeMessageBoxA originalMsgBoxA = MessageBoxA; // the original MessageBoxA function, before IAT hooking.

int print_evil(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
    printf("Evil print");
    Sleep(1000);
    return originalMsgBoxA(hWnd, lpText, lpCaption, uType);
}
int main()
{
    // message box before IAT unhooking
    MessageBoxA(NULL, "Before Hooking", "Before Hooking", 0);
    LPVOID imageBase = GetModuleHandleA(NULL); // image base, start of the loaded code (?)
    PIMAGE_DOS_HEADER dosHeaders = (PIMAGE_DOS_HEADER)imageBase; // dos headers
    PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)imageBase + dosHeaders->e_lfanew); // ntHeaders are in e_lfanew
    PIMAGE_IMPORT_DESCRIPTOR importDescriptor = NULL;
    IMAGE_DATA_DIRECTORY importsDirectory = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; // IAT
    importDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(importsDirectory.VirtualAddress + (DWORD_PTR)imageBase); // img descriptor
    LPCSTR currentLibraryName = NULL;
    HMODULE loadedLibrary = NULL;
    PIMAGE_IMPORT_BY_NAME functionName = NULL;
    while (importDescriptor->Name != NULL) // run until library name is not null, meaning we have libraries
    {
        currentLibraryName = (LPCSTR)importDescriptor->Name + (DWORD_PTR)imageBase; // get name of library
        loadedLibrary = LoadLibraryA(currentLibraryName); // loading the dll library
        if (loadedLibrary)
        {
            PIMAGE_THUNK_DATA originalFirstThunk = NULL;
            PIMAGE_THUNK_DATA firstThunk = NULL;
            // thunk where the functions are located  (?)
            originalFirstThunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)imageBase + importDescriptor->OriginalFirstThunk); // the INT (Names)
            firstThunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)imageBase + importDescriptor->FirstThunk); // the IAT (Addresses)
            while (originalFirstThunk->u1.AddressOfData != NULL) // run until function name is not null, meaning we have functions
            {
                functionName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)imageBase + originalFirstThunk->u1.AddressOfData); // name of function
                // if name is MessageBoxA, what we need, then switch the Function address of the function in the IAT, to our function.
                if (strcmp(functionName->Name, "MessageBoxA") == 0)
                {
                    DWORD oldProtect = 0;
                    VirtualProtect((LPVOID)(&firstThunk->u1.Function), 8, PAGE_READWRITE, &oldProtect);
                    firstThunk->u1.Function = (DWORD_PTR)print_evil;
                    DWORD newProtect = 0;
                    VirtualProtect((LPVOID)(&firstThunk->u1.Function), 8, oldProtect, &newProtect);
                }
                // increase to go over the next functions.
                originalFirstThunk++;
                firstThunk++;
            }
        }
        // increase to go over the next dlls.
        importDescriptor++;
    }
    // after IAT hooking
    MessageBoxA(0, "Hello", "Hello msg", 0);
    return 0;
}

代码应该输出&;evil print&;一次。但是它只是一遍又一遍地打印它(我添加了睡眠(1000),所以它不会因为太多的打印而缓冲区溢出…)。

我的猜测是,底部的MessageBoxA实际上调用了print_evil函数,而print_evil函数反复调用自己。

我没有任何解决办法。任何帮助将不胜感激!

代码应该输出&;evil print&;一次。但是它只是一遍又一遍地打印它(我添加了睡眠(1000),所以它不会因为太多的打印而缓冲区溢出…)。

您在编译阶段静态地分配前'MessageBox()'的地址。真正的地址是在程序提交到内存时由加载程序分配的。

在执行流程中按如下方式移动赋值:

#include <Windows.h>
#include <stdio.h>
typedef int (__stdcall * FunctionLikeMessageBoxA) (HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
FunctionLikeMessageBoxA originalMsgBoxA = NULL; // the original MessageBoxA function, before IAT hooking.
int print_evil(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
    printf("Evil print");
    Sleep(1000);
    return originalMsgBoxA(hWnd, lpText, lpCaption, uType);
}
int main(int argc, char *argv[])
{
    originalMsgBoxA = MessageBoxA;  // Assign here the original MessageBoxA function.
    // message box before IAT unhooking
    MessageBoxA(NULL, "Before Hooking", "Before Hooking", 0);
    LPVOID imageBase = GetModuleHandleA(NULL);  // image base, start of the loaded code (?)
    PIMAGE_DOS_HEADER dosHeaders = (PIMAGE_DOS_HEADER)imageBase;    // dos headers
    PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS) ((DWORD_PTR)imageBase + dosHeaders->e_lfanew);    // ntHeaders are in e_lfanew
    PIMAGE_IMPORT_DESCRIPTOR importDescriptor = NULL;
    IMAGE_DATA_DIRECTORY importsDirectory = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];  // IAT
    importDescriptor = (PIMAGE_IMPORT_DESCRIPTOR) (importsDirectory.VirtualAddress + (DWORD_PTR)imageBase); // img descriptor
    LPCSTR currentLibraryName = NULL;
    HMODULE loadedLibrary = NULL;
    PIMAGE_IMPORT_BY_NAME functionName = NULL;
    while (importDescriptor->Name != 0) // run until library name is not null, meaning we have libraries
    {
        currentLibraryName = (LPCSTR)importDescriptor->Name + (DWORD_PTR)imageBase; // get name of library
        loadedLibrary = LoadLibraryA(currentLibraryName);   // loading the dll library
        if (loadedLibrary)
        {
            PIMAGE_THUNK_DATA originalFirstThunk = NULL;
            PIMAGE_THUNK_DATA firstThunk = NULL;
            // thunk where the functions are located  (?)
            originalFirstThunk = (PIMAGE_THUNK_DATA) ((DWORD_PTR)imageBase + importDescriptor->OriginalFirstThunk); // the INT (Names)
            firstThunk = (PIMAGE_THUNK_DATA) ((DWORD_PTR)imageBase + importDescriptor->FirstThunk); // the IAT (Addresses)
            while (originalFirstThunk->u1.AddressOfData != 0)   // run until function name is not null, meaning we have functions
            {
                functionName = (PIMAGE_IMPORT_BY_NAME) ((DWORD_PTR)imageBase + originalFirstThunk->u1.AddressOfData);   // name of function
                // if name is MessageBoxA, what we need, then switch the Function address of the function in the IAT, to our function.
                if (strcmp(functionName->Name, "MessageBoxA") == 0)
                {
                    DWORD oldProtect = 0;
                    VirtualProtect((LPVOID) (&firstThunk->u1.Function), 8, PAGE_READWRITE, &oldProtect);
                    firstThunk->u1.Function = (DWORD_PTR)print_evil;
                    DWORD newProtect = 0;
                    VirtualProtect((LPVOID) (&firstThunk->u1.Function), 8, oldProtect, &newProtect);
                }
                // increase to go over the next functions.
                originalFirstThunk++;
                firstThunk++;
            }
        }
        // increase to go over the next dlls.
        importDescriptor++;
    }
    // after IAT hooking
    MessageBoxA(0, "Hello", "Hello msg", 0);
    return 0;
}

相关内容

  • 没有找到相关文章

最新更新