NtReadVirtualMemory等几个函数被游戏给hook了。
我想绕过hook,通过修改ssdt表内函数的地址跳转到自己的地址来实现绕过。
然后用自己的函数实现原始函数被hook前的代码段,然后跳转到没被hook的代码
例如修改好了ssdt表中的地址
然后用自己的函数实现前46个字节
然后在Jmp到原始的函数,也就是805B52C2+46
请教下大家Asm中,例如call 8053CBE0应该怎么写呢?
我这样写,貌似不对哦。
还有这样做是否能绕过保护呢?
hook前的函数
805B52C2 6A 1C push 1C
805B52C4 68 F0AE4D80 push 804DAEF0
805B52C9 E8 1279F8FF call 8053CBE0
805B52CE 64:A1 24010000 mov eax, dword ptr fs:[124]
805B52D4 8BF8 mov edi, eax
805B52D6 8A87 40010000 mov al, byte ptr [edi+140]
805B52DC 8845 E0 mov byte ptr [ebp-20], al
805B52DF 8B75 14 mov esi, dword ptr [ebp+14]
805B52E2 84C0 test al, al
805B52E4 74 66 je 805B534C
805B52E6 8B45 0C mov eax, dword ptr [ebp+C]
805B52E9 8D1430 lea edx, [eax+esi]
805B52EC 3BD0 cmp edx, eax
805B52EE 72 55 jc 805B5345
805B52F0 8B45 10 mov eax, dword ptr [ebp+10]
805B52F3 8D0C30 lea ecx, [eax+esi]
805B52F6 3BC8 cmp ecx, eax
805B52F8 72 4B jc 805B5345
hook后的函数
805B52C2 E9 5949ED07 jmp 88489C20
805B52C7 4D dec ebp
805B52C8 80E8 12 sub al, 12
805B52CB 79 F8 jns 805B52C5
805B52CD FF64A1 24 jmp dword ptr [ecx+24]
805B52D1 0100 add dword ptr [eax], eax
805B52D3 008B F88A8740 add byte ptr [ebx+40878AF8], cl
805B52D9 0100 add dword ptr [eax], eax
805B52DB 0088 45E08B75 add byte ptr [eax+758BE045], cl
805B52E1 14 84 adc al, 84
805B52E3 C07466 8B 45 sal byte ptr [esi-75], 45
805B52E8 0C 8D or al, 8D
805B52EA 14 30 adc al, 30
805B52EC 3BD0 cmp edx, eax
805B52EE 72 55 jc 805B5345
805B52F0 8B45 10 mov eax, dword ptr [ebp+10]
805B52F3 8D0C30 lea ecx, [eax+esi]
805B52F6 3BC8 cmp ecx, eax
805B52F8 72 4B jc 805B5345
下面为我修改的堕落天使的代码
#include<ntddk.h>
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PVOID ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
ULONG ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE; //由于KeServiceDescriptorTable只有一项,这里就简单点了
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;//KeServiceDescriptorTable为导出函数
/////////////////////////////////////
VOID Hook();
VOID Unhook();
VOID OnUnload(IN PDRIVER_OBJECT DriverObject);
//////////////////////////////////////
ULONG JmpAddress;//跳转到NtReadVirtualMemory里的地址
ULONG OldServiceAddress;//原来NtReadVirtualMemory的服务地址
#pragma warning(disable: 4733)
//////////////////////////////////////
__declspec(naked) NTSTATUS __stdcall MyNtReadVirtualMemory (
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG BufferSize,
OUT PULONG NumberOfBytesRead OPTIONAL
)
{
DbgPrint("NtReadVirtualMemory() called");
__asm{
push 1ch
push 804daef0h //共42个字节
push eax
mov eax, [esp+10]
mov [esp+10], ebp
lea ebp,[esp+10]
sub esp, eax
push ebx
push esi
push edi
mov eax,[ebp-8]
mov [ebp-18], esp
push eax
mov eax,[ebp-4]
mov [ebp-4], -1
mov [ebp-8], eax
lea eax,[ebp-10]
jmp [JmpAddress]
}
}
///////////////////////////////////////////////////
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
DriverObject->DriverUnload = OnUnload;
DbgPrint("Unhooker_load");
Hook();
return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
DbgPrint("Unhooker_unload!");
Unhook();
}
/////////////////////////////////////////////////////
VOID Hook()
{
ULONG Address;
Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0xBA * 4;//0xBA为NtReadVirtualMemory服务ID
DbgPrint("Address:0x%08X",Address);
OldServiceAddress = *(ULONG*)Address;//保存原来NtReadVirtualMemory的地址
//DbgPrint("OldServiceAddress:0x%08X",OldServiceAddress);
// DbgPrint("MyNtOpenProcess:0x%08X",MyNtReadVirtualMemory);
JmpAddress = (ULONG)OldServiceAddress + 12; //跳转到NtReadVirtualMemory函数头+10的地方,这样在其前面写的JMP都失效了
DbgPrint("JmpAddress:0x%08X",JmpAddress);
__asm{//去掉内存保护
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*((ULONG*)Address) = (ULONG)MyNtReadVirtualMemory;//HOOK SSDT
__asm{//恢复内存保护
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
//////////////////////////////////////////////////////
VOID Unhook()
{
ULONG Address;
Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0xBA * 4;//查找SSDT
__asm{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*((ULONG*)Address) = (ULONG)OldServiceAddress;//还原SSDT
__asm{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
DbgPrint("Unhook");
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课