| 728 | |
| 729 | |
| 730 | void LibraryManager::FindCharacterStatFuncsEoCPlugin() |
| 731 | { |
| 732 | memset(&StatsGetters.Ptrs, 0, sizeof(StatsGetters.Ptrs)); |
| 733 | |
| 734 | Pattern p; |
| 735 | p.FromString( |
| 736 | "45 84 E4 " // test r12b, r12b |
| 737 | "74 09 " // jz short loc_1810554AD |
| 738 | "41 8B 87 64 03 00 00 " // mov eax, [r15+364h] |
| 739 | "EB 07 " // jmp short loc_1810554B4 |
| 740 | "41 8B 87 60 03 00 00 " // mov eax, [r15+360h] |
| 741 | "41 0F B6 D4 " // movzx edx, r12b |
| 742 | "89 47 44 " // mov [rdi+44h], eax |
| 743 | ); |
| 744 | |
| 745 | uint8_t const * gettersStart{ nullptr }; |
| 746 | p.Scan(moduleStart_, moduleSize_, [&gettersStart](const uint8_t * match) { |
| 747 | gettersStart = match; |
| 748 | }, false); |
| 749 | |
| 750 | if (gettersStart != nullptr) { |
| 751 | Pattern p2; |
| 752 | p2.FromString( |
| 753 | "49 8B CF " // mov rcx, r15 |
| 754 | "E8 XX XX XX XX " // call CDivinityStats_Character__Getxxx |
| 755 | ); |
| 756 | |
| 757 | unsigned ptrIndex = 0; |
| 758 | p2.Scan(gettersStart, 0x240, [this, &ptrIndex](const uint8_t * match) { |
| 759 | if (ptrIndex < std::size(StatsGetters.Ptrs)) { |
| 760 | auto ptr = AsmCallToAbsoluteAddress(match + 3); |
| 761 | StatsGetters.Ptrs[ptrIndex++] = (void *)ptr; |
| 762 | } |
| 763 | }); |
| 764 | } |
| 765 | |
| 766 | if (StatsGetters.Funcs.GetUnknown == nullptr) { |
| 767 | Debug("LibraryManager::FindCharacterStatFuncsEoCPlugin(): Could not find all stat getters"); |
| 768 | InitFailed = true; |
| 769 | } |
| 770 | } |
| 771 | } |
| 772 | #endif |
nothing calls this directly
no test coverage detected