吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 11851|回复: 5
收起左侧

[游戏安全] [External Trainer] 外部工具实现原理 太吾绘卷工具 + 源码

[复制链接]
gshzhsheng 发表于 2020-3-18 19:04
本帖最后由 gshzhsheng 于 2020-3-18 19:10 编辑

所谓 External Trainer, 就是我们的工具和游戏不在一个进程,需要进行跨进程修改。

Windows为我们提供了一系列的 External 类 API,我们可以在MSDN中搜索带有Ex的API:
0.png

我们可以看到很多External 跨进程的函数。这些我们都可以进行利用,进行跨进程创建,访问,或者读写。

还有几个比较经典的 跨进程 External 访问内存的函数是 CreateRemoteThread, ReadMemoryProcess, WriteMemoryProcess .....

下面以 寻找 太吾绘卷 的基址 作为例子

我已经找到天数的偏移为:

std::vector<DWORD> daysOffset = { 0x004A2308, 0x210, 0x170, 0x60, 0x38,  0x8, 0x10, 0x8EC};

模块为: mono-2.0-bdwgc.dll

首先我们需要找到模块地址

ULONGLONG getModuleBaseAddr(TCHAR* name, DWORD pid) {

        HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid); //扫描游戏进程的所有模块

        if (hSnap == INVALID_HANDLE_VALUE)  //扫描失败,退出
        {
                DWORD error = GetLastError();
                return NULL;
        }

        MODULEENTRY32 me;
        me.dwSize = sizeof(MODULEENTRY32);

        if (Module32First(hSnap, &me))
        {
                do
                {
                        if (_tcscmp(me.szModule, name) == 0)  // 如果找到了我们需要的模块
                        {
                                CloseHandle(hSnap);
                                return (ULONGLONG)(me.modBaseAddr); // 返回此模块地址
                        }
                } while (Module32Next(hSnap, &me));
        }
}

接着我们需要通过找到的模块地址和偏移找到天数的地址:

ULONGLONG getFinalAddddy(std::vector<DWORD> offsetVector, ULONGLONG BaseAddr, HANDLE hProcess)
{
        DWORD offsetNum = offsetVector.size();  // 获取偏移的数量

        ULONGLONG myAddy = BaseAddr;

        for (int i = 0; i < offsetNum - 1; i++)
        {
                ReadProcessMemory(hProcess, LPCVOID(myAddy + offsetVector[i]), &myAddy, sizeof(ULONGLONG), NULL);  // 遍历偏移地址
        }

        myAddy += offsetVector[offsetNum - 1];

        return myAddy;
}

寻找天数最终的地址:

std::vector<DWORD> daysOffset = { 0x004A2308, 0x210, 0x170, 0x60, 0x38,  0x8, 0x10, 0x8EC}; // 天数偏移

ULONGLONG bdwgcModuleBaseAddr = getModuleBaseAddr((TCHAR*)(TEXT("mono-2.0-bdwgc.dll")), processId); // 模块地址

ULONGLONG dayAddress = getFinalAddddy(daysOffset, bdwgcModuleBaseAddr, hProcess); // 天数最终地址

寻找到最终天数地址我们就可以使用WriteMemoryProcess(),ReadMemoryProcess()进行读写

External Trainer 修改游戏进程的流程如下:

1.png

工具雏形:
0.png

源码地址:
https://github.com/absolutelycold/TaiWuWarrior

proc.h 解释

DWORD getPIDByName(TCHAR* name); // 通过进程名获取Process ID
HANDLE getProcessHandle(DWORD pid); // 通过 pid 获取进程句柄
ULONGLONG getModuleBaseAddr(TCHAR* name, DWORD pid); // 获取模块地址
ULONGLONG getFinalAddddy(std::vector<DWORD> offsetVector, ULONGLONG BaseAddr, HANDLE hProcess); // 通过偏移寻找地址
BOOL writeToMemoryInt(HANDLE hProcess, ULONGLONG addr, DWORD value); // 写入目标进程指定地址 4 字节大小的数据
DWORD readMemoryInt(HANDLE hProcess, ULONGLONG addr); // 读取目标进程指定地址 4 字节大小地址

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

cxh9588 发表于 2020-3-18 19:13
谢谢啦,要研究一下。
sq178178 发表于 2020-3-18 20:11
lolp2012 发表于 2020-8-10 01:22
Tony12589 发表于 2021-5-21 08:57
这游戏如果用作弊器一点意思也没得
sam喵喵 发表于 2021-5-21 15:34
感谢分享,最近刚好在研究内核,可以好好学习下API用法。
请教下大佬,现在游戏都不做内存地址读写保护的吗,如果有保护的一般怎么弄
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-22 10:49

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表