首页
社区
课程
招聘
[旧帖] 修改IAT实现HOOK API函数的问题 0.00雪花
发表于: 2012-10-25 21:17 7208

[旧帖] 修改IAT实现HOOK API函数的问题 0.00雪花

2012-10-25 21:17
7208
请教高手:通过修改IAT实现HOOK API函数的方法,是不是对所有的API函数都有效。我看到有个博文说对有些API函数是无效的,“这是因为编译器做了大量的优化工作,它可能早将IAT中函数地址保存在某个寄存器或者变量(了,所以你即使改变了IAT表中的地址值,也不会截获到这些API调用。这便是IAT法的最大的缺点——不能完全截获。”
真的是这样吗?
如果是的话,那用这种方法能否截获gethostbyname gethostbyaddr等函数呢?

求指点!!!急!!!在线等。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 2105
活跃值: (424)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
编译器是不会优化掉IAT的,getprocaddress动态获取的 IAT HOOK就不管用了

保险起见  还是inline hook好
2012-10-25 21:24
0
雪    币: 130
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
"getprocaddress动态获取的 IAT HOOK就不管用了",这句话的意思??不大明白。
我现在手头上有的是IAT HOOK,如果这个能行的话,就省好多事了。能否确定这种方法对gethostbyname函数有没有用?
2012-10-25 21:30
0
雪    币: 1689
活跃值: (379)
能力值: ( LV15,RANK:440 )
在线值:
发帖
回帖
粉丝
4
也可以考虑同时修改被hook函数所在模块的导出表。
2012-10-25 21:39
0
雪    币: 130
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
是修改IAT表吗?
2012-10-25 21:53
0
雪    币: 1689
活跃值: (379)
能力值: ( LV15,RANK:440 )
在线值:
发帖
回帖
粉丝
6
修改ws2_32.dll的导出表。GetProcAddress是通过查相应模块的导出表动态定位函数的。
2012-10-25 22:01
0
雪    币: 130
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我现在有的就是这个代码,修改导出表,但是无法HOOK到gethostbyname。我用MessageBoxA这个函数试了下,这个倒是能HOOK,所以就想请教大家,看看是不是跟要HOOK的对象有关?
2012-10-25 22:37
0
雪    币: 130
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
代码贴出来,请高手指点!
HookIAT.cpp:使用IAT法挂钩.
//
#include "stdafx.h"
#include <afxdllx.h>
#include "HookApi_IAT.h"
#include <windows.h>
#include <time.h>
#include   <winsock2.h> 
#include<iostream>
#include<fstream>
using namespace std;

void WINAPI ExampleIAT();
void WINAPI ExampleIAT_OFF();

static AFX_EXTENSION_MODULE HookIATDLL = { NULL, NULL };

//extern "C" int APIENTRY
extern "C" __declspec(dllexport)   struct   hostent*   FAR   IATgethostbyname(const   char*   name ); 


int DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    // Remove this if you use lpReserved
    UNREFERENCED_PARAMETER(lpReserved);

    if (dwReason == DLL_PROCESS_ATTACH)
    {
        ExampleIAT();
    }
    else if (dwReason == DLL_PROCESS_DETACH)
    {
        ExampleIAT_OFF();
        TRACE0("HOOKIAT.DLL Terminating!\n");
        // Terminate the library before destructors are called
        AfxTermExtensionModule(HookIATDLL);
    }
    return 1;   
}

//---------------------------------------------------------------------------
CHookApi_IAT myIAT;
struct hostent* FAR IATgethostbyname( const char* name ) {
struct hostent* tmp = NULL;

CStdioFile file;
__time32_t nNow = 0;
    tm stNow = {0};
    _time32(&nNow);
    _localtime32_s(&stNow,&nNow);
    char buff[255] = {0};
    _snprintf(buff,sizeof(buff)-1,"%d.%d.%d.%d.%d.%d",
        stNow.tm_year + 1900,
        stNow.tm_mon + 1,
        stNow.tm_mday,
        stNow.tm_hour,
        stNow.tm_min,
        stNow.tm_sec);
    ofstream outfile("gethostbyname.txt",ios::app);  //写入文件 
 for(int i=0;i<255;i++)  
  outfile<<buff[i]; 
tmp = gethostbyname(name);
return tmp;
}

//---------------------------------------------------------------------------
// 通过IAT挂钩API
void WINAPI ExampleIAT()
{
    PROC HookAPIAddr =(FARPROC)
        GetProcAddress(GetModuleHandle("wsock32.dll"), "gethostbyname");
    HMODULE hModule= GetModuleHandle(NULL);

// 挂钩所有模块,备用调用.
//    myIAT.HookAllAPI("wsock32.dll",HookAPIAddr,(PROC)IATgethostbyname);

// 挂钩单个模块.
     myIAT.HookOneAPI("wsock32.dll",HookAPIAddr,(PROC)IATgethostbyname,hModule);
}

//---------------------------------------------------------------------------
// 卸载IAT挂钩API
void WINAPI ExampleIAT_OFF()
{
    HMODULE hModule= GetModuleHandle(NULL);
     myIAT.HookOneAPI_OFF("wsock32.dll",hModule);
}



// HookApi_IAT.cpp:实现CHookApi_IAT类.
//
#include "stdafx.h"
#include "HookApi_IAT.h"
#include <tlhelp32.h>
#include <imagehlp.h>
#pragma comment (lib,"imagehlp.lib")

//---------------------------------------------------------------------------
CHookApi_IAT::CHookApi_IAT()
{
}

