mireado

starting commit

1 +#pragma once
2 +
3 +// ith/common/defs.h
4 +// 8/23/2013 jichi
5 +
6 +// DLL files
7 +
8 +//#define ITH_SERVER_DLL L"vnrsrv.dll"
9 +//#define ITH_CLIENT_DLL L"vnrcli.dll"
10 +//#define ITH_CLIENT_XP_DLL L"vnrclixp.dll"
11 +////#define ITH_CLIENT_UX_DLL L"vnrcliux.dll"
12 +//#define ITH_ENGINE_DLL L"vnreng.dll"
13 +//#define ITH_ENGINE_XP_DLL L"vnrengxp.dll"
14 +//#define ITH_ENGINE_UX_DLL L"vnrengux.dll"
15 +
16 +#define ITH_DLL L"vnrhook.dll"
17 +#define ITH_DLL_XP L"vnrhookxp.dll"
18 +
19 +// Pipes
20 +
21 +#define ITH_TEXT_PIPE L"\\??\\pipe\\VNR_TEXT"
22 +#define ITH_COMMAND_PIPE L"\\??\\pipe\\VNR_COMMAND"
23 +
24 +// Sections
25 +
26 +#define ITH_SECTION_ L"VNR_SECTION_" // _%d
27 +
28 +// Mutex
29 +
30 +#define ITH_PROCESS_MUTEX_ L"VNR_PROCESS_" // ITH_%d
31 +#define ITH_HOOKMAN_MUTEX_ L"VNR_HOOKMAN_" // ITH_HOOKMAN_%d
32 +#define ITH_DETACH_MUTEX_ L"VNR_DETACH_" // ITH_DETACH_%d
33 +
34 +#define ITH_GRANTPIPE_MUTEX L"VNR_GRANT_PIPE" // ITH_GRANT_PIPE
35 +
36 +//#define ITH_ENGINE_MUTEX L"VNR_ENGINE" // ITH_ENGINE
37 +#define ITH_CLIENT_MUTEX L"VNR_CLIENT" // ITH_DLL_RUNNING
38 +#define ITH_SERVER_MUTEX L"VNR_SERVER" // ITH_RUNNING
39 +#define ITH_SERVER_HOOK_MUTEX L"VNR_SERVER_HOOK" // original
40 +
41 +// Events
42 +
43 +#define ITH_REMOVEHOOK_EVENT L"VNR_REMOVE_HOOK" // ITH_REMOVE_HOOK
44 +#define ITH_MODIFYHOOK_EVENT L"VNR_MODIFY_HOOK" // ITH_MODIFY_HOOK
45 +#define ITH_PIPEEXISTS_EVENT L"VNR_PIPE_EXISTS" // ITH_PIPE_EXIST
46 +
47 +// EOF
1 +#pragma once
2 +
3 +// ith/common/except.h
4 +// 9/17/2013 jichi
5 +
6 +#define ITH_RAISE (*(int*)0 = 0) // raise C000005, for debugging only
7 +
8 +#ifdef ITH_HAS_SEH
9 +
10 +# define ITH_TRY __try
11 +# define ITH_EXCEPT __except(EXCEPTION_EXECUTE_HANDLER)
12 +# define ITH_WITH_SEH(...) \
13 + ITH_TRY { __VA_ARGS__; } ITH_EXCEPT {}
14 +
15 +#else // for old msvcrt.dll on Windows XP that does not have exception handler
16 +
17 +// Currently, only with_seh is implemented. Try and catch are not.
18 +# define ITH_TRY if (true)
19 +# define ITH_EXCEPT else
20 +# include "winseh/winseh.h"
21 +# define ITH_WITH_SEH(...) seh_with(__VA_ARGS__)
22 +
23 +#endif // ITH_HAS_SEH
24 +
25 +// EOF
1 +#pragma once
2 +
3 +// ith/common/growl.h
4 +// 9/17/2013 jichi
5 +
6 +//#ifdef ITH_HAS_GROWL
7 +
8 +#include <windows.h>
9 +#include "ith/common/string.h"
10 +
11 +#define ITH_MSG_A(_msg) MessageBoxA(nullptr, _msg, "VNR Message", MB_OK)
12 +#define ITH_MSG(_msg) MessageBoxW(nullptr, _msg, L"VNR Message", MB_OK)
13 +#define ITH_WARN(_msg) MessageBoxW(nullptr, _msg, L"VNR Warning", MB_OK)
14 +#define ITH_ERROR(_msg) MessageBoxW(nullptr, _msg, L"VNR Error", MB_OK)
15 +
16 +inline void ITH_GROWL_DWORD(DWORD value)
17 +{
18 + WCHAR buf[100];
19 + swprintf(buf, L"DWORD: %x", value);
20 + ITH_MSG(buf);
21 +}
22 +
23 +inline void ITH_GROWL_DWORD2(DWORD v, DWORD v2)
24 +{
25 + WCHAR buf[100];
26 + swprintf(buf, L"DWORD2: %x,%x", v, v2);
27 + ITH_MSG(buf);
28 +}
29 +
30 +inline void ITH_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 + ITH_MSG(buf);
35 +}
36 +
37 +inline void ITH_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 + ITH_MSG(buf);
42 +}
43 +
44 +inline void ITH_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 + ITH_MSG(buf);
49 +}
50 +
51 +inline void ITH_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 + ITH_MSG(buf);
56 +}
57 +
58 +inline void ITH_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 + ITH_MSG(buf);
63 +}
64 +
65 +inline void ITH_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 + ITH_MSG(buf);
70 +}
71 +
72 +inline void ITH_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 + ITH_MSG(buf);
77 +}
78 +
79 +inline void ITH_GROWL(DWORD v) { ITH_GROWL_DWORD(v); }
80 +inline void ITH_GROWL(LPCWSTR v) { ITH_MSG(v); }
81 +inline void ITH_GROWL(LPCSTR v) { ITH_MSG_A(v); }
82 +
83 +//#endif // ITH_HAS_GROWL
84 +
85 +// EOF
1 +#pragma once
2 +
3 +// ith/common/memory.h
4 +// 8/23/2013 jichi
5 +// Branch: ITH/mem.h, revision 66
6 +
7 +#ifndef ITH_HAS_HEAP
8 +# define ITH_MEMSET_HEAP(...) ::memset(__VA_ARGS__)
9 +#else
10 +# define ITH_MEMSET_HEAP(...) (void)0
11 +
12 +// Defined in kernel32.lilb
13 +extern "C" {
14 +// PVOID RtlAllocateHeap( _In_ PVOID HeapHandle, _In_opt_ ULONG Flags, _In_ SIZE_T Size);
15 +__declspec(dllimport) void * __stdcall RtlAllocateHeap(void *HeapHandle, unsigned long Flags, unsigned long Size);
16 +
17 +// BOOLEAN RtlFreeHeap( _In_ PVOID HeapHandle, _In_opt_ ULONG Flags, _In_ PVOID HeapBase);
18 +__declspec(dllimport) int __stdcall RtlFreeHeap(void *HeapHandle, unsigned long Flags, void *HeapBase);
19 +} // extern "C"
20 +
21 +//NTSYSAPI
22 +//BOOL
23 +//NTAPI
24 +//RtlFreeHeap(
25 +// _In_ HANDLE hHeap,
26 +// _In_ DWORD dwFlags,
27 +// _In_ LPVOID lpMem
28 +//);
29 +
30 +extern void *hHeap; // defined in ith/sys.cc
31 +
32 +inline void * __cdecl operator new(size_t lSize)
33 +{
34 + // http://msdn.microsoft.com/en-us/library/windows/desktop/aa366597%28v=vs.85%29.aspx
35 + // HEAP_ZERO_MEMORY flag is critical. All new objects are assumed with zero initialized.
36 + enum { HEAP_ZERO_MEMORY = 0x00000008 };
37 + return RtlAllocateHeap(::hHeap, HEAP_ZERO_MEMORY, lSize);
38 +}
39 +
40 +inline void __cdecl operator delete(void *pBlock)
41 +{ RtlFreeHeap(::hHeap, 0, pBlock); }
42 +
43 +inline void __cdecl operator delete[](void *pBlock)
44 +{ RtlFreeHeap(::hHeap, 0, pBlock); }
45 +
46 +#endif // ITH_HAS_HEAP
1 +#pragma once
2 +
3 +// ith/common/string.h
4 +// 8/9/2013 jichi
5 +// Branch: ITH/string.h, rev 66
6 +
7 +#ifdef ITH_HAS_CRT // ITH is linked with msvcrt dlls
8 +# include <cstdio>
9 +# include <cstring>
10 +
11 +#else
12 +# define _INC_SWPRINTF_INL_
13 +# define CRT_IMPORT __declspec(dllimport)
14 +
15 +#include <windows.h> // for wchar_t
16 +extern "C" {
17 +CRT_IMPORT int swprintf(wchar_t *src, const wchar_t *fmt, ...);
18 +CRT_IMPORT int sprintf(char *src, const char *fmt, ...);
19 +CRT_IMPORT int swscanf(const wchar_t *src, const wchar_t *fmt, ...);
20 +CRT_IMPORT int sscanf(const char *src, const char *fmt, ...);
21 +CRT_IMPORT int wprintf(const wchar_t *fmt, ...);
22 +CRT_IMPORT int printf(const char *fmt, ...);
23 +CRT_IMPORT int _wputs(const wchar_t *src);
24 +CRT_IMPORT int puts(const char *src);
25 +CRT_IMPORT int _stricmp(const char *x, const char *y);
26 +CRT_IMPORT int _wcsicmp(const wchar_t *x, const wchar_t *y);
27 +//CRT_IMPORT size_t strlen(const char *);
28 +//CRT_IMPORT size_t wcslen(const wchar_t *);
29 +//CRT_IMPORT char *strcpy(char *,const char *);
30 +//CRT_IMPORT wchar_t *wcscpy(wchar_t *,const wchar_t *);
31 +CRT_IMPORT void *memmove(void *dst, const void *src, size_t sz);
32 +CRT_IMPORT const char *strchr(const char *src, int val);
33 +CRT_IMPORT int strncmp(const char *x, const char *y, size_t sz);
34 +} // extern "C"
35 +
36 +#endif // ITH_HAS_CRT
1 +#pragma once
2 +
3 +// ith/common/types.h
4 +// 8/23/2013 jichi
5 +// Branch: ITH/common.h, rev 128
6 +
7 +#include <windows.h> // needed for windef types
8 +
9 + /** jichi 3/7/2014: Add guessed comment
10 + *
11 + * DWORD addr absolute or relative address
12 + * DWORD split esp offset of the split character
13 + *
14 + * http://faydoc.tripod.com/cpu/pushad.htm
15 + * http://agth.wikia.com/wiki/Cheat_Engine_AGTH_Tutorial
16 + * The order is the same as pushd
17 + * EAX, ECX, EDX, EBX, ESP (original value), EBP, ESI, and EDI (if the current operand-size attribute is 32) and AX, CX, DX, BX, SP
18 + * Negative values of 'data_offset' and 'sub_offset' refer to registers:-4 for EAX, -8 for ECX, -C for EDX, -10 for EBX, -14 for ESP, -18 for EBP, -1C for ESI, -20 for EDI
19 + */
20 +struct HookParam {
21 + // jichi 8/24/2013: For special hooks. Original name: DataFun
22 + typedef void (*text_fun_t)(DWORD esp, HookParam *hp, BYTE index, DWORD *data, DWORD *split, DWORD *len);
23 +
24 + // jichi 10/24/2014: Add filter function. Return the if skip the text
25 + typedef bool (*filter_fun_t)(LPVOID str, DWORD *len, HookParam *hp, BYTE index);
26 +
27 + // jichi 10/24/2014: Add generic hook function, return false if stop execution.
28 + typedef bool (*hook_fun_t)(DWORD esp, HookParam *hp);
29 +
30 + DWORD addr; // absolute or relative address
31 + DWORD off, // offset of the data in the memory
32 + ind, // ?
33 + split, // esp offset of the split character = pusha offset - 4
34 + split_ind; // ?
35 + DWORD module, // hash of the module
36 + function;
37 + text_fun_t text_fun;
38 + filter_fun_t filter_fun;
39 + hook_fun_t hook_fun;
40 + DWORD type; // flags
41 + WORD length_offset; // index of the string length
42 + BYTE hook_len, // ?
43 + recover_len; // ?
44 +
45 + // 2/2/2015: jichi number of times - 1 to run the hook
46 + BYTE extra_text_count;
47 + BYTE _unused; // jichi 2/2/2015: add a BYTE type to make to total sizeof(HookParam) even.
48 +
49 + // 7/20/2014: jichi additional parameters for PSP games
50 + DWORD user_flags,
51 + user_value;
52 +};
53 +
54 +// jichi 6/1/2014: Structure of the esp for extern functions
55 +struct HookStack
56 +{
57 + // pushad
58 + DWORD edi, // -0x24
59 + esi, // -0x20
60 + ebp, // -0x1c
61 + esp, // -0x18
62 + ebx, // -0x14
63 + edx, // -0x10
64 + ecx, // -0xc
65 + eax; // -0x8
66 + // pushfd
67 + DWORD eflags; // -0x4
68 + DWORD retaddr; // 0
69 + DWORD args[1]; // 0x4
70 +};
71 +
72 +struct SendParam {
73 + DWORD type;
74 + HookParam hp;
75 +};
76 +
77 +struct Hook { // size: 0x80
78 + HookParam hp;
79 + LPWSTR hook_name;
80 + int name_length;
81 + BYTE recover[0x68 - sizeof(HookParam)];
82 + BYTE original[0x10];
83 +
84 + DWORD Address() const { return hp.addr; }
85 + DWORD Type() const { return hp.type; }
86 + WORD Length() const { return hp.hook_len; }
87 + LPWSTR Name() const { return hook_name; }
88 + int NameLength() const { return name_length; }
89 +};
90 +
91 +// EOF
1 +#pragma once
2 +
3 +// dllconfig.h
4 +// 8/23/2013 jichi
5 +
6 +#include "ith/common/memory.h"
7 +#include "ith/common/string.h"
8 +#include "ntdll/ntdll.h"
9 +
10 +// EOF
1 +# dllconfig.pri
2 +# 8/9/2013 jichi
3 +# For linking ITH injectable dlls.
4 +# The dll is self-containd and Windows-independent.
5 +
6 +CONFIG += dll noqt #noeh nosafeseh
7 +CONFIG -= embed_manifest_dll # dynamically load dlls
8 +win32 {
9 + CONFIG(eh): DEFINES += ITH_HAS_SEH # Do have exception handler in msvcrt.dll on Windows Vista and later
10 + CONFIG(noeh): DEFINES -= ITH_HAS_SEH # Do not have exception handler in msvcrt.dll on Windows XP and before
11 +}
12 +include(../../../config.pri)
13 +#win32 {
14 +# CONFIG(noeh): include($$LIBDIR/winseh/winseh_safe.pri)
15 +#}
16 +
17 +# jichi 11/24/2013: Disable manual heap
18 +DEFINES -= ITH_HAS_HEAP
19 +
20 +# jichi 11/13/2011: disable swprinf warning
21 +DEFINES += _CRT_NON_CONFORMING_SWPRINTFS
22 +
23 +## Libraries
24 +
25 +#LIBS += -lkernel32 -luser32 -lgdi32
26 +LIBS += -L$$WDK7_HOME/lib/wxp/i386 -lntdll
27 +LIBS += $$WDK7_HOME/lib/crt/i386/msvcrt.lib # Override msvcrt10
28 +#LIBS += -L$$WDK7_HOME/lib/crt/i386 -lmsvcrt
29 +#QMAKE_LFLAGS += $$WDK7_HOME/lib/crt/i386/msvcrt.lib # This will leave runtime flags in the dll
30 +
31 +#LIBS += -L$$WDK8_HOME/lib/winv6.3/um/x86 -lntdll
32 +
33 +HEADERS += $$PWD/dllconfig.h
34 +
35 +# EOF
1 +# hook.pro
2 +# CONFIG += eh eha
3 +# include(../dllconfig.pri)
4 +
5 +# hookxp.pro
6 +# CONFIG += noeh
7 +# include(../dllconfig.pri)
8 +
9 +# dllconfig.pri
10 +# include(../../../config.pri)
11 +# win32 {
12 +# CONFIG(eh): DEFINES += ITH_HAS_SEH
13 +# CONFIG(noeh): DEFINES -= ITH_HAS_SEH
14 +# }
15 +
16 +# config.pri
17 +# CONFIG(eha) {
18 +# message(CONFIG eha)
19 +# QMAKE_CXXFLAGS_STL_ON -= /EHsc
20 +# QMAKE_CXXFLAGS_EXCEPTIONS_ON -= /EHsc
21 +# QMAKE_CXXFLAGS_STL_ON += /EHa
22 +# QMAKE_CXXFLAGS_EXCEPTIONS_ON += /EHa
23 +# }
24 +#
25 +# CONFIG(noeh) { # No Exception handler
26 +# QMAKE_CXXFLAGS += /GR-
27 +# QMAKE_CXXFLAGS_RTTI_ON -= /GR
28 +# QMAKE_CXXFLAGS_STL_ON -= /EHsc
29 +# QMAKE_CXXFLAGS_EXCEPTIONS_ON -= /EHsc
30 +# }
31 +
32 +include_directories(${CMAKE_CURRENT_SOURCE_DIR})
33 +
34 +set(vnrhook_src
35 + cli.h
36 + config.h
37 + hook.h
38 + main.cc
39 + engine/engine.cc
40 + engine/engine.h
41 + engine/hookdefs.h
42 + engine/match.cc
43 + engine/match.h
44 + engine/pchooks.cc
45 + engine/pchooks.h
46 + engine/util.cc
47 + engine/util.h
48 + hijack/texthook.cc
49 + rpc/pipe.cc
50 + tree/avl.h
51 + ${PROJECT_SOURCE_DIR}/ccutil/ccmacro.h
52 + ${PROJECT_SOURCE_DIR}/cpputil/cpplocale.h
53 + ${PROJECT_SOURCE_DIR}/cpputil/cppmarshal.h
54 + ${PROJECT_SOURCE_DIR}/cpputil/cppmath.h
55 + ${PROJECT_SOURCE_DIR}/cpputil/cpppath.h
56 + ${PROJECT_SOURCE_DIR}/cpputil/cppstring.h
57 + ${PROJECT_SOURCE_DIR}/cpputil/cpptype.h
58 + ${PROJECT_SOURCE_DIR}/cpputil/cppunicode.h
59 + ${PROJECT_SOURCE_DIR}/disasm/disasm.cc
60 + ${PROJECT_SOURCE_DIR}/memdbg/memdbg.h
61 + ${PROJECT_SOURCE_DIR}/memdbg/memsearch.cc
62 + ${PROJECT_SOURCE_DIR}/memdbg/memsearch.h
63 + ${PROJECT_SOURCE_DIR}/ntinspect/ntinspect.cc
64 + ${PROJECT_SOURCE_DIR}/ntinspect/ntinspect.h
65 + ${PROJECT_SOURCE_DIR}/winversion/winversion.cc
66 + ${PROJECT_SOURCE_DIR}/winversion/winversion.h
67 + ${common_src}
68 + ${import_src}
69 +)
70 +
71 +source_group("common" FILES ${common_src})
72 +source_group("import" FILES ${import_src})
73 +
74 +add_library(vnrhook SHARED ${vnrhook_src})
75 +
76 +set(vnrhookxp_src ${vnrhook_src}
77 + ${PROJECT_SOURCE_DIR}/winseh/winseh.cc
78 + ${PROJECT_SOURCE_DIR}/winseh/winseh_safe.cc
79 + ${PROJECT_SOURCE_DIR}/winseh/winseh.h
80 + ${PROJECT_SOURCE_DIR}/winseh/safeseh.asm
81 +)
82 +
83 +enable_language(ASM_MASM)
84 +
85 +set_source_files_properties(
86 + ${PROJECT_SOURCE_DIR}/winseh/safeseh.asm
87 + PROPERTIES
88 + # CMAKE_ASM_MASM_FLAGS /safeseh # CMake bug 14711: http://www.cmake.org/Bug/view.php?id=14711
89 + COMPILE_FLAGS /safeseh
90 +)
91 +
92 +add_library(vnrhookxp SHARED ${vnrhookxp_src})
93 +
94 +set_target_properties(vnrhook vnrhookxp PROPERTIES
95 + LINK_FLAGS "/SUBSYSTEM:WINDOWS /MANIFEST:NO"
96 +)
97 +
98 +target_compile_options(vnrhook PRIVATE
99 + /EHa
100 + $<$<CONFIG:Release>:>
101 + $<$<CONFIG:Debug>:>
102 +)
103 +
104 +target_compile_options(vnrhookxp PRIVATE
105 + /GR-
106 +# /EHs-c- # disable exception handling # CMake bug 15243: http://www.cmake.org/Bug/view.php?id=15243
107 + $<$<CONFIG:Release>:>
108 + $<$<CONFIG:Debug>:>
109 +)
110 +
111 +if(TARGET vnrhookxp)
112 + STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
113 +endif(TARGET vnrhookxp)
114 +
115 +set(vnrhook_libs
116 + vnrsys
117 + ${WDK_HOME}/lib/wxp/i386/ntdll.lib
118 + Version.lib
119 +)
120 +
121 +target_link_libraries(vnrhook ${vnrhook_libs})
122 +target_link_libraries(vnrhookxp ${vnrhook_libs})
123 +
124 +target_compile_definitions(vnrhook
125 + PRIVATE
126 + -DITH_HAS_SEH
127 +)
128 +target_compile_definitions(vnrhookxp
129 + PRIVATE
130 +)
131 +
132 +install(TARGETS vnrhook vnrhookxp RUNTIME
133 + DESTINATION .
134 + CONFIGURATIONS Release
135 +)
1 +#pragma once
2 +
3 +// cli.h
4 +// 8/24/2013 jichi
5 +// Branch: IHF_DLL/IHF_CLIENT.h, rev 133
6 +//
7 +// 8/24/2013 TODO:
8 +// - Clean up this file
9 +// - Reduce global variables. Use namespaces or singleton classes instead.
10 +
11 +//#include <windows.h>
12 +//#define IHF
13 +#include "config.h"
14 +#include "hook.h"
15 +
16 +// jichi 12/25/2013: Header in each message sent to vnrsrv
17 +// There are totally three elements
18 +// - 0x0 dwAddr hook address
19 +// - 0x4 dwRetn return address
20 +// - 0x8 dwSplit split value
21 +#define HEADER_SIZE 0xc
22 +
23 +extern int current_hook;
24 +extern WCHAR dll_mutex[];
25 +//extern WCHAR dll_name[];
26 +extern DWORD trigger;
27 +//extern DWORD current_process_id;
28 +
29 +// jichi 6/3/2014: Get memory range of the current module
30 +extern DWORD processStartAddress,
31 + processStopAddress;
32 +
33 +template <class T, class D, class fComp, class fCopy, class fLength>
34 +class AVLTree;
35 +struct FunctionInfo {
36 + DWORD addr;
37 + DWORD module;
38 + DWORD size;
39 + LPWSTR name;
40 +};
41 +struct SCMP;
42 +struct SCPY;
43 +struct SLEN;
44 +extern AVLTree<char, FunctionInfo, SCMP, SCPY, SLEN> *tree;
45 +
46 +void InitFilterTable();
47 +
48 +// jichi 9/25/2013: This class will be used by NtMapViewOfSectionfor
49 +// interprocedure communication, where constructor/destructor will NOT work.
50 +class TextHook : public Hook
51 +{
52 + int UnsafeInsertHookCode();
53 + DWORD UnsafeSend(DWORD dwDataBase, DWORD dwRetn);
54 +public:
55 + int InsertHook();
56 + int InsertHookCode();
57 + int InitHook(const HookParam &hp, LPCWSTR name = 0, WORD set_flag = 0);
58 + int InitHook(LPVOID addr, DWORD data, DWORD data_ind,
59 + DWORD split_off, DWORD split_ind, WORD type, DWORD len_off = 0);
60 + DWORD Send(DWORD dwDataBase, DWORD dwRetn);
61 + int RecoverHook();
62 + int RemoveHook();
63 + int ClearHook();
64 + int ModifyHook(const HookParam&);
65 + int SetHookName(LPCWSTR name);
66 + int GetLength(DWORD base, DWORD in); // jichi 12/25/2013: Return 0 if failed
67 + void CoolDown(); // jichi 9/28/2013: flush instruction cache on wine
68 +};
69 +
70 +extern TextHook *hookman,
71 + *current_available;
72 +
73 +//void InitDefaultHook();
74 +
75 +struct FilterRange { DWORD lower, upper; };
76 +extern FilterRange *filter;
77 +
78 +extern bool running,
79 + live;
80 +
81 +extern HANDLE hPipe,
82 + hmMutex;
83 +
84 +DWORD WINAPI WaitForPipe(LPVOID lpThreadParameter);
85 +DWORD WINAPI CommandPipe(LPVOID lpThreadParameter);
86 +
87 +//void RequestRefreshProfile();
88 +
89 +//typedef DWORD (*InsertHookFun)(DWORD);
90 +//typedef DWORD (*IdentifyEngineFun)();
91 +//typedef DWORD (*InsertDynamicHookFun)(LPVOID addr, DWORD frame, DWORD stack);
92 +//extern IdentifyEngineFun IdentifyEngine;
93 +//extern InsertDynamicHookFun InsertDynamicHook;
94 +
95 +// jichi 9/28/2013: Protect pipeline in wine
96 +void CliLockPipe();
97 +void CliUnlockPipe();
98 +
99 +// EOF
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 +
10 +// EOF
This diff could not be displayed because it is too large.
1 +#pragma once
2 +
3 +// engine/engine.h
4 +// 8/23/2013 jichi
5 +// See: http://ja.wikipedia.org/wiki/プロジェクト:美少女ゲーム系/ゲームエンジン
6 +
7 +#include "config.h"
8 +
9 +struct HookParam; // defined in ith types.h
10 +
11 +namespace Engine {
12 +
13 +// Global variables
14 +extern wchar_t process_name_[MAX_PATH], // cached
15 + process_path_[MAX_PATH]; // cached
16 +extern DWORD module_base_,
17 + module_limit_;
18 +
19 +//extern LPVOID trigger_addr;
20 +typedef bool (* trigger_fun_t)(LPVOID addr, DWORD frame, DWORD stack);
21 +extern trigger_fun_t trigger_fun_;
22 +
23 +bool InsertMonoHooks(); // Mono
24 +
25 +// Wii engines
26 +
27 +bool InsertGCHooks(); // Dolphin
28 +bool InsertVanillawareGCHook();
29 +
30 +// PS2 engines
31 +
32 +bool InsertPCSX2Hooks(); // PCSX2
33 +bool InsertMarvelousPS2Hook(); // http://marvelous.jp
34 +bool InsertMarvelous2PS2Hook(); // http://marvelous.jp
35 +bool InsertTypeMoonPS2Hook(); // http://typemoon.com
36 +//bool InsertNamcoPS2Hook();
37 +
38 +// PSP engines
39 +
40 +void SpecialPSPHook(DWORD esp_base, HookParam *hp, DWORD *data, DWORD *split, DWORD *len); // General PSP extern hook
41 +
42 +bool InsertPPSSPPHooks(); // PPSSPPWindows
43 +
44 +bool InsertPPSSPPHLEHooks();
45 +bool InsertOtomatePPSSPPHook(); // PSP otomate.jp, 0.9.9.0 only
46 +
47 +bool Insert5pbPSPHook(); // PSP 5pb.jp
48 +bool InsertAlchemistPSPHook(); // PSP Alchemist-net.co.jp, 0.9.8 only
49 +bool InsertAlchemist2PSPHook(); // PSP Alchemist-net.co.jp
50 +bool InsertBandaiNamePSPHook(); // PSP Bandai.co.jp
51 +bool InsertBandaiPSPHook(); // PSP Bandai.co.jp
52 +bool InsertBroccoliPSPHook(); // PSP Broccoli.co.jp
53 +bool InsertFelistellaPSPHook(); // PSP felistella.co.jp
54 +
55 +bool InsertCyberfrontPSPHook(); // PSP CYBERFRONT (closed)
56 +bool InsertImageepochPSPHook(); // PSP Imageepoch.co.jp
57 +bool InsertImageepoch2PSPHook();// PSP Imageepoch.co.jp
58 +bool InsertKadokawaNamePSPHook(); // PSP Kadokawa.co.jp
59 +bool InsertKonamiPSPHook(); // PSP Konami.jp
60 +bool InsertTecmoPSPHook(); // PSP Koeitecmo.co.jp
61 +//bool InsertTypeMoonPSPHook(); // PSP Typemoon.com
62 +
63 +bool InsertOtomatePSPHook(); // PSP Otomate.jp, 0.9.8 only
64 +//bool InsertOtomate2PSPHook(); // PSP otomate.jp >= 0.9.9.1
65 +
66 +bool InsertIntensePSPHook(); // PSP Intense.jp
67 +bool InsertKidPSPHook(); // PSP Kid-game.co.jp
68 +bool InsertNippon1PSPHook(); // PSP Nippon1.jp
69 +bool InsertNippon2PSPHook(); // PSP Nippon1.jp
70 +bool InsertYetiPSPHook(); // PSP Yetigame.jp
71 +bool InsertYeti2PSPHook(); // PSP Yetigame.jp
72 +
73 +// PC engines
74 +
75 +bool Insert2RMHook(); // 2RM - Adventure Engine
76 +bool Insert5pbHook(); // 5pb.jp, PSP/PS3 games ported to PC
77 +bool InsertAB2TryHook(); // Yane@AkabeiSoft2Try: YaneSDK.dll.
78 +bool InsertAbelHook(); // Abel
79 +bool InsertAdobeAirHook(); // Adobe AIR
80 +bool InsertAdobeFlash10Hook(); // Adobe Flash Player 10
81 +bool InsertAliceHook(); // System40@AliceSoft; do not work for latest alice games
82 +bool InsertAmuseCraftHook(); // AMUSE CRAFT: *.pac
83 +bool InsertAnex86Hook(); // Anex86: anex86.exe
84 +bool InsertAOSHook(); // AOS: *.aos
85 +bool InsertApricoTHook(); // Apricot: arc.a*
86 +bool InsertArtemisHook(); // Artemis Engine: *.pfs
87 +bool InsertAtelierHook(); // Atelier Kaguya: message.dat
88 +bool InsertBGIHook(); // BGI: BGI.*
89 +bool InsertC4Hook(); // C4: C4.EXE or XEX.EXE
90 +bool InsertCaramelBoxHook(); // Caramel: *.bin
91 +bool InsertCandyHook(); // SystemC@CandySoft: *.fpk
92 +bool InsertCatSystemHook(); // CatSystem2: *.int
93 +bool InsertCMVSHook(); // CMVS: data/pack/*.cpz; do not support the latest cmvs32.exe and cmvs64.exe
94 +bool InsertCotophaHook(); // Cotopha: *.noa
95 +bool InsertDebonosuHook(); // Debonosu: bmp.bak and dsetup.dll
96 +bool InsertEaglsHook(); // E.A.G.L.S: EAGLES.dll
97 +bool InsertEMEHook(); // EmonEngine: emecfg.ecf
98 +bool InsertEushullyHook(); // Eushully: AGERC.DLL
99 +bool InsertExpHook(); // EXP: http://www.exp-inc.jp
100 +bool InsertFocasLensHook(); // FocasLens: Dat/*.arc, http://www.fo-lens.net
101 +bool InsertGesen18Hook(); // Gsen18: *.szs
102 +bool InsertGXPHook(); // GXP: *.gxp
103 +bool InsertHorkEyeHook(); // HorkEye: resource string
104 +bool InsertKAGParserHook(); // plugin/KAGParser.dll
105 +bool InsertKAGParserExHook(); // plugin/KAGParserEx.dll
106 +bool InsertKiriKiriHook(); // KiriKiri: *.xp3, resource string
107 +bool InsertKiriKiriZHook(); // KiriKiri: *.xp3, resource string
108 +bool InsertLeafHook(); // Leaf: *.pak
109 +bool InsertLiveHook(); // Live: live.dll
110 +bool InsertLunaSoftHook(); // LunaSoft: Pac/*.pac
111 +bool InsertMalieHook(); // Malie@light: malie.ini
112 +bool InsertMajiroHook(); // Majiro: *.arc
113 +bool InsertMarineHeartHook(); // Marine Heart: SAISYS.exe
114 +bool InsertMBLHook(); // MBL: *.mbl
115 +bool InsertMEDHook(); // MED: *.med
116 +bool InsertMinkHook(); // Mink: *.at2
117 +//bool InsertMonoHook(); // Mono (Unity3D): */Mono/mono.dll
118 +bool InsertNeXASHook(); // NeXAS: Thumbnail.pac
119 +bool InsertNextonHook(); // NEXTON: aInfo.db
120 +bool InsertNexton1Hook();
121 +bool InsertNitroPlusHook(); // NitroPlus: *.npa
122 +bool InsertPensilHook(); // Pensil: PSetup.exe
123 +bool InsertQLIEHook(); // QLiE: GameData/*.pack
124 +//bool InsertRai7Hook(); // Rai7puk: rai7.exe
125 +bool InsertRejetHook(); // Rejet: Module/{gd.dat,pf.dat,sd.dat}
126 +bool InsertRUGPHook(); // rUGP: rUGP.exe
127 +bool InsertRetouchHook(); // Retouch: resident.dll
128 +bool InsertRREHook(); // RunrunEngine: rrecfg.rcf
129 +bool InsertShinaHook(); // ShinaRio: Rio.ini
130 +bool InsertShinyDaysHook(); // ShinyDays
131 +bool InsertElfHook(); // elf: Silky.exe
132 +bool InsertScenarioPlayerHook();// sol-fa-soft: *.iar && *.sec5
133 +bool InsertSiglusHook(); // SiglusEngine: SiglusEngine.exe
134 +bool InsertSideBHook(); // SideB: Copyright side-B
135 +bool InsertSyuntadaHook(); // Syuntada: dSoh.dat
136 +bool InsertSystem43Hook(); // System43@AliceSoft: AliceStart.ini
137 +bool InsertSystemAoiHook(); // SystemAoi: *.vfs
138 +bool InsertTanukiHook(); // Tanuki: *.tak
139 +bool InsertTaskforce2Hook(); // Taskforce2.exe
140 +bool InsertTencoHook(); // Tenco: Check.mdx
141 +bool InsertTriangleHook(); // Triangle: Execle.exe
142 +bool InsertYukaSystem2Hook(); // YukaSystem2: *.ykc
143 +bool InsertYurisHook(); // YU-RIS: *.ypf
144 +bool InsertWillPlusHook(); // WillPlus: Rio.arc
145 +bool InsertWolfHook(); // Wolf: Data.wolf
146 +
147 +void InsertBrunsHook(); // Bruns: bruns.exe
148 +void InsertIronGameSystemHook();// IroneGameSystem: igs_sample.exe
149 +void InsertLucifenHook(); // Lucifen@Navel: *.lpk
150 +void InsertRyokuchaHook(); // Ryokucha: _checksum.exe
151 +void InsertRealliveHook(); // RealLive: RealLive*.exe
152 +void InsertStuffScriptHook(); // Stuff: *.mpk
153 +void InsertTinkerBellHook(); // TinkerBell: arc00.dat
154 +void InsertWaffleHook(); // WAFFLE: cg.pak
155 +
156 +// CIRCUS: avdata/
157 +bool InsertCircusHook1();
158 +bool InsertCircusHook2();
159 +
160 +} // namespace Engine
161 +
162 +// EOF
1 +#pragma once
2 +
3 +// engine/hookdefs.h
4 +// 7/20/2014 jichi
5 +
6 +#include "config.h"
7 +
8 +// For HookParam user flags
9 +enum HookParamFlag : unsigned long {
10 + HPF_Null = 0 // never used
11 + , HPF_IgnoreSameAddress = 1 // ignore the last same text address
12 +};
13 +
14 +// EOF
This diff is collapsed. Click to expand it.
1 +#pragma once
2 +
3 +// engine/match.h
4 +// 8/23/2013 jichi
5 +// TODO: Clean up the interface to match game engines.
6 +// Split the engine match logic out of hooks.
7 +// Modify the game hook to allow replace functions for arbitary purpose
8 +// instead of just extracting text.
9 +
10 +#include "config.h"
11 +
12 +namespace Engine {
13 +
14 +void match(LPVOID lpThreadParameter);
15 +
16 +// jichi 10/21/2014: Return whether found the engine
17 +bool IdentifyEngine();
18 +
19 +// jichi 10/21/2014: Return 0 if failed
20 +DWORD InsertDynamicHook(LPVOID addr, DWORD frame, DWORD stack);
21 +
22 +} // namespace Engine
23 +
24 +// EOF
1 +// pchooks.cc
2 +// 8/1/2014 jichi
3 +
4 +#include "engine/pchooks.h"
5 +#include "hook.h"
6 +
7 +#define DEBUG "vnrcli"
8 +#define DPRINT(cstr) ConsoleOutput(DEBUG ":" __FUNCTION__ ":" cstr) // defined in vnrcli
9 +
10 +// 8/1/2014 jichi: Split is not used.
11 +// Although split is specified, USING_SPLIT is not assigned.
12 +
13 +// Use LPASTE to convert to wchar_t
14 +// http://bytes.com/topic/c/answers/135834-defining-wide-character-strings-macros
15 +#define LPASTE(s) L##s
16 +#define L(s) LPASTE(s)
17 +#define NEW_HOOK(_fun, _data, _data_ind, _split_off, _split_ind, _type, _len_off) \
18 + { \
19 + HookParam hp = {}; \
20 + hp.addr = (DWORD)_fun; \
21 + hp.off = _data; \
22 + hp.ind = _data_ind; \
23 + hp.split = _split_off; \
24 + hp.split_ind = _split_ind; \
25 + hp.type = _type; \
26 + hp.length_offset = _len_off; \
27 + NewHook(hp, L(#_fun)); \
28 + }
29 +
30 +// jichi 7/17/2014: Renamed from InitDefaultHook
31 +void PcHooks::hookGDIFunctions()
32 +{
33 + DPRINT("enter");
34 + // int TextHook::InitHook(LPVOID addr, DWORD data, DWORD data_ind, DWORD split_off, DWORD split_ind, WORD type, DWORD len_off)
35 + //
36 + // jichi 9/8/2013: Guessed meaning
37 + // - data(off): 4 * the n-th (base 1) parameter representing the data of the string
38 + // - len_off:
39 + // - the n-th (base 1) parameter representing the length of the string
40 + // - or 1 if is char
41 + // - or 0 if detect on run time
42 + // - type: USING_STRING if len_off != 1 else BIG_ENDIAN or USING_UNICODE
43 + //
44 + // Examples:
45 + // int WINAPI lstrlenA(LPCSTR lpString)
46 + // - data: 4 * 1 = 4, as lpString is the first
47 + // - len_off: 0, as no parameter representing string length
48 + // - type: BIG_ENDIAN, since len_off == 1
49 + // BOOL GetTextExtentPoint32(HDC hdc, LPCTSTR lpString, int c, LPSIZE lpSize);
50 + // - data: 4 * 2 = 0x8, as lpString is the second
51 + // - len_off: 3, as nCount is the 3rd parameter
52 + // - type: USING_STRING, since len_off != 1
53 + //
54 + // Note: All functions does not have NO_CONTEXT attribute and will be filtered.
55 +
56 + enum stack {
57 + s_retaddr = 0
58 + , s_arg1 = 4 * 1 // 0x4
59 + , s_arg2 = 4 * 2 // 0x8
60 + , s_arg3 = 4 * 3 // 0xc
61 + , s_arg4 = 4 * 4 // 0x10
62 + , s_arg5 = 4 * 5 // 0x14
63 + , s_arg6 = 4 * 6 // 0x18
64 + };
65 +
66 +//#define _(Name, ...) \
67 +// hookman[HF_##Name].InitHook(Name, __VA_ARGS__); \
68 +// hookman[HF_##Name].SetHookName(names[HF_##Name]);
69 +
70 + // Always use s_arg1 = hDC as split_off
71 + // 7/26/2014 jichi: Why there is no USING_SPLIT type?
72 +
73 + // gdi32.dll
74 + NEW_HOOK(GetTextExtentPoint32A, s_arg2, 0,s_arg1,0, USING_STRING, 3) // BOOL GetTextExtentPoint32(HDC hdc, LPCTSTR lpString, int c, LPSIZE lpSize);
75 + NEW_HOOK(GetGlyphOutlineA, s_arg2, 0,s_arg1,0, BIG_ENDIAN, 1) // DWORD GetGlyphOutline(HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPVOID lpvBuffer, const MAT2 *lpmat2);
76 + NEW_HOOK(ExtTextOutA, s_arg6, 0,s_arg1,0, USING_STRING, 7) // BOOL ExtTextOut(HDC hdc, int X, int Y, UINT fuOptions, const RECT *lprc, LPCTSTR lpString, UINT cbCount, const INT *lpDx);
77 + NEW_HOOK(TextOutA, s_arg4, 0,s_arg1,0, USING_STRING, 5) // BOOL TextOut(HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cchString);
78 + NEW_HOOK(GetCharABCWidthsA, s_arg2, 0,s_arg1,0, BIG_ENDIAN, 1) // BOOL GetCharABCWidths(HDC hdc, UINT uFirstChar, UINT uLastChar, LPABC lpabc);
79 + NEW_HOOK(GetTextExtentPoint32W, s_arg2, 0,s_arg1,0, USING_UNICODE|USING_STRING, 3)
80 + NEW_HOOK(GetGlyphOutlineW, s_arg2, 0,s_arg1,0, USING_UNICODE, 1)
81 + NEW_HOOK(ExtTextOutW, s_arg6, 0,s_arg1,0, USING_UNICODE|USING_STRING, 7)
82 + NEW_HOOK(TextOutW, s_arg4, 0,s_arg1,0, USING_UNICODE|USING_STRING, 5)
83 + NEW_HOOK(GetCharABCWidthsW, s_arg2, 0,s_arg1,0, USING_UNICODE, 1)
84 +
85 + // user32.dll
86 + NEW_HOOK(DrawTextA, s_arg2, 0,s_arg1,0, USING_STRING, 3) // int DrawText(HDC hDC, LPCTSTR lpchText, int nCount, LPRECT lpRect, UINT uFormat);
87 + NEW_HOOK(DrawTextExA, s_arg2, 0,s_arg1,0, USING_STRING, 3) // int DrawTextEx(HDC hdc, LPTSTR lpchText,int cchText, LPRECT lprc, UINT dwDTFormat, LPDRAWTEXTPARAMS lpDTParams);
88 + NEW_HOOK(DrawTextW, s_arg2, 0,s_arg1,0, USING_UNICODE|USING_STRING, 3)
89 + NEW_HOOK(DrawTextExW, s_arg2, 0,s_arg1,0, USING_UNICODE|USING_STRING, 3)
90 +//#undef _
91 + DPRINT("leave");
92 +}
93 +
94 +// jichi 10/2/2013
95 +// Note: All functions does not have NO_CONTEXT attribute and will be filtered.
96 +void PcHooks::hookLstrFunctions()
97 +{
98 + DPRINT("enter");
99 + // int TextHook::InitHook(LPVOID addr, DWORD data, DWORD data_ind, DWORD split_off, DWORD split_ind, WORD type, DWORD len_off)
100 +
101 + enum stack {
102 + s_retaddr = 0
103 + , s_arg1 = 4 * 1 // 0x4
104 + //, s_arg2 = 4 * 2 // 0x8
105 + //, s_arg3 = 4 * 3 // 0xc
106 + //, s_arg4 = 4 * 4 // 0x10
107 + //, s_arg5 = 4 * 5 // 0x14
108 + //, s_arg6 = 4 * 6 // 0x18
109 + };
110 +
111 + // http://msdn.microsoft.com/en-us/library/78zh94ax.aspx
112 + // int WINAPI lstrlen(LPCTSTR lpString);
113 + // Lstr functions usually extracts rubbish, and might crash certain games like 「Magical Marriage Lunatics!!」
114 + // Needed by Gift
115 + // Use arg1 address for both split and data
116 + NEW_HOOK(lstrlenA, s_arg1, 0,s_arg1,0, USING_STRING, 0) // 9/8/2013 jichi: int WINAPI lstrlen(LPCTSTR lpString);
117 + NEW_HOOK(lstrlenW, s_arg1, 0,s_arg1,0, USING_UNICODE|USING_STRING, 0) // 9/8/2013 jichi: add lstrlen
118 +
119 + // size_t strlen(const char *str);
120 + // size_t strlen_l(const char *str, _locale_t locale);
121 + // size_t wcslen(const wchar_t *str);
122 + // size_t wcslen_l(const wchar_t *str, _locale_t locale);
123 + // size_t _mbslen(const unsigned char *str);
124 + // size_t _mbslen_l(const unsigned char *str, _locale_t locale);
125 + // size_t _mbstrlen(const char *str);
126 + // size_t _mbstrlen_l(const char *str, _locale_t locale);
127 +
128 + // http://msdn.microsoft.com/en-us/library/ex0hs2ad.aspx
129 + // Needed by 娘姉妹
130 + //
131 + // <tchar.h>
132 + // char *_strinc(const char *current, _locale_t locale);
133 + // wchar_t *_wcsinc(const wchar_t *current, _locale_t locale);
134 + // <mbstring.h>
135 + // unsigned char *_mbsinc(const unsigned char *current);
136 + // unsigned char *_mbsinc_l(const unsigned char *current, _locale_t locale);
137 + //_(L"_strinc", _strinc, 4, 0,4,0, USING_STRING, 0) // 12/13/2013 jichi
138 + //_(L"_wcsinc", _wcsinc, 4, 0,4,0, USING_UNICODE|USING_STRING, 0)
139 + DPRINT("leave");
140 +}
141 +
142 +void PcHooks::hookWcharFunctions()
143 +{
144 + DPRINT("enter");
145 + // 12/1/2013 jichi:
146 + // AlterEgo
147 + // http://tieba.baidu.com/p/2736475133
148 + // http://www.hongfire.com/forum/showthread.php/36807-AGTH-text-extraction-tool-for-games-translation/page355
149 + //
150 + // MultiByteToWideChar
151 + // http://blgames.proboards.com/thread/265
152 + //
153 + // WideCharToMultiByte
154 + // http://www.hongfire.com/forum/showthread.php/36807-AGTH-text-extraction-tool-for-games-translation/page156
155 + //
156 + // int MultiByteToWideChar(
157 + // _In_ UINT CodePage,
158 + // _In_ DWORD dwFlags,
159 + // _In_ LPCSTR lpMultiByteStr, // hook here
160 + // _In_ int cbMultiByte,
161 + // _Out_opt_ LPWSTR lpWideCharStr,
162 + // _In_ int cchWideChar
163 + // );
164 + // int WideCharToMultiByte(
165 + // _In_ UINT CodePage,
166 + // _In_ DWORD dwFlags,
167 + // _In_ LPCWSTR lpWideCharStr,
168 + // _In_ int cchWideChar,
169 + // _Out_opt_ LPSTR lpMultiByteStr,
170 + // _In_ int cbMultiByte,
171 + // _In_opt_ LPCSTR lpDefaultChar,
172 + // _Out_opt_ LPBOOL lpUsedDefaultChar
173 + // );
174 +
175 + enum stack {
176 + s_retaddr = 0
177 + //, s_arg1 = 4 * 1 // 0x4
178 + //, s_arg2 = 4 * 2 // 0x8
179 + , s_arg3 = 4 * 3 // 0xc
180 + //, s_arg4 = 4 * 4 // 0x10
181 + //, s_arg5 = 4 * 5 // 0x14
182 + //, s_arg6 = 4 * 6 // 0x18
183 + };
184 +
185 + // 3/17/2014 jichi: Temporarily disabled
186 + // http://sakuradite.com/topic/159
187 + NEW_HOOK(MultiByteToWideChar, s_arg3, 0,4,0, USING_STRING, 4)
188 + NEW_HOOK(WideCharToMultiByte, s_arg3, 0,4,0, USING_UNICODE|USING_STRING, 4)
189 + DPRINT("leave");
190 +}
191 +
192 +// EOF
1 +#pragma once
2 +
3 +// pchooks.h
4 +// 8/1/2014 jichi
5 +
6 +#include "config.h"
7 +
8 +namespace PcHooks {
9 +
10 +void hookGDIFunctions();
11 +void hookLstrFunctions();
12 +void hookWcharFunctions();
13 +
14 +} // namespace PcHooks
15 +
16 +// EOF
1 +// util/util.cc
2 +// 8/23/2013 jichi
3 +// Branch: ITH_Engine/engine.cpp, revision 133
4 +// See: http://ja.wikipedia.org/wiki/プロジェクト:美少女ゲーム系/ゲームエンジン
5 +
6 +#include "engine/util.h"
7 +#include "ith/sys/sys.h"
8 +
9 +namespace { // unnamed
10 +
11 +// jichi 4/19/2014: Return the integer that can mask the signature
12 +DWORD SigMask(DWORD sig)
13 +{
14 + __asm
15 + {
16 + xor ecx,ecx
17 + mov eax,sig
18 +_mask:
19 + shr eax,8
20 + inc ecx
21 + test eax,eax
22 + jnz _mask
23 + sub ecx,4
24 + neg ecx
25 + or eax,-1
26 + shl ecx,3
27 + shr eax,cl
28 + }
29 +}
30 +
31 +} // namespace unnamed
32 +
33 +// jichi 8/24/2013: binary search?
34 +DWORD Util::GetCodeRange(DWORD hModule,DWORD *low, DWORD *high)
35 +{
36 + IMAGE_DOS_HEADER *DosHdr;
37 + IMAGE_NT_HEADERS *NtHdr;
38 + DWORD dwReadAddr;
39 + IMAGE_SECTION_HEADER *shdr;
40 + DosHdr = (IMAGE_DOS_HEADER *)hModule;
41 + if (IMAGE_DOS_SIGNATURE == DosHdr->e_magic) {
42 + dwReadAddr = hModule + DosHdr->e_lfanew;
43 + NtHdr = (IMAGE_NT_HEADERS *)dwReadAddr;
44 + if (IMAGE_NT_SIGNATURE == NtHdr->Signature) {
45 + shdr = (PIMAGE_SECTION_HEADER)((DWORD)(&NtHdr->OptionalHeader) + NtHdr->FileHeader.SizeOfOptionalHeader);
46 + while ((shdr->Characteristics & IMAGE_SCN_CNT_CODE) == 0)
47 + shdr++;
48 + *low = hModule + shdr->VirtualAddress;
49 + *high = *low + (shdr->Misc.VirtualSize & 0xfffff000) + 0x1000;
50 + }
51 + }
52 + return 0;
53 +}
54 +
55 +DWORD Util::FindCallAndEntryBoth(DWORD fun, DWORD size, DWORD pt, DWORD sig)
56 +{
57 + //WCHAR str[0x40];
58 + enum { reverse_length = 0x800 };
59 + DWORD t, l;
60 + DWORD mask = SigMask(sig);
61 + bool flag2;
62 + for (DWORD i = 0x1000; i < size-4; i++) {
63 + bool flag1 = false;
64 + if (*(BYTE *)(pt + i) == 0xe8) {
65 + flag1 = flag2 = true;
66 + t = *(DWORD *)(pt + i + 1);
67 + } else if (*(WORD *)(pt + i) == 0x15ff) {
68 + flag1 = true;
69 + flag2 = false;
70 + t = *(DWORD *)(pt + i + 2);
71 + }
72 + if (flag1) {
73 + if (flag2) {
74 + flag1 = (pt + i + 5 + t == fun);
75 + l = 5;
76 + } else if (t >= pt && t <= pt + size - 4) {
77 + flag1 = fun == *(DWORD *)t;
78 + l = 6;
79 + } else
80 + flag1 = false;
81 + if (flag1)
82 + //swprintf(str,L"CALL addr: 0x%.8X",pt + i);
83 + //OutputConsole(str);
84 + for (DWORD j = i; j > i - reverse_length; j--)
85 + if ((*(WORD *)(pt + j)) == (sig & mask)) //Fun entry 1.
86 + //swprintf(str,L"Entry: 0x%.8X",pt + j);
87 + //OutputConsole(str);
88 + return pt + j;
89 + else
90 + i += l;
91 + }
92 + }
93 + //OutputConsole(L"Find call and entry failed.");
94 + return 0;
95 +}
96 +
97 +DWORD Util::FindCallOrJmpRel(DWORD fun, DWORD size, DWORD pt, bool jmp)
98 +{
99 + BYTE sig = (jmp) ? 0xe9 : 0xe8;
100 + for (DWORD i = 0x1000; i < size - 4; i++)
101 + if (sig == *(BYTE *)(pt + i)) {
102 + DWORD t = *(DWORD *)(pt + i + 1);
103 + if(fun == pt + i + 5 + t)
104 + //OutputDWORD(pt + i);
105 + return pt + i;
106 + else
107 + i += 5;
108 + }
109 + return 0;
110 +}
111 +
112 +DWORD Util::FindCallOrJmpAbs(DWORD fun, DWORD size, DWORD pt, bool jmp)
113 +{
114 + WORD sig = jmp ? 0x25ff : 0x15ff;
115 + for (DWORD i = 0x1000; i < size - 4; i++)
116 + if (sig == *(WORD *)(pt + i)) {
117 + DWORD t = *(DWORD *)(pt + i + 2);
118 + if (t > pt && t < pt + size) {
119 + if (fun == *(DWORD *)t)
120 + return pt + i;
121 + else
122 + i += 5;
123 + }
124 + }
125 + return 0;
126 +}
127 +
128 +DWORD Util::FindCallBoth(DWORD fun, DWORD size, DWORD pt)
129 +{
130 + for (DWORD i = 0x1000; i < size - 4; i++) {
131 + if (*(BYTE *)(pt + i) == 0xe8) {
132 + DWORD t = *(DWORD *)(pt + i + 1) + pt + i + 5;
133 + if (t == fun)
134 + return i;
135 + }
136 + if (*(WORD *)(pt + i) == 0x15ff) {
137 + DWORD t = *(DWORD *)(pt + i + 2);
138 + if (t >= pt && t <= pt + size - 4) {
139 + if (*(DWORD *)t == fun)
140 + return i;
141 + else
142 + i += 6;
143 + }
144 + }
145 + }
146 + return 0;
147 +}
148 +
149 +DWORD Util::FindCallAndEntryAbs(DWORD fun, DWORD size, DWORD pt, DWORD sig)
150 +{
151 + //WCHAR str[0x40];
152 + enum { reverse_length = 0x800 };
153 + DWORD mask = SigMask(sig);
154 + for (DWORD i = 0x1000; i < size - 4; i++)
155 + if (*(WORD *)(pt + i) == 0x15ff) {
156 + DWORD t = *(DWORD *)(pt + i + 2);
157 + if (t >= pt && t <= pt + size - 4) {
158 + if (*(DWORD *)t == fun)
159 + //swprintf(str,L"CALL addr: 0x%.8X",pt + i);
160 + //OutputConsole(str);
161 + for (DWORD j = i ; j > i - reverse_length; j--)
162 + if ((*(DWORD *)(pt + j) & mask) == sig) // Fun entry 1.
163 + //swprintf(str,L"Entry: 0x%.8X",pt + j);
164 + //OutputConsole(str);
165 + return pt + j;
166 +
167 + } else
168 + i += 6;
169 + }
170 + //OutputConsole(L"Find call and entry failed.");
171 + return 0;
172 +}
173 +
174 +DWORD Util::FindCallAndEntryRel(DWORD fun, DWORD size, DWORD pt, DWORD sig)
175 +{
176 + //WCHAR str[0x40];
177 + enum { reverse_length = 0x800 };
178 + if (DWORD i = FindCallOrJmpRel(fun, size, pt, false)) {
179 + DWORD mask = SigMask(sig);
180 + for (DWORD j = i; j > i - reverse_length; j--)
181 + if (((*(DWORD *)j) & mask) == sig) //Fun entry 1.
182 + //swprintf(str,L"Entry: 0x%.8X",j);
183 + //OutputConsole(str);
184 + return j;
185 + //OutputConsole(L"Find call and entry failed.");
186 + }
187 + return 0;
188 +}
189 +DWORD Util::FindEntryAligned(DWORD start, DWORD back_range)
190 +{
191 + start &= ~0xf;
192 + for (DWORD i = start, j = start - back_range; i > j; i-=0x10) {
193 + DWORD k = *(DWORD *)(i-4);
194 + if (k == 0xcccccccc
195 + || k == 0x90909090
196 + || k == 0xccccccc3
197 + || k == 0x909090c3
198 + )
199 + return i;
200 + DWORD t = k & 0xff0000ff;
201 + if (t == 0xcc0000c2 || t == 0x900000c2)
202 + return i;
203 + k >>= 8;
204 + if (k == 0xccccc3 || k == 0x9090c3)
205 + return i;
206 + t = k & 0xff;
207 + if (t == 0xc2)
208 + return i;
209 + k >>= 8;
210 + if (k == 0xccc3 || k == 0x90c3)
211 + return i;
212 + k >>= 8;
213 + if (k == 0xc3)
214 + return i;
215 + }
216 + return 0;
217 +}
218 +
219 +DWORD Util::FindImportEntry(DWORD hModule, DWORD fun)
220 +{
221 + IMAGE_DOS_HEADER *DosHdr;
222 + IMAGE_NT_HEADERS *NtHdr;
223 + DWORD IAT, end, pt, addr;
224 + DosHdr = (IMAGE_DOS_HEADER *)hModule;
225 + if (IMAGE_DOS_SIGNATURE == DosHdr->e_magic) {
226 + NtHdr = (IMAGE_NT_HEADERS *)(hModule + DosHdr->e_lfanew);
227 + if (IMAGE_NT_SIGNATURE == NtHdr->Signature) {
228 + IAT = NtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress;
229 + end = NtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size;
230 + IAT += hModule;
231 + end += IAT;
232 + for (pt = IAT; pt < end; pt += 4) {
233 + addr = *(DWORD *)pt;
234 + if (addr == fun)
235 + return pt;
236 + }
237 + }
238 + }
239 + return 0;
240 +}
241 +
242 +// Search string in rsrc section. This section usually contains version and copyright info.
243 +bool Util::SearchResourceString(LPCWSTR str)
244 +{
245 + DWORD hModule = Util::GetModuleBase();
246 + IMAGE_DOS_HEADER *DosHdr;
247 + IMAGE_NT_HEADERS *NtHdr;
248 + DosHdr = (IMAGE_DOS_HEADER *)hModule;
249 + DWORD rsrc, size;
250 + //__asm int 3
251 + if (IMAGE_DOS_SIGNATURE == DosHdr->e_magic) {
252 + NtHdr = (IMAGE_NT_HEADERS *)(hModule + DosHdr->e_lfanew);
253 + if (IMAGE_NT_SIGNATURE == NtHdr->Signature) {
254 + rsrc = NtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
255 + if (rsrc) {
256 + rsrc += hModule;
257 + if (IthGetMemoryRange((LPVOID)rsrc, &rsrc ,&size) &&
258 + SearchPattern(rsrc, size - 4, str, wcslen(str) << 1))
259 + return true;
260 + }
261 + }
262 + }
263 + return false;
264 +}
265 +
266 +// jichi 4/15/2014: Copied from GetModuleBase in ITH CLI, for debugging purpose
267 +DWORD Util::FindModuleBase(DWORD hash)
268 +{
269 + __asm
270 + {
271 + mov eax,fs:[0x30]
272 + mov eax,[eax+0xc]
273 + mov esi,[eax+0x14]
274 + mov edi,_wcslwr
275 +listfind:
276 + mov edx,[esi+0x28]
277 + test edx,edx
278 + jz notfound
279 + push edx
280 + call edi
281 + pop edx
282 + xor eax,eax
283 +calc:
284 + movzx ecx, word ptr [edx]
285 + test cl,cl
286 + jz fin
287 + ror eax,7
288 + add eax,ecx
289 + add edx,2
290 + jmp calc
291 +fin:
292 + cmp eax,[hash]
293 + je found
294 + mov esi,[esi]
295 + jmp listfind
296 +notfound:
297 + xor eax,eax
298 + jmp termin
299 +found:
300 + mov eax,[esi+0x10]
301 +termin:
302 + }
303 +}
304 +
305 +// EOF
1 +#pragma once
2 +
3 +// util/util.h
4 +// 8/23/2013 jichi
5 +
6 +#include "config.h"
7 +
8 +namespace Util {
9 +
10 +DWORD GetCodeRange(DWORD hModule,DWORD *low, DWORD *high);
11 +DWORD FindCallAndEntryBoth(DWORD fun, DWORD size, DWORD pt, DWORD sig);
12 +DWORD FindCallOrJmpRel(DWORD fun, DWORD size, DWORD pt, bool jmp);
13 +DWORD FindCallOrJmpAbs(DWORD fun, DWORD size, DWORD pt, bool jmp);
14 +DWORD FindCallBoth(DWORD fun, DWORD size, DWORD pt);
15 +DWORD FindCallAndEntryAbs(DWORD fun, DWORD size, DWORD pt, DWORD sig);
16 +DWORD FindCallAndEntryRel(DWORD fun, DWORD size, DWORD pt, DWORD sig);
17 +DWORD FindEntryAligned(DWORD start, DWORD back_range);
18 +DWORD FindImportEntry(DWORD hModule, DWORD fun);
19 +
20 +// jichi 4/15/2014: Copied from ITH CLI, for debugging purpose
21 +DWORD FindModuleBase(DWORD hash);
22 +
23 +bool SearchResourceString(LPCWSTR str);
24 +
25 +/**
26 + * @param name process name without path deliminator
27 + */
28 +inline void GetProcessName(wchar_t *name)
29 +{
30 + //assert(name);
31 + PLDR_DATA_TABLE_ENTRY it;
32 + __asm
33 + {
34 + mov eax,fs:[0x30]
35 + mov eax,[eax+0xc]
36 + mov eax,[eax+0xc]
37 + mov it,eax
38 + }
39 + ::wcscpy(name, it->BaseDllName.Buffer);
40 +}
41 +
42 +/**
43 + * @param path with process name and directy name
44 + */
45 +inline void GetProcessPath(wchar_t *path)
46 +{
47 + //assert(path);
48 + PLDR_DATA_TABLE_ENTRY it;
49 + __asm
50 + {
51 + mov eax,fs:[0x30]
52 + mov eax,[eax+0xc]
53 + mov eax,[eax+0xc]
54 + mov it,eax
55 + }
56 + ::wcscpy(path, it->FullDllName.Buffer);
57 +}
58 +
59 +/**
60 + * @return HANDLE module handle
61 + */
62 +inline DWORD GetModuleBase()
63 +{
64 + __asm
65 + {
66 + mov eax,fs:[0x18]
67 + mov eax,[eax+0x30]
68 + mov eax,[eax+0xc]
69 + mov eax,[eax+0xc]
70 + mov eax,[eax+0x18]
71 + }
72 +}
73 +
74 +} // namespace Util
75 +
76 +// EOF
This diff is collapsed. Click to expand it.