ImageVerifierCode 换一换
格式:DOCX , 页数:21 ,大小:20.69KB ,
资源ID:7751183      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/7751183.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(安全稳定的实现进线程监控.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

安全稳定的实现进线程监控.docx

1、安全稳定的实现进线程监控安全稳定的实现进线程监控 用PsSetCreateProcessNotifyRoutine,PsSetCreateThreadNotifyRoutine来进行进程线程监控我想大家已经都非常熟练了。前一段时间看到网上有人在研究监视远线程的文章,比较有意思。就写代码玩一玩。这之中就出现了一些问题,比方说直接用sinister的代码的话,是不能动态卸载的,因为他在安装了进线程监视函数后没有进行清除动作,造成在动态卸载时蓝屏。 BUGCHECK为0x000000ce,错误码为: DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATI

2、ONS很显然,在驱动退出后,一些进线程操作仍然在访问原来的地址,造成出错。在XP后,微软给出了一个函数PsRemoveCreateThreadNotifyRoutine用来清除线程监视函数(清除进程监视的就是PsSetCreateProcessNotifyRoutine)。我一直奇怪ICESWORD在Windows2000中是怎么做到进线程监视的。后来才发现,在运行icesword后释放出一个detport.sys文件,然后一直在系统中存在着没有卸载掉。只是把它隐藏了而已。这不是个好消息,难道我为了测试一个驱动,测试一次就得重启一次吗?呵呵,肯定不是啊,所以想办法搞定它。 我们来看一下进线程监

3、视在底层是如何实现的,在Windows2000源代码中先找到创建线程的函数实现: / win2kprivatentospscreate.h/NTSTATUSPspCreateThread( . . ) . if (PspCreateProcessNotifyRoutineCount != 0) /首先调用进程监控函数 ULONG i; for (i=0; iInheritedFromUniqueProcessId, Process-UniqueProcessId, TRUE ); . . if (PspCreateThreadNotifyRoutineCount != 0) ULONG i;

4、for (i=0; iCid.UniqueProcess, Thread-Cid.UniqueThread, TRUE ); . .从上面可以看到,在每创建一个线程后会调用PspCreateProcessNotifyRoutinei地址指向的函数。而PsSetCreateThreadNotifyRoutine的作用就是将PspCreateThreadNotifyRoutinei数组设置值,该值就是监视函数的地址。 NTSTATUSPsSetCreateThreadNotifyRoutine( IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine ) UL

5、ONG i; NTSTATUS Status; Status = STATUS_INSUFFICIENT_RESOURCES; for (i = 0; i 上面的一些结构如下: / win2kprivatentospspsp.h/#define PSP_MAX_CREATE_THREAD_NOTIFY 8 /最大监视数目ULONG PspCreateThreadNotifyRoutineCount; /用来记数PCREATE_THREAD_NOTIFY_ROUTINE PspCreateThreadNotifyRoutine PSP_MAX_CREATE_THREAD_NOTIFY ; /函数

6、地址数组而PCREATE_THREAD_NOTIFY_ROUTINE定义如下: typedefVOID(*PCREATE_THREAD_NOTIFY_ROUTINE)( IN HANDLE ProcessId, IN HANDLE ThreadId, IN BOOLEAN Create );相应的,进程的结构也是一样的。 通过上面,我们可以看到,只要我们找出该函数数组地址,在我们退出驱动时先将其全部清零,清零的大小为PSP_MAX_CREATE_THREAD_NOTIFY。 这样的话下一次的进线程操作就不会调用这个函数指针了,也就让系统回到正常。我们再通过PsSetCreateProcessN

7、otifyRoutine来验证一下: NTSTATUSPsSetCreateProcessNotifyRoutine( IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine, IN BOOLEAN Remove ) ULONG i; for (i=0; i 好了,方法已经知道了,只要找出地址,我们就能够“全身而退”了。看一下Windows2003下面的PsRemoveCreateThreadNotifyRoutine实现: lkd u PsRemoveCreateThreadNotifyRoutine l 20nt!PsRemoveCreateThre

8、adNotifyRoutine:80651d7b 53 push ebx80651d7c 56 push esi80651d7d 57 push edi80651d7e 33db xor ebx,ebx80651d80 bf400f5780 mov edi,0x80570f40 /起始地址80651d85 57 push edi80651d86 e8a7500100 call nt!ExWaitForRundownProtectionRelease+0x5cf (80666e32)80651d8b 8bf0 mov esi,eax80651d8d 85f6 test esi,esi80651d

9、8f 7420 jz nt!PsRemoveCreateThreadNotifyRoutine+0x36 (80651db1)80651d91 56 push esi80651d92 e8ba1bffff call nt!IoReportTargetDeviceChange+0x7aa0 (80643951)80651d97 3b442410 cmp eax,esp+0x1080651d9b 750d jnz nt!PsRemoveCreateThreadNotifyRoutine+0x2f (80651daa)80651d9d 56 push esi80651d9e 6a00 push 0x

10、080651da0 57 push edi80651da1 e8c54f0100 call nt!ExWaitForRundownProtectionRelease+0x508 (80666d6b)80651da6 84c0 test al,al80651da8 751b jnz nt!PsRemoveCreateThreadNotifyRoutine+0x4a (80651dc5)80651daa 56 push esi80651dab 57 push edi80651dac e892510100 call nt!ExWaitForRundownProtectionRelease+0x6e0

11、 (80666f43)80651db1 43 inc ebx80651db2 83c704 add edi,0x480651db5 83fb08 cmp ebx,0x8 /看是否到了最大数(8)80651db8 72cb jb nt!PsRemoveCreateThreadNotifyRoutine+0xa (80651d85)80651dba b87a0000c0 mov eax,0xc000007a80651dbf 5f pop edi80651dc0 5e pop esi80651dc1 5b pop ebx80651dc2 c20400 ret 0x4lkd dd 0x80570f40

12、 /设置了监视函数后80570f40 e316e557 00000000 00000000 00000000.lkd dd 0x80570f40 /清除了监视函数后80570f40 00000000 00000000 00000000 00000000 哈哈,下面是实现代码,代码中实现了进线的的监视,并且实现了远线程的监视: Drivers.c/ / Made By ZwelL#include “ntddk.h”#include “windef.h”#include “define.h”#define SYSNAME “System”#define VERSIONLEN 100const WC

13、HAR devLink = L”?MyEvent”;const WCHAR devName = L”DeviceMyEvent”;UNICODE_STRING devNameUnicd;UNICODE_STRING devLinkUnicd; PVOID gpEventObject = NULL; / 与应用程序通信的 Event 对象ULONG ProcessNameOffset =0;PVOID outBuf255;BOOL g_bMainThread; ULONG g_dwParentId;CHECKLIST CheckList;ULONG BuildNumber; /系统版本号 ULO

14、NG SYSTEMID; /System进程的IDPWCHAR VersionVERSIONLEN;NTSTATUS PsLookupProcessByProcessId(IN ULONG ulProcId, OUT PEPROCESS * pEProcess);ULONG GetProcessNameOffset() PEPROCESS curproc; int i; curproc = PsGetCurrentProcess(); for( i = 0; i Data, valueInfoP-DataLength); ReturnValue = 1; if(!valueInfoP); Ex

15、FreePool(valueInfoP); ZwClose(KeyHandle); return ReturnValue;VOID MyRemoveCraeteThreadNotifyRoutine( IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine ) /PsRemoveCreateThreadNotifyRoutine(ThreadCreateMon); PVOID ptr=NULL; if(BuildNumber=2195) /Windows 2000 Sp4,2195 /低于sp4的我没有调试 ptr=0x80484520; else if(

16、BuildNumber=2600) if(wcscmp(Version,L”Service Pack 1”)=0) /Windows Xp Sp1,2600 ptr=0x8054efc0; else if(wcscmp(Version,L”Service Pack 2”)=0) /Windows Xp Sp2,2600 ptr=0x80561d20; else if(BuildNumber=3790) /Windows 2003 server,3790 ptr=0x80570f40; if(ptr!=NULL) memset(ptr, 0, sizeof(ULONG)*8);VOID Thre

17、adCreateMon (IN HANDLE PId, IN HANDLE TId, IN BOOLEAN bCreate) PEPROCESS EProcess,PEProcess; NTSTATUS status; HANDLE dwParentPID; status = PsLookupProcessByProcessId( (ULONG)PId, &EProcess); if (!NT_SUCCESS( status ) DbgPrint(“PsLookupProcessByProcessId()n”); return ; if ( bCreate ) dwParentPID=PsGe

18、tCurrentProcessId(); status = PsLookupProcessByProcessId( (ULONG)dwParentPID, &PEProcess); if (!NT_SUCCESS( status ) DbgPrint(“PsLookupProcessByProcessId()n”); return ; if(PId=4) /System进程创建的东东我们不管 /在2000下是0,在XP后是4 return; if(g_bMainThread=TRUE) &(g_dwParentId != dwParentPID) &(dwParentPID != PId) )

19、 g_bMainThread=FALSE; sprintf(outBuf, “=“ “Remote Thread :” “=“ “nT:%18s%9d%9d%25s%9dn” “=“ “=n”, (char *)(char *)EProcess+ProcessNameOffset), PId, TId, (char *)(char *)PEProcess+ProcessNameOffset),dwParentPID); if(gpEventObject!=NULL) KeSetEvent(PRKEVENT)gpEventObject, 0, FALSE); if(CheckList.ONLYS

20、HOWREMOTETHREAD) /只显示远线程 return; DbgPrint( “T:%18s%9d%9d%25s%9dn”, (char *)(char *)EProcess+ProcessNameOffset), PId, TId, (char *)(char *)PEProcess+ProcessNameOffset),dwParentPID); sprintf(outBuf, “T:%18s%9d%9d%25s%9dn”, (char *)(char *)EProcess+ProcessNameOffset), PId, TId, (char *)(char *)PEProces

