【ACCESS精品源码栏目提醒】:网学会员为需要ACCESS精品源码的朋友们搜集整理了【精品】易语言WindowsAPI - 其它资料相关资料,希望对各位网友有所帮助!
上一期我们讲了勾子基本概念和一些简单的应用这一期我们就来学习用用钩子技术和内存文件映射共享技术来实现远程线程插入 现在网上关于这项编程技术的介绍满天飞因为要想写出一个好的后门该后门至少要达到高隐蔽.防查杀无端口自启动等要求而将木马以 DLL 的形式嵌入到系统进程中基本上可以满足要求而这种远程线程注入技术也成为现代后门和木马程序的一项标准技术指标.如果大家要想更为清晰地掌握该项编程技术强烈推荐细读 jeffery Richter 的.该书个人觉得是每个学习 Windows 黑客编程技术爱好者的圣经.不过由于易语言出来的时间不长网上用易语言具体实现这项编程技术的资料廖廖无几今天我们就来用易语言来实现远程线程插入:大家知道传统的远程线程插入是通过以下几个 API 来完成的OpenProcess - 用于打开要寄生的目标进程。
VirtualAllocEx/VirtualFreeEx - 用于在目标进程中分配/释放内存空间。
WriteProcessMemory - 用于在目标进程中写入要加载的 DLL 名称。
CreateRemoteThread - 远程加载 DLL 的核心内容,用于控制目标进程调用 API 函数。
LoadLibrary - 目标进程通过调用此函数来加载病毒 DLL。
这种方法虽然好但有个缺点:只能在 NT 核心的系统上有效在 98 中无效并且由于易 DLL 的特殊性上面的方法并不奏效虽然可以用写入汇编码来解决问题但也较不方便钩子的出现为我们解决了这个难题通过钩子实现远程线程插入的思路如下:通过安装 windows 消息钩子 WH_GETMESSAGE把待插线程代码所在的 DLL 注入到其他进程里在钩子回调函数中判断当前进程 ID 是否是要插入的进程 ID如果是则创建一个新线程这个新线程函数就是我们要执行的代码所在的函数到这里也就达到了我们的目地.现在就产生了一个新问题由于我们的要执行的代码是放在一个 DLL 里面的创建新线程就需要加载这个 DLL就需要知道 DLL 路径还有判断当前进程 ID 是否是要插入的进程 ID首先也要知道要插入的进程 ID 是多少等等这些信息这就涉及到进程通讯我们可以用文件映射技术来进行进程通讯.文件映射主要是通过以下几个 API 来完成的:CreateFileMapping //创建文件映射对象 成功返回文件映射对象句柄 Dll 命令名:CreateFileMapping 所处动态链接库的文件名:kernel32 在所处动态链接库中的命令名:CreateFileMappingA 返回值类型:整数型 参数的名称为“文件映射句柄”,类型为“整数型”。
注明:指定欲在其中创建映射的一个文 件句柄。
HFFFFFFFF-1表示在内存中创建一个文件映射。
参数的名称为“安全对象”,类型为“SECURITY_ATTRIBUTES”。
注明:SECURITY_ATTRIBUTES 指定一个安全对象,在创建文件映射时使用。
如果为NULL(用 ByVal As Long 传递零), 表示使用默认安全对象。
参数的名称为“打开映射方式”,类型为“整数型”。
注明:下述常数之一:PAGE_READONLY 以只读方式打开映射PAGE_READWRITE:以可读、可写方式打开映射PAGE_WRITECOPY:为 写操作留下备份可组合使用下述一个或多个常数SEC_COMMIT:为文件映射一个小节中的 所有页分配内存SEC_IMAGE:文件是个可执行文件SEC_RESERVE:为没有分配实际内存的 一个小节保留虚拟内存空间 参数的名称为“文件映射最大长度”,类型为“整数型”。
注明:文件映射的最大长度(高32 位)。
参数的名称为“文件映射的最小长度”,类型为“整数型”。
注明:文件映射的最小长度(低 32 位)。
如这个参数和 dwMaximumSizeHigh 都是零,就用磁盘文件的实际长度。
参数的名称为“映射对象名”,类型为“文本型”。
注明:指定文件映射对象的名字。
如存在这个名字的一个映射,函数就会打开它。
用 vbNull 创建一个无名的文件映射。
OpenFileMappingA //打开一个已存在的文件映射对象成功返回打开的文件映射对象句柄 Dll 命令名:OpenFileMapping 公开 所处动态链接库的文件名:kernel32 在所处动态链接库中的命令名:OpenFileMappingA 返回值类型:整数型 类 参数的名称为“常数”, 型 为“整数型”。
注明:带有前缀 FILE_MAP_的一个常数。
参考 MapViewOfFile 函数的 dwDesiredAccess 参数的说明。
参数的名称为“进程继承”,类型为“整数型”。
注明:如这个函数返回的句柄能由当前进程启动的新进程继承,则这个参数为 TRUE。
参数的名称为“文件映射对象名称”,类型为“文本型”。
注明:指定要打开的文件映射对象名称。
MapViewOfFile /将一个文件映射对象映射到当前应用程序的地址空间Dll 命令名:MapViewOfFile 将一个文件映射对象映射到当前应用程序的地址空间。
MapViewOfFileEx 允许我们指定一个基本地址来进行映射文件映射在内存中的起始地址。
零表示出错。
会设置 GetLastError 所处动态链接库的文件名:kernel32 在所处动态链接库中的命令名:MapViewOfFile 返回值类型:整数型 参数的名称为“hFileMappingObject”,类型为“整数型”。
参数的名称为“dwDesiredAccess”,类型为“整数型”。
参数的名称为“dwFileOffsetHigh”,类型为“整数型”。
参数的名称为“dwFileOffsetLow”,类型为“整数型”。
参数的名称为“dwNumberOfBytesToMap”,类型为“整数型”。
通过以上 API 再结合易自带的写到内存指针到字节集指针到文本取字节集数据等命令就可以在进程间读写数据了.内存文件映射技术就介绍到这里在下面的实例中有具体应用我就不多说了.以资源管理器进程explorer.exe为例我们来开始解析程序:程序基本原理:start.exe 先在内存中创建一个映射文件把自己的线程 ID 和查找到的 Explorer 进程 ID以及 HookDL.dll 的路径写到映射文件再安装 HookDL.dll 中的 WH_GETMESSAGE 钩子此时start.exe 进入消息循环直到收到被插进程发来的线程退出消息 WM_QUIT 在钩子回调函数中首先把 start.exe 在内存中创建的映射文件映射到当前进程然后判断当前进程 ID 是否先前 Start.exe 查找到的 Explorer 进程 ID 是的话则再次 LoadLibraryHookDLL.dll并定位到其中 ThreadPro 函数. 此时创建一个新线程线程函数就是 ThreadPro该新线程首先往 Start.exe 消息队列放置一个线程退出消息 WM_QUIT导致其消息循环结束. 此时插入线程完成..可以看到屏幕左上角不断变化的数字..说明我们的代码正在执行.进程列表却没有 Start.exe用进程管理观察可发现 Explorer 进程的确多了个线程且来自HookDLL.dll ..如果希望插入 Explorer 的线程结束按 AltL 即可... :现在我们来看看主程序代码为照顾新手我会逐行分析:.版本 2系统核心支持库.应用接口支持库.程序集 窗口程序集 1.程序集变量 Explorer_PID 整数型.程序集变量 hhook 整数型.程序集变量 FileMapH 整数型.程序集变量 DLLPath 文本型.子程序 __启动窗口_创建完毕.局部变量 nil SECURITY_ATTRIBUTES.局部变量 TheNodeP 整数型.局部变量 ThreadMessage MSG.局部变量 MainPath 字节集.局部变量 ExplorerID 字节集.局部变量 MainThread 字节集.局部变量 Mainhhook 字节集 指定 DLL 路径DLLPath = 取运行目录 + “/HookDLL.dll” 检查插入线程是否已经存在FileMapH = api_OpenFileMapping FILE_MAP_ALL_
ACCESS 0“hacker0058Explorer8Mazi”api_CloseHandle FileMapH.如果真 FileMapH = 0 如果插入线程不存在开始插入 Explorer_PID = 取进程 PID “explorer.exe” 这里指定要插入的进程用到了子程序:取进程 PID.如果真 Explorer_PID = 0 查找 explorer 失败 信息框 “寻找指定进程出错” 0 结束 .如果真结束创建内存映射文件 FileMapH = api_CreateFileMapping -1 nil PAGE_READWRITE 0100“HookExplorer8Mazi”映射到本进程空间TheNodeP = api_MapViewOfFile FileMapH FILE_MAP_ALL_
ACCESS 0 0 0写入共享数据 ExplorerID = 到字节集 Explorer_PID MainThread = 到字节集 当前线程标志符_ MainPath = 到字节集 DLLPath + 0 0 0 字符串是以两字节的 0 为结束标志的所以这里加上 0 0 0 写到内存 ExplorerID + MainThread + MainPath TheNodeP 关闭内存映射 API_UnmapViewOfFile TheNodeP挂 DLL 跳板钩子 hMod = GetMsgHookOn .如果真 hMod = 0 输出调试文本 “挂 DLL 跳板钩子失败” api_CloseHandle FileMapH 关闭映射文件 结束 .如果真结束等待插入 Explorer 的新线程发来消息 api_GetMessage ThreadMessage 0 0 0脱 DLL 跳板钩子 GetMsgHookOff 御载 DLL api_FreeLibrary hMod 关闭映射文件 api_CloseHandle FileMapH.如果真结束结束 .子程序 取进程 PID 整数型 成功返回进程 PID失败返回 0.参数 标志文本 文本型 进程名或窗口名.局部变量 进程 进程信息 0.局部变量 PID 整数型.局部变量 i 整数型PID = 0.如果真 倒找文本 标志文本 “.” 真 ≠ -1 进程 = 取系统进程列表 .计次循环首 取数组成员数 进程 i .如果真 倒找文本 进程 .进程名称 标志文本 真 ≠ -1 PID = 进程 .进程标识符 跳出循环 .如果真结束 .计次循环尾 .如果真结束.如果真 PID = 0 API_取进程标识符 api_FindWindow 0 标志文本 PID.如果真结束返回 PID.现在主程序已经完成了它的任务现在来看看我们执行的核心HookDLL.dll 的代码:.版本 2.全局变量 TheNodeP 整数型.全局变量 hhook 整数型 公开.全局变量 DLL Main.程序集 HOOK 程序集.程序集变量 hMod 整数型.程序集变量 lpProc 子程序指针.程序集 DLL 程序集.版本 2.子程序 _启动子程序 整数型 请在本子程序中放置动态链接库初始化代码复制共享数据 初始化代码只有在程序第一次加载 DLL 时才被执行_临时子程序 返回 0先看看钩子回调函数:.子程序 GetMsgProc 整数型 公开 钩子回调函数.参数 code 整数型.参数 wParam 整数型.参数 lParam 整数型.局部变量 lpThreadA SECURITY_ATTRIBUTES.局部变量 LibraryH 整数型.局部变量 ThreadPt 整数型.局部变量 ThreadID 整数型 截获到消息开始执行下面的自定以代码回调函数复制共享数据 .如果真 TheNodeP ≠ 0 且 pnode.ExplorerID ≠ 0 且 api_GetCurrentProcessId =pnode.ExplorerID 是资源管理器 .如果真 倒找文本 MainPath “.dll” 真 ≠ -1 DLL 路径是否正确 LibraryH = api_LoadLibraryA MainPath 装载动态链接库 .如果真结束 .如果真 LibraryH ≠ 0 ThreadPt = 到整数 api_GetProcAddress LibraryH “ThreadPro” 定位线程函数 .如果真 ThreadPt ≠ 0 api_CreateThread lpThreadA 0 ThreadPt 0 0 ThreadID 创建新线程 .如果真结束 .如果真结束.如果真结束返回 api_CallNextHookEx hhook code wParam lParam 钩子循环再看看子程序:复制共享数据.子程序 复制共享数据 逻辑型.局部变量 i 整数型.局部变量 MainPath 文本型.局部变量 FileMapH 整数型FileMapH = api_OpenFileMapping FILE_MAP_ALL_
ACCESS 0“HookExplorer8Mazi”.如果真 FileMapH = 0 输出调试文本 “打开内存映射文件出错” 返回 假.如果真结束TheNodeP = api_MapViewOfFile FileMapH FILE_MAP_ALL_
ACCESS 0 0 0.如果真 TheNodeP = 0 api_CloseHandle FileMapH 输出调试文本 “映射到本进程空间出错” 返回 假.如果真结束取回共享数据DLL.ExplorerID = 取字节集数据 指针到字节集 TheNodeP 4 3 整数型数据尺寸大小是 4DLL.MainThread = 取字节集数据 指针到字节集 TheNodeP + 4 4 3 4DLL.MainPath = 指针到文本 TheNodeP + 8 8API_UnmapViewOfFile TheNodeP 关闭内存映射api_CloseHandle FileMapH 关闭文件映射对象返回 真钩子回调函数完成现在开始写待插线程代码这里实现写文字到屏幕的功能.版本 2.子程序 ThreadPro 公开 待插线程代码.局部变量 Count 整数型.局部变量 theMsg MSG.局部变量 FileMap 整数型.局部变量 nil SECURITY_ATTRIBUTES.局部变量 HotKeyID 整数型api_PostThreadMessage DLL.MainThread WM_QUIT 0 0FileMap = api_OpenFileMapping FILE_MAP_ALL_
ACCESS 0“hacker0058Explorer8Mazi” 禁止重复运行api_CloseHandle FileMap.如果真 FileMap = 0 FileMap = api_CreateFileMapping -1 nil 4 0 2 “hacker0058Explorer8Mazi” Count = 0 HotKeyID =GlobalAddAtom“hacker0058andALTL” 申请全局原子 RegisterHotKey 0 HotKeyID 1 L 键 注册热键 AltL .判断循环首 api_PeekMessage theMsg 0 0 0 PM_REMOVE = 0 且 取反theMsg.message = WM_HOTKEY 或 theMsg.message = WM_QUIT WriteScreen “ ” + Int2Hex Count + “ The Thread is From ” + 取执行文件名 + “ and AltL to Exit ” Count = Count + 1 延时 500 .判断循环尾 api_CloseHandle FileMap UnregisterHotKey0 HotKeyID 撤销热键 AltLDeleteAtom HotKeyID 释放全局原子.子程序 WriteScreen 写文字到屏幕.参数 s 文本型.局部变量 hScreenDC 整数型hScreenDC = 取设备场景_ 0api_TextOut hScreenDC 0 0 s 取文本长度 s 写文字到屏幕api_ReleaseDC 0 hScreenDC 撤消写文字到屏幕.子程序 Int2Hex 文本型 数值转字符串.参数 v 整数型.局部变量 i 整数型.局部变量 a 文本型.局部变量 b 文本型b = 取十六进制文本 v .计次循环首 8 - 取文本长度 b i a = a + “0”.计次循环尾 返回 “” + a + b.子程序 GetMsgHookOff 逻辑型 公开 关闭全局消息钩子 返回 api_UnhookWindowsHookEx hhook.子程序 GetMsgHookOn 整数型 公开 安装全局消息钩子hMod = api_LoadLibraryA MainPath 加载 DLL返回模块地址lpProc = api_GetProcAddress hMod “GetMsgProc” DLL 中钩子回调函数地址hhook = api_SetWindowsHookExA WH_GETMESSAGE lpProc hMod 0 安装钩子返回 hMod好了整个框架就这样了由于篇幅原因具体的不再细说了.附件里有完整的易程序
源码具体细节大家可以参阅
源码在 Windows xpsp2 易 4.02 中测试通过
上一篇:
【精品】常见文件扩展名和它们的说明
下一篇:
电咖汽车入选2018独角兽企业榜百强 发布“天际”品牌将推高估值