diff --git a/vnr/disasm/disasm.cc b/vnr/disasm/disasm.cc new file mode 100644 index 0000000..3e12604 --- /dev/null +++ b/vnr/disasm/disasm.cc @@ -0,0 +1,263 @@ +// disasm.cc +// 1/27/2013 jichi +// Original source: http://hack-expo.void.ru/groups/blt/text/disasm.txt +// +// 7/19/2014 jichi: Need to add SSE instruction support for PCSX2 +// Sample problematic input from Fate/Stay night PS2: +// 3024b80c -0f88 ae58dbd2 js pcsx2.030010c0 +// 3024b812 0f1201 movlps xmm0,qword ptr ds:[ecx] ; jichi: hook here +// 3024b815 0f1302 movlps qword ptr ds:[edx],xmm0 + +#include "disasm.h" + +// disasm_flag values: +enum : unsigned { + C_66 = 0x00000001 // 66-prefix + , C_67 = 0x00000002 // 67-prefix + , C_LOCK = 0x00000004 // lock + , C_REP = 0x00000008 // repz/repnz + , C_SEG = 0x00000010 // seg-prefix + , C_OPCODE2 = 0x00000020 // 2nd opcode present (1st==0f) + , C_MODRM = 0x00000040 // modrm present + , C_SIB = 0x00000080 // sib present + , C_ANYPREFIX = (C_66|C_67|C_LOCK|C_REP|C_SEG) +}; + +DISASM_BEGIN_NAMESPACE + +// These values are served as the output of disasm +// But the are currently unused and could make disasm thread-unsafe +namespace { // unnamed + +BYTE disasm_seg, // CS DS ES SS FS GS + disasm_rep, // REPZ/REPNZ + disasm_opcode, // opcode + disasm_opcode2, // used when opcode==0f + disasm_modrm, // modxxxrm + disasm_sib, // scale-index-base + disasm_mem[8], // mem addr value + disasm_data[8]; // data value + +} // unnamed namespace + +// return: length if success, 0 if error +int disasm(const BYTE *opcode0) +{ + const BYTE *opcode = opcode0; + + DWORD disasm_len = 0, // 0 if error + disasm_flag = 0, // C_xxx + disasm_memsize = 0, // value = disasm_mem + disasm_datasize = 0, // value = disasm_data + disasm_defdata = 4, // == C_66 ? 2 : 4 + disasm_defmem = 4; // == C_67 ? 2 : 4 + +retry: + disasm_opcode = *opcode++; + + switch (disasm_opcode) { + case 0x99: // 7/20/2014 jichi: CDQ, size = 1 + break; + + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x18: case 0x19: case 0x1a: case 0x1b: + case 0x20: case 0x21: case 0x22: case 0x23: + case 0x28: case 0x29: case 0x2a: case 0x2b: + case 0x30: case 0x31: case 0x32: case 0x33: + case 0x38: case 0x39: case 0x3a: case 0x3b: + case 0x62: case 0x63: + case 0x84: case 0x85: case 0x86: case 0x87: + case 0x88: case 0x89: case 0x8a: case 0x8b: + case 0x8c: case 0x8d: case 0x8e: case 0x8f: + case 0xc4: case 0xc5: + case 0xd0: case 0xd1: case 0xd2: case 0xd3: + case 0xd8: case 0xd9: case 0xda: case 0xdb: + case 0xdc: case 0xdd: case 0xde: case 0xdf: + case 0xfe: case 0xff: + disasm_flag |= C_MODRM; + break; + case 0xcd: disasm_datasize += *opcode==0x20 ? 1+4 : 1; + break; + case 0xf6: + case 0xf7: disasm_flag |= C_MODRM; + if (*opcode & 0x38) break; + // continue if + case 0x04: case 0x05: case 0x0c: case 0x0d: + case 0x14: case 0x15: case 0x1c: case 0x1d: + case 0x24: case 0x25: case 0x2c: case 0x2d: + case 0x34: case 0x35: case 0x3c: case 0x3d: + if (disasm_opcode & 1) + disasm_datasize += disasm_defdata; + else + disasm_datasize++; + break; + case 0x6a: + case 0xa8: + case 0xb0: case 0xb1: case 0xb2: case 0xb3: + case 0xb4: case 0xb5: case 0xb6: case 0xb7: + case 0xd4: case 0xd5: + case 0xe4: case 0xe5: case 0xe6: case 0xe7: + case 0x70: case 0x71: case 0x72: case 0x73: + case 0x74: case 0x75: case 0x76: case 0x77: + case 0x78: case 0x79: case 0x7a: case 0x7b: + case 0x7c: case 0x7d: case 0x7e: case 0x7f: + case 0xeb: + case 0xe0: case 0xe1: case 0xe2: case 0xe3: + disasm_datasize++; + break; + case 0x26: case 0x2e: case 0x36: case 0x3e: + case 0x64: case 0x65: + if (disasm_flag & C_SEG) return 0; + disasm_flag |= C_SEG; + disasm_seg = disasm_opcode; + goto retry; + case 0xf0: + if (disasm_flag & C_LOCK) return 0; + disasm_flag |= C_LOCK; + goto retry; + case 0xf2: case 0xf3: + if (disasm_flag & C_REP) return 0; + disasm_flag |= C_REP; + disasm_rep = disasm_opcode; + goto retry; + case 0x66: + if (disasm_flag & C_66) return 0; + disasm_flag |= C_66; + disasm_defdata = 2; + goto retry; + case 0x67: + if (disasm_flag & C_67) return 0; + disasm_flag |= C_67; + disasm_defmem = 2; + goto retry; + case 0x6b: + case 0x80: + case 0x82: + case 0x83: + case 0xc0: + case 0xc1: + case 0xc6: disasm_datasize++; + disasm_flag |= C_MODRM; + break; + case 0x69: + case 0x81: + case 0xc7: + disasm_datasize += disasm_defdata; + disasm_flag |= C_MODRM; + break; + case 0x9a: + case 0xea: disasm_datasize += 2 + disasm_defdata; + break; + case 0xa0: + case 0xa1: + case 0xa2: + case 0xa3: disasm_memsize += disasm_defmem; + break; + case 0x68: + case 0xa9: + case 0xb8: case 0xb9: case 0xba: case 0xbb: + case 0xbc: case 0xbd: case 0xbe: case 0xbf: + case 0xe8: + case 0xe9: + disasm_datasize += disasm_defdata; + break; + case 0xc2: + case 0xca: disasm_datasize += 2; + break; + case 0xc8: + disasm_datasize += 3; + break; + case 0xf1: + return 0; + case 0x0f: + // 7/19/2014 jichi: 0x0f1201 = movlps xmm0,qword ptr ds:[ecx] + // Given 0x0f1201, 0x0f will be strip off here and left 0x1201 + disasm_flag |= C_OPCODE2; + disasm_opcode2 = *opcode++; + switch (disasm_opcode2) { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x90: case 0x91: case 0x92: case 0x93: + case 0x94: case 0x95: case 0x96: case 0x97: + case 0x98: case 0x99: case 0x9a: case 0x9b: + case 0x9c: case 0x9d: case 0x9e: case 0x9f: + case 0xa3: + case 0xa5: + case 0xab: + case 0xad: + case 0xaf: + case 0xb0: case 0xb1: case 0xb2: case 0xb3: + case 0xb4: case 0xb5: case 0xb6: case 0xb7: + case 0xbb: + case 0xbc: case 0xbd: case 0xbe: case 0xbf: + case 0xc0: + case 0xc1: + // 7/19/2014 jichi: Add more cases for SSE instructions + // Sample instructions I need to consider + // 0f1201 movlps xmm0,qword ptr ds:[ecx] ; jichi: hook here + // 0f1302 movlps qword ptr ds:[edx],xmm0 + case 0x12: + case 0x13: + disasm_flag |= C_MODRM; + break; + case 0x06: + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0xa0: case 0xa1: case 0xa2: case 0xa8: + case 0xa9: + case 0xaa: + case 0xc8: case 0xc9: case 0xca: case 0xcb: + case 0xcc: case 0xcd: case 0xce: case 0xcf: + break; + case 0x80: case 0x81: case 0x82: case 0x83: + case 0x84: case 0x85: case 0x86: case 0x87: + case 0x88: case 0x89: case 0x8a: case 0x8b: + case 0x8c: case 0x8d: case 0x8e: case 0x8f: + disasm_datasize += disasm_defdata; + break; + case 0xa4: + case 0xac: + case 0xba: + default: return 0; // 7/19/2014 jichi: error + } // 0F-switch + break; + + } // switch + + if (disasm_flag & C_MODRM) { + disasm_modrm = *opcode++; + BYTE mod = disasm_modrm & 0xc0; + BYTE rm = disasm_modrm & 0x07; + if (mod != 0xc0) { + if (mod == 0x40) + disasm_memsize++; + if (mod == 0x80) + disasm_memsize += disasm_defmem; + if (disasm_defmem == 2) { // modrm16 + if (mod == 0x00 && rm == 0x06) + disasm_memsize += 2; + } else { // modrm32 + if (rm == 0x04) { + disasm_flag |= C_SIB; + disasm_sib = *opcode++; + rm = disasm_sib & 0x07; + } + if (rm == 0x05 && mod == 0x00) + disasm_memsize += 4; + } + } + } // C_MODRM + + for (DWORD i = 0; i < disasm_memsize; i++) + disasm_mem[i] = *opcode++; + for (DWORD i = 0; i < disasm_datasize; i++) + disasm_data[i] = *opcode++; + + disasm_len = opcode - opcode0; + + return disasm_len; +} // disasm + +DISASM_END_NAMESPACE + +// EOF diff --git a/vnr/disasm/disasm.h b/vnr/disasm/disasm.h new file mode 100644 index 0000000..69a9255 --- /dev/null +++ b/vnr/disasm/disasm.h @@ -0,0 +1,26 @@ +#pragma once +// disasm.h +// 1/27/2013 jichi + +// Include typedef of BYTE +//#include +#include + +//#ifdef QT_CORE_LIB +//# include +//#else +//# include +//#endif + +#ifndef DISASM_BEGIN_NAMESPACE +# define DISASM_BEGIN_NAMESPACE +#endif +#ifndef DISASM_END_NAMESPACE +# define DISASM_END_NAMESPACE +#endif + +DISASM_BEGIN_NAMESPACE +int disasm(const BYTE *opcode0); // return: op length if success, 0 if error +DISASM_END_NAMESPACE + +// EOF diff --git a/vnr/disasm/disasm.pri b/vnr/disasm/disasm.pri new file mode 100644 index 0000000..6f83e8f --- /dev/null +++ b/vnr/disasm/disasm.pri @@ -0,0 +1,13 @@ +# disasm.pri +# 1/31/2012 jichi +win32 { + +DEFINES += WITH_LIB_DISASM +LIBS += -ldisasm +DEPENDPATH += $$PWD +HEADERS += $$PWD/disasm.h +#SOURCES += $$PWD/disasm.cc + +} + +# EOF diff --git a/vnr/disasm/disasm.pro b/vnr/disasm/disasm.pro new file mode 100644 index 0000000..00833ae --- /dev/null +++ b/vnr/disasm/disasm.pro @@ -0,0 +1,16 @@ +# sys.pro +# 8/21/2013 jichi +# Build ITH_engine.dll + +CONFIG += noqt noeh staticlib +include(../../../config.pri) + +## Sources + +TEMPLATE = lib +TARGET = disasm + +HEADERS += disasm.h +SOURCES += disasm.cc + +# EOF diff --git a/vnr/exclude.txt b/vnr/exclude.txt new file mode 100644 index 0000000..45946d4 --- /dev/null +++ b/vnr/exclude.txt @@ -0,0 +1 @@ +.bak diff --git a/vnr/ith/common/common.pri b/vnr/ith/common/common.pri new file mode 100644 index 0000000..daddefd --- /dev/null +++ b/vnr/ith/common/common.pri @@ -0,0 +1,28 @@ +# ith/common/common.pri +# 8/9/2011 jichi +# Overwrite ITH headers + +#DEFINES += ITH_HAS_CRT # whether ITH is linked with msvcrt +#DEFINES += ITH_HAS_CXX # whether ITH has access to native C++ syntax + +DEPENDPATH += $$PWD + +HEADERS += \ + $$PWD/const.h \ + $$PWD/defs.h \ + $$PWD/except.h \ + $$PWD/growl.h \ + $$PWD/memory.h \ + $$PWD/string.h \ + $$PWD/types.h + +DEFINES += _CRT_NON_CONFORMING_SWPRINTFS + +# jichi 9/14/2013: Whether using SEH exception handle. +# msvcrt on Windows XP is missin EH +#DEFINES += ITH_HAS_SEH + +# jichi 9/22/2013: Whether let ITH manage heap +#DEFINES += ITH_HAS_HEAP + +# EOF diff --git a/vnr/ith/common/const.h b/vnr/ith/common/const.h new file mode 100644 index 0000000..dfe4928 --- /dev/null +++ b/vnr/ith/common/const.h @@ -0,0 +1,253 @@ +#pragma once + +// ith/common/const.h +// 8/23/2013 jichi +// Branch: ITH/common.h, rev 128 + +// jichi 9/9/2013: Another importnat function is lstrcatA, which is already handled by +// Debonosu hooks. Wait until it is really needed by certain games. +// The order of the functions is used in several place. +// I need to recompile all of the dlls to modify the order. +enum HookFunType { + HF_Null = -1 + , HF_GetTextExtentPoint32A + , HF_GetGlyphOutlineA + , HF_ExtTextOutA + , HF_TextOutA + , HF_GetCharABCWidthsA + , HF_DrawTextA + , HF_DrawTextExA + //, HF_lstrlenA + , HF_GetTextExtentPoint32W + , HF_GetGlyphOutlineW + , HF_ExtTextOutW + , HF_TextOutW + , HF_GetCharABCWidthsW + , HF_DrawTextW + , HF_DrawTextExW + //, HF_lstrlenW + , HookFunCount // 14 +}; + +// jichi 10/14/2014 +#define HOOK_GDI_FUNCTION_LIST \ + GetTextExtentPoint32A \ + , GetGlyphOutlineA \ + , ExtTextOutA \ + , TextOutA \ + , GetCharABCWidthsA \ + , GetTextExtentPoint32W \ + , GetGlyphOutlineW \ + , ExtTextOutW \ + , TextOutW \ + , GetCharABCWidthsW \ + , DrawTextA \ + , DrawTextExA \ + , DrawTextW \ + , DrawTextExW + +enum { HOOK_FUN_COUNT = HookFunCount }; +// jichi 1/16/2015: Though called max hook, it means max number of text threads +enum { MAX_HOOK = 32 }; // must be larger than HookFunCount +//enum { HOOK_SECTION_SIZE = 0x2000 }; // default ITH value +// jichi 1/16/2015: Change to a very large number to prevent crash +//enum { MAX_HOOK = 0x100 }; // must be larger than HookFunCount +enum { HOOK_SECTION_SIZE = MAX_HOOK * 0x100 }; // default ITH value is 0x2000 for 32 hook (0x100 per hook) + +// jichi 375/2014: Add offset of pusha/pushad +// http://faydoc.tripod.com/cpu/pushad.htm +// http://agth.wikia.com/wiki/Cheat_Engine_AGTH_Tutorial +// +// Warning: The offset in ITH has -4 offset comparing to pusha and AGTH +enum pusha_off { + pusha_eax_off = -0x4 + , pusha_ecx_off = -0x8 + , pusha_edx_off = -0xc + , pusha_ebx_off = -0x10 + , pusha_esp_off = -0x14 + , pusha_ebp_off = -0x18 + , pusha_esi_off = -0x1c + , pusha_edi_off = -0x20 + , pusha_off = -0x24 // pushad offset +}; + +enum IhfCommandType { + IHF_COMMAND = -1 // null type + , IHF_COMMAND_NEW_HOOK = 0 + , IHF_COMMAND_REMOVE_HOOK = 1 + , IHF_COMMAND_MODIFY_HOOK = 2 + , IHF_COMMAND_DETACH = 3 +}; + +enum IhfNotificationType { + IHF_NOTIFICATION = -1 // null type + , IHF_NOTIFICATION_TEXT = 0 + , IHF_NOTIFICATION_NEWHOOK = 1 +}; + +// jichi 9/8/2013: The meaning are guessed +// Values must be within DWORD +// Unused values are as follows: +// - 0x100 +enum HookParamType : unsigned long { + USING_STRING = 0x1 // type(data) is char* or wchar_t* and has length + , USING_UTF8 = USING_STRING // jichi 10/21/2014: temporarily handled the same way as USING_STRING + , USING_UNICODE = 0x2 // type(data) is wchar_t or wchar_t* + , BIG_ENDIAN = 0x4 // type(data) is char + , DATA_INDIRECT = 0x8 + , USING_SPLIT = 0x10 // aware of split time? + , SPLIT_INDIRECT = 0x20 + , MODULE_OFFSET = 0x40 // do hash module, and the address is relative to module + , FUNCTION_OFFSET = 0x80 // do hash function, and the address is relative to funccion + , PRINT_DWORD = 0x100 // jichi 12/7/2014: Removed + , STRING_LAST_CHAR = 0x200 + , NO_CONTEXT = 0x400 + //, EXTERN_HOOK = 0x800 // jichi 10/24/2014: Removed + //, HOOK_AUXILIARY = 0x2000 // jichi 12/13/2013: None of known hooks are auxiliary + , HOOK_ENGINE = 0x4000 + , HOOK_ADDITIONAL = 0x8000 + + // jichi 10/24/2014: Only trigger the dynamic function, do not return any data + , HOOK_EMPTY = 0x800 + // jichi 6/1/2014: fix the split value to 0x10001 + , FIXING_SPLIT = 0x1000 + , RELATIVE_SPLIT = 0x2000 // relative split return address +}; + +// 6/1/2014: Fixed split value for hok parameter +// Fuse all threads, and prevent floating +enum { FIXED_SPLIT_VALUE = 0x10001 }; + +// jichi 12/18/2013: +// These dlls are used to guess the range for non-NO_CONTEXT hooks. +// +// Disabling uxtheme.dll would crash certain system: http://tieba.baidu.com/p/2764436254 +#define IHF_FILTER_DLL_LIST \ + /* ITH original filters */ \ + L"gdiplus.dll" /* Graphics functions like TextOutA */ \ + , L"lpk.dll" /* Language package scripts and fonts */ \ + , L"msctf.dll" /* Text service */ \ + , L"psapi.dll" /* Processes */ \ + , L"usp10.dll" /* UNICODE rendering */ \ + , L"user32.dll" /* Non-graphics functions like lstrlenA */ \ + , L"uxtheme.dll" /* Theme */ \ + \ + /* Windows DLLs */ \ + , L"advapi32.dll" /* Advanced services */ \ + , L"apphelp.dll" /* Appliation help */ \ + , L"audioses.dll" /* Audios */ \ + , L"avrt.dll" /* Audio video runtime */ \ + , L"cfgmgr32.dll" /* Configuration manager */ \ + , L"clbcatq.dll" /* COM query service */ \ + , L"comctl32.dll" /* Common control library */ \ + , L"comdlg32.dll" /* Common dialogs */ \ + , L"crypt32.dll" /* Security cryption */ \ + , L"cryptbase.dll"/* Security cryption */ \ + , L"cryptsp.dll" /* Security cryption */ \ + , L"d3d8thk.dll" /* Direct3D 8 */ \ + , L"d3d9.dll" /* Direct3D 9 */ \ + , L"dbghelp.dll" /* Debug help */ \ + , L"dciman32.dll" /* Display cotrol */ \ + , L"devobj.dll" /* Device object */ \ + , L"ddraw.dll" /* Direct draw */ \ + , L"dinput.dll" /* Diret input */ \ + , L"dsound.dll" /* Direct sound */ \ + , L"DShowRdpFilter.dll" /* Direct show */ \ + , L"dwmapi.dll" /* Windows manager */ \ + , L"gdi32.dll" /* GDI32 */ \ + , L"hid.dll" /* HID user library */ \ + , L"iertutil.dll" /* IE runtime */ \ + , L"imagehlp.dll" /* Image help */ \ + , L"imm32.dll" /* Input method */ \ + , L"ksuser.dll" /* Kernel service */ \ + , L"ole32.dll" /* COM OLE */ \ + , L"oleacc.dll" /* OLE access */ \ + , L"oleaut32.dll" /* COM OLE */ \ + , L"kernel.dll" /* Kernel functions */ \ + , L"kernelbase.dll" /* Kernel functions */ \ + , L"midimap.dll" /* MIDI */ \ + , L"mmdevapi.dll" /* Audio device */ \ + , L"mpr.dll" /* Winnet */ \ + , L"msacm32.dll" /* MS ACM */ \ + , L"msacm32.drv" /* MS ACM */ \ + , L"msasn1.dll" /* Encoding/decoding */ \ + , L"msimg32.dll" /* Image */ \ + , L"msvfw32.dll" /* Media play */ \ + , L"netapi32.dll" /* Network service */ \ + , L"normaliz.dll" /* Normalize */ \ + , L"nsi.dll" /* NSI */ \ + , L"ntdll.dll" /* NT functions */ \ + , L"ntmarta.dll" /* NT MARTA */ \ + , L"nvd3dum.dll" /* Direct 3D */ \ + , L"powerprof.dll"/* Power profile */ \ + , L"profapi.dll" /* Profile API */ \ + , L"propsys.dll" /* System properties */ \ + , L"quartz.dll" /* OpenGL */ \ + , L"rpcrt4.dll" /* RPC runtime */ \ + , L"rpcrtremote.dll" /* RPC runtime */ \ + , L"rsabase.dll" /* RSA cryption */ \ + , L"rsaenh.dll" /* RSA cryption */ \ + , L"schannel.dll" /* Security channel */ \ + , L"sechost.dll" /* Service host */ \ + , L"setupapi.dll" /* Setup service */ \ + , L"shell32.dll" /* Windows shell */ \ + , L"shlwapi.dll" /* Light-weighted shell */ \ + , L"slc.dll" /* SLC */ \ + , L"srvcli.dll" /* Service client */ \ + , L"version.dll" /* Windows version */ \ + , L"wdmaud.drv" /* Wave output */ \ + , L"wldap32.dll" /* Wireless */ \ + , L"wininet.dll" /* Internet access */ \ + , L"winmm.dll" /* Windows sound */ \ + , L"winsta.dll" /* Connection system */ \ + , L"wtsapi32.dll" /* Windows terminal server */ \ + , L"wintrust.dll" /* Windows trust */ \ + , L"wsock32.dll" /* Windows sock */ \ + , L"ws2_32.dll" /* Terminal server */ \ + , L"wkscli.dll" /* ACIS */ \ + \ + /* MSVCRT */ \ + , L"msvcrt.dll" /* VC rutime */ \ + , L"msvcr80.dll" /* VC rutime 8 */ \ + , L"msvcp80.dll" /* VC rutime 8 */ \ + , L"msvcr90.dll" /* VC rutime 9 */ \ + , L"msvcp90.dll" /* VC rutime 9 */ \ + , L"msvcr100.dll" /* VC rutime 10 */ \ + , L"msvcp100.dll" /* VC rutime 10 */ \ + , L"msvcr110.dll" /* VC rutime 11 */ \ + , L"msvcp110.dll" /* VC rutime 11 */ \ + \ + /* VNR */ \ + , L"vnrhook.dll" \ + , L"vnrhookxp.dll" \ + \ + /* Sogou IME */ \ + , L"sogoupy.ime" \ + , L"PicFace.dll" \ + , L"AddressSearch.dll" \ + \ + /* QQ IME */ \ + , L"QQPINYIN.IME" \ + \ + /* AlphaROM */ \ + , L"kDays.dll" \ + \ + /* 360Safe */ \ + , L"safemon.dll" \ + \ + /* Locale changers */ \ + , L"AlLayer.dll" /* AppLocale */ \ + , L"LocaleEmulator.dll" /* Locale Emulator */ \ + , L"LSH.dll" /* LocaleSwitch */ \ + , L"ntleah.dll" /* NTLEA */ + + // Google Japanese IME + //, L"GoogleIMEJaTIP32.dll" + +enum { + //IHF_FILTER_COUNT = 7 + IHF_FILTER_COUNT = 7 + 72 + 9 + 4 + 3 + 1 + 1 + 1 + 4 // count of total dlls to filter + , IHF_FILTER_CAPACITY = IHF_FILTER_COUNT + 1 // one more than the dll count +}; + +// EOF