学习笔记之卸载远程目标进程中的DLL模块(转)


学习笔记之卸载远程目标进程中的DLL模块

 (2007-07-23 23:51:02)
302107415361408.gif转载
学习笔记之卸载远程目标进程中的DLL模块2007/7/23
1.首先得把DLL模块中的线程结束
使用CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);创建系统线程的快照然后用Thread32First()和
Thread32Next()遍历系统中所有线程.将遍历到的线程保存到THREADENTRY32结构,然后判断结构中的th32OwnerProcessID成员是否与目标进程ID是否相等从而判断该线程是否为目标进程的.然后用函数OpenThread()打开该线程.但是OpenThread函数在VC6中未被定义.该函数存在于kernel32.dll中.在使用时需要自己定义:第三个参数指定要打开的线程的ID(从THREADENTRY32结构获取)
typedef HANDLE (WINAPI*OPENTHREAD)(DWORD dwFlag, BOOL bInheritHandle, DWORD dwThreadId);
然后用GetProcAddress函数从kernel32.dll中获取OpenThread函数的地址后就可以使用该函数了
OPENTHREAD OpenThread=(OPENTHREAD)GetProcAddress(GetModuleHandle("Kernel32"), "OpenThread");
用OpenThread函数打开线程获取线程句柄
HANDLE hThread=OpenThread(THREAD_ALL_ACCESS,FALSE,Thread.th32ThreadID);
有了线程的句柄后就可以调用NtQueryInformationThread函数获取线程的入口地址
函数NtQueryInformationThread在VC6中也未被定义需要自己定义然后再使用
NtQueryInformationThread函数的第一个参数即为线程句柄,第二个参数为一个枚举值而该枚举类型在VC6中未被定义,同样需要自己定义
NtQueryInformationThread函数的定义
typedef DWORD (CALLBACK* NTQUERYINFORMATIONTHREAD)(HANDLE,DWORD,PVOID,DWORD,PDWORD);
获取NtQueryInformationThread函数的地址:NtQueryInformationThread函数存在于ntdll.dll中,ntdll.dll与kernel32.dll一样,在每个进程开始时,系统都为他们做了一会拷贝所以可以直接用
GetProcAddress函数获取其地址
NTQUERYINFORMATIONTHREAD NtQueryInformationThread=(NTQUERYINFORMATIONTHREAD)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQueryInformationThread");
定义NtQueryInformationThread要用到的枚举类型:
typedef enum _THREAD_INFORMATION_CLASS
{
    ThreadBasicInformation,
    ThreadTimes,
    ThreadPriority,
    ThreadBasePriority,
    ThreadAffinityMask,
    ThreadImpersonationToken,
    ThreadDescriptorTableEntry,
    ThreadEnableAlignmentFaultFixup,
    ThreadEventPair,
    ThreadQuerySetWin32StartAddress,
    ThreadZeroTlsCell,
    ThreadPerformanceCount,
    ThreadAmILastThread,
    ThreadIdealProcessor,
    ThreadPriorityBoost,
    ThreadSetTlsArrayAddress,
    ThreadIsIoPending,
    ThreadHideFromDebugger
}THREAD_INFORMATION_CLASS,*PTHREAD_INFORMATION_CLASS;
在此处NtQueryInformationThread函数将用到此枚举类型的第9个值ThreadQuerySetWin32StartAddress
可以不定义此枚举类型,直接将NtQueryInformationThread函数的第二个参数设为数值9也可以
关于NtQueryInformationThread函数的详细信息了解不多
此处的用法为:
NtQueryInformationThread(hThread,ThreadQuerySetWin32StartAddress,&Start,0x4,NULL);
第一个参数为线程句柄,由OpenThread函数获取,第二个参数为枚举值不多说了
第三个参数为一个DWORD变量的指针,此变量就是用来接收线程入口地址的.第四个参数只能为0x4暂时还不知道是什么意思.第五个参数也是一个DWORD变量指针,但在此处可以设为NULL

判断该线程的入口地址是否在某DLL模块中的方法为:
用NtQueryInformationThread函数获取的线程入口地址 - 该DLL模块句柄(需要先转换为DWORD值)
再用得到的差值与该DLL模块文件的大小相比较如果该差值正好小于或等于DLL模块文件的大小
说明该线程入口地址在该DLL模块之中.
这里所需要模块句柄,对于它的获取稍后再讲.

最后就可以调用TerminateThread(hThread,0);函数结束该线程

