这题与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
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
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编辑
,原因: