首页
社区
课程
招聘
[旧帖] [求助]NtReadVirtualMemory被Hook 0.00雪花
发表于: 2011-4-1 17:22 6568

[旧帖] [求助]NtReadVirtualMemory被Hook 0.00雪花

2011-4-1 17:22
6568
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直播授课

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 2362
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
堕落天使的代码没问题
过保护这些是不够的
2011-4-1 17:46
0
雪    币: 264
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
又见zapline,呵呵,可否给个Url呢?
2011-4-1 18:03
0
雪    币: 169
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
多google,网上都有答案的
call   8053CBE0
要这样写
mov eax,0x8053CBE0
call eax
2011-4-14 01:19
0
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
悲剧,没仔细看楼主的问题,抱歉,请直接跳过俺的回复

805B52C9    E8 1279F8FF    call   8053CBE0

这里已经写得很清楚了啊 call   xxxxxxx1  = E8 (xxxxxxx1-  805B52C9-5)

反正我看的教材里面是这样写得,大概意思就是在805B52C9位置写入E8 xxxxxxxx, 其中E8 XXXXXXXX占5个字节
你写入call的时候记得一定要看你要写入地方的位置够不够,会不会把下面一行代码一起占用,会不会蓝屏等等。。。
2011-4-14 12:03
0
游客
登录 | 注册 方可回帖
返回
//