用上述方法结束该DLL模块中的所有线程后就可以对该DLL模块进行卸载操作了
2.要卸载DLL模块首先需要获取该DLL模块的句柄
可以通过GetModuleHandle函数获取
也可以通过创建快照CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,processID);的然后用
Module32First和Module32Next遍历模块的方法获取
先说说用GetModuleHandle函数获取.此方法需要用CreateRemoteThread函数在远程进程中创建线程,让该线程调用Kernel32.dll中的GetModuleHandle函数.但是只这样还不行.因为GetModuleHandle函数需要以DLL模块文件名做参数.既然是远程线程调用GetModuleHandle函数.还需要先把DLL模块文件名写入目标进程的地址空间中.最后用CreateRemoteThread函数创建线程执行GetModuleHandle函数来获取DLL句柄
由于是用CreateRemoteThread函数远程执行GetModuleHandle函数.所以无法直接从GetModuleHandle函数得到返回值(也就是DLL句柄).在此必在WaitForSingleObject函数之后用GetExitCodeThread函数来获取线程的退出代码.如果线程正确返回.该退出代码就是线程函数(GetModuleHandle)的返回值然后再用同样的方法用CreateRemoteThread远程创建线程调用FreeLibrary函数来卸载该DLL
(注:此方法本人还没试验成功,理论上是可行的)
现在再来看第二种方法,通过CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,processID)创建进程模块的快照,然后用Module32First和Module32Next遍历进程中所有模块.Module32First和Module32Next函数会将遍历结果保存到MODULEENTRY32结构中.通过查询该结构中的szExePath或szModule成员来判断是否为我们要卸载的目标模块.其中szExePath保存了模块文件的包括全路径的文件名而szModule只包括模块文件名不含路径
3.两个关键的问题解决了,剩下的就是如何卸载DLL模块的问题
要卸载DLL模块需要用到FreeLibrary函数.由于是卸载远程进程中的模块必须让远程进程来执行该函数.
所以将再次用到CreateRemoteThread函数来创建远程线程
以下是实现方法:
首先从Kernel32.dll模块中获取FreeLibrary函数的地址
LPVOID pFunc=(LPTHREAD_START_ROUTINE)GetProcAddress(Pkernel32,"FreeLibrary");//其中Pkernel32是Kernel32.dll的句柄
最后再调用
HANDLE hThread = CreateRemoteThread( process, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc,                (LPVOID)Module->hModule, 0, &dwID/*用来接收新线程的ID*/ );
其中第五个参数就是我们上一步骤中获取的模块句柄
说明一下.由于一个进程可以多次调用LoadLibrary函数来装载一个DLL模块(调用一次LoadLibrary函数系统就会对该DLL模块增加一个引用计数并不是说该进程中会有多个相同的DLL模块)为了防止这种情况.最好用一个循环来进行卸载操作.同样通过用GetExitCodeThread的方法获取FreeLibrary函数的执行情况
直到返回结果为False为止.这样才表示完成了对该模块的卸载

4.另外附上一点关于CreateToolhelp32Snapshot函数的资料
CreateToolhelp32Snapshot函数为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程[THREAD])建立一个快照[snapshot]。

原型:
HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessID);

参数:
dwFlags
[输入]指定快照中包含的系统内容,这个参数能够使用下列数值(变量)中的一个。

     TH32CS_INHERIT - 声明快照句柄是可继承的。
     TH32CS_SNAPALL - 在快照中包含系统中所有的进程和线程。
     TH32CS_SNAPHEAPLIST - 在快照中包含在th32ProcessID中指定的进程的所有的堆。
     TH32CS_SNAPMODULE - 在快照中包含在th32ProcessID中指定的进程的所有的模块。
     TH32CS_SNAPPROCESS - 在快照中包含系统中所有的进程。
     TH32CS_SNAPTHREAD - 在快照中包含系统中所有的线程。

th32ProcessID
[输入]指定将要快照的进程ID。如果该参数为0表示快照当前进程。该参数只有在设置了TH32CS_SNAPHEAPLIST或TH32CS_SNAPMOUDLE后才有效,在其他情况下该参数被忽略,所有的进程都会被快照。

返回值:
调用成功,返回快照的句柄,调用失败,返回INVAID_HANDLE_VALUE。

