2014七月7
WD-新建SSDT项通讯
以下仅针对32位系统,在XP下测试:
以下是XP在ring3的调用方式:
View Code XML
1 2 3 4 5 6 7 8 9 10 11 12 | // 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:
View Code XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #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:
View Code XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | #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; } |
文章作者:hgy413
本文地址:https://hgy413.com/1514.html
版权所有 © 转载时必须以链接形式注明作者和原始出处!