说说windows内核中为什么要隐藏线程?(附源码)
发布时间:2020-12-14 02:38:18 所属栏目:Windows 来源:网络整理
导读:一、论: 接着上一篇来谈谈,进程都能隐藏,单独隐藏进程中的某一个线程干啥? 二、需求: 需求源动力,就是有需求,除了正儿八经热爱喜欢专研的朋友,无利无名、无食而学日不思,真的让人很尊敬。 三、打个比方: 当你想要去实现隐藏线程的时候你有可能在干
一、论:
接着上一篇来谈谈,进程都能隐藏,单独隐藏进程中的某一个线程干啥? 二、需求: 需求源动力,就是有需求,除了正儿八经热爱喜欢专研的朋友,无利无名、无食而学日不思,真的让人很尊敬。 三、打个比方: 当你想要去实现隐藏线程的时候你有可能在干什么?做一个工具?或者说是学习?通过隐藏线程可以更深入理解windows内部原理?进程与线程之间的关系?一个正常进程里面包含恶意线程?这是一个很棒的学习方式。也许你会用它来做一些事情,以前想写过一个类似于ARK的工具,才有了学习的需求及动力。但是还没有实际的环境去应用隐藏线程,没有需求,但还是把代码认真的写出来,分享一些知识,知识在于分享。 四、还是那些结构体: 有时候我在想,不用winAPI我能做什么事?也许我还能做很多的事情,因为有足够的结构体我就不慌、但是,如果没有了结构体我能做什么事情?这个还真不好说,其实相对于windows我更为喜欢Linux那种自由。 介绍主人公_ETHREAD与_KTHREAD: 1、_EPROCESS.ThreadListHead ---> _ETHREAD 2、_KPROCESS.ThreadListHead ---> _KTHREAD 线程属于进程,一个进程由多个线程、那么同一个进程的多个线程使用的是相同的进程空间,线程也叫做轻量级进程。线程挂靠技术,也可以本线程使用其他进程的空间。 windows下线程是最小执行单位,每个进程至少会有一个主线程去响应执行。同样_ETHREAD属于执行体层,内嵌偏移0是_KTHREAD(微内核层),异曲同工之妙,windows的管理不得不说很优秀,可以用艺术来形容。 _KPROCESS中会有一个成员叫做ThreadListHead字段是进程所有线程的链表。指向的位置是_KTHREAD.ThreadListEntry,这个地方当时异或了好久,为啥?为啥这个链表指向的就是这个结构体这个位置,其实我现在也很纠结. _KPROCESS.ThreadListHead指向 -----> _KTHREAD.ThreadListEntry 就是这个情况.内核就是通过这个来遍历属于某一个进程空间的所有线程。详细资料还是参考: https://bbs.pediy.com/thread-223858.htm 个人感觉翻译过来的文章质量五星好评。 五、贴上源码 #include "HideThreadHeader.h" VOID UnLoad(PDRIVER_OBJECT pDriverObj) { UNICODE_STRING DeleteSymbolicLinkName; RtlInitUnicodeString(&DeleteSymbolicLinkName,L"DosDevicesSymbolicLinkName"); IoDeleteSymbolicLink(&DeleteSymbolicLinkName); IoDeleteDevice(pDriverObj->DeviceObject); KdPrint(("UnLoad Sucess")); } NTSTATUS DefaultFun(DEVICE_OBJECT* pDeviceObj,IRP* irp) { UNREFERENCED_PARAMETER(pDeviceObj); irp->IoStatus.Information = 0; irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(irp,IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS onCreate(DEVICE_OBJECT* pDeviceObj,IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS onClose(DEVICE_OBJECT* pDeviceObj,IO_NO_INCREMENT); return STATUS_SUCCESS; } // 遍历属于某个进程所有线程 通过断链实现隐藏线程 VOID HideThreadListLink() { CLIENT_ID* ThreadId = NULL; PEPROCESS pkProcess = NULL; PKTHREAD pkThread = NULL; PETHREAD pEthread = NULL; LIST_ENTRY* pEthreadNext = NULL; LIST_ENTRY* pEthreadCurrent = NULL; pkProcess = PsGetCurrentProcess(); // 获取_KPROCESS->ThreadListHead(_LIST_ENTRY) pEthreadCurrent = (LIST_ENTRY *)((ULONG_PTR)pkProcess + 0x02c); /* 注: 1. _KPROCESS.ThreadListHead->Flink指向的是一个_KTHREAD.ThreadListEntry 2. _KTHREAD.ThreadListEntry - 偏移ThreadListEntry获取到KTHREAD地址,其实也就是ETHREAD地址. */ KdPrint(("ThreadListHead.Flink = %pn",pEthreadCurrent->Flink)); KdPrint(("ThreadListHead.blink = %pn",pEthreadCurrent->Blink)); // 这个 (PETHREAD)(PEPROCESS + 0x2c) pEthreadNext = pEthreadCurrent->Flink; DbgBreakPoint(); while (pEthreadCurrent != pEthreadNext) { pkThread = (PKTHREAD)((ULONG_PTR)pEthreadNext - 0x1e0); // pKthread->Teb 偏移 0x88 // KdPrint(("pKThread->Teb = %p,%s n",(ULONG_PTR)pkThread + 0x88,(((ULONG_PTR)pKThread + 0x88) == NULL || pkThread->Teb > 0x80000000 ? "System Thread" : "Non System Thread"))); // 转换成EPROCESS pEthread = (PETHREAD)pkThread; DbgBreakPoint(); // pEthread->Cid 偏移0x22c ThreadId = (CLIENT_ID *)((ULONG_PTR)pEthread + 0x22c); KdPrint(("ThreadId = %d,ProcessId = %dnn",ThreadId->UniqueThread,ThreadId->UniqueProcess)); // 这个地方也可以使用断链 伪代码 if (ThreadId->UniqueThread == "隐藏的线程id") { // 与进程隐藏断链方式一样 } pEthreadNext = pEthreadNext->Flink; } } // 驱动对象入口点 NTSTATUS DriverEntry(DRIVER_OBJECT* pDriverObj,IRP* irp) { UNREFERENCED_PARAMETER(irp); DbgBreakPoint(); for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; ++i) { pDriverObj->MajorFunction[i] = DefaultFun; } pDriverObj->DriverUnload = UnLoad; pDriverObj->MajorFunction[IRP_MJ_CREATE] = onCreate; pDriverObj->MajorFunction[IRP_MJ_CLOSE] = onClose; UNICODE_STRING DeviceName; UNICODE_STRING SymbolicLinkName; DEVICE_OBJECT* DeviceObj; NTSTATUS nStatus = STATUS_SUCCESS; RtlInitUnicodeString(&DeviceName,L"DeviceDeviceName"); RtlInitUnicodeString(&SymbolicLinkName,L"DosDevicesSymbolicLinkName"); nStatus = IoCreateDevice(pDriverObj,&DeviceName,FILE_DEVICE_UNKNOWN,&DeviceObj); if (!NT_SUCCESS(nStatus)) return nStatus; nStatus = IoCreateSymbolicLink(&SymbolicLinkName,&DeviceName); if (!NT_SUCCESS(nStatus)) return nStatus; DbgBreakPoint(); // 没有使用控制码等处理 伪代码进行测试 HideThreadListLink(); return STATUS_SUCCESS; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- 备份Windows上的SCP到Linux
- Windows上的.ctags文件在哪里?
- 存储 – 为什么robocopy导致我的Windows 2012服务器昨晚挂起
- 在程序中修改IP win7 winXP(参考1)
- 检查文件是否为只读,并在Windows批处理文件中进行更改
- Windows aero peek API
- 如果结构定义了uint16_t字和uint8_t字节,则数组的大小加倍
- 需要帮助在Windows上的Qt Creator中链接静态OpenCV库
- 单元测试 – WP7:UnitTest Framework入门:XamlParseExcep
- Windows上的TortoiseSVN – 结帐错误“…在目录中不是有效的
推荐文章
站长推荐
- windows-server-2008 – 将组策略应用于远程桌面
- exchange-2007 – 重新启动时禁用Server 2008服务
- QDialog不是这样的文件或目录 – Qt Windows
- windows – 具有基于标头的路由的HTTP负载均衡器
- 在Windows 10上使用Nuitka将Python 3.6脚本编译为
- iis – 从部署中排除文件夹并停止其他文件删除
- Windows上的SQLite数据库是否有MySQLAdmin或SQL
- 我应该开始用ErgoEmacs学习emacs吗?
- azure – 尝试通过Microsoft Virtual Machine Co
- Microsoft Web API帮助页面 – 如何为参数创建注
热点阅读