学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

2万

积分

41

好友

1171

主题
发表于 2021-4-13 11:27:39 | 查看: 12112| 回复: 0

相关题目:

♦ PC客户端初赛

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

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

过程:

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

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


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

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

其实原理都是一样的

这里有篇好文章


这里简要说一下,

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

2021腾讯游戏安全技术竞赛PC客户端初赛writeup
这里从内存中加载了两幅图,最后是OpenGL绘图

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

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

2021腾讯游戏安全技术竞赛PC客户端初赛writeup
我们想解锁自由视角,就需要控制camera

核心函数就是

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

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

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

2021腾讯游戏安全技术竞赛PC客户端初赛writeup
剩下的就是祭出Detour大法,InlineHook函数,替换

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

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

2021腾讯游戏安全技术竞赛PC客户端初赛writeup
很简单,设定好Hook点,同时我们获取了程序glfwGetKey的函数地址,做了键盘的视角控制函数

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

2021腾讯游戏安全技术竞赛PC客户端初赛writeup
WSAD控制着摄像机的坐标,RT为缩放

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

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

2021腾讯游戏安全技术竞赛PC客户端初赛writeup
使用Detours的DetourCreateProcessWithDll函数将Dll注入到程序中实现Hook

通过WSAD和RT控制镜头,得到对应的flag:dogod
// 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;
}

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

2021腾讯游戏安全技术竞赛PC客户端初赛writeup
在这里我偷懒了,发现只通过控制镜头的pos和缩放就能看到flag,实际中还有通过鼠标控制镜头朝向,大致的原理都一样。



温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
论坛交流群:672619046

小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

GMT+8, 2024-12-22 09:55 , Processed in 0.124800 second(s), 43 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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