5.新问题
在该次学习中所发现的新问题.某些程序在开始时总是要载入很多相关的DLL模块
比如QQGame.exe启动时就载入了多达109个模块.有些是常见的如Ntdll.dll kernel32.dll Gdi32.dll ole32.dll等等.也有一些QQGame.exe自己的DLL模块这些模块完成QQGAME.EXE的一些特殊功能.但是QQGAME.EXE启动后并没有马上就调用某些模块中的东西.比如QQGAME.EXE中的一个HelpDll.dll模块.我们就可以例用这样的模块来启动我们的病毒.我们可将该DLL模块文件拷贝到一隐蔽的目录下.然后自己从新写一个新的DLL模块.该模块应具备的功能.1首先要能载入我们拷贝的真正的DLL模块.2载入或者启动我们的病毒程序.3完成这两样工作后马上进行自我卸载. 最后将写好的DLL文件放到先前HelpDll.dll的目录下复盖真正的DLL文件.这样我们的病毒就会随QQGame.exe的启动而启动了
上面的例子本人测试成功.不知道其它的进程或模块会不会支持这样的方式

来源: <http://blog.sina.com.cn/s/blog_56ea069101000b3k.html>
 


来自为知笔记(Wiz)


转载于:https://www.cnblogs.com/hungryvampire/p/4469918.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/291348.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Wow,一个免费、不怕打的评论插件!

快速给网站添加评论功能大家好&#xff0c;我是鱼皮&#xff0c;前段时间我自己做的网站不是被 DDOS 攻击了么&#xff1f;然后我就即时地给大家分享了一下我是怎么临时 “化解” 这次 DDOS 攻击的。结果我今天一看&#xff0c;好家伙&#xff0c;这个视频竟然都已经 120 w 播放…

MSSQLSERVER启动不了,报SQL Server 无法生成 FRunCM 线程

为什么80%的码农都做不了架构师&#xff1f;>>> 在启动MSSQLSERVER服务时&#xff0c;提示启动不了&#xff0c;在事件查看器中发现报错&#xff1a;SQL Server 无法生成 FRunCM 线程 网上搜了一下说是&#xff1a;MSSQLSERVER的协议中VIA协议被启用了&#xff0c;…

hdu 2648 Shopping

原题链接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid2648 纯暴力的方法T_T。。。 如下: 1 #include<cstdio>2 #include<cstdlib>3 #include<string>4 #include<iostream>5 #include<algorithm>6 typedef char State[35];7 char *ta…

Windows导出所有计划任务方法

windows计划任务的命令为&#xff1a;schtasksSCHTASKS /parameter [arguments]描述:允许管理员创建、删除、查询、更改、运行和中止本地或远程系统上的计划任务。参数列表:/Create 创建新计划任务。/Delete 删除计划任务。/Query 显示所有计划任务。…

C# 使用多个异步方法

在一个异步方法中&#xff0c;可以调用一个或多个异步方法。如何编写代码&#xff0c;取决于一个异步方法的结果是否依靠于另一个异步方法。01 按顺序调用异步方法使用 await 关键字可以调用每个异步方法。在有些情况下&#xff0c;如果一个异步方法依赖另一个异步方法的结果&a…

Nova虚拟机启动提示libvirtError

OpenStack自动化安装基本折腾完毕&#xff0c;装一次大概也就10分钟&#xff0c;但是装完后今天我的虚拟机起不来&#xff0c;经过查找log发 现如下图提示&#xff1a; 已经到这里&#xff0c;说明已经过了nova-sheduler那一关&#xff0c;跟踪一下代码&#xff0c;也正是在调用…

ASP.NET Core使用功能开关控制路由访问

前言在前面的文章&#xff0c;我们介绍了使用Middleware有条件地允许访问路由&#xff08;《ASP.NET Core使用Middleware有条件地允许访问路由》&#xff09;。而对于一些试验性的功能&#xff0c;我们并不希望用密码去控制是否允许访问&#xff0c;而是想用一种开关的方式开放…

C#中的数组

欢迎您成为我的读者&#xff0c;希望这篇文章能给你一些帮助。前言前面的文章和大家一起看了C#中的异常&#xff0c;今天一起学习下C#中最基本的数据结构&#xff0c;数组的用法。数组实际上是由一个变量名称表示的一组同类型的数据元素。每个元素通过变量名称和一个或多个方括…

如何打卡后缀为3ds的文件

打开.3DS文件 3DS文件怎么打开&#xff1f; 用它吧&#xff1a;a3dsviewer&#xff0c;顾名思义&#xff0c;一个3D文件浏览工具&#xff0c;为用户提供一个快速和简单的3DS文件浏览器很容易。 这里是一些主要特点的“a3dsviewer”&#xff1a; 将3DS文件的POVRay格式。 输出的…

