0.ring0-新建SSDT项进行通讯(随手代码)
2011-12-27 20:14
148 查看
以下仅针对32位系统,在XP下测试:
以下是XP在ring3的调用方式:
ring3:
运行ring3小程序,可以看到outbuf为AAAAA..,大小为10:
以下是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:
相关文章推荐
- [转]与动态执行的C# 代码进行通讯
- 基于X.509证书和SSL协议的身份认证过程实现(OpenSSL可以自己产生证书,有TCP通过SSL进行实际安全通讯的实际编程代码)good
- 0.ring0-内存可读、可写、有效性、指针是否为空、深度校验字符串(随手代码)
- 与动态执行的C# 代码进行通讯
- 0.ring0-SSDT-SSTDSHADOW原理分析、遍历随手代码
- 利用java在服务器和客服端建立连接,进行通讯(代码实例)
- 利用java在服务器和客服端建立连接,进行通讯(代码实例)
- SYD8801从机和TIcc2540主机进行通讯(通过修改从机端代码实现)
- 在使用MyEclipse新建文件时常常有些不需要的冗余代码可以采用如下方式进行更改
- SYD8801从机和TIcc2540主机进行通讯(通过修改主机端代码实现)
- PHP与C(或其它语言)通过消息队列进行通讯,完整代码
- 与动态执行的C# 代码进行通讯
- 代码中进行事务处理 -多次新建连接导致的问题。
- 与动态执行的C# 代码进行通讯
- 与动态执行的C# 代码进行通讯
- PHP与C(或其它语言)通过消息队列进行通讯,完整代码
- 【微信开发】-发送位置进行Geocoding API转换(经纬度和地址名称互换), 主要代码在private function receiveLocation($object)
- irp追踪工具_CreateFile_进行通讯 打印主请求号
- 用程序来自动建立FTP帐号(serv-u的odbc设置)带.net新建帐户代码
- [置顶] 【JAVA】Eclipse中使用git进行pull远程代码,报错The current branch is not configured for pull No value for key branc