2.ring0-新建SSDT项进行通讯(随手代码)

以下仅针对32位系统,在XP下测试:
以下是XP在ring3的调用方式:

// xp
ntdll!NtReadFile:
7c92d9b0 b8b7000000	  mov	 eax,0B7h
7c92d9b5 ba0003fe7f	  mov	 edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92d9ba ff12			call	dword ptr [edx]	  ds:0023:7ffe0300={ntdll!KiFastSystemCall (7c92e4f0)}
7c92d9bc c22400		  ret	 24h
7c92d9bf 90			  nop
 
 
ntdll!KiFastSystemCall:
7c92e4f0 8bd4			mov	 edx,esp
7c92e4f2 0f34			sysenter
所以原理也比较简单了,仿写即可,注意SSDT要去掉写保护!
ring3:

#include "stdafx.h"
#include <Windows.h>
 
__declspec(naked) void MyKiFastSystemCall()
{
	__asm
	{
		mov  edx,esp;
		__emit 0x0f;
		__emit 0x34;
	}
};
 
__declspec(naked) NTSTATUS NTAPI
	IOSystemControl(
	IN ULONG IoCtrl,
	IN PVOID InputBuf,
	IN ULONG InputBufLen,
	OUT PVOID OutputBuf,
	IN ULONG OutputLen,
	OUT PULONG ReturnLen)
{
		__asm
		{
			mov eax, 11Ch;
			call MyKiFastSystemCall
			retn 0x18;
		}
}
 
int _tmain(int argc, _TCHAR* argv[])
{
	char szBuf[100] = {0};
	ULONG outlen = 0;
	IOSystemControl(0x12345678,"hgy413",strlen("hgy413"),szBuf,99,&outlen);
	printf("%s-%d\n",szBuf, outlen);
 
	getchar();
	return 0;
}
ring0:

#include "main.h"
// def
typedef struct _KSERVICE_TABLE_DESCRIPTOR
{
	PULONG ServiceTableBase;//SSTD基地址
	PULONG Count;				//包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新
	ULONG TableSize;			//由 ServiceTableBase 描述的服务的数目
	PUCHAR ArgumentTable;		//包含每个系统服务参数字节数表的基地址-系统服务参数表 每个表项是一个UCHAR,表示一个函数参数长度
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
 
//ssdt表已经导出了,这里例行公事下
extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;
KSERVICE_TABLE_DESCRIPTOR ssdt_copy;
ULONG NewSsdtServiceTableBase[1024] = {0};
UCHAR NewSsdtServiceTableNumber[1024] = {0};
 
NTSTATUS
IoSystemControl(IN ULONG ControlCode,
					 IN PVOID InputBuffer OPTIONAL,
					 IN ULONG InputBufferLength,
					 OUT PVOID OutputBuffer OPTIONAL,
					 IN ULONG OutputBufferLength,
					 OUT PULONG ReturnLength OPTIONAL
					 )
{
	NTSTATUS Status = STATUS_SUCCESS;
 
	if (OutputBuffer&&MmIsAddressValid(OutputBuffer))
	{
		KdPrint(("%s\r\n",InputBuffer));
		memset(OutputBuffer, 0x41, OutputBufferLength);//传出buf变为AAAAA...
		if (ReturnLength&& MmIsAddressValid(ReturnLength))
		{
			*ReturnLength = 10; //传出size随便设置为10
		}
	}
	return Status;
}
 
 
void  NtosAddSsdtServiceTable(
							  PVOID NewFunction,
							  ULONG NewNumber
							  )
{
	NTSTATUS Status = STATUS_SUCCESS;
	PEPROCESS Process;
 
	//禁止写保护,不然蓝屏
	__asm
	{
		MOV	EAX, CR0;
		OR	EAX, 10000H;
		MOV	CR0, EAX;
		STI;
	}
 
	//复制原始服务表
	//把原始表复制到我们的数组
	memcpy(
		NewSsdtServiceTableBase,
		KeServiceDescriptorTable->ServiceTableBase,
		KeServiceDescriptorTable->TableSize * 4
		);
 
	//原始函数个数
	memcpy(
		NewSsdtServiceTableNumber,
		KeServiceDescriptorTable->ArgumentTable,
		KeServiceDescriptorTable->TableSize
		);
 
	//修改SSDT表添加服务函数
	NewSsdtServiceTableBase[ssdt_copy.TableSize] = NewFunction;
	NewSsdtServiceTableNumber[ssdt_copy.TableSize] = NewNumber;
 
	//更新内存里面导出 KeServiceDescriptorTable Ssdt 表
	KeServiceDescriptorTable->ServiceTableBase = NewSsdtServiceTableBase;
	KeServiceDescriptorTable->ArgumentTable = NewSsdtServiceTableNumber;
	KeServiceDescriptorTable->TableSize = ssdt_copy.TableSize + 1;
 
	//恢复写保护
	__asm
	{
		MOV	EAX, CR0;
		OR	EAX, 10000H;
		MOV	CR0, EAX;
		STI;
	}
}
 
VOID DDKUnload (IN PDRIVER_OBJECT pDriverObject)
{
	KdPrint(("[DDKUnload]-start\n"));
 
	//恢复原始的
	KeServiceDescriptorTable->ServiceTableBase = ssdt_copy.ServiceTableBase;
	KeServiceDescriptorTable->Count = ssdt_copy.Count;
	KeServiceDescriptorTable->TableSize = ssdt_copy.TableSize;
	KeServiceDescriptorTable->ArgumentTable = ssdt_copy.ArgumentTable;
 
	KdPrint(("[DDKUnload]-end\n"));
}
 
NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject,
					  IN PUNICODE_STRING pRegistryPath)
{
	KdPrint(("[DriverEntry]-start\n"));
	pDriverObject->DriverUnload = DDKUnload;
 
	// 保存原始的
	ssdt_copy.ServiceTableBase = KeServiceDescriptorTable->ServiceTableBase;
	ssdt_copy.Count = KeServiceDescriptorTable->Count;
	ssdt_copy.TableSize = KeServiceDescriptorTable->TableSize;
	ssdt_copy.ArgumentTable = KeServiceDescriptorTable->ArgumentTable;
 
	//我们调用自定义函数,往SSDT表添加内存
	NtosAddSsdtServiceTable(IoSystemControl, 24);
 
	KdPrint(("[DriverEntry]-end\n"));
	return STATUS_SUCCESS;
}
在驱动加载后,可以看到:

运行ring3小程序,可以看到outbuf为AAAAA..,大小为10:






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值