Неработает код для перехвата Api-функции в Vista 64bit

Тема в разделе "Общие вопросы по С и С++", создана пользователем artemvyrtosu, 30 июн 2009.

  1. artemvyrtosu

    artemvyrtosu Гость

    Добрый день,

    Помогите пожалуйста решить следующую проблему. Я пытаюсь перехватить вызовы функции MessageBoxW во всех процессах системы. Интеграция в систему осуществляется за счет прописывания ключей:

    Код (Text):
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows]
    "AppInit_DLLs"="C:\\Windows\\System32\\NPHook64.dll"
    "LoadAppInit_DLLs"=dword:00000001

    (аналогично для 32-битной ветки)
    Мой код идеально работает под 32-битную XP. Но когда я осуществляю интеграцию в 64-битную Vista все перестает работать. Пробовал отключать контроль за кодом, проверки подписей, в конце концов подписывать мою длл-ку. Все до лампочки. Под 64-битную Vista длл-ка загружается (проверено на 100%) но не выполняется до конца.

    Гуглил сутками практически все примеры полный бред никак не работающий под 64-битную Vista. Укажите мне пожалуйста где у меня в коде ошибка чтобы оно работало и под Vista 64-bit.

    Еще одна проблема что OutputDebugStringW в удаленно подключенный WinDBG тоже ничего не выводит, в отличие опять же от своей идеальной работы в XP.

    Весь код собираю в VS2008. Тестирую в XP SP 3 и Vista x64 SP1.

    Код нижеcледует:

    (dllmain.c)
    Код (Text):
    #include "RQDFncLocator.h"

    #pragma pack (push, 1)

    extern FUNC_MAP _fncmap;

    BOOL WINAPI InterceptMessageBoxW(HWND hwnd, LPWSTR text, LPWSTR hdr, UINT utype)
    {
    try{
    BOOL (__stdcall* MessageBoxWAddr)(HWND, LPWSTR, LPWSTR, UINT) = NULL;

    MessageBoxWAddr = (BOOL (__stdcall*)(HWND, LPWSTR, LPWSTR, UINT))_fncmap["MessageBoxW"].second;

    return MessageBoxWAddr(hwnd, text, L"C410n has *цензура*ed your MessageBoxW", utype);
    }
    catch(...)
    {}
    }

    void InterceptFunctions()
    {
    FncInfo FI;
    FI.FillMapWithRealAddress("user32.dll","MessageBoxW");
    FI.InitializeModulePE(GetCurrentProcess(), 0x0);
    FI.InterceptSpecificFunction("user32.dll","MessageBoxW",InterceptMessageBoxW);
    }

    BOOL APIENTRY DllMain( HMODULE hModule,
    DWORD ul_reason_for_call,
    LPVOID lpReserved
    )
    {
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    InterceptFunctions();
    }
    return TRUE;
    }

    #pragma pack (show)
    (RQDFncLocator.h)
    Код (Text):
    #ifndef _RQDFncLocator_h_
    #define _RQDFncLocator_h_

    #pragma once

    #pragma pack(1)
    #pragma pack(push)
    #if defined (_WIN64)
    #pragma pack(16)
    #else
    #pragma pack(8)
    #endif

    #define UNICODE

    #include <windows.h>
    #include <Psapi.h>
    #include <stdlib.h>
    #include <stdio.h>

    #include <iostream>
    #include <string>
    #include <atlbase.h>
    #include <map>

    using std::wstring;
    using std::wcout;
    using std::map;

    #pragma pack(show)
    #pragma pack (pop)
    #pragma pack(show)

    #pragma pack (push, 1)

    #define OutputLogValue OutputDebugStringW//need this to be replaced

    #define RET(X,Y) {OutputLogValue( (Y) );return (X);}
    #define VRET(Y) {OutputLogValue(Y);return;}

    typedef std::pair<std::string,void*> LIBRARY_AND_POINTER;
    typedef map<std::string,LIBRARY_AND_POINTER> FUNC_MAP;

    FUNC_MAP _fncmap;

    struct FncInfo{
    public:

    struct PE_RET_INFO{
    public:
    IMAGE_FILE_HEADER *pe_head;
    IMAGE_OPTIONAL_HEADER *pe_opt_head;
    IMAGE_DOS_HEADER * mz_head;

    BYTE *pimage;

    DWORD peOffset;
    LPVOID ImportSecBeg;
    LPVOID ImportTable;

    IMAGE_IMPORT_DESCRIPTOR *DLLInfo;
    IMAGE_THUNK_DATA* thunk;
    } PE_Information;

    struct PROCESS_RET_INFO{
    public:
    HANDLE hProcess;
    DWORD PID;
    wchar_t processName[MAX_PATH + 1];
    } P_Information;

    FncInfo()
    {
    memset(P_Information.processName,0x0,MAX_PATH + 1);
    }

    bool FillMapWithRealAddress(char* Library, char* Function)
    {      
    void* RealAddr = GetProcAddress(GetModuleHandleA(Library), Function);

    if(RealAddr == NULL)
    {  
    RET(false,_T("Can't retrive MessageBoxW real address"));
    }

    LIBRARY_AND_POINTER fncdata;

    fncdata.first = Library;
    fncdata.second = RealAddr;

    _fncmap[Function] = fncdata;

    RET(true,_T("OK"));
    }

    wchar_t* InitializeModulePE(HANDLE _hProcess, wchar_t* moduleName)
    {      
    P_Information.hProcess = _hProcess;
    GetProcessImageFileNameW(P_Information.hProcess,P_Information.processName,MAX_PATH);
    P_Information.PID = GetCurrentProcessId();

    PE_Information.pimage = (BYTE*)GetModuleHandleW(moduleName);
    PE_Information.mz_head = (IMAGE_DOS_HEADER*)PE_Information.pimage;
    PE_Information.peOffset = PE_Information.mz_head->e_lfanew;
    IMAGE_NT_HEADERS & nth = *(IMAGE_NT_HEADERS*)(PE_Information.pimage + PE_Information.peOffset);
    PE_Information.pe_head = &nth.FileHeader;
    PE_Information.pe_opt_head = &nth.OptionalHeader;      
    PE_Information.DLLInfo =

    (IMAGE_IMPORT_DESCRIPTOR*)(PE_Information.pimage+PE_Information.pe_opt_head->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

    return P_Information.processName;
    }

    bool InterceptSpecificFunction(char* Library, char* Function, void* Replacement)
    {
    while (PE_Information.DLLInfo->Name != NULL)
    {
    if(stricmp((char*)(PE_Information.pimage + PE_Information.DLLInfo->Name), "USER32.DLL") == 0)
    goto next;

    PE_Information.DLLInfo++;
    }

    RET(false,_T("Can't retrive library in the import table"));

    next:

    ULONG_PTR Addr = (ULONG_PTR)&Replacement;

    PE_Information.thunk=(IMAGE_THUNK_DATA*)((BYTE*)PE_Information.pimage+PE_Information.DLLInfo->OriginalFirstThunk);

    int x=0;
    while(PE_Information.thunk->u1.Function)
    {
    char * functionname = (char*)((BYTE*)PE_Information.pimage+(unsigned)PE_Information.thunk->u1.AddressOfData+2);
    DWORD* IATentryaddress = (DWORD*)((BYTE*)PE_Information.pimage+PE_Information.DLLInfo->FirstThunk)+x;

    if (stricmp(functionname, Function) == 0)
    {
    SIZE_T byteswritten;  
    //WriteProcessMemory(hProcess, IATentryaddress, &Addr, sizeof(LPVOID), &byteswritten);//lower acces rights variant
    ReplaceMemoryWithHigherAccessRights(IATentryaddress, (LPVOID)&Replacement);

    RET(true,_T("OK"));
    }

    x++;
    PE_Information.thunk++;
    }

    RET(false,_T("Function not found in the import table"));
    }

    void ReplaceMemoryWithHigherAccessRights(LPVOID dest, LPCVOID src)
    {
    PDWORD oldProtect = 0;
    VirtualProtect(dest, sizeof(src), PAGE_EXECUTE_READWRITE, oldProtect);     
    HANDLE ServerHandle = OpenProcess(PROCESS_ALL_ACCESS, false, P_Information.PID);
    WriteProcessMemory(ServerHandle, dest, src, sizeof(src), NULL);
    VirtualProtect(dest, sizeof(src), (DWORD)oldProtect, NULL);
    }
    };

    #pragma pack (show)
    #endif
    С уважением.
    Выртосу Артем
     
Загрузка...

Поделиться этой страницей