forked from Public-Mirror/Textractor
implement read code
This commit is contained in:
parent
9a299f357f
commit
ed4879ba5c
@ -71,7 +71,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
std::map<int, QString> extensions = LoadExtensions();
|
std::map<int, QString> extensions = LoadExtensions();
|
||||||
for (auto i : extensions) extenCombo->addItem(QString::number(i.first) + ":" + i.second);
|
for (auto i : extensions) extenCombo->addItem(QString::number(i.first) + ":" + i.second);
|
||||||
Host::Open();
|
Host::Open();
|
||||||
Host::AddConsoleOutput(L"NextHooker beta v2.0.2 by Artikash\r\nSource code and more information available under GPLv3 at https://github.com/Artikash/NextHooker");
|
Host::AddConsoleOutput(L"NextHooker beta v2.1.0 by Artikash\r\nSource code and more information available under GPLv3 at https://github.com/Artikash/NextHooker");
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
@ -95,7 +95,7 @@ void MainWindow::AddProcess(unsigned int processId)
|
|||||||
for (int j = 1; j < hooks.length(); ++j)
|
for (int j = 1; j < hooks.length(); ++j)
|
||||||
{
|
{
|
||||||
Sleep(10);
|
Sleep(10);
|
||||||
Host::InsertHook(processId, ParseHCode(hooks.at(j)));
|
Host::InsertHook(processId, ParseCode(hooks.at(j)));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -112,7 +112,7 @@ void MainWindow::AddThread(TextThread* thread)
|
|||||||
TextThreadString(thread) +
|
TextThreadString(thread) +
|
||||||
QString::fromWCharArray(Host::GetHookName(thread->GetThreadParameter().pid, thread->GetThreadParameter().hook).c_str()) +
|
QString::fromWCharArray(Host::GetHookName(thread->GetThreadParameter().pid, thread->GetThreadParameter().hook).c_str()) +
|
||||||
" (" +
|
" (" +
|
||||||
GenerateHCode(Host::GetHookParam(thread->GetThreadParameter().pid, thread->GetThreadParameter().hook), thread->GetThreadParameter().pid) +
|
GenerateCode(Host::GetHookParam(thread->GetThreadParameter().pid, thread->GetThreadParameter().hook), thread->GetThreadParameter().pid) +
|
||||||
")"
|
")"
|
||||||
);
|
);
|
||||||
thread->RegisterOutputCallBack([&](TextThread* thread, std::wstring output)
|
thread->RegisterOutputCallBack([&](TextThread* thread, std::wstring output)
|
||||||
@ -188,15 +188,15 @@ void MainWindow::on_detachButton_clicked()
|
|||||||
void MainWindow::on_hookButton_clicked()
|
void MainWindow::on_hookButton_clicked()
|
||||||
{
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
QString hookCode = QInputDialog::getText(this, "Add Hook", HCodeInfoDump, QLineEdit::Normal, "/H", &ok);
|
QString hookCode = QInputDialog::getText(this, "Add Hook", CodeInfoDump, QLineEdit::Normal, "", &ok);
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
HookParam toInsert = ParseHCode(hookCode);
|
HookParam toInsert = ParseCode(hookCode);
|
||||||
if (toInsert.type == 0 && toInsert.length_offset == 0)
|
if (toInsert.type == 0 && toInsert.length_offset == 0)
|
||||||
{
|
{
|
||||||
Host::AddConsoleOutput(L"invalid /H code");
|
Host::AddConsoleOutput(L"invalid code");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Host::InsertHook(processCombo->currentText().split(":")[0].toInt(), ParseHCode(hookCode));
|
Host::InsertHook(processCombo->currentText().split(":")[0].toInt(), ParseCode(hookCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_unhookButton_clicked()
|
void MainWindow::on_unhookButton_clicked()
|
||||||
@ -206,7 +206,7 @@ void MainWindow::on_unhookButton_clicked()
|
|||||||
for (auto i : hooks) hookList.push_back(
|
for (auto i : hooks) hookList.push_back(
|
||||||
QString::fromWCharArray(Host::GetHookName(processCombo->currentText().split(":")[0].toInt(), i.address).c_str()) +
|
QString::fromWCharArray(Host::GetHookName(processCombo->currentText().split(":")[0].toInt(), i.address).c_str()) +
|
||||||
": " +
|
": " +
|
||||||
GenerateHCode(i, processCombo->currentText().split(":")[0].toInt())
|
GenerateCode(i, processCombo->currentText().split(":")[0].toInt())
|
||||||
);
|
);
|
||||||
bool ok;
|
bool ok;
|
||||||
QString hook = QInputDialog::getItem(this, "Unhook", "Which hook to remove?", hookList, 0, false, &ok);
|
QString hook = QInputDialog::getItem(this, "Unhook", "Which hook to remove?", hookList, 0, false, &ok);
|
||||||
@ -219,7 +219,7 @@ void MainWindow::on_saveButton_clicked()
|
|||||||
QString hookList = GetFullModuleName(processCombo->currentText().split(":")[0].toInt());;
|
QString hookList = GetFullModuleName(processCombo->currentText().split(":")[0].toInt());;
|
||||||
for (auto i : hooks)
|
for (auto i : hooks)
|
||||||
if (!(i.type & HOOK_ENGINE))
|
if (!(i.type & HOOK_ENGINE))
|
||||||
hookList += " , " + GenerateHCode(i, processCombo->currentText().split(":")[0].toInt());
|
hookList += " , " + GenerateCode(i, processCombo->currentText().split(":")[0].toInt());
|
||||||
QFile file("SavedHooks.txt");
|
QFile file("SavedHooks.txt");
|
||||||
if (!file.open(QIODevice::Append | QIODevice::Text)) return;
|
if (!file.open(QIODevice::Append | QIODevice::Text)) return;
|
||||||
file.write((hookList + "\r\n").toUtf8());
|
file.write((hookList + "\r\n").toUtf8());
|
||||||
|
61
GUI/misc.cpp
61
GUI/misc.cpp
@ -40,12 +40,38 @@ DWORD Hash(QString module)
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HookParam ParseRCode(QString RCode)
|
||||||
|
{
|
||||||
|
HookParam hp = {};
|
||||||
|
switch (RCode.at(0).unicode())
|
||||||
|
{
|
||||||
|
case L'S':
|
||||||
|
break;
|
||||||
|
case L'Q':
|
||||||
|
hp.type |= USING_STRING | USING_UNICODE;
|
||||||
|
break;
|
||||||
|
case L'V':
|
||||||
|
hp.type |= USING_STRING | USING_UTF8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
RCode.remove(0, 1);
|
||||||
|
QRegExp stringGap("^\\-?[\\dA-F]+");
|
||||||
|
if (stringGap.indexIn(RCode) == -1) return {};
|
||||||
|
hp.offset = stringGap.cap(0).toInt(nullptr, 16);
|
||||||
|
RCode.remove(0, stringGap.cap(0).length());
|
||||||
|
if (RCode.at(0).unicode() != L'@') return {};
|
||||||
|
RCode.remove(0, 1);
|
||||||
|
QRegExp address("[\\dA-F]+$");
|
||||||
|
if (address.indexIn(RCode) == -1) return {};
|
||||||
|
hp.address = address.cap(1).toInt(nullptr, 16);
|
||||||
|
return hp;
|
||||||
|
}
|
||||||
|
|
||||||
HookParam ParseHCode(QString HCode)
|
HookParam ParseHCode(QString HCode)
|
||||||
{
|
{
|
||||||
HookParam hp = {};
|
HookParam hp = {};
|
||||||
HCode = HCode.toUpper();
|
|
||||||
if (!HCode.startsWith("/H")) return {};
|
|
||||||
HCode.remove(0, 2);
|
|
||||||
switch (HCode.at(0).unicode())
|
switch (HCode.at(0).unicode())
|
||||||
{
|
{
|
||||||
case L'S':
|
case L'S':
|
||||||
@ -120,6 +146,14 @@ HookParam ParseHCode(QString HCode)
|
|||||||
return hp;
|
return hp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HookParam ParseCode(QString code)
|
||||||
|
{
|
||||||
|
code = code.toUpper();
|
||||||
|
if (code.startsWith("/H")) return ParseHCode(code.remove(0, 2));
|
||||||
|
else if (code.startsWith("/R")) return ParseRCode(code.remove(0, 2));
|
||||||
|
else return {};
|
||||||
|
}
|
||||||
|
|
||||||
QString GenerateHCode(HookParam hp, DWORD processId)
|
QString GenerateHCode(HookParam hp, DWORD processId)
|
||||||
{
|
{
|
||||||
QString code = "/H";
|
QString code = "/H";
|
||||||
@ -183,3 +217,24 @@ QString GenerateHCode(HookParam hp, DWORD processId)
|
|||||||
code += QString::fromWCharArray(wcsrchr(buffer, L'\\') + 1);
|
code += QString::fromWCharArray(wcsrchr(buffer, L'\\') + 1);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString GenerateRCode(HookParam hp)
|
||||||
|
{
|
||||||
|
QString code = "/R";
|
||||||
|
if (hp.type & USING_UNICODE)
|
||||||
|
code += "Q";
|
||||||
|
else if (hp.type & USING_UTF8)
|
||||||
|
code += "V";
|
||||||
|
else
|
||||||
|
code += "S";
|
||||||
|
code += QString::number(hp.offset, 16);
|
||||||
|
code += "@";
|
||||||
|
code += QString::number(hp.address, 16);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GenerateCode(HookParam hp, DWORD processId)
|
||||||
|
{
|
||||||
|
if (hp.type & DIRECT_READ) return GenerateRCode(hp);
|
||||||
|
else return GenerateHCode(hp, processId);
|
||||||
|
}
|
||||||
|
15
GUI/misc.h
15
GUI/misc.h
@ -8,16 +8,21 @@
|
|||||||
QString GetFullModuleName(DWORD processId, HMODULE module = NULL);
|
QString GetFullModuleName(DWORD processId, HMODULE module = NULL);
|
||||||
QString GetModuleName(DWORD processId, HMODULE module = NULL);
|
QString GetModuleName(DWORD processId, HMODULE module = NULL);
|
||||||
QStringList GetAllProcesses();
|
QStringList GetAllProcesses();
|
||||||
HookParam ParseHCode(QString HCode);
|
HookParam ParseCode(QString HCode);
|
||||||
QString GenerateHCode(HookParam hp, DWORD processId);
|
QString GenerateCode(HookParam hp, DWORD processId);
|
||||||
|
|
||||||
static QString HCodeInfoDump =
|
static QString CodeInfoDump =
|
||||||
"Enter hook code\r\n /H{A|B|W|S|Q|V}[N]data_offset[*deref_offset1][:split_offset[*deref_offset2]]@addr[:module]\r\n\
|
"Enter hook code\r\n\
|
||||||
|
/H{A|B|W|S|Q|V}[N]data_offset[*deref_offset1][:split_offset[*deref_offset2]]@addr[:module]\r\n\
|
||||||
|
OR\r\n\
|
||||||
|
Enter read code\r\n\
|
||||||
|
/R{S|Q|V}string_gap@addr\r\n\
|
||||||
All numbers in hexadecimal\r\n\
|
All numbers in hexadecimal\r\n\
|
||||||
A/B: Shift-JIS char little/big endian\r\n\
|
A/B: Shift-JIS char little/big endian\r\n\
|
||||||
W: UTF-16 char\r\n\
|
W: UTF-16 char\r\n\
|
||||||
S/Q/V: Shift-JIS/UTF-16/UTF-8 string\r\n\
|
S/Q/V: Shift-JIS/UTF-16/UTF-8 string\r\n\
|
||||||
Negatives for data_offset/sub_offset refer to registers\r\n\
|
Negatives for data_offset/sub_offset refer to registers\r\n\
|
||||||
-4 for EAX, -8 for ECX, -C for EDX, -10 for EBX, -14 for ESP, -18 for EBP, -1C for ESI, -20 for EDI\r\n\
|
-4 for EAX, -8 for ECX, -C for EDX, -10 for EBX, -14 for ESP, -18 for EBP, -1C for ESI, -20 for EDI\r\n\
|
||||||
* means dereference pointer+deref_offset";
|
* means dereference pointer+deref_offset\r\n\r\n\
|
||||||
|
Use 0 for string_gap if string is in same location every time";
|
||||||
#endif // MISC_H
|
#endif // MISC_H
|
||||||
|
@ -43,8 +43,10 @@ struct HookParam {
|
|||||||
recover_len; // ?
|
recover_len; // ?
|
||||||
|
|
||||||
// 7/20/2014: jichi additional parameters for PSP games
|
// 7/20/2014: jichi additional parameters for PSP games
|
||||||
DWORD user_flags,
|
DWORD user_value;
|
||||||
user_value;
|
|
||||||
|
// Artikash 8/4/2018: handle for reader thread
|
||||||
|
HANDLE readerHandle;
|
||||||
};
|
};
|
||||||
|
|
||||||
// jichi 6/1/2014: Structure of the esp for extern functions
|
// jichi 6/1/2014: Structure of the esp for extern functions
|
||||||
|
@ -16694,11 +16694,6 @@ void SpecialPSPHook(DWORD esp_base, HookParam *hp, BYTE, DWORD *data, DWORD *spl
|
|||||||
LPCSTR text = LPCSTR(offset + hp->user_value);
|
LPCSTR text = LPCSTR(offset + hp->user_value);
|
||||||
static LPCSTR lasttext;
|
static LPCSTR lasttext;
|
||||||
if (*text) {
|
if (*text) {
|
||||||
if (hp->user_flags & HPF_IgnoreSameAddress) {
|
|
||||||
if (text == lasttext)
|
|
||||||
return;
|
|
||||||
lasttext = text;
|
|
||||||
}
|
|
||||||
*data = (DWORD)text;
|
*data = (DWORD)text;
|
||||||
// I only considered SHIFT-JIS/UTF-8 case
|
// I only considered SHIFT-JIS/UTF-8 case
|
||||||
if (hp->length_offset == 1)
|
if (hp->length_offset == 1)
|
||||||
@ -17451,7 +17446,6 @@ bool InsertImageepochPSPHook()
|
|||||||
hp.type = USING_STRING|USING_SPLIT|NO_CONTEXT; // UTF-8, though
|
hp.type = USING_STRING|USING_SPLIT|NO_CONTEXT; // UTF-8, though
|
||||||
hp.offset = pusha_eax_off - 4;
|
hp.offset = pusha_eax_off - 4;
|
||||||
hp.split = pusha_ecx_off - 4;
|
hp.split = pusha_ecx_off - 4;
|
||||||
hp.user_flags = HPF_IgnoreSameAddress;
|
|
||||||
//hp.text_fun = SpecialPSPHook;
|
//hp.text_fun = SpecialPSPHook;
|
||||||
hp.text_fun = SpecialPSPHookImageepoch; // since this function is common, use its own static lasttext for HPF_IgnoreSameAddress
|
hp.text_fun = SpecialPSPHookImageepoch; // since this function is common, use its own static lasttext for HPF_IgnoreSameAddress
|
||||||
ConsoleOutput("vnreng: Imageepoch PSP: INSERT");
|
ConsoleOutput("vnreng: Imageepoch PSP: INSERT");
|
||||||
|
@ -316,9 +316,11 @@ DWORD TextHook::UnsafeSend(DWORD dwDataBase, DWORD dwRetn)
|
|||||||
|
|
||||||
int TextHook::InsertHook()
|
int TextHook::InsertHook()
|
||||||
{
|
{
|
||||||
|
int ok = 1;
|
||||||
//ConsoleOutput("vnrcli:InsertHook: enter");
|
//ConsoleOutput("vnrcli:InsertHook: enter");
|
||||||
WaitForSingleObject(hmMutex, 0);
|
WaitForSingleObject(hmMutex, 0);
|
||||||
int ok = InsertHookCode();
|
if (hp.type & DIRECT_READ) ok = InsertReadCode();
|
||||||
|
else ok = InsertHookCode();
|
||||||
ReleaseMutex(hmMutex);
|
ReleaseMutex(hmMutex);
|
||||||
//ConsoleOutput("vnrcli:InsertHook: leave");
|
//ConsoleOutput("vnrcli:InsertHook: leave");
|
||||||
return ok;
|
return ok;
|
||||||
@ -326,7 +328,6 @@ int TextHook::InsertHook()
|
|||||||
|
|
||||||
int TextHook::InsertHookCode()
|
int TextHook::InsertHookCode()
|
||||||
{
|
{
|
||||||
enum : int { yes = 0, no = 1 };
|
|
||||||
DWORD ret = no;
|
DWORD ret = no;
|
||||||
// jichi 9/17/2013: might raise 0xC0000005 AccessViolationException on win7
|
// jichi 9/17/2013: might raise 0xC0000005 AccessViolationException on win7
|
||||||
ITH_WITH_SEH(ret = UnsafeInsertHookCode());
|
ITH_WITH_SEH(ret = UnsafeInsertHookCode());
|
||||||
@ -335,10 +336,76 @@ int TextHook::InsertHookCode()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD WINAPI ReaderThread(LPVOID threadParam)
|
||||||
|
{
|
||||||
|
TextHook* hook = (TextHook*)threadParam;
|
||||||
|
BYTE buffer[PIPE_BUFFER_SIZE] = {};
|
||||||
|
char testChar;
|
||||||
|
unsigned int changeCount = 0;
|
||||||
|
const char* currentAddress = (char*)hook->hp.address;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
Sleep(50);
|
||||||
|
if (testChar == *currentAddress)
|
||||||
|
{
|
||||||
|
changeCount = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
testChar = *currentAddress;
|
||||||
|
if (++changeCount > 10)
|
||||||
|
{
|
||||||
|
ConsoleOutput("NextHooker: memory constantly changing, useless to read");
|
||||||
|
ConsoleOutput("NextHooker: remove read code");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dataLen;
|
||||||
|
if (hook->hp.type & USING_UNICODE)
|
||||||
|
dataLen = wcslen((const wchar_t*)currentAddress) * 2;
|
||||||
|
else
|
||||||
|
dataLen = strlen(currentAddress);
|
||||||
|
|
||||||
|
*(DWORD*)buffer = hook->hp.address;
|
||||||
|
*(DWORD*)(buffer + 4) = 0;
|
||||||
|
*(DWORD*)(buffer + 8) = 0;
|
||||||
|
memcpy(buffer + HEADER_SIZE, currentAddress, dataLen);
|
||||||
|
DWORD unused;
|
||||||
|
WriteFile(::hookPipe, buffer, dataLen + HEADER_SIZE, &unused, nullptr);
|
||||||
|
|
||||||
|
if (hook->hp.offset == 0) continue;
|
||||||
|
currentAddress += dataLen + hook->hp.offset;
|
||||||
|
testChar = *currentAddress;
|
||||||
|
}
|
||||||
|
hook->ClearHook();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TextHook::InsertReadCode()
|
||||||
|
{
|
||||||
|
hp.hook_len = 0x40;
|
||||||
|
//Check if the new hook range conflict with existing ones. Clear older if conflict.
|
||||||
|
TextHook *it = hookman;
|
||||||
|
for (int i = 0; i < currentHook; it++) {
|
||||||
|
if (it->Address())
|
||||||
|
i++;
|
||||||
|
if (it == this)
|
||||||
|
continue;
|
||||||
|
if ((it->Address() >= hp.address && it->Address() < hp.hook_len + hp.address) || (it->Address() <= hp.address && it->Address() + it->Length() > hp.address))
|
||||||
|
it->ClearHook();
|
||||||
|
}
|
||||||
|
if (!IthGetMemoryRange((LPCVOID)hp.address, 0, 0))
|
||||||
|
{
|
||||||
|
ConsoleOutput("cannot access read address");
|
||||||
|
return no;
|
||||||
|
}
|
||||||
|
hp.readerHandle = CreateThread(nullptr, 0, ReaderThread, this, 0, nullptr);
|
||||||
|
return yes;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int TextHook::UnsafeInsertHookCode()
|
int TextHook::UnsafeInsertHookCode()
|
||||||
{
|
{
|
||||||
//ConsoleOutput("vnrcli:UnsafeInsertHookCode: enter");
|
//ConsoleOutput("vnrcli:UnsafeInsertHookCode: enter");
|
||||||
enum : int { yes = 0, no = 1 };
|
|
||||||
if (hp.module && (hp.type & MODULE_OFFSET)) { // Map hook offset to real address.
|
if (hp.module && (hp.type & MODULE_OFFSET)) { // Map hook offset to real address.
|
||||||
if (DWORD base = GetModuleBase(hp.module)) {
|
if (DWORD base = GetModuleBase(hp.module)) {
|
||||||
hp.address += base;
|
hp.address += base;
|
||||||
@ -467,29 +534,36 @@ int TextHook::InitHook(const HookParam &h, LPCSTR name, WORD set_flag)
|
|||||||
|
|
||||||
int TextHook::RemoveHookCode()
|
int TextHook::RemoveHookCode()
|
||||||
{
|
{
|
||||||
enum : int { yes = 1, no = 0 };
|
|
||||||
if (!hp.address)
|
if (!hp.address)
|
||||||
return no;
|
return no;
|
||||||
ConsoleOutput("vnrcli:RemoveHook: enter");
|
|
||||||
WaitForSingleObject(hmMutex, TIMEOUT); // jichi 9/28/2012: wait at most for 5 seconds
|
|
||||||
DWORD l = hp.hook_len;
|
DWORD l = hp.hook_len;
|
||||||
//with_seh({ // jichi 9/17/2013: might crash ><
|
//with_seh({ // jichi 9/17/2013: might crash ><
|
||||||
// jichi 12/25/2013: Actually, __try cannot catch such kind of exception
|
// jichi 12/25/2013: Actually, __try cannot catch such kind of exception
|
||||||
ITH_TRY {
|
ITH_TRY {
|
||||||
NtWriteVirtualMemory(GetCurrentProcess(), (LPVOID)hp.address, original, hp.recover_len, &l);
|
NtWriteVirtualMemory(GetCurrentProcess(), (LPVOID)hp.address, original, hp.recover_len, &l);
|
||||||
NtFlushInstructionCache(GetCurrentProcess(), (LPVOID)hp.address, hp.recover_len);
|
NtFlushInstructionCache(GetCurrentProcess(), (LPVOID)hp.address, hp.recover_len);
|
||||||
} ITH_EXCEPT {}
|
}
|
||||||
|
ITH_EXCEPT {}
|
||||||
//});
|
//});
|
||||||
hp.hook_len = 0;
|
|
||||||
ReleaseMutex(hmMutex);
|
|
||||||
ConsoleOutput("vnrcli:RemoveHook: leave");
|
|
||||||
return yes;
|
return yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TextHook::RemoveReadCode()
|
||||||
|
{
|
||||||
|
if (!hp.address) return no;
|
||||||
|
TerminateThread(hp.readerHandle, 0);
|
||||||
|
CloseHandle(hp.readerHandle);
|
||||||
|
return yes;
|
||||||
|
}
|
||||||
|
|
||||||
int TextHook::ClearHook()
|
int TextHook::ClearHook()
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
WaitForSingleObject(hmMutex, 0);
|
WaitForSingleObject(hmMutex, 0);
|
||||||
int err = RemoveHookCode();
|
ConsoleOutput("vnrcli:RemoveHook: enter");
|
||||||
|
if (hp.type & DIRECT_READ) err = RemoveReadCode();
|
||||||
|
else err = RemoveHookCode();
|
||||||
NotifyHookRemove(hp.address);
|
NotifyHookRemove(hp.address);
|
||||||
if (hook_name) {
|
if (hook_name) {
|
||||||
delete[] hook_name;
|
delete[] hook_name;
|
||||||
@ -499,6 +573,7 @@ int TextHook::ClearHook()
|
|||||||
//if (current_available>this)
|
//if (current_available>this)
|
||||||
// current_available = this;
|
// current_available = this;
|
||||||
currentHook--;
|
currentHook--;
|
||||||
|
ConsoleOutput("vnrcli:RemoveHook: leave");
|
||||||
ReleaseMutex(hmMutex);
|
ReleaseMutex(hmMutex);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,11 @@ void InitFilterTable();
|
|||||||
class TextHook : public Hook
|
class TextHook : public Hook
|
||||||
{
|
{
|
||||||
int InsertHookCode();
|
int InsertHookCode();
|
||||||
|
int InsertReadCode();
|
||||||
int UnsafeInsertHookCode();
|
int UnsafeInsertHookCode();
|
||||||
DWORD UnsafeSend(DWORD dwDataBase, DWORD dwRetn);
|
DWORD UnsafeSend(DWORD dwDataBase, DWORD dwRetn);
|
||||||
int RemoveHookCode();
|
int RemoveHookCode();
|
||||||
|
int RemoveReadCode();
|
||||||
int SetHookName(LPCSTR name);
|
int SetHookName(LPCSTR name);
|
||||||
public:
|
public:
|
||||||
int InsertHook();
|
int InsertHook();
|
||||||
@ -71,4 +73,6 @@ DWORD WINAPI PipeManager(LPVOID unused);
|
|||||||
void CliLockPipe();
|
void CliLockPipe();
|
||||||
void CliUnlockPipe();
|
void CliUnlockPipe();
|
||||||
|
|
||||||
|
enum : int { yes = 0, no = 1 };
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
Loading…
x
Reference in New Issue
Block a user