Reputation: 532
I am trying to use IAT Hooking on Internet Explorer 8 (Not running in protected mode), Windows 7 x64. The code also doesnt work for IE7 on WinXP. I have obtained the pointer to the location at which the address of the function is stored. I am adding a snippet of my code, to make things easy.
typedef int (WINAPI *_MessageBoxW)(HWND,LPCWSTR,LPCWSTR,UINT);
int WINAPI TestMessageBox(HWND,LPCWSTR,LPCWSTR,UINT);
I Obtain the Import Address Table and the address at which the address of MessageBoxW is stored.
PIMAGE_THUNK_DATA pThunk = MakePtr(PIMAGE_THUNK_DATA, hMod, pImportDesc->FirstThunk);
PROC *pLocation=(PROC*)&(pThunk->u1.Function);
_MessageBoxW testVar1=&MessageBoxW;
Here the value of *pLocation is same as testVar1, so i am assuming i got the right address
_MessageBoxW testVar2=&TestMessageBox;
Now i change the permission of the address PROC, using VirtualProtect. After doing this i overwrite it with the new Address.
*pLocation=(PROC)testVar2;
I have verified that the address has been successfully changed, in spite of doing this my function is not getting called. Is there any thing i am missing out? I have pasted the entire code of the injected dll
// injected.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "injected.h"
#ifdef _MANAGED
#pragma managed(push, off)
#endif
BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
extern "C"{
INJECTED_API LRESULT CALLBACK fninjected(int code,WPARAM wParam,LPARAM lParam)
{
if(gdi32Handle==NULL){
GetBaseAddressOfModulesLoaded(ModuleBaseAddresses);
MessageBox(NULL,L"Press ok to Debug",L"Alert!",MB_OK);//Used for Attching Debugger to IE
PROC* pPROC=(PROC*)GetAddress(ModuleBaseAddresses,"MessageBoxW");
_MessageBoxW ddd=&MessageBoxW;
mbOrig=(_MessageBoxW)*pPROC;
_MessageBoxW mbNew=&AshishMessageBox;
if(ManipulateAddressPointer(pPROC,(PROC)mbNew)){
}else{
MessageBeep(!0x0);
}
//////////////////////////////////////////////////////////////////////////
MessageBoxW(NULL,L"Dummy",L"Heeeeee",MB_OK);
isProcessed=TRUE;
}else{
//A test function Comes Here, to check if the hook has been set or not;
}
//MessageBox(NULL,L"Hello World",L"Test",MB_OK);
return CallNextHookEx(NULL,code,wParam,lParam);
}
}
int GetBaseAddressOfModulesLoaded(std::vector<HMODULE> &MBAddressVect){
int count=0;
size_t bytesRead=sizeof(MEMORY_BASIC_INFORMATION);
MEMORY_BASIC_INFORMATION mbi;
HMODULE hModIter;
wchar_t imageName[1024];
hModIter=GetModuleHandle(NULL);
if(hModIter==NULL){
MessageBox(NULL,L"Failed to get Handle of Current Module",L"Error message",MB_OK);
}else{
MBAddressVect.push_back(hModIter);
}
for(size_t lpAddress=0;bytesRead==sizeof(MEMORY_BASIC_INFORMATION);lpAddress+=mbi.RegionSize){
memset(&mbi,0x00,sizeof(MEMORY_BASIC_INFORMATION));
memset(&imageName,0x00,sizeof(imageName));
bytesRead=VirtualQuery((LPCVOID)lpAddress,&mbi,sizeof(MEMORY_BASIC_INFORMATION));
if(mbi.AllocationBase!=mbi.BaseAddress)continue;
else if(!(mbi.State&MEM_COMMIT))continue;
if(!mbi.BaseAddress)continue;
hModIter=(HMODULE)mbi.BaseAddress;
if(hModIter && GetModuleFileName(hModIter,imageName,1023)>0){
/*
Push all the module handles into the vector
*/
if(!wcsstr(wcslwr(imageName),L"user32.dll")&&!wcsstr(wcslwr(imageName),L"gdi32.dll"))continue;
else{
MessageBox(NULL,imageName,L"Loaded DLL",MB_OK);
gdi32Handle=hModIter;//This is messy
MBAddressVect.push_back(hModIter);
count++;
}
}
}
return count;
}
void* GetAddress(std::vector <HMODULE> BaseAddresses,char *OrignalFunctionName){
PIMAGE_THUNK_DATA pThunk = NULL, pOrigThunk = NULL;
PIMAGE_IMPORT_BY_NAME pAddressOfData = NULL;
for (std::vector<HMODULE>::iterator it = BaseAddresses.begin(); it!=BaseAddresses.end(); ++it) {
HMODULE hMod=*it;
PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)hMod;
if(pDOSHeader->e_magic!=0x5A4D){
MessageBox(NULL,L"Not a Valid DOS Image",L"Error",MB_OK);
return NULL;
}else{
//MessageBox(NULL,L"Valid DOS Image",L"Message",MB_OK);
}
PIMAGE_NT_HEADERS pNTHeader=MakePtr(PIMAGE_NT_HEADERS,pDOSHeader,pDOSHeader->e_lfanew);
if(pNTHeader->Signature!=0x00004550){
MessageBox(NULL,L"Not a Valid NT Image",L"Error",MB_OK);
return NULL;
}else{
//MessageBox(NULL,L"Valid NT Image",L"Error",MB_OK);
}
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = MakePtr( PIMAGE_IMPORT_DESCRIPTOR, hMod,pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
if(!pImportDesc){
MessageBox(NULL,L"Failed to get Import Descriptors",L"Error",MB_OK);
}else{
//MessageBox(NULL,L"Obtained Import Descriptors",L"Success",MB_OK);
}
while (pImportDesc->FirstThunk){
pThunk = MakePtr(PIMAGE_THUNK_DATA, hMod, pImportDesc->FirstThunk); // updated by loader
pOrigThunk = MakePtr(PIMAGE_THUNK_DATA, hMod, pImportDesc->OriginalFirstThunk); // unmodified by loader
while (pOrigThunk->u1.Function){
pAddressOfData = MakePtr(PIMAGE_IMPORT_BY_NAME, hMod, pOrigThunk->u1.AddressOfData);
if (!IsBadReadPtr(pAddressOfData, sizeof(IMAGE_IMPORT_BY_NAME))) {
char* funcName=(char*)pAddressOfData->Name;
if(funcName){
if(strstr(funcName,OrignalFunctionName)){
MessageBox(NULL,L"Found",L"Success",MB_OK);
return(&(pThunk->u1.Function));
}
}
}
pThunk++;
pOrigThunk++;
}
pImportDesc++;
}
}
}
int WINAPI AshishMessageBox(HWND wHandle,LPCWSTR text,LPCWSTR title,UINT type){
return mbOrig(NULL,L"you will always see this",L"No Matter What you try",MB_OK);
}
BOOL AshishExtTextOut(HDC hdc,int X,int Y,UINT fuOptions,const RECT *lprc,LPCWSTR lpString,UINT cbCount,const INT *lpDx){
MessageBox(NULL,lpString,L"Intercepted Text",MB_OK);
return etoOrig(hdc,X,Y,fuOptions,lprc,lpString,cbCount,lpDx);
}
BOOL ManipulateAddressPointer(PROC* pAddress,PROC location){
BOOL rv=FALSE;
if(IsBadWritePtr(pAddress,sizeof(PROC))){
DWORD oldProtect;
if(VirtualProtect(pAddress,sizeof(PROC),PAGE_READWRITE,&oldProtect)){
*pAddress=location;
DWORD test;
if(VirtualProtect(pAddress,sizeof(PROC),oldProtect,&test)){
rv=TRUE;
}
}else{
MessageBox(NULL,L"Fail",L"Error message",MB_OK);
}
}
else{
//MessageBox(NULL,L"Memory Is Writable",L"Error message",MB_OK);
*pAddress=location;
}
return rv;
}
Upvotes: 1
Views: 1387
Reputation: 12951
There are possibilities where the IE7 may call the original MessageBoxW
without getting into your hands. Here are some of them:
MessageBoxW
not using the imported symbol. One may get its address by GetProcAddress
.MessageBoxW
(in some variable), and call it using it later. So that if you patch after its address has been received - it'll not work.MessageBoxW
. Instead it may call another lower-level function from User32/64.dll, which normally gets called by MessageBoxW
.First you should discover why are you not getting called. Run the IE7, when it displays a messagebox - connect to it via debugger, and do "Break all". Then look at the callstack. If you see at some point MessageBoxW
- the 4th case is not relevant. Then see how it's called. Perhaps you'll find out which module (EXE or DLL) has called it, and how.
Also, in order to avoid 1 and 2 - you should always patch the following functions:
LoadLibraryA
LoadLibraryW
LoadLibraryExA
LoadLibraryExW
GetProcAddress
Upvotes: 1