文章目录

  • 环境搭建
    • 项目地址
    • 项目介绍
    • 项目编译
    • 项目集成
  • 项目使用
    • 进程交互
      • 根据进程名枚举所有进程ID
      • 根据进程ID或进程名枚举进程信息
      • 枚举所有进程
      • 附加一个进程(打开进程),并获取相关信息
      • 启动并附加进程
    • 进程模块管理
    • 进程内存管理
    • 进程线程管理
    • JIT汇编
    • 远程代码执行
    • 内存搜索匹配
    • 远程函数调用
    • 系统调用 只适用于x64
    • dll隐藏注入
  • 总结

环境搭建

项目地址

https://github.com/DarthTon/Blackbone

项目介绍

作为Windows开发人员,经常遇到枚举进程、枚举模块、读写进程内存的操作;Windows安全开发人员更是会涉及注入、hook、操作PE文件、编写驱动。每次都要翻各种资料制造轮子,那么有没有好的开源库解决这个问题呢,目前知道的就Blackbone了,而且它的代码写的很好,完全可以作为教科书来用。

网上对于各种类型的封装库百分之99都是copy的这个项目,并且看雪很多大佬的项目都引用了其中的代码。由此可见,这个项目的重要性和牛逼程度就不言而喻了。

库内容包含

Process interaction(进程交互)操作PEB32/PEB64通过WOW64 barrier管理进程
Process Memory(进程内存)分配和释放虚拟内存改变内存保护属性读写虚拟内存
Process modules(进程模块)枚举所有进程加载的模块 (32/64 bit)获得导出函数地址获得主模块从模块列表中去除模块信息注入、卸载模块(支持 pure IL images)在WOW64进程中注入64位模块操作PE
Threads(线程)枚举线程创建和关闭线程获得线程退出码获得主线程管理 TEB32/TEB64join线程(等待线程退出)暂停、恢复线程设置、清除硬件断点
Pattern search特征码匹配(支持本进程和其他进程)
Remote code execution在远程进程中执行函数组装自己的代码并远程执行(shellcode注入)支持各种调用方式: cdecl/stdcall/thiscall/fastcall支持各种参数类型支持FPU支持在新线程或已经存在的线程中执行shellcode
Remote hooking通过软硬断点,在远程进程中hook函数Hook functions upon return(通过return挂钩函数)
Manual map features隐藏注入,支持x86和x64,注入任意未保护的进程,支持导入表和延迟导入等等特性,不一一列举了。
Driver features分配、释放、保护内存读写用户层、驱动层内存对于WOW64进程,禁用DEP修改进程保护标记修改句柄访问权限操作进程内存(如:将目标进程map到本进程等)隐藏已分配用户模式内存用户模式dll注入;手动mapping(手动加载模块)手动加载驱动

项目编译

需要安装下面几个组件

  1. sdk、wdk版本要相同10.0.17763.0
  2. cor.h文件及相关的mscoree.lib库找不到编译错误,需要安装.NET桌面开发
  3. VC++ 2017 Libs for Spectre (x86 and x64)
  4. Visual C++ ATL (x86/x64) with Spectre Mitigations

我用VS2017编译会报一个引用已删除函数的错误,找不到解决方案,就直接找人帮我编译了一份。

据说是最新版本只支持VS2019,如果要使用VS2017,需要选择其他分支代码。

项目集成

新建一个空项目

然后在项目目录下新建一个include文件夹

把src目录下的三个文件夹复制到include文件夹

上面三个文件夹的在引用头文件的时候需要用到,build里面存放的是已经编译好的lib库

接着包含lib库和头文件

#include <iostream>
#include "../include/BlackBone/Config.h"
#include "../include/BlackBone/Process/Process.h"
#include "../include/BlackBone/Process/MultPtr.hpp"
#include "../include/BlackBone/Process/RPC/RemoteFunction.hpp"
#include "../include/BlackBone/PE/PEImage.h"
#include "../include/BlackBone/Misc/Utils.h"
#include "../include/BlackBone/Misc/DynImport.h"
#include "../include/BlackBone/Syscalls/Syscall.h"
#include "../include/BlackBone/Patterns/PatternSearch.h"
#include "../include/BlackBone/Asm/LDasm.h"
#include "../include/BlackBone/localHook/VTableHook.hpp"
#include "../include/BlackBone/DriverControl/DriverControl.h"#ifdef _DEBUG
#pragma comment(lib, "..\\include\\build\\Win32\\Debug\\BlackBone.lib")
#else
#pragma comment(lib, "..\\include\\build\\Win32\\Release\\BlackBone.lib")
#endif

