首页
社区
课程
招聘
[原创]ring3下的IAT HOOK
发表于: 2013-3-28 11:30 31416

[原创]ring3下的IAT HOOK

2013-3-28 11:30
31416

IAT hooking
当应用程序使用另一个动态库的函数时,PE装载器会找到每个IAMGE_IMPORT_BY_NAME结构所指向的输入函数的地址,然后把这些地址存储在一个叫做IAT的表。当函数CALL一个输入函数的时候,会先在IAT找到对应的函数地址,紧接着再进入该函数空间。熟悉PE结构的朋友应该清楚,IAT是一个IMAGE_THUNK_DATAj结构的数组。只要程序装载进内存中,就只与IAT查询信息,所以可见IAT表是一个非常重要的位置。
如果在IAT表中把某个函数的地址修改为钩子函数的地址,当调用到函数的时候,就会执行到该钩子函数中去。示例代码如下:
钩子函数,这里只是简单的弹出个窗口:

 
int
WINAPI
MyMessageBoxW(
/* __in_opt HWND hWnd,
__in_opt LPCWSTR lpText,
__in_opt LPCWSTR lpCaption,
__in UINT uType*/)
{
//todo yourself
return MessageBox(NULL, "hello world", "caption", MB_OK);
}
BOOL Rookits
(
IN HMODULE hModule,
IN LPCTSTR pImageName,
IN LPCTSTR pTargetFuncName
)
{
LPDWORD pTargetFuncAddr = NULL;
HMODULE hLib = LoadLibrary(pImageName);
if (NULL != hLib)
{
pTargetFuncAddr = (LPDWORD)GetProcAddress(hLib, pTargetFuncName);
return ImportAddressTableHook(hModule, pImageName, pTargetFuncAddr, MyMessageBoxW);
}
 
return FALSE;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (24)
雪    币: 137
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
难不成我还抢了个沙发,支持下
2013-3-28 11:41
0
雪    币: 6723
活跃值: (1199)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
学习了......
2013-3-28 12:41
0
雪    币: 3366
活跃值: (1353)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
4
有收获。。。
2013-3-28 12:58
0
雪    币: 22
活跃值: (453)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
收藏~~~~~
2013-3-28 13:35
0
雪    币: 341
活跃值: (143)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
6
shafa,
2013-3-28 15:08
0
雪    币: 97697
活跃值: (200829)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
7
Thanks for share.
2013-3-28 15:17
0
雪    币: 257
活跃值: (67)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
来学习一下,支持了
2013-3-28 17:02
0
雪    币: 2194
活跃值: (1001)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
有码就是好  谢谢分享
2013-3-29 08:57
0
雪    币: 29
活跃值: (131)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
用了楼主的方法去测试了下不成功啊,你给一个你的测试实例来看看吧!
2013-3-29 11:42
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
虽然我还看不懂,帮顶一个先
2013-3-29 12:55
0
雪    币: 149
活跃值: (150)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
12
2013-3-30 14:32
0
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
刚下载,支持一下。。
2013-3-31 13:00
0
雪    币: 58
活跃值: (72)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
14
while(pImageImportDescriptor != 0)   
{
    ...
    pImageImportDescriptor++;   
}
这里若是一直匹配不到恐怕要崩溃吧?判断条件应该是pImageImportDescriptor->Characteristics != 0。
2013-4-3 21:36
0
雪    币: 149
活跃值: (150)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
15
多谢星逝兄提醒,判断条件应该改为数组里的任意一个成员不为零
2013-4-4 10:40
0
雪    币: 112
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
东西不错,留个脚印
2013-4-20 14:26
0
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
thanks for sharing .
you were wrong.
2013-6-2 01:52
0
雪    币: 36
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
支持支持,下载下来看看
2013-8-23 19:39
0
雪    币: 16
活跃值: (430)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
不错不错。。。
2013-11-28 22:15
0
雪    币: 16
活跃值: (430)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
细节问题还有,pImageImportDescriptor->Name 是ansi字符串,强转为LPCTSTR会有问题的。得用A2W转一下
2013-11-28 23:38
0
雪    币: 16
活跃值: (430)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
附一个修改版+测试代码
BOOL IATHook( IN HMODULE hModule, IN LPCTSTR pImageName, IN LPCVOID pTargetFuncAddr, IN LPCVOID pReplaceFuncAddr )
{
    IMAGE_DOS_HEADER* pImgDosHdr = ( IMAGE_DOS_HEADER* )hModule;
    IMAGE_OPTIONAL_HEADER* pImgOptHdr = ( IMAGE_OPTIONAL_HEADER* )( ( DWORD )hModule + pImgDosHdr->e_lfanew + 24 );
    IMAGE_IMPORT_DESCRIPTOR* pImgImportDes = ( IMAGE_IMPORT_DESCRIPTOR* )( ( DWORD )hModule + pImgOptHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress );
    IMAGE_THUNK_DATA* pImgThunkData = NULL;
    wstring TargetLibraryName;
    DWORD Value = 0;
    DWORD OldProtect = 0;
    DWORD NewProtect = 0;
    LPDWORD FuncAddress = NULL;
    
    while ( pImgImportDes->Characteristics  != 0 )
    {
        USES_CONVERSION;
        LPCTSTR lpszName = A2W( ( ( LPCSTR )( DWORD )hModule + pImgImportDes->Name ) );
        TargetLibraryName = lpszName;
        if ( TargetLibraryName.compare( pImageName ) == 0 )
        {
            pImgThunkData = ( IMAGE_THUNK_DATA* )( ( DWORD )hModule + pImgImportDes->FirstThunk );
            break;
        }
        pImgImportDes++;
    }
    if ( pImgThunkData == NULL )
    {
        return FALSE;
    }
    while ( pImgThunkData->u1.Function )
    {
        //循环查找目标函数地址所在的位置
        FuncAddress = ( LPDWORD ) & ( pImgThunkData->u1.Function );
        if ( *FuncAddress == ( DWORD )pTargetFuncAddr )
        {
            //找到目标函数的地址,然后修改为钩子函数的地址
            VirtualProtect( FuncAddress, sizeof( DWORD ), PAGE_READWRITE, &OldProtect );
            if ( !WriteProcessMemory( ( HANDLE ) - 1, FuncAddress, &pReplaceFuncAddr, 4, NULL ) )
            {
                return FALSE;
            }
            VirtualProtect( FuncAddress, sizeof( DWORD ), OldProtect, 0 );
            return TRUE;
        }
        pImgThunkData++;
    }
    return FALSE;
}

typedef int ( WINAPI* SysMessageBoxW )( HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType );
SysMessageBoxW g_MessageBoxW = 0;

int WINAPI MyMessageBoxW( HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType )
{
    return g_MessageBoxW( NULL, _T( "hello world" ), _T( "caption" ), MB_OK );
}

BOOL Rookits(HMODULE hModule,LPCTSTR pImageName,LPCSTR pTargetFuncName)
{
    HMODULE hLib = LoadLibrary( pImageName );
    if ( NULL != hLib )
    {
        g_MessageBoxW = ( SysMessageBoxW )GetProcAddress( hLib, pTargetFuncName );
        BOOL bRet = IATHook( hModule, pImageName, g_MessageBoxW, MyMessageBoxW );
        FreeLibrary( hLib );
        return bRet;
    }
    
    return FALSE;
}

void Test()
{
    Rookits( GetModuleHandle( NULL ), _T( "USER32.dll" ), ( "MessageBoxW" ) );
    MessageBox( NULL, _T( "h" ), 0, 0 );
}

2013-11-28 23:53
0
雪    币: 77
活跃值: (48)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
mark
2014-1-16 16:56
0
雪    币: 478
活跃值: (50)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
学习!顶一个
2014-1-16 18:13
0
雪    币: 360
活跃值: (106)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
mark
2020-11-16 20:14
0
雪    币: 220
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
25
不错,支持一下~
2022-2-3 02:05
0
游客
登录 | 注册 方可回帖
返回
//