󰅡收起

闲人的博客

专业代维,关注IT,专注于服务器维护、服务器代维、网站安全加固、网站建设、网站SEO优化,服务器托管、租用!

05
八月

菜鸟的hook法

作者: 闲人
分类: 时光记忆
发布时间: 2010-08-05 20:13

在论坛闲逛的时候发现了这个,就转载过来,最近再写一个小程序,累点,就没更新,先转篇…

//内核中根据模块名得到模块基地址和模块大小.

//MyGetModuleInfo:根据模块名得到模块的基地址和大小.
#define BASEADDRLEN 10;

......

ULONG
MyGetModuleInfo(
IN  char * ModuleName,
OUT ULONG *pModuleSize
)

/*
MyGetModuleInfo:根据模块名得到模块的基地址和大小.
参数----------------------------------
pModuleSize:模块大小将会放到这里.
返回值:基地址.
*/
{
PSYSTEM_MODULE_INFORMATION    pSysModule;

ULONG            uReturn;
ULONG            uCount;
PCHAR            pBuffer = NULL;
PCHAR            pName    = NULL;
NTSTATUS        status;
UINT            ui;

CHAR            szBuffer[BASEADDRLEN];
ULONG          BaseAddress;

//说来说去就是这个函数的使用.
status = ZwQuerySystemInformation( SystemModuleInformation, szBuffer, BASEADDRLEN, &uReturn );

pBuffer = ( PCHAR )ExAllocatePool( NonPagedPool, uReturn );

if ( pBuffer )
{
status = ZwQuerySystemInformation( SystemModuleInformation, pBuffer, uReturn, &uReturn );

if( status == STATUS_SUCCESS )
{
uCount = ( ULONG )*( ( ULONG * )pBuffer );
pSysModule = ( PSYSTEM_MODULE_INFORMATION )( pBuffer + sizeof( ULONG ) );

for ( ui = 0; ui < uCount; ui++ )
{
pName = strrchr( pSysModule->ImageName, '' );

if ( !pName )
{
pName = pSysModule->ImageName;
}

else {
pName++;
}

if( !_stricmp( pName, ModuleName ) )
{
(*pModuleSize) = pSysModule->Size;
BaseAddress = pSysModule->Base;
ExFreePool( pBuffer );
return BaseAddress;
}

pSysModule ++;
}
}

ExFreePool( pBuffer );
}

return NULL;

}

//然后可以看看导入表有没有我们想要hook的函数,用这个函数看看.
//如果有,就可以再干点别的.
PIMAGE_IMPORT_DESCRIPTOR
FindTheImportDescriptor(
ULONG BaseAddr,
char *file)
/*
从基址为 BaseAddr 的模块中找到 (用到了file(dll文件)的导出函数) IMAGE_IMPORT_DESCRIPTOR
file:    文件名  比如:hal.dll,ntoskrnl.exe...
BaseAddr:模块基址.
*/
{
PIMAGE_DOS_HEADER pimDH = (PIMAGE_DOS_HEADER)BaseAddr;
PIMAGE_NT_HEADERS pimNH = (PIMAGE_NT_HEADERS)((char*)BaseAddr+pimDH->e_lfanew);
//PIMAGE_IMPORT_DESCRIPTOR.
PIMAGE_IMPORT_DESCRIPTOR pimID = (PIMAGE_IMPORT_DESCRIPTOR)(BaseAddr+pimNH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
char * pName = NULL;
int    ulval=0;

if(pimID == NULL)
return 0;

while(pimID->Name)
{
//DLL文件的名称(0结尾的ASCII码字符串)的32位VA
pName = (char*)(BaseAddr + pimID->Name);
ulval=0;

for(int i=0;pName[i];i++)
{
ulval = pName[i]-file[i];
if(ulval!=0) break;
}

//ulval;
if(ulval==0) break;//如果找到

pimID++;
}

if(pimID->Name)
return pimID; //返回的是结构IMAGE_IMPORT_DESCRIPTOR指针.
else
return 0;
}

//然后可以去hook想要hook的函数.

VOID
MyHookFunction(
ULONG BaseAddr,    //模块基地址.
char * DllName,    //要hook的函数位于什么模块,这里是这个模块名.
char * FuncName,  //要hook的函数名.
PVOID  FuncHook,  //新函数地址.
ULONG * lpFunc)    //保存原函数地址.
/*
将基地址为BaseAddr中用到外部模块(DllName)的导出函数(FuncName) hook 掉.
用 FuncHook hook FuncName,并保存FuncName原来的值到lpFunc;
*/
{
//找到用到DllName的 IMAGE_IMPORT_DESCRIPTOR
PIMAGE_IMPORT_DESCRIPTOR pimID = FindTheImportDescriptor(BaseAddr,DllName);
if(pimID==NULL)  return;

PIMAGE_THUNK_DATA pITD = (PIMAGE_THUNK_DATA)((char *) BaseAddr + pimID->OriginalFirstThunk);
PIMAGE_THUNK_DATA pITD2 = (PIMAGE_THUNK_DATA)((char *) BaseAddr + pimID->FirstThunk);
PIMAGE_IMPORT_BY_NAME pIIBN = NULL;
int    ulval=0;
ULONG  cr0value = 0;

if(0 == pITD->AddressOfData) return TRUE;

do
{
if(pITD->AddressOfData < 0x80000000)
{
pIIBN = (PIMAGE_IMPORT_BY_NAME)(pITD->AddressOfData +  BaseAddr);
if(pIIBN->Name[0]=='')
continue;

ulval=0;
for(int i=0;pIIBN->Name[i];i++)
{
ulval = FuncName[i] - pIIBN->Name[i];
if(ulval!=0) break;
}
//ulval;
if(ulval==0) //如果找到
{
CloseWriteProtect(&cr0value);//修改Cr0值来关闭写保护
lpFunc = pITD2->Function;    //保存
pITD2->Function = FuncHook;  //hook
SetCr0(cr0value);            //还原Cr0值
break;
}
}
pITD ++;
pITD2 ++;
}while(pITD!=NULL);
return TRUE;
}

󰁠

本文出自 闲人的博客 ,转载时请注明出处及相应链接。

本文永久链接: http://www.xianren.org/memory/hookfangfa.html

一条评论

  1. 南通烧鸡公 2010年8月6日 上午9:00 回复

    好看的

发表评论

电子邮件地址不会被公开。 必填项已用*标注


*

Anti-spam image

| |