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 | ... | ... |
... | @@ -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 | ... | ... |
... | @@ -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.
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 | ... | ... |
vnr/hashutil/hashstr.h
0 → 100644
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 |
vnr/hashutil/hashutil.h
0 → 100644
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 |
vnr/hashutil/hashutil.pri
0 → 100644
vnr/ithsys/CMakeLists.txt
0 → 100644
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 | +) |
vnr/ithsys/ithsys.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/ithsys/ithsys.h
0 → 100644
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 |
vnr/ithsys/ithsys.pri
0 → 100644
vnr/ithsys/ithsys.pro
0 → 100644
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.
vnr/mono/mono.pri
0 → 100644
vnr/mono/monoobject.h
0 → 100644
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 |
vnr/mono/monotype.h
0 → 100644
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 | ... | ... |
vnr/profile/CMakeLists.txt
0 → 100644
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 | +#) |
vnr/profile/Profile.cpp
0 → 100644
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 | +} |
vnr/profile/Profile.h
0 → 100644
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 | +}; |
vnr/profile/misc.cpp
0 → 100644
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 | +} |
vnr/profile/misc.h
0 → 100644
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 | +} |
vnr/profile/pugiconfig.hpp
0 → 100644
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 | + */ |
vnr/profile/pugixml.cpp
0 → 100644
This diff could not be displayed because it is too large.
vnr/profile/pugixml.hpp
0 → 100644
This diff is collapsed. Click to expand it.
vnr/sakurakit/sakurakit.pri
0 → 100644
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 |
vnr/sakurakit/skautorun.h
0 → 100644
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 |
vnr/sakurakit/skdebug.h
0 → 100644
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 |
vnr/sakurakit/skglobal.h
0 → 100644
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 |
vnr/sakurakit/skhash.h
0 → 100644
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 |
vnr/texthook/growl.h
0 → 100644
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 |
vnr/texthook/host/CMakeLists.txt
0 → 100644
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 | +) |
vnr/texthook/host/avl_p.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/host/config.h
0 → 100644
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 |
vnr/texthook/host/hookman.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/host/hookman.h
0 → 100644
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 |
vnr/texthook/host/host.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/host/host.h
0 → 100644
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 |
vnr/texthook/host/host.pri
0 → 100644
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 |
vnr/texthook/host/host_p.h
0 → 100644
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 |
vnr/texthook/host/pipe.cc
0 → 100644
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 |
vnr/texthook/host/settings.h
0 → 100644
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 |
vnr/texthook/host/textthread.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/host/textthread.h
0 → 100644
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 |
vnr/texthook/host/textthread_p.h
0 → 100644
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 | +*/ |
vnr/texthook/ihf.txt
0 → 100644
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 |
vnr/texthook/ihf_p.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/ihf_p.h
0 → 100644
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 |
vnr/texthook/ith_p.cc
0 → 100644
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 |
vnr/texthook/ith_p.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/texthook.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/texthook.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/texthook.pri
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/texthook.pro
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/texthook.rc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/texthook_config.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/texthook_p.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/texthook_static.pri
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/textthread_p.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/textthread_p.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/winapi_p.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/texthook/winapi_p.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/CMakeLists.txt
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/TRASH/dllconfig.pri
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/TRASH/hookxp.pro
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/TRASH/memory.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/TRASH/string.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/TRASH/xp.txt
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/include/const.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/include/defs.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/include/types.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/engine/engine.cc
0 → 100644
This diff could not be displayed because it is too large.
vnr/vnrhook/src/engine/engine.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/engine/hookdefs.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/engine/match.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/engine/match.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/engine/mono/funcinfo.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/engine/mono/types.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/engine/pchooks.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/engine/pchooks.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/engine/ppsspp/funcinfo.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/except.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/hijack/texthook.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/hijack/texthook.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/main.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/main.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/pipe.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/tree/avl.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/util/growl.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/util/util.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/src/util/util.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/vnrhook.pri
0 → 100644
This diff is collapsed. Click to expand it.
vnr/vnrhook/vnrhook.pro
0 → 100644
This diff is collapsed. Click to expand it.
vnr/windbg/hijack.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/windbg/hijack.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/windbg/inject.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/windbg/inject.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/windbg/unload.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/windbg/unload.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/windbg/util.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/windbg/util.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/windbg/windbg.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/windbg/windbg.pri
0 → 100644
This diff is collapsed. Click to expand it.
vnr/windbg/windbg_p.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/winkey/winkey.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/winkey/winkey.pri
0 → 100644
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.
vnr/wintimer/wintimer.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/wintimer/wintimer.h
0 → 100644
This diff is collapsed. Click to expand it.
vnr/wintimer/wintimer.pri
0 → 100644
This diff is collapsed. Click to expand it.
vnr/wintimer/wintimer.pro
0 → 100644
This diff is collapsed. Click to expand it.
vnr/wintimer/wintimerbase.cc
0 → 100644
This diff is collapsed. Click to expand it.
vnr/wintimer/wintimerbase.h
0 → 100644
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment