diff --git a/GUI/mainwindow.cpp b/GUI/mainwindow.cpp index 8bb472a..a2c6b38 100644 --- a/GUI/mainwindow.cpp +++ b/GUI/mainwindow.cpp @@ -180,7 +180,7 @@ void MainWindow::on_hookButton_clicked() { bool ok; QString hookCode = QInputDialog::getText(this, "Add Hook", - "Enter hook code\r\n/H{A|B|W|S|Q}[N]data_offset[*drdo][:sub_offset[*drso]]@addr[:module]", + "Enter hook code\r\n/H{A|B|W|S|Q|V}[N]data_offset[*drdo][:sub_offset[*drso]]@addr[:module]", QLineEdit::Normal, "/H", &ok ); if (!ok) return; diff --git a/GUI/misc.cpp b/GUI/misc.cpp index 01580ff..fc4336f 100644 --- a/GUI/misc.cpp +++ b/GUI/misc.cpp @@ -65,6 +65,9 @@ HookParam ParseHCode(QString HCode) hp.type |= USING_UNICODE; hp.length_offset = 1; break; + case L'V': + hp.type |= USING_STRING | USING_UTF8; + break; default: return {}; } @@ -129,7 +132,9 @@ QString GenerateHCode(HookParam hp, DWORD processId) } else { - if (hp.type & USING_STRING) + if (hp.type & USING_UTF8) + code += "V"; + else if (hp.type & USING_STRING) code += "S"; else if (hp.type & BIG_ENDIAN) code += "A"; diff --git a/texthook/textthread.cc b/texthook/textthread.cc index 4da5160..2c00329 100644 --- a/texthook/textthread.cc +++ b/texthook/textthread.cc @@ -54,6 +54,12 @@ void TextThread::AddSentence() { sentence = std::wstring((wchar_t*)sentenceBuffer.data(), sentenceBuffer.size() / 2); } + else if (status & USING_UTF8) + { + wchar_t* converted = new wchar_t[sentenceBuffer.size()]; + sentence = std::wstring(converted, MultiByteToWideChar(CP_UTF8, 0, sentenceBuffer.data(), sentenceBuffer.size(), converted, sentenceBuffer.size())); + delete[] converted; + } else { wchar_t* converted = new wchar_t[sentenceBuffer.size()]; diff --git a/vnrhook/include/const.h b/vnrhook/include/const.h index 1edabd5..0966e3c 100644 --- a/vnrhook/include/const.h +++ b/vnrhook/include/const.h @@ -91,7 +91,6 @@ enum HostNotificationType { // - 0x100 enum HookParamType : unsigned long { USING_STRING = 0x1 // type(data) is char* or wchar_t* and has length - , USING_UTF8 = USING_STRING // jichi 10/21/2014: temporarily handled the same way as USING_STRING , USING_UNICODE = 0x2 // type(data) is wchar_t or wchar_t* , BIG_ENDIAN = 0x4 // type(data) is char , DATA_INDIRECT = 0x8 @@ -99,8 +98,7 @@ enum HookParamType : unsigned long { , SPLIT_INDIRECT = 0x20 , MODULE_OFFSET = 0x40 // do hash module, and the address is relative to module , FUNCTION_OFFSET = 0x80 // do hash function, and the address is relative to funccion - , PRINT_DWORD = 0x100 // jichi 12/7/2014: Removed - , NO_ASCII = 0x100 // jichi 1l/22/2015: Skip ascii characters + , USING_UTF8 = 0x100 , STRING_LAST_CHAR = 0x200 , NO_CONTEXT = 0x400 , HOOK_EMPTY = 0x800 diff --git a/vnrhook/src/engine/engine.cc b/vnrhook/src/engine/engine.cc index efed52f..65e7da9 100644 --- a/vnrhook/src/engine/engine.cc +++ b/vnrhook/src/engine/engine.cc @@ -16464,6 +16464,16 @@ static void SpecialHookMonoString(DWORD esp_base, HookParam *hp, BYTE, DWORD *da } } +bool NoAsciiFilter(LPVOID data, DWORD *size, HookParam *, BYTE) +{ + auto text = reinterpret_cast(data); + if (text) + for (size_t i = 0; i < *size; i++) + if (text[i] > 127) + return true; + return false; +} + bool InsertMonoHooks() { HMODULE h = ::GetModuleHandleA("mono.dll"); @@ -16481,7 +16491,8 @@ bool InsertMonoHooks() const auto &it = funcs[i]; if (FARPROC addr = ::GetProcAddress(h, it.functionName)) { hp.address = (DWORD)addr; - hp.type = it.hookType|NO_ASCII; // 11/27/2015: Disable ascii string + hp.type = it.hookType; + hp.filter_fun = NoAsciiFilter; hp.offset = it.textIndex * 4; hp.length_offset = it.lengthIndex * 4; hp.text_fun = (HookParam::text_fun_t)it.text_fun; diff --git a/vnrhook/src/hijack/texthook.cc b/vnrhook/src/hijack/texthook.cc index 6dd86a7..16ff21e 100644 --- a/vnrhook/src/hijack/texthook.cc +++ b/vnrhook/src/hijack/texthook.cc @@ -292,17 +292,6 @@ int ProcessHook(DWORD dwDataBase, DWORD dwRetn, TextHook *hook) // Use SEH to en } #endif // 1 -// Return false if all text are ascii -bool NoAsciiFilter(LPVOID data, DWORD *size, HookParam *, BYTE) -{ - auto text = reinterpret_cast(data); - if (text) - for (size_t i = 0; i < *size; i++) - if (text[i] > 127) - return true; - return false; -} - } // unnamed namespace // - TextHook methods - @@ -339,11 +328,7 @@ DWORD TextHook::UnsafeSend(DWORD dwDataBase, DWORD dwRetn) BYTE *pbData, pbSmallBuff[SMALL_BUFF_SIZE]; DWORD dwType = hp.type; - //if ((dwType & NO_CONTEXT) == 0 && HookFilter(dwRetn)) - // return 0; - if ((dwType & NO_ASCII) && !hp.filter_fun) - hp.filter_fun = NoAsciiFilter; // jichi 10/24/2014: Skip GDI functions // Artikash 6/3/2018: ^ why??