b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

eat hook原来 导出表钩子------EAT HOOK

电脑杂谈  发布时间:2017-04-27 00:08:54  来源:网络整理
eat hook原来eat hook原来

作 者: Sysnap时 间: 2008-04-05,17:13链 接: ?t=62574看了combojiang大侠的rootkit专题,发现少了一个导出表钩子,既EAT;HOOK,刚好前几天自己搞了个IATHOOK,然后就把其中的代码稍做修改,于是有这篇文章,偶学的东西不久,很多东西还不知道,请多指教,呵呵导出表钩子比导入表钩子感觉好用多,先说下原理吧,函数导入的函数的地址是再运行时候才确定的,比如我们的一个驱动程序导入了PsGetCurrentProcessId这个ntkrnlpa.exe导出的函数,那在我们驱动程序加载运行的时候,装载程序会确定ntkrnlpa.exe在内存的基地址,接着遍历它的导出表,在AddressOfNames指向的"函数名字表"中找到PsGetCurrentProcessId的位置,也就是如果在AddressOfNames[i]中找到PsGetCurrentProcessId,那就用i在AddressOfNameOrdinals中索引,假使得到是X,那么AddressOfFunctions[index]的值就是PsGetCurrentProcessId的RVA了,最后就可以知道PsGetCurrentProcessId在内存的值是MM=ntkrnlpa.exe在内存的基地址+PsGetCurrentProcessId的RVA,然后转载程序就把这个值写到我们驱动程序的IAT中,好了知道这些后,EATHOOK就是修改PsGetCurrentProcessId的RVA,使得PsGetCurrentProcessId的RVA(修改后的)+ntkrnlpa.exe在内存的基地址=我们自己函数的值,这样装载程序会把我们的函数的地址写入那些调用PsGetCurrentProcessId的驱动程序的IAT,那么当那些驱动程序调用PsGetCurrentProcessId时,实际上是执行了我们自己的函数...呵呵.是不是比IATHOOK更好用呢

EATHOOK可以用来监控系统函数的调用情况,比如我们EATHOOK了PsGetCurrentProcessId,那谁调用该函数我们就知道了,你也可以HOOKKeInitializeApc等热门函数,其实知道了EATHOOK原理后,我们可以修改函数名字表,比如把PsGetCurrentProcessId改成其它名字,这样装载程序遍历"函数名字表"就找不到匹对的名字,那驱动程序就宣告装载失败,详细代码请看<<利用导出表来禁止一些驱动程序的加载>>?t=62531

