@@ -572,7 +572,19 @@ auto result = range.find_one(
572572 )
573573);
574574
575- // 远程进程搜索(使用 ReadProcessMemory)
575+ // Pattern 字符串搜索(支持多种格式)
576+ auto result1 = range.find_one_pattern("aabbcc");
577+ auto result2 = range.find_one_pattern("aa bb cc");
578+ auto result3 = range.find_one_pattern("aa,bb,cc");
579+ auto result4 = range.find_one_pattern("0xaa, 0xbb, 0xcc");
580+ auto result5 = range.find_one_pattern("aa??12"); // 通配符
581+
582+ // find_one 自动判断本地/远程搜索
583+ // 本地进程使用快速扫描器,远程进程使用迭代器
584+ auto result = range.find_one({0x90, 0x90, 0x90});
585+
586+ // find_one_remote 已废弃,请使用 find_one
587+ [[deprecated]]
576588auto result = range.find_one_remote({0x90, 0x90, 0x90});
577589```
578590
@@ -1331,348 +1343,3 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved) {
13311343 return TRUE;
13321344}
13331345```
1334-
1335- ## 示例
1336-
1337- ### 示例 1: 简单的函数钩子
1338-
1339- ```cpp
1340- #include <blook/blook.h>
1341- #include <Windows.h>
1342- #include <iostream>
1343-
1344- int main() {
1345- auto proc = blook::Process::self();
1346- auto kernel32 = proc->module("kernel32.dll").value();
1347- auto sleep_func = kernel32->exports("Sleep").value();
1348-
1349- auto hook = sleep_func->inline_hook();
1350-
1351- hook->install([=](DWORD ms) {
1352- std::cout << "Sleep 被调用,参数: " << ms << "ms" << std::endl;
1353-
1354- // 减少睡眠时间
1355- hook->call_trampoline<void>(ms / 10);
1356-
1357- std::cout << "实际只睡了 " << (ms / 10) << "ms" << std::endl;
1358- });
1359-
1360- // 测试
1361- std::cout << "开始睡眠 1000ms..." << std::endl;
1362- Sleep(1000);
1363- std::cout << "睡眠结束" << std::endl;
1364-
1365- hook->uninstall();
1366- return 0;
1367- }
1368- ```
1369-
1370- ### 示例 2: 内存扫描和修改
1371-
1372- ``` cpp
1373- #include < blook/blook.h>
1374- #include < iostream>
1375-
1376- int main () {
1377- auto proc = blook::Process::self();
1378- auto mod = proc->module().value();
1379-
1380- // 假设我们要找游戏中的生命值
1381- int health = 100;
1382-
1383- // 在内存中搜索
1384- auto range = mod->memo();
1385- auto result = range.find_one(
1386- std::vector<uint8_t>(
1387- (uint8_t*)&health,
1388- (uint8_t*)&health + sizeof(health)
1389- )
1390- );
1391-
1392- if (result.has_value()) {
1393- std::cout << "找到生命值地址: " << result->data() << std::endl;
1394-
1395- // 修改为 999
1396- result->write_s32(999);
1397-
1398- std::cout << "生命值已修改为: " << health << std::endl;
1399- }
1400-
1401- return 0;
1402- }
1403- ```
1404-
1405- ### 示例 3: 代码洞穴 (Code Cave)
1406-
1407- ``` cpp
1408- #include < blook/blook.h>
1409-
1410- int main () {
1411- auto proc = blook::Process::self();
1412- auto mod = proc->module().value();
1413- auto text = mod->section(".text").value();
1414-
1415- // 查找 NOP 洞穴(连续的 0x90)
1416- auto cave = text.find_one({
1417- 0x90, 0x90, 0x90, 0x90, 0x90,
1418- 0x90, 0x90, 0x90, 0x90, 0x90
1419- });
1420-
1421- if (cave.has_value()) {
1422- std::cout << "找到代码洞穴: " << cave->data() << std::endl;
1423-
1424- // 在洞穴中写入自定义代码
1425- auto patch = cave->reassembly([](zasm::x86::Assembler& a) {
1426- a.push(zasm::x86::rax);
1427- a.mov(zasm::x86::rax, zasm::Imm(0x12345678));
1428- // ... 更多代码
1429- a.pop(zasm::x86::rax);
1430- a.ret();
1431- });
1432-
1433- patch.patch();
1434- }
1435-
1436- return 0;
1437- }
1438- ```
1439-
1440- ### 示例 4: 多级指针
1441-
1442- ``` cpp
1443- #include < blook/blook.h>
1444- #include < iostream>
1445-
1446- int main () {
1447- auto proc = blook::Process::self();
1448-
1449- // 假设游戏中的玩家数据结构
1450- // PlayerManager -> Player -> Stats -> Health
1451- blook::Pointer player_mgr = (void*)0x140000000;
1452-
1453- // 偏移链: [0x10] -> [0x20] -> [0x30] -> health
1454- auto health_ptr = player_mgr.offsets({0x10, 0x20, 0x30});
1455-
1456- if (health_ptr.has_value()) {
1457- int health = health_ptr->read_s32();
1458- std::cout << "当前生命值: " << health << std::endl;
1459-
1460- // 修改生命值
1461- health_ptr->write_s32(999);
1462- std::cout << "生命值已修改为 999" << std::endl;
1463- }
1464-
1465- return 0;
1466- }
1467- ```
1468-
1469-
1470- ### 示例 5: 反汇编和分析
1471-
1472- ``` cpp
1473- #include < blook/blook.h>
1474- #include < iostream>
1475-
1476- void analyze_function (void* func_addr) {
1477- blook::Pointer ptr = func_addr;
1478- auto range = ptr.range_size(200);
1479-
1480- std::cout << "分析函数: " << func_addr << std::endl;
1481- std::cout << "----------------------------------------" << std::endl;
1482-
1483- auto disasm = range.disassembly();
1484- int instr_count = 0;
1485-
1486- for (const auto& instr : disasm) {
1487- // 打印指令
1488- std::cout << std::hex << instr.ptr().data() << ": "
1489- << instr.dump() << std::endl;
1490-
1491- // 检查是否有交叉引用
1492- auto xrefs = instr.xrefs();
1493- for (const auto& xref : xrefs) {
1494- std::cout << " -> 引用: " << xref.data() << std::endl;
1495- }
1496-
1497- instr_count++;
1498-
1499- // 遇到 ret 指令停止
1500- if (instr->getMnemonic() == zasm::x86::Mnemonic::Ret) {
1501- break;
1502- }
1503- }
1504-
1505- std::cout << "总共 " << instr_count << " 条指令" << std::endl;
1506- }
1507-
1508- int main() {
1509- auto proc = blook::Process::self();
1510- auto kernel32 = proc->module("kernel32.dll").value();
1511- auto sleep_func = kernel32->exports("Sleep").value();
1512-
1513- analyze_function(sleep_func->data());
1514-
1515- return 0;
1516- }
1517- ```
1518-
1519- ### 示例 6: VEH 钩子监控
1520-
1521- ```cpp
1522- #include <blook/blook.h>
1523- #include <iostream>
1524- #include <vector>
1525-
1526- // 要监控的函数
1527- int sensitive_function(int a, int b) {
1528- return a * b + 42;
1529- }
1530-
1531- int main() {
1532- std::vector<std::pair<int, int>> call_log;
1533-
1534- // 添加硬件断点
1535- auto handler = blook::VEHHookManager::instance().add_breakpoint(
1536- blook::VEHHookManager::HardwareBreakpoint{
1537- .address = (void*)sensitive_function
1538- },
1539- [&](blook::VEHHookManager::VEHHookContext& ctx) {
1540- // 记录调用参数(x64 calling convention)
1541- #ifdef BLOOK_ARCHITECTURE_X86_64
1542- auto regs = (CONTEXT*)ctx.exception_info->ContextRecord;
1543- int a = (int)regs->Rcx;
1544- int b = (int)regs->Rdx;
1545- #else
1546- // x86 需要从栈上读取
1547- auto regs = (CONTEXT*)ctx.exception_info->ContextRecord;
1548- int* stack = (int*)regs->Esp;
1549- int a = stack[1];
1550- int b = stack[2];
1551- #endif
1552-
1553- call_log.push_back({a, b});
1554- std::cout << "函数被调用: " << a << ", " << b << std::endl;
1555- }
1556- );
1557-
1558- // 测试调用
1559- sensitive_function(10, 20);
1560- sensitive_function(5, 7);
1561- sensitive_function(3, 4);
1562-
1563- // 移除断点
1564- blook::VEHHookManager::instance().remove_breakpoint(handler);
1565-
1566- // 打印日志
1567- std::cout << "\n调用日志:" << std::endl;
1568- for (const auto& [a, b] : call_log) {
1569- std::cout << " (" << a << ", " << b << ")" << std::endl;
1570- }
1571-
1572- return 0;
1573- }
1574- ```
1575-
1576- ### 示例 7: 自动查找和钩住函数
1577-
1578- ``` cpp
1579- #include < blook/blook.h>
1580- #include < iostream>
1581-
1582- int main () {
1583- auto proc = blook::Process::self();
1584- auto mod = proc->module().value();
1585-
1586- // 查找包含特定字符串的函数
1587- auto rdata = mod->section(".rdata").value();
1588- auto text = mod->section(".text").value();
1589-
1590- // 查找错误消息字符串
1591- auto error_msg = rdata.find_one("Critical Error:");
1592-
1593- if (error_msg.has_value()) {
1594- std::cout << "找到错误消息: " << error_msg->data() << std::endl;
1595-
1596- // 查找引用这个字符串的代码
1597- auto xref = text.find_xref(*error_msg);
1598-
1599- if (xref.has_value()) {
1600- std::cout << "找到引用: " << xref->data() << std::endl;
1601-
1602- // 猜测函数起始地址
1603- auto func = xref->guess_function();
1604-
1605- if (func.has_value()) {
1606- std::cout << "找到函数: " << func->data() << std::endl;
1607-
1608- // 钩住这个函数
1609- auto hook = func->inline_hook();
1610-
1611- hook->install([=]() {
1612- std::cout << "错误处理函数被调用!" << std::endl;
1613-
1614- // 可以选择不调用原始函数,阻止错误
1615- // 或者调用原始函数
1616- hook->call_trampoline<void>();
1617- });
1618-
1619- std::cout << "已钩住错误处理函数" << std::endl;
1620- }
1621- }
1622- }
1623-
1624- return 0;
1625- }
1626- ```
1627-
1628- ### 示例 8: 内存分配器使用
1629-
1630- ``` cpp
1631- #include < blook/blook.h>
1632- #include < iostream>
1633-
1634- int main () {
1635- auto proc = blook::Process::self();
1636- auto& allocator = proc->allocator();
1637-
1638- std::cout << "初始状态:" << std::endl;
1639- std::cout << " 分配数: " << allocator.allocated_count() << std::endl;
1640- std::cout << " 已分配: " << allocator.total_allocated_bytes() << " 字节" << std::endl;
1641- std::cout << " 已保留: " << allocator.total_reserved_bytes() << " 字节" << std::endl;
1642-
1643- // 分配多个小块
1644- std::vector<blook::Pointer> ptrs;
1645- for (int i = 0; i < 10; i++) {
1646- auto ptr = allocator.allocate(512);
1647- ptrs.push_back(ptr);
1648-
1649- // 写入测试数据
1650- std::vector<uint8_t> data(512, i);
1651- ptr.write_bytearray(data);
1652- }
1653-
1654- std::cout << "\n分配 10 个块后:" << std::endl;
1655- std::cout << " 分配数: " << allocator.allocated_count() << std::endl;
1656- std::cout << " 已分配: " << allocator.total_allocated_bytes() << " 字节" << std::endl;
1657- std::cout << " 已保留: " << allocator.total_reserved_bytes() << " 字节" << std::endl;
1658-
1659- // 验证数据
1660- for (size_t i = 0; i < ptrs.size(); i++) {
1661- auto data = ptrs[i].read_bytearray(512);
1662- bool valid = std::all_of(data.begin(), data.end(),
1663- [i](uint8_t b) { return b == i; });
1664- std::cout << "块 " << i << " 数据" << (valid ? "正确" : "错误") << std::endl;
1665- }
1666-
1667- // 释放所有块
1668- for (auto& ptr : ptrs) {
1669- allocator.deallocate(ptr);
1670- }
1671-
1672- std::cout << "\n释放后:" << std::endl;
1673- std::cout << " 分配数: " << allocator.allocated_count() << std::endl;
1674- std::cout << " 已分配: " << allocator.total_allocated_bytes() << " 字节" << std::endl;
1675-
1676- return 0;
1677- }
1678- ```
0 commit comments