mirror of
https://github.com/Artikash/Textractor.git
synced 2024-12-23 17:04:12 +08:00
fix bugs with admin rights and pipe connection, plus some refactors
This commit is contained in:
parent
8e40c71563
commit
c9a7a606cb
@ -33,8 +33,9 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::enable_if_t<sizeof(T) < PIPE_BUFFER_SIZE> Send(T data)
|
void Send(T data)
|
||||||
{
|
{
|
||||||
|
static_assert(sizeof(data) < PIPE_BUFFER_SIZE);
|
||||||
std::thread([=]
|
std::thread([=]
|
||||||
{
|
{
|
||||||
DWORD DUMMY;
|
DWORD DUMMY;
|
||||||
@ -75,15 +76,12 @@ namespace
|
|||||||
{
|
{
|
||||||
std::thread([]
|
std::thread([]
|
||||||
{
|
{
|
||||||
SECURITY_DESCRIPTOR pipeSD = {};
|
|
||||||
InitializeSecurityDescriptor(&pipeSD, SECURITY_DESCRIPTOR_REVISION);
|
|
||||||
SetSecurityDescriptorDacl(&pipeSD, TRUE, NULL, FALSE); // Allow non-admin processes to connect to pipe created by admin host
|
|
||||||
SECURITY_ATTRIBUTES pipeSA = { sizeof(pipeSA), &pipeSD, FALSE };
|
|
||||||
|
|
||||||
struct PipeCloser { void operator()(HANDLE h) { DisconnectNamedPipe(h); CloseHandle(h); } };
|
struct PipeCloser { void operator()(HANDLE h) { DisconnectNamedPipe(h); CloseHandle(h); } };
|
||||||
AutoHandle<PipeCloser>
|
AutoHandle<PipeCloser>
|
||||||
hookPipe = CreateNamedPipeW(HOOK_PIPE, PIPE_ACCESS_INBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, PIPE_UNLIMITED_INSTANCES, 0, PIPE_BUFFER_SIZE, MAXDWORD, &pipeSA),
|
hookPipe = CreateNamedPipeW(HOOK_PIPE, PIPE_ACCESS_INBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, PIPE_UNLIMITED_INSTANCES, 0, PIPE_BUFFER_SIZE, MAXDWORD, &allAccess),
|
||||||
hostPipe = CreateNamedPipeW(HOST_PIPE, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, 0, MAXDWORD, &pipeSA);
|
hostPipe = CreateNamedPipeW(HOST_PIPE, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, 0, MAXDWORD, &allAccess);
|
||||||
|
static AutoHandle<> pipeAvailableEvent = CreateEventW(&allAccess, FALSE, FALSE, PIPE_AVAILABLE_EVENT);
|
||||||
|
SetEvent(pipeAvailableEvent);
|
||||||
ConnectNamedPipe(hookPipe, nullptr);
|
ConnectNamedPipe(hookPipe, nullptr);
|
||||||
|
|
||||||
BYTE buffer[PIPE_BUFFER_SIZE] = {};
|
BYTE buffer[PIPE_BUFFER_SIZE] = {};
|
||||||
@ -171,8 +169,6 @@ namespace Host
|
|||||||
WinMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(processId));
|
WinMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(processId));
|
||||||
if (GetLastError() == ERROR_ALREADY_EXISTS) return AddConsoleOutput(ALREADY_INJECTED);
|
if (GetLastError() == ERROR_ALREADY_EXISTS) return AddConsoleOutput(ALREADY_INJECTED);
|
||||||
|
|
||||||
static std::wstring location = Util::GetModuleFilename(LoadLibraryExW(ITH_DLL, nullptr, DONT_RESOLVE_DLL_REFERENCES)).value();
|
|
||||||
|
|
||||||
if (AutoHandle<> process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId))
|
if (AutoHandle<> process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId))
|
||||||
{
|
{
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
@ -180,6 +176,7 @@ namespace Host
|
|||||||
IsWow64Process(process, &invalidProcess);
|
IsWow64Process(process, &invalidProcess);
|
||||||
if (invalidProcess) return AddConsoleOutput(ARCHITECTURE_MISMATCH);
|
if (invalidProcess) return AddConsoleOutput(ARCHITECTURE_MISMATCH);
|
||||||
#endif
|
#endif
|
||||||
|
static std::wstring location = Util::GetModuleFilename(LoadLibraryExW(ITH_DLL, nullptr, DONT_RESOLVE_DLL_REFERENCES)).value();
|
||||||
if (LPVOID remoteData = VirtualAllocEx(process, nullptr, (location.size() + 1) * sizeof(wchar_t), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))
|
if (LPVOID remoteData = VirtualAllocEx(process, nullptr, (location.size() + 1) * sizeof(wchar_t), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))
|
||||||
{
|
{
|
||||||
WriteProcessMemory(process, remoteData, location.c_str(), (location.size() + 1) * sizeof(wchar_t), nullptr);
|
WriteProcessMemory(process, remoteData, location.c_str(), (location.size() + 1) * sizeof(wchar_t), nullptr);
|
||||||
|
@ -78,9 +78,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
{
|
{
|
||||||
QSettings settings(CONFIG_FILE, QSettings::IniFormat);
|
QSettings(CONFIG_FILE, QSettings::IniFormat).setValue(WINDOW, geometry());
|
||||||
settings.setValue(WINDOW, geometry());
|
|
||||||
settings.sync();
|
|
||||||
SetErrorMode(SEM_NOGPFAULTERRORBOX);
|
SetErrorMode(SEM_NOGPFAULTERRORBOX);
|
||||||
ExitProcess(0);
|
ExitProcess(0);
|
||||||
}
|
}
|
||||||
|
@ -4,25 +4,11 @@
|
|||||||
// 8/23/2013 jichi
|
// 8/23/2013 jichi
|
||||||
// Branch: ITH/common.h, rev 128
|
// Branch: ITH/common.h, rev 128
|
||||||
|
|
||||||
enum { MESSAGE_SIZE = 500, PIPE_BUFFER_SIZE = 2000, SHIFT_JIS = 932, MAX_MODULE_SIZE = 120, HOOK_NAME_SIZE = 30 };
|
enum Misc { MESSAGE_SIZE = 500, PIPE_BUFFER_SIZE = 2000, SHIFT_JIS = 932, MAX_MODULE_SIZE = 120, HOOK_NAME_SIZE = 30, FIXED_SPLIT_VALUE = 0x10001 };
|
||||||
|
|
||||||
enum HostCommandType
|
enum HostCommandType { HOST_COMMAND_NEW_HOOK, HOST_COMMAND_REMOVE_HOOK, HOST_COMMAND_MODIFY_HOOK, HOST_COMMAND_HIJACK_PROCESS, HOST_COMMAND_DETACH };
|
||||||
{
|
|
||||||
HOST_COMMAND = -1, // null type
|
|
||||||
HOST_COMMAND_NEW_HOOK = 0,
|
|
||||||
HOST_COMMAND_REMOVE_HOOK = 1,
|
|
||||||
HOST_COMMAND_MODIFY_HOOK = 2,
|
|
||||||
HOST_COMMAND_HIJACK_PROCESS = 3,
|
|
||||||
HOST_COMMAND_DETACH = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
enum HostNotificationType
|
enum HostNotificationType { HOST_NOTIFICATION_TEXT, HOST_NOTIFICATION_NEWHOOK, HOST_NOTIFICATION_RMVHOOK };
|
||||||
{
|
|
||||||
HOST_NOTIFICATION = -1, // null type
|
|
||||||
HOST_NOTIFICATION_TEXT = 0,
|
|
||||||
HOST_NOTIFICATION_NEWHOOK = 1,
|
|
||||||
HOST_NOTIFICATION_RMVHOOK = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
enum HookParamType : unsigned
|
enum HookParamType : unsigned
|
||||||
{
|
{
|
||||||
@ -30,7 +16,7 @@ enum HookParamType : unsigned
|
|||||||
USING_UNICODE = 0x2, // type(data) is wchar_t or wchar_t*
|
USING_UNICODE = 0x2, // type(data) is wchar_t or wchar_t*
|
||||||
BIG_ENDIAN = 0x4, // type(data) is char
|
BIG_ENDIAN = 0x4, // type(data) is char
|
||||||
DATA_INDIRECT = 0x8,
|
DATA_INDIRECT = 0x8,
|
||||||
USING_SPLIT = 0x10, // aware of split time?
|
USING_SPLIT = 0x10, // use ctx2 or not
|
||||||
SPLIT_INDIRECT = 0x20,
|
SPLIT_INDIRECT = 0x20,
|
||||||
MODULE_OFFSET = 0x40, // address is relative to module
|
MODULE_OFFSET = 0x40, // address is relative to module
|
||||||
FUNCTION_OFFSET = 0x80, // address is relative to function
|
FUNCTION_OFFSET = 0x80, // address is relative to function
|
||||||
@ -43,5 +29,3 @@ enum HookParamType : unsigned
|
|||||||
HOOK_ENGINE = 0x4000,
|
HOOK_ENGINE = 0x4000,
|
||||||
HOOK_ADDITIONAL = 0x8000
|
HOOK_ADDITIONAL = 0x8000
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { FIXED_SPLIT_VALUE = 0x10001 }; // 6/1/2014: Fixed split value for hok parameter. Fuse all threads, and prevent floating
|
|
||||||
|
@ -14,9 +14,14 @@ constexpr auto HOST_PIPE = L"\\\\.\\pipe\\TEXTRACTOR_HOST";
|
|||||||
|
|
||||||
constexpr auto ITH_SECTION_ = L"VNR_SECTION_"; // _%d
|
constexpr auto ITH_SECTION_ = L"VNR_SECTION_"; // _%d
|
||||||
|
|
||||||
// Mutex
|
// Mutexes
|
||||||
|
|
||||||
constexpr auto ITH_HOOKMAN_MUTEX_ = L"VNR_HOOKMAN_"; // ITH_HOOKMAN_%d
|
constexpr auto ITH_HOOKMAN_MUTEX_ = L"VNR_HOOKMAN_"; // ITH_HOOKMAN_%d
|
||||||
|
constexpr auto CONNECTING_MUTEX = L"TEXTRACTOR_CONNECTING_PIPES";
|
||||||
|
|
||||||
|
// Events
|
||||||
|
|
||||||
|
constexpr auto PIPE_AVAILABLE_EVENT = L"TEXTRACTOR_PIPE_AVAILABLE";
|
||||||
|
|
||||||
// Files
|
// Files
|
||||||
|
|
||||||
@ -31,6 +36,14 @@ constexpr auto REPLACE_SAVE_FILE = u8"SavedReplacements.txt";
|
|||||||
|
|
||||||
constexpr auto DEFAULT_EXTENSIONS = u8"Remove Repetition>Lua>Copy to Clipboard>Bing Translate>Extra Window>Extra Newlines";
|
constexpr auto DEFAULT_EXTENSIONS = u8"Remove Repetition>Lua>Copy to Clipboard>Bing Translate>Extra Window>Extra Newlines";
|
||||||
|
|
||||||
|
inline SECURITY_ATTRIBUTES allAccess = std::invoke([] // allows non-admin processes to access kernel objects made by admin processes
|
||||||
|
{
|
||||||
|
static SECURITY_DESCRIPTOR sd = {};
|
||||||
|
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
|
||||||
|
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
|
||||||
|
return SECURITY_ATTRIBUTES{ sizeof(SECURITY_ATTRIBUTES), &sd, FALSE };
|
||||||
|
});
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
|
@ -48,6 +48,17 @@ private:
|
|||||||
std::unique_ptr<void, HandleCleaner> h;
|
std::unique_ptr<void, HandleCleaner> h;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WinMutex // Like CMutex but works with scoped_lock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WinMutex(std::wstring name = L"", LPSECURITY_ATTRIBUTES sa = nullptr) : m(CreateMutexW(sa, FALSE, name.empty() ? NULL : name.c_str())) {}
|
||||||
|
void lock() { if (m) WaitForSingleObject(m, INFINITE); }
|
||||||
|
void unlock() { if (m) ReleaseMutex(m); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
AutoHandle<> m;
|
||||||
|
};
|
||||||
|
|
||||||
// jichi 3/7/2014: Add guessed comment
|
// jichi 3/7/2014: Add guessed comment
|
||||||
struct HookParam
|
struct HookParam
|
||||||
{
|
{
|
||||||
@ -83,16 +94,6 @@ struct ThreadParam
|
|||||||
uint64_t ctx2; // The subcontext of the hook: 0 by default, generated in a method specific to the hook
|
uint64_t ctx2; // The subcontext of the hook: 0 by default, generated in a method specific to the hook
|
||||||
};
|
};
|
||||||
|
|
||||||
class WinMutex // Like CMutex but works with scoped_lock
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WinMutex(std::wstring name) : m(CreateMutexW(nullptr, FALSE, name.c_str())) {}
|
|
||||||
void lock() { if (m) WaitForSingleObject(m, INFINITE); }
|
|
||||||
void unlock() { if (m) ReleaseMutex(m); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
AutoHandle<> m;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct InsertHookCmd // From host
|
struct InsertHookCmd // From host
|
||||||
{
|
{
|
||||||
|
@ -10,12 +10,12 @@
|
|||||||
#include "texthook.h"
|
#include "texthook.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
std::unique_ptr<WinMutex> viewMutex;
|
WinMutex viewMutex;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
AutoHandle<> hookPipe = INVALID_HANDLE_VALUE, mappedFile = INVALID_HANDLE_VALUE;
|
AutoHandle<> hookPipe = INVALID_HANDLE_VALUE, mappedFile = INVALID_HANDLE_VALUE;
|
||||||
TextHook* hooks;
|
TextHook (*hooks)[MAX_HOOK];
|
||||||
bool running;
|
bool running;
|
||||||
int currentHook = 0;
|
int currentHook = 0;
|
||||||
DWORD DUMMY;
|
DWORD DUMMY;
|
||||||
@ -30,21 +30,16 @@ DWORD WINAPI Pipe(LPVOID)
|
|||||||
AutoHandle<> hostPipe = INVALID_HANDLE_VALUE;
|
AutoHandle<> hostPipe = INVALID_HANDLE_VALUE;
|
||||||
hookPipe = INVALID_HANDLE_VALUE;
|
hookPipe = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
while (!hookPipe || !hostPipe)
|
while (!hostPipe || !hookPipe)
|
||||||
{
|
{
|
||||||
if (!hookPipe)
|
WinMutex connectionMutex(CONNECTING_MUTEX, &allAccess);
|
||||||
{
|
std::scoped_lock lock(connectionMutex);
|
||||||
hookPipe = CreateFileW(HOOK_PIPE, GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
WaitForSingleObject(AutoHandle<>(CreateEventW(&allAccess, FALSE, FALSE, PIPE_AVAILABLE_EVENT)), INFINITE);
|
||||||
}
|
hostPipe = CreateFileW(HOST_PIPE, GENERIC_READ | FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
if (hookPipe && !hostPipe)
|
hookPipe = CreateFileW(HOOK_PIPE, GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
{
|
|
||||||
hostPipe = CreateFileW(HOST_PIPE, GENERIC_READ | FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
|
||||||
DWORD mode = PIPE_READMODE_MESSAGE;
|
|
||||||
SetNamedPipeHandleState(hostPipe, &mode, NULL, NULL);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Sleep(50);
|
|
||||||
}
|
}
|
||||||
|
DWORD mode = PIPE_READMODE_MESSAGE;
|
||||||
|
SetNamedPipeHandleState(hostPipe, &mode, NULL, NULL);
|
||||||
|
|
||||||
*(DWORD*)buffer = GetCurrentProcessId();
|
*(DWORD*)buffer = GetCurrentProcessId();
|
||||||
WriteFile(hookPipe, buffer, sizeof(DWORD), &count, nullptr);
|
WriteFile(hookPipe, buffer, sizeof(DWORD), &count, nullptr);
|
||||||
@ -69,7 +64,7 @@ DWORD WINAPI Pipe(LPVOID)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
hookPipe = INVALID_HANDLE_VALUE;
|
hookPipe = INVALID_HANDLE_VALUE;
|
||||||
for (int i = 0; i < MAX_HOOK; ++i) if (hooks[i].address) hooks[i].Clear();
|
for (auto& hook : *hooks) if (hook.address) hook.Clear();
|
||||||
FreeLibraryAndExitThread(GetModuleHandleW(ITH_DLL), 0);
|
FreeLibraryAndExitThread(GetModuleHandleW(ITH_DLL), 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -105,19 +100,19 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID)
|
|||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
{
|
{
|
||||||
viewMutex = std::make_unique<WinMutex>(ITH_HOOKMAN_MUTEX_ + std::to_wstring(GetCurrentProcessId()));
|
viewMutex = WinMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(GetCurrentProcessId()), &allAccess);
|
||||||
if (GetLastError() == ERROR_ALREADY_EXISTS) return FALSE;
|
if (GetLastError() == ERROR_ALREADY_EXISTS) return FALSE;
|
||||||
DisableThreadLibraryCalls(hModule);
|
DisableThreadLibraryCalls(hModule);
|
||||||
|
|
||||||
// jichi 9/25/2013: Interprocedural communication with vnrsrv.
|
// jichi 9/25/2013: Interprocedural communication with vnrsrv.
|
||||||
mappedFile = CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr, PAGE_EXECUTE_READWRITE, 0, HOOK_SECTION_SIZE, (ITH_SECTION_ + std::to_wstring(GetCurrentProcessId())).c_str());
|
mappedFile = CreateFileMappingW(INVALID_HANDLE_VALUE, &allAccess, PAGE_EXECUTE_READWRITE, 0, HOOK_SECTION_SIZE, (ITH_SECTION_ + std::to_wstring(GetCurrentProcessId())).c_str());
|
||||||
hooks = (TextHook*)MapViewOfFile(mappedFile, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, HOOK_BUFFER_SIZE);
|
hooks = (TextHook(*)[MAX_HOOK])MapViewOfFile(mappedFile, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, HOOK_BUFFER_SIZE);
|
||||||
memset(hooks, 0, HOOK_BUFFER_SIZE);
|
memset(hooks, 0, HOOK_BUFFER_SIZE);
|
||||||
|
|
||||||
MH_Initialize();
|
MH_Initialize();
|
||||||
running = true;
|
running = true;
|
||||||
|
|
||||||
CreateThread(nullptr, 0, Pipe, nullptr, 0, nullptr); // Using std::thread here = deadlock
|
CloseHandle(CreateThread(nullptr, 0, Pipe, nullptr, 0, nullptr)); // Using std::thread here = deadlock
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
@ -143,7 +138,7 @@ void NewHook(HookParam hp, LPCSTR lpname, DWORD flag)
|
|||||||
if (strlen(utf8Text) < 8 || strlen(codepageText) < 8 || wcslen(hp.text) < 4) return ConsoleOutput(NOT_ENOUGH_TEXT);
|
if (strlen(utf8Text) < 8 || strlen(codepageText) < 8 || wcslen(hp.text) < 4) return ConsoleOutput(NOT_ENOUGH_TEXT);
|
||||||
for (auto[addrs, type] : Array<std::tuple<std::vector<uint64_t>, HookParamType>>{
|
for (auto[addrs, type] : Array<std::tuple<std::vector<uint64_t>, HookParamType>>{
|
||||||
{ Util::SearchMemory(utf8Text, strlen(utf8Text), PAGE_READWRITE), USING_UTF8 },
|
{ Util::SearchMemory(utf8Text, strlen(utf8Text), PAGE_READWRITE), USING_UTF8 },
|
||||||
{ Util::SearchMemory(codepageText, strlen(codepageText), PAGE_READWRITE), (HookParamType)0 },
|
{ Util::SearchMemory(codepageText, strlen(codepageText), PAGE_READWRITE), USING_STRING },
|
||||||
{ Util::SearchMemory(hp.text, wcslen(hp.text) * 2, PAGE_READWRITE), USING_UNICODE }
|
{ Util::SearchMemory(hp.text, wcslen(hp.text) * 2, PAGE_READWRITE), USING_UNICODE }
|
||||||
})
|
})
|
||||||
for (auto addr : addrs)
|
for (auto addr : addrs)
|
||||||
@ -164,14 +159,13 @@ void NewHook(HookParam hp, LPCSTR lpname, DWORD flag)
|
|||||||
if (lpname && *lpname) strncpy_s(hp.name, lpname, HOOK_NAME_SIZE - 1);
|
if (lpname && *lpname) strncpy_s(hp.name, lpname, HOOK_NAME_SIZE - 1);
|
||||||
ConsoleOutput(INSERTING_HOOK, hp.name);
|
ConsoleOutput(INSERTING_HOOK, hp.name);
|
||||||
if (hp.address) RemoveHook(hp.address, 0);
|
if (hp.address) RemoveHook(hp.address, 0);
|
||||||
if (!hooks[currentHook].Insert(hp, flag)) ConsoleOutput(HOOK_FAILED);
|
if (!(*hooks)[currentHook].Insert(hp, flag)) ConsoleOutput(HOOK_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveHook(uint64_t addr, int maxOffset)
|
void RemoveHook(uint64_t addr, int maxOffset)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAX_HOOK; i++)
|
for (auto& hook : *hooks) if (abs((long long)(hook.address - addr)) <= maxOffset) return hook.Clear();
|
||||||
if (abs((long long)(hooks[i].address - addr)) <= maxOffset) return hooks[i].Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "ithsys/ithsys.h"
|
#include "ithsys/ithsys.h"
|
||||||
|
|
||||||
extern std::unique_ptr<WinMutex> viewMutex;
|
extern WinMutex viewMutex;
|
||||||
|
|
||||||
// - Unnamed helpers -
|
// - Unnamed helpers -
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ void SetTrigger()
|
|||||||
|
|
||||||
bool TextHook::Insert(HookParam h, DWORD set_flag)
|
bool TextHook::Insert(HookParam h, DWORD set_flag)
|
||||||
{
|
{
|
||||||
std::scoped_lock lock(*viewMutex);
|
std::scoped_lock lock(viewMutex);
|
||||||
hp = h;
|
hp = h;
|
||||||
address = hp.address;
|
address = hp.address;
|
||||||
hp.type |= set_flag;
|
hp.type |= set_flag;
|
||||||
@ -283,7 +283,7 @@ void TextHook::RemoveReadCode()
|
|||||||
|
|
||||||
void TextHook::Clear()
|
void TextHook::Clear()
|
||||||
{
|
{
|
||||||
std::scoped_lock lock(*viewMutex);
|
std::scoped_lock lock(viewMutex);
|
||||||
if (*hp.name) ConsoleOutput(REMOVING_HOOK, hp.name);
|
if (*hp.name) ConsoleOutput(REMOVING_HOOK, hp.name);
|
||||||
if (hp.type & DIRECT_READ) RemoveReadCode();
|
if (hp.type & DIRECT_READ) RemoveReadCode();
|
||||||
else RemoveHookCode();
|
else RemoveHookCode();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user