//---------------------------------------------------------------------------
CHookApi_IAT::~CHookApi_IAT()
{
}

//---------------------------------------------------------------------------
BOOL CHookApi_IAT::HookAllAPI(LPCTSTR ModuleName, PROC HookAPIAddr, PROC lpNewFunc)
{
    if (ModuleName == NULL||HookAPIAddr == NULL)
        return FALSE;

    HANDLE hSnapshot;
    MODULEENTRY32 hMod = {sizeof(hMod)}; 
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,NULL);
    
    // 取得所有模块列表中的指定的模块. 
    BOOL bMoreMods = Module32First(hSnapshot, &hMod); 
    if (bMoreMods == FALSE) return FALSE;
    
    // 循环取得想要的模块. 
    for (;bMoreMods; bMoreMods = Module32Next(hSnapshot, &hMod)) 
    { 
        MEMORY_BASIC_INFORMATION mbi;
        // 获取本模块信息.
        VirtualQuery(this,&mbi,sizeof(mbi));
        // 不在自己的模块中挂钩函数.
        if (hMod.hModule != (HMODULE)mbi.AllocationBase)
        {
            //hMod.hModule:指向当前被挂钩进程的每一个模块. 
            HookOneAPI(    ModuleName,HookAPIAddr,
                lpNewFunc,hMod.hModule);
        }
    }
    
    return TRUE;  
}

//---------------------------------------------------------------------------
BOOL CHookApi_IAT::HookOneAPI(PCSTR   ModuleName, PROC HookAPIAddr, 
                              PROC    lpNewFunc, HMODULE hmodCaller) 
{
    DWORD size;
    
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc = 
        (PIMAGE_IMPORT_DESCRIPTOR) ImageDirectoryEntryToData(
        hmodCaller,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&size);
    
    if(pImportDesc == NULL) return FALSE;
    
    for (;pImportDesc->Name;pImportDesc++)
    {
        LPSTR pszDllName = (LPSTR)((PBYTE)hmodCaller + pImportDesc->Name);
        if(lstrcmpiA(pszDllName,ModuleName) == 0) break;
    }
    
    if(pImportDesc->Name == NULL) return FALSE;
    PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)
        ((PBYTE)hmodCaller + pImportDesc->FirstThunk);//IAT

    for(;pThunk->u1.Function;pThunk++)
    {
        PROC * ppfn= (PROC *)&pThunk->u1.Function;
        
        m_lpOldFunc = (PROC)pThunk->u1.Function;
        m_lpNewFunc =lpNewFunc;

        if (*ppfn == HookAPIAddr)
        {
            MEMORY_BASIC_INFORMATION mbi;
            ZeroMemory(&mbi, sizeof(MEMORY_BASIC_INFORMATION));
            VirtualQuery(ppfn,&mbi,sizeof(MEMORY_BASIC_INFORMATION));
            VirtualProtect(mbi.BaseAddress,mbi.RegionSize,
                                       PAGE_READWRITE,&mbi.Protect);
            *ppfn = *lpNewFunc;
            DWORD dwOldProtect;
            VirtualProtect(mbi.BaseAddress,mbi.RegionSize,
                                mbi.Protect,&dwOldProtect);
            return TRUE;
        }
    }
    
    return FALSE;
}

//---------------------------------------------------------------------------
BOOL CHookApi_IAT::HookOneAPI_OFF(PCSTR ModuleName, HMODULE hmodCaller) 
{
    return  HookOneAPI(ModuleName, m_lpNewFunc,m_lpOldFunc,hmodCaller); 
}
2012-10-25 23:22
0
雪    币: 22
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
只对当前进程中的有效
2012-10-25 23:41
0
雪    币: 1689
活跃值: (379)
能力值: ( LV15,RANK:440 )
在线值:
发帖
回帖
粉丝
10
IAT = Import Address Table
EAT= Export Address Table

不一样地。那代码看上去是IAT。

为了避免GetProcAddress过IAT hook,你可以同时把对应的EAT hook了。
2012-10-26 07:30
0
雪    币: 130
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
代码确实是IAT。
楼上的意思是同时使用IAT和EAT吗?对EAT我之前没怎么了解,这样做,一定能够HOOK到gethostbyname吗
2012-10-26 08:06
0
雪    币: 130
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
有修改EAT进行HOOK的源码吗?我看网上大部分都是IAT的
2012-10-26 08:23
0
雪    币: 55
活跃值: (531)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
13
EAT HOOK是导出表HOOK( dll ),IAT HOOK是导入表HOOK( exe ).
调用WIN32 API时,如果是通过lib静态库调用到win32 api,则是通过IAT的方式。(即文件dll随程序的加载而装载)

如果是动态调用(函数指针方式),则是从LoadLibrary获得的hModule开始定位dll文件EAT内所需要用到的导出函数地址,
而后用GetProcAddress读取dll内保存所有导出函数地址的EAT表,将所需要用到的函数地址存入调用方内的函数指针变量。(文件dll在必要时通过LoadLibrary装载)。


需要注意时的是,EAT HOOK必须在程序调用GetProcAddress之前就进行,否则是不一定成功的。
2012-10-26 16:10
0
雪    币: 549
活跃值: (551)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
14
http%3A%2F%2Fbbs.pediy.com%2Flogin.php%3Fdo%3Dlogout%26logouthash%3D1351245318-fcd04acff76e732f2b95311c825a446949abf166+
2012-10-26 18:06
0
雪    币: 549
活跃值: (551)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
15
2012-10-26 18:07
0
游客
登录 | 注册 方可回帖
返回
//