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

  • Автор темы artemvyrtosu
  • Дата начала
A

artemvyrtosu

#1
Добрый день,

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

Код:
[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)
Код:
#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)
Код:
#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
С уважением.
Выртосу Артем