吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2204|回复: 18
收起左侧

[游戏安全] 某二次元塔防游戏残血AXE绕过分析

[复制链接]
0xLuna 发表于 2026-3-19 19:33
本帖最后由 0xLuna 于 2026-3-19 22:40 编辑

前言
研究仅供学习交流目的,请勿用于任何违法用途

听说ARK上架了PC端,作为一个资深二游玩家,决定一探究竟

基本分析

下载游戏,第一件事就是查看游戏采用的保护方案。看文件夹名称就能略知一二了


2026-03-18-19-22-44-image.png

ida64打开 GameAssembly.dll,发现text 段和 il2cpp 段均未加密。这两个段通常都会被加密运行时依赖 XXShell (xxxBase.dll ) 进行解密。看来可以尝试一些有趣的操作。参考链接:某PC沙盒游戏残血ACE反作弊ring3下的绕过分析

2026-03-18-20-47-33-image.png

先看下这个模块 Arknights.exe,显然是调用了ArknightsBase的导出函数

2026-03-18-20-33-26-image.png

我们找一个未接入axe的游戏,看一下是什么样子,1400A6B22调用了 UnityPlayer.dll 的导出函数 UnityMain这就对了,那么可以做出假设,把call指令的地址 ArknightsBase_1修改成UnityMain的地址这样axe就不工作了!

2026-03-18-20-45-32-image.png

代码实现

dll注入使用Manual Map的注入方式 Create进程挂起,再将dll注入,然后恢复被挂起的线程dll代码,先写代码实验

main.h
[C++] 纯文本查看 复制代码
#pragma once
#include <Windows.h>
#include <stdio.h>

HMODULE UnityPlayer = LoadLibraryW(L"UnityPlayer.dll");
PBYTE Arknights = (PBYTE)GetModuleHandleW(NULL);

int (*UnityMain)(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);

/*
Arknights.exe+A6B22 - FF15 02000000 EB08 0000000000000000 | call HookHandler
*/
BYTE HookShellCode[] = { 0xFF, 0x15, 0x02, 0x00, 0x00, 0x00, 0xEB, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
main.cpp
[C++] 纯文本查看 复制代码
#include "main.h"

/* 
优化控制 保证堆栈平衡
*/
#pragma optimize("t", on)
void __fastcall HookHandler(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
     UnityMain(hInstance, hPrevInstance, lpCmdLine, nShowCmd);
}
#pragma optimize("", on) 

void InstallHook(PVOID lpTargetAddress)
{
    DWORD dwOldProtect = 0;
    VirtualProtect(lpTargetAddress, sizeof(HookShellCode), PAGE_EXECUTE_READWRITE, &dwOldProtect);
    *(DWORD64*)&HookShellCode[8] = (DWORD64)HookHandler;
    RtlCopyMemory(lpTargetAddress, HookShellCode, sizeof(HookShellCode));
    VirtualProtect(lpTargetAddress, sizeof(HookShellCode), dwOldProtect, &dwOldProtect);
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    if (ul_reason_for_call != DLL_PROCESS_ATTACH)
        return FALSE;

    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)Arknights;

    PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(Arknights + pDosHeader->e_lfanew);

    if (pNtHeader->Signature == IMAGE_NT_SIGNATURE)
    {
        IMAGE_OPTIONAL_HEADER OptionalHeader = pNtHeader->OptionalHeader;
        DWORD dwEntryPoint = OptionalHeader.AddressOfEntryPoint;

        void (*Start)() = ((void(*)())((Arknights + dwEntryPoint)));

        UnityMain = (int(*)(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd))(GetProcAddress(UnityPlayer, "UnityMain"));

        InstallHook(PVOID((DWORD64)Start + 4));
    }

    return TRUE;
}


注入测试
手动Create进程,注入后发现游戏窗口被隐藏了,任务管理器查看游戏进程正在运行,看样子是有问题的。问题的答案显然是调用UnityMain未传入所需的参数调用UnityMain的时候,寄存器保存的是一些乱七八糟的值


2026-03-19-12-04-29-image.png


找一个未接入axe的unity游戏,分析一下nShowCmd是哪来的

