diff --git a/metamod/msvc/metamod.vcxproj b/metamod/msvc/metamod.vcxproj index 892b93f..77621ad 100644 --- a/metamod/msvc/metamod.vcxproj +++ b/metamod/msvc/metamod.vcxproj @@ -247,6 +247,7 @@ + diff --git a/metamod/msvc/metamod.vcxproj.filters b/metamod/msvc/metamod.vcxproj.filters index da7aeac..b1c7484 100644 --- a/metamod/msvc/metamod.vcxproj.filters +++ b/metamod/msvc/metamod.vcxproj.filters @@ -9,6 +9,9 @@ {dfc6c7bb-cea4-43c5-bb1b-b8145cf93dd5} ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + {6da03b3e-ec77-465c-bdef-280206450268} + @@ -183,6 +186,9 @@ Resource Files + + Extra + diff --git a/metamod/src/callback_jit.cpp b/metamod/src/callback_jit.cpp index efd850b..c693eeb 100644 --- a/metamod/src/callback_jit.cpp +++ b/metamod/src/callback_jit.cpp @@ -140,7 +140,7 @@ void CForwardCallbackJIT::naked_main() jecxz(go_next_plugin); jnz(go_next_plugin); - if (&plug == &m_jitdata->plugins->front()) { // init + if (&plug == &m_jitdata->plugins->front()) { // init meta globals xor_(eax, eax); mov(dword_ptr[globals + mg_mres], MRES_IGNORED); mov(dword_ptr[globals + mg_prev_mres], eax); // MRES_UNSET @@ -154,12 +154,14 @@ void CForwardCallbackJIT::naked_main() call_func(ecx); + // update highest meta result mov(edx, dword_ptr[globals + mg_mres]); mov(ecx, dword_ptr[globals + mg_status]); cmp(edx, ecx); cmovg(ecx, edx); mov(dword_ptr[globals + mg_status], ecx); + // save return value if supercede if (m_jitdata->has_ret) { mov(ecx, dword_ptr[esp + over_ret]); cmp(edx, MRES_SUPERCEDE); @@ -170,20 +172,22 @@ void CForwardCallbackJIT::naked_main() L(go_next_plugin); } - // call original if need + // call original if it needed cmp(dword_ptr[globals + mg_status], MRES_SUPERCEDE); jz("skip_original"); { + // and present if (m_jitdata->pfn_original) { mov(ecx, m_jitdata->pfn_original); call_func(ecx); } + // store original return value if (m_jitdata->has_ret) { if (m_jitdata->pfn_original) mov(dword_ptr[esp + orig_ret], eax); else - mov(dword_ptr[esp + orig_ret], TRUE); // for should collide :/ + mov(dword_ptr[esp + orig_ret], TRUE); // fix for should collide :/ jmp("skip_supercede"); } @@ -219,7 +223,7 @@ void CForwardCallbackJIT::naked_main() jecxz(go_next_plugin); jnz(go_next_plugin); - if (&plug == &m_jitdata->plugins->front()) { // init + if (&plug == &m_jitdata->plugins->front()) { // init meta globals xor_(eax, eax); mov(dword_ptr[globals + mg_mres], MRES_IGNORED); mov(dword_ptr[globals + mg_prev_mres], eax); // MRES_UNSET @@ -233,12 +237,14 @@ void CForwardCallbackJIT::naked_main() call_func(ecx); + // update highest meta result mov(edx, dword_ptr[globals + mg_mres]); mov(ecx, dword_ptr[globals + mg_status]); cmp(ecx, edx); cmovl(ecx, edx); mov(dword_ptr[globals + mg_status], ecx); + // save return value if supercede if (m_jitdata->has_ret) { cmp(edx, MRES_SUPERCEDE); mov(ecx, dword_ptr[esp + over_ret]); @@ -255,11 +261,13 @@ void CForwardCallbackJIT::naked_main() call_func(ecx); } + // restore meta globals movaps(xmm0, xmmword_ptr[esp + mg_backup + sizeof(int) * 2]); movq(xmm1, qword_ptr[esp + mg_backup]); movaps(xmmword_ptr[globals], xmm0); movq(qword_ptr[globals + xmmreg_size], xmm1); + // setup return value and override it if needed if (m_jitdata->has_ret) { mov(eax, dword_ptr[esp + orig_ret]); cmp(dword_ptr[globals + mg_status], MRES_OVERRIDE); @@ -370,9 +378,9 @@ void CJit::clear_tramps() size_t CJit::is_callback_retaddr(uint32 addr) { if (m_callback_allocator.contain(addr)) { - // FF D1 call ecx - // 83 C4 20 add esp, 20h ; optional - // 8B 13 mov edx, [ebx] + // FF D1 call ecx + // 83 C4 20 add esp, 20h ; optional + // 8B 13 mov edx, [ebx] char *ptr = (char *)addr - 2; return mem_compare(ptr, "\xFF\xD1\x83\xC4", 4) || mem_compare(ptr, "\xFF\xD1\x8B\x13", 4); } diff --git a/metamod/src/metamod.cpp b/metamod/src/metamod.cpp index 2c447d9..eab9aad 100644 --- a/metamod/src/metamod.cpp +++ b/metamod/src/metamod.cpp @@ -439,28 +439,28 @@ static void meta_collect_fix_data(uint32* const esp, std::vector& dat char* raddr = (char *)*pret; size_t args_count = 0; - if ((raddr[0] == 0x83 && raddr[1] == 0xC4)) + if ((raddr[0] == 0x83 && raddr[1] == 0xC4)) // add esp, XX args_count = raddr[2] / 4; - // 8B 0D 4E 61 BC 00 mov ecx, ds : 0BC614Eh - // 80 3D 4E 61 BC 00 05 cmp byte ptr ds : 0BC614Eh, 5 + // 8B 0D 4E 61 BC 00 mov ecx, ds:0BC614Eh + // 80 3D 4E 61 BC 00 05 cmp byte ptr ds:0BC614Eh, 5 char pattern[] = "\x8B\x0D\x2A\x2A\x2A\x2A\x80\x3D"; // scan for callback addr do raddr--; while (!mem_compare(raddr, pattern, sizeof pattern - 1)); - uint32 callback = *(uint32 *)(raddr + 2); + uint32 callback = *(uint32 *)(raddr + 2); // mov ecx, [callback] data.push_back({pret, callback}); - // 0F 29 44 24 1C movaps xmmword ptr[esp + 1Ch], xmm0 - // 66 0F D6 4C 24 14 movq mmword ptr[esp + 14h], xmm1 + // 0F 29 44 24 1C movaps xmmword ptr [esp + 1Ch], xmm0 + // 66 0F D6 4C 24 14 movq mmword ptr [esp + 14h], xmm1 - // 0F 29 84 24 36 05 00 00 movaps xmmword ptr[esp + 536h], xmm0 - // 66 0F D6 8C 24 36 05 00 00 movq qword ptr[esp + 536h], xmm1 + // 0F 29 84 24 36 05 00 00 movaps xmmword ptr [esp + 536h], xmm0 + // 66 0F D6 8C 24 36 05 00 00 movq qword ptr [esp + 536h], xmm1 char pattern2[] = "\x66\x0F\xD6\x2A\x24"; - // scan for mg_backup + // scan for mg_backup at stack do raddr--; while (!mem_compare(raddr, pattern2, sizeof pattern2 - 1)); @@ -478,7 +478,7 @@ static void meta_collect_fix_data(uint32* const esp, std::vector& dat static void meta_apply_fix_data(std::vector& data) { for (auto& d : data) { - // 8B 0D 4E 61 BC 00 mov ecx, ds:0BC614Eh + // 8B 0D 4E 61 BC 00 mov ecx, ds:0BC614Eh char pattern[6] = "\x8B\x0D"; *(uint32 *)(pattern + 2) = d.callback; @@ -488,9 +488,9 @@ static void meta_apply_fix_data(std::vector& data) do_exit(666); } - // FF D1 call ecx - // 83 C4 20 add esp, 20h ; optional - // 8B 13 mov edx, [ebx] + // FF D1 call ecx + // 83 C4 20 add esp, 20h ; optional + // 8B 13 mov edx, [ebx] do ptr++; while (!mem_compare(ptr, "\xFF\xD1\x83\xC4", 4) && !mem_compare(ptr, "\xFF\xD1\x8B\x13", 4)); diff --git a/publish.gradle b/publish.gradle index 576b9ce..c4800af 100644 --- a/publish.gradle +++ b/publish.gradle @@ -74,11 +74,11 @@ task publishPrepareFiles << { } copy { from 'metamod/extra/example' - into 'publish/publishRoot/metamod/example' + into 'publish/publishRoot/metamod/example_plugin' } copy { from 'publish/publishRoot/metamod/sdk' - into 'publish/publishRoot/metamod/example/include/metamod' + into 'publish/publishRoot/metamod/example_plugin/include/metamod' } }