21、s+ProcessNameOffset),dwParentPID); if(gpEventObject!=NULL) KeSetEvent(PRKEVENT)gpEventObject, 0, FALSE); else if(CheckList.SHOWTERMINATETHREAD) DbgPrint( “TERMINATED = THREAD ID: %dn”, TId); sprintf(outBuf,”TERMINATED = THREAD ID: %dn”, TId); if(gpEventObject!=NULL) KeSetEvent(PRKEVENT)gpEventObject

22、, 0, FALSE); VOID ProcessCreateMon ( HANDLE hParentId, HANDLE PId, BOOLEAN bCreate ) PEPROCESS EProcess,PProcess; NTSTATUS status; HANDLE TId; g_dwParentId = hParentId; status = PsLookupProcessByProcessId(ULONG)PId, &EProcess); if (!NT_SUCCESS( status ) DbgPrint(“PsLookupProcessByProcessId()n”); ret

23、urn ; status = PsLookupProcessByProcessId(ULONG)hParentId, &PProcess); if (!NT_SUCCESS( status ) DbgPrint(“PsLookupProcessByProcessId()n”); return ; if ( bCreate ) g_bMainThread = TRUE; DbgPrint( “P:%18s%9d%9d%25s%9dn”, (char *)(char *)EProcess+ProcessNameOffset), PId,PsGetCurrentThreadId(), (char *

24、)(char *)PProcess+ProcessNameOffset), hParentId ); sprintf(outBuf, “P:%18s%9d%9d%25s%9dn”, (char *)(char *)EProcess+ProcessNameOffset), PId,PsGetCurrentThreadId(), (char *)(char *)PProcess+ProcessNameOffset), hParentId ); if(gpEventObject!=NULL) KeSetEvent(PRKEVENT)gpEventObject, 0, FALSE); else if(

25、CheckList.SHOWTERMINATEPROCESS) DbgPrint( “TERMINATED = PROCESS ID: %dn”, PId); sprintf(outBuf,”TERMINATED = PROCESS ID: %dn”, PId); if(gpEventObject!=NULL) KeSetEvent(PRKEVENT)gpEventObject, 0, FALSE); NTSTATUS OnUnload( IN PDRIVER_OBJECT pDriverObject ) NTSTATUS status; DbgPrint(“OnUnload calledn”

26、); if(gpEventObject) ObDereferenceObject(gpEventObject); PsSetCreateProcessNotifyRoutine(ProcessCreateMon, TRUE); MyRemoveCraeteThreadNotifyRoutine(ThreadCreateMon); if(pDriverObject-DeviceObject != NULL) status=IoDeleteSymbolicLink( &devLinkUnicd ); if ( !NT_SUCCESS( status ) ) DbgPrint( “IoDeleteS

27、ymbolicLink() failedn” ); return status; IoDeleteDevice( pDriverObject-DeviceObject ); return STATUS_SUCCESS;NTSTATUS DeviceIoControlDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp ) PIO_STACK_LOCATION irpStack; NTSTATUS status; PVOID inputBuffer; ULONG inputLength; PVOID outputBuffer; ULONG

28、outputLength; OBJECT_HANDLE_INFORMATION objHandleInfo; status = STATUS_SUCCESS; / 取出IOCTL请求代码 irpStack = IoGetCurrentIrpStackLocation(pIrp); switch (irpStack-MajorFunction) case IRP_MJ_CREATE : DbgPrint(“Call IRP_MJ_CREATEn”); break; case IRP_MJ_CLOSE: DbgPrint(“Call IRP_MJ_CLOSEn”); break; case IRP_MJ_DEVICE_CONTROL: DbgPrint(“IRP_MJ_DEVICE_CONTROLn”); inpu

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1