mireado

update to 3.5640.1

update to ITHVNR 3.5640.1
and translation
Showing 140 changed files with 3558 additions and 705 deletions
1 -# common.pri
2 -# DEFINES += _CRT_NON_CONFORMING_SWPRINTFS
3 -
4 -# config.pri
5 -# win32 {
6 -# DEFINES += _SECURE_SCL=0 _SCL_SECURE_NO_WARNINGS
7 -# DEFINES += _CRT_SECURE_NO_WARNINGS
8 -# QMAKE_CXXFLAGS += -wd4819
9 -# }
10 -
11 -# config.pri
12 -# win32 {
13 -# CONFIG(nocrt) {
14 -# message(CONFIG nocrt)
15 -# QMAKE_CFLAGS -= /MD /MDd
16 -# QMAKE_CFLAGS_DEBUG -= /MD /MDd
17 -# QMAKE_CFLAGS_RELEASE -= /MD /MDd
18 -# QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO -= /MD /MDd
19 -# QMAKE_CXXFLAGS -= /MD /MDd
20 -# QMAKE_CXXFLAGS_DEBUG -= /MD /MDd
21 -# QMAKE_CXXFLAGS_RELEASE -= /MD /MDd
22 -# QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO -= /MD /MDd
23 -# }
24 -# CONFIG(eha) {
25 -# message(CONFIG eha)
26 -# QMAKE_CXXFLAGS_STL_ON -= /EHsc
27 -# QMAKE_CXXFLAGS_EXCEPTIONS_ON -= /EHsc
28 -# QMAKE_CXXFLAGS_STL_ON += /EHa
29 -# QMAKE_CXXFLAGS_EXCEPTIONS_ON += /EHa
30 -# }
31 -# CONFIG(noeh) {
32 -# message(CONFIG noeh)
33 -# QMAKE_CXXFLAGS += /GR-
34 -# QMAKE_CXXFLAGS_RTTI_ON -= /GR
35 -# QMAKE_CXXFLAGS_STL_ON -= /EHsc
36 -# QMAKE_CXXFLAGS_EXCEPTIONS_ON -= /EHsc
37 -# CONFIG(dll) {
38 -# QMAKE_LFLAGS += /ENTRY:"DllMain"
39 -# }
40 -# }
41 -# CONFIG(nosafeseh) {
42 -# message(CONFIG nosafeseh)
43 -# QMAKE_LFLAGS += -safeseh:no
44 -# }
45 -# }
46 -
47 -# dllconfig.pri
48 -# win32 {
49 -# CONFIG(eh): DEFINES += ITH_HAS_SEH
50 -# CONFIG(noeh): DEFINES -= ITH_HAS_SEH
51 -# }
52 -
53 cmake_minimum_required(VERSION 2.8) 1 cmake_minimum_required(VERSION 2.8)
54 2
55 set(CMAKE_CONFIGURATION_TYPES Debug Release) 3 set(CMAKE_CONFIGURATION_TYPES Debug Release)
...@@ -66,10 +14,11 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/Release") ...@@ -66,10 +14,11 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/Release")
66 14
67 set(CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION ON) 15 set(CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION ON)
68 16
17 +
69 set(CPACK_GENERATOR "ZIP") 18 set(CPACK_GENERATOR "ZIP")
70 set(CPACK_PACKAGE_VERSION_MAJOR 3) 19 set(CPACK_PACKAGE_VERSION_MAJOR 3)
71 -set(CPACK_PACKAGE_VERSION_MINOR 4152) 20 +set(CPACK_PACKAGE_VERSION_MINOR 5640)
72 -set(CPACK_PACKAGE_VERSION_PATCH 0) 21 +set(CPACK_PACKAGE_VERSION_PATCH 1)
73 set(CPACK_SOURCE_GENERATOR "ZIP") 22 set(CPACK_SOURCE_GENERATOR "ZIP")
74 set(CPACK_SOURCE_IGNORE_FILES "/CVS/;/\\\\.svn/;/\\\\.bzr/;/\\\\.hg/;/\\\\.git/;\\\\.swp$;\\\\.#;/#" ".*\\\\.user$" "\\\\.gitignore$" "\\\\.gitmodules$" "\\\\.git$") 23 set(CPACK_SOURCE_IGNORE_FILES "/CVS/;/\\\\.svn/;/\\\\.bzr/;/\\\\.hg/;/\\\\.git/;\\\\.swp$;\\\\.#;/#" ".*\\\\.user$" "\\\\.gitignore$" "\\\\.gitmodules$" "\\\\.git$")
75 include(CPack) 24 include(CPack)
...@@ -84,24 +33,20 @@ add_compile_options( ...@@ -84,24 +33,20 @@ add_compile_options(
84 ) 33 )
85 34
86 add_definitions( 35 add_definitions(
87 - -D_SECURE_SCL=0 # config.pri 36 + /D_SECURE_SCL=0 # config.pri
88 - -D_SCL_SECURE_NO_WARNINGS # config.pri 37 + /D_SCL_SECURE_NO_WARNINGS # config.pri
89 - -D_CRT_SECURE_NO_WARNINGS # config.pri 38 + /D_CRT_SECURE_NO_WARNINGS # config.pri
90 - -DUNICODE # config.pri 39 + /DUNICODE # config.pri
91 - -D_UNICODE 40 + /D_UNICODE
92 - -D_CRT_NON_CONFORMING_SWPRINTFS # common.pri 41 + /D_CRT_NON_CONFORMING_SWPRINTFS # common.pri
93 - -DITH_HAS_CRT 42 + /DITH_HAS_CRT
94 ) 43 )
95 44
96 -include_directories(${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/vnr ${CMAKE_BINARY_DIR}/gui) 45 +include_directories(
97 - 46 + .
98 -set(common_src 47 + vnr
99 - vnr/ith/common/const.h 48 + vnr/texthook
100 - vnr/ith/common/defs.h 49 + ${CMAKE_BINARY_DIR}/gui
101 - vnr/ith/common/except.h
102 - vnr/ith/common/growl.h
103 - vnr/ith/common/memory.h
104 - vnr/ith/common/types.h
105 ) 50 )
106 51
107 set(resource_src 52 set(resource_src
...@@ -119,13 +64,8 @@ set(ithvnr_src ...@@ -119,13 +64,8 @@ set(ithvnr_src
119 gui/main.cpp 64 gui/main.cpp
120 gui/ProcessWindow.cpp 65 gui/ProcessWindow.cpp
121 gui/ProcessWindow.h 66 gui/ProcessWindow.h
122 - gui/Profile.cpp
123 - gui/Profile.h
124 gui/ProfileManager.cpp 67 gui/ProfileManager.cpp
125 gui/ProfileManager.h 68 gui/ProfileManager.h
126 - gui/pugiconfig.hpp
127 - gui/pugixml.cpp
128 - gui/pugixml.hpp
129 gui/resource.h 69 gui/resource.h
130 gui/utility.cpp 70 gui/utility.cpp
131 gui/utility.h 71 gui/utility.h
...@@ -135,17 +75,15 @@ set(ithvnr_src ...@@ -135,17 +75,15 @@ set(ithvnr_src
135 gui/window.h 75 gui/window.h
136 gui/TextBuffer.cpp 76 gui/TextBuffer.cpp
137 gui/TextBuffer.h 77 gui/TextBuffer.h
138 - ${common_src}
139 ${resource_src} 78 ${resource_src}
140 ) 79 )
141 80
142 -source_group("common" FILES ${common_src})
143 -
144 source_group("Resource Files" FILES ${resource_src}) 81 source_group("Resource Files" FILES ${resource_src})
145 82
146 add_executable(${PROJECT_NAME} ${ithvnr_src}) 83 add_executable(${PROJECT_NAME} ${ithvnr_src})
147 84
148 add_subdirectory(vnr) 85 add_subdirectory(vnr)
86 +# add_subdirectory(profile)
149 87
150 set_target_properties(${PROJECT_NAME} PROPERTIES 88 set_target_properties(${PROJECT_NAME} PROPERTIES
151 LINK_FLAGS "/SUBSYSTEM:WINDOWS /MANIFESTDEPENDENCY:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"" 89 LINK_FLAGS "/SUBSYSTEM:WINDOWS /MANIFESTDEPENDENCY:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\""
...@@ -158,8 +96,9 @@ target_compile_definitions(${PROJECT_NAME} ...@@ -158,8 +96,9 @@ target_compile_definitions(${PROJECT_NAME}
158 ) 96 )
159 97
160 target_link_libraries(${PROJECT_NAME} 98 target_link_libraries(${PROJECT_NAME}
99 + profile
161 vnrhost 100 vnrhost
162 - vnrsys 101 + ithsys
163 ${WDK_HOME}/lib/wxp/i386/ntdll.lib 102 ${WDK_HOME}/lib/wxp/i386/ntdll.lib
164 comctl32.lib 103 comctl32.lib
165 psapi.lib 104 psapi.lib
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18 #pragma once 18 #pragma once
19 +
19 #include "ITH.h" 20 #include "ITH.h"
20 21
21 typedef void (*CustomFilterCallBack) (WORD, PVOID); 22 typedef void (*CustomFilterCallBack) (WORD, PVOID);
......
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 #pragma once 17 #pragma once
18 -#include <windows.h> 18 +
19 +#include <Windows.h>
19 #include <string> 20 #include <string>
20 #include <sstream> 21 #include <sstream>
21 #include <ios> 22 #include <ios>
...@@ -29,9 +30,8 @@ ...@@ -29,9 +30,8 @@
29 #include <map> 30 #include <map>
30 #include <CommCtrl.h> 31 #include <CommCtrl.h>
31 #include <intrin.h> 32 #include <intrin.h>
32 -#include <WindowsX.h>
33 #include <sstream> 33 #include <sstream>
34 #include <regex> 34 #include <regex>
35 #include <set> 35 #include <set>
36 -#include "pugixml.hpp" 36 +#include "profile/pugixml.hpp"
37 #pragma warning(disable: 4146) 37 #pragma warning(disable: 4146)
......
1 -// Generated by ResEdit 1.6.3 1 +// Generated by ResEdit 1.6.5
2 -// Copyright (C) 2006-2014 2 +// Copyright (C) 2006-2015
3 // http://www.resedit.net 3 // http://www.resedit.net
4 4
5 #include <windows.h> 5 #include <windows.h>
...@@ -7,9 +7,6 @@ ...@@ -7,9 +7,6 @@
7 #include <richedit.h> 7 #include <richedit.h>
8 #include "resource.h" 8 #include "resource.h"
9 9
10 -#define WC_LISTVIEW L"SysListView32"
11 -
12 -
13 10
14 11
15 12
...@@ -22,14 +19,14 @@ STYLE DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYS ...@@ -22,14 +19,14 @@ STYLE DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYS
22 CAPTION "Process Explorer" 19 CAPTION "Process Explorer"
23 FONT 8, "MS Shell Dlg", 400, 0, 1 20 FONT 8, "MS Shell Dlg", 400, 0, 1
24 { 21 {
25 - DEFPUSHBUTTON "확인", IDOK, 281, 189, 53, 14, 0, WS_EX_LEFT 22 + DEFPUSHBUTTON "확인", IDOK, 281, 189, 53, 14, 0, WS_EX_LEFT
26 - PUSHBUTTON "프로필 제거", IDC_BUTTON6, 226, 189, 53, 14, 0, WS_EX_LEFT 23 + PUSHBUTTON "프로필 제거", IDC_BUTTON6, 226, 189, 53, 14, 0, WS_EX_LEFT
27 - CONTROL "", IDC_LIST1, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | LVS_REPORT, 7, 20, 327, 164, WS_EX_LEFT 24 + CONTROL "", IDC_LIST1, WC_LISTVIEW, WS_TABSTOP | WS_BORDER | LVS_ALIGNLEFT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | LVS_REPORT, 7, 20, 327, 164, WS_EX_LEFT
28 - LTEXT "프로세스", IDC_STATIC, 7, 7, 65, 13, SS_LEFT | SS_CENTERIMAGE, WS_EX_LEFT 25 + LTEXT "프로세스", IDC_STATIC, 7, 7, 65, 13, SS_LEFT | SS_CENTERIMAGE, WS_EX_LEFT
29 - PUSHBUTTON "부착", IDC_BUTTON2, 61, 189, 53, 14, 0, WS_EX_LEFT 26 + PUSHBUTTON "부착", IDC_BUTTON2, 61, 189, 53, 14, 0, WS_EX_LEFT
30 - PUSHBUTTON "탈착", IDC_BUTTON3, 116, 189, 53, 14, 0, WS_EX_LEFT 27 + PUSHBUTTON "탈착", IDC_BUTTON3, 116, 189, 53, 14, 0, WS_EX_LEFT
31 - PUSHBUTTON "프로필 추가", IDC_BUTTON5, 171, 189, 53, 14, 0, WS_EX_LEFT 28 + PUSHBUTTON "프로필 추가", IDC_BUTTON5, 171, 189, 53, 14, 0, WS_EX_LEFT
32 - PUSHBUTTON "새로고침", IDC_BUTTON1, 7, 189, 53, 14, 0, WS_EX_LEFT 29 + PUSHBUTTON "새로고침", IDC_BUTTON1, 7, 189, 53, 14, 0, WS_EX_LEFT
33 } 30 }
34 31
35 32
...@@ -40,22 +37,22 @@ STYLE DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYS ...@@ -40,22 +37,22 @@ STYLE DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYS
40 CAPTION "Option" 37 CAPTION "Option"
41 FONT 8, "MS Shell Dlg", 400, 0, 1 38 FONT 8, "MS Shell Dlg", 400, 0, 1
42 { 39 {
43 - DEFPUSHBUTTON "확인", IDOK, 8, 164, 50, 14, 0, WS_EX_LEFT 40 + DEFPUSHBUTTON "확인", IDOK, 8, 164, 50, 14, 0, WS_EX_LEFT
44 - PUSHBUTTON "취소", IDCANCEL, 65, 164, 50, 14, 0, WS_EX_LEFT 41 + PUSHBUTTON "취소", IDCANCEL, 65, 164, 50, 14, 0, WS_EX_LEFT
45 - EDITTEXT IDC_EDIT1, 60, 7, 55, 14, ES_AUTOHSCROLL, WS_EX_LEFT 42 + EDITTEXT IDC_EDIT1, 60, 7, 55, 14, ES_AUTOHSCROLL, WS_EX_LEFT
46 - LTEXT "문단나누기", IDC_STATIC, 7, 7, 47, 13, SS_LEFT | SS_CENTERIMAGE, WS_EX_LEFT 43 + LTEXT "문단나누기", IDC_STATIC, 7, 7, 47, 13, SS_LEFT | SS_CENTERIMAGE, WS_EX_LEFT
47 - EDITTEXT IDC_EDIT2, 60, 25, 55, 14, ES_AUTOHSCROLL, WS_EX_LEFT 44 + EDITTEXT IDC_EDIT2, 60, 25, 55, 14, ES_AUTOHSCROLL, WS_EX_LEFT
48 - LTEXT "프로세스 대기", IDC_STATIC, 7, 26, 47, 13, SS_LEFT | SS_CENTERIMAGE, WS_EX_LEFT 45 + LTEXT "프로세스 대기", IDC_STATIC, 7, 26, 47, 13, SS_LEFT | SS_CENTERIMAGE, WS_EX_LEFT
49 - EDITTEXT IDC_EDIT3, 60, 45, 55, 14, ES_AUTOHSCROLL, WS_EX_LEFT 46 + EDITTEXT IDC_EDIT3, 60, 45, 55, 14, ES_AUTOHSCROLL, WS_EX_LEFT
50 - LTEXT "인젝션 대기", IDC_STATIC, 7, 45, 47, 13, SS_LEFT | SS_CENTERIMAGE, WS_EX_LEFT 47 + LTEXT "인젝션 대기", IDC_STATIC, 7, 45, 47, 13, SS_LEFT | SS_CENTERIMAGE, WS_EX_LEFT
51 - EDITTEXT IDC_EDIT4, 60, 65, 55, 14, ES_AUTOHSCROLL, WS_EX_LEFT 48 + EDITTEXT IDC_EDIT4, 60, 65, 55, 14, ES_AUTOHSCROLL, WS_EX_LEFT
52 - LTEXT "삽입 대기", IDC_STATIC, 7, 65, 47, 13, SS_LEFT | SS_CENTERIMAGE, WS_EX_LEFT 49 + LTEXT "삽입 대기", IDC_STATIC, 7, 65, 47, 13, SS_LEFT | SS_CENTERIMAGE, WS_EX_LEFT
53 - AUTOCHECKBOX "자동 부착", IDC_CHECK1, 7, 87, 54, 10, 0, WS_EX_LEFT 50 + AUTOCHECKBOX "자동 부착", IDC_CHECK1, 7, 87, 54, 10, 0, WS_EX_LEFT
54 - AUTOCHECKBOX "자동 삽입", IDC_CHECK2, 62, 87, 50, 10, 0, WS_EX_LEFT 51 + AUTOCHECKBOX "자동 삽입", IDC_CHECK2, 62, 87, 50, 10, 0, WS_EX_LEFT
55 - AUTOCHECKBOX "클립보드로 자동 복사", IDC_CHECK3, 7, 103, 88, 10, 0, WS_EX_LEFT 52 + AUTOCHECKBOX "클립보드로 자동 복사", IDC_CHECK3, 7, 103, 88, 10, 0, WS_EX_LEFT
56 - AUTOCHECKBOX "자동 반복문 제거", IDC_CHECK4, 7, 119, 95, 10, 0, WS_EX_LEFT 53 + AUTOCHECKBOX "자동 반복문 제거", IDC_CHECK4, 7, 119, 95, 10, 0, WS_EX_LEFT
57 - AUTOCHECKBOX "문자필터 초기화", IDC_CHECK6, 7, 149, 81, 8, 0, WS_EX_LEFT 54 + AUTOCHECKBOX "문자필터 초기화", IDC_CHECK6, 7, 149, 81, 8, 0, WS_EX_LEFT
58 - AUTOCHECKBOX "글로벌 필터 활성화", IDC_CHECK5, 7, 134, 75, 10, 0, WS_EX_LEFT 55 + AUTOCHECKBOX "글로벌 필터 활성화", IDC_CHECK5, 7, 134, 75, 10, 0, WS_EX_LEFT
59 } 56 }
60 57
61 58
...@@ -65,3 +62,21 @@ FONT 8, "MS Shell Dlg", 400, 0, 1 ...@@ -65,3 +62,21 @@ FONT 8, "MS Shell Dlg", 400, 0, 1
65 // 62 //
66 LANGUAGE LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN 63 LANGUAGE LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN
67 IDI_ICON1 ICON "icon1.ico" 64 IDI_ICON1 ICON "icon1.ico"
65 +
66 +
67 +
68 +//
69 +// Version Information resources
70 +//
71 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
72 +1 VERSIONINFO
73 + FILEVERSION 0,0,0,0
74 + PRODUCTVERSION 0,0,0,0
75 + FILEOS VOS_UNKNOWN
76 + FILETYPE VFT_UNKNOWN
77 + FILESUBTYPE VFT2_UNKNOWN
78 + FILEFLAGSMASK 0
79 + FILEFLAGS 0
80 +{
81 +
82 +}
......
1 #include "ProcessWindow.h" 1 #include "ProcessWindow.h"
2 #include "resource.h" 2 #include "resource.h"
3 -#include "ith/host/srv.h" 3 +#include "host/host.h"
4 -#include "ith/host/hookman.h" 4 +#include "host/hookman.h"
5 #include "ProfileManager.h" 5 #include "ProfileManager.h"
6 -#include "Profile.h" 6 +#include "profile/Profile.h"
7 7
8 extern HookManager* man; // main.cpp 8 extern HookManager* man; // main.cpp
9 extern ProfileManager* pfman; // ProfileManager.cpp 9 extern ProfileManager* pfman; // ProfileManager.cpp
...@@ -22,6 +22,8 @@ ProcessWindow::ProcessWindow(HWND hDialog) : hDlg(hDialog) ...@@ -22,6 +22,8 @@ ProcessWindow::ProcessWindow(HWND hDialog) : hDlg(hDialog)
22 ListView_SetExtendedListViewStyleEx(hlProcess, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT); 22 ListView_SetExtendedListViewStyleEx(hlProcess, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
23 InitProcessDlg(); 23 InitProcessDlg();
24 RefreshProcess(); 24 RefreshProcess();
25 + EnableWindow(hbDetach, FALSE);
26 + EnableWindow(hbAttach, FALSE);
25 } 27 }
26 28
27 void ProcessWindow::InitProcessDlg() 29 void ProcessWindow::InitProcessDlg()
...@@ -73,30 +75,33 @@ void ProcessWindow::RefreshProcess() ...@@ -73,30 +75,33 @@ void ProcessWindow::RefreshProcess()
73 void ProcessWindow::AttachProcess() 75 void ProcessWindow::AttachProcess()
74 { 76 {
75 DWORD pid = GetSelectedPID(); 77 DWORD pid = GetSelectedPID();
76 - if (IHF_InjectByPID(pid) != -1) 78 + if (Host_InjectByPID(pid))
79 + {
80 + Host_HijackProcess(pid);
77 RefreshThreadWithPID(pid, true); 81 RefreshThreadWithPID(pid, true);
82 + }
78 } 83 }
79 84
80 void ProcessWindow::DetachProcess() 85 void ProcessWindow::DetachProcess()
81 { 86 {
82 DWORD pid = GetSelectedPID(); 87 DWORD pid = GetSelectedPID();
83 - if (IHF_ActiveDetachProcess(pid) == 0) 88 + if (Host_ActiveDetachProcess(pid) == 0)
84 RefreshThreadWithPID(pid, false); 89 RefreshThreadWithPID(pid, false);
85 } 90 }
86 91
87 -void ProcessWindow::AddCurrentToProfile() 92 +void ProcessWindow::CreateProfileForSelectedProcess()
88 { 93 {
89 DWORD pid = GetSelectedPID(); 94 DWORD pid = GetSelectedPID();
90 auto path = GetProcessPath(pid); 95 auto path = GetProcessPath(pid);
91 if (!path.empty()) 96 if (!path.empty())
92 { 97 {
93 - Profile* pf = pfman->AddProfile(path, pid); 98 + Profile* pf = pfman->CreateProfile(pid);
94 - pfman->FindProfileAndUpdateHookAddresses(pid, path); 99 + pfman->SaveProfiles();
95 RefreshThread(ListView_GetSelectionMark(hlProcess)); 100 RefreshThread(ListView_GetSelectionMark(hlProcess));
96 } 101 }
97 } 102 }
98 103
99 -void ProcessWindow::RemoveCurrentFromProfile() 104 +void ProcessWindow::DeleteProfileForSelectedProcess()
100 { 105 {
101 DWORD pid = GetSelectedPID(); 106 DWORD pid = GetSelectedPID();
102 auto path = GetProcessPath(pid); 107 auto path = GetProcessPath(pid);
...@@ -132,7 +137,7 @@ void ProcessWindow::RefreshThreadWithPID(DWORD pid, bool isAttached) ...@@ -132,7 +137,7 @@ void ProcessWindow::RefreshThreadWithPID(DWORD pid, bool isAttached)
132 137
133 DWORD ProcessWindow::GetSelectedPID() 138 DWORD ProcessWindow::GetSelectedPID()
134 { 139 {
135 - LVITEM item={}; 140 + LVITEM item = {};
136 item.mask = LVIF_PARAM; 141 item.mask = LVIF_PARAM;
137 item.iItem = ListView_GetSelectionMark(hlProcess); 142 item.iItem = ListView_GetSelectionMark(hlProcess);
138 ListView_GetItem(hlProcess, &item); 143 ListView_GetItem(hlProcess, &item);
......
1 #pragma once 1 #pragma once
2 +
2 #include "ITH.h" 3 #include "ITH.h"
3 4
4 class ProcessWindow 5 class ProcessWindow
...@@ -9,8 +10,8 @@ public: ...@@ -9,8 +10,8 @@ public:
9 void RefreshProcess(); 10 void RefreshProcess();
10 void AttachProcess(); 11 void AttachProcess();
11 void DetachProcess(); 12 void DetachProcess();
12 - void AddCurrentToProfile(); 13 + void CreateProfileForSelectedProcess();
13 - void RemoveCurrentFromProfile(); 14 + void DeleteProfileForSelectedProcess();
14 void RefreshThread(int index); 15 void RefreshThread(int index);
15 private: 16 private:
16 void RefreshThreadWithPID(DWORD pid, bool isAttached); 17 void RefreshThreadWithPID(DWORD pid, bool isAttached);
......
1 #include "ProfileManager.h" 1 #include "ProfileManager.h"
2 -#include "Profile.h" 2 +#include "profile/Profile.h"
3 -#include "ith/host/srv.h" 3 +#include "host/host.h"
4 -#include "ith/host/hookman.h" 4 +#include "host/hookman.h"
5 -#include "ith/common/types.h" 5 +#include "vnrhook/include/types.h"
6 -#include "ith/common/const.h" 6 +#include "vnrhook/include/const.h"
7 +#include "utility.h"
8 +#include "profile/misc.h"
7 9
8 extern HookManager* man; // main.cpp 10 extern HookManager* man; // main.cpp
9 extern LONG auto_inject, auto_insert, inject_delay; // main.cpp 11 extern LONG auto_inject, auto_insert, inject_delay; // main.cpp
...@@ -12,21 +14,16 @@ bool MonitorFlag; ...@@ -12,21 +14,16 @@ bool MonitorFlag;
12 ProfileManager* pfman; 14 ProfileManager* pfman;
13 15
14 DWORD WINAPI MonitorThread(LPVOID lpThreadParameter); 16 DWORD WINAPI MonitorThread(LPVOID lpThreadParameter);
15 -void AddHooksToProfile(Profile& pf, const ProcessRecord& pr);
16 -void AddThreadsToProfile(Profile& pf, const ProcessRecord& pr, DWORD pid);
17 -DWORD AddThreadToProfile(Profile& pf, const ProcessRecord& pr, TextThread& thread);
18 -void MakeHookRelative(const ProcessRecord& pr, HookParam& hp);
19 -std::wstring GetHookNameByAddress(const ProcessRecord& pr, DWORD hook_address);
20 -void GetHookNameToAddressMap(const ProcessRecord& pr, std::map<std::wstring, DWORD>& hookNameToAddress);
21 17
22 -ProfileManager::ProfileManager(): 18 +ProfileManager::ProfileManager() :
23 hMonitorThread(IthCreateThread(MonitorThread, 0)) 19 hMonitorThread(IthCreateThread(MonitorThread, 0))
24 { 20 {
25 - LoadProfile(); 21 + LoadProfiles();
26 } 22 }
23 +
27 ProfileManager::~ProfileManager() 24 ProfileManager::~ProfileManager()
28 { 25 {
29 - SaveProfile(); 26 + SaveProfiles();
30 WaitForSingleObject(hMonitorThread.get(), 0); 27 WaitForSingleObject(hMonitorThread.get(), 0);
31 } 28 }
32 29
...@@ -42,7 +39,7 @@ Profile* ProfileManager::GetProfile(DWORD pid) ...@@ -42,7 +39,7 @@ Profile* ProfileManager::GetProfile(DWORD pid)
42 return NULL; 39 return NULL;
43 } 40 }
44 41
45 -bool ProfileManager::AddProfile(pugi::xml_node game) 42 +bool ProfileManager::CreateProfile(pugi::xml_node game)
46 { 43 {
47 auto file = game.child(L"File"); 44 auto file = game.child(L"File");
48 auto profile = game.child(L"Profile"); 45 auto profile = game.child(L"Profile");
...@@ -56,13 +53,17 @@ bool ProfileManager::AddProfile(pugi::xml_node game) ...@@ -56,13 +53,17 @@ bool ProfileManager::AddProfile(pugi::xml_node game)
56 auto pf = new Profile(title); 53 auto pf = new Profile(title);
57 if (!pf->XmlReadProfile(profile)) 54 if (!pf->XmlReadProfile(profile))
58 return false; 55 return false;
59 - AddProfile(path.value(), profile_ptr(pf)); 56 + CSLock lock(cs);
60 - return true; 57 + auto& oldProfile = profile_tree[path.value()];
58 + if (!oldProfile)
59 + oldProfile.swap(profile_ptr(pf));
60 + return true;
61 } 61 }
62 62
63 -Profile* ProfileManager::AddProfile(const std::wstring& path, DWORD pid) 63 +Profile* ProfileManager::CreateProfile(DWORD pid)
64 { 64 {
65 CSLock lock(cs); 65 CSLock lock(cs);
66 + auto path = GetProcessPath(pid);
66 auto& pf = profile_tree[path]; 67 auto& pf = profile_tree[path];
67 if (!pf) 68 if (!pf)
68 { 69 {
...@@ -72,15 +73,6 @@ Profile* ProfileManager::AddProfile(const std::wstring& path, DWORD pid) ...@@ -72,15 +73,6 @@ Profile* ProfileManager::AddProfile(const std::wstring& path, DWORD pid)
72 return pf.get(); 73 return pf.get();
73 } 74 }
74 75
75 -Profile* ProfileManager::AddProfile(const std::wstring& path, profile_ptr new_profile)
76 -{
77 - CSLock lock(cs);
78 - auto& pf = profile_tree[path];
79 - if (!pf)
80 - pf.swap(new_profile);
81 - return pf.get();
82 -}
83 -
84 void ProfileManager::WriteProfileXml(const std::wstring& path, Profile& pf, pugi::xml_node root) 76 void ProfileManager::WriteProfileXml(const std::wstring& path, Profile& pf, pugi::xml_node root)
85 { 77 {
86 auto game = root.append_child(L"Game"); 78 auto game = root.append_child(L"Game");
...@@ -96,7 +88,7 @@ void ProfileManager::WriteProfileXml(const std::wstring& path, Profile& pf, pugi ...@@ -96,7 +88,7 @@ void ProfileManager::WriteProfileXml(const std::wstring& path, Profile& pf, pugi
96 } 88 }
97 } 89 }
98 90
99 -void ProfileManager::LoadProfile() 91 +void ProfileManager::LoadProfiles()
100 { 92 {
101 pugi::xml_document doc; 93 pugi::xml_document doc;
102 UniqueHandle hFile(IthCreateFile(L"ITH_Profile.xml", GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING)); 94 UniqueHandle hFile(IthCreateFile(L"ITH_Profile.xml", GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING));
...@@ -112,10 +104,10 @@ void ProfileManager::LoadProfile() ...@@ -112,10 +104,10 @@ void ProfileManager::LoadProfile()
112 if (!root) 104 if (!root)
113 return; 105 return;
114 for (auto game = root.begin(); game != root.end(); ++game) 106 for (auto game = root.begin(); game != root.end(); ++game)
115 - AddProfile(*game); 107 + CreateProfile(*game);
116 } 108 }
117 109
118 -void ProfileManager::SaveProfile() 110 +void ProfileManager::SaveProfiles()
119 { 111 {
120 pugi::xml_document doc; 112 pugi::xml_document doc;
121 auto root = doc.append_child(L"ITH_Profile"); 113 auto root = doc.append_child(L"ITH_Profile");
...@@ -138,44 +130,14 @@ void ProfileManager::DeleteProfile(const std::wstring& path) ...@@ -138,44 +130,14 @@ void ProfileManager::DeleteProfile(const std::wstring& path)
138 profile_tree.erase(profile_tree.find(path)); 130 profile_tree.erase(profile_tree.find(path));
139 } 131 }
140 132
141 -void ProfileManager::FindProfileAndUpdateHookAddresses(DWORD pid, const std::wstring& path) 133 +Profile* ProfileManager::GetProfile(const std::wstring& path)
142 { 134 {
143 if (path.empty()) 135 if (path.empty())
144 - return; 136 + return nullptr;
145 auto it = profile_tree.find(path); 137 auto it = profile_tree.find(path);
146 if (it == profile_tree.end()) 138 if (it == profile_tree.end())
147 - return; 139 + return nullptr;
148 - auto& pf = it->second; 140 + return it->second.get();
149 - const ProcessRecord* pr = man->GetProcessRecord(pid);
150 - if (pr == NULL)
151 - return;
152 - // hook name -> hook address
153 - std::map<std::wstring, DWORD> hookNameToAddress;
154 - GetHookNameToAddressMap(*pr, hookNameToAddress);
155 - for (auto thread_profile = pf->Threads().begin(); thread_profile != pf->Threads().end();
156 - ++thread_profile)
157 - {
158 - auto it = hookNameToAddress.find((*thread_profile)->HookName());
159 - if (it != hookNameToAddress.end())
160 - (*thread_profile)->HookAddress() = it->second;
161 - }
162 -}
163 -
164 -void GetHookNameToAddressMap(const ProcessRecord& pr,
165 - std::map<std::wstring, DWORD>& hookNameToAddress)
166 -{
167 - WaitForSingleObject(pr.hookman_mutex, 0);
168 - auto hooks = (const Hook*)pr.hookman_map;
169 - for (DWORD i = 0; i < MAX_HOOK; ++i)
170 - {
171 - if (hooks[i].Address() == 0)
172 - continue;
173 - auto& hook = hooks[i];
174 - std::unique_ptr<WCHAR[]> name(new WCHAR[hook.NameLength() * 2]);
175 - if (ReadProcessMemory(pr.process_handle, hook.Name(), name.get(), hook.NameLength() * 2, NULL))
176 - hookNameToAddress[name.get()] = hook.Address();
177 - }
178 - ReleaseMutex(pr.hookman_mutex);
179 } 141 }
180 142
181 bool ProfileManager::HasProfile(const std::wstring& path) 143 bool ProfileManager::HasProfile(const std::wstring& path)
...@@ -183,7 +145,7 @@ bool ProfileManager::HasProfile(const std::wstring& path) ...@@ -183,7 +145,7 @@ bool ProfileManager::HasProfile(const std::wstring& path)
183 return profile_tree.find(path) != profile_tree.end(); 145 return profile_tree.find(path) != profile_tree.end();
184 } 146 }
185 147
186 -DWORD ProfileManager::ProfileCount() 148 +DWORD ProfileManager::CountProfiles()
187 { 149 {
188 return profile_tree.size(); 150 return profile_tree.size();
189 } 151 }
...@@ -194,7 +156,7 @@ DWORD WINAPI InjectThread(LPVOID lpThreadParameter) ...@@ -194,7 +156,7 @@ DWORD WINAPI InjectThread(LPVOID lpThreadParameter)
194 Sleep(inject_delay); 156 Sleep(inject_delay);
195 if (man == NULL) 157 if (man == NULL)
196 return 0; 158 return 0;
197 - DWORD status = IHF_InjectByPID(pid); 159 + DWORD status = Host_InjectByPID(pid);
198 if (!auto_insert) 160 if (!auto_insert)
199 return status; 161 return status;
200 if (status == -1) 162 if (status == -1)
...@@ -206,7 +168,10 @@ DWORD WINAPI InjectThread(LPVOID lpThreadParameter) ...@@ -206,7 +168,10 @@ DWORD WINAPI InjectThread(LPVOID lpThreadParameter)
206 SendParam sp; 168 SendParam sp;
207 sp.type = 0; 169 sp.type = 0;
208 for (auto hp = pf->Hooks().begin(); hp != pf->Hooks().end(); ++hp) 170 for (auto hp = pf->Hooks().begin(); hp != pf->Hooks().end(); ++hp)
209 - IHF_InsertHook(pid, const_cast<HookParam*>(&(*hp)->HP()), (*hp)->Name().c_str()); 171 + {
172 + std::string name = toMultiByteString((*hp)->Name());
173 + Host_InsertHook(pid, const_cast<HookParam*>(&(*hp)->HP()), name.c_str());
174 + }
210 } 175 }
211 return status; 176 return status;
212 } 177 }
...@@ -215,7 +180,7 @@ DWORD WINAPI MonitorThread(LPVOID lpThreadParameter) ...@@ -215,7 +180,7 @@ DWORD WINAPI MonitorThread(LPVOID lpThreadParameter)
215 { 180 {
216 while (MonitorFlag) 181 while (MonitorFlag)
217 { 182 {
218 - DWORD aProcesses[1024], cbNeeded, cProcesses; 183 + DWORD aProcesses[1024], cbNeeded, cProcesses;
219 if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) 184 if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
220 break; 185 break;
221 cProcesses = cbNeeded / sizeof(DWORD); 186 cProcesses = cbNeeded / sizeof(DWORD);
...@@ -237,116 +202,17 @@ DWORD WINAPI MonitorThread(LPVOID lpThreadParameter) ...@@ -237,116 +202,17 @@ DWORD WINAPI MonitorThread(LPVOID lpThreadParameter)
237 202
238 DWORD SaveProcessProfile(DWORD pid) 203 DWORD SaveProcessProfile(DWORD pid)
239 { 204 {
240 - const ProcessRecord* pr = man->GetProcessRecord(pid);
241 - if (pr == NULL)
242 - return 0;
243 std::wstring path = GetProcessPath(pid); 205 std::wstring path = GetProcessPath(pid);
244 if (path.empty()) 206 if (path.empty())
245 return 0; 207 return 0;
208 + pugi::xml_document doc;
209 + pugi::xml_node profile_node = doc.append_child(L"Profile");
210 + man->GetProfile(pid, profile_node);
246 Profile* pf = pfman->GetProfile(pid); 211 Profile* pf = pfman->GetProfile(pid);
247 if (pf != NULL) 212 if (pf != NULL)
248 pf->Clear(); 213 pf->Clear();
249 else 214 else
250 - pf = pfman->AddProfile(path, pid); 215 + pf = pfman->CreateProfile(pid);
251 - AddHooksToProfile(*pf, *pr); 216 + pf->XmlReadProfile(profile_node);
252 - AddThreadsToProfile(*pf, *pr, pid);
253 return 0; 217 return 0;
254 } 218 }
255 -
256 -void AddHooksToProfile(Profile& pf, const ProcessRecord& pr)
257 -{
258 - WaitForSingleObject(pr.hookman_mutex, 0);
259 - auto hooks = (const Hook*)pr.hookman_map;
260 - for (DWORD i = 0; i < MAX_HOOK; ++i)
261 - {
262 - if (hooks[i].Address() == 0)
263 - continue;
264 - auto& hook = hooks[i];
265 - DWORD type = hook.Type();
266 - if ((type & HOOK_ADDITIONAL) && (type & HOOK_ENGINE) == 0)
267 - {
268 - std::unique_ptr<WCHAR[]> name(new WCHAR[hook.NameLength() * 2]);
269 - if (ReadProcessMemory(pr.process_handle, hook.Name(), name.get(), hook.NameLength() * 2, NULL))
270 - {
271 - if (hook.hp.module)
272 - {
273 - HookParam hp = hook.hp;
274 - MakeHookRelative(pr, hp);
275 - pf.AddHook(hp, name.get());
276 - }
277 - else
278 - pf.AddHook(hook.hp, name.get());
279 - }
280 - }
281 - }
282 - ReleaseMutex(pr.hookman_mutex);
283 -}
284 -
285 -void MakeHookRelative(const ProcessRecord& pr, HookParam& hp)
286 -{
287 - MEMORY_BASIC_INFORMATION info;
288 - VirtualQueryEx(pr.process_handle, (LPCVOID)hp.addr, &info, sizeof(info));
289 - hp.addr -= (DWORD)info.AllocationBase;
290 - hp.function = 0;
291 -}
292 -
293 -void AddThreadsToProfile(Profile& pf, const ProcessRecord& pr, DWORD pid)
294 -{
295 - man->LockHookman();
296 - ThreadTable* table = man->Table();
297 - for (int i = 0; i < table->Used(); ++i)
298 - {
299 - TextThread* tt = table->FindThread(i);
300 - if (tt == NULL || tt->GetThreadParameter()->pid != pid)
301 - continue;
302 - //if (tt->Status() & CURRENT_SELECT || tt->Link() || tt->GetComment())
303 - if (tt->Status() & CURRENT_SELECT || tt->Link())
304 - AddThreadToProfile(pf, pr, *tt);
305 - }
306 - man->UnlockHookman();
307 -}
308 -
309 -DWORD AddThreadToProfile(Profile& pf, const ProcessRecord& pr, TextThread& thread)
310 -{
311 - const ThreadParameter* tp = thread.GetThreadParameter();
312 - std::wstring hook_name = GetHookNameByAddress(pr, tp->hook);
313 - if (hook_name.empty())
314 - return -1;
315 - auto thread_profile = new ThreadProfile(hook_name, tp->retn, tp->spl, 0, 0,
316 - THREAD_MASK_RETN | THREAD_MASK_SPLIT, L"");
317 - DWORD threads_size = pf.Threads().size();
318 - int thread_profile_index = pf.AddThread(thread_ptr(thread_profile));
319 - if (thread_profile_index == threads_size) // new thread
320 - {
321 - WORD iw = thread_profile_index & 0xFFFF;
322 - if (thread.Status() & CURRENT_SELECT)
323 - pf.SelectedIndex() = iw;
324 - if (thread.Link())
325 - {
326 - WORD to_index = AddThreadToProfile(pf, pr, *(thread.Link())) & 0xFFFF;
327 - if (iw >= 0)
328 - pf.AddLink(link_ptr(new LinkProfile(iw, to_index)));
329 - }
330 - }
331 - return thread_profile_index; // in case more than one thread links to the same thread.
332 -}
333 -
334 -std::wstring GetHookNameByAddress(const ProcessRecord& pr, DWORD hook_address)
335 -{
336 - std::wstring hook_name;
337 - WaitForSingleObject(pr.hookman_mutex, 0);
338 - auto hooks = (const Hook*)pr.hookman_map;
339 - for (int i = 0; i < MAX_HOOK; ++i)
340 - {
341 - auto& hook = hooks[i];
342 - if (hook.Address() == hook_address)
343 - {
344 - std::unique_ptr<WCHAR[]> name(new WCHAR[hook.NameLength() * 2]);
345 - if (ReadProcessMemory(pr.process_handle, hooks[i].Name(), name.get(), hook.NameLength() * 2, NULL))
346 - hook_name = name.get();
347 - break;
348 - }
349 - }
350 - ReleaseMutex(pr.hookman_mutex);
351 - return hook_name;
352 -}
......
1 #pragma once 1 #pragma once
2 +
2 #include "ITH.h" 3 #include "ITH.h"
3 #include "utility.h" // UniqueHandle, CriticalSection 4 #include "utility.h" // UniqueHandle, CriticalSection
4 5
...@@ -9,14 +10,14 @@ class ProfileManager ...@@ -9,14 +10,14 @@ class ProfileManager
9 public: 10 public:
10 ProfileManager(); 11 ProfileManager();
11 ~ProfileManager(); 12 ~ProfileManager();
12 - Profile* AddProfile(const std::wstring& path, DWORD pid); 13 + Profile* CreateProfile(DWORD pid);
13 - void DeleteProfile(const std::wstring& path); 14 + Profile* GetProfile(DWORD pid);
14 - void LoadProfile(); 15 + Profile* GetProfile(const std::wstring& path);
15 - void SaveProfile(); 16 + void LoadProfiles();
16 - void FindProfileAndUpdateHookAddresses(DWORD pid, const std::wstring& path); 17 + void SaveProfiles();
18 + void DeleteProfile(const std::wstring& path);
19 + void UpdateHookAddresses(DWORD pid);
17 bool HasProfile(const std::wstring& path); 20 bool HasProfile(const std::wstring& path);
18 - Profile* GetProfile(DWORD pid);
19 - DWORD ProfileCount();
20 private: 21 private:
21 typedef std::unique_ptr<Profile> profile_ptr; 22 typedef std::unique_ptr<Profile> profile_ptr;
22 typedef std::map<std::wstring, profile_ptr> profile_map; 23 typedef std::map<std::wstring, profile_ptr> profile_map;
...@@ -24,8 +25,8 @@ private: ...@@ -24,8 +25,8 @@ private:
24 ProfileManager(const ProfileManager&); 25 ProfileManager(const ProfileManager&);
25 ProfileManager operator=(const ProfileManager&); 26 ProfileManager operator=(const ProfileManager&);
26 27
27 - bool AddProfile(pugi::xml_node game); 28 + DWORD CountProfiles();
28 - Profile* AddProfile(const std::wstring& path, profile_ptr new_profile); 29 + bool CreateProfile(pugi::xml_node game);
29 void WriteProfileXml(const std::wstring& path, Profile& pf, pugi::xml_node doc); 30 void WriteProfileXml(const std::wstring& path, Profile& pf, pugi::xml_node doc);
30 // locate profile with executable path 31 // locate profile with executable path
31 profile_map profile_tree; 32 profile_map profile_tree;
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
3 DWORD WINAPI FlushThread(LPVOID lParam); // window.cpp 3 DWORD WINAPI FlushThread(LPVOID lParam); // window.cpp
4 4
5 TextBuffer::TextBuffer(HWND edit) : hThread(IthCreateThread(FlushThread, (DWORD)this)), 5 TextBuffer::TextBuffer(HWND edit) : hThread(IthCreateThread(FlushThread, (DWORD)this)),
6 - hEdit(edit), 6 +hEdit(edit),
7 - running(true) 7 +running(true)
8 { 8 {
9 } 9 }
10 10
......
1 #pragma once 1 #pragma once
2 +
2 #include "ITH.h" 3 #include "ITH.h"
3 #include "utility.h" // UniqueHandle, CriticalSection 4 #include "utility.h" // UniqueHandle, CriticalSection
4 5
......
...@@ -16,157 +16,16 @@ ...@@ -16,157 +16,16 @@
16 */ 16 */
17 17
18 #include "ITH.h" 18 #include "ITH.h"
19 -#include "ith/host/srv.h" 19 +#include "host/host.h"
20 -#include "ith/common/const.h" 20 +#include "vnrhook/include/const.h"
21 -#include "ith/common/types.h" 21 +#include "vnrhook/include/types.h"
22 #include "language.h" 22 #include "language.h"
23 #include "utility.h" 23 #include "utility.h"
24 +#include "profile/misc.h"
24 25
25 extern HookManager* man; 26 extern HookManager* man;
26 extern HWND hwndProcessComboBox; 27 extern HWND hwndProcessComboBox;
27 28
28 -bool Parse(const std::wstring& cmd, HookParam& hp)
29 -{
30 - using std::wregex;
31 - using std::regex_search;
32 - // /H[X]{A|B|W|S|Q}[N][data_offset[*drdo]][:sub_offset[*drso]]@addr[:[module[:{name|#ordinal}]]]
33 - wregex rx(L"^X?([ABWSQ])(N)?", wregex::icase);
34 - std::match_results<std::wstring::const_iterator> m;
35 - auto start = cmd.begin();
36 - auto end = cmd.end();
37 - bool result = regex_search(start, end, m, rx);
38 - if (!result)
39 - return result;
40 - start = m[0].second;
41 - if (m[2].matched)
42 - hp.type |= NO_CONTEXT;
43 -
44 - switch (m[1].first[0])
45 - {
46 - case L's':
47 - case L'S':
48 - hp.type |= USING_STRING;
49 - break;
50 - case L'e':
51 - case L'E':
52 - hp.type |= STRING_LAST_CHAR;
53 - case L'a':
54 - case L'A':
55 - hp.type |= BIG_ENDIAN;
56 - hp.length_offset = 1;
57 - break;
58 - case L'b':
59 - case L'B':
60 - hp.length_offset = 1;
61 - break;
62 - case L'h':
63 - case L'H':
64 - hp.type |= PRINT_DWORD;
65 - case L'q':
66 - case L'Q':
67 - hp.type |= USING_STRING | USING_UNICODE;
68 - break;
69 - case L'l':
70 - case L'L':
71 - hp.type |= STRING_LAST_CHAR;
72 - case L'w':
73 - case L'W':
74 - hp.type |= USING_UNICODE;
75 - hp.length_offset = 1;
76 - break;
77 - default:
78 - break;
79 - }
80 -
81 - // [data_offset[*drdo]]
82 - std::wstring data_offset(L"(-?[[:xdigit:]]+)"), drdo(L"(\\*-?[[:xdigit:]]+)?");
83 - rx = wregex(L"^"+ data_offset + drdo, wregex::icase);
84 - result = regex_search(start, end, m, rx);
85 - if (result)
86 - {
87 - start = m[0].second;
88 - hp.off = std::stoul(m[1].str(), NULL, 16);
89 - if (m[2].matched)
90 - {
91 - hp.type |= DATA_INDIRECT;
92 - hp.ind = std::stoul(m[2].str().substr(1), NULL, 16);
93 - }
94 - }
95 -
96 - // [:sub_offset[*drso]]
97 - std::wstring sub_offset(L"(-?[[:xdigit:]]+)"), drso(L"(\\*-?[[:xdigit:]]+)?");
98 - rx = wregex(L"^:" + sub_offset + drso, wregex::icase);
99 - result = regex_search(start, end, m, rx);
100 - if (result)
101 - {
102 - start = m[0].second;
103 - hp.type |= USING_SPLIT;
104 - hp.split = std::stoul(m[1].str(), NULL, 16);
105 - if (m[2].matched)
106 - {
107 - hp.type |= SPLIT_INDIRECT;
108 - hp.split_ind = std::stoul(m[2].str().substr(1), NULL, 16);
109 - }
110 - }
111 - // @addr
112 - rx = wregex(L"^@[[:xdigit:]]+", wregex::icase);
113 - result = regex_search(start, end, m, rx);
114 - if (!result)
115 - return false;
116 - start = m[0].second;
117 - hp.addr = std::stoul(m[0].str().substr(1), NULL, 16);
118 - if (hp.off & 0x80000000)
119 - hp.off -= 4;
120 - if (hp.split & 0x80000000)
121 - hp.split -= 4;
122 -
123 - // [:[module[:{name|#ordinal}]]]
124 - // ":" ->
125 - // "" -> MODULE_OFFSET && module == NULL && function == addr
126 - // ":GDI.dll" -> MODULE_OFFSET && module != NULL
127 - // ":GDI.dll:strlen" -> MODULE_OFFSET | FUNCTION_OFFSET && module != NULL && function != NULL
128 - // ":GDI.dll:#123" -> MODULE_OFFSET | FUNCTION_OFFSET && module != NULL && function != NULL
129 - std::wstring module(L"([[:graph:]]+)"), name(L"[[:graph:]]+"), ordinal(L"\\d+");
130 - rx = wregex(L"^:(" + module + L"(:" + name + L"|#" + ordinal + L")?)?$", wregex::icase);
131 - result = regex_search(start, end, m, rx);
132 - if (result) // :[module[:{name|#ordinal}]]
133 - {
134 - if (m[1].matched) // module
135 - {
136 - hp.type |= MODULE_OFFSET;
137 - std::wstring module = m[2];
138 - std::transform(module.begin(), module.end(), module.begin(), ::towlower);
139 - hp.module = Hash(module);
140 - if (m[3].matched) // :name|#ordinal
141 - {
142 - hp.type |= FUNCTION_OFFSET;
143 - hp.function = Hash(m[3].str().substr(1));
144 - }
145 - }
146 - }
147 - else
148 - {
149 - rx = wregex(L"^!([[:xdigit:]]+)(!([[:xdigit:]]+))?$", wregex::icase);
150 - result = regex_search(start, end, m, rx);
151 - if (result)
152 - {
153 - hp.type |= MODULE_OFFSET;
154 - hp.module = std::stoul(m[1].str(), NULL, 16);
155 - if (m[2].matched)
156 - {
157 - hp.type |= FUNCTION_OFFSET;
158 - hp.function = std::stoul(m[2].str().substr(1), NULL, 16);
159 - }
160 - }
161 - else
162 - {
163 - hp.type |= MODULE_OFFSET;
164 - hp.function = hp.addr;
165 - }
166 - }
167 - return true;
168 -}
169 -
170 DWORD ProcessCommand(const std::wstring& cmd, DWORD pid) 29 DWORD ProcessCommand(const std::wstring& cmd, DWORD pid)
171 { 30 {
172 using std::wregex; 31 using std::wregex;
...@@ -175,40 +34,40 @@ DWORD ProcessCommand(const std::wstring& cmd, DWORD pid) ...@@ -175,40 +34,40 @@ DWORD ProcessCommand(const std::wstring& cmd, DWORD pid)
175 34
176 if (regex_match(cmd, m, wregex(L"/pn(.+)", wregex::icase))) 35 if (regex_match(cmd, m, wregex(L"/pn(.+)", wregex::icase)))
177 { 36 {
178 - pid = IHF_GetPIDByName(m[1].str().c_str()); 37 + pid = Host_GetPIDByName(m[1].str().c_str());
179 if (pid == 0) 38 if (pid == 0)
180 return 0; 39 return 0;
181 - IHF_InjectByPID(pid); 40 + Host_InjectByPID(pid);
182 } 41 }
183 else if (regex_match(cmd, m, wregex(L"/p(\\d+)", wregex::icase))) 42 else if (regex_match(cmd, m, wregex(L"/p(\\d+)", wregex::icase)))
184 { 43 {
185 pid = std::stoul(m[1].str()); 44 pid = std::stoul(m[1].str());
186 - IHF_InjectByPID(pid); 45 + Host_InjectByPID(pid);
187 } 46 }
188 - else if (regex_match(cmd, m, wregex (L"/h(.+)", wregex::icase))) 47 + else if (regex_match(cmd, m, wregex(L"/h(.+)", wregex::icase)))
189 { 48 {
190 HookParam hp = {}; 49 HookParam hp = {};
191 if (Parse(m[1].str(), hp)) 50 if (Parse(m[1].str(), hp))
192 - IHF_InsertHook(pid, &hp); 51 + Host_InsertHook(pid, &hp);
193 } 52 }
194 - else if (regex_match(cmd, m, wregex(L"(?::|)(?:ㅇ|연|l|)([[:xdigit:]]+)(?:-| )([[:xdigit:]]+)", wregex::icase))) 53 + else if (regex_match(cmd, m, wregex(L"(?::|)(?:|연|l|)([[:xdigit:]]+)(?:-| )([[:xdigit:]]+)", wregex::icase)))
195 { 54 {
196 DWORD from = std::stoul(m[1].str(), NULL, 16); 55 DWORD from = std::stoul(m[1].str(), NULL, 16);
197 DWORD to = std::stoul(m[2].str(), NULL, 16); 56 DWORD to = std::stoul(m[2].str(), NULL, 16);
198 - IHF_AddLink(from, to); 57 + Host_AddLink(from, to);
199 } 58 }
200 - else if (regex_match(cmd, m, wregex(L"(?::|)(?:ㅎ|해|해제|u)([[:xdigit:]]+)", wregex::icase))) 59 + else if (regex_match(cmd, m, wregex(L"(?::|)(?:ㅎ|해|해제|u)([[:xdigit:]]+)", wregex::icase)))
201 { 60 {
202 DWORD from = std::stoul(m[1].str(), NULL, 16); 61 DWORD from = std::stoul(m[1].str(), NULL, 16);
203 - IHF_UnLink(from); 62 + Host_UnLink(from);
204 } 63 }
205 - else if (regex_match(cmd, m, wregex(L"(?::|)(?:ㄷ|도|도움|도움말|h|help)", wregex::icase))) 64 + else if (regex_match(cmd, m, wregex(L"(?::|)(?:ㄷ|도|도움|도움말|h|help)", wregex::icase)))
206 { 65 {
207 ConsoleOutput(Usage); 66 ConsoleOutput(Usage);
208 } 67 }
209 else 68 else
210 { 69 {
211 - ConsoleOutput(L"알 수 없는 명령어. 도움말을 보시려면, :h 나 :help를 입력하세요."); 70 + ConsoleOutput(L"알 수 없는 명령어. 도움말을 보시려면, :h 나 :help를 입력하세요.");
212 } 71 }
213 return 0; 72 return 0;
214 } 73 }
......
...@@ -14,44 +14,44 @@ ...@@ -14,44 +14,44 @@
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 -const wchar_t* Warning=L"경고!"; 17 +const wchar_t* Warning = L"경고!";
18 //command.cpp 18 //command.cpp
19 -const wchar_t* ErrorSyntax=L"명령어 오류"; 19 +const wchar_t* ErrorSyntax = L"명령어 오류";
20 -const wchar_t* Usage = L"명령어:\r\n\ 20 +const wchar_t* Usage = L"령어:\r\n\
21 \r\n\ 21 \r\n\
22 -도움말 //도움말을 출력합니다\r\n\ 22 +도움말 //도움말을 출력합니다\r\n\
23 -출발 도착 // '출발'스레드에서 '도착'스레드로 연결합니다\r\n\ 23 +출발 도착 // '출발'스레드에서 '도착'스레드로 연결합니다\r\n\
24 -ㅎ출발 // '출발'스레드에 연결된 링크를 해제합니다\r\n\ 24 +ㅎ출발 // '출발'스레드에 연결된 링크를 해제합니다\r\n\
25 \r\n\ 25 \r\n\
26 -'출발'과 '도착'에는 16진법(헥사코드) 스레드번호를 입력합니다. 스레드 번호는 맨 앞에 있는 첫 번째 숫자열입니다.\r\n\ 26 +'출발'과 '도착'에는 16진법(헥사코드) 스레드번호를 입력합니다. 스레드 번호는 맨 앞에 있는 첫 번째 숫자열입니다.\r\n\
27 \r\n\ 27 \r\n\
28 -로더 옵션:\r\n\ 28 +로더 옵션:\r\n\
29 -/P[{process_id|Nprocess_name}] //프로세스에 부착\r\n\ 29 +/P[{process_id|Nprocess_name}] //프로세스에 부착\r\n\
30 \r\n\ 30 \r\n\
31 -H코드 후킹 옵션:\r\n\ 31 +H코드 후킹 옵션:\r\n\
32 /H[X]{A|B|W|S|Q}[N][data_offset[*drdo]][:sub_offset[*drso]]@addr[:module[:{name|#ordinal}]]\r\n\ 32 /H[X]{A|B|W|S|Q}[N][data_offset[*drdo]][:sub_offset[*drso]]@addr[:module[:{name|#ordinal}]]\r\n\
33 \r\n\ 33 \r\n\
34 -(서수를 제외한) /H코드의 모든 숫자는 아무것도 처리되지 않은 16진법(헥사코드)입니다"; 34 +(서수를 제외한) /H코드의 모든 숫자는 아무것도 처리되지 않은 16진법(헥사코드)입니다";
35 35
36 const wchar_t* ExtendedUsage = L"/H[X]{A|B|W|S|Q}[N][data_offset[*drdo]][:sub_offset[*drso]]@addr[:[module[:{name|#ordinal}]]]\r\n\ 36 const wchar_t* ExtendedUsage = L"/H[X]{A|B|W|S|Q}[N][data_offset[*drdo]][:sub_offset[*drso]]@addr[:[module[:{name|#ordinal}]]]\r\n\
37 \r\n\ 37 \r\n\
38 -추가 사용자정의 후킹설정\r\n\ 38 +추가 사용자정의 후킹설정\r\n\
39 \r\n\ 39 \r\n\
40 -후킹 종류 :\r\n\ 40 +후킹 종류 :\r\n\
41 -A - DBCS 문자\r\n\ 41 +A - DBCS 문자\r\n\
42 -B - DBCS 문자(big-endian)\r\n\ 42 +B - DBCS 문자(big-endian)\r\n\
43 -W - UCS2 문자\r\n\ 43 +W - UCS2 문자\r\n\
44 -S - MBCS 문자열\r\n\ 44 +S - MBCS 자열\r\n\
45 -Q - UTF-16 문자열\r\n\ 45 +Q - UTF-16 자열\r\n\
46 \r\n\ 46 \r\n\
47 -매개변수:\r\n\ 47 +개변수:\r\n\
48 -X - 하드웨어 구획점 사용\r\n\ 48 +X - 하드웨어 구획점 사용\r\n\
49 -N - 문법을 사용하지 않음\r\n\ 49 +N - 문법을 사용하지 않음\r\n\
50 data_offset - stack offset to char / string pointer\r\n\ 50 data_offset - stack offset to char / string pointer\r\n\
51 drdo - add a level of indirection to data_offset\r\n\ 51 drdo - add a level of indirection to data_offset\r\n\
52 sub_offset - stack offset to subcontext\r\n\ 52 sub_offset - stack offset to subcontext\r\n\
53 drso - add a level of indirection to sub_offset\r\n\ 53 drso - add a level of indirection to sub_offset\r\n\
54 -addr - 후킹할 주소\r\n\ 54 +addr - 후킹할 주소\r\n\
55 module - name of the module to use as base for 'addr'\r\n\ 55 module - name of the module to use as base for 'addr'\r\n\
56 name - name of the 'module' export to use as base for 'addr'\r\n\ 56 name - name of the 'module' export to use as base for 'addr'\r\n\
57 ordinal - number of the 'module' export ordinal to use as base for 'addr'\r\n\ 57 ordinal - number of the 'module' export ordinal to use as base for 'addr'\r\n\
...@@ -64,70 +64,70 @@ Negative values of 'data_offset' and 'sub_offset' refer to registers: \r\n\ ...@@ -64,70 +64,70 @@ Negative values of 'data_offset' and 'sub_offset' refer to registers: \r\n\
64 All numbers except ordinal are hexadecimal without any prefixes"; 64 All numbers except ordinal are hexadecimal without any prefixes";
65 65
66 //inject.cpp 66 //inject.cpp
67 -const wchar_t* ErrorRemoteThread=L"원격 스레드를 생성할 수 없음."; 67 +const wchar_t* ErrorRemoteThread = L"원격 스레드를 생성할 수 없음.";
68 -const wchar_t* ErrorOpenProcess=L"프로세스를 열 수 없음."; 68 +const wchar_t* ErrorOpenProcess = L"프로세스를 열 수 없음.";
69 -const wchar_t* ErrorNoProcess=L"프로세스를 찾을 수 없음"; 69 +const wchar_t* ErrorNoProcess = L"프로세스를 찾을 수 없음";
70 -const wchar_t* SelfAttach=L"ITH.exe에 부착하지 말아 주세요"; 70 +const wchar_t* SelfAttach = L"ITH.exe에 부착하지 말아 주세요";
71 -const wchar_t* AlreadyAttach=L"프로세스가 이미 부착됨."; 71 +const wchar_t* AlreadyAttach = L"프로세스가 이미 부착됨.";
72 -const wchar_t* FormatInject=L"프로세스 %d에 인젝션. 모듈 기반 %.8X"; 72 +const wchar_t* FormatInject = L"프로세스 %d에 인젝션. 모듈 기반 %.8X";
73 //main.cpp 73 //main.cpp
74 -const wchar_t* NotAdmin=L"SeDebugPrevilege을 활성화 할 수 없습니다. ITH가 제대로 작동하지 못합니다.\r\n\ 74 +const wchar_t* NotAdmin = L"SeDebugPrevilege을 활성화 할 수 없습니다. ITH가 제대로 작동하지 못합니다.\r\n\
75 -관리자 계정으로 실행하시거나 UAC를 끄시고 ITH를 실행해 주세요."; 75 +관리자 계정으로 실행하시거나 UAC를 끄시고 ITH를 실행해 주세요.";
76 //pipe.cpp 76 //pipe.cpp
77 -const wchar_t* ErrorCreatePipe=L"텍스트 파이프를 생성할 수 없거나, 요청이 너무 많습니다."; 77 +const wchar_t* ErrorCreatePipe = L"텍스트 파이프를 생성할 수 없거나, 요청이 너무 많습니다.";
78 -const wchar_t* FormatDetach=L"프로세스 %d가 탈착됨."; 78 +const wchar_t* FormatDetach = L"프로세스 %d가 탈착됨.";
79 -const wchar_t* ErrorCmdQueueFull=L"명령어 대기열이 가득참."; 79 +const wchar_t* ErrorCmdQueueFull = L"명령어 대기열이 가득참.";
80 -const wchar_t* ErrorNoAttach=L"프로세스가 부착되지 않음."; 80 +const wchar_t* ErrorNoAttach = L"프로세스가 부착되지 않음.";
81 81
82 //profile.cpp 82 //profile.cpp
83 -const wchar_t* ErrorMonitor=L"프로세스를 감시할 수 없음."; 83 +const wchar_t* ErrorMonitor = L"프로세스를 감시할 수 없음.";
84 //utility.cpp 84 //utility.cpp
85 -const wchar_t* InitMessage=L"Copyright (C) 2010-2012 kaosu <qiupf2000@gmail.com>\r\n\ 85 +const wchar_t* InitMessage = L"Copyright (C) 2010-2012 kaosu <qiupf2000@gmail.com>\r\n\
86 Copyright (C) 2015 zorkzero <zorkzero@hotmail.com>\r\n\ 86 Copyright (C) 2015 zorkzero <zorkzero@hotmail.com>\r\n\
87 -소스코드 <https://code.google.com/p/interactive-text-hooker/>\r\n\ 87 +소스코드 <https://code.google.com/p/interactive-text-hooker/>\r\n\
88 -일반토론 <https://groups.google.com/forum/?fromgroups#!forum/interactive-text-hooker>\r\n\ 88 +반토론 <https://groups.google.com/forum/?fromgroups#!forum/interactive-text-hooker>\r\n\
89 -한글화 @mireado<https://twitter.com/mireado>"; 89 +한글화 @mireado<https://twitter.com/mireado>";
90 -const wchar_t* BackgroundMsg=L"도움말을 보시려면, \"help\", \"도움말\"이나 \"도움\"을 입력하세요."; 90 +const wchar_t* BackgroundMsg = L"도움말을 보시려면, \"help\", \"도움말\"이나 \"도움\"을 입력하세요.";
91 -const wchar_t* ErrorLinkExist=L"연결이 존재함."; 91 +const wchar_t* ErrorLinkExist = L"연결이 존재함.";
92 -const wchar_t* ErrorCylicLink=L"연결실패. 순환연결은 허용되지 않습니다."; 92 +const wchar_t* ErrorCylicLink = L"연결실패. 순환연결은 허용되지 않습니다.";
93 -const wchar_t* FormatLink=L"출발스레드%.4x에서 도착스레드%.4x로 연결."; 93 +const wchar_t* FormatLink = L"출발스레드%.4x에서 도착스레드%.4x로 연결.";
94 -const wchar_t* ErrorLink=L"연결실패. 출발/도착 스레드를 찾을 수 없음."; 94 +const wchar_t* ErrorLink = L"연결실패. 출발/도착 스레드를 찾을 수 없음.";
95 -const wchar_t* ErrorDeleteCombo=L"글상자에서 지우기 실패."; 95 +const wchar_t* ErrorDeleteCombo = L"글상자에서 지우기 실패.";
96 96
97 //window.cpp 97 //window.cpp
98 -const wchar_t* ClassName=L"ITH"; 98 +const wchar_t* ClassName = L"ITH";
99 -const wchar_t* ClassNameAdmin=L"ITH (관리자)"; 99 +const wchar_t* ClassNameAdmin = L"ITH (관리자)";
100 -const wchar_t* ErrorNotSplit=L"먼저 문단 나누기를 활성화해주세요!"; 100 +const wchar_t* ErrorNotSplit = L"먼저 문단 나누기를 활성화해주세요!";
101 -const wchar_t* ErrorNotModule=L"먼저 모듈을 활성화해주세요!"; 101 +const wchar_t* ErrorNotModule = L"먼저 모듈을 활성화해주세요!";
102 //Main window buttons 102 //Main window buttons
103 -const wchar_t* ButtonTitleProcess=L"프로세스"; 103 +const wchar_t* ButtonTitleProcess = L"프로세스";
104 -const wchar_t* ButtonTitleThread=L"스레드"; 104 +const wchar_t* ButtonTitleThread = L"스레드";
105 -const wchar_t* ButtonTitleHook=L"후킹"; 105 +const wchar_t* ButtonTitleHook = L"후킹";
106 -const wchar_t* ButtonTitleProfile=L"프로필"; 106 +const wchar_t* ButtonTitleProfile = L"프로필";
107 -const wchar_t* ButtonTitleOption=L"옵션"; 107 +const wchar_t* ButtonTitleOption = L"옵션";
108 -const wchar_t* ButtonTitleClear=L"지우기"; 108 +const wchar_t* ButtonTitleClear = L"지우기";
109 -const wchar_t* ButtonTitleSave=L"저장"; 109 +const wchar_t* ButtonTitleSave = L"저장";
110 -const wchar_t* ButtonTitleTop=L"항상위"; 110 +const wchar_t* ButtonTitleTop = L"항상위";
111 //Hook window 111 //Hook window
112 -const wchar_t* SpecialHook=L"H코드 후킹, AGTH 코드는 지원하지 않습니다."; 112 +const wchar_t* SpecialHook = L"H코드 후킹, AGTH 코드는 지원하지 않습니다.";
113 //Process window 113 //Process window
114 -const wchar_t* TabTitlePID=L"PID"; 114 +const wchar_t* TabTitlePID = L"PID";
115 -const wchar_t* TabTitleMemory=L"메모리"; 115 +const wchar_t* TabTitleMemory = L"메모리";
116 -const wchar_t* TabTitleName=L"이름"; 116 +const wchar_t* TabTitleName = L"이름";
117 -const wchar_t* TabTitleTID=L"TID"; 117 +const wchar_t* TabTitleTID = L"TID";
118 -const wchar_t* TabTitleStart=L"시작"; 118 +const wchar_t* TabTitleStart = L"시작";
119 -const wchar_t* TabTitleModule=L"모듈"; 119 +const wchar_t* TabTitleModule = L"모듈";
120 -const wchar_t* TabTitleState=L"상태"; 120 +const wchar_t* TabTitleState = L"상태";
121 -const wchar_t* SuccessAttach=L"프로세스에 ITH 부착성공."; 121 +const wchar_t* SuccessAttach = L"프로세스에 ITH 부착성공.";
122 -const wchar_t* FailAttach=L"프로세스에 ITH 부착실패."; 122 +const wchar_t* FailAttach = L"프로세스에 ITH 부착실패.";
123 -const wchar_t* SuccessDetach=L"프로세스에서 ITH 탈착성공."; 123 +const wchar_t* SuccessDetach = L"프로세스에서 ITH 탈착성공.";
124 -const wchar_t* FailDetach=L"ITH 탈착실패."; 124 +const wchar_t* FailDetach = L"ITH 탈착실패.";
125 //Profile window 125 //Profile window
126 -const wchar_t* ProfileExist=L"프로필이 이미 존재함."; 126 +const wchar_t* ProfileExist = L"프로필이 이미 존재함.";
127 -const wchar_t* SuccessAddProfile=L"프로필 추가됨."; 127 +const wchar_t* SuccessAddProfile = L"프로필 추가됨.";
128 -const wchar_t* FailAddProfile=L"프로필 추가실패"; 128 +const wchar_t* FailAddProfile = L"프로필 추가실패";
129 -const wchar_t* TabTitleNumber=L"No."; 129 +const wchar_t* TabTitleNumber = L"No.";
130 -const wchar_t* NoFile=L"파일을 찾을 수 없음."; 130 +const wchar_t* NoFile = L"파일을 찾을 수 없음.";
131 -const wchar_t* PathDismatch=L"프로세스 이름이 일치하지 않습니다, 계속하시겠습니까?"; 131 +const wchar_t* PathDismatch = L"프로세스 이름이 일치하지 않습니다, 계속하시겠습니까?";
132 -const wchar_t* SuccessImportProfile=L"프로필 가져오기 성공"; 132 +const wchar_t* SuccessImportProfile = L"프로필 가져오기 성공";
133 -//const wchar_t* SuccessAddProfile=L"Profile added."; 133 +//const wchar_t* SuccessAddProfile=L"Profile added.";
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -16,11 +16,11 @@ ...@@ -16,11 +16,11 @@
16 */ 16 */
17 17
18 #include "ITH.h" 18 #include "ITH.h"
19 -#include "ith/host/srv.h" 19 +#include "host/host.h"
20 -#include "ith/host/hookman.h" 20 +#include "host/hookman.h"
21 -#include "ith/host/SettingManager.h" 21 +#include "host/settings.h"
22 #include "CustomFilter.h" 22 #include "CustomFilter.h"
23 -#include "profile.h" 23 +#include "profile/Profile.h"
24 #include "ProfileManager.h" 24 #include "ProfileManager.h"
25 25
26 HINSTANCE hIns; 26 HINSTANCE hIns;
...@@ -39,10 +39,10 @@ extern "C" { ...@@ -39,10 +39,10 @@ extern "C" {
39 CustomFilter* uni_filter; 39 CustomFilter* uni_filter;
40 CustomFilter* mb_filter; 40 CustomFilter* mb_filter;
41 HookManager* man; 41 HookManager* man;
42 -SettingManager* setman; 42 +Settings* setman;
43 LONG split_time, cyclic_remove, global_filter; 43 LONG split_time, cyclic_remove, global_filter;
44 LONG process_time, inject_delay, insert_delay, 44 LONG process_time, inject_delay, insert_delay,
45 - auto_inject, auto_insert, clipboard_flag; 45 +auto_inject, auto_insert, clipboard_flag;
46 46
47 std::map<std::wstring, long> setting; 47 std::map<std::wstring, long> setting;
48 48
...@@ -69,11 +69,13 @@ void RecordUniChar(WORD uni, PVOID f) ...@@ -69,11 +69,13 @@ void RecordUniChar(WORD uni, PVOID f)
69 69
70 void SaveSettings() 70 void SaveSettings()
71 { 71 {
72 - GetWindowRect(hMainWnd, &window); 72 + WINDOWPLACEMENT wndpl;
73 - setting[L"window_left"] = window.left; 73 + wndpl.length = sizeof(WINDOWPLACEMENT);
74 - setting[L"window_right"] = window.right; 74 + GetWindowPlacement(hMainWnd, &wndpl);
75 - setting[L"window_top"] = window.top; 75 + setting[L"window_left"] = wndpl.rcNormalPosition.left;
76 - setting[L"window_bottom"] = window.bottom; 76 + setting[L"window_right"] = wndpl.rcNormalPosition.right;
77 + setting[L"window_top"] = wndpl.rcNormalPosition.top;
78 + setting[L"window_bottom"] = wndpl.rcNormalPosition.bottom;
77 setting[L"split_time"] = split_time; 79 setting[L"split_time"] = split_time;
78 setting[L"process_time"] = process_time; 80 setting[L"process_time"] = process_time;
79 setting[L"inject_delay"] = inject_delay; 81 setting[L"inject_delay"] = inject_delay;
...@@ -238,17 +240,18 @@ LONG WINAPI UnhandledExcept(_EXCEPTION_POINTERS *ExceptionInfo) ...@@ -238,17 +240,18 @@ LONG WINAPI UnhandledExcept(_EXCEPTION_POINTERS *ExceptionInfo)
238 return 0; 240 return 0;
239 } 241 }
240 242
241 -int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 243 +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
242 { 244 {
245 + InitCommonControls();
243 if (!IthInitSystemService()) 246 if (!IthInitSystemService())
244 TerminateProcess(GetCurrentProcess(), 0); 247 TerminateProcess(GetCurrentProcess(), 0);
245 CreateMutex(NULL, TRUE, L"ITH_MAIN_RUNNING"); 248 CreateMutex(NULL, TRUE, L"ITH_MAIN_RUNNING");
246 - if (IHF_Init()) 249 + if (Host_Open())
247 { 250 {
248 SetUnhandledExceptionFilter(UnhandledExcept); 251 SetUnhandledExceptionFilter(UnhandledExcept);
249 - IHF_GetHookManager(&man); 252 + Host_GetHookManager(&man);
250 - IHF_GetSettingManager(&setman); 253 + Host_GetSettings(&setman);
251 - setman->SetValue(SETTING_SPLIT_TIME, 200); 254 + setman->splittingInterval = 200;
252 MonitorFlag = true; 255 MonitorFlag = true;
253 pfman = new ProfileManager(); 256 pfman = new ProfileManager();
254 mb_filter = new CustomFilter(); 257 mb_filter = new CustomFilter();
...@@ -256,11 +259,11 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin ...@@ -256,11 +259,11 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
256 DefaultSettings(); 259 DefaultSettings();
257 LoadSettings(); 260 LoadSettings();
258 InitializeSettings(); 261 InitializeSettings();
259 - setman->SetValue(SETTING_SPLIT_TIME, split_time); 262 + setman->splittingInterval = split_time;
260 - setman->SetValue(SETTING_CLIPFLAG, clipboard_flag); 263 + setman->clipboardFlag = clipboard_flag > 0;
261 hIns = hInstance; 264 hIns = hInstance;
262 MyRegisterClass(hIns); 265 MyRegisterClass(hIns);
263 - InitInstance(hIns, IHF_IsAdmin(), &window); 266 + InitInstance(hIns, FALSE, &window);
264 MSG msg; 267 MSG msg;
265 while (GetMessage(&msg, NULL, 0, 0)) 268 while (GetMessage(&msg, NULL, 0, 0))
266 { 269 {
...@@ -277,7 +280,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin ...@@ -277,7 +280,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
277 { 280 {
278 FindITH(); 281 FindITH();
279 } 282 }
280 - IHF_Cleanup(); 283 + Host_Close();
281 IthCloseSystemService(); 284 IthCloseSystemService();
282 TerminateProcess(GetCurrentProcess(), 0); 285 TerminateProcess(GetCurrentProcess(), 0);
283 } 286 }
......
...@@ -16,10 +16,11 @@ ...@@ -16,10 +16,11 @@
16 */ 16 */
17 17
18 #include "utility.h" 18 #include "utility.h"
19 -#include "ith/host/srv.h" 19 +#include "host/host.h"
20 -#include "ith/host/hookman.h" 20 +#include "host/hookman.h"
21 -#include "ith/common/types.h" 21 +#include "vnrhook/include/types.h"
22 -#include "ith/common/const.h" 22 +#include "vnrhook/include/const.h"
23 +#include "profile/misc.h"
23 24
24 extern HookManager* man; // main.cpp 25 extern HookManager* man; // main.cpp
25 26
...@@ -65,11 +66,11 @@ std::wstring GetWindowsPath(const std::wstring& path) ...@@ -65,11 +66,11 @@ std::wstring GetWindowsPath(const std::wstring& path)
65 // path is in device form 66 // path is in device form
66 // \Device\HarddiskVolume2\Windows\System32\taskhost.exe 67 // \Device\HarddiskVolume2\Windows\System32\taskhost.exe
67 auto pathOffset = path.find(L'\\', 1) + 1; 68 auto pathOffset = path.find(L'\\', 1) + 1;
68 - pathOffset = path.find(L'\\', pathOffset); 69 + pathOffset = path.find(L'\\', pathOffset);
69 std::wstring devicePath = path.substr(0, pathOffset); // \Device\HarddiskVolume2 70 std::wstring devicePath = path.substr(0, pathOffset); // \Device\HarddiskVolume2
70 std::wstring dosDrive = GetDriveLetter(devicePath); // C: 71 std::wstring dosDrive = GetDriveLetter(devicePath); // C:
71 if (dosDrive.empty()) 72 if (dosDrive.empty())
72 - return L""; 73 + return path;
73 std::wstring dosPath = dosDrive; // C: 74 std::wstring dosPath = dosDrive; // C:
74 dosPath += path.substr(pathOffset); // C:\Windows\System32\taskhost.exe 75 dosPath += path.substr(pathOffset); // C:\Windows\System32\taskhost.exe
75 return dosPath; 76 return dosPath;
...@@ -117,16 +118,16 @@ std::wstring GetCode(const HookParam& hp, DWORD pid) ...@@ -117,16 +118,16 @@ std::wstring GetCode(const HookParam& hp, DWORD pid)
117 code += c; 118 code += c;
118 if (hp.type & NO_CONTEXT) 119 if (hp.type & NO_CONTEXT)
119 code += L'N'; 120 code += L'N';
120 - if (hp.off >> 31) 121 + if (hp.offset >> 31)
121 - code += L"-" + ToHexString(-(hp.off + 4)); 122 + code += L"-" + ToHexString(-(hp.offset + 4));
122 else 123 else
123 - code += ToHexString(hp.off); 124 + code += ToHexString(hp.offset);
124 if (hp.type & DATA_INDIRECT) 125 if (hp.type & DATA_INDIRECT)
125 { 126 {
126 - if (hp.ind >> 31) 127 + if (hp.index >> 31)
127 - code += L"*-" + ToHexString(-hp.ind); 128 + code += L"*-" + ToHexString(-hp.index);
128 else 129 else
129 - code += L"*" + ToHexString(hp.ind); 130 + code += L"*" + ToHexString(hp.index);
130 } 131 }
131 if (hp.type & USING_SPLIT) 132 if (hp.type & USING_SPLIT)
132 { 133 {
...@@ -137,21 +138,21 @@ std::wstring GetCode(const HookParam& hp, DWORD pid) ...@@ -137,21 +138,21 @@ std::wstring GetCode(const HookParam& hp, DWORD pid)
137 } 138 }
138 if (hp.type & SPLIT_INDIRECT) 139 if (hp.type & SPLIT_INDIRECT)
139 { 140 {
140 - if (hp.split_ind >> 31) 141 + if (hp.split_index >> 31)
141 - code += L"*-" + ToHexString(-hp.split_ind); 142 + code += L"*-" + ToHexString(-hp.split_index);
142 else 143 else
143 - code += L"*" + ToHexString(hp.split_ind); 144 + code += L"*" + ToHexString(hp.split_index);
144 } 145 }
145 if (pid) 146 if (pid)
146 { 147 {
147 - PVOID allocationBase = GetAllocationBase(pid, (LPCVOID)hp.addr); 148 + PVOID allocationBase = GetAllocationBase(pid, (LPCVOID)hp.address);
148 if (allocationBase) 149 if (allocationBase)
149 { 150 {
150 std::wstring path = GetModuleFileNameAsString(pid, allocationBase); 151 std::wstring path = GetModuleFileNameAsString(pid, allocationBase);
151 if (!path.empty()) 152 if (!path.empty())
152 { 153 {
153 auto fileName = path.substr(path.rfind(L'\\') + 1); 154 auto fileName = path.substr(path.rfind(L'\\') + 1);
154 - DWORD relativeHookAddress = hp.addr - (DWORD)allocationBase; 155 + DWORD relativeHookAddress = hp.address - (DWORD)allocationBase;
155 code += L"@" + ToHexString(relativeHookAddress) + L":" + fileName; 156 code += L"@" + ToHexString(relativeHookAddress) + L":" + fileName;
156 return code; 157 return code;
157 } 158 }
...@@ -159,20 +160,20 @@ std::wstring GetCode(const HookParam& hp, DWORD pid) ...@@ -159,20 +160,20 @@ std::wstring GetCode(const HookParam& hp, DWORD pid)
159 } 160 }
160 if (hp.module) 161 if (hp.module)
161 { 162 {
162 - code += L"@" + ToHexString(hp.addr) + L"!" + ToHexString(hp.module); 163 + code += L"@" + ToHexString(hp.address) + L"!" + ToHexString(hp.module);
163 if (hp.function) 164 if (hp.function)
164 code += L"!" + ToHexString(hp.function); 165 code += L"!" + ToHexString(hp.function);
165 } 166 }
166 else 167 else
167 { 168 {
168 - // hack, the original address is stored in the function field 169 + // Hack. The original address is stored in the function field
169 - // if (module == NULL && function != NULL) 170 + // if (module == NULL && function != NULL).
170 - // in TextHook::UnsafeInsertHookCode() MODULE_OFFSET and FUNCTION_OFFSET are removed from 171 + // MODULE_OFFSET and FUNCTION_OFFSET are removed from HookParam.type in
171 - // HookParam.type 172 + // TextHook::UnsafeInsertHookCode() and can not be used here.
172 if (hp.function) 173 if (hp.function)
173 code += L"@" + ToHexString(hp.function); 174 code += L"@" + ToHexString(hp.function);
174 else 175 else
175 - code += L"@" + ToHexString(hp.addr) + L":"; 176 + code += L"@" + ToHexString(hp.address) + L":";
176 } 177 }
177 return code; 178 return code;
178 } 179 }
...@@ -282,13 +283,13 @@ HANDLE IthCreateFile(LPCWSTR name, DWORD option, DWORD share, DWORD disposition) ...@@ -282,13 +283,13 @@ HANDLE IthCreateFile(LPCWSTR name, DWORD option, DWORD share, DWORD disposition)
282 return CreateFile(path.c_str(), option, share, NULL, disposition, FILE_ATTRIBUTE_NORMAL, NULL); 283 return CreateFile(path.c_str(), option, share, NULL, disposition, FILE_ATTRIBUTE_NORMAL, NULL);
283 } 284 }
284 285
285 -//SJIS->Unicode. 'mb' must be null-terminated. 'wc_length' is the length of 'wc' in characters. 286 +//SJIS->Unicode. mb must be null-terminated. wc_length is the length of wc in characters.
286 int MB_WC(const char* mb, wchar_t* wc, int wc_length) 287 int MB_WC(const char* mb, wchar_t* wc, int wc_length)
287 { 288 {
288 return MultiByteToWideChar(932, 0, mb, -1, wc, wc_length); 289 return MultiByteToWideChar(932, 0, mb, -1, wc, wc_length);
289 } 290 }
290 291
291 -// Count characters in wide string. 'mb_length' is the number of bytes from 'mb' to convert or 292 +// Count characters in wide string. mb_length is the number of bytes from mb to convert or
292 // -1 if the string is null terminated. 293 // -1 if the string is null terminated.
293 int MB_WC_count(const char* mb, int mb_length) 294 int MB_WC_count(const char* mb, int mb_length)
294 { 295 {
...@@ -300,12 +301,3 @@ int WC_MB(const wchar_t *wc, char* mb, int mb_length) ...@@ -300,12 +301,3 @@ int WC_MB(const wchar_t *wc, char* mb, int mb_length)
300 { 301 {
301 return WideCharToMultiByte(932, 0, wc, -1, mb, mb_length, NULL, NULL); 302 return WideCharToMultiByte(932, 0, wc, -1, mb, mb_length, NULL, NULL);
302 } 303 }
303 -
304 -DWORD Hash(const std::wstring& module, int length)
305 -{
306 - DWORD hash = 0;
307 - auto end = length < 0 || static_cast<std::size_t>(length) > module.length() ? module.end() : module.begin() + length;
308 - for (auto it = module.begin(); it != end; ++it)
309 - hash = _rotr(hash, 7) + *it;
310 - return hash;
311 -}
......
1 #pragma once 1 #pragma once
2 +
2 #include "ITH.h" 3 #include "ITH.h"
3 4
4 struct HookParam; 5 struct HookParam;
5 struct ProcessRecord; 6 struct ProcessRecord;
6 7
7 -DWORD Hash(const std::wstring& module, int length = -1);
8 DWORD ProcessCommand(const std::wstring& cmd, DWORD pid); 8 DWORD ProcessCommand(const std::wstring& cmd, DWORD pid);
9 std::wstring GetProcessPath(DWORD pid); 9 std::wstring GetProcessPath(DWORD pid);
10 void ConsoleOutput(LPCWSTR); 10 void ConsoleOutput(LPCWSTR);
...@@ -58,13 +58,6 @@ int MB_WC_count(const char* mb, int mb_length); ...@@ -58,13 +58,6 @@ int MB_WC_count(const char* mb, int mb_length);
58 int WC_MB(const wchar_t *wc, char* mb, int mb_length); 58 int WC_MB(const wchar_t *wc, char* mb, int mb_length);
59 bool Parse(const std::wstring& cmd, HookParam& hp); 59 bool Parse(const std::wstring& cmd, HookParam& hp);
60 60
61 -template <typename T>
62 -std::wstring ToHexString(T i) {
63 - std::wstringstream ss;
64 - ss << std::uppercase << std::hex << i;
65 - return ss.str();
66 -}
67 -
68 // http://jrdodds.blogs.com/blog/2004/08/raii_in_c.html 61 // http://jrdodds.blogs.com/blog/2004/08/raii_in_c.html
69 class CriticalSection 62 class CriticalSection
70 { 63 {
......
This diff is collapsed. Click to expand it.
...@@ -16,4 +16,5 @@ ...@@ -16,4 +16,5 @@
16 */ 16 */
17 17
18 #pragma once 18 #pragma once
19 +
19 #include "ITH.h" 20 #include "ITH.h"
......
1 +# config.pri
2 +# DEFINES += _SECURE_SCL=0 _SCL_SECURE_NO_WARNINGS
3 +# DEFINES += _CRT_SECURE_NO_WARNINGS
4 +
1 cmake_minimum_required(VERSION 2.8) 5 cmake_minimum_required(VERSION 2.8)
2 6
3 set(CMAKE_CONFIGURATION_TYPES Debug Release) 7 set(CMAKE_CONFIGURATION_TYPES Debug Release)
4 8
5 project(vnr) 9 project(vnr)
6 10
7 -set(WDK_HOME "C:\\WinDDK\\7600.16385.1" CACHE FILEPATH "path to the Windows DDK directory") 11 +set(WDK_HOME "C:\\WinDDK\\7600.16385.1" CACHE FILEPATH "Windows Driver Kit path")
8 12
9 add_definitions( 13 add_definitions(
10 - -DUNICODE 14 + /DUNICODE
11 - -D_UNICODE 15 + /D_UNICODE
16 + /D_SECURE_SCL=0
17 + /D_SCL_SECURE_NO_WARNINGS
18 + /D_CRT_SECURE_NO_WARNINGS
12 ) 19 )
13 20
14 -include_directories(${PROJECT_SOURCE_DIR}) 21 +include_directories(
15 - 22 + ${PROJECT_SOURCE_DIR}
16 -set(common_src 23 + ${PROJECT_SOURCE_DIR}/texthook
17 - ${PROJECT_SOURCE_DIR}/ith/common/const.h
18 - ${PROJECT_SOURCE_DIR}/ith/common/defs.h
19 - ${PROJECT_SOURCE_DIR}/ith/common/except.h
20 - ${PROJECT_SOURCE_DIR}/ith/common/growl.h
21 - ${PROJECT_SOURCE_DIR}/ith/common/memory.h
22 - ${PROJECT_SOURCE_DIR}/ith/common/types.h
23 -)
24 -
25 -set(import_src
26 - ${PROJECT_SOURCE_DIR}/ith/import/mono/funcinfo.h
27 - ${PROJECT_SOURCE_DIR}/ith/import/mono/types.h
28 - ${PROJECT_SOURCE_DIR}/ith/import/ppsspp/funcinfo.h
29 ) 24 )
30 25
31 -add_subdirectory(ith/hook) 26 +add_subdirectory(vnrhook)
32 -add_subdirectory(ith/host) 27 +add_subdirectory(texthook/host)
33 -add_subdirectory(ith/sys) 28 +add_subdirectory(ithsys)
29 +add_subdirectory(profile)
......
...@@ -72,8 +72,8 @@ win32 { ...@@ -72,8 +72,8 @@ win32 {
72 ## External Libraries 72 ## External Libraries
73 73
74 win32 { 74 win32 {
75 - D3D_HOME = "$$PROGRAMFILES/Microsoft DirectX SDK" 75 + D3D_HOME = "C:/Program Files/Microsoft DirectX SDK"
76 - DETOURS_HOME = "$$PROGRAMFILES/Microsoft Research/Detours Express 3.0" 76 + DETOURS_HOME = "C:/Program Files/Microsoft Research/Detours Express 3.0"
77 #DEV_HOME = c:/dev 77 #DEV_HOME = c:/dev
78 DEV_HOME = z:/local/windows/developer 78 DEV_HOME = z:/local/windows/developer
79 BOOST_HOME = $$DEV_HOME/boost/build 79 BOOST_HOME = $$DEV_HOME/boost/build
...@@ -81,8 +81,8 @@ win32 { ...@@ -81,8 +81,8 @@ win32 {
81 MSIME_HOME = $$DEV_HOME/msime 81 MSIME_HOME = $$DEV_HOME/msime
82 #PYTHON_HOME = $$ROOTDIR/../Python 82 #PYTHON_HOME = $$ROOTDIR/../Python
83 #PYTHON_HOME = C:/Python 83 #PYTHON_HOME = C:/Python
84 - PYTHON_HOME = Z:/Local/Windows/Developer/Python 84 + PYTHON_HOME = $$DEV_HOME/python
85 - PYSIDE_HOME = $$PYTHON_HOME/Lib/site-packages/PySide 85 + PYSIDE_HOME = $$PYTHON_HOME/lib/site-packages/PySide
86 QT_HOME = c:/qt/4 86 QT_HOME = c:/qt/4
87 QT_SRC = c:/qt 87 QT_SRC = c:/qt
88 SAPI_HOME = "$$PROGRAMFILES/Microsoft Speech SDK 5.1" 88 SAPI_HOME = "$$PROGRAMFILES/Microsoft Speech SDK 5.1"
...@@ -161,7 +161,7 @@ win32 { ...@@ -161,7 +161,7 @@ win32 {
161 QMAKE_CXXFLAGS_EXCEPTIONS_ON += -EHa 161 QMAKE_CXXFLAGS_EXCEPTIONS_ON += -EHa
162 } 162 }
163 163
164 - CONFIG(noeh) { # No Exception handler 164 + CONFIG(noeh) { # No exception handler
165 message(CONFIG noeh) 165 message(CONFIG noeh)
166 #CONFIG -= rtti #-exceptions -stl 166 #CONFIG -= rtti #-exceptions -stl
167 QMAKE_CXXFLAGS += /GR- 167 QMAKE_CXXFLAGS += /GR-
...@@ -175,7 +175,7 @@ win32 { ...@@ -175,7 +175,7 @@ win32 {
175 } 175 }
176 } 176 }
177 177
178 - CONFIG(nosafeseh) { # No Exception handler 178 + CONFIG(nosafeseh) { # No safe exception handler
179 message(CONFIG nosafeseh) 179 message(CONFIG nosafeseh)
180 180
181 # Disable SafeSEH table 181 # Disable SafeSEH table
......
1 @echo off 1 @echo off
2 setlocal 2 setlocal
3 if [%1] == [] ( 3 if [%1] == [] (
4 - echo usage: copy_vnr <path-to-Sakura-directory> 4 + echo usage: copy_vnr path_to_Sakura
5 goto :EOF 5 goto :EOF
6 ) 6 )
7 xcopy %1\config.pri . /S /Y /I 7 xcopy %1\config.pri . /S /Y /I
8 xcopy %1\cpp\libs\ccutil ccutil /S /Y /I 8 xcopy %1\cpp\libs\ccutil ccutil /S /Y /I
9 xcopy %1\cpp\libs\cpputil cpputil /S /Y /I 9 xcopy %1\cpp\libs\cpputil cpputil /S /Y /I
10 xcopy %1\cpp\libs\disasm disasm /S /Y /I /EXCLUDE:exclude.txt 10 xcopy %1\cpp\libs\disasm disasm /S /Y /I /EXCLUDE:exclude.txt
11 -xcopy %1\cpp\plugins\ith ith /S /Y /I 11 +xcopy %1\cpp\libs\hashutil hashutil /S /Y /I
12 +xcopy %1\cpp\plugins\ithsys ithsys /S /Y /I
13 +xcopy %1\cpp\plugins\vnrhook vnrhook /S /Y /I
14 +xcopy %1\cpp\plugins\texthook texthook /S /Y /I /EXCLUDE:exclude.txt
12 xcopy %1\cpp\libs\memdbg memdbg /S /Y /I 15 xcopy %1\cpp\libs\memdbg memdbg /S /Y /I
13 xcopy %1\cpp\libs\ntdll ntdll /S /Y /I 16 xcopy %1\cpp\libs\ntdll ntdll /S /Y /I
14 xcopy %1\cpp\libs\ntinspect ntinspect /S /Y /I 17 xcopy %1\cpp\libs\ntinspect ntinspect /S /Y /I
18 +xcopy %1\cpp\libs\winkey winkey /S /Y /I
15 xcopy %1\cpp\libs\winmaker winmaker /S /Y /I 19 xcopy %1\cpp\libs\winmaker winmaker /S /Y /I
16 xcopy %1\cpp\libs\winmutex winmutex /S /Y /I 20 xcopy %1\cpp\libs\winmutex winmutex /S /Y /I
17 xcopy %1\cpp\libs\winversion winversion /S /Y /I 21 xcopy %1\cpp\libs\winversion winversion /S /Y /I
18 xcopy %1\cpp\libs\winseh winseh /S /Y /I 22 xcopy %1\cpp\libs\winseh winseh /S /Y /I
23 +xcopy %1\cpp\libs\wintimer wintimer /S /Y /I
24 +xcopy %1\cpp\libs\windbg windbg /S /Y /I
25 +xcopy %1\cpp\libs\sakurakit sakurakit /S /Y /I
26 +xcopy %1\cpp\libs\mono mono /S /Y /I
19 27
20 endlocal 28 endlocal
......
...@@ -19,8 +19,8 @@ inline size_t cpp_basic_strlen(const charT *s) ...@@ -19,8 +19,8 @@ inline size_t cpp_basic_strlen(const charT *s)
19 return p - s; 19 return p - s;
20 } 20 }
21 21
22 -inline size_t cpp_strlen(const char *s) { return cpp_basic_strlen(s); } 22 +inline size_t cpp_strlen(const char *s) { return cpp_basic_strlen<char>(s); }
23 -inline size_t cpp_wstrlen(const wchar_t *s) { return cpp_basic_strlen(s); } 23 +inline size_t cpp_wstrlen(const wchar_t *s) { return cpp_basic_strlen<wchar_t>(s); }
24 24
25 template <typename charT> 25 template <typename charT>
26 inline size_t cpp_basic_strnlen(const charT *s, size_t n) 26 inline size_t cpp_basic_strnlen(const charT *s, size_t n)
...@@ -30,8 +30,8 @@ inline size_t cpp_basic_strnlen(const charT *s, size_t n) ...@@ -30,8 +30,8 @@ inline size_t cpp_basic_strnlen(const charT *s, size_t n)
30 return p - s; 30 return p - s;
31 } 31 }
32 32
33 -inline size_t cpp_strnlen(const char *s, size_t n) { return cpp_basic_strnlen(s, n); } 33 +inline size_t cpp_strnlen(const char *s, size_t n) { return cpp_basic_strnlen<char>(s, n); }
34 -inline size_t cpp_wstrnlen(const wchar_t *s, size_t n) { return cpp_basic_strnlen(s, n); } 34 +inline size_t cpp_wstrnlen(const wchar_t *s, size_t n) { return cpp_basic_strnlen<wchar_t>(s, n); }
35 35
36 // strnchr 36 // strnchr
37 37
...@@ -45,19 +45,15 @@ inline size_t cpp_wstrnlen(const wchar_t *s, size_t n) { return cpp_basic_strnle ...@@ -45,19 +45,15 @@ inline size_t cpp_wstrnlen(const wchar_t *s, size_t n) { return cpp_basic_strnle
45 return nullptr; \ 45 return nullptr; \
46 } 46 }
47 template <typename charT> 47 template <typename charT>
48 -inline charT *cpp_basic_strnchr(charT *s, int c, size_t n) 48 +inline charT *cpp_basic_strnchr(charT *s, charT c, size_t n) cpp_basic_strnchr_(s, c, n)
49 -cpp_basic_strnchr_(s, c, n)
50 -
51 template <typename charT> 49 template <typename charT>
52 -inline const charT *cpp_basic_strnchr(const charT *s, int c, size_t n) 50 +inline const charT *cpp_basic_strnchr(const charT *s, charT c, size_t n) cpp_basic_strnchr_(s, c, n)
53 -cpp_basic_strnchr_(s, c, n)
54 51
55 // The same as memchr 52 // The same as memchr
56 -inline char *cpp_strnchr(char *s, int c, size_t n) { return cpp_basic_strnchr(s, c, n); } 53 +inline char *cpp_strnchr(char *s, char c, size_t n) { return cpp_basic_strnchr<char>(s, c, n); }
57 -inline const char *cpp_strnchr(const char *s, int c, size_t n) { return cpp_basic_strnchr(s, c, n); } 54 +inline const char *cpp_strnchr(const char *s, char c, size_t n) { return cpp_basic_strnchr<char>(s, c, n); }
58 - 55 +inline wchar_t *cpp_wcsnchr(wchar_t *s, wchar_t c, size_t n) { return cpp_basic_strnchr<wchar_t>(s, c, n); }
59 -inline wchar_t *cpp_wcsnchr(wchar_t *s, int c, size_t n) { return cpp_basic_strnchr(s, c, n); } 56 +inline const wchar_t *cpp_wcsnchr(const wchar_t *s, wchar_t c, size_t n) { return cpp_basic_strnchr<wchar_t>(s, c, n); }
60 -inline const wchar_t *cpp_wcsnchr(const wchar_t *s, int c, size_t n) { return cpp_basic_strnchr(s, c, n); }
61 57
62 // strnstr 58 // strnstr
63 59
...@@ -72,25 +68,19 @@ inline const wchar_t *cpp_wcsnchr(const wchar_t *s, int c, size_t n) { return cp ...@@ -72,25 +68,19 @@ inline const wchar_t *cpp_wcsnchr(const wchar_t *s, int c, size_t n) { return cp
72 } 68 }
73 69
74 template <typename charT> 70 template <typename charT>
75 -inline charT *cpp_basic_strnstr(charT *s, const charT *r, size_t n) 71 +inline charT *cpp_basic_strnstr(charT *s, const charT *r, size_t n) cpp_basic_strnstr_(s, n, r, ::strlen(r), ::strncmp)
76 -cpp_basic_strnstr_(s, n, r, ::strlen(r), ::strncmp)
77 -
78 template <typename charT> 72 template <typename charT>
79 -inline const charT *cpp_basic_strnstr(const charT *s, const charT *r, size_t n) 73 +inline const charT *cpp_basic_strnstr(const charT *s, const charT *r, size_t n) cpp_basic_strnstr_(s, n, r, ::strlen(r), ::strncmp)
80 -cpp_basic_strnstr_(s, n, r, ::strlen(r), ::strncmp)
81 74
82 template <> 75 template <>
83 -inline wchar_t *cpp_basic_strnstr<wchar_t>(wchar_t *s, const wchar_t *r, size_t n) 76 +inline wchar_t *cpp_basic_strnstr<wchar_t>(wchar_t *s, const wchar_t *r, size_t n) cpp_basic_strnstr_(s, n, r, ::wcslen(r), ::wcsncmp)
84 -cpp_basic_strnstr_(s, n, r, ::wcslen(r), ::wcsncmp)
85 -
86 template <> 77 template <>
87 -inline const wchar_t *cpp_basic_strnstr<wchar_t>(const wchar_t *s, const wchar_t *r, size_t n) 78 +inline const wchar_t *cpp_basic_strnstr<wchar_t>(const wchar_t *s, const wchar_t *r, size_t n) cpp_basic_strnstr_(s, n, r, ::wcslen(r), ::wcsncmp)
88 -cpp_basic_strnstr_(s, n, r, ::wcslen(r), ::wcsncmp)
89 79
90 -inline char *cpp_strnstr(char *s, const char *r, size_t n) { return cpp_basic_strnstr(s, r, n); } 80 +inline char *cpp_strnstr(char *s, const char *r, size_t n) { return cpp_basic_strnstr<char>(s, r, n); }
91 -inline const char *cpp_strnstr(const char *s, const char *r, size_t n) { return cpp_basic_strnstr(s, r, n); } 81 +inline const char *cpp_strnstr(const char *s, const char *r, size_t n) { return cpp_basic_strnstr<char>(s, r, n); }
92 -inline wchar_t *cpp_wcsnstr(wchar_t *s, const wchar_t *r, size_t n) { return cpp_basic_strnstr(s, r, n); } 82 +inline wchar_t *cpp_wcsnstr(wchar_t *s, const wchar_t *r, size_t n) { return cpp_basic_strnstr<wchar_t>(s, r, n); }
93 -inline const wchar_t *cpp_wcsnstr(const wchar_t *s, const wchar_t *r, size_t n) { return cpp_basic_strnstr(s, r, n); } 83 +inline const wchar_t *cpp_wcsnstr(const wchar_t *s, const wchar_t *r, size_t n) { return cpp_basic_strnstr<wchar_t>(s, r, n); }
94 84
95 // strnpbrk 85 // strnpbrk
96 86
......
...@@ -4,9 +4,23 @@ ...@@ -4,9 +4,23 @@
4 // cpplocale.h 4 // cpplocale.h
5 // 9/26/2014 jichi 5 // 9/26/2014 jichi
6 6
7 -#include <codecvt>
8 #include <locale> 7 #include <locale>
9 8
9 +#ifdef WITHOUT_CXX_CODECVT
10 +// http://www.boost.org/doc/libs/1_48_0/libs/serialization/doc/codecvt.html
11 +# define BOOST_UTF8_BEGIN_NAMESPACE
12 +# define BOOST_UTF8_END_NAMESPACE
13 +# define BOOST_UTF8_DECL
14 +# include <boost/detail/utf8_codecvt_facet.hpp>
15 +# include <boost/detail/utf8_codecvt_facet.ipp> // WARNING: This implementation should only be included ONCE
16 +# define CPPLOCALE_NEW_FACET_UTF8(charT) (new utf8_codecvt_facet) // charT is ignored and assumed to be wchar_t
17 +//# include <boost/detail/serialization/utf8_codecvt_facet.hpp>
18 +//# define CPPLOCALE_NEW_FACET_UTF8(charT) (new utf8_codecvt_facet<charT>)
19 +#else
20 +# include <codecvt>
21 +# define CPPLOCALE_NEW_FACET_UTF8(charT) (new std::codecvt_utf8<charT, 0x10ffff, std::consume_header>)
22 +#endif // WITHOUT_CXX_CODECVT
23 +
10 //#include <boost/locale.hpp> 24 //#include <boost/locale.hpp>
11 25
12 // See: http://stackoverflow.com/questions/20195262/how-to-read-an-utf-8-encoded-file-containing-chinese-characters-and-output-them 26 // See: http://stackoverflow.com/questions/20195262/how-to-read-an-utf-8-encoded-file-containing-chinese-characters-and-output-them
...@@ -15,7 +29,7 @@ ...@@ -15,7 +29,7 @@
15 // - 0x10ffff is the default maximum value. 29 // - 0x10ffff is the default maximum value.
16 // - std::consume_header will skip the leading encoding byte from the input. 30 // - std::consume_header will skip the leading encoding byte from the input.
17 template <class charT> 31 template <class charT>
18 -inline std::locale cpp_utf8_locale(std::locale init = std::locale()) 32 +inline std::locale cpp_utf8_locale(std::locale init = std::locale()) //::empty())
19 -{ return std::locale(init, new std::codecvt_utf8<charT, 0x10ffff, std::consume_header>()); } 33 +{ return std::locale(init, CPPLOCALE_NEW_FACET_UTF8(charT)); }
20 34
21 #endif // CPPLOCALE_H 35 #endif // CPPLOCALE_H
......
...@@ -4,33 +4,15 @@ ...@@ -4,33 +4,15 @@
4 // cppstring.h 4 // cppstring.h
5 // 10/12/2014 jichi 5 // 10/12/2014 jichi
6 6
7 -#include <cstring> 7 +/#include <string>
8 -#include <string>
9 8
10 // Initializers 9 // Initializers
11 10
12 -template <typename charT, typename stringT> 11 +template <typename charT>
13 -inline std::basic_string<charT> cpp_basic_string_of(const stringT &s) 12 +inline std::basic_string<charT> cpp_basic_string_of(const std::string &s)
14 -{ return std::basic_string<charT>(s.cbegin(), s.cend()); } 13 +{ return std::basic_string<charT>(s.begin(), s.end()); }
15 14
16 -template <typename stringT> 15 +inline std::wstring cpp_wstring_of(const std::string &s)
17 -inline std::string cpp_string_of(const stringT &s) 16 +{ return std::wstring(s.begin(), s.end()); }
18 -{ return std::string(s.cbegin(), s.cend()); }
19 -
20 -inline std::string cpp_string_of(const char *s)
21 -{ return s; }
22 -
23 -inline std::string cpp_string_of(const wchar_t *s)
24 -{ return std::string(s, s + ::wcslen(s)); }
25 -
26 -template <typename stringT>
27 -inline std::wstring cpp_wstring_of(const stringT &s)
28 -{ return std::wstring(s.cbegin(), s.cend()); }
29 -
30 -inline std::wstring cpp_wstring_of(const wchar_t *s)
31 -{ return s; }
32 -
33 -inline std::wstring cpp_wstring_of(const char *s)
34 -{ return std::wstring(s, s + ::strlen(s)); }
35 17
36 #endif // CPPSTRING_H 18 #endif // CPPSTRING_H
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
9 // 3024b815 0f1302 movlps qword ptr ds:[edx],xmm0 9 // 3024b815 0f1302 movlps qword ptr ds:[edx],xmm0
10 10
11 #include "disasm.h" 11 #include "disasm.h"
12 +#include <windows.h>
12 13
13 // disasm_flag values: 14 // disasm_flag values:
14 enum : unsigned { 15 enum : unsigned {
...@@ -29,21 +30,22 @@ DISASM_BEGIN_NAMESPACE ...@@ -29,21 +30,22 @@ DISASM_BEGIN_NAMESPACE
29 // But the are currently unused and could make disasm thread-unsafe 30 // But the are currently unused and could make disasm thread-unsafe
30 namespace { // unnamed 31 namespace { // unnamed
31 32
32 -BYTE disasm_seg, // CS DS ES SS FS GS 33 +BYTE disasm_seg // CS DS ES SS FS GS
33 - disasm_rep, // REPZ/REPNZ 34 + , disasm_rep // REPZ/REPNZ
34 - disasm_opcode, // opcode 35 + , disasm_opcode // opcode
35 - disasm_opcode2, // used when opcode==0f 36 + , disasm_opcode2 // used when opcode==0f
36 - disasm_modrm, // modxxxrm 37 + , disasm_modrm // modxxxrm
37 - disasm_sib, // scale-index-base 38 + , disasm_sib // scale-index-base
38 - disasm_mem[8], // mem addr value 39 + , disasm_mem[8] // mem addr value
39 - disasm_data[8]; // data value 40 + , disasm_data[8] // data value
41 + ;
40 42
41 } // unnamed namespace 43 } // unnamed namespace
42 44
43 // return: length if success, 0 if error 45 // return: length if success, 0 if error
44 -int disasm(const BYTE *opcode0) 46 +size_t disasm(const void *opcode0)
45 { 47 {
46 - const BYTE *opcode = opcode0; 48 + const BYTE *opcode = (const BYTE *)opcode0;
47 49
48 DWORD disasm_len = 0, // 0 if error 50 DWORD disasm_len = 0, // 0 if error
49 disasm_flag = 0, // C_xxx 51 disasm_flag = 0, // C_xxx
...@@ -253,7 +255,7 @@ retry: ...@@ -253,7 +255,7 @@ retry:
253 for (DWORD i = 0; i < disasm_datasize; i++) 255 for (DWORD i = 0; i < disasm_datasize; i++)
254 disasm_data[i] = *opcode++; 256 disasm_data[i] = *opcode++;
255 257
256 - disasm_len = opcode - opcode0; 258 + disasm_len = opcode - (const BYTE *)opcode0;
257 259
258 return disasm_len; 260 return disasm_len;
259 } // disasm 261 } // disasm
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
4 4
5 // Include typedef of BYTE 5 // Include typedef of BYTE
6 //#include <windef.h> 6 //#include <windef.h>
7 -#include <windows.h> 7 +//#include <windows.h>
8 8
9 //#ifdef QT_CORE_LIB 9 //#ifdef QT_CORE_LIB
10 //# include <qt_windows.h> 10 //# include <qt_windows.h>
...@@ -20,7 +20,13 @@ ...@@ -20,7 +20,13 @@
20 #endif 20 #endif
21 21
22 DISASM_BEGIN_NAMESPACE 22 DISASM_BEGIN_NAMESPACE
23 -int disasm(const BYTE *opcode0); // return: op length if success, 0 if error 23 +/**
24 + * This function can do more, but currently only used to estimate the length of an instruction.
25 + * Warning: The current implementation is stateful and hence not thread-safe.
26 + * @param address of the instruction to look at
27 + * @return length of the instruction at the address or 0 if failed
28 + */
29 +size_t disasm(const void *address);
24 DISASM_END_NAMESPACE 30 DISASM_END_NAMESPACE
25 31
26 // EOF 32 // EOF
......
1 +#ifndef HASHSTR_H
2 +#define HASHSTR_H
3 +
4 +// hashstr.h
5 +// 8/1/2011
6 +// See: http://www.cse.yorku.ca/~oz/hash.html
7 +
8 +#include "hashutil/hashutil.h"
9 +#include <cstdint>
10 +
11 +HASHUTIL_BEGIN_NAMESPACE
12 +
13 +enum : uint64_t { djb2_hash0 = 5381 };
14 +
15 +/// djb2: h = h*33 + c
16 +template <typename charT>
17 +inline uint64_t djb2(const charT *str, uint64_t hash = djb2_hash0)
18 +{
19 + charT c;
20 + while ((c = *str++))
21 + hash = ((hash << 5) + hash) + c; // hash * 33 + c
22 + return hash;
23 +}
24 +
25 +/// n: length
26 +template <typename charT>
27 +inline uint64_t djb2_n(const charT *str, size_t len, uint64_t hash = djb2_hash0)
28 +{
29 + while (len--)
30 + hash = ((hash << 5) + hash) + (*str++); // hash * 33 + c
31 + return hash;
32 +}
33 +
34 +/// sdbm: hash(i) = hash(i - 1) * 65599 + str[i];
35 +template <typename charT>
36 +inline uint64_t sdbm(const charT *str, uint64_t hash = 0)
37 +{
38 + charT c;
39 + while ((c = *str++))
40 + hash = c + (hash << 6) + (hash << 16) - hash;
41 + return hash;
42 +}
43 +
44 +template <typename charT>
45 +inline uint64_t loselose(const charT *str, uint64_t hash = 0)
46 +{
47 + charT c;
48 + while ((c = *str++))
49 + hash += c;
50 + return hash;
51 +}
52 +
53 +HASHUTIL_END_NAMESPACE
54 +
55 +#endif // HASHSTR_H
1 +#ifndef HASHUTIL_H
2 +#define HASHUTIL_H
3 +
4 +// hashutil.h
5 +// 6/16/2015 jichi
6 +
7 +// Redefine HASHUTIL_BEGIN_NAMESPACE/HASHUTIL_END_NAMESPACE if need custom namespace
8 +#ifndef HASHUTIL_BEGIN_NAMESPACE
9 +# define HASHUTIL_BEGIN_NAMESPACE namespace hashutil {
10 +#endif
11 +#ifndef HASHUTIL_END_NAMESPACE
12 +# define HASHUTIL_END_NAMESPACE } // namespace hashutil
13 +#endif
14 +
15 +#endif // HASHUTIL_H
1 +# hashutil.pri
2 +# 6/28/2011 jichi
3 +
4 +DEFINES += WITH_LIB_HASHUTIL
5 +DEPENDPATH += $$PWD
6 +
7 +HEADERS += \
8 + $$PWD/hashstr.h \
9 + $$PWD/hashutil.h
10 +
11 +# EOF
1 +# # ithsys.pro
2 +# CONFIG += noqt staticlib
3 +# include(../../../config.pri)
4 +
5 +# # jichi 7/12/2015: Always enable SEH
6 +# DEFINES += ITH_HAS_SEH
7 +
8 +# DEFINES += _CRT_NON_CONFORMING_SWPRINTFS
9 +
10 +set(ithsys_src
11 + ithsys.h
12 + ithsys.cc
13 +)
14 +
15 +add_library(ithsys STATIC ${ithsys_src})
16 +
17 +target_compile_options(ithsys PRIVATE
18 + $<$<CONFIG:Release>:>
19 + $<$<CONFIG:Debug>:>
20 +)
21 +
22 +target_link_libraries(ithsys comctl32.lib)
23 +
24 +target_compile_definitions(ithsys
25 + PRIVATE
26 + ITH_HAS_SEH
27 + _CRT_NON_CONFORMING_SWPRINTFS
28 +)
This diff is collapsed. Click to expand it.
1 +#pragma once
2 +
3 +// ithsys.h
4 +// 8/23/2013 jichi
5 +// Branch: ITH/IHF_SYS.h, rev 111
6 +
7 +#ifdef _MSC_VER
8 +# pragma warning(disable:4800) // C4800: forcing value to bool
9 +#endif // _MSC_VER
10 +
11 +#include "ntdll/ntdll.h"
12 +
13 +// jichi 8/24/2013: Why extern "C"? Any specific reason to use C instead of C++ naming?
14 +extern "C" {
15 +//int disasm(BYTE *opcode0); // jichi 8/15/2013: move disasm to separate file
16 +extern WORD *NlsAnsiCodePage;
17 +int FillRange(LPCWSTR name,DWORD *lower, DWORD *upper);
18 +int MB_WC(char *mb, wchar_t *wc);
19 +//int MB_WC_count(char *mb, int mb_length);
20 +int WC_MB(wchar_t *wc, char *mb);
21 +
22 +// jichi 10/1/2013: Return 0 if failed. So, it is ambiguous if the search pattern starts at 0
23 +DWORD SearchPattern(DWORD base, DWORD base_length, LPCVOID search, DWORD search_length); // KMP
24 +
25 +// jichi 2/5/2014: The same as SearchPattern except it uses 0xff to match everything
26 +// According to @Andys, 0xff seldom appear in the source code: http://sakuradite.com/topic/124
27 +enum : BYTE { SP_ANY = 0xff };
28 +#define SP_ANY_2 SP_ANY,SP_ANY
29 +#define SP_ANY_3 SP_ANY,SP_ANY,SP_ANY
30 +#define SP_ANY_4 SP_ANY,SP_ANY,SP_ANY,SP_ANY
31 +DWORD SearchPatternEx(DWORD base, DWORD base_length, LPCVOID search, DWORD search_length, BYTE wildcard=SP_ANY);
32 +
33 +BOOL IthInitSystemService();
34 +void IthCloseSystemService();
35 +DWORD IthGetMemoryRange(LPCVOID mem, DWORD *base, DWORD *size);
36 +BOOL IthCheckFile(LPCWSTR file);
37 +BOOL IthFindFile(LPCWSTR file);
38 +BOOL IthGetFileInfo(LPCWSTR file, LPVOID info, DWORD size = 0x1000);
39 +BOOL IthCheckFileFullPath(LPCWSTR file);
40 +HANDLE IthCreateFile(LPCWSTR name, DWORD option, DWORD share, DWORD disposition);
41 +HANDLE IthCreateFileInDirectory(LPCWSTR name, HANDLE dir, DWORD option, DWORD share, DWORD disposition);
42 +HANDLE IthCreateDirectory(LPCWSTR name);
43 +HANDLE IthCreateFileFullPath(LPCWSTR fullpath, DWORD option, DWORD share, DWORD disposition);
44 +HANDLE IthPromptCreateFile(DWORD option, DWORD share, DWORD disposition);
45 +HANDLE IthCreateSection(LPCWSTR name, DWORD size, DWORD right);
46 +HANDLE IthCreateEvent(LPCWSTR name, DWORD auto_reset=0, DWORD init_state=0);
47 +HANDLE IthOpenEvent(LPCWSTR name);
48 +void IthSetEvent(HANDLE hEvent);
49 +void IthResetEvent(HANDLE hEvent);
50 +HANDLE IthCreateMutex(LPCWSTR name, BOOL InitialOwner, DWORD *exist=0);
51 +HANDLE IthOpenMutex(LPCWSTR name);
52 +BOOL IthReleaseMutex(HANDLE hMutex);
53 +//DWORD IthWaitForSingleObject(HANDLE hObject, DWORD dwTime);
54 +HANDLE IthCreateThread(LPCVOID start_addr, DWORD param, HANDLE hProc=(HANDLE)-1);
55 +DWORD GetExportAddress(DWORD hModule,DWORD hash);
56 +void IthSleep(int time); // jichi 9/28/2013: in ms
57 +void IthSystemTimeToLocalTime(LARGE_INTEGER *ptime);
58 +void FreeThreadStart(HANDLE hProc);
59 +void CheckThreadStart();
60 +} // extern "C"
61 +
62 +#ifdef ITH_HAS_HEAP
63 +extern HANDLE hHeap; // used in ith/common/memory.h
64 +#endif // ITH_HAS_HEAP
65 +
66 +extern DWORD current_process_id;
67 +extern DWORD debug;
68 +extern BYTE LeadByteTable[];
69 +extern LPVOID page;
70 +extern BYTE launch_time[];
71 +
72 +inline DWORD GetHash(LPSTR str)
73 +{
74 + DWORD hash = 0;
75 + //for (; *str; str++)
76 + while (*str)
77 + hash = ((hash>>7) | (hash<<25)) + *str++;
78 + return hash;
79 +}
80 +
81 +inline DWORD GetHash(LPCWSTR str)
82 +{
83 + DWORD hash = 0;
84 + //for (; *str; str++)
85 + while (*str)
86 + hash = ((hash>>7) | (hash<<25)) + *str++;
87 + return hash;
88 +}
89 +
90 +inline void IthBreak()
91 +{ if (debug) __debugbreak(); }
92 +
93 +inline LPCWSTR GetMainModulePath()
94 +{
95 + __asm
96 + {
97 + mov eax, fs:[0x30]
98 + mov eax, [eax + 0xC]
99 + mov eax, [eax + 0xC]
100 + mov eax, [eax + 0x28]
101 + }
102 +}
103 +
104 +// jichi 9/28/2013: Add this to lock NtWriteFile in wine
105 +class IthMutexLocker
106 +{
107 + HANDLE m;
108 +public:
109 + explicit IthMutexLocker(HANDLE mutex) : m(mutex)
110 + { NtWaitForSingleObject(m, 0, 0); }
111 +
112 + ~IthMutexLocker() { if (m != INVALID_HANDLE_VALUE) IthReleaseMutex(m); }
113 +
114 + bool locked() const { return m != INVALID_HANDLE_VALUE; }
115 +
116 + void unlock() { if (m != INVALID_HANDLE_VALUE) { IthReleaseMutex(m); m = INVALID_HANDLE_VALUE; } }
117 +};
118 +
119 +void IthCoolDown();
120 +
121 +BOOL IthIsWine();
122 +BOOL IthIsWindowsXp();
123 +//BOOL IthIsWindows8OrGreater(); // not public
124 +
125 +/** Get current dll path.
126 + * @param buf
127 + * @param len
128 + * @return length of the path excluding \0
129 + */
130 +size_t IthGetCurrentModulePath(wchar_t *buf, size_t len);
131 +
132 +// EOF
1 +# ithsys.pri
2 +# 8/21/2013 jichi
3 +
4 +DEFINES += WITH_LIB_ITHSYS
5 +LIBS += -lithsys
6 +DEPENDPATH += $$PWD
7 +HEADERS += $$PWD/ithsys.h
8 +#SOURCES += $$PWD/ithsys.cc
9 +
10 +#include($$LIBDIR/winddk/winddk.pri)
11 +#LIBS += -L$$WDK/lib/wxp/i386
12 +
13 +# EOF
1 +# ithsys.pro
2 +# 8/21/2013 jichi
3 +# Build ithsys.lib
4 +
5 +#CONFIG += noqt noeh staticlib
6 +CONFIG += noqt staticlib
7 +
8 +include(../../../config.pri)
9 +include($$LIBDIR/ntdll/ntdll.pri)
10 +
11 +#LIBS += -L$$WDK7_HOME/lib/wxp/i386 -lntdll
12 +
13 +#include($$LIBDIR/winddk/winddk.pri)
14 +#LIBS += -L$$WDK/lib/wxp/i386
15 +
16 +# jichi 9/22/2013: When ITH is on wine, certain NT functions are replaced
17 +#DEFINES += ITH_WINE
18 +
19 +# jichi 7/12/2015: Always enable SEH
20 +DEFINES += ITH_HAS_SEH
21 +
22 +# jichi 11/24/2013: Disable manual heap
23 +DEFINES -= ITH_HAS_HEAP
24 +
25 +## Libraries
26 +
27 +#INCLUDEPATH += $$ITH_HOME/include
28 +#INCLUDEPATH += $$WDK7_HOME/inc/ddk
29 +
30 +#LIBS += -lgdi32 -luser32 -lkernel32
31 +#LIBS += -L$$WDK7_HOME/lib/wxp/i386 -lntdll
32 +#LIBS += $$WDK7_HOME/lib/crt/i386/msvcrt.lib # Override msvcrt10
33 +
34 +#DEFINES += ITH_HAS_CXX
35 +
36 +#LIBS += -lith_sys -lntdll
37 +#LIBS += -lith_tls -lntdll
38 +#LIBS += -lntoskrnl
39 +
40 +DEFINES += _CRT_NON_CONFORMING_SWPRINTFS
41 +
42 +## Sources
43 +
44 +TEMPLATE = lib
45 +TARGET = ithsys
46 +
47 +HEADERS += ithsys.h
48 +SOURCES += ithsys.cc
49 +
50 +OTHER_FILES += ithsys.pri
51 +
52 +# EOF
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 +# mono.pri
2 +# 9/26/2012 jichi
3 +
4 +DEFINES += WITH_LIB_MONO
5 +
6 +DEPENDPATH += $$PWD
7 +
8 +HEADERS += \
9 + $$PWD/monoobject.h \
10 + $$PWD/monotype.h
11 +
12 +# EOF
1 +#ifndef MONOOBJECT_H
2 +#define MONOOBJECT_H
3 +
4 +// monoobject.h
5 +// 12/26/2014 jichi
6 +// https://github.com/mono/mono/blob/master/mono/metadata/object.h
7 +// https://github.com/mono/mono/blob/master/mono/metadata/object-internals.h
8 +// https://github.com/mono/mono/blob/master/mono/util/mono-publib.h
9 +
10 +#include <cstdint>
11 +
12 +#define MONO_ZERO_LEN_ARRAY 1
13 +
14 +// mono/io-layer/uglify.h
15 +//typedef int8_t gint8;
16 +//typedef int32_t gint32;
17 +//typedef wchar_t gunichar2; // either char or wchar_t, depending on how mono is compiled
18 +
19 +typedef int32_t mono_bool;
20 +typedef uint8_t mono_byte;
21 +typedef uint16_t mono_unichar2;
22 +typedef uint32_t mono_unichar4;
23 +
24 +// mono/metadata/object.h
25 +
26 +typedef mono_bool MonoBoolean;
27 +
28 +struct MonoArray;
29 +struct MonoDelegate;
30 +struct MonoDomain;
31 +struct MonoException;
32 +struct MonoString;
33 +struct MonoThreadsSync;
34 +struct MonoThread;
35 +struct MonoVTable;
36 +
37 +struct MonoObject {
38 + MonoVTable *vtable;
39 + MonoThreadsSync *synchronisation;
40 +};
41 +
42 +struct MonoString {
43 + MonoObject object;
44 + int32_t length;
45 + mono_unichar2 chars[MONO_ZERO_LEN_ARRAY];
46 +};
47 +
48 +#endif // MONOOBJECT_H
1 +#ifndef MONOTYPE_H
2 +#define MONOTYPE_H
3 +
4 +// monotype.h
5 +// 12/26/2014 jichi
6 +// https://github.com/mono/mono/blob/master/mono/metadata/object.h
7 +
8 +#include "mono/monoobject.h"
9 +
10 +// Function typedefs
11 +typedef MonoDomain *(* mono_object_get_domain_fun_t)(MonoObject *obj);
12 +
13 +typedef MonoString *(* mono_string_new_utf16_fun_t)(MonoDomain *domain, const mono_unichar2 *text, int32_t len);
14 +
15 +typedef char * (* mono_string_to_utf8_fun_t)(MonoString *string_obj);
16 +
17 +#endif // MONOTYPE_H
...@@ -3,11 +3,15 @@ ...@@ -3,11 +3,15 @@
3 #include "ntdll/ntdll.h" 3 #include "ntdll/ntdll.h"
4 #include "ntinspect/ntinspect.h" 4 #include "ntinspect/ntinspect.h"
5 5
6 +// https://social.msdn.microsoft.com/Forums/vstudio/en-US/4cb11cd3-8ce0-49d7-9dda-d62e9ae0180b/how-to-get-current-module-handle?forum=vcgeneral
7 +EXTERN_C IMAGE_DOS_HEADER __ImageBase;
8 +
6 //#ifdef _MSC_VER 9 //#ifdef _MSC_VER
7 //# pragma warning(disable:4018) // C4018: signed/unsigned mismatch 10 //# pragma warning(disable:4018) // C4018: signed/unsigned mismatch
8 //#endif // _MSC_VER 11 //#endif // _MSC_VER
9 12
10 namespace { // unnamed 13 namespace { // unnamed
14 +
11 // Replacement of wcscpy_s which is not available on Windows XP's msvcrt 15 // Replacement of wcscpy_s which is not available on Windows XP's msvcrt
12 // http://sakuradite.com/topic/247 16 // http://sakuradite.com/topic/247
13 errno_t wcscpy_safe(wchar_t *buffer, size_t bufferSize, const wchar_t *source) 17 errno_t wcscpy_safe(wchar_t *buffer, size_t bufferSize, const wchar_t *source)
...@@ -22,7 +26,12 @@ errno_t wcscpy_safe(wchar_t *buffer, size_t bufferSize, const wchar_t *source) ...@@ -22,7 +26,12 @@ errno_t wcscpy_safe(wchar_t *buffer, size_t bufferSize, const wchar_t *source)
22 26
23 NTINSPECT_BEGIN_NAMESPACE 27 NTINSPECT_BEGIN_NAMESPACE
24 28
25 -BOOL getCurrentProcessName(LPWSTR buffer, int bufferSize) 29 +// https://social.msdn.microsoft.com/Forums/vstudio/en-US/4cb11cd3-8ce0-49d7-9dda-d62e9ae0180b/how-to-get-current-module-handle?forum=vcgeneral
30 +HMODULE getCurrentModuleHandle() { return (HMODULE)&__ImageBase; }
31 +
32 +/** Memory range */
33 +
34 +BOOL getProcessName(LPWSTR buffer, int bufferSize)
26 { 35 {
27 //assert(name); 36 //assert(name);
28 PLDR_DATA_TABLE_ENTRY it; 37 PLDR_DATA_TABLE_ENTRY it;
...@@ -38,6 +47,7 @@ BOOL getCurrentProcessName(LPWSTR buffer, int bufferSize) ...@@ -38,6 +47,7 @@ BOOL getCurrentProcessName(LPWSTR buffer, int bufferSize)
38 return 0 == wcscpy_safe(buffer, bufferSize, it->BaseDllName.Buffer); 47 return 0 == wcscpy_safe(buffer, bufferSize, it->BaseDllName.Buffer);
39 } 48 }
40 49
50 +// See: ITH FillRange
41 BOOL getModuleMemoryRange(LPCWSTR moduleName, DWORD *lowerBound, DWORD *upperBound) 51 BOOL getModuleMemoryRange(LPCWSTR moduleName, DWORD *lowerBound, DWORD *upperBound)
42 { 52 {
43 //assert(lower); 53 //assert(lower);
...@@ -86,15 +96,114 @@ BOOL getModuleMemoryRange(LPCWSTR moduleName, DWORD *lowerBound, DWORD *upperBou ...@@ -86,15 +96,114 @@ BOOL getModuleMemoryRange(LPCWSTR moduleName, DWORD *lowerBound, DWORD *upperBou
86 return FALSE; 96 return FALSE;
87 } 97 }
88 98
89 -BOOL getCurrentMemoryRange(DWORD *lowerBound, DWORD *upperBound) 99 +BOOL getProcessMemoryRange(DWORD *lowerBound, DWORD *upperBound)
90 { 100 {
91 WCHAR procName[MAX_PATH]; // cached 101 WCHAR procName[MAX_PATH]; // cached
92 *lowerBound = 0; 102 *lowerBound = 0;
93 *upperBound = 0; 103 *upperBound = 0;
94 - return getCurrentProcessName(procName, MAX_PATH) 104 + return getProcessName(procName, MAX_PATH)
95 && getModuleMemoryRange(procName, lowerBound, upperBound); 105 && getModuleMemoryRange(procName, lowerBound, upperBound);
96 } 106 }
97 107
108 +/** Module header */
109 +
110 +// See: ITH AddAllModules
111 +bool iterModule(const iter_module_fun_t &fun)
112 +{
113 + // Iterate loaded modules
114 + PPEB ppeb;
115 + __asm {
116 + mov eax, fs:[0x30]
117 + mov ppeb, eax
118 + }
119 + const DWORD start = *(DWORD *)&ppeb->Ldr->InLoadOrderModuleList;
120 + for (auto it = (PLDR_DATA_TABLE_ENTRY)start;
121 + it->SizeOfImage && *(DWORD *)it != start;
122 + it = (PLDR_DATA_TABLE_ENTRY)it->InLoadOrderModuleList.Flink)
123 + if (!fun((HMODULE)it->DllBase, it->BaseDllName.Buffer))
124 + return false;
125 + return true;
126 +}
127 +
128 +
129 +// See: ITH AddAllModules
130 +DWORD getExportFunction(LPCSTR funcName)
131 +{
132 + // Iterate loaded modules
133 + PPEB ppeb;
134 + __asm {
135 + mov eax, fs:[0x30]
136 + mov ppeb, eax
137 + }
138 + const DWORD start = *(DWORD *)&ppeb->Ldr->InLoadOrderModuleList;
139 + for (auto it = (PLDR_DATA_TABLE_ENTRY)start;
140 + it->SizeOfImage && *(DWORD *)it != start;
141 + it = (PLDR_DATA_TABLE_ENTRY)it->InLoadOrderModuleList.Flink) {
142 + //if (moduleName && ::wcscmp(moduleName, it->BaseDllName.Buffer)) // BaseDllName.Buffer == moduleName
143 + // continue;
144 + if (DWORD addr = getModuleExportFunction((HMODULE)it->DllBase, funcName))
145 + return addr;
146 + }
147 + return 0;
148 +}
149 +
150 +// See: ITH AddModule
151 +DWORD getModuleExportFunction(HMODULE hModule, LPCSTR funcName)
152 +{
153 + if (!hModule)
154 + return 0;
155 + DWORD startAddress = (DWORD)hModule;
156 + IMAGE_DOS_HEADER *DosHdr = (IMAGE_DOS_HEADER *)hModule;
157 + if (IMAGE_DOS_SIGNATURE == DosHdr->e_magic) {
158 + DWORD dwReadAddr = startAddress + DosHdr->e_lfanew;
159 + IMAGE_NT_HEADERS *NtHdr = (IMAGE_NT_HEADERS *)dwReadAddr;
160 + if (IMAGE_NT_SIGNATURE == NtHdr->Signature) {
161 + DWORD dwExportAddr = NtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
162 + if (dwExportAddr == 0)
163 + return 0;
164 + dwExportAddr += startAddress;
165 + IMAGE_EXPORT_DIRECTORY *ExtDir = (IMAGE_EXPORT_DIRECTORY *)dwExportAddr;
166 + dwExportAddr = startAddress + ExtDir->AddressOfNames;
167 + for (UINT uj = 0; uj < ExtDir->NumberOfNames; uj++) {
168 + DWORD dwFuncName = *(DWORD *)dwExportAddr;
169 + LPCSTR pcFuncName = (LPCSTR)(startAddress + dwFuncName);
170 + if (::strcmp(funcName, pcFuncName) == 0) {
171 + char *pcFuncPtr = (char *)(startAddress + (DWORD)ExtDir->AddressOfNameOrdinals+(uj * sizeof(WORD)));
172 + WORD word = *(WORD *)pcFuncPtr;
173 + pcFuncPtr = (char *)(startAddress + (DWORD)ExtDir->AddressOfFunctions+(word * sizeof(DWORD)));
174 + return startAddress + *(DWORD *)pcFuncPtr; // absolute address
175 + }
176 + dwExportAddr += sizeof(DWORD);
177 + }
178 + }
179 + }
180 + return 0;
181 +}
182 +
183 +// See: ITH FindImportEntry
184 +DWORD getModuleImportAddress(HMODULE hModule, DWORD exportAddress)
185 +{
186 + if (!hModule)
187 + return 0;
188 + DWORD startAddress = (DWORD)hModule;
189 + IMAGE_DOS_HEADER *DosHdr = (IMAGE_DOS_HEADER *)hModule;
190 + if (IMAGE_DOS_SIGNATURE == DosHdr->e_magic) {
191 + IMAGE_NT_HEADERS *NtHdr = (IMAGE_NT_HEADERS *)(startAddress + DosHdr->e_lfanew);
192 + if (IMAGE_NT_SIGNATURE == NtHdr->Signature) {
193 + DWORD IAT = NtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress;
194 + DWORD end = NtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size;
195 + IAT += startAddress;
196 + end += IAT;
197 + for (DWORD pt = IAT; pt < end; pt += 4) {
198 + DWORD addr = *(DWORD *)pt;
199 + if (addr == (DWORD)exportAddress)
200 + return pt;
201 + }
202 + }
203 + }
204 + return 0;
205 +}
206 +
98 NTINSPECT_END_NAMESPACE 207 NTINSPECT_END_NAMESPACE
99 208
100 // EOF 209 // EOF
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
4 // 4/20/2014 jichi 4 // 4/20/2014 jichi
5 5
6 #include <windows.h> 6 #include <windows.h>
7 +#ifndef MEMDBG_NO_STL
8 +# include <functional>
9 +#endif // MEMDBG_NO_STL
7 10
8 #ifndef NTINSPECT_BEGIN_NAMESPACE 11 #ifndef NTINSPECT_BEGIN_NAMESPACE
9 # define NTINSPECT_BEGIN_NAMESPACE namespace NtInspect { 12 # define NTINSPECT_BEGIN_NAMESPACE namespace NtInspect {
...@@ -14,17 +17,73 @@ ...@@ -14,17 +17,73 @@
14 17
15 NTINSPECT_BEGIN_NAMESPACE 18 NTINSPECT_BEGIN_NAMESPACE
16 19
20 +// Get the module handle of the current module (not the current process that is GetModuleHandleA(0))
21 +HMODULE getCurrentModuleHandle();
22 +
17 /// Get current module name in fs:0x30 23 /// Get current module name in fs:0x30
18 -BOOL getCurrentProcessName(_Out_ LPWSTR buffer, _In_ int bufferSize); 24 +BOOL getProcessName(_Out_ LPWSTR buffer, _In_ int bufferSize);
19 25
20 /** 26 /**
21 * Get the memory range of the module if succeed 27 * Get the memory range of the module if succeed
22 - * See: ITH FillRange 28 + * @param moduleName
29 + * @param[out[ lowerBound
30 + * @param[out] upperBound
31 + * @return if succeed
23 */ 32 */
24 BOOL getModuleMemoryRange(_In_ LPCWSTR moduleName, _Out_ DWORD *lowerBound, _Out_ DWORD *upperBound); 33 BOOL getModuleMemoryRange(_In_ LPCWSTR moduleName, _Out_ DWORD *lowerBound, _Out_ DWORD *upperBound);
25 34
26 -/// Get memory of the current process 35 +/// Get memory of the current process module
27 -BOOL getCurrentMemoryRange(_Out_ DWORD *lowerBound, _Out_ DWORD *upperBound); 36 +BOOL getProcessMemoryRange(_Out_ DWORD *lowerBound, _Out_ DWORD *upperBound);
37 +
38 +#ifndef NTINSPECT_NO_STL
39 +/// Iterate module information and return false if abort iteration.
40 +typedef std::function<bool (HMODULE hModule, LPCWSTR moduleName)> iter_module_fun_t;
41 +#else
42 +typedef bool (* iter_module_fun_t)(HMODULE hModule, LPCWSTR moduleName);
43 +#endif // NTINSPECT_NO_STL
44 +
45 +/**
46 + * Iterate all modules
47 + * @param fun the first parameter is the address of the caller, and the second parameter is the address of the call itself
48 + * @return false if return early, and true if iterate all elements
49 + */
50 +bool iterModule(const iter_module_fun_t &fun);
51 +
52 +/**
53 + * Return the absolute address of the function imported from the given module
54 + * @param functionName
55 + * @param* hModule find from any module when null
56 + * @return function address or 0
57 + */
58 +DWORD getModuleExportFunction(HMODULE hModule, LPCSTR functionName);
59 +
60 +inline DWORD getModuleExportFunctionA(LPCSTR moduleName, LPCSTR functionName)
61 +{ return getModuleExportFunction(::GetModuleHandleA(moduleName), functionName); }
62 +
63 +inline DWORD getModuleExportFunctionW(LPCWSTR moduleName, LPCSTR functionName)
64 +{ return getModuleExportFunction(::GetModuleHandleW(moduleName), functionName); }
65 +
66 +/// Get the function address exported from any module
67 +DWORD getExportFunction(LPCSTR functionName);
68 +
69 +/**
70 + * Get the import address in the specified module
71 + * @param hModule
72 + * @param exportAddress absolute address of the function exported from other modules
73 + * @return function address or 0
74 + */
75 +DWORD getModuleImportAddress(HMODULE hModule, DWORD exportAddress);
76 +
77 +inline DWORD getModuleImportAddressA(LPCSTR moduleName, DWORD exportAddress)
78 +{ return getModuleImportAddress(::GetModuleHandleA(moduleName), exportAddress); }
79 +
80 +inline DWORD getModuleImportAddressW(LPCWSTR moduleName, DWORD exportAddress)
81 +{ return getModuleImportAddress(::GetModuleHandleW(moduleName), exportAddress); }
82 +
83 +/// Get the import address in the current executable
84 +inline DWORD getProcessImportAddress(DWORD exportAddress)
85 +{ return getModuleImportAddress(::GetModuleHandleA(nullptr), exportAddress); }
86 +
28 87
29 NTINSPECT_END_NAMESPACE 88 NTINSPECT_END_NAMESPACE
30 89
......
1 +set(profile_src
2 + Profile.h
3 + Profile.cpp
4 + pugiconfig.hpp
5 + pugixml.cpp
6 + pugixml.hpp
7 + misc.h
8 + misc.cpp
9 +)
10 +
11 +add_library(profile STATIC ${profile_src})
12 +
13 +target_compile_options(profile PRIVATE
14 + $<$<CONFIG:Release>:>
15 + $<$<CONFIG:Debug>:>
16 +)
17 +
18 +#target_link_libraries(profile comctl32.lib)
19 +
20 +#target_compile_definitions(profile
21 +# PRIVATE
22 +# _CRT_NON_CONFORMING_SWPRINTFS
23 +#)
1 +/* Copyright (C) 2010-2012 kaosu (qiupf2000@gmail.com)
2 + * This file is part of the Interactive Text Hooker.
3 +
4 + * Interactive Text Hooker is free software: you can redistribute it and/or
5 + * modify it under the terms of the GNU General Public License as published
6 + * by the Free Software Foundation, either version 3 of the License, or
7 + * (at your option) any later version.
8 +
9 + * This program is distributed in the hope that it will be useful,
10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 + * GNU General Public License for more details.
13 +
14 + * You should have received a copy of the GNU General Public License
15 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 + */
17 +
18 +
19 +#include "host/host.h"
20 +#include "host/hookman.h"
21 +#include "vnrhook/include/types.h"
22 +#include "vnrhook/include/const.h"
23 +#include "Profile.h"
24 +#include "misc.h"
25 +#include <algorithm>
26 +#include "pugixml.hpp"
27 +
28 +extern HookManager* man;
29 +
30 +Profile::Profile(const std::wstring& title) :
31 +select_index(-1),
32 +title(title)
33 +{}
34 +
35 +const std::unordered_set<hook_ptr>& Profile::Hooks() const
36 +{
37 + return hooks;
38 +}
39 +
40 +const std::vector<thread_ptr>& Profile::Threads() const
41 +{
42 + return threads;
43 +}
44 +
45 +const std::unordered_set<link_ptr>& Profile::Links() const
46 +{
47 + return links;
48 +}
49 +
50 +bool Profile::XmlReadProfile(pugi::xml_node profile)
51 +{
52 + auto hooks_node = profile.child(L"Hooks");
53 + auto threads_node = profile.child(L"Threads");
54 + auto links_node = profile.child(L"Links");
55 + if (hooks_node && !XmlReadProfileHook(hooks_node))
56 + return false;
57 + if (threads_node && !XmlReadProfileThread(threads_node))
58 + return false;
59 + if (links_node && !XmlReadProfileLink(links_node))
60 + return false;
61 + auto select_node = profile.child(L"Select");
62 + if (select_node)
63 + {
64 + auto thread_index = select_node.attribute(L"ThreadIndex");
65 + if (!thread_index)
66 + return false;
67 + DWORD tmp_select = std::stoul(thread_index.value(), NULL, 16);
68 + select_index = tmp_select & 0xFFFF;
69 + }
70 + return true;
71 +}
72 +
73 +bool Profile::XmlReadProfileHook(pugi::xml_node hooks_node)
74 +{
75 + for (auto hook = hooks_node.begin(); hook != hooks_node.end(); ++hook)
76 + {
77 + std::wstring name = hook->name();
78 + if (name.empty() || name.compare(L"Hook") != 0)
79 + return false;
80 + auto type = hook->attribute(L"Type");
81 + if (!type || type.empty())
82 + return false;
83 + auto code = hook->attribute(L"Code");
84 + if (!code)
85 + return false;
86 + std::wstring code_value = code.value();
87 + HookParam hp = {};
88 + switch (type.value()[0])
89 + {
90 + case L'H':
91 + if (code_value[0] != L'/')
92 + return false;
93 + if (code_value[1] != L'H' && code_value[1] != L'h')
94 + return false;
95 + if (Parse(code_value.substr(2), hp))
96 + {
97 + auto name = hook->attribute(L"Name");
98 + if (!name || name.empty())
99 + AddHook(hook_ptr(new HookProfile(hp, L"")));
100 + else
101 + AddHook(hook_ptr(new HookProfile(hp, name.value())));
102 + }
103 + break;
104 + default:
105 + return false;
106 + }
107 + }
108 + return true;
109 +}
110 +
111 +bool Profile::XmlReadProfileThread(pugi::xml_node threads_node)
112 +{
113 + std::wstring hook_name_buffer;
114 + for (auto thread = threads_node.begin(); thread != threads_node.end(); ++thread)
115 + {
116 + std::wstring name = thread->name();
117 + if (name.empty() || name.compare(L"Thread") != 0)
118 + return false;
119 + auto hook_name = thread->attribute(L"HookName");
120 + if (!hook_name)
121 + return false;
122 + auto context = thread->attribute(L"Context");
123 + if (!context)
124 + return false;
125 + auto sub_context = thread->attribute(L"SubContext");
126 + if (!sub_context)
127 + return false;
128 + auto mask = thread->attribute(L"Mask");
129 + if (!mask)
130 + return false;
131 + DWORD mask_tmp = std::stoul(mask.value(), NULL, 16);
132 + auto comment = thread->attribute(L"Comment");
133 + auto retn = std::stoul(context.value(), NULL, 16);
134 + auto split = std::stoul(sub_context.value(), NULL, 16);
135 + WORD flags = mask_tmp & 0xFFFF;
136 + auto tp = new ThreadProfile(hook_name.value(), retn, split, 0, 0, flags,
137 + comment.value());
138 + AddThread(thread_ptr(tp));
139 + }
140 + return true;
141 +}
142 +
143 +bool Profile::XmlReadProfileLink(pugi::xml_node links_node)
144 +{
145 + for (auto link = links_node.begin(); link != links_node.end(); ++link)
146 + {
147 + std::wstring name = link->name();
148 + if (name.empty() || name.compare(L"Link") != 0)
149 + return false;
150 + auto from = link->attribute(L"From");
151 + if (!from)
152 + return false;
153 + DWORD link_from = std::stoul(from.value(), NULL, 16);
154 + auto to = link->attribute(L"To");
155 + if (!to)
156 + return false;
157 + DWORD link_to = std::stoul(to.value(), NULL, 16);
158 + auto lp = new LinkProfile(link_from & 0xFFFF, link_to & 0xFFFF);
159 + AddLink(link_ptr(lp));
160 + }
161 + return true;
162 +}
163 +
164 +bool Profile::XmlWriteProfile(pugi::xml_node profile_node)
165 +{
166 + if (!hooks.empty())
167 + {
168 + auto node = profile_node.append_child(L"Hooks");
169 + XmlWriteProfileHook(node);
170 + }
171 + if (!threads.empty())
172 + {
173 + auto node = profile_node.append_child(L"Threads");
174 + XmlWriteProfileThread(node);
175 + }
176 + if (!links.empty())
177 + {
178 + auto node = profile_node.append_child(L"Links");
179 + XmlWriteProfileLink(node);
180 + }
181 + if (select_index != 0xFFFF)
182 + {
183 + auto node = profile_node.append_child(L"Select");
184 + node.append_attribute(L"ThreadIndex") = select_index;
185 + }
186 + return true;
187 +}
188 +
189 +bool Profile::XmlWriteProfileHook(pugi::xml_node hooks_node)
190 +{
191 + for (auto hook = hooks.begin(); hook != hooks.end(); ++hook)
192 + {
193 + auto hook_node = hooks_node.append_child(L"Hook");
194 + hook_node.append_attribute(L"Type") = L"H";
195 + hook_node.append_attribute(L"Code") = ParseCode((*hook)->HP()).c_str();
196 + if (!(*hook)->Name().empty())
197 + hook_node.append_attribute(L"Name") = (*hook)->Name().c_str();
198 + }
199 + return true;
200 +}
201 +
202 +bool Profile::XmlWriteProfileThread(pugi::xml_node threads_node)
203 +{
204 + for (auto thread = threads.begin(); thread != threads.end(); ++thread)
205 + {
206 + const std::wstring& name = (*thread)->HookName();
207 + if (name.empty())
208 + return false;
209 + auto node = threads_node.append_child(L"Thread");
210 + node.append_attribute(L"HookName") = name.c_str();
211 + std::wstring hex = ToHexString((*thread)->Flags() & (THREAD_MASK_RETN | THREAD_MASK_SPLIT));
212 + node.append_attribute(L"Mask") = hex.c_str();
213 + hex = ToHexString((*thread)->Split());
214 + node.append_attribute(L"SubContext") = hex.c_str();
215 + hex = ToHexString((*thread)->Return());
216 + node.append_attribute(L"Context") = hex.c_str();
217 + if (!(*thread)->Comment().empty())
218 + node.append_attribute(L"Comment") = (*thread)->Comment().c_str();
219 + }
220 + return true;
221 +}
222 +
223 +bool Profile::XmlWriteProfileLink(pugi::xml_node links_node)
224 +{
225 + for (auto link = links.begin(); link != links.end(); ++link)
226 + {
227 + auto node = links_node.append_child(L"Link");
228 + node.append_attribute(L"From") = ToHexString((*link)->FromIndex()).c_str();
229 + node.append_attribute(L"To") = ToHexString((*link)->ToIndex()).c_str();
230 + }
231 + return true;
232 +}
233 +
234 +void Profile::Clear()
235 +{
236 + title = L"";
237 + select_index = -1;
238 + hooks.clear();
239 + threads.clear();
240 + links.clear();
241 +}
242 +
243 +void Profile::AddHook(hook_ptr hook)
244 +{
245 + hooks.insert(std::move(hook));
246 +}
247 +
248 +// add the thread profile and return its index
249 +int Profile::AddThread(thread_ptr tp)
250 +{
251 + auto it = std::find_if(threads.begin(), threads.end(), [&tp](thread_ptr& thread)
252 + {
253 + return thread->HookName().compare(tp->HookName()) == 0 &&
254 + thread->Return() == tp->Return() &&
255 + thread->Split() == tp->Split();
256 + });
257 + if (it != threads.end())
258 + return it - threads.begin();
259 + threads.push_back(std::move(tp));
260 + return threads.size() - 1;
261 +}
262 +
263 +void Profile::AddLink(link_ptr link)
264 +{
265 + links.insert(std::move(link));
266 +}
267 +
268 +const std::wstring& Profile::Title() const
269 +{
270 + return title;
271 +}
272 +
273 +bool Profile::IsThreadSelected(thread_ptr_iter thread_profile)
274 +{
275 + if (thread_profile != threads.end())
276 + {
277 + auto thread_index = thread_profile - threads.begin();
278 + return select_index == thread_index;
279 + }
280 + return false;
281 +}
282 +
283 +thread_ptr_iter Profile::FindThread(const ThreadParameter* tp, const std::wstring& hook_name) const
284 +{
285 + auto thread_profile = std::find_if(threads.begin(), threads.end(),
286 + [&tp, &hook_name](const thread_ptr& thread_profile) -> bool
287 + {
288 + return thread_profile->HookName().compare(hook_name) == 0
289 + && thread_profile->Return() == tp->retn
290 + && thread_profile->Split() == tp->spl;
291 + });
292 + return thread_profile;
293 +}
1 +/* Copyright (C) 2010-2012 kaosu (qiupf2000@gmail.com)
2 + * This file is part of the Interactive Text Hooker.
3 +
4 + * Interactive Text Hooker is free software: you can redistribute it and/or
5 + * modify it under the terms of the GNU General Public License as published
6 + * by the Free Software Foundation, either version 3 of the License, or
7 + * (at your option) any later version.
8 +
9 + * This program is distributed in the hope that it will be useful,
10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 + * GNU General Public License for more details.
13 +
14 + * You should have received a copy of the GNU General Public License
15 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 + */
17 +
18 +#pragma once
19 +
20 +#include "vnrhook/include/types.h" // HookParam
21 +#include <string>
22 +#include <memory>
23 +#include <vector>
24 +#include <unordered_set>
25 +
26 +struct ThreadParameter;
27 +class TextThread;
28 +class HookProfile;
29 +class ThreadProfile;
30 +class LinkProfile;
31 +typedef std::unique_ptr<HookProfile> hook_ptr;
32 +typedef std::unique_ptr<ThreadProfile> thread_ptr;
33 +typedef std::unique_ptr<LinkProfile> link_ptr;
34 +typedef std::vector<thread_ptr>::const_iterator thread_ptr_iter;
35 +namespace pugi {
36 + class xml_node;
37 +}
38 +
39 +#define THREAD_MASK_RETN 1
40 +#define THREAD_MASK_SPLIT 2
41 +
42 +class HookProfile
43 +{
44 + HookParam hp;
45 + std::wstring name;
46 +public:
47 + HookProfile(const HookParam& hp, const std::wstring& name) :
48 + hp(hp),
49 + name(name)
50 + {}
51 + const HookParam& HP() const { return hp; };
52 + const std::wstring& Name() const { return name; };
53 +};
54 +
55 +class ThreadProfile
56 +{
57 + std::wstring hook_name;
58 + DWORD retn;
59 + DWORD split;
60 + DWORD hook_addr;
61 + WORD hm_index, flags;
62 + std::wstring comment;
63 +public:
64 + ThreadProfile(const std::wstring& hook_name,
65 + DWORD retn,
66 + DWORD split,
67 + DWORD hook_addr,
68 + WORD hm_index,
69 + WORD flags,
70 + const std::wstring& comment) :
71 + hook_name(hook_name),
72 + retn(retn),
73 + split(split),
74 + hook_addr(hook_addr),
75 + hm_index(hm_index),
76 + flags(flags),
77 + comment(comment)
78 + {
79 + }
80 + const std::wstring& HookName() const { return hook_name; }
81 + const std::wstring& Comment() const { return comment; }
82 + DWORD Return() const { return retn; }
83 + DWORD Split() const { return split; }
84 + DWORD& HookAddress() { return hook_addr; }
85 + WORD& HookManagerIndex() { return hm_index; }
86 + WORD Flags() const { return flags; }
87 +};
88 +
89 +class LinkProfile
90 +{
91 + WORD from_index, to_index;
92 +public:
93 + LinkProfile(WORD from_index, WORD to_index) :
94 + from_index(from_index),
95 + to_index(to_index)
96 + {}
97 + WORD FromIndex() const { return from_index; }
98 + WORD ToIndex() const { return to_index; }
99 +};
100 +
101 +namespace std {
102 + template<>
103 + struct hash<hook_ptr> {
104 + size_t operator()(const hook_ptr &r) const
105 + {
106 + return hash<DWORD>{}(r->HP().address)
107 + ^ hash<DWORD>{}(r->HP().module)
108 + ^ hash<DWORD>{}(r->HP().function);
109 + }
110 + };
111 + template<>
112 + struct equal_to<hook_ptr> {
113 + bool operator()(const hook_ptr& r, const hook_ptr& r2) const
114 + {
115 + return r->HP().address == r2->HP().address
116 + && r->HP().module == r2->HP().module
117 + && r->HP().function == r2->HP().function;
118 + }
119 + };
120 +
121 + template<>
122 + struct hash<link_ptr> {
123 + size_t operator()(const link_ptr &r) const
124 + {
125 + return hash<WORD>{}(r->FromIndex())
126 + ^ hash<WORD>{}(r->ToIndex());
127 + }
128 + };
129 + template<>
130 + struct equal_to<link_ptr> {
131 + bool operator()(const link_ptr& r, const link_ptr& r2) const
132 + {
133 + return r->FromIndex() == r2->FromIndex()
134 + && r->ToIndex() == r2->ToIndex();
135 + }
136 + };
137 +}
138 +
139 +class Profile
140 +{
141 +public:
142 + Profile(const std::wstring& title);
143 + bool XmlReadProfile(pugi::xml_node profile_node);
144 + bool XmlWriteProfile(pugi::xml_node profile_node);
145 + void AddHook(hook_ptr hook);
146 + int AddThread(thread_ptr tp);
147 + void AddLink(link_ptr lp);
148 + void Clear();
149 + const std::unordered_set<hook_ptr>& Hooks() const;
150 + const std::vector<thread_ptr>& Threads() const;
151 + const std::unordered_set<link_ptr>& Links() const;
152 + const std::wstring& Title() const;
153 + thread_ptr_iter FindThread(const ThreadParameter* tp, const std::wstring& hook_name) const;
154 + WORD& SelectedIndex() { return select_index; }
155 + bool IsThreadSelected(thread_ptr_iter thread_profile);
156 +
157 +private:
158 + bool XmlReadProfileHook(pugi::xml_node hooks_node);
159 + bool XmlReadProfileThread(pugi::xml_node threads_node);
160 + bool XmlReadProfileLink(pugi::xml_node links_node);
161 + bool XmlWriteProfileHook(pugi::xml_node hooks_node);
162 + bool XmlWriteProfileThread(pugi::xml_node threads_node);
163 + bool XmlWriteProfileLink(pugi::xml_node links_node);
164 +
165 + std::wstring title;
166 + std::unordered_set<hook_ptr> hooks;
167 + std::vector<thread_ptr> threads;
168 + std::unordered_set<link_ptr> links;
169 +
170 + WORD select_index;
171 +};
1 +#include "misc.h"
2 +#include <regex>
3 +#include <memory>
4 +#include "host/host.h"
5 +#include "vnrhook/include/const.h"
6 +#include "vnrhook/include/types.h"
7 +
8 +DWORD Hash(const std::wstring& module, int length)
9 +{
10 + DWORD hash = 0;
11 + auto end = (length < 0 || static_cast<size_t>(length) > module.length()) ?
12 + module.end() :
13 + module.begin() + length;
14 + for (auto it = module.begin(); it != end; ++it)
15 + hash = _rotr(hash, 7) + *it;
16 + return hash;
17 +}
18 +
19 +bool Parse(const std::wstring& cmd, HookParam& hp)
20 +{
21 + using std::wregex;
22 + using std::regex_search;
23 + // /H[X]{A|B|W|S|Q}[N][data_offset[*drdo]][:sub_offset[*drso]]@addr[:[module[:{name|#ordinal}]]]
24 + wregex rx(L"^X?([ABWSQ])(N)?", wregex::icase);
25 + std::match_results<std::wstring::const_iterator> m;
26 + auto start = cmd.begin();
27 + auto end = cmd.end();
28 + bool result = regex_search(start, end, m, rx);
29 + if (!result)
30 + return result;
31 + start = m[0].second;
32 + if (m[2].matched)
33 + hp.type |= NO_CONTEXT;
34 +
35 + switch (m[1].first[0])
36 + {
37 + case L's':
38 + case L'S':
39 + hp.type |= USING_STRING;
40 + break;
41 + case L'e':
42 + case L'E':
43 + hp.type |= STRING_LAST_CHAR;
44 + case L'a':
45 + case L'A':
46 + hp.type |= BIG_ENDIAN;
47 + hp.length_offset = 1;
48 + break;
49 + case L'b':
50 + case L'B':
51 + hp.length_offset = 1;
52 + break;
53 + case L'h':
54 + case L'H':
55 + hp.type |= PRINT_DWORD;
56 + case L'q':
57 + case L'Q':
58 + hp.type |= USING_STRING | USING_UNICODE;
59 + break;
60 + case L'l':
61 + case L'L':
62 + hp.type |= STRING_LAST_CHAR;
63 + case L'w':
64 + case L'W':
65 + hp.type |= USING_UNICODE;
66 + hp.length_offset = 1;
67 + break;
68 + default:
69 + break;
70 + }
71 +
72 + // [data_offset[*drdo]]
73 + std::wstring data_offset(L"(-?[[:xdigit:]]+)"), drdo(L"(\\*-?[[:xdigit:]]+)?");
74 + rx = wregex(L"^" + data_offset + drdo, wregex::icase);
75 + result = regex_search(start, end, m, rx);
76 + if (result)
77 + {
78 + start = m[0].second;
79 + hp.offset = std::stoul(m[1].str(), NULL, 16);
80 + if (m[2].matched)
81 + {
82 + hp.type |= DATA_INDIRECT;
83 + hp.index = std::stoul(m[2].str().substr(1), NULL, 16);
84 + }
85 + }
86 +
87 + // [:sub_offset[*drso]]
88 + std::wstring sub_offset(L"(-?[[:xdigit:]]+)"), drso(L"(\\*-?[[:xdigit:]]+)?");
89 + rx = wregex(L"^:" + sub_offset + drso, wregex::icase);
90 + result = regex_search(start, end, m, rx);
91 + if (result)
92 + {
93 + start = m[0].second;
94 + hp.type |= USING_SPLIT;
95 + hp.split = std::stoul(m[1].str(), NULL, 16);
96 + if (m[2].matched)
97 + {
98 + hp.type |= SPLIT_INDIRECT;
99 + hp.split_index = std::stoul(m[2].str().substr(1), NULL, 16);
100 + }
101 + }
102 + // @addr
103 + rx = wregex(L"^@[[:xdigit:]]+", wregex::icase);
104 + result = regex_search(start, end, m, rx);
105 + if (!result)
106 + return false;
107 + start = m[0].second;
108 + hp.address = std::stoul(m[0].str().substr(1), NULL, 16);
109 + if (hp.offset & 0x80000000)
110 + hp.offset -= 4;
111 + if (hp.split & 0x80000000)
112 + hp.split -= 4;
113 +
114 + // [:[module[:{name|#ordinal}]]]
115 + // ":" -> module == NULL &% function == NULL
116 + // "" -> MODULE_OFFSET && module == NULL && function == addr
117 + // ":GDI.dll" -> MODULE_OFFSET && module != NULL
118 + // ":GDI.dll:strlen" -> MODULE_OFFSET | FUNCTION_OFFSET && module != NULL && function != NULL
119 + // ":GDI.dll:#123" -> MODULE_OFFSET | FUNCTION_OFFSET && module != NULL && function != NULL
120 + std::wstring module(L"([[:graph:]]+)"), name(L"[[:graph:]]+"), ordinal(L"\\d+");
121 + rx = wregex(L"^:(" + module + L"(:" + name + L"|#" + ordinal + L")?)?$", wregex::icase);
122 + result = regex_search(start, end, m, rx);
123 + if (result) // :[module[:{name|#ordinal}]]
124 + {
125 + if (m[1].matched) // module
126 + {
127 + hp.type |= MODULE_OFFSET;
128 + std::wstring module = m[2];
129 + std::transform(module.begin(), module.end(), module.begin(), ::towlower);
130 + hp.module = Hash(module);
131 + if (m[3].matched) // :name|#ordinal
132 + {
133 + hp.type |= FUNCTION_OFFSET;
134 + hp.function = Hash(m[3].str().substr(1));
135 + }
136 + }
137 + }
138 + else
139 + {
140 + rx = wregex(L"^!([[:xdigit:]]+)(!([[:xdigit:]]+))?$", wregex::icase);
141 + result = regex_search(start, end, m, rx);
142 + if (result)
143 + {
144 + hp.type |= MODULE_OFFSET;
145 + hp.module = std::stoul(m[1].str(), NULL, 16);
146 + if (m[2].matched)
147 + {
148 + hp.type |= FUNCTION_OFFSET;
149 + hp.function = std::stoul(m[2].str().substr(1), NULL, 16);
150 + }
151 + }
152 + else
153 + {
154 + // Hack. Hook is relative to the executable. Store the original address in function.
155 + // hp.module == NULL && hp.function != NULL
156 + hp.type |= MODULE_OFFSET;
157 + hp.function = hp.address;
158 + }
159 + }
160 + return true;
161 +}
162 +
163 +std::wstring ParseCode(const HookParam& hp)
164 +{
165 + std::wstring code(L"/H");
166 + WCHAR c;
167 + if (hp.type & PRINT_DWORD)
168 + c = L'H';
169 + else if (hp.type & USING_UNICODE)
170 + {
171 + if (hp.type & USING_STRING)
172 + c = L'Q';
173 + else if (hp.type & STRING_LAST_CHAR)
174 + c = L'L';
175 + else
176 + c = L'W';
177 + }
178 + else
179 + {
180 + if (hp.type & USING_STRING)
181 + c = L'S';
182 + else if (hp.type & BIG_ENDIAN)
183 + c = L'A';
184 + else if (hp.type & STRING_LAST_CHAR)
185 + c = L'E';
186 + else
187 + c = L'B';
188 + }
189 + code += c;
190 + if (hp.type & NO_CONTEXT)
191 + code += L'N';
192 + if (hp.offset >> 31)
193 + code += L'-' + ToHexString(-(hp.offset + 4));
194 + else
195 + code += ToHexString(hp.offset);
196 + if (hp.type & DATA_INDIRECT)
197 + {
198 + if (hp.index >> 31)
199 + code += L'*-' + ToHexString(-hp.index);
200 + else
201 + code += L'*' + ToHexString(hp.index);
202 + }
203 + if (hp.type & USING_SPLIT)
204 + {
205 + if (hp.split >> 31)
206 + code += L":-" + ToHexString(-(4 + hp.split));
207 + else
208 + code += L":" + ToHexString(hp.split);
209 + }
210 + if (hp.type & SPLIT_INDIRECT)
211 + {
212 + if (hp.split_index >> 31)
213 + code += L"*-" + ToHexString(-hp.split_index);
214 + else
215 + code += L"*" + ToHexString(hp.split_index);
216 + }
217 + if (hp.module)
218 + {
219 + code += L"@" + ToHexString(hp.address) + L"!" + ToHexString(hp.module);
220 + if (hp.function)
221 + code += L"!" + ToHexString(hp.function);
222 + }
223 + else
224 + {
225 + // Hack. The original address is stored in the function field
226 + // if (module == NULL && function != NULL).
227 + // MODULE_OFFSET and FUNCTION_OFFSET are removed from HookParam.type in
228 + // TextHook::UnsafeInsertHookCode() and can not be used here.
229 + if (hp.function)
230 + code += L"@" + ToHexString(hp.function);
231 + else
232 + code += L"@" + ToHexString(hp.address) + L":";
233 + }
234 + return code;
235 +}
236 +
237 +
238 +std::string toMultiByteString(const std::wstring& unicodeString)
239 +{
240 + int cbMultiByte = WideCharToMultiByte(932, 0, unicodeString.c_str(), unicodeString.length(),
241 + NULL, 0, NULL, NULL);
242 + auto lpMultiByteStr = std::make_unique<CHAR[]>(cbMultiByte);
243 + WideCharToMultiByte(932, 0, unicodeString.c_str(), unicodeString.length(),
244 + lpMultiByteStr.get(), cbMultiByte, NULL, NULL);
245 + return std::string(lpMultiByteStr.get(), cbMultiByte);
246 +}
247 +
248 +std::wstring toUnicodeString(const std::string& mbString)
249 +{
250 + int cchWideChar = MultiByteToWideChar(932, 0, mbString.c_str(), mbString.length(), NULL, 0);
251 + auto lpWideCharStr = std::make_unique<WCHAR[]>(cchWideChar);
252 + MultiByteToWideChar(932, 0, mbString.c_str(), mbString.length(), lpWideCharStr.get(), cchWideChar);
253 + return std::wstring(lpWideCharStr.get(), cchWideChar);
254 +}
255 +
256 +std::wstring GetHookNameByAddress(const ProcessRecord& pr, DWORD hook_address)
257 +{
258 + std::wstring hook_name;
259 + WaitForSingleObject(pr.hookman_mutex, 0);
260 + auto hooks = (const Hook*)pr.hookman_map;
261 + for (int i = 0; i < MAX_HOOK; ++i)
262 + {
263 + auto& hook = hooks[i];
264 + if (hook.Address() == hook_address)
265 + {
266 + std::unique_ptr<CHAR[]> name(new CHAR[hook.NameLength()]);
267 + // name is zero terminated
268 + if (ReadProcessMemory(pr.process_handle, hooks[i].Name(), name.get(), hook.NameLength(), NULL))
269 + hook_name = toUnicodeString(name.get());
270 + break;
271 + }
272 + }
273 + ReleaseMutex(pr.hookman_mutex);
274 + return hook_name;
275 +}
1 +#pragma once
2 +
3 +#include <Windows.h>
4 +#include <string>
5 +#include <sstream>
6 +
7 +struct HookParam;
8 +struct ProcessRecord;
9 +
10 +bool Parse(const std::wstring& cmd, HookParam& hp);
11 +DWORD Hash(const std::wstring& module, int length = -1);
12 +std::wstring ParseCode(const HookParam& hp);
13 +std::string toMultiByteString(const std::wstring& unicodeString);
14 +std::wstring toUnicodeString(const std::string& mbString);
15 +std::wstring GetHookNameByAddress(const ProcessRecord& pr, DWORD hook_address);
16 +
17 +template <typename T>
18 +std::wstring ToHexString(T i) {
19 + std::wstringstream ss;
20 + ss << std::uppercase << std::hex << i;
21 + return ss.str();
22 +}
1 +/**
2 + * pugixml parser - version 1.6
3 + * --------------------------------------------------------
4 + * Copyright (C) 2006-2015, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
5 + * Report bugs and download new versions at http://pugixml.org/
6 + *
7 + * This library is distributed under the MIT License. See notice at the end
8 + * of this file.
9 + *
10 + * This work is based on the pugxml parser, which is:
11 + * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net)
12 + */
13 +
14 +#ifndef HEADER_PUGICONFIG_HPP
15 +#define HEADER_PUGICONFIG_HPP
16 +
17 +// Uncomment this to enable wchar_t mode
18 +#define PUGIXML_WCHAR_MODE
19 +
20 +// Uncomment this to disable XPath
21 +// #define PUGIXML_NO_XPATH
22 +
23 +// Uncomment this to disable STL
24 +// #define PUGIXML_NO_STL
25 +
26 +// Uncomment this to disable exceptions
27 +// #define PUGIXML_NO_EXCEPTIONS
28 +
29 +// Set this to control attributes for public classes/functions, i.e.:
30 +// #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL
31 +// #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL
32 +// #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall
33 +// In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead
34 +
35 +// Tune these constants to adjust memory-related behavior
36 +// #define PUGIXML_MEMORY_PAGE_SIZE 32768
37 +// #define PUGIXML_MEMORY_OUTPUT_STACK 10240
38 +// #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096
39 +
40 +// Uncomment this to switch to header-only version
41 +// #define PUGIXML_HEADER_ONLY
42 +
43 +// Uncomment this to enable long long support
44 +// #define PUGIXML_HAS_LONG_LONG
45 +
46 +#endif
47 +
48 +/**
49 + * Copyright (c) 2006-2015 Arseny Kapoulkine
50 + *
51 + * Permission is hereby granted, free of charge, to any person
52 + * obtaining a copy of this software and associated documentation
53 + * files (the "Software"), to deal in the Software without
54 + * restriction, including without limitation the rights to use,
55 + * copy, modify, merge, publish, distribute, sublicense, and/or sell
56 + * copies of the Software, and to permit persons to whom the
57 + * Software is furnished to do so, subject to the following
58 + * conditions:
59 + *
60 + * The above copyright notice and this permission notice shall be
61 + * included in all copies or substantial portions of the Software.
62 + *
63 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
64 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
65 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
66 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
67 + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
68 + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
69 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
70 + * OTHER DEALINGS IN THE SOFTWARE.
71 + */
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
1 +# sakurakit.pri
2 +# 6/28/2011 jichi
3 +#
4 +# config:
5 +# - sakurakit_qml
6 +# - sakurakit_gui
7 +# - sakurakit_widgets
8 +
9 +DEFINES += WITH_LIB_SAKURAKIT
10 +DEPENDPATH += $$PWD
11 +
12 +#QT += core
13 +HEADERS += \
14 + $$PWD/skautorun.h \
15 + $$PWD/skdebug.h \
16 + $$PWD/skglobal.h \
17 + $$PWD/skhash.h
18 +
19 +#CONFIG(sakurakit_gui) {
20 +# DEFINES += SK_ENABLE_GUI
21 +# QT += gui
22 +# HEADERS += \
23 +# $$PWD/skuiutil.h
24 +#
25 +# CONFIG(sakurakit_qml) {
26 +# DEFINES += SK_ENABLE_QML
27 +# QT += qml quick
28 +# HEADERS += \
29 +# $$PWD/skdraggablequickview.h
30 +# SOURCES += \
31 +# $$PWD/skdraggablequickview.cc
32 +# }
33 +#
34 +# CONFIG(sakurakit_widgets) {
35 +# DEFINES += SK_ENABLE_WIDGETS
36 +# QT += widgets
37 +# HEADERS += \
38 +# $$PWD/skdraggabledialog.h \
39 +# $$PWD/skdraggablemainwindow.h \
40 +# $$PWD/skdraggablewidget.h \
41 +# $$PWD/skpushbutton.h \
42 +# $$PWD/sksystemtrayicon.h \
43 +# $$PWD/sktoolbutton.h \
44 +# $$PWD/skwindowcontainer.h
45 +# SOURCES += \
46 +# $$PWD/skdraggablewidget.cc \
47 +# $$PWD/skpushbutton.cc \
48 +# $$PWD/sktoolbutton.cc \
49 +# $$PWD/skwindowcontainer.cc \
50 +# $$PWD/skdraggabledialog.cc \
51 +# $$PWD/skdraggablemainwindow.cc
52 +#
53 +# CONFIG(sakurakit_qml) {
54 +# HEADERS += \
55 +# $$PWD/skquickwidget.h
56 +# SOURCES += \
57 +# $$PWD/skquickwidget.cc
58 +# }
59 +# }
60 +#}
61 +
62 +# EOF
1 +#ifndef SKAUTORUN_H
2 +#define SKAUTORUN_H
3 +
4 +// skautorun.h
5 +// 9/30/2012 jichi
6 +
7 +#include "sakurakit/skglobal.h"
8 +#include <functional>
9 +
10 +SK_BEGIN_NAMESPACE
11 +
12 +class SkAutoRun
13 +{
14 +public:
15 + typedef std::function<void ()> function_type;
16 + SkAutoRun(const function_type &start, const function_type &exit)
17 + : exit_(exit) { start(); }
18 + ~SkAutoRun() { exit_(); }
19 +private:
20 + function_type exit_;
21 +};
22 +
23 +class SkAutoRunAtStartup
24 +{
25 +public:
26 + typedef SkAutoRun::function_type function_type;
27 + explicit SkAutoRunAtStartup(const function_type &start) { start(); }
28 +};
29 +
30 +class SkAutoRunAtExit
31 +{
32 +public:
33 + typedef SkAutoRun::function_type function_type;
34 + explicit SkAutoRunAtExit(const function_type &exit) : exit_(exit) {}
35 + ~SkAutoRunAtExit() { exit_(); }
36 +private:
37 + function_type exit_;
38 +};
39 +
40 +SK_END_NAMESPACE
41 +
42 +#endif // SkAUTORUN_H
1 +#ifndef SKDEBUG_H
2 +#define SKDEBUG_H
3 +
4 +// skdebug.h
5 +// 10/16/2011 jichi
6 +// Macros for debug.
7 +
8 +// Debug I/O
9 +// - DPRINT: similar to fprintf, or KDPrint. Print to qDebug
10 +// - DOUT: similar to std::cout. Print to qDebug
11 +// - DERR: similar to std::cerr. Print to qWarning
12 +#if defined(DEBUG) && !defined(SK_NO_DEBUG)
13 +
14 +# if defined(QT_CORE_LIB) && !defined(SK_NO_QT)
15 +# include <QtCore/QDebug>
16 +# define DPRINT(...) qDebug(QString("%1:%2:").arg((DEBUG), (__FUNCTION__)).toLocal8Bit().constData(), __VA_ARGS__)
17 +# define DOUT(_msg) qDebug() << QString("%1:%2:").arg((DEBUG), (__FUNCTION__)).toLocal8Bit().constData() << _msg
18 +# define DERR(_msg) qWarning() << QString("%1:%2:").arg((DEBUG), (__FUNCTION__)).toLocal8Bit().constData() << _msg
19 +# else
20 +# include <iostream>
21 +# include <cstdio>
22 +# define DPRINT(...) fprintf(stderr, DEBUG ":" __FUNCTION__ ": " __VA_ARGS__)
23 +# define DWPRINT(...) fwprintf(stderr, DEBUG ":" __FUNCTION__ ": " __VA_ARGS__)
24 +# define DOUT(_msg) std::cout << DEBUG << ":" << __FUNCTION__ << ": " << _msg << std::endl
25 +# define DWOUT(_msg) std::wcout << DEBUG << ":" << __FUNCTION__ << ": " << _msg << std::endl
26 +# define DERR(_msg) std::cerr << DEBUG << ":" << __FUNCTION__ << ": " << _msg << std::endl
27 +# define DWERR(_msg) std::wcerr << DEBUG << ":" << __FUNCTION__ << ": " << _msg << std::endl
28 +# endif // QT_CORE_LIB
29 +
30 +#else // DEBUG
31 +
32 +# define DPRINT(_dummy) (void)0
33 +# define DOUT(_dummy) (void)0
34 +# define DERR(_dummy) (void)0
35 +
36 +//#ifdef _MSC_VER
37 +//# pragma warning (disable:4390) // C4390: empty controlled statement found: is this the intent?
38 +//#endif // _MSC_VER
39 +
40 +//#ifdef __GNUC__
41 +//# pragma GCC diagnostic ignored "-Wempty-body" // empty body in an if or else statement
42 +//#endif // __GNUC__
43 +
44 +#endif // DEBUG
45 +
46 +#endif // SKDEBUG_H
1 +#ifndef SKGLOBAL_H
2 +#define SKGLOBAL_H
3 +
4 +// skglobal.h
5 +// 9/15/2012 jichi
6 +// Similar to QtGlobal from Qt.
7 +//
8 +// Conventions:
9 +// - All classes in sakurakit will be wrapped with SK_BEGIN_NAMESPACE and SK_END_NAMESPACE
10 +// - All classes from sakurakit begin with Sk, such as SkClassA.
11 +// All functions from sakurakit begin with sk, such as skFuncA.
12 +
13 +// Redefine SK_BEGIN_NAMESPACE/SK_END_NAMESPACE if need custom namespace
14 +#ifndef SK_BEGIN_NAMESPACE
15 +# define SK_BEGIN_NAMESPACE namespace Sk {
16 +#endif
17 +#ifndef SK_END_NAMESPACE
18 +# define SK_END_NAMESPACE } // namespace Sk
19 +#endif
20 +
21 +#define SK_FORWARD_DECLARE_CLASS(_name) SK_BEGIN_NAMESPACE class _name; SK_END_NAMESPACE
22 +#define SK_FORWARD_DECLARE_STRUCT(_name) SK_BEGIN_NAMESPACE struct _name; SK_END_NAMESPACE
23 +
24 +SK_BEGIN_NAMESPACE
25 +namespace Sk {}
26 +SK_END_NAMESPACE
27 +
28 +// In case Qt is not avaliable
29 +
30 +//inline void sk_noop(void) {}
31 +//
32 +//template <typename T>
33 +//inline void skUnused(T &x) { (void)x; }
34 +
35 +#define SK_UNUSED(_var) (void)(_var)
36 +#define SK_NOP SK_UNUSED(0)
37 +
38 +// same as Q_DISABLE_COPY and boost::noncopyable
39 +// Disable when BOOST_PYTHON is enabled
40 +#ifdef BOOST_PYTHON
41 +# define SK_DISABLE_COPY(_class)
42 +#else
43 +# define SK_DISABLE_COPY(_class) \
44 + _class(const _class &); \
45 + _class &operator=(const _class &);
46 +#endif // BOOST_PYTHON
47 +
48 +// - Qt-like Pimp -
49 +
50 +// Similar to QT_DECLARE_PRIVATE
51 +#define SK_DECLARE_PRIVATE(_class) \
52 + friend class _class; \
53 + typedef _class D; \
54 + D *const d_;
55 +
56 +// Similar to QT_DECLARE_PUBLIC
57 +#define SK_DECLARE_PUBLIC(_class) \
58 + friend class _class; \
59 + typedef _class Q; \
60 + Q *const q_;
61 +
62 +// - Self and Base -
63 +
64 +#define SK_CLASS(_self) \
65 + typedef _self Self; \
66 + Self *self() const { return const_cast<Self *>(this); }
67 +
68 +#define SK_EXTEND_CLASS(_self, _base) \
69 + SK_CLASS(_self) \
70 + typedef _base Base;
71 +
72 +#define SK_UNDEF_POS QPoint(-1, -1)
73 +#define SK_UNDEF_POSF QPointF(-1, -1)
74 +
75 +// - QWidget Style Class for QSS -
76 +
77 +// Read-only property
78 +#define SK_STYLE_CLASS(_class) \
79 + Q_PROPERTY(QString class READ styleClass) \
80 + public: \
81 + QString styleClass() const { return #_class; } \
82 + private:
83 +
84 +// Read-write property
85 +#define SK_SYNTHESIZE_STYLE_CLASS \
86 + Q_PROPERTY(QString class READ styleClass WRITE setStyleClass) \
87 + QString styleClass_; \
88 + public: \
89 + QString styleClass() const { return styleClass_; } \
90 + public slots: \
91 + void seStyleClass(const QString &value) { styleClass_ = value; } \
92 + private:
93 +
94 +#endif // SKGLOBAL_H
1 +#ifndef SKHASH_H
2 +#define SKHASH_H
3 +
4 +// skhash.h
5 +// 8/1/2011
6 +
7 +#include "sakurakit/skglobal.h"
8 +#include <QtGlobal>
9 +
10 +SK_BEGIN_NAMESPACE
11 +
12 +enum : quint64 { djb2_hash0 = 5381 };
13 +
14 +/// djb2: h = h*33 + c
15 +inline quint64 djb2(const quint8 *str, quint64 hash = djb2_hash0)
16 +{
17 + quint8 c;
18 + while ((c = *str++))
19 + hash = ((hash << 5) + hash) + c; // hash * 33 + c
20 + return hash;
21 +}
22 +
23 +/// s: signed char
24 +inline quint64 djb2_s(const char *str, quint64 hash = djb2_hash0)
25 +{
26 + char c;
27 + while ((c = *str++))
28 + hash = ((hash << 5) + hash) + c; // hash * 33 + c
29 + return hash;
30 +}
31 +
32 +/// n: length
33 +inline quint64 djb2_n(const quint8 *str, size_t len, quint64 hash = djb2_hash0)
34 +{
35 + while (len--)
36 + hash = ((hash << 5) + hash) + (*str++); // hash * 33 + c
37 + return hash;
38 +}
39 +
40 +/// sdbm: hash(i) = hash(i - 1) * 65599 + str[i];
41 +inline quint64 sdbm(const quint8 *str, quint64 hash = 0)
42 +{
43 + quint8 c;
44 + while ((c = *str++))
45 + hash = c + (hash << 6) + (hash << 16) - hash;
46 + return hash;
47 +}
48 +
49 +inline quint64 loselose(const quint8 *str, quint64 hash = 0)
50 +{
51 + quint8 c;
52 + while ((c = *str++))
53 + hash += c;
54 + return hash;
55 +}
56 +
57 +SK_END_NAMESPACE
58 +
59 +#endif // SKHASH_H
1 +#pragma once
2 +
3 +// growl.h
4 +// 9/17/2013 jichi
5 +
6 +//#ifdef GROWL_HAS_GROWL
7 +
8 +#include <windows.h>
9 +#include <cstdio>
10 +
11 +#define GROWL_MSG_A(_msg) MessageBoxA(nullptr, _msg, "VNR Message", MB_OK)
12 +#define GROWL_MSG(_msg) MessageBoxW(nullptr, _msg, L"VNR Message", MB_OK)
13 +#define GROWL_WARN(_msg) MessageBoxW(nullptr, _msg, L"VNR Warning", MB_OK)
14 +#define GROWL_ERROR(_msg) MessageBoxW(nullptr, _msg, L"VNR Error", MB_OK)
15 +
16 +inline void GROWL_DWORD(DWORD value)
17 +{
18 + WCHAR buf[100];
19 + swprintf(buf, L"DWORD: %x", value);
20 + GROWL_MSG(buf);
21 +}
22 +
23 +inline void GROWL_DWORD2(DWORD v, DWORD v2)
24 +{
25 + WCHAR buf[100];
26 + swprintf(buf, L"DWORD2: %x,%x", v, v2);
27 + GROWL_MSG(buf);
28 +}
29 +
30 +inline void GROWL_DWORD3(DWORD v, DWORD v2, DWORD v3)
31 +{
32 + WCHAR buf[100];
33 + swprintf(buf, L"DWORD3: %x,%x,%x", v, v2, v3);
34 + GROWL_MSG(buf);
35 +}
36 +
37 +inline void GROWL_DWORD4(DWORD v, DWORD v2, DWORD v3, DWORD v4)
38 +{
39 + WCHAR buf[100];
40 + swprintf(buf, L"DWORD4: %x,%x,%x,%x", v, v2, v3, v4);
41 + GROWL_MSG(buf);
42 +}
43 +
44 +inline void GROWL_DWORD5(DWORD v, DWORD v2, DWORD v3, DWORD v4, DWORD v5)
45 +{
46 + WCHAR buf[100];
47 + swprintf(buf, L"DWORD5: %x,%x,%x,%x,%x", v, v2, v3, v4, v5);
48 + GROWL_MSG(buf);
49 +}
50 +
51 +inline void GROWL_DWORD6(DWORD v, DWORD v2, DWORD v3, DWORD v4, DWORD v5, DWORD v6)
52 +{
53 + WCHAR buf[100];
54 + swprintf(buf, L"DWORD6: %x,%x,%x,%x,%x,%x", v, v2, v3, v4, v5, v6);
55 + GROWL_MSG(buf);
56 +}
57 +
58 +inline void GROWL_DWORD7(DWORD v, DWORD v2, DWORD v3, DWORD v4, DWORD v5, DWORD v6, DWORD v7)
59 +{
60 + WCHAR buf[100];
61 + swprintf(buf, L"DWORD7: %x,%x,%x,%x,%x,%x,%x", v, v2, v3, v4, v5, v6, v7);
62 + GROWL_MSG(buf);
63 +}
64 +
65 +inline void GROWL_DWORD8(DWORD v, DWORD v2, DWORD v3, DWORD v4, DWORD v5, DWORD v6, DWORD v7, DWORD v8)
66 +{
67 + WCHAR buf[100];
68 + swprintf(buf, L"DWORD8: %x,%x,%x,%x,%x,%x,%x,%x", v, v2, v3, v4, v5, v6, v7, v8);
69 + GROWL_MSG(buf);
70 +}
71 +
72 +inline void GROWL_DWORD9(DWORD v, DWORD v2, DWORD v3, DWORD v4, DWORD v5, DWORD v6, DWORD v7, DWORD v8, DWORD v9)
73 +{
74 + WCHAR buf[100];
75 + swprintf(buf, L"DWORD9: %x,%x,%x,%x,%x,%x,%x,%x,%x", v, v2, v3, v4, v5, v6, v7, v8, v9);
76 + GROWL_MSG(buf);
77 +}
78 +
79 +inline void GROWL(DWORD v) { GROWL_DWORD(v); }
80 +inline void GROWL(LPCWSTR v) { GROWL_MSG(v); }
81 +inline void GROWL(LPCSTR v) { GROWL_MSG_A(v); }
82 +
83 +//#endif // GROWL_HAS_GROWL
84 +
85 +// EOF
1 +# texthook.pro
2 +# CONFIG += noqtgui dll #eha # eha will catch all exceptions, but does not work on Windows XP
3 +
4 +# DEFINES += ITH_HAS_CRT # Use native CRT
5 +
6 +# # TODO: Get rid of dependence on msvc's swprintf
7 +# DEFINES += _CRT_NON_CONFORMING_SWPRINTFS
8 +
9 +set(vnrhost_src
10 + avl_p.h
11 + config.h
12 + hookman.h
13 + host.h
14 + host_p.h
15 + settings.h
16 + textthread.h
17 + textthread_p.h
18 + hookman.cc
19 + host.cc
20 + pipe.cc
21 + textthread.cc
22 + ${PROJECT_SOURCE_DIR}/winmaker/winmaker.h
23 + ${PROJECT_SOURCE_DIR}/winmaker/winmaker.cc
24 + ${PROJECT_SOURCE_DIR}/winmutex/winmutex.h
25 +# ${PROJECT_SOURCE_DIR}/wintimer/wintimer.h
26 +# ${PROJECT_SOURCE_DIR}/wintimer/wintimer.cc
27 +# ${PROJECT_SOURCE_DIR}/wintimer/wintimerbase.cc
28 +# ${PROJECT_SOURCE_DIR}/wintimer/wintimerbase.h
29 + ${PROJECT_SOURCE_DIR}/windbg/windbg.h
30 + ${PROJECT_SOURCE_DIR}/windbg/windbg_p.h
31 + ${PROJECT_SOURCE_DIR}/windbg/inject.h
32 + ${PROJECT_SOURCE_DIR}/windbg/inject.cc
33 + ${PROJECT_SOURCE_DIR}/windbg/hijack.h
34 + ${PROJECT_SOURCE_DIR}/windbg/hijack.cc
35 + ${PROJECT_SOURCE_DIR}/windbg/util.h
36 +# ${PROJECT_SOURCE_DIR}/windbg/util.cc
37 + ${PROJECT_SOURCE_DIR}/windbg/unload.h
38 + ${PROJECT_SOURCE_DIR}/windbg/unload.cc
39 + ${PROJECT_SOURCE_DIR}/sakurakit/skdebug.h
40 +)
41 +
42 +add_library(vnrhost SHARED ${vnrhost_src})
43 +
44 +set_target_properties(vnrhost PROPERTIES LINK_FLAGS /SUBSYSTEM:WINDOWS)
45 +
46 +target_compile_options(vnrhost PRIVATE
47 +# /GR-
48 + $<$<CONFIG:Release>:>
49 + $<$<CONFIG:Debug>:>
50 +)
51 +
52 +#STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
53 +
54 +target_link_libraries(vnrhost
55 + ithsys
56 + profile
57 + ${WDK_HOME}/lib/wxp/i386/ntdll.lib
58 +)
59 +
60 +target_compile_definitions(vnrhost
61 + PRIVATE
62 + ITH_HAS_CRT
63 + _CRT_NON_CONFORMING_SWPRINTFS
64 +)
65 +
66 +install(TARGETS vnrhost RUNTIME
67 + DESTINATION .
68 + CONFIGURATIONS Release
69 +)
This diff is collapsed. Click to expand it.
1 +#pragma once
2 +
3 +// config.h
4 +// 8/23/2013 jichi
5 +// The first header file that are included by all source files.
6 +
7 +#define IHF // for dll import
8 +//#include "ith/dllconfig.h"
9 +#define IHFAPI __stdcall
10 +#ifdef IHF
11 +# define IHFSERVICE __declspec(dllexport)
12 +#else
13 +# define IHFSERVICE __declspec(dllimport)
14 +#endif
15 +
16 +// EOF
This diff is collapsed. Click to expand it.
1 +#pragma once
2 +
3 +// hookman.h
4 +// 8/23/2013 jichi
5 +// Branch: ITH/HookManager.h, rev 133
6 +
7 +#include "host/avl_p.h"
8 +#include "host/textthread.h"
9 +#include "winmutex/winmutex.h"
10 +
11 +namespace pugi {
12 + class xml_node;
13 +}
14 +class Profile;
15 +
16 +enum { MAX_REGISTER = 0xf };
17 +enum { MAX_PREV_REPEAT_LENGTH = 0x20 };
18 +
19 +struct ProcessRecord {
20 + DWORD pid_register;
21 + DWORD hookman_register;
22 + DWORD module_register;
23 + //DWORD engine_register; // jichi 10/19/2014: removed
24 + HANDLE process_handle;
25 + HANDLE hookman_mutex;
26 + HANDLE hookman_section;
27 + LPVOID hookman_map;
28 +};
29 +
30 +class ThreadTable : public MyVector<TextThread *, 0x40>
31 +{
32 +public:
33 + virtual void SetThread(DWORD number, TextThread *ptr);
34 + virtual TextThread *FindThread(DWORD number);
35 +};
36 +
37 +struct IHFSERVICE TCmp { char operator()(const ThreadParameter *t1, const ThreadParameter *t2); };
38 +struct IHFSERVICE TCpy { void operator()(ThreadParameter *t1, const ThreadParameter *t2); };
39 +struct IHFSERVICE TLen { int operator()(const ThreadParameter *t); };
40 +
41 +typedef DWORD (*ProcessEventCallback)(DWORD pid);
42 +
43 +class IHFSERVICE HookManager : public AVLTree<ThreadParameter, DWORD, TCmp, TCpy, TLen>
44 +{
45 +public:
46 + HookManager();
47 + ~HookManager();
48 + // jichi 12/26/2013: remove virtual modifiers
49 + TextThread *FindSingle(DWORD pid, DWORD hook, DWORD retn, DWORD split);
50 + TextThread *FindSingle(DWORD number);
51 + ProcessRecord *GetProcessRecord(DWORD pid);
52 + DWORD GetProcessIDByPath(LPCWSTR str); // private
53 + void RemoveSingleThread(DWORD number);
54 + //void LockHookman();
55 + //void UnlockHookman();
56 + void ResetRepeatStatus();
57 + void ClearCurrent();
58 + void AddLink(WORD from, WORD to);
59 + void UnLink(WORD from);
60 + void UnLinkAll(WORD from);
61 + void SelectCurrent(DWORD num);
62 + void DetachProcess(DWORD pid);
63 + void SetCurrent(TextThread *it);
64 + void AddConsoleOutput(LPCWSTR text);
65 +
66 + // jichi 10/27/2013: Add const; add space.
67 + void DispatchText(DWORD pid, const BYTE *text, DWORD hook, DWORD retn, DWORD split, int len, bool space);
68 +
69 + void ClearText(DWORD pid, DWORD hook, DWORD retn, DWORD split); // private
70 + void RemoveProcessContext(DWORD pid); // private
71 + void RemoveSingleHook(DWORD pid, DWORD addr);
72 + void RegisterThread(TextThread*, DWORD); // private
73 + void RegisterPipe(HANDLE text, HANDLE cmd, HANDLE thread);
74 + void RegisterProcess(DWORD pid, DWORD hookman, DWORD module);
75 + void UnRegisterProcess(DWORD pid);
76 + //void SetName(DWORD);
77 +
78 + DWORD GetCurrentPID(); // private
79 + HANDLE GetCmdHandleByPID(DWORD pid);
80 +
81 + ConsoleCallback RegisterConsoleCallback(ConsoleCallback cf)
82 + { return (ConsoleCallback)_InterlockedExchange((long*)&console,(long)cf); }
83 +
84 + ConsoleWCallback RegisterConsoleWCallback(ConsoleWCallback cf)
85 + { return (ConsoleWCallback)_InterlockedExchange((long*)&wconsole,(long)cf); }
86 +
87 + ThreadEventCallback RegisterThreadCreateCallback(ThreadEventCallback cf)
88 + { return (ThreadEventCallback)_InterlockedExchange((long*)&create,(long)cf); }
89 +
90 + ThreadEventCallback RegisterThreadRemoveCallback(ThreadEventCallback cf)
91 + { return (ThreadEventCallback)_InterlockedExchange((long*)&remove,(long)cf); }
92 +
93 + ThreadEventCallback RegisterThreadResetCallback(ThreadEventCallback cf)
94 + { return (ThreadEventCallback)_InterlockedExchange((long*)&reset,(long)cf); }
95 +
96 + ThreadEventCallback RegisterAddRemoveLinkCallback(ThreadEventCallback cf)
97 + { return (ThreadEventCallback)_InterlockedExchange((long*)&addRemoveLink, (long)cf); }
98 +
99 + ProcessEventCallback RegisterProcessAttachCallback(ProcessEventCallback cf)
100 + { return (ProcessEventCallback)_InterlockedExchange((long*)&attach,(long)cf); }
101 +
102 + ProcessEventCallback RegisterProcessDetachCallback(ProcessEventCallback cf)
103 + { return (ProcessEventCallback)_InterlockedExchange((long*)&detach,(long)cf); }
104 +
105 + ProcessEventCallback RegisterProcessNewHookCallback(ProcessEventCallback cf)
106 + { return (ProcessEventCallback)_InterlockedExchange((long*)&hook,(long)cf); }
107 +
108 + ProcessEventCallback ProcessNewHook() { return hook; }
109 + TextThread *GetCurrentThread() { return current; } // private
110 + ProcessRecord *Records() { return record; } // private
111 + ThreadTable *Table() { return thread_table; } // private
112 +
113 + //DWORD& SplitTime() { return split_time; }
114 + //DWORD& RepeatCount() { return repeat_count; }
115 + //DWORD& CyclicRemove() { return cyclic_remove; }
116 + //DWORD& GlobalFilter() { return global_filter; }
117 + void ConsoleOutput(LPCSTR text) { if (console) console(text); } // not thread safe
118 + void ConsoleOutputW(LPCWSTR text) { if (wconsole) wconsole(text); } // not thread safe
119 +
120 + void OnThreadCreate(pugi::xml_node profile_node, TextThread* thread);
121 + void GetProfile(DWORD pid, pugi::xml_node profile_node);
122 +
123 +private:
124 + typedef win_mutex<CRITICAL_SECTION> mutex_type;
125 + mutex_type hmcs;
126 +
127 + TextThread *current;
128 + ConsoleCallback console; // jichi 12/25/2013: add console output callback
129 + ConsoleWCallback wconsole;
130 + ThreadEventCallback create,
131 + remove,
132 + reset,
133 + addRemoveLink;
134 + ProcessEventCallback attach,
135 + detach,
136 + hook;
137 + DWORD current_pid;
138 + ThreadTable *thread_table;
139 + HANDLE destroy_event;
140 + ProcessRecord record[MAX_REGISTER + 1];
141 + HANDLE text_pipes[MAX_REGISTER + 1],
142 + cmd_pipes[MAX_REGISTER + 1],
143 + recv_threads[MAX_REGISTER + 1];
144 + WORD register_count,
145 + new_thread_number;
146 +
147 + // jichi 1/16/2014: Stop adding new threads when full
148 + bool IsFull() const; // { return new_thread_number >= MAX_HOOK; }
149 + bool IsEmpty() const { return !new_thread_number; }
150 + void HookManager::AddThreadsToProfile(Profile& pf, const ProcessRecord& pr, DWORD pid);
151 +};
152 +
153 +// EOF
This diff is collapsed. Click to expand it.
1 +#pragma once
2 +
3 +// host.h
4 +// 8/23/2013 jichi
5 +// Branch: ITH/IHF.h, rev 105
6 +
7 +//#include "host/settings.h"
8 +#include "config.h"
9 +#include "host/hookman.h"
10 +
11 +struct Settings;
12 +struct HookParam;
13 +
14 +IHFSERVICE void IHFAPI Host_Init();
15 +IHFSERVICE void IHFAPI Host_Destroy();
16 +
17 +IHFSERVICE DWORD IHFAPI Host_Start();
18 +IHFSERVICE BOOL IHFAPI Host_Open();
19 +IHFSERVICE DWORD IHFAPI Host_Close();
20 +IHFSERVICE DWORD IHFAPI Host_GetHookManager(HookManager **hookman);
21 +IHFSERVICE bool IHFAPI Host_GetSettings(Settings **settings);
22 +IHFSERVICE DWORD IHFAPI Host_GetPIDByName(LPCWSTR pwcTarget);
23 +IHFSERVICE bool IHFAPI Host_InjectByPID(DWORD pid);
24 +IHFSERVICE bool IHFAPI Host_ActiveDetachProcess(DWORD pid);
25 +IHFSERVICE bool IHFAPI Host_HijackProcess(DWORD pid);
26 +IHFSERVICE DWORD IHFAPI Host_InsertHook(DWORD pid, HookParam *hp, LPCSTR name = nullptr);
27 +IHFSERVICE DWORD IHFAPI Host_ModifyHook(DWORD pid, HookParam *hp);
28 +IHFSERVICE DWORD IHFAPI Host_RemoveHook(DWORD pid, DWORD addr);
29 +IHFSERVICE DWORD IHFAPI Host_AddLink(DWORD from, DWORD to);
30 +IHFSERVICE DWORD IHFAPI Host_UnLink(DWORD from);
31 +IHFSERVICE DWORD IHFAPI Host_UnLinkAll(DWORD from);
32 +
33 +// EOF
1 +# host.pri
2 +# 8/9/2011 jichi
3 +
4 +DEFINES += WITH_LIB_VNRHOST
5 +
6 +DEPENDPATH += $$PWD
7 +
8 +HEADERS += \
9 + $$PWD/avl_p.h \
10 + $$PWD/hookman.h \
11 + $$PWD/settings.h \
12 + $$PWD/host.h \
13 + $$PWD/host_p.h \
14 + $$PWD/textthread.h \
15 + $$PWD/textthread_p.h
16 +
17 +SOURCES += \
18 + $$PWD/hookman.cc \
19 + $$PWD/host.cc \
20 + $$PWD/pipe.cc \
21 + $$PWD/textthread.cc
22 +
23 +# EOF
1 +#pragma once
2 +// host_p.h
3 +// 8/24/2013 jichi
4 +// Branch IHF/main.h, rev 111
5 +#include <windows.h>
6 +
7 +#define GLOBAL extern
8 +#define SHIFT_JIS 0x3A4
9 +class HookManager;
10 +//class CommandQueue;
11 +class SettingManager;
12 +class TextHook;
13 +//class BitMap;
14 +//class CustomFilterMultiByte;
15 +//class CustomFilterUnicode;
16 +//#define TextHook Hook
17 +GLOBAL BOOL running;
18 +//GLOBAL BitMap *pid_map;
19 +//GLOBAL CustomFilterMultiByte *mb_filter;
20 +//GLOBAL CustomFilterUnicode *uni_filter;
21 +GLOBAL HookManager *man;
22 +//GLOBAL CommandQueue *cmdq;
23 +GLOBAL SettingManager *setman;
24 +GLOBAL WCHAR recv_pipe[];
25 +GLOBAL WCHAR command[];
26 +GLOBAL HANDLE hPipeExist;
27 +GLOBAL DWORD split_time,
28 + cyclic_remove,
29 + clipboard_flag,
30 + global_filter;
31 +GLOBAL CRITICAL_SECTION detach_cs;
32 +
33 +DWORD WINAPI RecvThread(LPVOID lpThreadParameter);
34 +DWORD WINAPI CmdThread(LPVOID lpThreadParameter);
35 +
36 +DWORD GetCurrentPID();
37 +//DWORD GetProcessIDByPath(LPWSTR str);
38 +HANDLE GetCmdHandleByPID(DWORD pid);
39 +//DWORD Inject(HANDLE hProc);
40 +//DWORD InjectByPID(DWORD pid);
41 +//DWORD PIDByName(LPWSTR target);
42 +//DWORD Hash(LPCWSTR module, int length=-1);
43 +
44 +// EOF
1 +// pipe.cc
2 +// 8/24/2013 jichi
3 +// Branch IHF/pipe.cpp, rev 93
4 +// 8/24/2013 TODO: Clean up this file
5 +
6 +#include "host_p.h"
7 +#include "hookman.h"
8 +#include "vnrhook/include/defs.h"
9 +#include "vnrhook/include/const.h"
10 +#include "ithsys/ithsys.h"
11 +#include <stdio.h>
12 +//#include "CommandQueue.h"
13 +//#include <QtCore/QDebug>
14 +
15 +#define DEBUG "vnrhost/pipe.cc"
16 +#include "sakurakit/skdebug.h"
17 +
18 +//DWORD WINAPI UpdateWindows(LPVOID lpThreadParameter);
19 +
20 +namespace { // unnamed
21 +enum NamedPipeCommand {
22 + NAMED_PIPE_DISCONNECT = 1
23 + , NAMED_PIPE_CONNECT = 2
24 +};
25 +
26 +bool newline = false;
27 +bool detach = false;
28 +
29 +// jichi 10/27/2013
30 +// Check if text has leading space
31 +enum { _filter_limit = 0x20 }; // The same as the orignal ITH filter. So, I don't have to check \u3000
32 +//enum { _filter_limit = 0x19 };
33 +inline bool has_leading_space(const BYTE *text, int len)
34 +{
35 + return len == 1 ? *text <= _filter_limit : // 1 byte
36 + *reinterpret_cast<const WORD *>(text) <= _filter_limit; // 2 bytes
37 +}
38 +
39 +// jichi 9/28/2013: Skip leading garbage
40 +// Note:
41 +// - Modifying limit will break manual translation. The orignal one is 0x20
42 +// - Eliminating 0x20 will break English-translated games
43 +const BYTE *Filter(const BYTE *str, int len)
44 +{
45 +#ifdef ITH_DISABLE_FILTER // jichi 9/28/2013: only for debugging purpose
46 + return str;
47 +#endif // ITH_DISABLE_FILTER
48 +// if (len && *str == 0x10) // jichi 9/28/2013: garbage on wine, data link escape, or ^P
49 +// return nullptr;
50 + //enum { limit = 0x19 };
51 + while (true)
52 + if (len >= 2) {
53 + if (*(const WORD *)str <= _filter_limit) { // jichi 10/27/2013: two bytes
54 + str += 2;
55 + len -= 2;
56 + } else
57 + break;
58 + } else if (*str <= _filter_limit) { // jichi 10/27/2013: 1 byte
59 + str++;
60 + len--;
61 + } else
62 + break;
63 + return str;
64 +}
65 +} // unnamed namespace
66 +
67 +//WCHAR recv_pipe[] = L"\\??\\pipe\\ITH_PIPE";
68 +//WCHAR command_pipe[] = L"\\??\\pipe\\ITH_COMMAND";
69 +wchar_t recv_pipe[] = ITH_TEXT_PIPE;
70 +wchar_t command_pipe[] = ITH_COMMAND_PIPE;
71 +
72 +CRITICAL_SECTION detach_cs; // jichi 9/27/2013: also used in main
73 +//HANDLE hDetachEvent;
74 +extern HANDLE hPipeExist;
75 +
76 +void CreateNewPipe()
77 +{
78 + static DWORD acl[7] = {
79 + 0x1C0002,
80 + 1,
81 + 0x140000,
82 + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
83 + 0x101,
84 + 0x1000000,
85 + 0};
86 + static SECURITY_DESCRIPTOR sd = {1, 0, 4, 0, 0, 0, (PACL)acl};
87 +
88 + HANDLE hTextPipe, hCmdPipe, hThread;
89 + IO_STATUS_BLOCK ios;
90 + UNICODE_STRING us;
91 +
92 + OBJECT_ATTRIBUTES oa = {sizeof(oa), 0, &us, OBJ_CASE_INSENSITIVE, &sd, 0};
93 + LARGE_INTEGER time = {-500000, -1};
94 +
95 + RtlInitUnicodeString(&us, recv_pipe);
96 + if (!NT_SUCCESS(NtCreateNamedPipeFile(
97 + &hTextPipe,
98 + GENERIC_READ | SYNCHRONIZE,
99 + &oa,
100 + &ios,
101 + FILE_SHARE_WRITE,
102 + FILE_OPEN_IF,
103 + FILE_SYNCHRONOUS_IO_NONALERT,
104 + 1, 1, 0, -1,
105 + 0x1000,
106 + 0x1000,
107 + &time))) {
108 + //ConsoleOutput(ErrorCreatePipe);
109 + DOUT("failed to create recv pipe");
110 + return;
111 + }
112 +
113 + RtlInitUnicodeString(&us, command_pipe);
114 + if (!NT_SUCCESS(NtCreateNamedPipeFile(
115 + &hCmdPipe,
116 + GENERIC_WRITE | SYNCHRONIZE,
117 + &oa,
118 + &ios,
119 + FILE_SHARE_READ,
120 + FILE_OPEN_IF,
121 + FILE_SYNCHRONOUS_IO_NONALERT,
122 + 1, 1, 0, -1,
123 + 0x1000,
124 + 0x1000,
125 + &time))) {
126 + //ConsoleOutput(ErrorCreatePipe);
127 + DOUT("failed to create cmd pipe");
128 + return;
129 + }
130 +
131 + hThread = IthCreateThread(RecvThread, (DWORD)hTextPipe);
132 + man->RegisterPipe(hTextPipe, hCmdPipe, hThread);
133 +}
134 +
135 +void DetachFromProcess(DWORD pid)
136 +{
137 + HANDLE hMutex = INVALID_HANDLE_VALUE,
138 + hEvent = INVALID_HANDLE_VALUE;
139 + //try {
140 + IO_STATUS_BLOCK ios;
141 + ProcessRecord *pr = man->GetProcessRecord(pid);
142 + if (!pr)
143 + return;
144 + //IthBreak();
145 + hEvent = IthCreateEvent(nullptr);
146 + if (STATUS_PENDING == NtFsControlFile(
147 + man->GetCmdHandleByPID(pid),
148 + hEvent,
149 + 0,0,
150 + &ios,
151 + CTL_CODE(FILE_DEVICE_NAMED_PIPE, NAMED_PIPE_DISCONNECT, 0, 0),
152 + 0,0,0,0))
153 + NtWaitForSingleObject(hEvent, 0, 0);
154 + NtClose(hEvent);
155 + //hEvent = INVALID_HANDLE_VALUE;
156 +
157 + WCHAR mutex[0x20];
158 + swprintf(mutex, ITH_DETACH_MUTEX_ L"%d", pid);
159 + hMutex = IthOpenMutex(mutex);
160 + if (hMutex != INVALID_HANDLE_VALUE) {
161 + NtWaitForSingleObject(hMutex, 0, 0);
162 + NtReleaseMutant(hMutex, 0);
163 + NtClose(hMutex);
164 + //hMutex = INVALID_HANDLE_VALUE;
165 + }
166 +
167 + //} catch (...) {
168 + // if (hEvent != INVALID_HANDLE_VALUE)
169 + // NtClose(hEvent);
170 + // else if (hMutex != INVALID_HANDLE_VALUE) {
171 + // NtWaitForSingleObject(hMutex, 0, 0);
172 + // NtReleaseMutant(hMutex, 0);
173 + // NtClose(hMutex);
174 + // }
175 + //}
176 +
177 + //NtSetEvent(hDetachEvent, 0);
178 + if (::running)
179 + NtSetEvent(hPipeExist, 0);
180 +}
181 +
182 +// jichi 9/27/2013: I don't need this
183 +//void OutputDWORD(DWORD d)
184 +//{
185 +// WCHAR str[0x20];
186 +// swprintf(str, L"%.8X", d);
187 +// ConsoleOutput(str);
188 +//}
189 +
190 +DWORD WINAPI RecvThread(LPVOID lpThreadParameter)
191 +{
192 + HANDLE hTextPipe = (HANDLE)lpThreadParameter;
193 +
194 + IO_STATUS_BLOCK ios;
195 + NtFsControlFile(hTextPipe,
196 + 0, 0, 0,
197 + &ios,
198 + CTL_CODE(FILE_DEVICE_NAMED_PIPE, NAMED_PIPE_CONNECT, 0, 0),
199 + 0, 0, 0, 0);
200 + if (!::running) {
201 + NtClose(hTextPipe);
202 + return 0;
203 + }
204 +
205 + BYTE *buff;
206 +
207 + enum { PipeBufferSize = 0x1000 };
208 + buff = new BYTE[PipeBufferSize];
209 + ::memset(buff, 0, PipeBufferSize); // jichi 8/27/2013: zero memory, or it will crash wine on start up
210 +
211 + // 10/19/2014 jichi: there are totally three words received
212 + // See: hook/rpc/pipe.cc
213 + // struct {
214 + // DWORD pid;
215 + // TextHook *man;
216 + // DWORD module;
217 + // //DWORD engine;
218 + // } u;
219 + enum { module_struct_size = 12 };
220 + NtReadFile(hTextPipe, 0, 0, 0, &ios, buff, module_struct_size, 0, 0);
221 +
222 + // jichi 7/2/2015: This must be consistent with the struct declared in vnrhook/pipe.cc
223 + DWORD pid = *(DWORD *)buff,
224 + module = *(DWORD *)(buff + 0x8),
225 + hookman = *(DWORD *)(buff + 0x4);
226 + //engine = *(DWORD *)(buff + 0xc);
227 + man->RegisterProcess(pid, hookman, module);
228 +
229 + // jichi 9/27/2013: why recursion?
230 + CreateNewPipe();
231 +
232 + //NtClose(IthCreateThread(UpdateWindows,0));
233 + while (::running) {
234 + if (!NT_SUCCESS(NtReadFile(hTextPipe,
235 + 0, 0, 0,
236 + &ios,
237 + buff,
238 + 0xf80,
239 + 0, 0)))
240 + break;
241 +
242 + enum { data_offset = 0xc }; // jichi 10/27/2013: Seem to be the data offset in the pipe
243 +
244 + DWORD RecvLen = ios.uInformation;
245 + if (RecvLen < data_offset)
246 + break;
247 + DWORD hook = *(DWORD *)buff;
248 +
249 + union { DWORD retn; DWORD cmd_type; };
250 + union { DWORD split; DWORD new_engine_type; };
251 +
252 + retn = *(DWORD *)(buff + 4);
253 + split = *(DWORD *)(buff + 8);
254 +
255 + buff[RecvLen] = 0;
256 + buff[RecvLen + 1] = 0;
257 +
258 + if (hook == HOST_NOTIFICATION) {
259 + switch (cmd_type) {
260 + case HOST_NOTIFICATION_NEWHOOK:
261 + {
262 + static long lock;
263 + while (InterlockedExchange(&lock, 1) == 1);
264 + ProcessEventCallback new_hook = man->ProcessNewHook();
265 + if (new_hook)
266 + new_hook(pid);
267 + lock = 0;
268 + } break;
269 + case HOST_NOTIFICATION_TEXT:
270 + //qDebug() << ((LPCSTR)(buff + 8));
271 + break;
272 + }
273 + } else {
274 + // jichi 9/28/2013: Debug raw data
275 + //ITH_DEBUG_DWORD9(RecvLen - 0xc,
276 + // buff[0xc], buff[0xd], buff[0xe], buff[0xf],
277 + // buff[0x10], buff[0x11], buff[0x12], buff[0x13]);
278 +
279 + const BYTE *data = buff + data_offset; // th
280 + int len = RecvLen - data_offset;
281 + bool space = ::has_leading_space(data, len);
282 + if (space) {
283 + const BYTE *it = ::Filter(data, len);
284 + len -= it - data;
285 + data = it;
286 + }
287 + if (len >> 31) // jichi 10/27/2013: len is too large, which seldom happens
288 + len = 0;
289 + //man->DispatchText(pid, len ? data : nullptr, hook, retn, split, len, space);
290 + man->DispatchText(pid, data, hook, retn, split, len, space);
291 + }
292 + }
293 +
294 + EnterCriticalSection(&detach_cs);
295 +
296 + HANDLE hDisconnect = IthCreateEvent(nullptr);
297 +
298 + if (STATUS_PENDING == NtFsControlFile(
299 + hTextPipe,
300 + hDisconnect,
301 + 0, 0,
302 + &ios,
303 + CTL_CODE(FILE_DEVICE_NAMED_PIPE, NAMED_PIPE_DISCONNECT, 0, 0),
304 + 0, 0, 0, 0))
305 + NtWaitForSingleObject(hDisconnect, 0, 0);
306 +
307 + NtClose(hDisconnect);
308 + DetachFromProcess(pid);
309 + man->UnRegisterProcess(pid);
310 +
311 + //NtClearEvent(hDetachEvent);
312 +
313 + LeaveCriticalSection(&detach_cs);
314 + delete[] buff;
315 +
316 + if (::running)
317 + DOUT("detached");
318 +
319 + //if (::running) {
320 + // swprintf((LPWSTR)buff, FormatDetach, pid);
321 + // ConsoleOutput((LPWSTR)buff);
322 + // NtClose(IthCreateThread(UpdateWindows, 0));
323 + //}
324 + return 0;
325 +}
326 +
327 +// EOF
1 +#pragma once
2 +
3 +// settings.h
4 +// 8/24/2013 jichi
5 +
6 +struct Settings {
7 + //bool debug; // whether output debug messages using pipes
8 + int splittingInterval;// time to split text into sentences
9 + bool clipboardFlag;
10 +
11 + Settings() : splittingInterval(200),
12 + clipboardFlag(false)
13 + {}
14 +
15 +};
16 +
17 +// EOF
This diff is collapsed. Click to expand it.
1 +#pragma once
2 +
3 +// textthread.h
4 +// 8/23/2013 jichi
5 +// Branch: ITH/TextThread.h, rev 120
6 +
7 +#include "host/textthread_p.h"
8 +#include <intrin.h> // require _InterlockedExchange
9 +
10 +struct RepeatCountNode {
11 + short repeat;
12 + short count;
13 + RepeatCountNode *next;
14 +
15 + //RepeatCountNode() : repeat(0), count(0), next(nullptr) {}
16 +};
17 +
18 +struct ThreadParameter {
19 + DWORD pid; // jichi: 5/11/2014: The process ID
20 + DWORD hook;
21 + DWORD retn; // jichi 5/11/2014: The return address of the hook
22 + DWORD spl; // jichi 5/11/2014: the processed split value of the hook parameter
23 +};
24 +
25 +#define CURRENT_SELECT 0x1000
26 +#define REPEAT_NUMBER_DECIDED 0x2000
27 +#define BUFF_NEWLINE 0x4000
28 +#define CYCLIC_REPEAT 0x8000
29 +#define COUNT_PER_FOWARD 0x200
30 +#define REPEAT_DETECT 0x10000
31 +#define REPEAT_SUPPRESS 0x20000
32 +#define REPEAT_NEWLINE 0x40000
33 +
34 +class TextThread;
35 +typedef void (* ConsoleCallback)(LPCSTR text);
36 +typedef void (* ConsoleWCallback)(LPCWSTR text);
37 +typedef DWORD (* ThreadOutputFilterCallback)(TextThread *, BYTE *, DWORD, DWORD, PVOID, bool space); // jichi 10/27/2013: Add space
38 +typedef DWORD (* ThreadEventCallback)(TextThread *);
39 +
40 +//extern DWORD split_time,repeat_count,global_filter,cyclic_remove;
41 +
42 +class TextThread : public MyVector<BYTE, 0x200>
43 +{
44 +public:
45 + TextThread(DWORD pid, DWORD hook, DWORD retn, DWORD spl, WORD num);
46 + ~TextThread();
47 + //virtual void CopyLastSentence(LPWSTR str);
48 + //virtual void SetComment(LPWSTR);
49 + //virtual void ExportTextToFile(LPWSTR filename);
50 +
51 + virtual bool CheckCycle(TextThread *start);
52 + virtual DWORD GetThreadString(LPSTR str, DWORD max);
53 + virtual DWORD GetEntryString(LPSTR str, DWORD max = 0x200);
54 +
55 + void Reset();
56 + void AddText(const BYTE *con,int len, bool new_line, bool space); // jichi 10/27/2013: add const; remove console; add space
57 + void RemoveSingleRepeatAuto(const BYTE *con, int &len); // jichi 10/27/2013: add const
58 + void RemoveSingleRepeatForce(BYTE *con, int &len);
59 + void RemoveCyclicRepeat(BYTE *&con, int &len);
60 + void ResetRepeatStatus();
61 + void AddLineBreak();
62 + //void ResetEditText();
63 + void ComboSelectCurrent();
64 + void UnLinkAll();
65 + void CopyLastToClipboard();
66 +
67 + //void AdjustPrevRepeat(DWORD len);
68 + //void PrevRepeatLength(DWORD &len);
69 +
70 + //bool AddToCombo();
71 + bool RemoveFromCombo();
72 +
73 + void SetNewLineFlag();
74 + void SetNewLineTimer();
75 +
76 + BYTE *GetStore(DWORD *len) { if (len) *len = used; return storage; }
77 + DWORD LastSentenceLen() { return used - last_sentence; }
78 + DWORD PID() const { return tp.pid; }
79 + DWORD Addr() const {return tp.hook; }
80 + DWORD &Status() { return status; }
81 + WORD Number() const { return thread_number; }
82 + WORD &Last() { return last; }
83 + WORD &LinkNumber() { return link_number; }
84 + UINT_PTR &Timer() { return timer; }
85 + ThreadParameter *GetThreadParameter() { return &tp; }
86 + TextThread *&Link() { return link; }
87 + //LPCWSTR GetComment() { return comment; }
88 +
89 + ThreadOutputFilterCallback RegisterOutputCallBack(ThreadOutputFilterCallback cb, PVOID data)
90 + {
91 + app_data = data;
92 + return (ThreadOutputFilterCallback)_InterlockedExchange((long*)&output,(long)cb);
93 + }
94 +
95 + ThreadOutputFilterCallback RegisterFilterCallBack(ThreadOutputFilterCallback cb, PVOID data)
96 + {
97 + app_data = data;
98 + return (ThreadOutputFilterCallback)_InterlockedExchange((long*)&filter,(long)cb);
99 + }
100 +
101 + void SetRepeatFlag() { status |= CYCLIC_REPEAT; }
102 + void ClearNewLineFlag() { status &= ~BUFF_NEWLINE; }
103 + void ClearRepeatFlag() { status &= ~CYCLIC_REPEAT; }
104 +
105 +protected:
106 + void AddTextDirect(const BYTE *con, int len, bool space); // jichi 10/27/2013: add const; add space; change to protected
107 +
108 +private:
109 + ThreadParameter tp;
110 +
111 + WORD thread_number,
112 + link_number;
113 + WORD last,
114 + align_space;
115 + WORD repeat_single;
116 + WORD repeat_single_current;
117 + WORD repeat_single_count;
118 + WORD repeat_detect_count;
119 + RepeatCountNode *head;
120 +
121 + TextThread *link;
122 + ThreadOutputFilterCallback filter; // jichi 10/27/2013: Remove filter
123 + ThreadOutputFilterCallback output;
124 + PVOID app_data;
125 + LPSTR thread_string;
126 + UINT_PTR timer;
127 + DWORD status,repeat_detect_limit;
128 + DWORD last_sentence,
129 + prev_sentence,
130 + sentence_length,
131 + repeat_index,
132 + last_time;
133 +};
134 +
135 +// EOF
1 +#pragma once
2 +// textthread_p.h
3 +// 8/14/2013 jichi
4 +// Branch: ITH/main_template.h, rev 66
5 +
6 +#include <windows.h>
7 +
8 +template <typename T>
9 +void Release(const T &p) { delete p; }
10 +
11 +// Prevent memory release.
12 +// Used when T is basic types and will be automatically released (on stack).
13 +#define MK_BASIC_TYPE(T) \
14 + template<> \
15 + void Release<T>(const T &p) {}
16 +
17 +template<class T>
18 +struct BinaryEqual {
19 + bool operator ()(const T &a, const T &b, DWORD) { return a == b; }
20 +};
21 +
22 +template<class T, int default_size, class fComp=BinaryEqual<T> >
23 +class MyVector
24 +{
25 +public:
26 + MyVector() : size(default_size), used(0)
27 + {
28 + InitializeCriticalSection(&cs_store);
29 + storage = new T[size];
30 + // jichi 9/21/2013: zero memory
31 + // This would cause trouble if T is not an atomic type
32 + ::memset(storage, 0, sizeof(T) * size);
33 + }
34 +
35 + virtual ~MyVector()
36 + {
37 + if (storage)
38 + delete[] storage;
39 + DeleteCriticalSection(&cs_store);
40 + storage = 0;
41 + }
42 +
43 + void Reset()
44 + {
45 + EnterCriticalSection(&cs_store);
46 + for (int i = 0; i < used; i++) {
47 + Release<T>(storage[i]);
48 + storage[i] = T();
49 + }
50 + used = 0;
51 + LeaveCriticalSection(&cs_store);
52 + }
53 + void Remove(int index)
54 + {
55 + if (index>=used)
56 + return;
57 + Release<T>(storage[index]);
58 + for (int i = index; i < used; i++)
59 + storage[i] = storage[i+1];
60 + used--;
61 + }
62 + void ClearMemory(int offset, int clear_size)
63 + {
64 + if (clear_size < 0)
65 + return;
66 + EnterCriticalSection(&cs_store);
67 + if (offset+clear_size <= size)
68 + ::memset(storage+offset, 0, clear_size * sizeof(T)); // jichi 11/30/2013: This is the original code of ITH
69 + LeaveCriticalSection(&cs_store);
70 + //else __asm int 3
71 + }
72 + int AddToStore(T *con,int amount)
73 + {
74 + if (amount <= 0 || con == 0)
75 + return 0;
76 + int status = 0;
77 + EnterCriticalSection(&cs_store);
78 + if (amount + used + 2 >= size) {
79 + while (amount + used + 2 >= size)
80 + size<<=1;
81 + T *temp;
82 + if (size * sizeof(T) < 0x1000000) {
83 + temp = new T[size];
84 + if (size > used)
85 + ::memset(temp, 0, (size - used) * sizeof(T)); // jichi 9/25/2013: zero memory
86 + memcpy(temp, storage, used * sizeof(T));
87 + } else {
88 + size = default_size;
89 + temp = new T[size];
90 + ::memset(temp, 0, sizeof(T) * size); // jichi 9/25/2013: zero memory
91 + used = 0;
92 + status = 1;
93 + }
94 + delete[] storage;
95 + storage = temp;
96 + }
97 + memcpy(storage+used, con, amount * sizeof(T));
98 + used += amount;
99 + LeaveCriticalSection(&cs_store);
100 + return status;
101 + }
102 + int Find(const T &item, int start = 0, DWORD control = 0)
103 + {
104 + int c = -1;
105 + for (int i=start; i < used; i++)
106 + if (fCmp(storage[i],item,control)) {
107 + c=i;
108 + break;
109 + }
110 + //if (storage[i]==item) {c=i;break;}
111 + return c;
112 + }
113 + int Used() const { return used; }
114 + T *Storage() const { return storage; }
115 + void LockVector() { EnterCriticalSection(&cs_store); }
116 + void UnlockVector() { LeaveCriticalSection(&cs_store); }
117 +protected:
118 + CRITICAL_SECTION cs_store;
119 + int size,
120 + used;
121 + T *storage;
122 + fComp fCmp;
123 +};
124 +
125 +// EOF
126 +
127 +/*
128 +#ifndef ITH_STACK
129 +#define ITH_STACK
130 +template<class T, int default_size>
131 +class MyStack
132 +{
133 +public:
134 + MyStack(): index(0) {}
135 + void push_back(const T& e)
136 + {
137 + if (index<default_size)
138 + s[index++]=e;
139 + }
140 + void pop_back()
141 + {
142 + index--;
143 + }
144 + T& back()
145 + {
146 + return s[index-1];
147 + }
148 + T& operator[](int i) {return s[i];}
149 + int size() {return index;}
150 +private:
151 + int index;
152 + T s[default_size];
153 +};
154 +#endif
155 +*/
1 +# 6/6/2012
2 +# IHF.dll
3 +# Skip swprintf and MessageBox statements in GetDebugPriv
4 +#
5 +# SVN checkout: 2012/6/6
6 +# - IHF/main.cpp: 2012/4/8
7 +# - IHF.{dll,lib}: 2012/6/5
8 +
9 +6F753055 CALL DWORD PTR DS:ntdll.ZwAdjustPrivilegesTOken
10 +6F75305B TEST EAX,EAX
11 +6F75305B JNE SHORT 6F753077 => JNE SHORT 6F75309F
12 +...
13 +6F753077 PUSH EAX
14 +...
15 +6F75309F MOVE EAX,DWORD PTR SS:[ESP]
16 +6F7530A2 PUSH EAX
17 +6F7530A3 CALL DWORD PTR DS:ntdll.NtClose
18 +...
19 +
20 +# EOF
This diff is collapsed. Click to expand it.
1 +#pragma once
2 +
3 +// ihf_p.h
4 +// 10/15/2011 jichi
5 +// Internal header.
6 +// Wrapper of IHF functions.
7 +
8 +#include <QtCore/QHash>
9 +#include <QtCore/QList>
10 +#include <QtCore/QString>
11 +#include <QtGui/qwindowdefs.h> // for WId
12 +
13 +//struct Settings; // opaque in ith/host/settings.h
14 +class HookManager; // opaque in ith/host/hookman.h
15 +class TextThread; // opaque in ith/host/textthread.h
16 +class TextThreadDelegate;
17 +
18 +enum { ITH_THREAD_NAME_CAPACITY = 0x200 }; // used internally by ITH
19 +
20 +class Ihf
21 +{
22 + Ihf() {} // Singleton
23 +
24 + static bool enabled_;
25 +
26 + //static Settings *settings_;
27 + static HookManager *hookManager_;
28 + static qint64 messageInterval_;
29 + static WId parentWindow_;
30 +
31 + static QHash<TextThread *, TextThreadDelegate *> threadDelegates_;
32 + //static QHash<TextThreadDelegate *, TextThreadDelegate *> linkedDelegates_;
33 + static QHash<QString, ulong> hookAddresses_;
34 +
35 + enum { WhitelistSize = 0x20 + 1 }; // ITH capacity is 0x20
36 + static qint32 whitelist_[WhitelistSize]; // List of signatures. The last element is zero. I.e., at most BlackSize-1 threads.
37 + static bool whitelistEnabled_;
38 + static char keptThreadName_[ITH_THREAD_NAME_CAPACITY];
39 + //static QString userDefinedThreadName_;
40 +
41 +public:
42 +
43 + // - Initialization -
44 + static void init();
45 + static void destroy();
46 +
47 + static bool load();
48 + static bool isLoaded() { return hookManager_; }
49 + static void unload();
50 +
51 + // - Properties -
52 +
53 + static bool isEnabled() { return enabled_; }
54 + static void setEnabled(bool t) { enabled_ = t; }
55 +
56 + /// A valid window handle is required to make ITH work
57 + static WId parentWindow() { return parentWindow_; }
58 + static void setParentWindow(WId hwnd) { parentWindow_ = hwnd; }
59 +
60 + /// Timeout (msecs) for a text message
61 + static qint64 messageInterval() { return messageInterval_; }
62 + static void setMessageInterval(qint64 msecs) { messageInterval_ = msecs; }
63 +
64 + // - Injection -
65 + static bool attachProcess(ulong pid);
66 + static bool detachProcess(ulong pid);
67 + static bool hijackProcess(ulong pid);
68 +
69 + /// Add hook code
70 + static bool addHook(ulong pid, const QString &code, const QString &name = QString(), bool verbose = true);
71 + static bool updateHook(ulong pid, const QString &code); // not used
72 + static bool removeHook(ulong pid, const QString &code);
73 + static bool verifyHookCode(const QString &code);
74 +
75 + // - Whitelist -
76 + static bool isWhitelistEnabled() { return whitelistEnabled_; }
77 + static void setWhitelistEnabled(bool t) { whitelistEnabled_ = t; }
78 +
79 + static QList<qint32> whitelist();
80 + static void setWhitelist(const QList<qint32> &l);
81 + static void clearWhitelist();
82 +
83 + //static QString userDefinedThreadName() { return userDefinedThreadName_; }
84 + //static void setUserDefinedThreadName(const QString &val) { userDefinedThreadName_ = val; }
85 + static const char *keptThreadName() { return keptThreadName_; }
86 +
87 + static void setKeptThreadName(const QString &v)
88 + {
89 + if (v.size() < ITH_THREAD_NAME_CAPACITY)
90 + ::strcpy(keptThreadName_, v.toAscii());
91 + else
92 + setKeptThreadName(v.left(ITH_THREAD_NAME_CAPACITY - 1));
93 + }
94 +
95 +private:
96 + static bool whitelistContains(qint32 signature);
97 +
98 + // - Callbacks -
99 + //static ulong processAttach(ulong pid);
100 + //static ulong processDetach(ulong pid);
101 + //static ulong processNewHook(ulong pid);
102 +
103 + static ulong threadCreate(_In_ TextThread *t);
104 + static ulong threadRemove(_In_ TextThread *t);
105 + static ulong threadOutput(_In_ TextThread *t, _In_ uchar *data, _In_ ulong dataLength, _In_ ulong bNewLine, _In_ void *pUserData, _In_ bool space);
106 + //static ulong threadFilter(_In_ TextThread *t, _Out_ uchar *data, _In_ ulong dataLength, _In_ ulong bNewLine, _In_ void *pUserData);
107 + //static ulong threadReset(TextThread *t);
108 + //static void consoleOutput(const char *text);
109 + //static void consoleOutputW(const wchar_t *text);
110 +
111 + // - Linked threasds -
112 +private:
113 + //static TextThreadDelegate *findLinkedDelegate(TextThreadDelegate *d);
114 + static void updateLinkedDelegate(TextThreadDelegate *d);
115 +};
116 +
117 +// EOF
1 +// ith_p.cc
2 +// 10/15/2011 jichi
3 +
4 +#include "texthook/ith_p.h"
5 +#include "vnrhook/include/const.h"
6 +#include "vnrhook/include/types.h"
7 +#include <string>
8 +
9 +#define DEBUG "ith_p.cc"
10 +#include "sakurakit/skdebug.h"
11 +
12 +// HookParam copied from ITH/common.h:
13 +// struct HookParam // size = 40 (0x24)
14 +// {
15 +// typedef void (*DataFun)(DWORD, HookParam*, DWORD*, DWORD*, DWORD*);
16 +//
17 +// DWORD addr; // 4
18 +// DWORD off, // 8
19 +// ind, // 12
20 +// split, // 16
21 +// split_ind; // 20
22 +// DWORD module, // 24
23 +// function; // 28
24 +// DataFun text_fun; // 32, jichi: is this the same in x86 and x86_64?
25 +// DWORD type; // 36
26 +// WORD length_offset; // 38
27 +// BYTE hook_len, // 39
28 +// recover_len; // 40
29 +// };
30 +
31 +
32 +// - Implementation Details -
33 +
34 +namespace { namespace detail { // unnamed
35 +
36 +// ITH ORIGINAL CODE BEGIN
37 +
38 +// See: ITH/ITH.h
39 +// Revision: 133
40 +inline DWORD Hash(_In_ LPWSTR module, int length = -1)
41 +{
42 + bool flag = length == -1;
43 + DWORD hash = 0;
44 + for (; *module && (flag || length--); module++)
45 + hash = _rotr(hash,7) + *module; //hash=((hash>>7)|(hash<<25))+(*module);
46 + return hash;
47 +}
48 +
49 +// See: ITH/command.cpp
50 +// Revision: 133
51 +//
52 +// jichi note: str[0xF] will be modified and restored.
53 +// So, the buffer of str must be larger than 0xF.
54 +int Convert(_In_ LPWSTR str, _Out_ DWORD *num, _In_ LPWSTR delim)
55 +{
56 + if (!num)
57 + return -1;
58 + WCHAR t = *str,
59 + tc = *(str + 0xF);
60 + WCHAR temp[0x10] = {};
61 + LPWSTR it = temp,
62 + istr = str,
63 + id = temp;
64 + if (delim) {
65 + id = wcschr(delim, t);
66 + str[0xF] = delim[0]; // reset str[0xF] in case of out-of-bound iteration
67 + }
68 + else
69 + str[0xF] = 0; // reset str[0xF] in case of out-of-bound iteration
70 + while (!id && t) {
71 + *it = t;
72 + it++; istr++;
73 + t = *istr;
74 + if (delim)
75 + id = wcschr(delim, t);
76 + }
77 + swscanf(temp, L"%x", num);
78 + str[0xF] = tc; // restore the str[0xF]
79 + if (!id || istr - str == 0xF)
80 + return -1;
81 +
82 + if (!t)
83 + return istr - str; // >= 0
84 + else
85 + return id - delim; // >= 0
86 +}
87 +
88 +// See: ITH/command.cpp
89 +// Revision: 133
90 +//
91 +// jichi note: str[0xF] will be modified and restored.
92 +// So, the buffer of cmd must be larger than 0xF*2 = 0x1F.
93 +bool Parse(_In_ LPWSTR cmd, _Out_ HookParam &hp)
94 +{
95 + ::memset(&hp, 0, sizeof(hp));
96 +
97 + int t;
98 + bool accept = false;
99 + DWORD *data = &hp.offset; //
100 + LPWSTR offset = cmd + 1;
101 + LPWSTR delim_str = L":*@!";
102 + LPWSTR delim = delim_str;
103 + if (*offset == L'n' || *offset == 'N') {
104 + offset++;
105 + hp.type |= NO_CONTEXT;
106 + }
107 + // jichi 4/25/2015: Add support for fixing hook
108 + if (*offset == L'f' || *offset == 'F') {
109 + offset++;
110 + hp.type |= FIXING_SPLIT;
111 + }
112 + if (*offset == L'j' || *offset == 'J') { // 11/22/2015: J stands for Japanese only
113 + offset++;
114 + hp.type |= NO_ASCII;
115 + }
116 + while (!accept) {
117 + t = Convert(offset, data, delim);
118 + if (t < 0)
119 + return false; //ConsoleOutput(L"Syntax error.");
120 + offset = ::wcschr(offset , delim[t]);
121 + if (offset)
122 + offset++; // skip the current delim
123 + else //goto _error;
124 + return false; //ConsoleOutput(L"Syntax error.");
125 + switch (delim[t]) {
126 + case L':':
127 + data = &hp.split;
128 + delim = delim_str + 1;
129 + hp.type |= USING_SPLIT;
130 + break;
131 + case L'*':
132 + if (hp.split) {
133 + data = &hp.split_index;
134 + delim = delim_str + 2;
135 + hp.type |= SPLIT_INDIRECT;
136 + }
137 + else {
138 + hp.type |= DATA_INDIRECT;
139 + data = &hp.index;
140 + }
141 + break;
142 + case L'@':
143 + accept = true;
144 + break;
145 + }
146 + }
147 + t = Convert(offset, &hp.address, delim_str);
148 + if (t < 0)
149 + return false;
150 + if (hp.offset & 0x80000000)
151 + hp.offset -= 4;
152 + if (hp.split & 0x80000000)
153 + hp.split -= 4;
154 + LPWSTR temp = offset;
155 + offset = ::wcschr(offset, L':');
156 + if (offset) {
157 + hp.type |= MODULE_OFFSET;
158 + offset++;
159 + delim = ::wcschr(offset, L':');
160 +
161 + if (delim) {
162 + *delim = 0;
163 + delim++;
164 + _wcslwr(offset);
165 + hp.function = Hash(delim);
166 + hp.module = Hash(offset, delim - offset - 1);
167 + hp.type |= FUNCTION_OFFSET;
168 + }
169 + else
170 + hp.module = Hash(_wcslwr(offset));
171 +
172 + } else {
173 + offset = ::wcschr(temp, L'!');
174 + if (offset) {
175 + hp.type |= MODULE_OFFSET;
176 + swscanf(offset + 1, L"%x", &hp.module);
177 + offset = ::wcschr(offset + 1, L'!');
178 + if (offset) {
179 + hp.type |= FUNCTION_OFFSET;
180 + swscanf(offset + 1, L"%x", &hp.function);
181 + }
182 + }
183 + }
184 + switch (*cmd) {
185 + case L's':
186 + case L'S':
187 + hp.type |= USING_STRING;
188 + break;
189 + case L'e':
190 + case L'E':
191 + hp.type |= STRING_LAST_CHAR;
192 + case L'a':
193 + case L'A':
194 + hp.type |= BIG_ENDIAN;
195 + hp.length_offset = 1;
196 + break;
197 + case L'b':
198 + case L'B':
199 + hp.length_offset = 1;
200 + break;
201 + // jichi 12/7/2014: Disabled
202 + //case L'h':
203 + //case L'H':
204 + // hp.type |= PRINT_DWORD;
205 + case L'q':
206 + case L'Q':
207 + hp.type |= USING_STRING | USING_UNICODE;
208 + break;
209 + case L'l':
210 + case L'L':
211 + hp.type |= STRING_LAST_CHAR;
212 + case L'w':
213 + case L'W':
214 + hp.type |= USING_UNICODE;
215 + hp.length_offset = 1;
216 + break;
217 + default: ;
218 + }
219 + //ConsoleOutput(L"Try to insert additional hook.");
220 + return true;
221 +}
222 +
223 +// ITH ORIGINAL CODE END
224 +
225 +}} // unnamed detail
226 +
227 +// - ITH API -
228 +
229 +// Sample code: L"/HS-4:-14@4383C0" (WHITE ALBUM 2)
230 +bool Ith::parseHookCode(const QString &code, HookParam *hp, bool verbose)
231 +{
232 +#define HCODE_PREFIX "/H"
233 + enum { HCODE_PREFIX_LEN = sizeof(HCODE_PREFIX) -1 }; // 2
234 + if (!hp || !code.startsWith(HCODE_PREFIX))
235 + return false;
236 + if (verbose)
237 + DOUT("enter: code =" << code);
238 + else
239 + DOUT("enter");
240 +
241 + size_t bufsize = qMax(0xFF, code.size() + 1); // in case detail::Convert modify the buffer
242 + auto buf = new wchar_t[bufsize];
243 + code.toWCharArray(buf);
244 + buf[code.size()] = 0;
245 +
246 + bool ret = detail::Parse(buf + HCODE_PREFIX_LEN, *hp);
247 + delete[] buf;
248 +#ifdef DEBUG
249 + if (ret && verbose)
250 + qDebug()
251 + << "addr:" << hp->address
252 + << ", text_fun:" << hp->text_fun
253 + << ", function:"<< hp->function
254 + << ", hook_len:" << hp->hook_len
255 + << ", ind:" << hp->index
256 + << ", length_offset:" << hp->length_offset
257 + << ", module:" << hp->module
258 + << ", off:" <<hp->offset
259 + << ", recover_len:" << hp->recover_len
260 + << ", split:" << hp->split
261 + << ", split_ind:" << hp->split_index
262 + << ", type:" << hp->type;
263 +#endif // DEBUG
264 + DOUT("leave: ret =" << ret);
265 + return ret;
266 +#undef HOOK_CODE_PREFIX
267 +}
268 +
269 +bool Ith::verifyHookCode(const QString &code)
270 +{
271 + HookParam hp = {};
272 + return parseHookCode(code, &hp);
273 +}
274 +
275 +// EOF
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.