起这么个标题,其实没啥用.
进入正题,Half-Life是Valve的一个引擎,算是比较老了,CS1.6 CSOL等等是基于它的。
至于实现透视的方法,这几年对OpenGL的glBegin的检测一步步在加强,但过去也还是没问题的。
不如换一个思路,直接对HL引擎绘制人物部分下手。
先看HL SDK这几个地方
extern "C" int DLLEXPORT HUD_GetStudioModelInterface( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio )
{
if ( version != STUDIO_INTERFACE_VERSION )
return 0;
// Point the engine to our callbacks
*ppinterface = &studio;
// Copy in engine helper functions
memcpy( &IEngineStudio, pstudio, sizeof( IEngineStudio ) );
// Initialize local variables, etc.
R_StudioInit();
// Success
return 1;
}
// client blending
typedef struct r_studio_interface_s
{
int version;
int ( *StudioDrawModel ) ( int flags );
int ( *StudioDrawPlayer ) ( int flags, struct entity_state_s *pplayer );
} r_studio_interface_t;
这个函数在CSOL的client.dll导出,IDA看一下
text:01AB7360 lea eax, [esp+arg_8]
.text:01AB7364 lea ecx, [esp+arg_4]
.text:01AB7368 push eax
.text:01AB7369 mov eax, dword_1D9D508
.text:01AB736E lea edx, [esp+4+arg_0]
.text:01AB7372 push ecx
.text:01AB7373 push edx
.text:01AB7374 call dword ptr [eax+9Ch]
.text:01AB737A mov eax, [esp+0Ch+arg_0]
.text:01AB737E add esp, 0Ch
.text:01AB7381 cmp eax, 1
.text:01AB7384 jz short loc_1AB7389
.text:01AB7386 xor eax, eax
.text:01AB7388 retn
.text:01AB7389 ; ---------------------------------------------------------------------------
.text:01AB7389
.text:01AB7389 loc_1AB7389: ; CODE XREF: HUD_GetStudioModelInterface+24j
.text:01AB7389 mov ecx, [esp+arg_4]
.text:01AB738D push esi
.text:01AB738E push edi
.text:01AB738F mov edi, offset dword_1EB91B0
.text:01AB7394 mov dword ptr [ecx], 1CBB730h
.text:01AB739A mov esi, [esp+8+arg_8]
.text:01AB739E mov ecx, 2Eh
.text:01AB73A3 rep movsd
.text:01AB73A5 mov ecx, offset dword_1E7DD08
.text:01AB73AA call sub_1B1EE00
.text:01AB73AF pop edi
.text:01AB73B0 mov eax, 1
.text:01AB73B5 pop esi
.text:01AB73B6 retn
OK 看起来只是这样的个东西 那就这样干
client := GetModuleHandle('client.dll');
pHUD_GetStudioModelInterface := DWORD(GetProcAddress(client, 'HUD_GetStudioModelInterface'));
StudioInterface := Pointer(PDWORD(pHUD_GetStudioModelInterface + $36)^);
OldStudioDrawModel := @StudioInterface.StudioDrawModel;
StudioInterface.StudioDrawPlayer := @NewStudioDrawPlayer;
OK 钩住它了 接下来还有一个问题,由于历史原因HL引擎是GL/D3D两个模式,其中D3D其实是用D3D模拟了OpenGL的函数。
hw := GetModuleHandle('hw.dll');
_glDepthRange := Pointer(GetProcAddress(hw, '_glDepthRange@16'));
D3D模拟这个函数获取到就可以了
function NewStudioDrawPlayer(flags : Integer; pplayer : Pointer) : Integer; cdecl;
begin
if RunInDirect3D then
begin
_glDepthRange(0, 0.1);
Result := OldStudioDrawPlayer(flags, pplayer);
_glDepthRange(0, 1.0);
end
else
begin
glDepthRange(0, 0.1);
Result := OldStudioDrawPlayer(flags, pplayer);
glDepthRange(0, 1.0);
end;
end;
OK这样就可以达到透视的目的了
最后,CSOL有个无聊的检测,那就是
procedure NewglGetFloatv(pname : GLenum; params : PGLfloat); stdcall;
begin
if pname = GL_DEPTH_RANGE then
begin
params[0] := 0.0;
params[1] := 1.0;
end
else
begin
OldglGetFloatv(pname, params);
end;
end;
OK,搞定
注册五年后第一次发帖噢
[课程]Android-CTF解题方法汇总!