那怎么防止EATHOOK,一个方法是自己定位函数在内存地址,请看下面的代码,用于枚举ntkrnlpa.exe导出函数在内存的地址VOIDListKernelFunctionAndAddress(){

HANDLEhMod;

PVOIDBaseAddress=NULL;

IMAGE_DOS_HEADER*dosheader;

IMAGE_OPTIONAL_HEADER*opthdr;

PIMAGE_EXPORT_DIRECTORYexports;

USHORTindex=0;

ULONGaddr,i;

PVOIDFuncNameRVA;

PUCHARpFuncName=NULL;

PULONGpAddressOfFunctions,pAddressOfNames,pAddressOfNameOrdinals;

BaseAddress=GetDriverBaseAdress("ntkrnlpa.exe");

DbgPrint("MapBaseAddressis:%x/n",BaseAddress);

hMod=BaseAddress;

dosheader=(IMAGE_DOS_HEADER*)hMod;

opthdr=(IMAGE_OPTIONAL_HEADER*)((BYTE*)hMod+dosheader->e_lfanew+24);

exports=(PIMAGE_EXPORT_DIRECTORY)((BYTE*)dosheader+opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

pAddressOfFunctions=(ULONG*)((BYTE*)hMod+exports->AddressOfFunctions);

pAddressOfNames=(ULONG*)((BYTE*)hMod+exports->AddressOfNames);

pAddressOfNameOrdinals=(USHORT*)((BYTE*)hMod+exports->AddressOfNameOrdinals);

for(i=0;i<exports->NumberOfNames;i++){

index=pAddressOfNameOrdinals[i];

addr=pAddressOfFunctions[index];

pFuncName=(PUCHAR)((BYTE*)hMod+pAddressOfNames[i]);

addr=pAddressOfFunctions[index];

DbgPrint("thefunction:%sisat:0x%x/n",pFuncName,addr+(BYTE*)hMod);}}运行后:------------------------------------------------------------------------

好了,讲了这么多时候进去正题,怎样EATHOOK,这里我们以HOOKntkrnlpa.exe导出的PsGetCurrentProcessId

首先我们是定位ntkrnlpa.exe被加载在内存中的什么地方,那就写一个函数吧,PVOIDGetModlueBaseAdress(char*ModlueName){

ULONGsize,index;

PULONGbuf;NTSTATUSstatus;

PSYSTEM_MODULE_INFORMATIONmodule;

PVOIDdriverAddress=0;

ZwQuerySystemInformation(SystemModuleInformation,&size,0,&size);if(NULL==(buf=(PULONG)ExAllocatePool(PagedPool,size)))

{

DbgPrint("failedallocmemoryfailed/n");

return0;

}status=ZwQuerySystemInformation(SystemModuleInformation,buf,size,0);

if(!NT_SUCCESS(status))

{DbgPrint("failedquery/n");

return0;

}module=(PSYSTEM_MODULE_INFORMATION)((PULONG)buf+1);

for(index=0;index<*buf;index++)

if(_stricmp(module[index].ImageName+module[index].ModuleNameOffset,ModlueName)==0)

{driverAddress=module[index].Base;DbgPrint("Modulefoundat:%x/n",driverAddress);

}

ExFreePool(buf);

returndriverAddress;}自己添加点测试代码编译下,没什么问题,这样我们就完成了第一个问题

接着是写自己的函数了,就是替换PsGetCurrentProcessId的函数,这里我们很简单的输出点内容就可以了ULONGg_OriginalPsGetCurrentProcessId;typedefHANDLE(*PSGETCURRENTPROCESSID)();HANDLEMyPsGetCurrentProcessId(){

HANDLEhandle;

DbgPrint("HOOK_PsGetCurrentProcessIdcalled!/n");handle=((PSGETCURRENTPROCESSID)(g_OriginalPsGetCurrentProcessId))();returnhandle;}

好了,那就开始写安装钩子程序吧,因为在卸在钩子时需要用到一些变量,这里我们就把安装和卸载写成一个函数就可以了,注意INunsignedinttest,传入1表示安装钩子,否则表示卸载,INPCSTRfunName这里我们传入PsGetCurrentProcessId,好了请看代码VOIDStartHook_And_Unhook(INPCSTRfunName,INunsignedinttest){

HANDLEhMod;

PUCHARBaseAddress=NULL;

IMAGE_DOS_HEADER*dosheader;

IMAGE_OPTIONAL_HEADER*opthdr;

PIMAGE_EXPORT_DIRECTORYexports;

USHORTindex=0;

ULONGaddr,i;

PUCHARpFuncName=NULL;

PULONGpAddressOfFunctions,pAddressOfNames;

PUSHORTpAddressOfNameOrdinals;

BaseAddress=GetModlueBaseAdress("ntkrnlpa.exe");

DbgPrint("MapBaseAddressis:%x/n",BaseAddress);

hMod=BaseAddress;

dosheader=(IMAGE_DOS_HEADER*)hMod;

opthdr=(IMAGE_OPTIONAL_HEADER*)((BYTE*)hMod+dosheader->e_lfanew+24);

exports=(PIMAGE_EXPORT_DIRECTORY)((BYTE*)dosheader+opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

pAddressOfFunctions=(ULONG*)((BYTE*)hMod+exports->AddressOfFunctions);

pAddressOfNames=(ULONG*)((BYTE*)hMod+exports->AddressOfNames);

pAddressOfNameOrdinals=(USHORT*)((BYTE*)hMod+exports->AddressOfNameOrdinals);

for(i=0;i<exports->NumberOfNames;i++){

index=pAddressOfNameOrdinals[i];

pFuncName=(PUCHAR)((BYTE*)hMod+pAddressOfNames[i]);

if(_stricmp((char*)pFuncName,funName)==0){

addr=pAddressOfFunctions[index];

break;}}

if(test==1)

{

_asm

{

CLI

MOV

EAX,CR0

ANDEAX,NOT10000H

MOV

CR0,EAX

}

DbgPrint("PsGetCurrentProcessIdis:%x/n",(PUCHAR)hMod+pAddressOfFunctions[index]);

pAddressOfFunctions[index]=(PCHAR)MyPsGetCurrentProcessId-BaseAddress;

DbgPrint("g_OriginalPsGetCurrentProcessIdis:%x/n",g_OriginalPsGetCurrentProcessId);

g_OriginalPsGetCurrentProcessId=(PUCHAR)hMod+pAddressOfFunctions[index];_asm

{

MOV

EAX,CR0

OR

EAX,10000H

MOV

CR0,EAX

STI

}

}

else

{_asm

{

CLI

MOV

EAX,CR0

ANDEAX,NOT10000H

MOV

CR0,EAX

}

pAddressOfFunctions[index]=(PCHAR)g_OriginalPsGetCurrentProcessId-BaseAddress;

_asm

{

MOV

EAX,CR0

OR

EAX,10000H

MOV

CR0,EAX

STI

}

}}好了,基本框架就差不多了,接着就是一些结构的声明,我们把它放在hookiat.h这个头文件里,因为很长就不帖了,可以在附件里看,上面的代码很多地方不是很好,需要自己修改,不保证在你机器不蓝,呵呵,学习靠思考,在代码里我修改了一处地方


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/tongxinshuyu/article-43685-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...