看了combojing前辈写的Inline Hook的文章,有很多都不明白,我自己尝试在原由代码之上加了一些注释,不知道是否正确。还请各位高手赐教。有懂的希望多给加点注释,然后给讲讲。
=================================================
/*
该Code的作者对同一变量进行了相同的赋值操作,我想也许他在接触Rootkit之前并没有花太
多时间在编程技术的研究上,包括语法...
*/
/*
The Is Inline Hook Code,Inline Hook Rewrite Function Head Code.
*/
/*include head file*/
#include <ntddk.h>
//#include <ntifs.h> //Im Not The File
/*声明全局变量*/
ULONG g_KiInsertQueueApc;
char g_oricode[8];
ULONG g_uCr0;
char *non_paged_memory;
//The Function Is What ?
void WPOFF()
{
ULONG uAttr;
/*嵌入Asm Code To Current Function Body*/
__asm
{
push eax;
mov eax,cr0; //cr0 Is What ?
mov uAttr,eax;
and eax,0FFFEFFFFh; /*CR0 16 BIT = 0*/
mov cr0,eax;
pop eax;
cli
};
g_uCr0=uAttr; /*保存原有的CRO属性*/
}
VOID WPON()
{
/*嵌入Asm Code*/
__asm
{
sti
push eax;
mov eax, g_uCr0; /*恢復原有 CR0 属性*/
mov cr0, eax;
pop eax;
};
}
__declspec(naked) my_function_detour_KiInsertQueueApc()
{
/*嵌入Asm Code*/
__asm
{
mov edi,edi
push ebp
mov ebp, esp
push ecx
mov eax,ecx
_emit 0xEA
_emit 0xAA
_emit 0xAA
_emit 0xAA
_emit 0xAA
_emit 0x08
_emit 0x00
}
}
//Get FunctionAddress Of FunctionName
ULONG GetFunctionAddr(IN PCWSTR FunctionName)
{
UNICODE_STRING UniCodeFunctionName;
RtlInitUnicodeString(&UniCodeFunctionName,FunctionName); //Initialize UnicodeString To UniCodeFunctionName Variable
return (ULONG)MmGetSystemRoutineAddress(&UniCodeFunctionName);
}
/*根据特征值,从KeInsertQueueApc搜索中搜索KiInsertQueueApc*/
//根据KeInsertQueueApc找到KiInsertQueueApc?
ULONG FindKiInsertQueueApcAddress()
{
//下面有2个函数名字很类似,注意区分.
char *Addr_KeInsertQueueApc=0;
int i;
char Findcode[]={0xE8,0xcc,0x29,0x00,0x00}; //The Is Opcode
ULONG Addr_KiInsertQueueApc=0;
Addr_KeInsertQueueApc=(char *)GetFunctionAddr(L"KeInsertQueueApc"); //Get The Function Address
//Loop Body
for(i=0;i<100;++i)
{
if(Addr_KeInsertQueueApc[i] == Findcode[0] &&
Addr_KeInsertQueueApc[i+1] == Findcode[1] &&
Addr_KeInsertQueueApc[i+2] == Findcode[2] &&
Addr_KeInsertQueueApc[i+3] == Findcode[3] &&
Addr_KeInsertQueueApc[i+4] == Findcode[4] )
{
Addr_KiInsertQueueApc=(ULONG)&Addr_KeInsertQueueApc[i]+0x29cc+5; //加密Opcode
break;
}
}
return Addr_KiInsertQueueApc;
}
VOID DetourFunctionKiInsertQueueApc()
{
//actual_function Save kiInsertQueueApc Address
char *actual_function=(char *)g_KiInsertQueueApc; //Get KiInsertQueueApc Address
unsigned long detour_address;
unsigned long reentry_address;
KIRQL oldIrql;
int i;
char newcode[]={0xEA,0x44,0x33,0x22,0x11,0x08,0x00,0x90}; //Save Address
reentry_address=((unsigned long)g_KiInsertQueueApc)+8;
non_paged_memory=ExAllocatePool(NonPagedPool,256); //Allocate MemoryBlock
//Loop Body
for(i=0;i<256;++i)
{
//Save Asm Code To Buffer ?
((unsigned char *)non_paged_memory)[i] = ((unsigned char *)my_function_detour_KiInsertQueueApc)[i];
}
detour_address=(unsigned long)non_paged_memory; //Get Function EntryPoint
*((unsigned long *)(&newcode[1]))=detour_address; //newcode[1]=detour_address
//Loop Body
for(i=0;i<200;++i)
{
if(
(0xAA == ((unsigned char *)non_paged_memory)[i]) &&
(0xAA == ((unsigned char *)non_paged_memory)[i+1]) &&
(0xAA == ((unsigned char *)non_paged_memory)[i+2]) &&
(0xAA == ((unsigned char *)non_paged_memory)[i+3])
)
{
*((unsigned long *)(&non_paged_memory[i]))=reentry_address;
break;
}
}
oldIrql=KeRaiseIrqlToDpcLevel();
//Loop 8 Count
for(i=0;i<8;++i)
{
g_oricode[i]=actual_function[i]; //Save KiInsertQueueApc 前8 Byte To g_oricode
actual_function[i]=newcode[i]; //Update actual_function array
}
KeLowerIrql(oldIrql); //降低Irql优先级
}
//The Function 负责 Unload Driver
VOID UnDetourFunction()
{
char *actual_function=(char *)g_KiInsertQueueApc; //Get KiInsertQueueApc Address
KIRQL oldIrql; //中断 ?
int i;
WPOFF(); //Call The Function
oldIrql=KeRaiseIrqlToDpcLevel(); //提升The Irql 优先级
for(i=0;i<8;++i)
{
actual_function[i]=g_oricode[i];
}
KeLowerIrql(oldIrql);
WPON();
ExFreePool(non_paged_memory); //Free MemoryBlock About non_paged_memory
}
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
DbgPrint("Unload The Driver In Current Function.");
UnDetourFunction(); //Call The Function
}
//Driver EntryPoint
NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,IN PUNICODE_STRING theRegistryPath)
{
DbgPrint("Current In DriverEntry"); //Send String To Kernel Debug
theDriverObject->DriverUnload=OnUnload; //Unload Driver Function
g_KiInsertQueueApc=FindKiInsertQueueApcAddress(); //Get KiInsertQueueApc Address
DetourFunctionKiInsertQueueApc(); //Call The Function
return STATUS_SUCCESS;
}
==================================================
请问Inline Hook 是不是要改写函数头部啊,然后之后在恢复?
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!