使用命名空间

using namespace blackbone;

随意调用一个函数,即可编译通过。编译通过说明集成成功。

接着需要把build生成的三个文件拷贝到项目目录下,否则会报下面的错误

项目使用

下面讲解每一个模块的代码功能使用。

进程交互

根据进程名枚举所有进程ID

auto pids = Process::EnumByName(L"explorer.exe");

根据进程ID或进程名枚举进程信息

 auto procInfo = Process::EnumByNameOrPID(4596, L"");for (auto info : procInfo.result()){wcout << info.imageName << info.pid << info.threads.size();}

枚举所有进程

 auto all = Process::EnumByNameOrPID(0, L"");for (auto info : all.result()){wcout << info.imageName << "\t" << info.pid << info.threads.size() << endl;}

附加一个进程(打开进程),并获取相关信息

 Process process;vector<DWORD> vecPid = Process::EnumByName(L"QQ.exe");//附加一个进程if (!vecPid.empty()&&NT_SUCCESS(process.Attach(vecPid.front()))){//ProcessCore类ProcessCore& processCore = process.core();//进程WOW64信息Wow64Barrier barrier = process.barrier();//获取进程ID和进程句柄DWORD dwPid = processCore.pid();HANDLE hProcess = processCore.handle();//获取进程PEBPEB_T peb = {};ptr_t ptrPEB = processCore.peb(&peb);//获取进程的所有句柄for (HandleInfo handleInfo:process.EnumHandles().result()){wcout << handleInfo.name << handleInfo.handle << handleInfo.typeName << endl;}

启动并附加进程

 //启动并附加进程Process process;process.CreateAndAttach(L"D:\\InjectTool.exe", true);{//恢复进程process.Resume();//延迟100毫秒std::this_thread::sleep_for(std::chrono::milliseconds(100));}

进程模块管理

 //进程模块管理Process process;if (NT_SUCCESS(process.Attach(L"WeChat.exe"))){//模块管理ProcessModules& proModules = process.modules();//获取所有模块 包括x86跟x64模块auto mapModule = proModules.GetAllModules();//获取主模块ModuleDataPtr mainModule = proModules.GetMainModule();//主模块基地址module_t baseAddress = mainModule->baseAddress;//获取导出函数地址call_result_t<exportData> exportFunAddr = proModules.GetExport(L"kernel32.dll", "LoadLibraryW");if (exportFunAddr.success()){cout << "LoadLibraryW" << exportFunAddr->procAddress << endl;}//模块断链proModules.Unlink(mainModule);auto mapModule2 = proModules.GetAllModules();//注入模块call_result_t<ModuleDataPtr> ptr= proModules.Inject(L"E:\\Dll1.dll");//卸载模块proModules.Unload(ptr);}

里面有一个很牛逼的功能,模块断链,实测可行~

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oc7z6bW0-1642037164410)(Blackbone黑客库的使用.assets/image-20220112125146182.png)]

