3)Two-dimensional array is used to save function front byte, Array form is array[15][30];
Each function have 30 bytes usable on 15 function. First save orginal function front byte on 30 bytes, Then write 0xe9, Continue write array current place with original hook function address offset that we already copy bytecode after place among re;atove offset value.
The array effect, when after hook function, execute to finish our hook function, Then need recover original api function, Because original api function front five bytes already is rewrite, function original front byte already save to appropriate array, So there idea is, execute machine code on the array, array machine code execute to the end, jump to original function some offset place, continue to execute.
3. Inline hook
1) IoAllocateMdl
,Allocate one mdl, Hook function is mapping to here.
2) MmProbeAndLockPages, Lock page
3)
do away with write-protect
4) Save function front machine code to homologous two-dimensional array, rewrite front five bytes, Let is jump to start address on .data:00034E98 jump table homologous jump function.
5)
Recover write-protect
6) MmUnlockPages
7) IoFreeMdl
4.
Revover After Inline hook
The example is hook了KiInsertQueueApc, Because KiInsertQueueApc isn't export, need find on KeInsetQueueApc.
#include <ntddk.h>
#include
<ntifs.h>
ULONG g_KiInsertQueueApc;
char g_oricode[8];
ULONG
g_uCr0;
char *non_paged_memory;
void WPOFF()
{
ULONG uAttr;
_asm
{
push eax;
mov eax, cr0;
mov uAttr, eax;
and eax, 0FFFEFFFFh; // CR0 16 BIT = 0
mov cr0, eax;
pop eax;
cli
};
g_uCr0 =
uAttr; //Save original CR0
}
VOID WPON()
{
_asm
{
sti
push eax;
mov eax, g_uCr0; //Recover orginal CR
mov cr0, eax;
pop eax;
};
}
__declspec(naked)
my_function_detour_KiInsertQueueApc()
{
__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
}
}
ULONG
GetFunctionAddr( IN PCWSTR FunctionName)
{
UNICODE_STRING UniCodeFunctionName;
RtlInitUnicodeString(
&UniCodeFunctionName, FunctionName );
return
(ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName );
}
//
根据特征值,从KeInsertQueueApc搜索中搜索KiInsertQueueApc
ULONG
FindKiInsertQueueApcAddress()
{
char *
Addr_KeInsertQueueApc = 0;
int i = 0;
char Findcode[] = {
0xE8, 0xcc, 0x29, 0x00, 0x00 };
ULONG Addr_KiInsertQueueApc =
0;
Addr_KeInsertQueueApc = (char *)
GetFunctionAddr(L"KeInsertQueueApc");
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;
break;
}
}
return Addr_KiInsertQueueApc;
}
VOID
DetourFunctionKiInsertQueueApc()
{
char
*actual_function = (char *)g_KiInsertQueueApc;
unsigned long
detour_address;
unsigned long reentry_address;
KIRQL
oldIrql;
int i = 0;
char newcode[] = { 0xEA,
0x44, 0x33, 0x22, 0x11, 0x08, 0x00, 0x90 };
reentry_address = ((unsigned long)g_KiInsertQueueApc) + 8;
non_paged_memory = ExAllocatePool(NonPagedPool, 256);
for(i=0;i<256;i++)
{
((unsigned char
*)non_paged_memory)[i] = ((unsigned char
*)my_function_detour_KiInsertQueueApc)[i];
}
detour_address = (unsigned long)non_paged_memory;
*(
(unsigned long *)(&newcode[1]) ) = detour_address;
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();
for(i=0;i < 8;i++)
{
g_oricode[i] = actual_function[i];
actual_function[i] =
newcode[i];
}
KeLowerIrql(oldIrql);
}
VOID
UnDetourFunction()
{
char *actual_function = (char
*)g_KiInsertQueueApc;
KIRQL oldIrql;
int i = 0;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 8;i++)
{
actual_function[i] =
g_oricode[i];
}
KeLowerIrql(oldIrql);
WPON();
ExFreePool(non_paged_memory);
}
VOID
OnUnload( IN PDRIVER_OBJECT DriverObject )
{
DbgPrint("My
Driver Unloaded!");
UnDetourFunction();
}
NTSTATUS
DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING
theRegistryPath )
{
DbgPrint("My Driver Loaded!");
theDriverObject->DriverUnload = OnUnload;
g_KiInsertQueueApc = FindKiInsertQueueApcAddress();
DetourFunctionKiInsertQueueApc();
return
STATUS_SUCCESS;
}
No comments:
Post a Comment