mireado

starting commit

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