@@ -165,6 +165,8 @@ namespace sdk {
165165 return ;
166166 }
167167
168+ sdk::RETypeDB* tdb = nullptr ;
169+
168170 for (auto i = 0 ; i < 0x20000 ; i += sizeof (void *)) {
169171 auto ptr = *(sdk::RETypeDB**)((uintptr_t )*potential_context + i);
170172
@@ -173,6 +175,7 @@ namespace sdk {
173175 }
174176
175177 if (*(uint32_t *)ptr == *(uint32_t *)" TDB" ) {
178+ tdb = ptr;
176179 const auto version = *(uint32_t *)((uintptr_t )ptr + 4 );
177180
178181 s_tdb_version = version;
@@ -286,6 +289,93 @@ namespace sdk {
286289 48 8B CF mov rcx, rdi
287290 */
288291
292+ auto alternative_invoke_scan = [&]() -> bool {
293+ auto tdb_references = utility::scan_displacement_references (mod, (uintptr_t )tdb);
294+
295+ if (tdb_references.empty ()) {
296+ spdlog::info (" [VM::update_pointers] Unable to find TDB references." );
297+ return false ;
298+ }
299+
300+ for (const auto & ref : tdb_references) {
301+ const auto fn_start = utility::find_function_start (ref);
302+
303+ if (!fn_start) {
304+ continue ;
305+ }
306+
307+ spdlog::info (" [VM::update_pointers] Disassembling function at {:x}" , *fn_start);
308+
309+ bool found = false ;
310+
311+ utility::exhaustive_decode ((uint8_t *)*fn_start, 1000 , [&](utility::ExhaustionContext& ctx) -> utility::ExhaustionResult {
312+ if (found) {
313+ return utility::ExhaustionResult::BREAK ;
314+ }
315+
316+ if (std::string_view{ctx.instrux .Mnemonic } == " CALL" ) {
317+ return utility::ExhaustionResult::STEP_OVER ;
318+ }
319+
320+ if (std::string_view{ctx.instrux .Mnemonic } != " LEA" ) {
321+ return utility::ExhaustionResult::CONTINUE ;
322+ }
323+
324+ const auto disp = utility::resolve_displacement (ctx.addr );
325+
326+ if (!disp) {
327+ return utility::ExhaustionResult::CONTINUE ;
328+ }
329+
330+ try {
331+ uintptr_t * functions = (uintptr_t *)*disp;
332+
333+ // First pointer must always be null
334+ if (functions[0 ] != 0 ) {
335+ return utility::ExhaustionResult::CONTINUE ;
336+ }
337+
338+ // Rest of pointers are not null and point somewhere within the game module
339+ for (auto i = 1 ; i < 100 ; ++i) {
340+ if (functions[i] == 0 || IsBadReadPtr (&functions[i], sizeof (void *))) {
341+ return utility::ExhaustionResult::CONTINUE ;
342+ }
343+
344+ if (utility::get_module_within (functions[i]).value_or (nullptr ) != mod) {
345+ return utility::ExhaustionResult::CONTINUE ;
346+ }
347+
348+ /* const auto ptr_fn_start = utility::find_function_start(functions[i]);
349+
350+ if (!ptr_fn_start) {
351+ return utility::ExhaustionResult::CONTINUE;
352+ }
353+
354+ if (*ptr_fn_start != functions[i]) {
355+ break;
356+ }*/
357+ }
358+
359+ s_invoke_tbl = (sdk::InvokeMethod*)functions;
360+ found = true ;
361+
362+ spdlog::info (" [VM::update_pointers] s_invoke_tbl: {:x}" , (uintptr_t )s_invoke_tbl);
363+
364+ return utility::ExhaustionResult::BREAK ;
365+ } catch (...) {
366+ return utility::ExhaustionResult::CONTINUE ;
367+ }
368+
369+ return utility::ExhaustionResult::CONTINUE ;
370+ });
371+
372+ if (found) {
373+ return true ;
374+ }
375+ }
376+
377+ return false ;
378+ };
289379
290380 std::optional<uintptr_t > method_inside_invoke_tbl{std::nullopt };
291381
@@ -297,19 +387,32 @@ namespace sdk {
297387 break ;
298388 }
299389 }
390+
300391 if (!method_inside_invoke_tbl) {
301392 spdlog::info (" [VM::update_pointers] Unable to find method inside invoke table. Trying fallback scan..." );
302393 const auto anchor = utility::scan (mod, " 8D 56 FF 48 8B CF E8 ? ? ? ?" );
303394
304395 if (!anchor) {
305- spdlog::info (" [VM::update_pointers] Unable to find anchor for invoke table." );
396+ spdlog::info (" [VM::update_pointers] Unable to find anchor for invoke table, trying alternative scan..." );
397+
398+ if (!alternative_invoke_scan ()) {
399+ spdlog::info (" [VM::update_pointers] Unable to find invoke table." );
400+ return ;
401+ }
402+
306403 return ;
307404 }
308405
309406 const auto lea_rdx = utility::scan_reverse (*anchor, 0x100 , " 48 8D 15 ? ? ? ?" );
310407
311408 if (!lea_rdx) {
312409 spdlog::info (" [VM::update_pointers] Unable to find lea rdx for invoke table." );
410+
411+ if (!alternative_invoke_scan ()) {
412+ spdlog::info (" [VM::update_pointers] Unable to find invoke table." );
413+ return ;
414+ }
415+
313416 return ;
314417 }
315418
@@ -326,6 +429,12 @@ namespace sdk {
326429
327430 if (!ptr_inside_invoke_tbl) {
328431 spdlog::info (" [VM::update_pointers] Unable to find ptr inside invoke table." );
432+
433+ if (!alternative_invoke_scan ()) {
434+ spdlog::info (" [VM::update_pointers] Unable to find invoke table." );
435+ return ;
436+ }
437+
329438 return ;
330439 }
331440
0 commit comments