ASP.NET Core使用功能开关控制路由访问(续)

前言在前面的文章&#xff0c;我们介绍了使用功能开关控制路由访问。但其实我们使用了2个条件做的判断&#xff1a;var isDebugEndpoint context.Request.Path.Value.Contains("/test"); var debugEndpoint await _featureManager.IsEnabledAsync("ForbiddenD…

如何使用CDR智能填充工具

使用智能填充工具可以为任意的闭合区域填充颜色并设置轮廓。与其他填充工具不同&#xff0c;智能填充工具仅填充对象&#xff0c;它检测到区域的边缘并创建一个闭合路径&#xff0c;因此可以填充区域。例如&#xff0c;智能填充工具可以检测多个对象相交产生的闭合区域&#xf…

java对象引用出错_“Java有值传递和引用传递”为什么错了?

前言初学Java的时候&#xff0c;老师在课堂上说“Java有值传递和引用传递”&#xff0c;但网上“Java只有值传递”的呼声很高。本人在查找资料的过程中&#xff0c;在这两个说法之间反复横跳。经过本人的整理后&#xff0c;其实还真的是Java只有值传递。什么是值传递&#xff1…

程序员生存之道-教你如何在丛林中捕获食物

文章目录 &#x1f4a5; 序言&#x1f423; 躺&#x1f95d; 从零到一还是从零到100&#xff1f;&#x1f344; 螺丝钉文化&#x1f354; 价值分析&#x1f353; 长期主义者&#xff1f;&#x1f96c; 何为顺其自然&#xff1f;&#x1f308; 总结 &#x1f4a5; 序言 嗨&#…

微软发文庆祝 .NET 诞生 20 周年纪念日!

技术编辑&#xff1a;MissD丨发自 思否编辑部公众号&#xff1a;SegmentFault刚刚过去的“情人节”里&#xff0c;.NET 团队为庆祝 .NET 社区诞生 20 周年而举办了一场盛大的活动。没错&#xff01;.NET 于 2002 年 2 月 13 日与 Visual-Studio 一起推出&#xff0c;本月终于迎…

根据文件扩展名得到文件对应该类型Icon方法

2019独角兽企业重金招聘Python工程师标准>>> 根据文件扩展名得到文件对应该类型Icon方法 package com.fleety.util; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.…

Asp-Net-Core开发笔记:在docker部署时遇到一个小坑

哦吼之前刚说了尝试了使用docker来部署AspNetCore应用&#xff08;Asp.Net Core部署&#xff1a;早知道&#xff0c;还是docker!以及一点碎碎念&#xff09;&#xff0c;结果这才刚上班就遇到问题了 …我这项目用的数据库是Oracle&#xff0c;之前直接运行没啥问题&#xff0c;…

lasso特征选择python_转:结合Scikit-learn介绍几种常用的特征选择方法-2

4.2 平均精确率减少 Mean decrease accuracy另一种常用的特征选择方法就是直接度量每个特征对模型精确率的影响。主要思路是打乱每个特征的特征值顺序&#xff0c;并且度量顺序变动对模型的精确率的影响。很明显&#xff0c;对于不重要的变量来说&#xff0c;打乱顺序对模型的精…

Mac Generating Pods project Abort trap: 6

为什么80%的码农都做不了架构师&#xff1f;>>> 为项目添加cocoapods如果产生此种错误时,主要有以下几点原因: 1,cocoapods版本过低: 打开终端在终端输入:pod --version,目前最新版本是1.2.0(2017年3月),如果发现版本过低,则可以在终端输入以下命令:gem install co…

svn 服务器搭建

2019独角兽企业重金招聘Python工程师标准>>> Svn搭建 1. Linux 搭建 YUM 服务器 [rootlocalhost conf]# yum install -y subversion 2.验证安装版本&#xff1a; [rootlocalhost conf]# svnserve –version 3.创建SVN 版本库 [rootlocalhost conf]# mkdir /v…

C# 使用 ValueTasks

C# 7 带有更灵活的 await 关键字&#xff1b;它现在可以等待任何提供 GetAwaiter 方法的对象。一种可用于等待的新类型是 ValueTask。与 Task 类相反&#xff0c;ValueTask 是一个结构。这具有性能优势&#xff0c;因为 ValueTask 在堆上没有对象。与异步方法调用相比&#xff…