@@ -573,6 +573,8 @@ void Engine_FillAddress_GL_Init(const mh_dll_info_t& DllInfo, const mh_dll_info_
573573 if (gPrivateFuncs.GL_Init)
574574 return;
575575
576+ PVOID GL_Init_VA = NULL;
577+
576578 {
577579 const char pattern[] = "\x68\x00\x1F\x00\x00\xFF";
578580 PUCHAR SearchBegin = (PUCHAR)DllInfo.TextBase;
@@ -666,7 +668,8 @@ void Engine_FillAddress_GL_Init(const mh_dll_info_t& DllInfo, const mh_dll_info_
666668
667669 if (ctx.bFoundPushString)
668670 {
669- gPrivateFuncs.GL_Init = (decltype(gPrivateFuncs.GL_Init))ConvertDllInfoSpace(pCandidateFunction, DllInfo, RealDllInfo);
671+ GL_Init_VA = pCandidateFunction;
672+
670673 break;
671674 }
672675 }
@@ -679,6 +682,73 @@ void Engine_FillAddress_GL_Init(const mh_dll_info_t& DllInfo, const mh_dll_info_
679682 }
680683 }
681684 }
685+
686+ if (GL_Init_VA)
687+ {
688+ gPrivateFuncs.GL_Init = (decltype(gPrivateFuncs.GL_Init))ConvertDllInfoSpace(GL_Init_VA, DllInfo, RealDllInfo);
689+
690+ // 在 GL_Init 中定位 gl_extensions
691+ // 模式: push 0x1F03 (GL_EXTENSIONS) -> call glGetString -> mov [imm32], eax
692+ if (!gl_extensions && !gPrivateFuncs.SDL_GL_GetProcAddress)
693+ {
694+ typedef struct GL_Init_ExtSearch_s
695+ {
696+ const mh_dll_info_t& DllInfo;
697+ const mh_dll_info_t& RealDllInfo;
698+ PUCHAR push_GL_EXTENSIONS_address{};
699+ int push_GL_EXTENSIONS_instCount{};
700+ }GL_Init_ExtSearch;
701+
702+ GL_Init_ExtSearch extCtx = { DllInfo, RealDllInfo };
703+
704+ g_pMetaHookAPI->DisasmRanges(GL_Init_VA, 0x120, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) {
705+
706+ auto pinst = (cs_insn*)inst;
707+ auto ctx = (GL_Init_ExtSearch*)context;
708+
709+ if (gl_extensions)
710+ return TRUE;
711+
712+ // 检测 push 0x1F03 (GL_EXTENSIONS)
713+ if (pinst->id == X86_INS_PUSH &&
714+ pinst->detail->x86.op_count == 1 &&
715+ pinst->detail->x86.operands[0].type == X86_OP_IMM &&
716+ pinst->detail->x86.operands[0].imm == 0x1F03)
717+ {
718+ ctx->push_GL_EXTENSIONS_address = address;
719+ ctx->push_GL_EXTENSIONS_instCount = instCount;
720+ }
721+
722+ // 检测 mov [mem], eax 在 push GL_EXTENSIONS 之后
723+ if (ctx->push_GL_EXTENSIONS_address &&
724+ address > ctx->push_GL_EXTENSIONS_address &&
725+ address < ctx->push_GL_EXTENSIONS_address + 0x30 &&
726+ instCount > ctx->push_GL_EXTENSIONS_instCount &&
727+ instCount < ctx->push_GL_EXTENSIONS_instCount + 10 &&
728+ pinst->id == X86_INS_MOV &&
729+ pinst->detail->x86.op_count == 2 &&
730+ pinst->detail->x86.operands[0].type == X86_OP_MEM &&
731+ pinst->detail->x86.operands[0].mem.base == 0 &&
732+ pinst->detail->x86.operands[0].mem.index == 0 &&
733+ pinst->detail->x86.operands[1].type == X86_OP_REG &&
734+ pinst->detail->x86.operands[1].reg == X86_REG_EAX &&
735+ (PUCHAR)pinst->detail->x86.operands[0].mem.disp >(PUCHAR)ctx->DllInfo.DataBase &&
736+ (PUCHAR)pinst->detail->x86.operands[0].mem.disp < (PUCHAR)ctx->DllInfo.DataBase + ctx->DllInfo.DataSize)
737+ {
738+ gl_extensions = (decltype(gl_extensions))ConvertDllInfoSpace((PVOID)pinst->detail->x86.operands[0].mem.disp, ctx->DllInfo, ctx->RealDllInfo);
739+ }
740+
741+ if (address[0] == 0xCC)
742+ return TRUE;
743+
744+ if (pinst->id == X86_INS_RET)
745+ return TRUE;
746+
747+ return FALSE;
748+
749+ }, 0, &extCtx);
750+ }
751+ }
682752
683753 Sig_FuncNotFound(GL_Init);
684754}
@@ -918,6 +988,7 @@ void Engine_FillAddress_GL_SetMode(const mh_dll_info_t& DllInfo, const mh_dll_in
918988 {
919989 Sig_FuncNotFound(GL_SetMode_call_qwglCreateContext);
920990 }
991+
921992 Sig_VarNotFound(gl_extensions);
922993
923994 if ((g_iEngineType == ENGINE_GOLDSRC || g_iEngineType == ENGINE_GOLDSRC_HL25) &&
0 commit comments