学习笔记之卸载远程目标进程中的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…

qqp2011java_腾讯开放平台中实现QQ登陆的功能

昨天为自己的网站实现了QQ登陆的功能,虽然,没有进行绑定,但是在技术层面上来说,已经了解了一点腾讯开放平台的协议.具体什么是OAUTH,请您GG一下吧...关于腾讯的开放平台,最主要的就是参数一定不能多,能有的要有,不能有的一定不能有.不然提交过去,就会提示什么什么错了.最关键的…

LeetCode之Longest Common Prefix

1、题目 Write a function to find the longest common prefix string amongst an array of strings2、代码实现 package leetcode.chenyu.test;public class LongestCommonPrefix {public static void main(String[] args) {String [] ss {"12345", "3234&qu…

51CTO各位博友大家好!

一直浏览51CTO的技术文章&#xff0c;感谢大家提供这么多的技术文章&#xff0c;今天下决心与大家共同交流。转载于:https://blog.51cto.com/tuidaohu/1414099

java遍历字典_Java中的HashMap遍历和C#的字典遍历

Dictionary list new Dictionary();list.Add("d", 1);//3.0以上版本foreach (var item in list){Console.WriteLine(item.Key item.Value);}//KeyValuePairforeach (KeyValuePair kv in list){Console.WriteLine(kv.Key kv.Value);}//通过键的集合取foreach (stri…

git 使用详解-- tag打标签

Git 的标签管理。跟大多数的 VCS 工具一样&#xff0c;git 也有在历史状态的关键点“贴标签”的功能&#xff0c;一般人们用这个功能来标记发布点&#xff08;例如’v1.0′&#xff09;。列出git中现有标签 要想列出git中现有的所有标签&#xff0c;输入’git tag’命令运行即可…

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;而是想用一种开关的方式开放…

LeetCode之Single Number

1、题目 Given an array of integers, every element appears twice except for one. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? Subscribe to see which companies asked…

C#中的数组

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

java怎么实现同步到微博功能_新浪微博信息站外同步的完整实现

最近遇到一个项目&#xff0c;其中需要将用户的微博信息与自己的网站项目上同步&#xff0c;好在新浪微博是提供了API的&#xff0c;大概查阅了一下&#xff0c;信息同步需要调用的是在关于授权机制说明中&#xff0c;新浪微博的API一共有两种验证机制&#xff0c;分别是&#…

33:计算分数加减表达式的值

33:计算分数加减表达式的值 查看提交统计提问总时间限制: 1000ms内存限制: 65536kB描述编写程序&#xff0c;输入n的值&#xff0c;求 1/1 - 1/2 1/3 - 1/4 1/5 - 1/6 1/7 - 1/8 ... (-1)n-11/n 的值。 输入输入一个正整数n。1 < n < 1000。输出输出一个实数&#x…

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

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

C/C++基本数据类型所占字节数

关于这个主要的问题&#xff0c;非常早曾经就非常清楚了&#xff0c;C标准中并没有详细给出规定那个基本类型应该是多少字节数&#xff0c;并且这个也与机器、OS、编译器有关&#xff0c;比方相同是在32bits的操作系统系&#xff0c;VC的编译器下int类型为占4个字节&#xff1b…

LeetCode之Find the Difference

1、题目 Given two strings s and t which consist of only lowercase letters. String t is generated by random shuffling string s and then add one more letter at a random position. Find the letter that was added in t. Example: Input: s "abcd" t &qu…

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

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