最强黑客库Blackbone使用教程

云惠网小编 2022年1月17日03:22:34
评论
9869字阅读32分53秒
摘要

最强黑客库Blackbone揭秘

广告也精彩

需要安装下面几个组件

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;

项目介绍

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

auto pids = Process::EnumByName(L"explorer.exe");
//隐藏注入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);
}

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

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

	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 manually
args.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);
}
}

在这里插入图片描述

项目使用

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

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

在这里插入图片描述

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

启动并附加进程

内存搜索匹配

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

	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();
//获取进程PEB
PEB_T peb = {};
ptr_t ptrPEB = processCore.peb(&peb);
//获取进程的所有句柄
for (HandleInfo handleInfo:process.EnumHandles().result())
{
wcout << handleInfo.name << handleInfo.handle << handleInfo.typeName << endl;
}

总结

在这里插入图片描述

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

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

新建一个空项目
在这里插入图片描述

项目集成

文章目录

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

https://github.com/DarthTon/Blackbone

库内容包含

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

在这里插入图片描述

远程代码执行

接着包含lib库和头文件

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

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

进程交互

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);

进程线程管理

在这里插入图片描述

JIT汇编

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

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

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

{
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 ))
{
}
}

进程内存管理

	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);
}
}
}
	auto procInfo = Process::EnumByNameOrPID(4596, L"");
for (auto info : procInfo.result())
{
wcout << info.imageName << info.pid << info.threads.size();
}
Process interaction(进程交互)
操作PEB32/PEB64
通过WOW64 barrier管理进程
Process Memory(进程内存)
分配和释放虚拟内存
改变内存保护属性
读写虚拟内存
Process modules(进程模块)
枚举所有进程加载的模块 (32/64 bit)
获得导出函数地址
获得主模块
从模块列表中去除模块信息
注入、卸载模块(支持 pure IL images)
在WOW64进程中注入64位模块
操作PE
Threads(线程)
枚举线程
创建和关闭线程
获得线程退出码
获得主线程
管理 TEB32/TEB64
join线程(等待线程退出)
暂停、恢复线程
设置、清除硬件断点
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(手动加载模块)
手动加载驱动

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

在这里插入图片描述

使用命名空间

	//进程模块管理
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);
}

在这里插入图片描述

枚举所有进程

项目编译

dll隐藏注入

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

	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();
}

环境搭建

  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

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

	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);
}

远程函数调用

https://github.com/DarthTon/Xenos

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

进程模块管理

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

在这里插入图片描述

上面的SearchRemote函数是远程搜索

项目地址

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

using namespace blackbone;

在这里插入图片描述

系统调用 只适用于x64

	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);
}

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

#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

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

本文转自 https://blog.csdn.net/qq_38474570/article/details/122466905

腾讯云618
云惠网小编
SpringCloud -- Config、Bus解析 java

SpringCloud — Config、Bus解析

1、Config1.1、概述简介1. 分布式面临的问题微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要...
Java数据结构-了解复杂度 java

Java数据结构-了解复杂度

2.实例分析与计算  四.写在最后  // 计算斐波那契递归fibonacci的时间复杂度 int fibonacci(int N) { return N < 2 ? N : fibonacci...
Java数据结构-认识顺序表 java

Java数据结构-认识顺序表

目录二.顺序表1.概念及结构2.顺序表的实现打印顺序表获取顺序表的有效长度在pos位置新增元素判断是否包含某个元素查找某个元素对应的位置获取/查找pos位置的元素给pos位置的元素...
腾讯云618

发表评论