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

来源:互联网 发布:学尤克里里下什么软件 编辑:程序博客网 时间:2024/04/27 12:46

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

// xpntdll!NtReadFile:7c92d9b0 b8b7000000  mov eax,0B7h7c92d9b5 ba0003fe7f  mov edx,offset SharedUserData!SystemCallStub (7ffe0300)7c92d9ba ff12calldword ptr [edx]  ds:0023:7ffe0300={ntdll!KiFastSystemCall (7c92e4f0)}7c92d9bc c22400  ret 24h7c92d9bf 90  nop  ntdll!KiFastSystemCall:7c92e4f0 8bd4mov edx,esp7c92e4f2 0f34sysenter
所以原理也比较简单了,仿写即可,注意SSDT要去掉写保护!
ring3:

#include "stdafx.h"#include <Windows.h> __declspec(naked) void MyKiFastSystemCall(){__asm{mov  edx,esp;__emit 0x0f;__emit 0x34;}}; __declspec(naked) NTSTATUS NTAPIIOSystemControl(IN ULONG IoCtrl,IN PVOID InputBuf,IN ULONG InputBufLen,OUT PVOID OutputBuf,IN ULONG OutputLen,OUT PULONG ReturnLen){__asm{mov eax, 11Ch;call MyKiFastSystemCallretn 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"// deftypedef 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}; NTSTATUSIoSystemControl(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{MOVEAX, CR0;OREAX, 10000H;MOVCR0, 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{MOVEAX, CR0;OREAX, 10000H;MOVCR0, 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:






原创粉丝点击