首页
社区
课程
招聘
[求助]Hook NtTerminateProcess 监视参数出问题了
发表于: 2011-9-27 09:57 6717

[求助]Hook NtTerminateProcess 监视参数出问题了

2011-9-27 09:57
6717
#include <ntddk.h>
#include "stdio.h"
#include <Xed.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为导出函数

/////////////////////////////////////
ULONG GetFunctionAddr( IN PCWSTR FunctionName);
VOID Hook();
VOID Unhook();
VOID OnUnload(IN PDRIVER_OBJECT DriverObject);
VOID GetAddress();
ULONG OutCall;
VOID CLI();
VOID STI();



char *Name="[DbgPrint:] %8x %8x %8x %8x %8x %8x %8x %8x";



ULONG JmpAddress;//跳转到NtOpenProcess里的地址
ULONG OldServiceAddress;//原来NtOpenProcess的服务地址
ULONG DbgPrintFunAddr;
UCHAR KiByte[5]={0xe9,0x00,0x00,0x00,0x00};
ULONG OutHook_1,OutJmp_1;

//////////////////////////////////////
__declspec(naked) NTSTATUS __stdcall MyNtTerminateProcess() 
{
//	__asm
//	{
//	pushad
//	pushf
//	}
	__asm
	{
	push    dword ptr [ebp+28h] 
	push    dword ptr [ebp+24h] 
	push    dword ptr [ebp+20h]
	push    dword ptr [ebp+1ch]
	push    dword ptr [ebp+18h]
	push    dword ptr [ebp+14h]
	push    dword ptr [ebp+10h]
	push    dword ptr [ebp+0xC]
//	push    ecx   //Hwnd
	push    dword ptr [ebp+0x8]
	push	Name  //Ascii
	call	DbgPrintFunAddr
	add esp,0x28
	}
//	__asm
//	{
//	popad
//	popf
//	}
	__asm
	{
	call    OutCall		//NtCreateProcessEx
	jmp 	OutJmp_1
//	ret
//	jmp 	JmpAddress
	}
}
///////////////////////////////////////////////////
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
  DriverObject->DriverUnload = OnUnload;
  DbgPrintFunAddr = (ULONG)GetFunctionAddr(L"DbgPrint"); 
  //ObReferenceObjectByHandle  有导出。。
  
  GetAddress();
//  DbgPrint("[DbgPrint: ] %8x",DbgPrintFunAddr);
  KdPrint(("[MyNtCreateProcessEx:] %8x",MyNtCreateProcessEx));
  Hook();
  return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
  Unhook();
}
/////////////////////////////////////////////////////
VOID Hook()
{
 	ULONG JmpOffKiAt;
//	UCHAR JmpCodeKiAt[5]={0xE8,0x00,0x00,0x00,0x00};   //这里是CALL方式  我用CALL怎么都处理不好。
	UCHAR JmpCodeKiAt[5]={0xE9,0x00,0x00,0x00,0x00};   //Jmp方式
	UCHAR MaxByte[4]={0xFF,0xFF,0xFF,0xFF};
	RtlCopyMemory (KiByte, (PVOID)OutHook_1, 5);  //保存HOOK原位置数据
	
	
	JmpOffKiAt=(PCHAR)MyMyNtTerminateProcess-(PCHAR)OutHook_1-0x5;
	RtlCopyMemory(JmpCodeKiAt+1,&JmpOffKiAt,4);

	CLI();
	RtlCopyMemory((PVOID)OutHook_1,(PVOID)JmpCodeKiAt,5);
	STI();

}

VOID Unhook()
{
	CLI();
	RtlCopyMemory((PVOID)OutHook_1,KiByte,5);	
	STI();

  KdPrint(("Unhook"));
}

ULONG GetFunctionAddr( IN PCWSTR FunctionName)  //Get Funcion Address
{
  UNICODE_STRING UniCodeFunctionName;
  RtlInitUnicodeString( &UniCodeFunctionName, FunctionName );
  return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName );   
}

VOID GetAddress()
{
	ULONG AddCall_1,AddCallEnd_1,i,KiFunAddr;
	UCHAR CallByte_1[4]={0x00,0x00,0x00,0x00}; 
	UCHAR MaxByte[4]={0xFF,0xFF,0xFF,0xFF}; 
	PBYTE CurByte;
	ULONG CurAddr_1;
	ULONG Address,Adds_1;

	Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x30 * 4;
	Address = *(ULONG*)Address;
	CurByte = (PBYTE)Address;
	
	for (i=0;i<=200;i++)   
	{
		if (CurByte[i] == 0xC3) //先搜索返回
		{
		KiFunAddr = *(PULONG)&CurByte[i+1];
		break;   
		}
	}

	CurByte=CurByte+i+0x4;//跳过第一个E8
	
	CurByte= (PBYTE)CurByte;
//	DbgPrint("[CurByte] %x\n",(ULONG)CurByte); 
	
	
	for (i=0;i<=200;i++)   
	{
		if (CurByte[i] == 0xe8) //
		{
		//Adds_1 = *(PULONG)&CurByte[i+1];//取地址后接着取内容
		Adds_1 = *(ULONG*)&CurByte[i+1];		
		//DbgPrint("[Adds_1] %x\n",(ULONG)Adds_1); 
		break;   
		}
	}

	AddCall_1= (ULONG)&CurByte[i+1];         //Call 代码地址	
	//DbgPrint("[AddCall_1地址] %x\n",(ULONG)AddCall_1);
	
	OutHook_1 = (ULONG)AddCall_1-0x1;
	OutJmp_1  = (ULONG)AddCall_1+0x4;
	
	AddCallEnd_1 = AddCall_1+0x4;                //CALL地址后面
	JmpAddress = AddCallEnd_1;
	AddCall_1 =  (ULONG)*((PULONG)MaxByte)-(ULONG)Adds_1;    //比下面的更加智能化
	AddCall_1 =  AddCallEnd_1-AddCall_1-0x1; 
	//DbgPrint("[NtCreateProcessEx_Call] %x\n",(ULONG)AddCall_1);  //到这里已经定位出 NtCreateProcessEx_Call 的函数地址了
	OutCall = (ULONG)AddCall_1;
}

VOID CLI()
{
  __asm
  {
    cli
    mov  eax,cr0
    and  eax,not 10000h
    mov  cr0,eax
  }
}
VOID STI()
{
  __asm
  {  
    mov  eax,cr0
    or   eax,10000h
    mov  cr0,eax
    sti
  }
}






我看看了函数说明,第一个是句柄,可是我得到的数值怎么看都不对。
求教
我在调试输出中看到的一个参数和eprocess里面一个成员的数值相同
1ff***
参数应该没问题

我在使用PsTerminateProcess结束进程传入第一个参数发现不行。所以疑问。

大致过程:
push进参数
输出
恢复堆栈

调用原函数
--------------
q2:
cli
sti
这2个函数内部代码
我在一本书上看到
说的是用CR0来操作一个了寄存器的16BIT
置0或者1来实现对内存的访问控制
说的好像是R0可以访问R3的内存
但是我在驱动中都是操作的R0内存。

那么我不写可以吗?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 304
活跃值: (507)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
cr0.wp位 清0可以写代码页

PsTerminateProcess参数是eprocess
2011-9-27 22:50
0
雪    币: 129
活跃值: (147)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
此人是骗子,大家注意
2022-6-30 16:52
0
游客
登录 | 注册 方可回帖
返回
//