手把手教会你白加黑无敌免杀(附工具和源码)

admin 2026-05-27 05:04:11 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详细介绍了白加黑免杀技术中DLL开发的核心知识,包括VS项目目录结构解析、DLLMain入口点函数各参数含义及四种调用场景(进程/线程加载卸载)的执行逻辑,并针对开发过程中常见的死锁、线程挂接等问题提供解决方案。 综合评分: 75 文章分类: 免杀,安全开发,红队


cover_image

手把手教会你白加黑无敌免杀(附工具和源码)

原创

星夜AI安全 星夜AI安全

星夜AI安全

2026年1月3日 08:14 吉林

在小说阅读器读本章

去阅读

📌各位可以将公众号设为星标⭐

📌这样就不会错过每期的推荐内容啦~

📌这对我真的很重要!

📌1. 本平台分享的安全知识和工具信息源于公开资料及专业交流,仅供个人学习提升安全意识、了解防护手段,禁止用于任何违法活动,否则使用者自行承担法律后果。

📌2. 所分享内容及工具虽具普遍性,但因场景、版本、系统等因素,无法保证完全适用,使用者要自行承担知识运用不当、工具使用故障带来的损失。

📌3. 使用者在学习操作过程中务必遵守法规道德,面对有风险环节需谨慎预估后果、做好防护,若未谨慎操作引发信息泄露、设备损坏等不良后果,责任自负。

前言

最近看到微步的一篇文章,里面提到“白文件+黑 DLL”组合的利用思路,引发了我的兴趣。起初我以为实现并不复杂,但真正动手尝试后,才发现过程中有不少坑点:

  • 关于 DLL 编写的资料零散且不够系统;
  • 在 DllMain 中直接执行代码时容易出现死锁;
  • 如何正确挂接主线程逻辑也需要反复调试。

经过一番研究,我逐步解决了这些问题,并成功完成了实验。在过程中也发现,虽然“白+黑”方式在设计上较为简单高效,但要想稳定运行仍然需要不少细节打磨。

接下来的文章将会从 DLL 开发基础 开始讲起,结合实践经验,介绍:

  • 如何着手开发和调试 DLL;
  • 在不同入口点执行逻辑的差异;
  • DllMain 与导出函数中加载逻辑的不同方式;
  • 以及常见问题与对应的解决思路。

希望这份总结能为刚接触 DLL 技术的朋友提供一些思路,避免在入门阶段踩过多的坑。

一、dll 开发前置知识

动态链接库(Dynamic Link Library,简称 DLL)是 Windows 操作系统中的一种共享组件文件,它内部包含了可供多个程序调用的函数、数据和资源。与可执行文件(EXE)一样,DLL 也是一种 PE(Portable Executable)文件格式

当应用程序需要使用某个功能时,并不需要一开始就把所有代码加载进内存,而是会在需要时才加载对应的 DLL,并获取其中目标函数的入口地址,再进行调用。通过这种方式,程序可以更高效地运行,同时也便于多个程序共享相同的功能模块,减少重复开发和资源占用。

1. VS目录结构

首先我们打开vs2022新建一个动态链接库:

可以看到有如下目录结构,可以看到有framework.h、pch.h、dllmain.cpp、pch.cpp四个文件:

(1)framework.h 文件

framework.h 文件用于包含项目中需要使用的头文件,可以看到已经默认包含了windows头文件:

(2)pch.h 文件

pch.h 是预编译标头文件,dll的导出函数应该在此处定义:

(3)dllmain.cpp 文件

dllmain.cpp 文件包含程序的入口点,在 dllmain.cpp 中实现的在 pch.h 中定义函数,当然也可以在其他 cpp 文件中实现,如 pch.cpp 等。

2. 入口函数(DllMain)

DllMain是动态链接库的可选入口点。当系统启动或终止进程或线程时,它会使用进程的第一个线程为每个加载的 dll 调用入口点函数。当 dll 使用 LoadLibrary(Ex) 加载和使用 FreeLibrary 函数卸载 dll 时,系统还会调用该函数的入口点函数。

(1)DllMain 示例

DllMain函数结构如下:

运行

/*
* hModule:DLL模块句柄
* ul_reason_for_call:调用函数的原因
* lpReserved:保留参数
*/
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
      case DLL_PROCESS_ATTACH: // 当DLL被进程加载时执行,每个新进程只初始化一次。
      case DLL_THREAD_ATTACH: // 当线程被创建时调用
      case DLL_THREAD_DETACH: // 当线程结束时执行
      case DLL_PROCESS_DETACH: // 当DLL被进程卸载时执行
            if (lpvReserved != nullptr)
            {
                break; // lpvReserved为非空时,表示进程被终止,不做任何清理
            }
            // 执行必要的清理
          break;
    }
    return TRUE; // DLL_PROCESS_ATTACH成功
}
(2)DLL_PROCESS_ATTACH

当一个 dll 文件被映射到进程的地址空间时,系统调用该 dll 的 DllMain 函数,传递的 fdwReason 参数为DLL_PROCESS_ATTACH,该值只会被传递一次。

一个程序要调用DLL里的函数,首先要先把DLL文件映射到进程的地址空间。要把一个 dll 文件映射到进程的地址空间,有两种方法:静态链接(.lib)和使用 LoadLibrary(Ex) 方法加载的动态链接。

(3)DLL_PROCESS_DETACH

当 dll 被从进程的地址空间解除映射时调用。

以下情况 dll 会被从进程的地址空间中解除映射:

  • 调用 FreeLibrary
  • 进程结束
  • 传入 DLL_PROCESS_ATTACH 的 DllMain 返回 FALSE

如果调用了 TerminateProcess() 终结进程,则不会传入 DLL_PROCESS_DETACH 做任何清理工作。

(4)DLL_THREAD_ATTACH

当进程创建一线程时调用,与 DLL_PROCESS_ATTACH 不同,该值可被多次调用。

当进程创建一线程时,系统查看当前映射到进程地址空间中的所有 dll 文件映像,并用值 DLL_THREAD_ATTACH 调用 dll 的 DllMain 函数。新创建的线程负责执行这次的 dll 的 DllMain 函数,只有当所有的 dll 都处理完这一通知后,系统才允许进程开始执行它的线程函数。

(5)DLL_THREAD_DETACH

当线程调用了 ExitThread 来结束线程(线程函数返回)时调用。如果调用了 TerminateThread() 终结线程,则不会传入 DLL_THREAD_DETACH 做任何清理工作。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:星夜AI安全 星夜AI安全 星夜AI安全《手把手教会你白加黑无敌免杀(附工具和源码)》

评论:0   参与:  0