发新话题
打印

[C++] 【原创】科普一下如何对抗IAT Hook

本主题由 System 于 2008-9-18 05:00 解除限时置顶

【原创】科普一下如何对抗IAT Hook

绕过IAT Hook的方法。
处理一下可以恢复InlineHook。

引用:
//0GiNr.com 小伟的小伟
//转载请保留出处。

//获取函数的原始地址,以此绕过IAT Hook
//原理:读取文件,从导出表里面弄偏移,然后加上加载基址即可。

//参考文献:《加密与解密 第三版》,也就是我学习PE结构的书。
//当初通过潜龙收购,可惜。。。。。。。。
#include <windows.h>
#include <stdio.h>
#include <imagehlp.h>
#pragma comment(lib,"imagehlp")

typedef int (WINAPI *pfnMessageBoxA)(
                  
HWND hWnd,
                  
LPCSTR lpText,
                  
LPCSTR lpCaption,
                  
UINT uType
                  
);
//函数原型

pfnMessageBoxA OrigMessageBoxA = NULL;//保存原始函数地址
LPVOID RvaToPtr(PIMAGE_NT_HEADERS pNtH,LPVOID ImageBase,DWORD dwRVA);//转化成文件偏移
DWORD GetOrigMessageBoxAAddress();//获取函数原始地址

int main(int argc, char* argv[])
{
   
printf("AntiIATHook Demo\nBy XiaoWei[0GiNr]\n");
   
printf("http://www.0GiNr.com\n");
   
printf("http://0Gsns.com\n");
   
printf("http://hi.baidu.com/zoo%%5F\n\n");
   
OrigMessageBoxA = (pfnMessageBoxA)GetOrigMessageBoxAAddress();
   
printf("OrigMessageBoxA = 0x%08lX\n",OrigMessageBoxA);
   
OrigMessageBoxA(0,"0GiNr","0GiNr",0);
   
getchar();
   
return 0;
}

LPVOID RvaToPtr(PIMAGE_NT_HEADERS pNtH,LPVOID ImageBase,DWORD dwRVA)
{   
   
return ImageRvaToVa(pNtH,ImageBase,dwRVA,NULL);
}

DWORD GetOrigMessageBoxAAddress()
{
   
LPVOID lpBass = NULL;
   
HANDLE hMapFile = NULL;
   
HANDLE hFile = NULL;
   
PIMAGE_DOS_HEADER    pDH = NULL;
   
PIMAGE_NT_HEADERS    pNH = NULL;
   
PIMAGE_OPTIONAL_HEADER    pOH = NULL;
   
PIMAGE_EXPORT_DIRECTORY pED = NULL;
   
DWORD        dwDataStartRVA    = 0;
   
PDWORD      pdwRvas, pdwNames;
   
PWORD       pwOrds;
   
UINT        iNumOfName;
   
char        *szFuncName;
   
int            i,j;
   
HMODULE        hUser32;
   
DWORD        dwRetAddr;
   
//////////////////////////////////////////////////////////////////////////
   
::LoadLibraryA("user32.dll");//load一下。
   
hUser32 = GetModuleHandleA("user32.dll");
   
if (!hUser32) {
        
printf("Get User32 Base Error..\n");
        
goto __exit;
    }
   
hFile = ::CreateFileA(
        
"c:\\windows\\system32\\user32.dll",
        
GENERIC_READ,
        
FILE_SHARE_READ,
        
NULL,
        
OPEN_EXISTING,
        
FILE_ATTRIBUTE_NORMAL,
        
NULL);
   
if ( hFile == INVALID_HANDLE_VALUE ) {
        
printf("open file error..\n");
        
goto __exit;
    }
   
hMapFile = ::CreateFileMappingA(
        
hFile,
        
NULL,
        
PAGE_READONLY,
        
NULL,
        
NULL,
        
NULL);
   
if ( hMapFile == INVALID_HANDLE_VALUE ) {
        
printf("CreateFileMappingA error..\n");
        
goto __exit;
    }
   
lpBass = MapViewOfFile(
        
hMapFile,
        
FILE_MAP_READ,
        
0,
        
0,
        
0);
   
if ( !lpBass ) {
        
printf("CreateFileMappingA error..\n");
        
goto __exit;
    }
   
pDH = (PIMAGE_DOS_HEADER)lpBass;
   
pNH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
   
pOH = &pNH->OptionalHeader;
   
dwDataStartRVA = pOH->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
   
pED = (PIMAGE_EXPORT_DIRECTORY)RvaToPtr(pNH,lpBass,dwDataStartRVA);

   
pwOrds    = (PWORD)RvaToPtr(pNH, lpBass,pED->AddressOfNameOrdinals);
   
pdwRvas   = (PDWORD)RvaToPtr(pNH, lpBass,pED->AddressOfFunctions);
   
pdwNames  = (PDWORD)RvaToPtr(pNH, lpBass,pED->AddressOfNames);
   
iNumOfName = pED->NumberOfNames;

   
for (i = 0;i<pED->NumberOfFunctions;i++) {
        
if (*pdwRvas) {
            
for (j = 0;j<iNumOfName;j++) {
               
if ( i == pwOrds[j] ) {
                    
szFuncName = (char*)RvaToPtr(pNH,lpBass,pdwNames[j]);
                    
break;
                }
            }
            
if ( !strcmp(szFuncName,"MessageBoxA") ) {
               
printf("*pdwRvas : 0x%08lX..\n",*pdwRvas);
               
dwRetAddr = (DWORD)hUser32 + *pdwRvas;
//文件偏移加上加载地址,得到原始函数地址。
               
goto __exit;
            }
            
pdwRvas++;
        }
    }
__exit:
   
if (lpBass)
        ::
UnmapViewOfFile(lpBass);
    ::
CloseHandle(hFile);
    ::
CloseHandle(hMapFile);
   
return dwRetAddr;
}
[ 本帖最后由 Liangent 于 2008-9-15 01:38 编辑 ]
附件: 您所在的用户组无法下载或查看附件
本帖最近评分记录
  • KingsamChen 现金 +20 帅毙了~ 2008-8-21 11:16
  • ssword 现金 +10 困了~睡觉去~ 2008-8-21 00:04

