首页
社区
课程
招聘
[原创]2021腾讯游戏安全技术竞赛PC客户端初赛writeup
发表于: 2021-4-12 21:36 6703

[原创]2021腾讯游戏安全技术竞赛PC客户端初赛writeup

2021-4-12 21:36
6703

这题与18年的题目的一部分相似。

典型的自由视角解锁问题,常见于各类FPS游戏。

过程

首先通过IDA静态分析,发现其为OpenGL做的3维图形显示程序

从网上找到了比较类似的代码:

https://blog.csdn.net/szqsdq/article/details/79584409

执行程序后发现了箭头,但是没有发现另一副图画,这引起了我的注意

发现其实移动鼠标是有视野的,但是并没有全面,所以直接联想到FPS游戏中的视角解锁,之前做过D3D游戏的视角解锁挂(没错就是吃鸡),但是没有接触过OpenGL

其实原理都是一样的

这里有篇好文章

https://learnopengl-cn.github.io/01%20Getting%20started/09%20Camera/

这里简要说一下,

图片描述

这里从内存中加载了两幅图,最后是OpenGL绘图

进去之后OpenGL对照源码标记函数,这个没啥好讲的

图片描述

我们想解锁自由视角,就需要控制camera

核心函数就是

图片描述
图片描述

剩下的就是祭出Detour大法,InlineHook函数,替换

那两个 glm::mat4 坐标为自己设定的值,就能解锁视角

图片描述

很简单,设定好Hook点,同时我们获取了程序glfwGetKey的函数地址,做了键盘的视角控制函数

图片描述

WSAD控制着摄像机的坐标,RT为缩放

之后我们使用DetourCreateProcessWithDll来让DLL注入到进程中,其实最开始用DetourSetDll程序设置程序import注入Dll,结果发生了黑屏图片显示不正常的问题,这个是因为修改了文件头,破坏了最初的拿图片数据的结构,所以只能动态去注入Hook

图片描述

使用Detours的DetourCreateProcessWithDll函数将Dll注入到程序中实现Hook

通过WSAD和RT控制镜头,得到对应的flag:dogod

图片描述

在这里我偷懒了,发现只通过控制镜头的pos和缩放就能看到flag,实际中还有通过鼠标控制镜头朝向,大致的原理都一样。

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// DllMain
#include "stdafx.h"
 
#define RVA_glfwGetKey 0x19920
 
#define RVA_Get_p_windows_HookPoint 0x06542
#define RVA_Key_HookPoint 0x06BDB
#define RVA_Setprojection_HookPoint 0x06CDB
#define RVA_SetView_HookPoint 0x06DEE
 
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
 
float fov = 50.0f;
 
typedef DWORD(__cdecl* pfnglfwGetKey)(DWORD p_windows, DWORD KeyValue);
pfnglfwGetKey m_glfwGetKey;
 
DWORD p_windows;
HMODULE hModule_EXE;
PVOID p_windows_HookPoint = NULL;
PVOID p_GetKey_HookPoint = NULL;
 
PVOID p_Setprojection = NULL;
PVOID p_Setview = NULL;
 
glm::mat4 projection;
glm::mat4 view;
 
VOID NAKED Get_p_windows()
{
    STACK_FRAME_BEGIN
        __asm {
        mov p_windows, eax
    }
    STACK_FRAME_END
        __asm {
        push p_windows_HookPoint
        ret
    }
 
}
 
VOID NAKED prcessInPut()
{
    STACK_FRAME_BEGIN
        if (m_glfwGetKey(p_windows, GLFW_KEY_W) == GLFW_PRESS)
        {
            cameraPos += cameraFront;
        }
    if (m_glfwGetKey(p_windows, GLFW_KEY_S) == GLFW_PRESS)
    {
        cameraPos -= cameraFront;
    }
    if (m_glfwGetKey(p_windows, GLFW_KEY_A) == GLFW_PRESS)
    {
        cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp));
    }
    if (m_glfwGetKey(p_windows, GLFW_KEY_D) == GLFW_PRESS)
    {
        cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp));
    }
    if (m_glfwGetKey(p_windows, GLFW_KEY_R) == GLFW_PRESS)
    {
        fov -= 1.0;
    }
    if (m_glfwGetKey(p_windows, GLFW_KEY_T) == GLFW_PRESS)
    {
        fov += 1.0f;
 
    }
    view = glm::lookAt(cameraPos, cameraFront + cameraPos, cameraUp);
    projection = glm::perspective(glm::radians(fov), (float)800.0 / (float)600.0, 0.1f, 200.0f);
 
    STACK_FRAME_END
        __asm {
        push p_GetKey_HookPoint
        ret
    }
}
 
VOID NAKED Setprojection()
{
    __asm {
        mov ecx, offset projection
        push p_Setprojection
        ret
    }
}
 
VOID NAKED Setview()
{
    __asm
    {
        mov ecx, offset view
        push p_Setview
        ret
    }
}
 
BOOL DetourHook()
{
    if (DetourTransactionBegin() == NO_ERROR)
    {
        DetourAttach(&p_windows_HookPoint, Get_p_windows);
        DetourAttach(&p_GetKey_HookPoint, prcessInPut);
        DetourAttach(&p_Setprojection, Setprojection);
        DetourAttach(&p_Setview, Setview);
 
        if (DetourTransactionCommit() == NO_ERROR)
        {
            return TRUE;
        }
    }
    return FALSE;
}
 
BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        hModule_EXE = GetModuleHandle(NULL);
        m_glfwGetKey = (pfnglfwGetKey)((DWORD)hModule_EXE + RVA_glfwGetKey);
 
        p_windows_HookPoint = (PVOID)((DWORD)hModule_EXE + RVA_Get_p_windows_HookPoint);
        p_GetKey_HookPoint = (PVOID)((DWORD)hModule_EXE + RVA_Key_HookPoint);
        p_Setprojection = (PVOID)((DWORD)hModule_EXE + RVA_Setprojection_HookPoint);
        p_Setview = (PVOID)((DWORD)hModule_EXE + RVA_SetView_HookPoint);
 
        DetourHook();
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
// DllMain
#include "stdafx.h"
 
#define RVA_glfwGetKey 0x19920
 
#define RVA_Get_p_windows_HookPoint 0x06542
#define RVA_Key_HookPoint 0x06BDB
#define RVA_Setprojection_HookPoint 0x06CDB
#define RVA_SetView_HookPoint 0x06DEE
 
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
 
float fov = 50.0f;
 
typedef DWORD(__cdecl* pfnglfwGetKey)(DWORD p_windows, DWORD KeyValue);
pfnglfwGetKey m_glfwGetKey;
 
DWORD p_windows;
HMODULE hModule_EXE;
PVOID p_windows_HookPoint = NULL;
PVOID p_GetKey_HookPoint = NULL;
 
PVOID p_Setprojection = NULL;
PVOID p_Setview = NULL;
 
glm::mat4 projection;
glm::mat4 view;
 
VOID NAKED Get_p_windows()
{
    STACK_FRAME_BEGIN
        __asm {
        mov p_windows, eax
    }
    STACK_FRAME_END
        __asm {
        push p_windows_HookPoint
        ret
    }
 
}
 

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2021-4-12 21:40 被M00yy编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 910
活跃值: (73)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
厉害
2021-4-20 12:19
0
雪    币: 47147
活跃值: (20310)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
目标程序本地上传一份?
2021-4-22 17:00
0
游客
登录 | 注册 方可回帖
返回
//