[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows]
"AppInit_DLLs"="C:\\Windows\\System32\\NPHook64.dll"
"LoadAppInit_DLLs"=dword:00000001
(аналогично для 32-битной ветки)
Неработает код для перехвата API-функции в Vista 64bit
Помогите пожалуйста решить следующую проблему. Я пытаюсь перехватить вызовы функции MessageBoxW во всех процессах системы. Интеграция в систему осуществляется за счет прописывания ключей:
Код:
Мой код идеально работает под 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)
Код:
#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 fucked 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)
#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 fucked 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)
Код:
#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
#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
С уважением.
Выртосу Артем