TOP

看不懂,路过……等有了内核态的JVM再说
Welcome to JAFTBlog:http://blog.icybear.cn

TOP

IAT Hook=?

TOP

引用:
原帖由 Liangent 于 2008-8-21 09:24 发表
IAT Hook=?
某种Hook。


   

另外和内核无关~Ring3的。

内核的JVM。。。。那是什么效率啊。。。。。
本帖最近评分记录
  • KingsamChen 现金 +20 恭喜成为8月优秀帖子 2008-9-12 21:35

TOP

IAT HOOK和INLINE HOOK差不多,不过比后者稳定,实现也会简单一些~
伟哥干吗不多写点注释……
如此好贴,不加精真可惜~
收藏收藏~

TOP

引用:
原帖由 KingsamChen 于 2008-8-21 11:19 发表
IAT HOOK和INLINE HOOK差不多,不过比后者稳定,实现也会简单一些~
伟哥干吗不多写点注释……
如此好贴,不加精真可惜~
收藏收藏~
说稳定也未必,IAT Hook有可能Hook不到的。

InlineHook可以相对稳定的,内核中常常使用。

TOP

好像听说InlineHook有线程同步问题

TOP

引用:
原帖由 opqxyz456 于 2008-8-21 11:58 发表
好像听说InlineHook有线程同步问题
方法问题。

一般的InlineHook是这样:
1、修改原函数头部的代码,使之跳到代理函数。
2、当原函数执行,会转到代理函数,这时候可以过滤掉一些数据。
3、为了调用原函数(若必要),把原始代码写回去,然后执行原函数。
4、原函数正常执行,返回到代理函数。
5、代理函数返回到调用者。

所以在多线程的程序当中,当把原始代码写回去的时候(步骤3),当前线程可能被挂起,而另外的线程这个时候执行到该函数的时候就会出现Hook不到的情况。

所以,把原始指令放到另外一个地方去执行即可。

现在我们都这么做了~~~Hoho~~~

TOP

回复 3楼 的帖子

IAT Hook = import address table Hook与PE中的IMAGE_IMPORT_DEsCRIPTOR结构体关系紧密,呵呵
可以跌倒无数次,但是每一次都要顽强地站起来
我的个人空间

TOP

我也骗点精华吧。
0GiNr的炉子, 不多解释了.

有事请PM.

TOP

回复 10楼 的帖子

快了~

TOP

发新话题