IAT Hooking Internet Explorer

Я пытаюсь использовать IAT Hooking в Internet Explorer 8 (не работает в защищенном режиме), Windows 7 x64. Код также не работает для IE7 на WinXP. Я получил указатель на место, в котором хранится адрес функции. Я добавляю фрагмент своего кода, чтобы упростить процесс.

typedef int (WINAPI *_MessageBoxW)(HWND,LPCWSTR,LPCWSTR,UINT);
int WINAPI TestMessageBox(HWND,LPCWSTR,LPCWSTR,UINT);

Я получаю таблицу адресов для импорта и адрес, по которому хранится адрес MessageBoxW.

PIMAGE_THUNK_DATA pThunk = MakePtr(PIMAGE_THUNK_DATA, hMod, pImportDesc->FirstThunk);

PROC *pLocation=(PROC*)&(pThunk->u1.Function);
_MessageBoxW testVar1=&MessageBoxW;

Здесь значение *pLocation такое же, как testVar1, поэтому я предполагаю, что получил правильный адрес

_MessageBoxW testVar2=&TestMessageBox;

Теперь я меняю разрешение адреса PROC, используя VirtualProtect. После этого я перезаписываю его новым адресом.

*pLocation=(PROC)testVar2;

Я проверил, что адрес был успешно изменен, несмотря на то, что моя функция не вызывается. Есть ли что-то, что я пропускаю? Я вставил весь код введенной 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;
}

1 ответ

Есть возможности, когда IE7 может назвать оригинал MessageBoxW не попадая в твои руки. Вот некоторые из них:

  1. IE7 работает в процессе, состоящем из нескольких модулей (EXE + DLL). Перехват IAT работает путем исправления таблицы импорта определенного модуля. Вы уверены, что исправили все модули без каких-либо исключений? Кстати, некоторые модули могут быть загружены позже (после вашего исправления).
  2. Можно позвонить MessageBoxW не используя импортированный символ. Можно получить его адрес по GetProcAddress,
  3. Можно сохранить адрес MessageBoxW (в некоторой переменной), и вызовите это, используя это позже. Так что если вы заплатите после того, как его адрес получен - он не будет работать.
  4. Можно избежать использования MessageBoxW, Вместо этого он может вызвать другую функцию более низкого уровня из User32/64.dll, которая обычно вызывается MessageBoxW,

Сначала вы должны выяснить, почему вам не звонят. Запустите IE7, когда отобразится окно сообщения - подключитесь к нему через отладчик и выполните команду "Разбить все". Тогда посмотрите на стек вызовов. Если вы видите в какой-то момент MessageBoxW - 4-й случай не актуален. Тогда посмотри как это называется. Возможно, вы узнаете, какой модуль (EXE или DLL) вызвал его и как.

Также, чтобы избежать 1 и 2 - вы всегда должны исправлять следующие функции:

  • LoadLibraryA
  • LoadLibraryW
  • LoadLibraryExA
  • LoadLibraryExW
  • GetProcAddress
Другие вопросы по тегам