http://blog.csdn.net/hgy413/article/details/7107009
以下仅针对32位系统,在XP下测试:
以下是XP在ring3的调用方式:
[cpp] view plaincopy
- // 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:
[cpp] view plaincopy
- #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:
[cpp] view plaincopy
- #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:
时间: 2024-11-06 03:53:29