Merge branch 'master' of github.com:goatcorp/Dalamud

This commit is contained in:
goat 2022-08-24 18:48:42 +02:00
commit 8867133de3
No known key found for this signature in database
GPG key ID: 49E2AA8C6A76498B
5 changed files with 48 additions and 25 deletions

View file

@ -348,6 +348,27 @@ utils::signature_finder& utils::signature_finder::look_for_hex(std::string_view
return *this; return *this;
} }
const char* utils::signature_finder::result::resolve_jump_target(size_t instructionOffset) const {
nmd_x86_instruction instruction{};
if (!nmd_x86_decode(&Match[instructionOffset], NMD_X86_MAXIMUM_INSTRUCTION_LENGTH, &instruction, NMD_X86_MODE_64, NMD_X86_DECODER_FLAGS_ALL))
throw std::runtime_error("Matched address does not have a valid assembly instruction");
size_t numExplicitOperands = 0;
for (size_t i = 0; i < instruction.num_operands; i++)
numExplicitOperands += instruction.operands[i].is_implicit ? 0 : 1;
if (numExplicitOperands != 1)
throw std::runtime_error("Number of operands at the instruction at matched address is not 1");
if (!(instruction.group & NMD_GROUP_CALL) && !(instruction.group & NMD_GROUP_JUMP))
throw std::runtime_error("The instruction at matched address is not a call or jump instruction");
const auto& arg1 = instruction.operands[0];
if (arg1.type != NMD_X86_OPERAND_TYPE_IMMEDIATE)
throw std::runtime_error("The first operand for the instruction at matched address is not an immediate value");
return &Match[instructionOffset] + instruction.length + arg1.fields.imm;
}
std::vector<utils::signature_finder::result> utils::signature_finder::find(size_t minCount, size_t maxCount, bool bErrorOnMoreThanMaximum) const { std::vector<utils::signature_finder::result> utils::signature_finder::find(size_t minCount, size_t maxCount, bool bErrorOnMoreThanMaximum) const {
std::vector<result> res; std::vector<result> res;
@ -383,8 +404,8 @@ std::vector<utils::signature_finder::result> utils::signature_finder::find(size_
return res; return res;
} }
std::span<const char> utils::signature_finder::find_one() const { utils::signature_finder::result utils::signature_finder::find_one() const {
return find(1, 1, false).front().Match; return find(1, 1, false).front();
} }
utils::memory_tenderizer::memory_tenderizer(const void* pAddress, size_t length, DWORD dwNewProtect) : m_data(reinterpret_cast<char*>(const_cast<void*>(pAddress)), length) { utils::memory_tenderizer::memory_tenderizer(const void* pAddress, size_t length, DWORD dwNewProtect) : m_data(reinterpret_cast<char*>(const_cast<void*>(pAddress)), length) {

View file

@ -96,11 +96,18 @@ namespace utils {
size_t PatternIndex; size_t PatternIndex;
size_t MatchIndex; size_t MatchIndex;
size_t CaptureIndex; size_t CaptureIndex;
const char* resolve_jump_target(size_t instructionOffset = 0) const;
template<typename T>
T resolve_jump_target(size_t instructionOffset = 0) const {
return reinterpret_cast<T>(const_cast<char*>(resolve_jump_target(instructionOffset)));
}
}; };
std::vector<result> find(size_t minCount, size_t maxCount, bool bErrorOnMoreThanMaximum) const; std::vector<result> find(size_t minCount, size_t maxCount, bool bErrorOnMoreThanMaximum) const;
std::span<const char> find_one() const; result find_one() const;
}; };
class memory_tenderizer { class memory_tenderizer {

View file

@ -169,26 +169,11 @@ static TFnGetInputDeviceManager* GetGetInputDeviceManager(HWND hwnd) {
if (pCached) if (pCached)
return pCached; return pCached;
char szClassName[256]; return pCached = utils::signature_finder()
GetClassNameA(hwnd, szClassName, static_cast<int>(sizeof szClassName));
WNDCLASSEXA wcx{};
GetClassInfoExA(g_hGameInstance, szClassName, &wcx);
const auto match = utils::signature_finder()
.look_in(utils::loaded_module(g_hGameInstance), ".text") .look_in(utils::loaded_module(g_hGameInstance), ".text")
.look_for_hex("41 81 fe 19 02 00 00 0f 87 ?? ?? 00 00 0f 84 ?? ?? 00 00") .look_for_hex("e8 ?? ?? ?? ?? 48 8b 58 10 48 85 db")
.find_one(); .find_one()
.resolve_jump_target<TFnGetInputDeviceManager*>();
auto ptr = match.data() + match.size() + *reinterpret_cast<const int*>(match.data() + match.size() - 4);
ptr += 4; // CMP RBX, 0x7
ptr += 2; // JNZ <giveup>
ptr += 7; // MOV RCX, <Framework::Instance>
ptr += 3; // TEST RCX, RCX
ptr += 2; // JZ <giveup>
ptr += 5; // CALL <GetInputDeviceManagerInstance()>
ptr += *reinterpret_cast<const int*>(ptr - 4);
return pCached = reinterpret_cast<TFnGetInputDeviceManager*>(ptr);
} }
void xivfixes::prevent_devicechange_crashes(bool bApply) { void xivfixes::prevent_devicechange_crashes(bool bApply) {
@ -202,9 +187,13 @@ void xivfixes::prevent_devicechange_crashes(bool bApply) {
static const auto s_pfnBinder = static_cast<WNDPROC>(VirtualAlloc(nullptr, 64, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE)); static const auto s_pfnBinder = static_cast<WNDPROC>(VirtualAlloc(nullptr, 64, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE));
static const auto s_pfnAlternativeWndProc = static_cast<WNDPROC>([](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -> LRESULT { static const auto s_pfnAlternativeWndProc = static_cast<WNDPROC>([](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -> LRESULT {
if (uMsg == WM_DEVICECHANGE && wParam == DBT_DEVNODES_CHANGED) { if (uMsg == WM_DEVICECHANGE && wParam == DBT_DEVNODES_CHANGED) {
if (!GetGetInputDeviceManager(hWnd)()) { try {
logging::I("{} WndProc(0x{:X}, WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, {}) called but the game does not have InputDeviceManager initialized; doing nothing.", LogTag, reinterpret_cast<size_t>(hWnd), lParam); if (!GetGetInputDeviceManager(hWnd)()) {
return 0; logging::I("{} WndProc(0x{:X}, WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, {}) called but the game does not have InputDeviceManager initialized; doing nothing.", LogTag, reinterpret_cast<size_t>(hWnd), lParam);
return 0;
}
} catch (const std::exception& e) {
logging::W("{} WndProc(0x{:X}, WM_DEVICECHANGE, DBT_DEVNODES_CHANGED, {}) called, but failed to resolve address for GetInputDeviceManager: {}", LogTag, reinterpret_cast<size_t>(hWnd), lParam, e.what());
} }
} }

View file

@ -454,5 +454,9 @@ namespace Dalamud.Game.Text.SeStringHandling
/// The Garlemald region icon. /// The Garlemald region icon.
/// </summary> /// </summary>
Garlemald = 115, Garlemald = 115,
/// <summary>
/// The Island Sanctuary icon.
IslandSanctuary = 116,
} }
} }

View file

@ -258,6 +258,8 @@ internal partial class PluginManager : IDisposable, IServiceType
if (configuration.HiddenPluginInternalName.Contains(manifest.InternalName)) if (configuration.HiddenPluginInternalName.Contains(manifest.InternalName))
return false; return false;
return true; // TODO temporary
// Hidden by manifest // Hidden by manifest
return !manifest.IsHide; return !manifest.IsHide;
} }