diff --git a/gui/CustomFilter.cpp b/gui/CustomFilter.cpp new file mode 100644 index 0000000..9fe03f0 --- /dev/null +++ b/gui/CustomFilter.cpp @@ -0,0 +1,44 @@ +/* Copyright (C) 2010-2012 kaosu (qiupf2000@gmail.com) + * This file is part of the Interactive Text Hooker. + + * Interactive Text Hooker is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "CustomFilter.h" + +void CustomFilter::Insert(WORD number) +{ + set.insert(number); +} + +void CustomFilter::Erase(WORD number) +{ + set.erase(number); +} + +bool CustomFilter::Find(WORD number) const +{ + return set.find(number) != set.end(); +} + +void CustomFilter::Clear() +{ + set.clear(); +} + +void CustomFilter::Traverse(CustomFilterCallBack callback, PVOID param) +{ + for (auto ch = set.begin(); ch != set.end(); ++ch) + callback(*ch, param); +} diff --git a/gui/CustomFilter.h b/gui/CustomFilter.h new file mode 100644 index 0000000..4bdcbc4 --- /dev/null +++ b/gui/CustomFilter.h @@ -0,0 +1,33 @@ +/* Copyright (C) 2010-2012 kaosu (qiupf2000@gmail.com) + * This file is part of the Interactive Text Hooker. + + * Interactive Text Hooker is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include "ITH.h" + +typedef void (*CustomFilterCallBack) (WORD, PVOID); + +class CustomFilter +{ +public: + bool Find(WORD number) const; + void Insert(WORD number); + void Erase(WORD number); + void Clear(); + void Traverse(CustomFilterCallBack callback, PVOID param); +private: + std::set set; +}; diff --git a/gui/ITH.h b/gui/ITH.h new file mode 100644 index 0000000..0873862 --- /dev/null +++ b/gui/ITH.h @@ -0,0 +1,37 @@ +/* Copyright (C) 2010-2012 kaosu (qiupf2000@gmail.com) + * This file is part of the Interactive Text Hooker. + + * Interactive Text Hooker is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pugixml.hpp" +#pragma warning(disable: 4146) diff --git a/gui/ITHVNR.rc b/gui/ITHVNR.rc new file mode 100644 index 0000000..d008fee --- /dev/null +++ b/gui/ITHVNR.rc @@ -0,0 +1,67 @@ +// Generated by ResEdit 1.6.3 +// Copyright (C) 2006-2014 +// http://www.resedit.net + +#include +#include +#include +#include "resource.h" + +#define WC_LISTVIEW L"SysListView32" + + + + + +// +// Dialog resources +// +LANGUAGE LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN +IDD_DIALOG2 DIALOGEX 100, 100, 341, 210 +STYLE DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU +CAPTION "Process Explorer" +FONT 8, "MS Shell Dlg", 400, 0, 1 +{ + DEFPUSHBUTTON "OK", IDOK, 281, 189, 53, 14, 0, WS_EX_LEFT + PUSHBUTTON "Remove Profile", IDC_BUTTON6, 226, 189, 53, 14, 0, WS_EX_LEFT + CONTROL "", IDC_LIST1, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | LVS_REPORT, 7, 20, 327, 164, WS_EX_LEFT + LTEXT "Process", IDC_STATIC, 7, 7, 65, 13, SS_LEFT | SS_CENTERIMAGE, WS_EX_LEFT + PUSHBUTTON "Attach", IDC_BUTTON2, 61, 189, 53, 14, 0, WS_EX_LEFT + PUSHBUTTON "Detach", IDC_BUTTON3, 116, 189, 53, 14, 0, WS_EX_LEFT + PUSHBUTTON "Add Profile", IDC_BUTTON5, 171, 189, 53, 14, 0, WS_EX_LEFT + PUSHBUTTON "Refresh", IDC_BUTTON1, 7, 189, 53, 14, 0, WS_EX_LEFT +} + + + +LANGUAGE LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN +IDD_DIALOG4 DIALOGEX 150, 100, 123, 185 +STYLE DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU +CAPTION "Option" +FONT 8, "MS Shell Dlg", 400, 0, 1 +{ + DEFPUSHBUTTON "OK", IDOK, 8, 164, 50, 14, 0, WS_EX_LEFT + PUSHBUTTON "Cancel", IDCANCEL, 65, 164, 50, 14, 0, WS_EX_LEFT + EDITTEXT IDC_EDIT1, 60, 7, 55, 14, ES_AUTOHSCROLL, WS_EX_LEFT + LTEXT "Split time", IDC_STATIC, 7, 7, 47, 13, SS_LEFT | SS_CENTERIMAGE, WS_EX_LEFT + EDITTEXT IDC_EDIT2, 60, 25, 55, 14, ES_AUTOHSCROLL, WS_EX_LEFT + LTEXT "Process delay", IDC_STATIC, 7, 26, 47, 13, SS_LEFT | SS_CENTERIMAGE, WS_EX_LEFT + EDITTEXT IDC_EDIT3, 60, 45, 55, 14, ES_AUTOHSCROLL, WS_EX_LEFT + LTEXT "Inject delay", IDC_STATIC, 7, 45, 47, 13, SS_LEFT | SS_CENTERIMAGE, WS_EX_LEFT + EDITTEXT IDC_EDIT4, 60, 65, 55, 14, ES_AUTOHSCROLL, WS_EX_LEFT + LTEXT "Insert delay", IDC_STATIC, 7, 65, 47, 13, SS_LEFT | SS_CENTERIMAGE, WS_EX_LEFT + AUTOCHECKBOX "Auto attach", IDC_CHECK1, 7, 87, 54, 10, 0, WS_EX_LEFT + AUTOCHECKBOX "Auto insert", IDC_CHECK2, 62, 87, 50, 10, 0, WS_EX_LEFT + AUTOCHECKBOX "Auto copy to clipboard", IDC_CHECK3, 7, 103, 88, 10, 0, WS_EX_LEFT + AUTOCHECKBOX "Auto suppress repetition", IDC_CHECK4, 7, 119, 95, 10, 0, WS_EX_LEFT + AUTOCHECKBOX "Reset character filter", IDC_CHECK6, 7, 149, 81, 8, 0, WS_EX_LEFT + AUTOCHECKBOX "Enable global filter", IDC_CHECK5, 7, 134, 75, 10, 0, WS_EX_LEFT +} + + + +// +// Icon resources +// +LANGUAGE LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN +IDI_ICON1 ICON "icon1.ico" diff --git a/gui/command.cpp b/gui/command.cpp new file mode 100644 index 0000000..f7e6b5f --- /dev/null +++ b/gui/command.cpp @@ -0,0 +1,214 @@ +/* Copyright (C) 2010-2012 kaosu (qiupf2000@gmail.com) + * This file is part of the Interactive Text Hooker. + + * Interactive Text Hooker is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "ITH.h" +#include "ith/host/srv.h" +#include "ith/common/const.h" +#include "ith/common/types.h" +#include "language.h" +#include "utility.h" + +extern HookManager* man; +extern HWND hwndProcessComboBox; + +bool Parse(const std::wstring& cmd, HookParam& hp) +{ + using std::wregex; + using std::regex_search; + // /H[X]{A|B|W|S|Q}[N][data_offset[*drdo]][:sub_offset[*drso]]@addr[:[module[:{name|#ordinal}]]] + wregex rx(L"^X?([ABWSQ])(N)?", wregex::icase); + std::match_results m; + auto start = cmd.begin(); + auto end = cmd.end(); + bool result = regex_search(start, end, m, rx); + if (!result) + return result; + start = m[0].second; + if (m[2].matched) + hp.type |= NO_CONTEXT; + + switch (m[1].first[0]) + { + case L's': + case L'S': + hp.type |= USING_STRING; + break; + case L'e': + case L'E': + hp.type |= STRING_LAST_CHAR; + case L'a': + case L'A': + hp.type |= BIG_ENDIAN; + hp.length_offset = 1; + break; + case L'b': + case L'B': + hp.length_offset = 1; + break; + case L'h': + case L'H': + hp.type |= PRINT_DWORD; + case L'q': + case L'Q': + hp.type |= USING_STRING | USING_UNICODE; + break; + case L'l': + case L'L': + hp.type |= STRING_LAST_CHAR; + case L'w': + case L'W': + hp.type |= USING_UNICODE; + hp.length_offset = 1; + break; + default: + break; + } + + // [data_offset[*drdo]] + std::wstring data_offset(L"(-?[[:xdigit:]]+)"), drdo(L"(\\*-?[[:xdigit:]]+)?"); + rx = wregex(L"^"+ data_offset + drdo, wregex::icase); + result = regex_search(start, end, m, rx); + if (result) + { + start = m[0].second; + hp.off = std::stoul(m[1].str(), NULL, 16); + if (m[2].matched) + { + hp.type |= DATA_INDIRECT; + hp.ind = std::stoul(m[2].str().substr(1), NULL, 16); + } + } + + // [:sub_offset[*drso]] + std::wstring sub_offset(L"(-?[[:xdigit:]]+)"), drso(L"(\\*-?[[:xdigit:]]+)?"); + rx = wregex(L"^:" + sub_offset + drso, wregex::icase); + result = regex_search(start, end, m, rx); + if (result) + { + start = m[0].second; + hp.type |= USING_SPLIT; + hp.split = std::stoul(m[1].str(), NULL, 16); + if (m[2].matched) + { + hp.type |= SPLIT_INDIRECT; + hp.split_ind = std::stoul(m[2].str().substr(1), NULL, 16); + } + } + // @addr + rx = wregex(L"^@[[:xdigit:]]+", wregex::icase); + result = regex_search(start, end, m, rx); + if (!result) + return false; + start = m[0].second; + hp.addr = std::stoul(m[0].str().substr(1), NULL, 16); + if (hp.off & 0x80000000) + hp.off -= 4; + if (hp.split & 0x80000000) + hp.split -= 4; + + // [:[module[:{name|#ordinal}]]] + // ":" -> + // "" -> MODULE_OFFSET && module == NULL && function == addr + // ":GDI.dll" -> MODULE_OFFSET && module != NULL + // ":GDI.dll:strlen" -> MODULE_OFFSET | FUNCTION_OFFSET && module != NULL && function != NULL + // ":GDI.dll:#123" -> MODULE_OFFSET | FUNCTION_OFFSET && module != NULL && function != NULL + std::wstring module(L"([[:graph:]]+)"), name(L"[[:graph:]]+"), ordinal(L"\\d+"); + rx = wregex(L"^:(" + module + L"(:" + name + L"|#" + ordinal + L")?)?$", wregex::icase); + result = regex_search(start, end, m, rx); + if (result) // :[module[:{name|#ordinal}]] + { + if (m[1].matched) // module + { + hp.type |= MODULE_OFFSET; + std::wstring module = m[2]; + std::transform(module.begin(), module.end(), module.begin(), ::towlower); + hp.module = Hash(module); + if (m[3].matched) // :name|#ordinal + { + hp.type |= FUNCTION_OFFSET; + hp.function = Hash(m[3].str().substr(1)); + } + } + } + else + { + rx = wregex(L"^!([[:xdigit:]]+)(!([[:xdigit:]]+))?$", wregex::icase); + result = regex_search(start, end, m, rx); + if (result) + { + hp.type |= MODULE_OFFSET; + hp.module = std::stoul(m[1].str(), NULL, 16); + if (m[2].matched) + { + hp.type |= FUNCTION_OFFSET; + hp.function = std::stoul(m[2].str().substr(1), NULL, 16); + } + } + else + { + hp.type |= MODULE_OFFSET; + hp.function = hp.addr; + } + } + return true; +} + +DWORD ProcessCommand(const std::wstring& cmd, DWORD pid) +{ + using std::wregex; + using std::regex_match; + std::match_results m; + + if (regex_match(cmd, m, wregex(L"/pn(.+)", wregex::icase))) + { + pid = IHF_GetPIDByName(m[1].str().c_str()); + if (pid == 0) + return 0; + IHF_InjectByPID(pid); + } + else if (regex_match(cmd, m, wregex(L"/p(\\d+)", wregex::icase))) + { + pid = std::stoul(m[1].str()); + IHF_InjectByPID(pid); + } + else if (regex_match(cmd, m, wregex (L"/h(.+)", wregex::icase))) + { + HookParam hp = {}; + if (Parse(m[1].str(), hp)) + IHF_InsertHook(pid, &hp); + } + else if (regex_match(cmd, m, wregex(L":l([[:xdigit:]]+)-([[:xdigit:]]+)", wregex::icase))) + { + DWORD from = std::stoul(m[1].str(), NULL, 16); + DWORD to = std::stoul(m[2].str(), NULL, 16); + IHF_AddLink(from, to); + } + else if (regex_match(cmd, m, wregex(L":u([[:xdigit:]]+)", wregex::icase))) + { + DWORD from = std::stoul(m[1].str(), NULL, 16); + IHF_UnLink(from); + } + else if (regex_match(cmd, m, wregex(L":(?:h|help)", wregex::icase))) + { + ConsoleOutput(Usage); + } + else + { + ConsoleOutput(L"Unknown command. Type :h or :help for help."); + } + return 0; +} diff --git a/gui/icon1.ico b/gui/icon1.ico new file mode 100644 index 0000000..bfc3455 Binary files /dev/null and b/gui/icon1.ico differ diff --git a/gui/pugiconfig.hpp b/gui/pugiconfig.hpp new file mode 100644 index 0000000..6965d4c --- /dev/null +++ b/gui/pugiconfig.hpp @@ -0,0 +1,72 @@ +/** + * pugixml parser - version 1.5 + * -------------------------------------------------------- + * Copyright (C) 2006-2014, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) + * Report bugs and download new versions at http://pugixml.org/ + * + * This library is distributed under the MIT License. See notice at the end + * of this file. + * + * This work is based on the pugxml parser, which is: + * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) + */ + +#ifndef HEADER_PUGICONFIG_HPP +#define HEADER_PUGICONFIG_HPP + +// Uncomment this to enable wchar_t mode +#define PUGIXML_WCHAR_MODE + +// Uncomment this to disable XPath +// #define PUGIXML_NO_XPATH + +// Uncomment this to disable STL +// #define PUGIXML_NO_STL + +// Uncomment this to disable exceptions +// #define PUGIXML_NO_EXCEPTIONS + +// Set this to control attributes for public classes/functions, i.e.: +// #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL +// #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL +// #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall +// In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead + +// Tune these constants to adjust memory-related behavior +// #define PUGIXML_MEMORY_PAGE_SIZE 32768 +// #define PUGIXML_MEMORY_OUTPUT_STACK 10240 +// #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096 + +// Uncomment this to switch to header-only version +// #define PUGIXML_HEADER_ONLY +// #include "pugixml.cpp" + +// Uncomment this to enable long long support +// #define PUGIXML_HAS_LONG_LONG + +#endif + +/** + * Copyright (c) 2006-2014 Arseny Kapoulkine + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ diff --git a/vnr/winseh/winseh_unsafe.pri b/vnr/winseh/winseh_unsafe.pri new file mode 100644 index 0000000..4b2a567 --- /dev/null +++ b/vnr/winseh/winseh_unsafe.pri @@ -0,0 +1,18 @@ +# winseh_unsafe.pri +# 12/13/2013 jichi +# +# Need compile with /SAFESEH:NO +# See: http://stackoverflow.com/questions/19722308/exception-handler-not-called-in-c +#CONFIG += nosafeseh +win32 { +DEFINES += WITH_LIB_WINSEH + +DEPENDPATH += $$PWD + +HEADERS += $$PWD/winseh.h +SOURCES += \ + $$PWD/winseh.cc \ + $$PWD/winseh_unsafe.cc +} + +# EOF diff --git a/vnr/winversion/winversion.cc b/vnr/winversion/winversion.cc new file mode 100644 index 0000000..4a1a3ad --- /dev/null +++ b/vnr/winversion/winversion.cc @@ -0,0 +1,30 @@ +// winversion.cc +// 9/5/2014 jichi + +#include "winversion/winversion.h" +#include + +// http://stackoverflow.com/questions/940707/how-do-i-programatically-get-the-version-of-a-dll-or-exe-file +bool WinVersion::queryFileVersion(const wchar_t *path, int ver[]) +{ + bool ok = false; + // get the version info for the file requested + if (DWORD dwSize = ::GetFileVersionInfoSizeW(path, nullptr)) { + UINT len = 0; + BYTE *buf = new BYTE[dwSize]; + VS_FIXEDFILEINFO *info = nullptr; + ok = ::GetFileVersionInfoW(path, 0, dwSize, buf) + && ::VerQueryValueW(buf, L"\\", (LPVOID*)&info, &len) + && info; + if (ok) { + ver[0] = HIWORD(info->dwFileVersionMS), + ver[1] = LOWORD(info->dwFileVersionMS), + ver[2] = HIWORD(info->dwFileVersionLS), + ver[3] = LOWORD(info->dwFileVersionLS); + } + delete[] buf; + } + return ok; +} + +// EOF diff --git a/vnr/winversion/winversion.h b/vnr/winversion/winversion.h new file mode 100644 index 0000000..4bff0d0 --- /dev/null +++ b/vnr/winversion/winversion.h @@ -0,0 +1,16 @@ +#pragma once + +// winversion.h +// 9/5/2014 jichi + +#ifdef _MSC_VER +# include // for wchar_t +#endif // _MSC_VER + +namespace WinVersion { + +bool queryFileVersion(const wchar_t *path, int ver[4]); + +} // namespace WinVersion + +// EOF diff --git a/vnr/winversion/winversion.pri b/vnr/winversion/winversion.pri new file mode 100644 index 0000000..96b4a6b --- /dev/null +++ b/vnr/winversion/winversion.pri @@ -0,0 +1,14 @@ +# winversion.pri +# 9/5/2014 jichi +win32 { +DEFINES += WITH_LIB_WINVERSION + +LIBS += -lversion + +DEPENDPATH += $$PWD + +HEADERS += $$PWD/winversion.h +SOURCES += $$PWD/winversion.cc +} + +# EOF