免費論壇 繁體 | 簡體
Sclub交友聊天~加入聊天室當版主
分享
返回列表 发帖

IAT表

A、初识IAT
    B、IAT表相关结构
    C、读出IAT项
    D、编写代码测试分析   
    E、HOOK IAT
        F、测试分析
        课时:30
       
A、认识IAT表 导入函数表

B、IAT表相关结构

PIMAGE_DOS_HEADER
//->e_lfanew //PE文件头偏移值
PIMAGE_NT_HEADERS //->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
PIMAGE_IMPORT_DESCRIPTOR
//.FirstThunk //IAT偏移
PIMAGE_THUNK_DATA
// u1.Function

//www.yjxsoft.com  2010.6.26
//文件名 IAT.H
#include <windows.h>
VOID __stdcall mySleep(DWORD m)
{
        MessageBoxA(0,"Hook 成功","IAT hook",MB_OK);
}
PVOID EnumAPI()  
{  
PBYTE ImageBase;
PIMAGE_THUNK_DATA r;   
PIMAGE_NT_HEADERS pNtHeader;   
PIMAGE_IMPORT_DESCRIPTOR pImport;   
//取得DOS头基址
ImageBase=(PBYTE)GetModuleHandle(NULL);//0x400000
//PE头=ImageBase+[ImageBase+3c]
pNtHeader = (PIMAGE_NT_HEADERS) (ImageBase + ((PIMAGE_DOS_HEADER) ImageBase)->e_lfanew);   
//IMAGE_DIRECTORY_ENTRY_IMPORT值为1 表示import tabale
pImport = (PIMAGE_IMPORT_DESCRIPTOR)
(ImageBase + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);   

////遍历整个 输入表
for (; pImport->Name; pImport++)   
{      
         printf("导入模块:%s\n",ImageBase+pImport->Name);   
       //遍历IAT信息  PIMAGE_THUNK_DATA基址
                 for (r = (PIMAGE_THUNK_DATA) (ImageBase + pImport->FirstThunk); r->u1.Function; r++)   //枚举函数地址
                {  if (Sleep==(PVOID)r->u1.Function)        //如果是我们要的函数
                {   DWORD pSleep=(DWORD)(&r->u1.Function);
                        __asm
                        {
                                    mov ebx,pSleep /// HOOK它
                                        lea eax,mySleep
                                        mov [ebx],eax
                }
                }
                        printf("Function=%x \n", &(r->u1.Function));     
                }   
}   
return NULL;   
}   
  
int main(int argc, char* argv[])   
{   //MessageBoxA(0,NULL,NULL,MB_OK) ;
    //MessageBoxW(0,NULL,NULL,MB_OK);
        EnumAPI();
    Sleep(111);
    return 0;   
}  


==========================================

笔记:
本节课不讲驱动,而是讲IAT表方便我们HOOK,虽然IAT表已经是很老的技术但也是基础知识.新建一个EXE,用OD加载看一下里面的Sleep函数,是通过指针来调用,而里面的地址就是IAT表, 如果修改这个指针则会指向另外一个函数.

写完代码但是却没有弹出框. 用OD看一下,是地址有错,改一下HOOK成功了,下面是正确的代码:

#include "stdafx.h"
#include "IAT.h"
#include <windows.h>
#define  pSleep 0x42A190
VOID __stdcall mySleep(DWORD m)
{
        MessageBoxA(0,"Hook 成功","IAT hook",MB_OK);
}
int main(int argc, char* argv[])
{  
*((PDWORD)(pSleep))=(DWORD)(&mySleep);
        Sleep(1111);
        printf("Hello World!\n");
        return 0;
}

其中上面一句可以替换成下面汇编
__asm
{
mov ebx,pSleep /// mov ebx,0x42A190
lea eax,mySleep
mov [ebx],eax
}

但是上面这种方法通用性不强,另外这里还有一种方法IAT.h文件已经写好了.过程就是先取DOS头,再取PE头偏移,再获取导入信息,其中的FirstThunk就是IAT偏移,再遍历,这样就找到了IAT表.最后HOOK函数,经过修改后终于成功了(代码在教案中).最后讲如果是LoadLibrary动态载入函数的话这种方式就无效了,所以是一种过时的技术.

随记:
以前只知道HOOK地址,现在连IAT也可以HOOK了,老师讲的东西越来越先进了.

返回列表