Skip to content

Commit 721f6dc

Browse files
feat: add find_one_pattern
1 parent d25538e commit 721f6dc

5 files changed

Lines changed: 195 additions & 360 deletions

File tree

LLMDOCS.md

Lines changed: 13 additions & 346 deletions
Original file line numberDiff line numberDiff line change
@@ -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]]
576588
auto 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

Comments
 (0)