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

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

2021-4-12 21:36
5939

初赛

这题与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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// 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;
}

图片描述

 

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


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

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