2026-03-19-12-19-42-image.png


根据伪代码实现即可

2026-03-19-12-20-55-image.png

改进代码

main.h
[C++] 纯文本查看 复制代码
#pragma once
#include <Windows.h>
#include <stdio.h>

HMODULE UnityPlayer = LoadLibraryW(L"UnityPlayer.dll");
PBYTE Arknights = (PBYTE)GetModuleHandleW(NULL);
WORD  wShowWindow;

int (*UnityMain)(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);

/*
Arknights.exe+A6B22 - FF15 02000000 EB08 0000000000000000 | call HookHandler
*/
BYTE HookShellCode[] = { 0xFF, 0x15, 0x02, 0x00, 0x00, 0x00, 0xEB, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
main.cpp
[C++] 纯文本查看 复制代码
#include "main.h"


WORD GetShowWindowMode()
{
    WORD result = 10;
    STARTUPINFOW StartupInfo = { sizeof(StartupInfo) };
    GetStartupInfoW(&StartupInfo);

    if ((StartupInfo.dwFlags & 1) != 0)
        return StartupInfo.wShowWindow;
    return result;
}

/* 
优化控制 保证堆栈平衡
*/
#pragma optimize("t", on)
void __fastcall HookHandler(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    nShowCmd = wShowWindow;
     UnityMain(hInstance, hPrevInstance, lpCmdLine, nShowCmd);
}
#pragma optimize("", on) 

void InstallHook(PVOID lpTargetAddress)
{
    DWORD dwOldProtect = 0;
    VirtualProtect(lpTargetAddress, sizeof(HookShellCode), PAGE_EXECUTE_READWRITE, &dwOldProtect);
    *(DWORD64*)&HookShellCode[8] = (DWORD64)HookHandler;
    RtlCopyMemory(lpTargetAddress, HookShellCode, sizeof(HookShellCode));
    VirtualProtect(lpTargetAddress, sizeof(HookShellCode), dwOldProtect, &dwOldProtect);
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    if (ul_reason_for_call != DLL_PROCESS_ATTACH)
        return FALSE;

    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)Arknights;

    PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(Arknights + pDosHeader->e_lfanew);

    if (pNtHeader->Signature == IMAGE_NT_SIGNATURE)
    {
        IMAGE_OPTIONAL_HEADER OptionalHeader = pNtHeader->OptionalHeader;
        DWORD dwEntryPoint = OptionalHeader.AddressOfEntryPoint;

        void (*Start)() = ((void(*)())((Arknights + dwEntryPoint)));

        UnityMain = (int(*)(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd))(GetProcAddress(UnityPlayer, "UnityMain"));

        wShowWindow = GetShowWindowMode();

        InstallHook(PVOID((DWORD64)Start + 4));
    }

    return TRUE;
}



注入测试,这时候axe已经不工作了,用x64dbg附加没有问题

2026-03-19-12-58-37-image.png

结论
加强安全组件运行时依赖可以提高剥离难度,希望有关游戏厂商能尽快修复问题

免费评分

参与人数 5威望 +1 吾爱币 +24 热心值 +4 收起 理由
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
shiren3 + 1 + 1 用心讨论,共获提升!
XHiaoe + 1 + 1 用心讨论,共获提升!
IcePlume + 1 + 1 我很赞同!
kotlyne + 1 我很赞同!

查看全部评分

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

kotlyne 发表于 2026-3-20 17:02
严肃学习了,这么好的帖子为什么没人
gh8671 发表于 2026-3-20 21:32
IcePlume 发表于 2026-3-21 02:13
PercyDan 发表于 2026-3-21 11:40
哪要这么麻烦,直接替换主程序
XHiaoe 发表于 2026-3-21 14:13
学到了,前两天才下下来玩
wupeiwupei 发表于 2026-3-21 14:19
没玩过,要不下载玩玩试一试~!
nianyueripe 发表于 2026-3-21 18:41
跟迷你是一样的
yvmo 发表于 2026-3-22 00:45
厉害厉害。学习了哈哈哈
alex663301 发表于 2026-3-22 08:25
厉害 学习下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2026-9-7 17:33

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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