进程内存管理

 Process process;if (NT_SUCCESS(process.Attach(L"QQ.exe"))){//操作内存类ProcessMemory& memory = process.memory();//主模块ModuleDataPtr  mainModoulePtr = process.modules().GetMainModule();//PE头信息IMAGE_DOS_HEADER dosHeader = {};//读取内存 模块的开始信息是PE头信息//第一种方法memory.Read(mainModoulePtr->baseAddress, dosHeader);//第二种方法memory.Read(mainModoulePtr->baseAddress, sizeof(dosHeader),&dosHeader);//第三种方法call_result_t<IMAGE_DOS_HEADER> dosHeaderResult = memory.Read<IMAGE_DOS_HEADER>(mainModoulePtr->baseAddress);//改变内存读写属性if (NT_SUCCESS(memory.Protect(mainModoulePtr->baseAddress,sizeof(dosHeader), PAGE_READWRITE))){//写内存第一种方法memory.Write(mainModoulePtr->baseAddress, dosHeader);//写内存第二种方法memory.Write(mainModoulePtr->baseAddress, sizeof(dosHeader),&dosHeader);}//分配内存call_result_t<MemBlock> memBlockResult = memory.Allocate(0x1000, PAGE_READWRITE);if (memBlockResult.success()){//写内存memBlockResult->Write(0x10, 12.0);//读内存memBlockResult->Read<double>(0x10, 0.0);}//枚举所有有效内存区域vector<MEMORY_BASIC_INFORMATION64> region = memory.EnumRegions();}

进程线程管理

 Process process;if (NT_SUCCESS(process.Attach(L"QQ.exe"))){//枚举所有线程vector<ThreadPtr> vecTheadPtr = process.threads().getAll();//获取主线程ThreadPtr mainThread = process.threads().getMain();//根据线程ID获取线程信息ThreadPtr threadPtr = process.threads().get(mainThread->id());//获取线程上下文CONTEXT_T ctx = {};if (threadPtr->GetContext(ctx, CONTEXT_FLOATING_POINT)){//这里设置Dr寄存器就可以清除硬件断点//......//设置线程上下文threadPtr->SetContext(ctx);}//等待线程退出threadPtr->Join(100);}

JIT汇编

AsmHelper32 asmPtr = AsmFactory::GetAssembler();IAsmHelper& a = *asmPtr;//生成函数代码a->GenPrologue();a->add(a->zcx, a->zdx);a->mov(a->zax, a->zdx);a.GenEpilogue();auto func = reinterpret_cast<uintptr_t(__fastcall*)(uintptr_t, uintptr_t)>(a->make());uintptr_t r = func(10, 5);

远程代码执行

 Process process;if (NT_SUCCESS(process.Attach(L"QQ.exe"))){//远程执行类RemoteExec& remoteExe = process.remote();//创建远程执行环境remoteExe.CreateRPCEnvironment(Worker_None, true);//获取导出函数地址call_result_t<exportData> GetModuleHandleWPtr = process.modules().GetExport(L"kernel32.dll", "GetModuleHandleW");if (GetModuleHandleWPtr.success()){//使用指定的入口点和参数创建新线程DWORD mod = remoteExe.ExecDirect(GetModuleHandleWPtr->procAddress, 0);AsmHelperPtr asmPtr = AsmFactory::GetAssembler();if (asmPtr){blackbone::IAsmHelper& asmHelper = *asmPtr;asmHelper.GenPrologue();asmHelper.GenCall(static_cast<uintptr_t>(GetModuleHandleWPtr->procAddress), { nullptr }, blackbone::cc_stdcall);asmHelper.GenEpilogue();uint64_t result = 0;//创建新线程并在其中执行代码。 等待执行结束remoteExe.ExecInNewThread(asmHelper->make(), asmHelper->getCodeSize(), result);}//在主线程执行blackbone::ThreadPtr mainThreadPtr = process.threads().getMain();blackbone::AsmHelperPtr asmHelperPtr = blackbone::AsmFactory::GetAssembler();if (asmHelperPtr){blackbone::IAsmHelper& asmHelper = *asmHelperPtr;asmHelper.GenPrologue();asmHelper.GenCall(static_cast<uintptr_t>(GetModuleHandleWPtr->procAddress), { nullptr }, blackbone::cc_stdcall);asmHelper.GenEpilogue();uint64_t result = 0;remoteExe.ExecInAnyThread(asmHelper->make(), asmHelper->getCodeSize(), result, mainThreadPtr);}}}

内存搜索匹配

 Process process;if (NT_SUCCESS(process.Attach(L"QQ.exe"))){//匹配模版PatternSearch ps{ 1,2,3,4,5,6,7,8,9 };//搜索结果vector<ptr_t> results;//内存搜索ps.SearchRemote(process, false, 0, results);}

上面的SearchRemote函数是远程搜索

BLACKBONE_API size_t Search( uint8_t wildcard, void* scanStart, size_t scanSize, std::vector<ptr_t>& out, ptr_t value_offset = 0,size_t maxMatches = SIZE_MAX) const;

另外还提供了一个Search函数支持本进程搜索吗,而且还支持通配符

远程函数调用

 Process process;if (NT_SUCCESS(process.Attach(L"QQ.exe"))){//1.简单直接调用//获取远程函数对象RemoteFunction<decltype(&MessageBoxW)> pMessageBoxW = MakeRemoteFunction<decltype(&MessageBoxW)>(process, L"user32.dll", "MessageBoxW");if (pMessageBoxW.valid()){//远程调用auto result = pMessageBoxW(HWND_DESKTOP, L"HelloWorld", L"Title", MB_OK);}//2.使用特定线程调用auto mainThread = process.threads().getMain();if (auto pIsGuiThread= MakeRemoteFunction<decltype(&IsGUIThread)>(process, L"user32.dll", "IsGUIThread"); pIsGuiThread && mainThread){auto result = pIsGuiThread.Call({ FALSE }, mainThread);if (*result){}}//3.给定参数调用if (auto pMultiByteToWideChar = blackbone::MakeRemoteFunction<decltype(&MultiByteToWideChar)>(process, L"kernel32.dll", "MultiByteToWideChar")){auto args = pMultiByteToWideChar.MakeArguments({ CP_ACP, 0, "Sample text", -1, nullptr, 0 });std::wstring converted(32, L'\0');// Set buffer pointer and size manuallyargs.set(4, blackbone::AsmVariant(converted.data(), converted.size() * sizeof(wchar_t)));args.set(5, converted.size());auto length = pMultiByteToWideChar.Call(args);if (length)converted.resize(*length - 1);}}

系统调用 只适用于x64

{uint8_t buf[32] = { };uintptr_t bytes = 0;NTSTATUS status = syscall::nt_syscall(syscall::get_index( "NtReadVirtualMemory" ),GetCurrentProcess(),GetModuleHandle( nullptr ),buf,sizeof(buf),&bytes);if (NT_SUCCESS( status )){}}

dll隐藏注入

//隐藏注入dll 进程名 dll路径 适配32位和64位
void HideInject(const std::wstring& processName, const std::wstring& dllPath)
{vector<DWORD> vecPid = Process::EnumByName(processName);if (vecPid.empty()){MessageBoxA(0, "不存在目标进程", "提示", 0);return;}//首先要拿到目标进程的信息Process proc;proc.Attach(vecPid.front());//确保LdrInitializeProcess被调用proc.EnsureInit();//将PE文件映射到目标进程 1.PE文件路径 flags(手动映射导入函数) 回调函数auto image = proc.mmap().MapImage(dllPath, ManualImports, &MapCallback2);//获取导出函数地址auto g_loadDataPtr = proc.modules().GetExport(image.result(), "g_LoadData");//调用导出函数auto g_loadData = proc.memory().Read<DllLoadData>(g_loadDataPtr->procAddress);
}

ManualMap模块的代码利用反射型dll注入的原理,将PE文件不借助LoadLibrary在目标进程中展开,从而实现隐藏注入。

https://github.com/DarthTon/Xenos

另外这个作者还有一个非常强大的注入工具,支持三种零环的注入方式和两种三环的注入。不过这个工具基本都已经被国外的各大游戏检测的死死的。

总结

这个项目功能看似很强大,包含有各个模块的封装。但实际使用的时候往往只会用到其中一两个模块的功能。我只需要里面的特征码搜索和dll隐藏注入这两个功能,然后顺便学习了一下其他模块。

没想到最后集成的时候,头文件之间互相包含依赖,而且数据类型都是作者自定义的。如果想拿出其中的一个模块,最后会因为头文件包含的问题,从而把整个工程代码都包含进来。

为了一个功能而把剩下几个不需要的模块代码也加进来实在是有点鸡肋。总的来说,学习价值拉满,实用性就不得而知了。

最强黑客库Blackbone使用教程相关推荐

  1. 3分钟入门python_3分钟学完Python,直接从入门到精通「史上最强干货库」

    作为帅气小编,我已经把python一些模块的甩在这儿了qwq,只要你拿到这些干货,包你玩转python,直接冲向"大佬"的段位,如果已经学了C或者C++或者说如果你需要你的一段关键 ...

  2. 最强黑客组织“匿名者”常用安全渗透软件

    黑客技术一直以来都被人们认为是一种神秘的行为,如今技术不断的进步,随之黑客技术也成为了一种普遍的现象,黑客技术可能没有以往那么神秘了.很多刚入门的黑客们,都喜欢用工具软件进行辅助学习,当然也可以利用黑 ...

  3. PHP7Grafika,PHP图片处理库Grafika详细教程(3):图像属性处理

    该文章是接着上篇文章,<PHP极其强大的图片处理库Grafika详细教程(2):图像特效处理模块>,由于grafika功能太多,所以分开写,其他的点击这里 该文章主要写grafika的图像 ...

  4. Python-EEG工具库MNE中文教程(14)-Epoch对象中的元数据(metadata)

    目录 本分享为脑机学习者Rose整理发表于公众号:脑机接口社区 .QQ交流群:903290195 本案例演示使用Epochs元数据.关于Epochs数据结构:可以查看文章Python-EEG工具库MN ...

  5. Python-EEG工具库MNE中文教程(13)-“bad“通道介绍

    目录 标记坏频道/标记不良通道(marking bad channels) 本分享为脑机学习者Rose整理发表于公众号:脑机接口社区 .QQ交流群:903290195 本教程主要介绍手动标记坏通道以及 ...

  6. 用python画玫瑰花教程-利用Python的turtle库绘制玫瑰教程

    用Python的turtle库绘图是很简单的,闲来无事就画了一个玫瑰花,下面奉上源码.... 源码: ''' Created on Nov 18, 2017 @author: QiZhao ''' i ...

  7. python使用教程pandas-Python 数据处理库 pandas 入门教程基本操作

    pandas是一个Python语言的软件包,在我们使用Python语言进行机器学习编程的时候,这是一个非常常用的基础编程库.本文是对它的一个入门教程. pandas提供了快速,灵活和富有表现力的数据结 ...

  8. PHP极其强大的图片处理库Grafika详细教程(3):图像属性处理

    该文章是接着上篇文章,<PHP极其强大的图片处理库Grafika详细教程(2):图像特效处理模块>,由于grafika功能太多,所以分开写,其他的点击这里 <1.图像基本处理> ...

  9. python安装成功第三方库但import出问题_解析pip安装第三方库但PyCharm中却无法识别的问题及PyCharm安装第三方库的方法教程...

    一.问题具体描述: 在cmd控制台 pip install xxxx 后并显示安装成功后,并且尝试用cmd 的python 中import xxxx ,没有显示异常,说明这个库是安装成功了的.(这里以 ...

最新文章

  1. vmware 克隆后Linux没有eth网卡只有lo
  2. leetcode979. 在二叉树中分配硬币(dfs)
  3. 小程序学习(2):vs code 安装插件
  4. python中的深浅拷贝
  5. 上海联影医疗公司软件开发工程师面试经历
  6. 会计的思考(37):“弱水三千,只取一瓢饮”--业务人员的财务意识
  7. C语言【微项目17】—DustBase微尘数据库[自制键值对数据库][超轻量]【2022-03-23】
  8. 学习Java应该关注哪些网站?
  9. 漫画:什么是哥德巴赫猜想?
  10. 复利计算--结对1.0,做汉堡,结对2.0-复利计算再升级
  11. 5java讲解(xy)
  12. OkHttp调用第三方接口
  13. J2ME学习之Nokia系列手机介绍—S40、S60和S90系列
  14. scrapy+selenium爬取五个外国新闻网站关于“中国“的新闻,并分析
  15. 一次激光纠正近视手术引发的血案 【 激光纠正近视手术 本世纪最大骗局 】
  16. 易 键盘读取,识别键盘代码,程序中响应键盘,键盘输入等,详细例子,手把手教会你!
  17. BP或FI12维护银行账户,报错“银行帐户编号XXX必须具有长度 18”
  18. 单级放大器1db压缩点 matlab仿真,0.1db压缩点
  19. JavaScript基础知识点复习
  20. 玩具CE认证安全指令2009/48 / EC

热门文章

  1. SWIG:SWIG的简介、安装、使用方法之详细攻略
  2. 成功解决ValueError: Expected 2D array, got 1D array instead: Reshape your data either using array.reshap
  3. ML之LSOLS:LSOLS算法的简介、论文、算法的改进(最佳子集选择OFSS法、前向逐步回归FSR法)、代码实现等详细攻略
  4. 【构建之法教学项目】一个简单的基于C#的电子商务系统演练场景的代码示例...
  5. linux 安装 redis3.0
  6. 关于mysql_connect CLIENT_MULTI_RESULTS
  7. 转工厂方法模式-想吃什么汉堡自己要
  8. 论论资排辈和有能者居之
  9. 拔掉网线时Socket的检查方法
  10. Linux 设备模型之 (kobject、kset 和 Subsystem)(二)