插件开发手册

插件产品介绍
Game-Plug 是一款功能强大的 Windows 逆向开发插件,兼容 VC++、Delphi、VB、按键精灵、火山 PC、等多种编程语言调用。它面向编程人员提供窗口、内存、线程、汇编、HOOK、注入、Call、按键、封包、驱动防检测等全方位操作命令,并配有对应的使用案例示范,简单易学、上手快、实用性强。
目录导航

特征码搜索 - SearchPattern

接口 ID 120 | 分类:内存读写与搜索 | 定义文件:x64GamePlug.idl

作用说明

特征码搜索(AOB Scan),在 startAddr 到 endAddr 之间搜索;endAddr 传 0 表示搜到起始地址所在模块末尾(不在模块内则搜 64MB);pattern 支持 48 8B ?? 05 或 488B??05,?? 为整字节通配;maxCount 0 默认 50;返回 地址1|地址2 十六进制,没找到返回 0

参数说明
参数名方向类型说明
pid[in]long目标进程 ID(可用 EnumProcessList / GetPidByName 取得)
startAddr[in]__int64 (int64)特征码搜索的起始地址(64 位)
endAddr[in]__int64 (int64)搜索结束地址(传 0 表示搜到起始地址所在模块末尾,不在模块内则搜 64MB)
pattern[in]string (BSTR)特征码(AOB),支持 "48 8B ?? 05" 或 "488B??05",?? 为整字节通配
maxCount[in]long(见上方说明)
VC++ 调用示例(x64,控制台工程)

// 说明:本示例为完整 x64 控制台工程,整段复制覆盖新建控制台工程的 main.cpp 即可编译运行。

//   1. VS2019 新建「控制台应用」,项目属性 -> 平台选 x64,才能加载 64 位 DLL。

//   2. 项目属性 -> C/C++ -> 预编译头 -> 改为「不使用预编译头」,否则默认找 pch.h 会报 C1010。

//   3. 把 x64Game-Plug.dll 放到 exe 同目录(#import 与免注册加载都需要)。

//   4. 源码保存为 UTF-8 带 BOM,避免中文乱码;全站用 regsvr32 注册也可(需管理员)。

#include <iostream>

#include <clocale>

#include <windows.h>

#include <comdef.h>



// 免注册加载:用 IGamePlug 智能指针装载

// rename 是为避开 windows.h 的 FindWindow 宏冲突,接口里的 FindWindow 在 C++ 侧改名为 FindWindowGP

#import "x64Game-Plug.dll" no_namespace rename("FindWindow", "FindWindowGP")



static HMODULE      g_hDll = NULL;

static IGamePlugPtr g_plug;



// ---------- 免注册:加载 DLL 并创建对象(发布时把 DLL 放 exe 同目录)----------

static bool LoadPlug() {

    const wchar_t* paths[] = {

        L"x64Game-Plug.dll",

        L"..\x64Game-Plug.dll"

    };

    for (int i = 0; i < (int)(sizeof(paths) / sizeof(paths[0])); ++i) {

        g_hDll = ::LoadLibraryW(paths[i]);

        if (g_hDll) break;

    }

    if (!g_hDll) {

        std::cout << "LoadLibrary failed: put x64Game-Plug.dll next to the exe" << std::endl;

        return false;

    }

    typedef HRESULT (__stdcall *GamePlugCreateFn)(IGamePlug**);

    GamePlugCreateFn fn = (GamePlugCreateFn)::GetProcAddress(g_hDll, "GamePlugCreate");

    if (!fn) { std::cout << "GetProcAddress GamePlugCreate failed" << std::endl; return false; }

    HRESULT hr = fn(&g_plug);

    if (FAILED(hr)) { std::cout << "GamePlugCreate failed: 0x" << std::hex << hr << std::endl; return false; }

    return true;

}

int main() {

    if (!LoadPlug()) { system("pause"); return 1; }

    // 授权(收费功能需先传入授权码,去 https://www.game-plug.cn/ 获取)

    g_plug->SetUsername(_bstr_t(L"U12-XXXXXXXXXXXXXXXX"));



    // ---------- 调用插件本命令方法如下 ----------

    try {

        long pid = 1234;

        __int64 startAddr = 0x0000000140001234;

        __int64 endAddr = 0x0000000140001234;

        _bstr_t pattern = L"48 8B ?? 05";

        long maxCount = 0;

        long v = g_plug->SearchPattern(pid, startAddr, endAddr, pattern, maxCount);

        std::cout << "结果: " << v << std::endl;

    } catch (_com_error& e) {

        std::wcout << L"COM error: " << e.ErrorMessage() << std::endl;

    }



    g_plug->Release();

    system("pause");

    return 0;

}



返回值

返回命中地址列表(十六进制,多个用 | 分隔);未找到返回 "0"。

常见注意事项
  • 以上内存读写与搜索相关方法均为收费功能,使用前需先调用 SetUsername 传入有效授权码(示例开头已激活该调用,发布时请改为你自己的授权码)。
  • 32 位目标进程的内存地址须 <= 0xFFFFFFFF;64 位进程使用完整 64 位地址。
  • 写入代码段或只读数据前,应先使用 SetMemProtect 将对应区域改为可写,否则写入会失败。
  • 请确认传入的地址在目标进程中真实有效,无效地址通常会返回 0 或空串。