LunaHook-mirror/LunaHook/engine32/System4x.cpp

1760 lines
79 KiB
C++
Raw Normal View History

2024-02-07 20:59:24 +08:00
#include"System4x.h"
/**
* jichi 12/26/2013: Rance hook
*
* 01 : /HSN4:-14@5506A9
* - addr: 5572265 (0x5596a9)
* - off: 4
* - split: 4294967272 (0xffffffe8 = -0x18)
* - type: 1041 (0x411)
*
* the above code has the same pattern except int3.
* 005506a9 |. e8 f2fb1600 call Rance01.006c02a0 ; hook here
* 005506ae |. 83c4 0c add esp,0xc
* 005506b1 |. 5f pop edi
* 005506b2 |. 5e pop esi
* 005506b3 |. b0 01 mov al,0x1
* 005506b5 |. 5b pop ebx
* 005506b6 \. c2 0400 retn 0x4
* 005506b9 cc int3
*
* <EFBFBD> /hsn4:-14@42e08a
* 0042e08a |. e8 91ed1f00 call Ranceque.0062ce20 ; hook here
* 0042e08f |. 83c4 0c add esp,0xc
* 0042e092 |. 5f pop edi
* 0042e093 |. 5e pop esi
* 0042e094 |. b0 01 mov al,0x1
* 0042e096 |. 5b pop ebx
* 0042e097 \. c2 0400 retn 0x4
* 0042e09a cc int3
*
* 5/7/2015 version 1.0.1
* The hooked function is no longer get called after loading AliceRunPatch.dll.
* The hooked function is below.
* See also ATcode: http://capita.tistory.com/m/post/256
* 005C40AE CC INT3
* 005C40AF CC INT3
* 005C40B0 53 PUSH EBX
* 005C40B1 8B5C24 08 MOV EBX,DWORD PTR SS:[ESP+0x8]
* 005C40B5 56 PUSH ESI
* 005C40B6 57 PUSH EDI
* 005C40B7 8B7B 10 MOV EDI,DWORD PTR DS:[EBX+0x10]
* 005C40BA 8BF0 MOV ESI,EAX
* 005C40BC 47 INC EDI
* 005C40BD 3B7E 0C CMP EDI,DWORD PTR DS:[ESI+0xC]
* 005C40C0 76 0F JBE SHORT .005C40D1
* 005C40C2 E8 79F8FFFF CALL .005C3940
* 005C40C7 84C0 TEST AL,AL
* 005C40C9 75 06 JNZ SHORT .005C40D1
* 005C40CB 5F POP EDI
* 005C40CC 5E POP ESI
* 005C40CD 5B POP EBX
* 005C40CE C2 0400 RETN 0x4
* 005C40D1 837B 14 10 CMP DWORD PTR DS:[EBX+0x14],0x10
* 005C40D5 72 02 JB SHORT .005C40D9
* 005C40D7 8B1B MOV EBX,DWORD PTR DS:[EBX]
* 005C40D9 837E 0C 00 CMP DWORD PTR DS:[ESI+0xC],0x0
* 005C40DD 75 15 JNZ SHORT .005C40F4
* 005C40DF 57 PUSH EDI
* 005C40E0 33C0 XOR EAX,EAX
* 005C40E2 53 PUSH EBX
* 005C40E3 50 PUSH EAX
* 005C40E4 E8 B7400D00 CALL .006981A0
* 005C40E9 83C4 0C ADD ESP,0xC
* 005C40EC 5F POP EDI
* 005C40ED 5E POP ESI
* 005C40EE B0 01 MOV AL,0x1
* 005C40F0 5B POP EBX
* 005C40F1 C2 0400 RETN 0x4
* 005C40F4 8B46 08 MOV EAX,DWORD PTR DS:[ESI+0x8]
* 005C40F7 57 PUSH EDI
* 005C40F8 53 PUSH EBX
* 005C40F9 50 PUSH EAX
* 005C40FA E8 A1400D00 CALL .006981A0 ; jichi: call here
* 005C40FF 83C4 0C ADD ESP,0xC
* 005C4102 5F POP EDI
* 005C4103 5E POP ESI
* 005C4104 B0 01 MOV AL,0x1
* 005C4106 5B POP EBX
* 005C4107 C2 0400 RETN 0x4
* 005C410A CC INT3
* 005C410B CC INT3
* 005C410C CC INT3 *
*/
static bool InsertSystem43OldHook(ULONG startAddress, ULONG stopAddress, LPCSTR hookName)
{
// i.e. 83c40c5f5eb0015bc20400cccc without leading 0xe8
//const BYTE ins[] = { // 005506a9 |. e8 f2fb1600 call rance01.006c02a0 ; hook here
// 0x83,0xc4, 0x0c, // 005506ae |. 83c4 0c add esp,0xc
// 0x5f, // 005506b1 |. 5f pop edi
// 0x5e, // 005506b2 |. 5e pop esi
// 0xb0, 0x01, // 005506b3 |. b0 01 mov al,0x1
// 0x5b, // 005506b5 |. 5b pop ebx
// 0xc2, 0x04,0x00, // 005506b6 \. c2 0400 retn 0x4
// 0xcc, 0xcc // patching a few int3 to make sure that this is at the end of the code block
//};
//enum { addr_offset = -5 }; // the function call before the ins
//ULONG addr = processStartAddress; //- sizeof(ins);
////addr = 0x5506a9;
//enum { near_call = 0xe8 }; // intra-module function call
//do {
// //addr += sizeof(ins); // so that each time return diff address -- not needed
// ULONG range = min(processStopAddress - addr, MAX_REL_ADDR);
// addr = MemDbg::findBytes(ins, sizeof(ins), addr, addr + range);
// if (!addr) {
// //ITH_MSG(L"failed");
// ConsoleOutput("System43: pattern not found");
// return false;
// }
// addr += addr_offset;
//} while(near_call != *(BYTE *)addr); // function call
//GROWL_DWORD(addr);
// i.e. 83c40c5f5eb0015bc20400cccc without leading 0xe8
const BYTE bytes[] = {
0xe8, XX4, // 005506a9 |. e8 f2fb1600 call rance01.006c02a0 ; hook here
0x83,0xc4, 0x0c, // 005506ae |. 83c4 0c add esp,0xc
XX, // 005506b1 |. 5f pop edi ; Artikash 2/9/2019 change these to wildcards: Evenicle 2 has the pops and moves switched order
XX, // 005506b2 |. 5e pop esi
XX, XX, // 005506b3 |. b0 01 mov al,0x1
0x5b, // 005506b5 |. 5b pop ebx
0xc2, 0x04,0x00, // 005506b6 \. c2 0400 retn 0x4
0xcc, 0xcc // patching a few int3 to make sure that this is at the end of the code block
};
enum { addr_offset = 0 };
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
//GROWL_DWORD(addr);
if (!addr) {
ConsoleOutput("System43: pattern not found");
return false;
}
HookParam hp;
hp.address = addr + addr_offset;
hp.offset=get_stack(1);
hp.split = get_reg(regs::esp);
hp.type = NO_CONTEXT|USING_SPLIT|USING_STRING|EMBED_ABLE|EMBED_BEFORE_SIMPLE|EMBED_AFTER_NEW|EMBED_DYNA_SJIS;
ConsoleOutput("INSERT System43");
ConsoleOutput("System43: disable GDI hooks"); // disable hooking to TextOutA, which is cached
return NewHook(hp, hookName);
}
/** 5/13/2015 Add new hook for System43 engine that has no garbage threads and can detect character name
* Sample game: Evenicle
* See: http://capita.tistory.com/m/post/256
*
* 004EEA6C CC INT3
* 004EEA6D CC INT3
* 004EEA6E CC INT3
* 004EEA6F CC INT3
* 004EEA70 6A FF PUSH -0x1
* 004EEA72 68 E8267000 PUSH .007026E8
* 004EEA77 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
* 004EEA7D 50 PUSH EAX
* 004EEA7E 83EC 20 SUB ESP,0x20
* 004EEA81 A1 DCC47700 MOV EAX,DWORD PTR DS:[0x77C4DC]
* 004EEA86 33C4 XOR EAX,ESP
* 004EEA88 894424 1C MOV DWORD PTR SS:[ESP+0x1C],EAX
* 004EEA8C 53 PUSH EBX
* 004EEA8D 55 PUSH EBP
* 004EEA8E 56 PUSH ESI
* 004EEA8F 57 PUSH EDI
* 004EEA90 A1 DCC47700 MOV EAX,DWORD PTR DS:[0x77C4DC]
* 004EEA95 33C4 XOR EAX,ESP
* 004EEA97 50 PUSH EAX
* 004EEA98 8D4424 34 LEA EAX,DWORD PTR SS:[ESP+0x34]
* 004EEA9C 64:A3 00000000 MOV DWORD PTR FS:[0],EAX
* 004EEAA2 8B4424 44 MOV EAX,DWORD PTR SS:[ESP+0x44]
* 004EEAA6 8BF1 MOV ESI,ECX
* 004EEAA8 E8 8346FBFF CALL .004A3130
* 004EEAAD 8BE8 MOV EBP,EAX
* 004EEAAF 33DB XOR EBX,EBX
* 004EEAB1 3BEB CMP EBP,EBX
* 004EEAB3 75 07 JNZ SHORT .004EEABC
* 004EEAB5 32C0 XOR AL,AL
* 004EEAB7 E9 92000000 JMP .004EEB4E
* 004EEABC 8B06 MOV EAX,DWORD PTR DS:[ESI]
* 004EEABE 8B10 MOV EDX,DWORD PTR DS:[EAX]
* 004EEAC0 8BCE MOV ECX,ESI
* 004EEAC2 FFD2 CALL EDX
* 004EEAC4 8BC8 MOV ECX,EAX
* 004EEAC6 C74424 28 0F0000>MOV DWORD PTR SS:[ESP+0x28],0xF
* 004EEACE 895C24 24 MOV DWORD PTR SS:[ESP+0x24],EBX
* 004EEAD2 885C24 14 MOV BYTE PTR SS:[ESP+0x14],BL
* 004EEAD6 8D71 01 LEA ESI,DWORD PTR DS:[ECX+0x1]
* 004EEAD9 8DA424 00000000 LEA ESP,DWORD PTR SS:[ESP]
* 004EEAE0 8A11 MOV DL,BYTE PTR DS:[ECX]
* 004EEAE2 41 INC ECX
* 004EEAE3 3AD3 CMP DL,BL
* 004EEAE5 ^75 F9 JNZ SHORT .004EEAE0
* 004EEAE7 2BCE SUB ECX,ESI
* 004EEAE9 50 PUSH EAX
* 004EEAEA 8BF9 MOV EDI,ECX
* 004EEAEC 8D7424 18 LEA ESI,DWORD PTR SS:[ESP+0x18]
* 004EEAF0 E8 CB27F1FF CALL .004012C0
* 004EEAF5 8B7C24 48 MOV EDI,DWORD PTR SS:[ESP+0x48]
* 004EEAF9 895C24 3C MOV DWORD PTR SS:[ESP+0x3C],EBX
* 004EEAFD 8B75 3C MOV ESI,DWORD PTR SS:[EBP+0x3C]
* 004EEB00 E8 1B4A0100 CALL .00503520
* 004EEB05 8BF8 MOV EDI,EAX
* 004EEB07 8DB7 E4000000 LEA ESI,DWORD PTR DS:[EDI+0xE4]
* 004EEB0D 8D4424 14 LEA EAX,DWORD PTR SS:[ESP+0x14]
* 004EEB11 8BD6 MOV EDX,ESI
* 004EEB13 E8 985CF1FF CALL .004047B0
* 004EEB18 BD 10000000 MOV EBP,0x10
* 004EEB1D 84C0 TEST AL,AL
* 004EEB1F 75 18 JNZ SHORT .004EEB39
* 004EEB21 895E 10 MOV DWORD PTR DS:[ESI+0x10],EBX
* 004EEB24 396E 14 CMP DWORD PTR DS:[ESI+0x14],EBP
* 004EEB27 72 02 JB SHORT .004EEB2B
* 004EEB29 8B36 MOV ESI,DWORD PTR DS:[ESI]
* 004EEB2B 8D4424 14 LEA EAX,DWORD PTR SS:[ESP+0x14]
* 004EEB2F 50 PUSH EAX
* 004EEB30 8BCF MOV ECX,EDI
* 004EEB32 881E MOV BYTE PTR DS:[ESI],BL
* 004EEB34 E8 67CB0100 CALL .0050B6A0 ; jichi: ATcode modified here, text is on the top of the stack
* 004EEB39 396C24 28 CMP DWORD PTR SS:[ESP+0x28],EBP
* 004EEB3D 72 0D JB SHORT .004EEB4C
* 004EEB3F 8B4C24 14 MOV ECX,DWORD PTR SS:[ESP+0x14]
* 004EEB43 51 PUSH ECX
* 004EEB44 E8 42DC1900 CALL .0068C78B
* 004EEB49 83C4 04 ADD ESP,0x4
* 004EEB4C B0 01 MOV AL,0x1
* 004EEB4E 8B4C24 34 MOV ECX,DWORD PTR SS:[ESP+0x34]
* 004EEB52 64:890D 00000000 MOV DWORD PTR FS:[0],ECX
* 004EEB59 59 POP ECX
* 004EEB5A 5F POP EDI
* 004EEB5B 5E POP ESI
* 004EEB5C 5D POP EBP
* 004EEB5D 5B POP EBX
* 004EEB5E 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+0x1C]
* 004EEB62 33CC XOR ECX,ESP
* 004EEB64 E8 9CD61900 CALL .0068C205
* 004EEB69 83C4 2C ADD ESP,0x2C
* 004EEB6C C3 RETN
* 004EEB6D CC INT3
* 004EEB6E CC INT3
*
* Actual binary patch for Evenicle exe: http://capita.tistory.com/m/post/256
* {005E393B(EB), 004EEB34(E9 13 B6 21 00), 005C71E0(E9 48 2F 14 00), 005B6494(E9 10 3D 15 00), 0070A10F(90 90 90 90 90 E8 F7 9F EB FF E9 C7 D0 EB FF 90 90 90 90 90 E8 78 15 E0 FF E9 0C 4A DE FF 50 8B 87 B0 00 00 00 66 81 38 84 00 75 0E 83 78 EA 5B 75 08 E8 A2 00 00 00 58 EB C6 58 EB C8 50 52 BA E0 0B 7A 00 60 89 D7 8B 74 E4 28 B9 06 00 00 00 F3 A5 61 8B 44 E4 08 8B 40 10 85 C0 74 29 8B 44 E4 08 8B 40 14 83 F8 0F 75 08 89 54 E4 08 5A 58 EB 9D 8D 42 20 60 89 C7 8B 32 8B 4A 14 83 C1 09 F3 A4 61 89 02 EB E3 5A 58 EB 89 90 90 90 90 90 E8 6C 9F EB FF E9 F0 C2 EA FF 50 8B 44 E4 04 83 78 0C 01 76 31 8B 87 84 02 00 00 66 83 78 FC 46 75 24 83 78 F8 22 74 16 83 78 F8 13 75 18 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 E8 06 00 00 00 58 EB B5 58 EB B7 60 8B 74 E4 28 BF E0 0B 7A 00 89 7C E4 28 B9 0C 00 00 00 F3 A5 61 C3)}
*
* ATcode: FORCEFONT(5),ENCODEKOR,FONT(Malgun Gothic,-13),HOOK(0x0070A10F,TRANS([[ESP]+0x8],LEN([ESP]+0XC),PTRCHEAT),RETNPOS(COPY)),HOOK(0x0070A11E,TRANS([ESP],SMSTR(IGNORE)),RETNPOS(COPY)),HOOK(0x0070A19A,TRANS([[ESP]+0x8],LEN([ESP]+0XC),PTRCHEAT),RETNPOS(COPY))
* FilterCode: DenyWord{CUT(2)},FixLine{},KoFilter{},DumpText{},CustomDic{CDic},CustomScript{Write,Pass(-1),Cache}
*
* The second hooked address pointed to the text address.
* The logic here is simplify buffer the read text, and replace the text by zero
* Then translate/paint them together.
* Several variables near the text address is used to check if the text is finished or not.
*
* Function immediately before patched code:
* 0070A09E CC INT3
* 0070A09F CC INT3
* 0070A0A0 6A FF PUSH -0x1
* 0070A0A2 68 358A7000 PUSH .00708A35
* 0070A0A7 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
* 0070A0AD 50 PUSH EAX
* 0070A0AE 51 PUSH ECX
* 0070A0AF 56 PUSH ESI
* 0070A0B0 A1 DCC47700 MOV EAX,DWORD PTR DS:[0x77C4DC]
* 0070A0B5 33C4 XOR EAX,ESP
* 0070A0B7 50 PUSH EAX
* 0070A0B8 8D4424 0C LEA EAX,DWORD PTR SS:[ESP+0xC]
* 0070A0BC 64:A3 00000000 MOV DWORD PTR FS:[0],EAX
* 0070A0C2 C74424 14 000000>MOV DWORD PTR SS:[ESP+0x14],0x0
* 0070A0CA A1 54D17900 MOV EAX,DWORD PTR DS:[0x79D154]
* 0070A0CF 8B08 MOV ECX,DWORD PTR DS:[EAX]
* 0070A0D1 50 PUSH EAX
* 0070A0D2 51 PUSH ECX
* 0070A0D3 8D7424 10 LEA ESI,DWORD PTR SS:[ESP+0x10]
* 0070A0D7 E8 6416F8FF CALL .0068B740
* 0070A0DC A1 54D17900 MOV EAX,DWORD PTR DS:[0x79D154]
* 0070A0E1 50 PUSH EAX
* 0070A0E2 E8 A426F8FF CALL .0068C78B
* 0070A0E7 83C4 04 ADD ESP,0x4
* 0070A0EA 8B4C24 0C MOV ECX,DWORD PTR SS:[ESP+0xC]
* 0070A0EE 64:890D 00000000 MOV DWORD PTR FS:[0],ECX
* 0070A0F5 59 POP ECX
* 0070A0F6 5E POP ESI
* 0070A0F7 83C4 10 ADD ESP,0x10
* 0070A0FA C3 RETN
* 0070A0FB C705 C4C17900 64>MOV DWORD PTR DS:[0x79C1C4],.0070B664
* 0070A105 B9 C4C17900 MOV ECX,.0079C1C4
* 0070A10A ^E9 0722F8FF JMP .0068C316
*
* Patched code:
* 0070A10F 90 NOP ; jichi: ATcode hooked here
* 0070A110 90 NOP
* 0070A111 90 NOP
* 0070A112 90 NOP
* 0070A113 90 NOP
* 0070A114 E8 F79FEBFF CALL .005C4110
* 0070A119 ^E9 C7D0EBFF JMP .005C71E5
* 0070A11E 90 NOP
* 0070A11F 90 NOP
* 0070A120 90 NOP
* 0070A121 90 NOP
* 0070A122 90 NOP
* 0070A123 E8 7815E0FF CALL .0050B6A0 ; jichi: call the original function for hookpoint #2
* 0070A128 ^E9 0C4ADEFF JMP .004EEB39 ; jichi: come back to hookpoint#2
* 0070A12D 50 PUSH EAX ; jichi: this is for hookpoint #3, translate the text before send it to paint
* 0070A12E 8B87 B0000000 MOV EAX,DWORD PTR DS:[EDI+0xB0]
* 0070A134 66:8138 8400 CMP WORD PTR DS:[EAX],0x84
* 0070A139 75 0E JNZ SHORT .0070A149
* 0070A13B 8378 EA 5B CMP DWORD PTR DS:[EAX-0x16],0x5B
* 0070A13F 75 08 JNZ SHORT .0070A149
* 0070A141 E8 A2000000 CALL .0070A1E8
* 0070A146 58 POP EAX
* 0070A147 ^EB C6 JMP SHORT .0070A10F
* 0070A149 58 POP EAX
* 0070A14A ^EB C8 JMP SHORT .0070A114
* 0070A14C 50 PUSH EAX ; jichi: hookpoint#2 jmp here, text address is in [esp]
* 0070A14D 52 PUSH EDX
* 0070A14E BA E00B7A00 MOV EDX,.007A0BE0 ; jichi: 007A0BE0 points to unused zeroed memory
* 0070A153 60 PUSHAD ; jichi esp -= 0x20, now, esp[0x28] is text address, esp[0x24] = eax, and esp[0x20] = edx
* 0070A154 89D7 MOV EDI,EDX ; set 007A0BE0 as the target buffer to save text, edx is never modified
* 0070A156 8B74E4 28 MOV ESI,DWORD PTR SS:[ESP+0x28] ; set source text as target
* 0070A15A B9 06000000 MOV ECX,0x6 ; move for 6 bytes
* 0070A15F F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
* 0070A161 61 POPAD ; finished saving text, now [esp] is old edx, esp[0x4] is old eax, esp[0x8] is old text address
* 0070A162 8B44E4 08 MOV EAX,DWORD PTR SS:[ESP+0x8] ; eax = original text address
* 0070A166 8B40 10 MOV EAX,DWORD PTR DS:[EAX+0x10] ; eax = text[0x10]
* 0070A169 85C0 TEST EAX,EAX ; if end of text,
* 0070A16B 74 29 JE SHORT .0070A196 ; jump if eax is zero, comeback to hookpoint and ignore it
* 0070A16D 8B44E4 08 MOV EAX,DWORD PTR SS:[ESP+0x8] ; otherwise, if eax is not zero
* 0070A171 8B40 14 MOV EAX,DWORD PTR DS:[EAX+0x14] ; eax = text[0x14]
* 0070A174 83F8 0F CMP EAX,0xF ; jichi: compare text[0x14] with 0xf
* 0070A177 75 08 JNZ SHORT .0070A181 ; jump if not zero leaving text not modified, other continue and modify the text
* 0070A179 8954E4 08 MOV DWORD PTR SS:[ESP+0x8],EDX ; override esp+8 with edx, i.e. override text address by new text address and do translation
* 0070A17D 5A POP EDX
* 0070A17E 58 POP EAX ; jichi: restore edx and eax, now esp is back to normal. [esp] is the new text address
* 0070A17F ^EB 9D JMP SHORT .0070A11E ; jichi: jump to the top of the hooked place (nop) and do translation before coming back
* 0070A181 8D42 20 LEA EAX,DWORD PTR DS:[EDX+0x20] ; text is not modified, esp[0x8] is the text address, edx is the modified buffer, eax = buffer[0x20] address
* 0070A184 60 PUSHAD ; jichi: esp[0x28] is now the text address
* 0070A185 89C7 MOV EDI,EAX ; jichi: edx[0x20] is the target
* 0070A187 8B32 MOV ESI,DWORD PTR DS:[EDX] ; jichi: edx is the source
* 0070A189 8B4A 14 MOV ECX,DWORD PTR DS:[EDX+0x14]
* 0070A18C 83C1 09 ADD ECX,0x9 ; move for [edx+0x14]+0x9 time
* 0070A18F F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] ; jichi: shift text by 0x14 dword ptr
* 0070A191 61 POPAD ; jichi: now esp[0x8] is the text address
* 0070A192 8902 MOV DWORD PTR DS:[EDX],EAX ; eax is the new text address (edx+0x20), move the address to beginning of buffer ([edx]), i.e. edx is pointed to zero memory now
* 0070A194 ^EB E3 JMP SHORT .0070A179 ; come bback to modify the text address
* 0070A196 5A POP EDX
* 0070A197 58 POP EAX
* 0070A198 ^EB 89 JMP SHORT .0070A123 ; jichi: come back to call
* 0070A19A 90 NOP
* 0070A19B 90 NOP
* 0070A19C 90 NOP
* 0070A19D 90 NOP
* 0070A19E 90 NOP
* 0070A19F E8 6C9FEBFF CALL .005C4110
* 0070A1A4 ^E9 F0C2EAFF JMP .005B6499
* 0070A1A9 50 PUSH EAX ; jichi: from hookpoint #4
* 0070A1AA 8B44E4 04 MOV EAX,DWORD PTR SS:[ESP+0x4] ; jichi: move top of the old stack address to eax
* 0070A1AE 8378 0C 01 CMP DWORD PTR DS:[EAX+0xC],0x1
* 0070A1B2 76 31 JBE SHORT .0070A1E5 ; jichi: jump to leave if text[0xc] <= 0x1
* 0070A1B4 8B87 84020000 MOV EAX,DWORD PTR DS:[EDI+0x284]
* 0070A1BA 66:8378 FC 46 CMP WORD PTR DS:[EAX-0x4],0x46
* 0070A1BF 75 24 JNZ SHORT .0070A1E5
* 0070A1C1 8378 F8 22 CMP DWORD PTR DS:[EAX-0x8],0x22
* 0070A1C5 74 16 JE SHORT .0070A1DD
* 0070A1C7 8378 F8 13 CMP DWORD PTR DS:[EAX-0x8],0x13
* 0070A1CB 75 18 JNZ SHORT .0070A1E5
* 0070A1CD 90 NOP
* 0070A1CE 90 NOP
* 0070A1CF 90 NOP
* 0070A1D0 90 NOP
* 0070A1D1 90 NOP
* 0070A1D2 90 NOP
* 0070A1D3 90 NOP
* 0070A1D4 90 NOP
* 0070A1D5 90 NOP
* 0070A1D6 90 NOP
* 0070A1D7 90 NOP
* 0070A1D8 90 NOP
* 0070A1D9 90 NOP
* 0070A1DA 90 NOP
* 0070A1DB 90 NOP
* 0070A1DC 90 NOP
* 0070A1DD E8 06000000 CALL .0070A1E8
* 0070A1E2 58 POP EAX
* 0070A1E3 ^EB B5 JMP SHORT .0070A19A
* 0070A1E5 58 POP EAX
* 0070A1E6 ^EB B7 JMP SHORT .0070A19F
* 0070A1E8 60 PUSHAD
* 0070A1E9 8B74E4 28 MOV ESI,DWORD PTR SS:[ESP+0x28]
* 0070A1ED BF E00B7A00 MOV EDI,.007A0BE0
* 0070A1F2 897CE4 28 MOV DWORD PTR SS:[ESP+0x28],EDI
* 0070A1F6 B9 0C000000 MOV ECX,0xC
* 0070A1FB F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
* 0070A1FD 61 POPAD
* 0070A1FE C3 RETN
* 0070A1FF 0000 ADD BYTE PTR DS:[EAX],AL
* 0070A201 0000 ADD BYTE PTR DS:[EAX],AL
* 0070A203 0000 ADD BYTE PTR DS:[EAX],AL
*
* Modified places:
*
* 005E391C CC INT3
* 005E391D CC INT3
* 005E391E CC INT3
* 005E391F CC INT3
* 005E3920 55 PUSH EBP
* 005E3921 8BEC MOV EBP,ESP
* 005E3923 83E4 C0 AND ESP,0xFFFFFFC0
* 005E3926 83EC 34 SUB ESP,0x34
* 005E3929 53 PUSH EBX
* 005E392A 8B5D 08 MOV EBX,DWORD PTR SS:[EBP+0x8]
* 005E392D 817B 04 00010000 CMP DWORD PTR DS:[EBX+0x4],0x100
* 005E3934 56 PUSH ESI
* 005E3935 57 PUSH EDI
* 005E3936 8B7D 0C MOV EDI,DWORD PTR SS:[EBP+0xC]
* 005E3939 8BF0 MOV ESI,EAX
* 005E393B EB 67 JMP SHORT .005E39A4 ; jichi: here modified point#1, change to always jump to 5e39a4, when enabled it will change font size
* 005E393D 8D4424 28 LEA EAX,DWORD PTR SS:[ESP+0x28]
* 005E3941 50 PUSH EAX
* 005E3942 8D4C24 30 LEA ECX,DWORD PTR SS:[ESP+0x30]
*
* 004EEA6E CC INT3
* 004EEA6F CC INT3
* 004EEA70 6A FF PUSH -0x1
* 004EEA72 68 E8267000 PUSH .007026E8
* 004EEA77 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
* 004EEA7D 50 PUSH EAX
* 004EEA7E 83EC 20 SUB ESP,0x20
* 004EEA81 A1 DCC47700 MOV EAX,DWORD PTR DS:[0x77C4DC]
* 004EEA86 33C4 XOR EAX,ESP
* 004EEA88 894424 1C MOV DWORD PTR SS:[ESP+0x1C],EAX
* 004EEA8C 53 PUSH EBX
* 004EEA8D 55 PUSH EBP
* 004EEA8E 56 PUSH ESI
* 004EEA8F 57 PUSH EDI
* 004EEA90 A1 DCC47700 MOV EAX,DWORD PTR DS:[0x77C4DC]
* 004EEA95 33C4 XOR EAX,ESP
* 004EEA97 50 PUSH EAX
* 004EEA98 8D4424 34 LEA EAX,DWORD PTR SS:[ESP+0x34]
* 004EEA9C 64:A3 00000000 MOV DWORD PTR FS:[0],EAX
* 004EEAA2 8B4424 44 MOV EAX,DWORD PTR SS:[ESP+0x44]
* 004EEAA6 8BF1 MOV ESI,ECX
* 004EEAA8 E8 8346FBFF CALL .004A3130
* 004EEAAD 8BE8 MOV EBP,EAX
* 004EEAAF 33DB XOR EBX,EBX
* 004EEAB1 3BEB CMP EBP,EBX
* 004EEAB3 75 07 JNZ SHORT .004EEABC
* 004EEAB5 32C0 XOR AL,AL
* 004EEAB7 E9 92000000 JMP .004EEB4E
* 004EEABC 8B06 MOV EAX,DWORD PTR DS:[ESI]
* 004EEABE 8B10 MOV EDX,DWORD PTR DS:[EAX]
* 004EEAC0 8BCE MOV ECX,ESI
* 004EEAC2 FFD2 CALL EDX
* 004EEAC4 8BC8 MOV ECX,EAX
* 004EEAC6 C74424 28 0F0000>MOV DWORD PTR SS:[ESP+0x28],0xF
* 004EEACE 895C24 24 MOV DWORD PTR SS:[ESP+0x24],EBX
* 004EEAD2 885C24 14 MOV BYTE PTR SS:[ESP+0x14],BL
* 004EEAD6 8D71 01 LEA ESI,DWORD PTR DS:[ECX+0x1]
* 004EEAD9 8DA424 00000000 LEA ESP,DWORD PTR SS:[ESP]
* 004EEAE0 8A11 MOV DL,BYTE PTR DS:[ECX]
* 004EEAE2 41 INC ECX
* 004EEAE3 3AD3 CMP DL,BL
* 004EEAE5 ^75 F9 JNZ SHORT .004EEAE0
* 004EEAE7 2BCE SUB ECX,ESI
* 004EEAE9 50 PUSH EAX
* 004EEAEA 8BF9 MOV EDI,ECX
* 004EEAEC 8D7424 18 LEA ESI,DWORD PTR SS:[ESP+0x18]
* 004EEAF0 E8 CB27F1FF CALL .004012C0
* 004EEAF5 8B7C24 48 MOV EDI,DWORD PTR SS:[ESP+0x48]
* 004EEAF9 895C24 3C MOV DWORD PTR SS:[ESP+0x3C],EBX
* 004EEAFD 8B75 3C MOV ESI,DWORD PTR SS:[EBP+0x3C]
* 004EEB00 E8 1B4A0100 CALL .00503520
* 004EEB05 8BF8 MOV EDI,EAX
* 004EEB07 8DB7 E4000000 LEA ESI,DWORD PTR DS:[EDI+0xE4]
* 004EEB0D 8D4424 14 LEA EAX,DWORD PTR SS:[ESP+0x14]
* 004EEB11 8BD6 MOV EDX,ESI
* 004EEB13 E8 985CF1FF CALL .004047B0
* 004EEB18 BD 10000000 MOV EBP,0x10
* 004EEB1D 84C0 TEST AL,AL
* 004EEB1F 75 18 JNZ SHORT .004EEB39
* 004EEB21 895E 10 MOV DWORD PTR DS:[ESI+0x10],EBX
* 004EEB24 396E 14 CMP DWORD PTR DS:[ESI+0x14],EBP
* 004EEB27 72 02 JB SHORT .004EEB2B
* 004EEB29 8B36 MOV ESI,DWORD PTR DS:[ESI]
* 004EEB2B 8D4424 14 LEA EAX,DWORD PTR SS:[ESP+0x14]
* 004EEB2F 50 PUSH EAX
* 004EEB30 8BCF MOV ECX,EDI
* 004EEB32 881E MOV BYTE PTR DS:[ESI],BL
* 004EEB34 E9 13B62100 JMP .0070A14C ; jichi: here hookpoint#2, name is modified here, scenario and names are here accessed char by char on the top of the stack
* 004EEB39 396C24 28 CMP DWORD PTR SS:[ESP+0x28],EBP
* 004EEB3D 72 0D JB SHORT .004EEB4C
* 004EEB3F 8B4C24 14 MOV ECX,DWORD PTR SS:[ESP+0x14]
* 004EEB43 51 PUSH ECX
* 004EEB44 E8 42DC1900 CALL .0068C78B
* 004EEB49 83C4 04 ADD ESP,0x4
* 004EEB4C B0 01 MOV AL,0x1
* 004EEB4E 8B4C24 34 MOV ECX,DWORD PTR SS:[ESP+0x34]
* 004EEB52 64:890D 00000000 MOV DWORD PTR FS:[0],ECX
* 004EEB59 59 POP ECX
* 004EEB5A 5F POP EDI
* 004EEB5B 5E POP ESI
* 004EEB5C 5D POP EBP
* 004EEB5D 5B POP EBX
* 004EEB5E 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+0x1C]
* 004EEB62 33CC XOR ECX,ESP
* 004EEB64 E8 9CD61900 CALL .0068C205
* 004EEB69 83C4 2C ADD ESP,0x2C
* 004EEB6C C3 RETN
* 004EEB6D CC INT3
* 004EEB6E CC INT3
*
* 005C70EE CC INT3
* 005C70EF CC INT3
* 005C70F0 83EC 18 SUB ESP,0x18
* 005C70F3 A1 DCC47700 MOV EAX,DWORD PTR DS:[0x77C4DC]
* 005C70F8 33C4 XOR EAX,ESP
* 005C70FA 894424 14 MOV DWORD PTR SS:[ESP+0x14],EAX
* 005C70FE 53 PUSH EBX
* 005C70FF 8B5C24 20 MOV EBX,DWORD PTR SS:[ESP+0x20]
* 005C7103 55 PUSH EBP
* 005C7104 8B6C24 2C MOV EBP,DWORD PTR SS:[ESP+0x2C]
* 005C7108 8B45 1C MOV EAX,DWORD PTR SS:[EBP+0x1C]
* 005C710B 56 PUSH ESI
* 005C710C 8BF2 MOV ESI,EDX
* 005C710E 57 PUSH EDI
* 005C710F 8BF9 MOV EDI,ECX
* 005C7111 897424 10 MOV DWORD PTR SS:[ESP+0x10],ESI
* 005C7115 83F8 44 CMP EAX,0x44
* 005C7118 77 7A JA SHORT .005C7194
* 005C711A 0FB680 7C735C00 MOVZX EAX,BYTE PTR DS:[EAX+0x5C737C]
* 005C7121 FF2485 60735C00 JMP DWORD PTR DS:[EAX*4+0x5C7360]
* 005C7128 8B4B 0C MOV ECX,DWORD PTR DS:[EBX+0xC]
* 005C712B 8B4424 30 MOV EAX,DWORD PTR SS:[ESP+0x30]
* 005C712F C1E9 02 SHR ECX,0x2
* 005C7132 3BC1 CMP EAX,ECX
* 005C7134 73 5E JNB SHORT .005C7194
* 005C7136 837B 0C 00 CMP DWORD PTR DS:[EBX+0xC],0x0
* 005C713A 75 1C JNZ SHORT .005C7158
* 005C713C 33DB XOR EBX,EBX
* 005C713E 5F POP EDI
* 005C713F 893483 MOV DWORD PTR DS:[EBX+EAX*4],ESI
* 005C7142 5E POP ESI
* 005C7143 5D POP EBP
* 005C7144 B0 01 MOV AL,0x1
* 005C7146 5B POP EBX
* 005C7147 8B4C24 14 MOV ECX,DWORD PTR SS:[ESP+0x14]
* 005C714B 33CC XOR ECX,ESP
* 005C714D E8 B3500C00 CALL .0068C205
* 005C7152 83C4 18 ADD ESP,0x18
* 005C7155 C2 0C00 RETN 0xC
* 005C7158 8B5B 08 MOV EBX,DWORD PTR DS:[EBX+0x8]
* 005C715B 5F POP EDI
* 005C715C 893483 MOV DWORD PTR DS:[EBX+EAX*4],ESI
* 005C715F 5E POP ESI
* 005C7160 5D POP EBP
* 005C7161 B0 01 MOV AL,0x1
* 005C7163 5B POP EBX
* 005C7164 8B4C24 14 MOV ECX,DWORD PTR SS:[ESP+0x14]
* 005C7168 33CC XOR ECX,ESP
* 005C716A E8 96500C00 CALL .0068C205
* 005C716F 83C4 18 ADD ESP,0x18
* 005C7172 C2 0C00 RETN 0xC
* 005C7175 F3:0F104424 10 MOVSS XMM0,DWORD PTR SS:[ESP+0x10]
* 005C717B 51 PUSH ECX
* 005C717C 8B4C24 34 MOV ECX,DWORD PTR SS:[ESP+0x34]
* 005C7180 8BC3 MOV EAX,EBX
* 005C7182 F3:0F110424 MOVSS DWORD PTR SS:[ESP],XMM0
* 005C7187 E8 14C7FFFF CALL .005C38A0
* 005C718C 84C0 TEST AL,AL
* 005C718E 0F85 B2010000 JNZ .005C7346
* 005C7194 5F POP EDI
* 005C7195 5E POP ESI
* 005C7196 5D POP EBP
* 005C7197 32C0 XOR AL,AL
* 005C7199 5B POP EBX
* 005C719A 8B4C24 14 MOV ECX,DWORD PTR SS:[ESP+0x14]
* 005C719E 33CC XOR ECX,ESP
* 005C71A0 E8 60500C00 CALL .0068C205
* 005C71A5 83C4 18 ADD ESP,0x18
* 005C71A8 C2 0C00 RETN 0xC
* 005C71AB 8B4C24 30 MOV ECX,DWORD PTR SS:[ESP+0x30]
* 005C71AF 8D5424 10 LEA EDX,DWORD PTR SS:[ESP+0x10]
* 005C71B3 52 PUSH EDX
* 005C71B4 8BC3 MOV EAX,EBX
* 005C71B6 E8 25C7FFFF CALL .005C38E0
* 005C71BB 84C0 TEST AL,AL
* 005C71BD ^74 D5 JE SHORT .005C7194
* 005C71BF 8B4C24 10 MOV ECX,DWORD PTR SS:[ESP+0x10]
* 005C71C3 8BC7 MOV EAX,EDI
* 005C71C5 E8 D6F0FFFF CALL .005C62A0
* 005C71CA 8BD8 MOV EBX,EAX
* 005C71CC 8BCE MOV ECX,ESI
* 005C71CE 8BC7 MOV EAX,EDI
* 005C71D0 E8 CBF0FFFF CALL .005C62A0
* 005C71D5 85DB TEST EBX,EBX
* 005C71D7 ^74 BB JE SHORT .005C7194
* 005C71D9 85C0 TEST EAX,EAX
* 005C71DB ^74 B7 JE SHORT .005C7194
* 005C71DD 50 PUSH EAX
* 005C71DE 8BC3 MOV EAX,EBX
* 005C71E0 E8 2BCFFFFF CALL .005C4110 ; original function call
* //005C71E0 E9 482F1400 JMP .0070A12D ; jichi: here hookpoint#3, text is modified here, text in [[esp]+0x8]], length in [esp]+0xc
* 005C71E5 ^EB A5 JMP SHORT .005C718C
* 005C71E7 8B47 08 MOV EAX,DWORD PTR DS:[EDI+0x8]
* 005C71EA 8B4F 0C MOV ECX,DWORD PTR DS:[EDI+0xC]
* 005C71ED 2BC8 SUB ECX,EAX
* 005C71EF C1F9 02 SAR ECX,0x2
* 005C71F2 3BF1 CMP ESI,ECX
* 005C71F4 ^73 9E JNB SHORT .005C7194
* 005C71F6 8B34B0 MOV ESI,DWORD PTR DS:[EAX+ESI*4]
* 005C71F9 85F6 TEST ESI,ESI
* 005C71FB ^74 97 JE SHORT .005C7194
*
* 005B640E CC INT3
* 005B640F CC INT3
* 005B6410 53 PUSH EBX
* 005B6411 56 PUSH ESI
* 005B6412 B9 FCFFFFFF MOV ECX,-0x4
* 005B6417 57 PUSH EDI
* 005B6418 8BF8 MOV EDI,EAX
* 005B641A 018F B0020000 ADD DWORD PTR DS:[EDI+0x2B0],ECX
* 005B6420 8B87 B0020000 MOV EAX,DWORD PTR DS:[EDI+0x2B0]
* 005B6426 8B30 MOV ESI,DWORD PTR DS:[EAX]
* 005B6428 018F B0020000 ADD DWORD PTR DS:[EDI+0x2B0],ECX
* 005B642E 8B87 B0020000 MOV EAX,DWORD PTR DS:[EDI+0x2B0]
* 005B6434 8B08 MOV ECX,DWORD PTR DS:[EAX]
* 005B6436 8B87 E0010000 MOV EAX,DWORD PTR DS:[EDI+0x1E0]
* 005B643C 2B87 DC010000 SUB EAX,DWORD PTR DS:[EDI+0x1DC]
* 005B6442 C1F8 02 SAR EAX,0x2
* 005B6445 3BF0 CMP ESI,EAX
* 005B6447 73 0D JNB SHORT .005B6456
* 005B6449 8B87 DC010000 MOV EAX,DWORD PTR DS:[EDI+0x1DC]
* 005B644F 8B14B0 MOV EDX,DWORD PTR DS:[EAX+ESI*4]
* 005B6452 85D2 TEST EDX,EDX
* 005B6454 75 13 JNZ SHORT .005B6469
* 005B6456 68 70757200 PUSH .00727570
* 005B645B 8BCF MOV ECX,EDI
* 005B645D E8 AEC9FFFF CALL .005B2E10
* 005B6462 83C4 04 ADD ESP,0x4
* 005B6465 5F POP EDI
* 005B6466 5E POP ESI
* 005B6467 5B POP EBX
* 005B6468 C3 RETN
* 005B6469 8B9F E0010000 MOV EBX,DWORD PTR DS:[EDI+0x1E0]
* 005B646F 2BD8 SUB EBX,EAX
* 005B6471 C1FB 02 SAR EBX,0x2
* 005B6474 3BCB CMP ECX,EBX
* 005B6476 73 07 JNB SHORT .005B647F
* 005B6478 8B0488 MOV EAX,DWORD PTR DS:[EAX+ECX*4]
* 005B647B 85C0 TEST EAX,EAX
* 005B647D 75 14 JNZ SHORT .005B6493
* 005B647F 51 PUSH ECX
* 005B6480 68 A0757200 PUSH .007275A0
* 005B6485 8BCF MOV ECX,EDI
* 005B6487 E8 84C9FFFF CALL .005B2E10
* 005B648C 83C4 08 ADD ESP,0x8
* 005B648F 5F POP EDI
* 005B6490 5E POP ESI
* 005B6491 5B POP EBX
* 005B6492 C3 RETN
* 005B6493 52 PUSH EDX
* 005B6494 E8 77DC0000 CALL .005C4110
* //005B6494 E9 103D1500 JMP .0070A1A9 ; jichi: here hookpoint#4
* 005B6499 84C0 TEST AL,AL
* 005B649B 75 16 JNZ SHORT .005B64B3
* 005B649D 68 D4757200 PUSH .007275D4
* 005B64A2 B9 F0757200 MOV ECX,.007275F0 ; ASCII "S_ASSIGN"
* 005B64A7 E8 84C8FFFF CALL .005B2D30
* 005B64AC 83C4 04 ADD ESP,0x4
* 005B64AF 5F POP EDI
* 005B64B0 5E POP ESI
* 005B64B1 5B POP EBX
* 005B64B2 C3 RETN
* 005B64B3 8B8F B0020000 MOV ECX,DWORD PTR DS:[EDI+0x2B0]
* 005B64B9 8931 MOV DWORD PTR DS:[ECX],ESI
* 005B64BB 8387 B0020000 04 ADD DWORD PTR DS:[EDI+0x2B0],0x4
* 005B64C2 5F POP EDI
* 005B64C3 5E POP ESI
* 005B64C4 5B POP EBX
* 005B64C5 C3 RETN
* 005B64C6 CC INT3
* 005B64C7 CC INT3
* 005B64C8 CC INT3
*
* Slightly modified #4 in AliceRunPatch.dll
* 101B6C10 5B POP EBX
* 101B6C11 59 POP ECX
* 101B6C12 C3 RETN
* 101B6C13 52 PUSH EDX
* 101B6C14 8BC1 MOV EAX,ECX
* 101B6C16 E9 4E7D1600 JMP .1031E969 ; jichi: hook here
* 101B6C1B 84C0 TEST AL,AL
* 101B6C1D 75 18 JNZ SHORT .101B6C37
* 101B6C1F 68 FCB53310 PUSH .1033B5FC
* 101B6C24 B9 18B63310 MOV ECX,.1033B618 ; ASCII "S_ASSIGN"
* 101B6C29 E8 92B8FFFF CALL .101B24C0
* 101B6C2E 83C4 04 ADD ESP,0x4
* 101B6C31 5F POP EDI
* 101B6C32 5E POP ESI
* 101B6C33 5D POP EBP
* 101B6C34 5B POP EBX
* 101B6C35 59 POP ECX
* 101B6C36 C3 RETN
* 101B6C37 53 PUSH EBX
* 101B6C38 56 PUSH ESI
* 101B6C39 E8 E29C0100 CALL .101D0920
* 101B6C3E 5F POP EDI
* 101B6C3F 5E POP ESI
* 101B6C40 5D POP EBP
* 101B6C41 5B POP EBX
* 101B6C42 59 POP ECX
* 101B6C43 C3 RETN
* 101B6C44 CC INT3
* 101B6C45 CC INT3
* 101B6C46 CC INT3
*
* The function get called to paint string of names for hookpoint #2, text in arg1:
* 0050B69E CC INT3
* 0050B69F CC INT3
* 0050B6A0 55 PUSH EBP
* 0050B6A1 8BEC MOV EBP,ESP
* 0050B6A3 83E4 F8 AND ESP,0xFFFFFFF8
* 0050B6A6 6A FF PUSH -0x1
* 0050B6A8 68 F8277000 PUSH .007027F8
* 0050B6AD 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
* 0050B6B3 50 PUSH EAX
* 0050B6B4 83EC 18 SUB ESP,0x18
* 0050B6B7 53 PUSH EBX
* 0050B6B8 56 PUSH ESI
* 0050B6B9 57 PUSH EDI
* 0050B6BA A1 DCC47700 MOV EAX,DWORD PTR DS:[0x77C4DC]
* 0050B6BF 33C4 XOR EAX,ESP
* 0050B6C1 50 PUSH EAX
* 0050B6C2 8D4424 28 LEA EAX,DWORD PTR SS:[ESP+0x28]
* 0050B6C6 64:A3 00000000 MOV DWORD PTR FS:[0],EAX
* 0050B6CC 8BF9 MOV EDI,ECX
* 0050B6CE 57 PUSH EDI
* 0050B6CF E8 5CEAFFFF CALL .0050A130
* 0050B6D4 8B45 08 MOV EAX,DWORD PTR SS:[EBP+0x8]
* 0050B6D7 6A FF PUSH -0x1
* 0050B6D9 33DB XOR EBX,EBX
* 0050B6DB 53 PUSH EBX
* 0050B6DC 8DB7 E4000000 LEA ESI,DWORD PTR DS:[EDI+0xE4]
* 0050B6E2 50 PUSH EAX
* 0050B6E3 E8 886BEFFF CALL .00402270
* 0050B6E8 895C24 14 MOV DWORD PTR SS:[ESP+0x14],EBX
* 0050B6EC 895C24 18 MOV DWORD PTR SS:[ESP+0x18],EBX
* 0050B6F0 895C24 1C MOV DWORD PTR SS:[ESP+0x1C],EBX
* 0050B6F4 56 PUSH ESI
* 0050B6F5 8D4C24 18 LEA ECX,DWORD PTR SS:[ESP+0x18]
* 0050B6F9 51 PUSH ECX
* 0050B6FA 57 PUSH EDI
* 0050B6FB 895C24 3C MOV DWORD PTR SS:[ESP+0x3C],EBX
* 0050B6FF E8 6C290000 CALL .0050E070
* 0050B704 8D5424 14 LEA EDX,DWORD PTR SS:[ESP+0x14]
* 0050B708 8BCF MOV ECX,EDI
* 0050B70A E8 B1010000 CALL .0050B8C0
* 0050B70F 8B7424 14 MOV ESI,DWORD PTR SS:[ESP+0x14]
* 0050B713 C687 E0000000 01 MOV BYTE PTR DS:[EDI+0xE0],0x1
* 0050B71A 3BF3 CMP ESI,EBX
* 0050B71C 74 14 JE SHORT .0050B732
* 0050B71E 8B7C24 18 MOV EDI,DWORD PTR SS:[ESP+0x18]
* 0050B722 8BC6 MOV EAX,ESI
* 0050B724 E8 7751F0FF CALL .004108A0
* 0050B729 56 PUSH ESI
* 0050B72A E8 5C101800 CALL .0068C78B
* 0050B72F 83C4 04 ADD ESP,0x4
* 0050B732 8B4C24 28 MOV ECX,DWORD PTR SS:[ESP+0x28]
* 0050B736 64:890D 00000000 MOV DWORD PTR FS:[0],ECX
* 0050B73D 59 POP ECX
* 0050B73E 5F POP EDI
* 0050B73F 5E POP ESI
* 0050B740 5B POP EBX
* 0050B741 8BE5 MOV ESP,EBP
* 0050B743 5D POP EBP
* 0050B744 C2 0400 RETN 0x4
* 0050B747 CC INT3
* 0050B748 CC INT3
* 0050B749 CC INT3
* 0050B74A CC INT3
* 0050B74B CC INT3
* 0050B74C CC INT3
*
* Function get called for hookpoint #3, text in [arg1+0x10], length in arg1+0xc, only for scenario, function call is looped
* 005C410D CC INT3
* 005C410E CC INT3
* 005C410F CC INT3
* 005C4110 53 PUSH EBX
* 005C4111 8B5C24 08 MOV EBX,DWORD PTR SS:[ESP+0x8]
* 005C4115 837B 0C 00 CMP DWORD PTR DS:[EBX+0xC],0x0
* 005C4119 56 PUSH ESI
* 005C411A 57 PUSH EDI
* 005C411B 8BF0 MOV ESI,EAX
* 005C411D 74 07 JE SHORT .005C4126
* 005C411F 8B43 08 MOV EAX,DWORD PTR DS:[EBX+0x8]
* 005C4122 85C0 TEST EAX,EAX
* 005C4124 75 04 JNZ SHORT .005C412A
* 005C4126 33C0 XOR EAX,EAX
* 005C4128 EB 0F JMP SHORT .005C4139
* 005C412A 8D50 01 LEA EDX,DWORD PTR DS:[EAX+0x1]
* 005C412D 8D49 00 LEA ECX,DWORD PTR DS:[ECX]
* 005C4130 8A08 MOV CL,BYTE PTR DS:[EAX]
* 005C4132 40 INC EAX
* 005C4133 84C9 TEST CL,CL
* 005C4135 ^75 F9 JNZ SHORT .005C4130
* 005C4137 2BC2 SUB EAX,EDX
* 005C4139 8D78 01 LEA EDI,DWORD PTR DS:[EAX+0x1]
* 005C413C 3B7E 0C CMP EDI,DWORD PTR DS:[ESI+0xC]
* 005C413F 76 0F JBE SHORT .005C4150
* 005C4141 E8 FAF7FFFF CALL .005C3940
* 005C4146 84C0 TEST AL,AL
* 005C4148 75 06 JNZ SHORT .005C4150
* 005C414A 5F POP EDI
* 005C414B 5E POP ESI
* 005C414C 5B POP EBX
* 005C414D C2 0400 RETN 0x4
* 005C4150 837B 0C 00 CMP DWORD PTR DS:[EBX+0xC],0x0
* 005C4154 75 04 JNZ SHORT .005C415A
* 005C4156 33C9 XOR ECX,ECX
* 005C4158 EB 03 JMP SHORT .005C415D
* 005C415A 8B4B 08 MOV ECX,DWORD PTR DS:[EBX+0x8]
* 005C415D 837E 0C 00 CMP DWORD PTR DS:[ESI+0xC],0x0
* 005C4161 75 15 JNZ SHORT .005C4178
* 005C4163 57 PUSH EDI
* 005C4164 33C0 XOR EAX,EAX
* 005C4166 51 PUSH ECX
* 005C4167 50 PUSH EAX
* 005C4168 E8 33400D00 CALL .006981A0
* 005C416D 83C4 0C ADD ESP,0xC
* 005C4170 5F POP EDI
* 005C4171 5E POP ESI
* 005C4172 B0 01 MOV AL,0x1
* 005C4174 5B POP EBX
* 005C4175 C2 0400 RETN 0x4
* 005C4178 8B46 08 MOV EAX,DWORD PTR DS:[ESI+0x8]
* 005C417B 57 PUSH EDI
* 005C417C 51 PUSH ECX
* 005C417D 50 PUSH EAX
* 005C417E E8 1D400D00 CALL .006981A0
* 005C4183 83C4 0C ADD ESP,0xC
* 005C4186 5F POP EDI
* 005C4187 5E POP ESI
* 005C4188 B0 01 MOV AL,0x1
* 005C418A 5B POP EBX
* 005C418B C2 0400 RETN 0x4
* 005C418E CC INT3
*/
static bool InsertSystem43NewHook(ULONG startAddress, ULONG stopAddress, LPCSTR hookName)
{
const BYTE bytes[] = {
0xe8, XX4, // 004eeb34 e8 67cb0100 call .0050b6a0 ; jichi: hook here, text on the top of the stack
0x39,0x6c,0x24, 0x28, // 004eeb39 396c24 28 cmp dword ptr ss:[esp+0x28],ebp
0x72, 0x0d, // 004eeb3d 72 0d jb short .004eeb4c
0x8b,0x4c,0x24, 0x14, // 004eeb3f 8b4c24 14 mov ecx,dword ptr ss:[esp+0x14]
0x51, // 004eeb43 51 push ecx
0xe8 //, XX4, // 004eeb44 e8 42dc1900 call .0068c78b
};
enum { addr_offset = 0 };
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
//GROWL_DWORD(addr);
if (!addr) {
ConsoleOutput("System43+: pattern not found");
return false;
}
//addr = *(DWORD *)(addr+1) + addr + 5; // change to hook to the actual address of function being called
HookParam hp;
hp.address = addr;
hp.type = NO_CONTEXT|USING_STRING|USING_SPLIT|SPLIT_INDIRECT;
//hp.type = NO_CONTEXT|USING_STRING|FIXING_SPLIT;
hp.split_index = 0x10; // use [[esp]+0x10] to differentiate name and thread
// Only name can be modified here, where the value of split is 0x6, and text in 0x2
ConsoleOutput("INSERT System43+");
ConsoleOutput("System43+: disable GDI hooks"); // disable hooking to TextOutA, which is cached
return NewHook(hp, hookName);
}
bool System43New2Filter(LPVOID data, size_t *size, HookParam *)
{
auto text = reinterpret_cast<LPSTR>(data);
auto len = reinterpret_cast<size_t *>(size);
CharReplacer(text, len, '\n', ' ');
if (cpp_strnstr(text, "${", *len)) {
StringFilterBetween(text, len, "${", 3, "}", 1);
}
return true;
}
bool InsertSystem43New2Hook()
{
/*
* Sample games:
* https://vndb.org/r84067
*/
const BYTE bytes[] = {
0xC7, 0x46, 0x10, XX4, // mov [esi+10],00000000
0x72, 0x02, // jb dohnadohna.exe+1BFA7E
0x8B, 0x36, // mov esi,[esi]
0x8B, 0x4C, 0x24, 0x14, // mov ecx,[esp+14]
0x57, // push edi
0xC6, 0x06, 0x00 // mov byte ptr [esi],00 << hook here
};
enum { addr_offset = sizeof(bytes) - 3 };
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) {
ConsoleOutput("System43new: pattern not found");
return false;
}
HookParam hp;
hp.address = addr + addr_offset;
hp.offset=get_reg(regs::edx);
hp.split = get_reg(regs::esp);
hp.type = NO_CONTEXT | USING_STRING | USING_SPLIT;
hp.filter_fun = System43New2Filter;
ConsoleOutput("INSERT System43new");
return NewHook(hp, "System43new");
}
bool InsertSystem43Hook()
{
if (InsertSystem43New2Hook())
return true;
//bool patched = Util::CheckFile(L"AliceRunPatch.dll");
bool patched = ::GetModuleHandleA("AliceRunPatch.dll");
// Insert new hook first
bool ok = InsertSystem43OldHook(processStartAddress, processStopAddress, patched ? "AliceRunPatch43" : "System43");
ok = InsertSystem43NewHook(processStartAddress, processStopAddress, "System43+") || ok;
return ok;
}
namespace { // unnamed
struct TextArgument // first argument of the scenario hook
{
ULONG *unknown[2];
LPCSTR text;
int size; // text data size including '\0', length = size - 1
int capacity;
ULONG split;
bool isValid() const
{
return size <= capacity && size >= 4 && text && ::strlen(text) + 1 == size // skip translating single text
//&& !Util::allAscii(text)
&& (UINT8)text[0] > 127 && (UINT8)text[size - 3] > 127 // skip text beginning / ending with ascii
&& !::strstr(text, "\x81\x5e"); // ""
}
};
enum : UINT64 { djb2_hash0 = 5381 };
inline UINT64 djb2(const UINT8 *str, UINT64 hash = djb2_hash0)
{
UINT8 c;
while ((c = *str++))
hash = ((hash << 5) + hash) + c; // hash * 33 + c
return hash;
}inline UINT64 djb2_n2(const char* str, size_t len, UINT64 hash = djb2_hash0)
{
while (len--)
hash = ((hash << 5) + hash) + (*str++); // hash * 33 + c
return hash;
}
inline UINT64 hashByteArraySTD(const std::string& b, UINT64 h = djb2_hash0)
{
return djb2_n2(b.c_str(), b.size(), h);
}
inline UINT64 hashCharArray(const void *lp)
{ return djb2(reinterpret_cast<const UINT8 *>(lp)); }
namespace ScenarioHook {
namespace Private {
bool isOtherText(LPCSTR text)
{
static const char *s[] = {
"\x82\xa2\x82\xa2\x82\xa6" /* いいえ */
, "\x82\xcd\x82\xa2" /* はい */
};
for (int i = 0; i < sizeof(s)/sizeof(*s); i++)
if (::strcmp(text, s[i]) == 0)
return true;
return false;
}
TextArgument *arg_,
argValue_;
/**
* Sample game: Rance03
*
* Caller that related to load/save, which is the only caller get kept:
* 005C68A7 8B86 74010000 MOV EAX,DWORD PTR DS:[ESI+0x174]
* 005C68AD 8B1CA8 MOV EBX,DWORD PTR DS:[EAX+EBP*4]
* 005C68B0 85DB TEST EBX,EBX
* 005C68B2 74 63 JE SHORT Rance03T.005C6917
* 005C68B4 8B86 78010000 MOV EAX,DWORD PTR DS:[ESI+0x178]
* 005C68BA 2B86 74010000 SUB EAX,DWORD PTR DS:[ESI+0x174]
* 005C68C0 C1F8 02 SAR EAX,0x2
* 005C68C3 3BD0 CMP EDX,EAX
* 005C68C5 73 3C JNB SHORT Rance03T.005C6903
* 005C68C7 8B86 74010000 MOV EAX,DWORD PTR DS:[ESI+0x174]
* 005C68CD 8B0C90 MOV ECX,DWORD PTR DS:[EAX+EDX*4]
* 005C68D0 85C9 TEST ECX,ECX
* 005C68D2 74 2F JE SHORT Rance03T.005C6903
* 005C68D4 53 PUSH EBX
* 005C68D5 -E9 26976B09 JMP 09C80000 ; jichi: called
* 005C68DA 84C0 TEST AL,AL
* 005C68DC 75 18 JNZ SHORT Rance03T.005C68F6
* 005C68DE 68 94726E00 PUSH Rance03T.006E7294
* 005C68E3 68 00736E00 PUSH Rance03T.006E7300 ; ASCII "S_ASSIGN"
* 005C68E8 56 PUSH ESI
* 005C68E9 E8 12BBFFFF CALL Rance03T.005C2400
* 005C68EE 83C4 0C ADD ESP,0xC
* 005C68F1 5F POP EDI
* 005C68F2 5E POP ESI
*
* Caller of the scenario thread:
*
* 005D6F80 ^74 BE JE SHORT Rance03T.005D6F40
* 005D6F82 85C0 TEST EAX,EAX
* 005D6F84 ^74 BA JE SHORT Rance03T.005D6F40
* 005D6F86 50 PUSH EAX
* 005D6F87 8BCF MOV ECX,EDI
* 005D6F89 -E9 72907009 JMP 09CE0000 ; jichi: called here
* 005D6F8E ^EB A8 JMP SHORT Rance03T.005D6F38
* 005D6F90 8B46 0C MOV EAX,DWORD PTR DS:[ESI+0xC]
* 005D6F93 2B46 08 SUB EAX,DWORD PTR DS:[ESI+0x8]
* 005D6F96 C1F8 02 SAR EAX,0x2
* 005D6F99 3BD8 CMP EBX,EAX
* 005D6F9B ^73 A3 JNB SHORT Rance03T.005D6F40
* 005D6F9D 8B46 08 MOV EAX,DWORD PTR DS:[ESI+0x8]
* 005D6FA0 8B1C98 MOV EBX,DWORD PTR DS:[EAX+EBX*4]
*/
std::unordered_set<uint64_t> hashes_;
void hookafter2(hook_stack*s,void* data, size_t len){
auto newData =std::string((char*)data,len);
static std::string data_;
data_ = newData;
auto arg = (TextArgument *)s->stack[0]; // arg1
arg_ = arg;
argValue_ = *arg;
arg->text = data_.c_str();
arg->size = data_.size() + 1;
arg->capacity = arg->size;
hashes_.insert(hashCharArray(arg->text));
}
bool hookBefore(hook_stack*s,void* data, size_t* len1,uintptr_t*role)
{
static std::string data_; // persistent storage, which makes this function not thread-safe
//auto split = s->stack[5]; // parent function return address
//auto split = s->stack[10]; // parent's parent function return address
//auto split = *(DWORD *)(s->ecx + 0x10);
auto split = *(DWORD *)(s->ecx + 0x34);
//auto split = *(DWORD *)(s->ecx + 0x48);
// 005C68DA 84C0 TEST AL,AL
//if (*(WORD *)retaddr == 0xc084) // otherwise system text will be translated
// return true;
//if (*(WORD *)retaddr != 0xc084) // only translate one caller
// return true;
// 005D6F8E ^EB A8 JMP SHORT Rance03T.005D6F38
//if (*(WORD *)retaddr != 0xa8eb) // this function has 7 callers, and only one is kept
// return true;
if (split > 0xff || split && split < 0xf)
return false;
auto arg = (TextArgument *)s->stack[0]; // arg1
if (!arg || !arg->isValid()
|| hashes_.find(hashCharArray(arg->text)) != hashes_.end())
return false;
if (arg->size < 0xf && split > 0 && !isOtherText(arg->text))
return false;
//auto sig = Engine::hashThreadSignature(role, split);
//auto role = Engine::OtherRole;
* role = Engine::OtherRole;
if (!isOtherText(arg->text)) {
if (split == 0 && arg->size <= 0x10)
*role = Engine::NameRole;
else if (split >= 2 && split <= 0x14 && split != 3 && split != 0xb || split == 0x22)
*role = Engine::ScenarioRole;
}
2024-03-21 17:57:04 +08:00
write_string_overwrite(data,len1,arg->text);
2024-02-07 20:59:24 +08:00
return true;
}
bool hookAfter(hook_stack*s,void* data, size_t* len1,uintptr_t*role)
{
if (arg_) {
*arg_ = argValue_;
arg_ = nullptr;
}
return false;
}
} // namespace Private
/**
* Sample game: Rance03
*
* Function that is similar to memcpy, found by debugging where game text get modified:
*
* 0069D84F CC INT3
* 0069D850 57 PUSH EDI
* 0069D851 56 PUSH ESI
* 0069D852 8B7424 10 MOV ESI,DWORD PTR SS:[ESP+0x10]
* 0069D856 8B4C24 14 MOV ECX,DWORD PTR SS:[ESP+0x14]
* 0069D85A 8B7C24 0C MOV EDI,DWORD PTR SS:[ESP+0xC]
* 0069D85E 8BC1 MOV EAX,ECX
* 0069D860 8BD1 MOV EDX,ECX
* 0069D862 03C6 ADD EAX,ESI
* 0069D864 3BFE CMP EDI,ESI
* 0069D866 76 08 JBE SHORT Rance03T.0069D870
* 0069D868 3BF8 CMP EDI,EAX
* 0069D86A 0F82 68030000 JB Rance03T.0069DBD8
* 0069D870 0FBA25 5CC97500 >BT DWORD PTR DS:[0x75C95C],0x1
* 0069D878 73 07 JNB SHORT Rance03T.0069D881
* 0069D87A F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
* 0069D87C E9 17030000 JMP Rance03T.0069DB98
* 0069D881 81F9 80000000 CMP ECX,0x80
* 0069D887 0F82 CE010000 JB Rance03T.0069DA5B
* 0069D88D 8BC7 MOV EAX,EDI
* 0069D88F 33C6 XOR EAX,ESI
* 0069D891 A9 0F000000 TEST EAX,0xF
* 0069D896 75 0E JNZ SHORT Rance03T.0069D8A6
* 0069D898 0FBA25 10A47400 >BT DWORD PTR DS:[0x74A410],0x1
* 0069D8A0 0F82 DA040000 JB Rance03T.0069DD80
* 0069D8A6 0FBA25 5CC97500 >BT DWORD PTR DS:[0x75C95C],0x0
* 0069D8AE 0F83 A7010000 JNB Rance03T.0069DA5B
* 0069D8B4 F7C7 03000000 TEST EDI,0x3
* 0069D8BA 0F85 B8010000 JNZ Rance03T.0069DA78
* 0069D8C0 F7C6 03000000 TEST ESI,0x3
* 0069D8C6 0F85 97010000 JNZ Rance03T.0069DA63
* 0069D8CC 0FBAE7 02 BT EDI,0x2
* 0069D8D0 73 0D JNB SHORT Rance03T.0069D8DF
* 0069D8D2 8B06 MOV EAX,DWORD PTR DS:[ESI]
* 0069D8D4 83E9 04 SUB ECX,0x4
* 0069D8D7 8D76 04 LEA ESI,DWORD PTR DS:[ESI+0x4]
* 0069D8DA 8907 MOV DWORD PTR DS:[EDI],EAX
* 0069D8DC 8D7F 04 LEA EDI,DWORD PTR DS:[EDI+0x4]
* 0069D8DF 0FBAE7 03 BT EDI,0x3
* 0069D8E3 73 11 JNB SHORT Rance03T.0069D8F6
* 0069D8E5 F3: PREFIX REP: ; Superfluous prefix
* 0069D8E6 0F7E0E MOVD DWORD PTR DS:[ESI],MM1
* 0069D8E9 83E9 08 SUB ECX,0x8
* 0069D8EC 8D76 08 LEA ESI,DWORD PTR DS:[ESI+0x8]
* 0069D8EF 66:0FD6 ??? ; Unknown command
* 0069D8F2 -0F8D 7F08F7C6 JGE C760E177
* 0069D8F8 07 POP ES ; Modification of segment register
* 0069D8F9 0000 ADD BYTE PTR DS:[EAX],AL
* 0069D8FB 007463 0F ADD BYTE PTR DS:[EBX+0xF],DH
* 0069D8FF BA E6030F83 MOV EDX,0x830F03E6
* 0069D904 B2 00 MOV DL,0x0
* 0069D906 0000 ADD BYTE PTR DS:[EAX],AL
* 0069D908 66:0F6F4E F4 MOVQ MM1,QWORD PTR DS:[ESI-0xC]
* 0069D90D 8D76 F4 LEA ESI,DWORD PTR DS:[ESI-0xC]
* 0069D910 66:0F6F5E 10 MOVQ MM3,QWORD PTR DS:[ESI+0x10]
* 0069D915 83E9 30 SUB ECX,0x30
* 0069D918 66:0F6F46 20 MOVQ MM0,QWORD PTR DS:[ESI+0x20]
* 0069D91D 66:0F6F6E 30 MOVQ MM5,QWORD PTR DS:[ESI+0x30]
* 0069D922 8D76 30 LEA ESI,DWORD PTR DS:[ESI+0x30]
* 0069D925 83F9 30 CMP ECX,0x30
* 0069D928 66:0F6FD3 MOVQ MM2,MM3
* 0069D92C 66:0F3A ??? ; Unknown command
* 0069D92F 0FD90C66 PSUBUSW MM1,QWORD PTR DS:[ESI]
* 0069D933 0F7F1F MOVQ QWORD PTR DS:[EDI],MM3
* 0069D936 66:0F6FE0 MOVQ MM4,MM0
* 0069D93A 66:0F3A ??? ; Unknown command
* 0069D93D 0FC20C66 0F CMPPS XMM1,DQWORD PTR DS:[ESI],0xF
* 0069D942 7F 47 JG SHORT Rance03T.0069D98B
* 0069D944 1066 0F ADC BYTE PTR DS:[ESI+0xF],AH
* 0069D947 6F OUTS DX,DWORD PTR ES:[EDI] ; I/O command
* 0069D948 CD 66 INT 0x66
* 0069D94A 0F3A ??? ; Unknown command
* 0069D94C 0FEC0C66 PADDSB MM1,QWORD PTR DS:[ESI]
* 0069D950 0F7F6F 20 MOVQ QWORD PTR DS:[EDI+0x20],MM5
* 0069D954 8D7F 30 LEA EDI,DWORD PTR DS:[EDI+0x30]
* 0069D957 ^7D B7 JGE SHORT Rance03T.0069D910
* 0069D959 8D76 0C LEA ESI,DWORD PTR DS:[ESI+0xC]
* 0069D95C E9 AF000000 JMP Rance03T.0069DA10
* 0069D961 66:0F6F4E F8 MOVQ MM1,QWORD PTR DS:[ESI-0x8]
* 0069D966 8D76 F8 LEA ESI,DWORD PTR DS:[ESI-0x8]
* 0069D969 8D49 00 LEA ECX,DWORD PTR DS:[ECX]
* 0069D96C 66:0F6F5E 10 MOVQ MM3,QWORD PTR DS:[ESI+0x10]
* 0069D971 83E9 30 SUB ECX,0x30
* 0069D974 66:0F6F46 20 MOVQ MM0,QWORD PTR DS:[ESI+0x20]
* 0069D979 66:0F6F6E 30 MOVQ MM5,QWORD PTR DS:[ESI+0x30]
* 0069D97E 8D76 30 LEA ESI,DWORD PTR DS:[ESI+0x30]
* 0069D981 83F9 30 CMP ECX,0x30
* 0069D984 66:0F6FD3 MOVQ MM2,MM3
* 0069D988 66:0F3A ??? ; Unknown command
* 0069D98B 0FD908 PSUBUSW MM1,QWORD PTR DS:[EAX]
* 0069D98E 66:0F7F1F MOVQ QWORD PTR DS:[EDI],MM3
* 0069D992 66:0F6FE0 MOVQ MM4,MM0
* 0069D996 66:0F3A ??? ; Unknown command
* 0069D999 0FC208 66 CMPPS XMM1,DQWORD PTR DS:[EAX],0x66
* 0069D99D 0F7F47 10 MOVQ QWORD PTR DS:[EDI+0x10],MM0
* 0069D9A1 66:0F6FCD MOVQ MM1,MM5
* 0069D9A5 66:0F3A ??? ; Unknown command
* 0069D9A8 0FEC08 PADDSB MM1,QWORD PTR DS:[EAX]
* 0069D9AB 66:0F7F6F 20 MOVQ QWORD PTR DS:[EDI+0x20],MM5
* 0069D9B0 8D7F 30 LEA EDI,DWORD PTR DS:[EDI+0x30]
* 0069D9B3 ^7D B7 JGE SHORT Rance03T.0069D96C
* 0069D9B5 8D76 08 LEA ESI,DWORD PTR DS:[ESI+0x8]
* 0069D9B8 EB 56 JMP SHORT Rance03T.0069DA10
* 0069D9BA 66:0F6F4E FC MOVQ MM1,QWORD PTR DS:[ESI-0x4]
* 0069D9BF 8D76 FC LEA ESI,DWORD PTR DS:[ESI-0x4]
* 0069D9C2 8BFF MOV EDI,EDI
* 0069D9C4 66:0F6F5E 10 MOVQ MM3,QWORD PTR DS:[ESI+0x10]
* 0069D9C9 83E9 30 SUB ECX,0x30
* 0069D9CC 66:0F6F46 20 MOVQ MM0,QWORD PTR DS:[ESI+0x20]
* 0069D9D1 66:0F6F6E 30 MOVQ MM5,QWORD PTR DS:[ESI+0x30]
* 0069D9D6 8D76 30 LEA ESI,DWORD PTR DS:[ESI+0x30]
* 0069D9D9 83F9 30 CMP ECX,0x30
* 0069D9DC 66:0F6FD3 MOVQ MM2,MM3
* 0069D9E0 66:0F3A ??? ; Unknown command
* 0069D9E3 0FD90466 PSUBUSW MM0,QWORD PTR DS:[ESI]
* 0069D9E7 0F7F1F MOVQ QWORD PTR DS:[EDI],MM3
* 0069D9EA 66:0F6FE0 MOVQ MM4,MM0
* 0069D9EE 66:0F3A ??? ; Unknown command
* 0069D9F1 0FC20466 0F CMPPS XMM0,DQWORD PTR DS:[ESI],0xF
* 0069D9F6 7F 47 JG SHORT Rance03T.0069DA3F
* 0069D9F8 1066 0F ADC BYTE PTR DS:[ESI+0xF],AH
* 0069D9FB 6F OUTS DX,DWORD PTR ES:[EDI] ; I/O command
* 0069D9FC CD 66 INT 0x66
* 0069D9FE 0F3A ??? ; Unknown command
* 0069DA00 0FEC0466 PADDSB MM0,QWORD PTR DS:[ESI]
* 0069DA04 0F7F6F 20 MOVQ QWORD PTR DS:[EDI+0x20],MM5
* 0069DA08 8D7F 30 LEA EDI,DWORD PTR DS:[EDI+0x30]
* 0069DA0B ^7D B7 JGE SHORT Rance03T.0069D9C4
* 0069DA0D 8D76 04 LEA ESI,DWORD PTR DS:[ESI+0x4]
* 0069DA10 83F9 10 CMP ECX,0x10
* 0069DA13 7C 13 JL SHORT Rance03T.0069DA28
* 0069DA15 F3: PREFIX REP: ; Superfluous prefix
* 0069DA16 0F6F0E MOVQ MM1,QWORD PTR DS:[ESI]
* 0069DA19 83E9 10 SUB ECX,0x10
* 0069DA1C 8D76 10 LEA ESI,DWORD PTR DS:[ESI+0x10]
* 0069DA1F 66:0F7F0F MOVQ QWORD PTR DS:[EDI],MM1
* 0069DA23 8D7F 10 LEA EDI,DWORD PTR DS:[EDI+0x10]
* 0069DA26 ^EB E8 JMP SHORT Rance03T.0069DA10
* 0069DA28 0FBAE1 02 BT ECX,0x2
* 0069DA2C 73 0D JNB SHORT Rance03T.0069DA3B
* 0069DA2E 8B06 MOV EAX,DWORD PTR DS:[ESI]
* 0069DA30 83E9 04 SUB ECX,0x4
* 0069DA33 8D76 04 LEA ESI,DWORD PTR DS:[ESI+0x4]
* 0069DA36 8907 MOV DWORD PTR DS:[EDI],EAX
* 0069DA38 8D7F 04 LEA EDI,DWORD PTR DS:[EDI+0x4]
* 0069DA3B 0FBAE1 03 BT ECX,0x3
* 0069DA3F 73 11 JNB SHORT Rance03T.0069DA52
* 0069DA41 F3: PREFIX REP: ; Superfluous prefix
* 0069DA42 0F7E0E MOVD DWORD PTR DS:[ESI],MM1
* 0069DA45 83E9 08 SUB ECX,0x8
* 0069DA48 8D76 08 LEA ESI,DWORD PTR DS:[ESI+0x8]
* 0069DA4B 66:0FD6 ??? ; Unknown command
* 0069DA4E -0F8D 7F088B04 JGE 04F4E2D3
* 0069DA54 8D88 DB6900FF LEA ECX,DWORD PTR DS:[EAX+0xFF0069DB]
* 0069DA5A ^E0 F7 LOOPDNE SHORT Rance03T.0069DA53
* 0069DA5C C703 00000075 MOV DWORD PTR DS:[EBX],0x75000000
* 0069DA62 15 C1E90283 ADC EAX,0x8302E9C1
* 0069DA67 E2 03 LOOPD SHORT Rance03T.0069DA6C
* 0069DA69 83F9 08 CMP ECX,0x8
* 0069DA6C 72 2A JB SHORT Rance03T.0069DA98
* 0069DA6E F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI>
* 0069DA70 FF2495 88DB6900 JMP DWORD PTR DS:[EDX*4+0x69DB88]
* 0069DA77 90 NOP
*
* 0012F810 0B4D3F30
* 0012F814 06128970
* 0012F818 005D3E12 RETURN to Rance03T.005D3E12 from Rance03T.0069D850
* 0012F81C 06160B98 ; jichi: target text
* 0012F820 07F8CA80 ; jichi: source text
* 0012F824 00000017 ; jichi: size including \0
* 0012F828 00384460
* 0012F82C 00384240
* 0012F830 0B4D3F30
* 0012F834 005C68DA RETURN to Rance03T.005C68DA from Rance03T.005D3D90
* 0012F838 0B4D3F30
* 0012F83C 0012FAA8
* 0012F840 00384240
* 0012F844 0012F85C
* 0012F848 0012FF18
* 0012F84C 005C1693 RETURN to Rance03T.005C1693 from Rance03T.005C6870
* 0012F850 0012FAA8
* 0012F854 00384240
* 0012F858 0000000F
* 0012F85C /0012FF3C
*
* Actual hooked function:
* 005D3D8B CC INT3
* 005D3D8C CC INT3
* 005D3D8D CC INT3
* 005D3D8E CC INT3
* 005D3D8F CC INT3
* 005D3D90 53 PUSH EBX
* 005D3D91 56 PUSH ESI
* 005D3D92 8B7424 0C MOV ESI,DWORD PTR SS:[ESP+0xC]
* 005D3D96 57 PUSH EDI
* 005D3D97 8BF9 MOV EDI,ECX
* 005D3D99 837E 0C 00 CMP DWORD PTR DS:[ESI+0xC],0x0
* 005D3D9D 74 1C JE SHORT Rance03T.005D3DBB
* 005D3D9F 8B56 08 MOV EDX,DWORD PTR DS:[ESI+0x8]
* 005D3DA2 85D2 TEST EDX,EDX
* 005D3DA4 74 15 JE SHORT Rance03T.005D3DBB
* 005D3DA6 8D4A 01 LEA ECX,DWORD PTR DS:[EDX+0x1]
* 005D3DA9 8DA424 00000000 LEA ESP,DWORD PTR SS:[ESP]
* 005D3DB0 8A02 MOV AL,BYTE PTR DS:[EDX]
* 005D3DB2 42 INC EDX
* 005D3DB3 84C0 TEST AL,AL
* 005D3DB5 ^75 F9 JNZ SHORT Rance03T.005D3DB0
* 005D3DB7 2BD1 SUB EDX,ECX
* 005D3DB9 EB 02 JMP SHORT Rance03T.005D3DBD
* 005D3DBB 33D2 XOR EDX,EDX
* 005D3DBD 8D5A 01 LEA EBX,DWORD PTR DS:[EDX+0x1]
* 005D3DC0 3B5F 0C CMP EBX,DWORD PTR DS:[EDI+0xC]
* 005D3DC3 76 1A JBE SHORT Rance03T.005D3DDF
* 005D3DC5 53 PUSH EBX
* 005D3DC6 8D4F 04 LEA ECX,DWORD PTR DS:[EDI+0x4]
* 005D3DC9 C747 0C 00000000 MOV DWORD PTR DS:[EDI+0xC],0x0
* 005D3DD0 E8 DB700700 CALL Rance03T.0064AEB0
* 005D3DD5 84C0 TEST AL,AL
* 005D3DD7 75 06 JNZ SHORT Rance03T.005D3DDF
* 005D3DD9 5F POP EDI
* 005D3DDA 5E POP ESI
* 005D3DDB 5B POP EBX
* 005D3DDC C2 0400 RETN 0x4
* 005D3DDF 837E 0C 00 CMP DWORD PTR DS:[ESI+0xC],0x0
* 005D3DE3 75 04 JNZ SHORT Rance03T.005D3DE9
* 005D3DE5 33C9 XOR ECX,ECX
* 005D3DE7 EB 03 JMP SHORT Rance03T.005D3DEC
* 005D3DE9 8B4E 08 MOV ECX,DWORD PTR DS:[ESI+0x8]
* 005D3DEC 837F 0C 00 CMP DWORD PTR DS:[EDI+0xC],0x0
* 005D3DF0 75 15 JNZ SHORT Rance03T.005D3E07
* 005D3DF2 53 PUSH EBX
* 005D3DF3 33C0 XOR EAX,EAX
* 005D3DF5 51 PUSH ECX
* 005D3DF6 50 PUSH EAX
* 005D3DF7 E8 549A0C00 CALL Rance03T.0069D850
* 005D3DFC 83C4 0C ADD ESP,0xC
* 005D3DFF B0 01 MOV AL,0x1
* 005D3E01 5F POP EDI
* 005D3E02 5E POP ESI
* 005D3E03 5B POP EBX
* 005D3E04 C2 0400 RETN 0x4
* 005D3E07 8B47 08 MOV EAX,DWORD PTR DS:[EDI+0x8]
* 005D3E0A 53 PUSH EBX
* 005D3E0B 51 PUSH ECX
* 005D3E0C 50 PUSH EAX
* 005D3E0D -E9 EEC1A201 JMP 02000000 ; jichi: called here
* 005D3E12 83C4 0C ADD ESP,0xC
* 005D3E15 B0 01 MOV AL,0x1
* 005D3E17 5F POP EDI
* 005D3E18 5E POP ESI
* 005D3E19 5B POP EBX
* 005D3E1A C2 0400 RETN 0x4
* 005D3E1D CC INT3
* 005D3E1E CC INT3
* 005D3E1F CC INT3
*
* Arg1 of this function:
* 07B743F8 90 7A 70 00 F4 87 70 00 70 0E 27 08 1B 00 00 00 p.p.p'...
* 07B74408 20 00 00 00 02 00 00 00 01 00 00 00 CC 7F 2D 00 .........-.
* 07B74418 B3 52 41 00 FF FF FF FF EC 87 70 00 10 E3 1D 08 RA.p.
*
* Caller that preserved:
* 005C68A7 8B86 74010000 MOV EAX,DWORD PTR DS:[ESI+0x174]
* 005C68AD 8B1CA8 MOV EBX,DWORD PTR DS:[EAX+EBP*4]
* 005C68B0 85DB TEST EBX,EBX
* 005C68B2 74 63 JE SHORT Rance03T.005C6917
* 005C68B4 8B86 78010000 MOV EAX,DWORD PTR DS:[ESI+0x178]
* 005C68BA 2B86 74010000 SUB EAX,DWORD PTR DS:[ESI+0x174]
* 005C68C0 C1F8 02 SAR EAX,0x2
* 005C68C3 3BD0 CMP EDX,EAX
* 005C68C5 73 3C JNB SHORT Rance03T.005C6903
* 005C68C7 8B86 74010000 MOV EAX,DWORD PTR DS:[ESI+0x174]
* 005C68CD 8B0C90 MOV ECX,DWORD PTR DS:[EAX+EDX*4]
* 005C68D0 85C9 TEST ECX,ECX
* 005C68D2 74 2F JE SHORT Rance03T.005C6903
* 005C68D4 53 PUSH EBX
* 005C68D5 E8 B6D40000 CALL Rance03T.005D3D90 ; jichi: called
* 005C68DA 84C0 TEST AL,AL ; jichi: retaddr
* 005C68DC 75 18 JNZ SHORT Rance03T.005C68F6
* 005C68DE 68 94726E00 PUSH Rance03T.006E7294
* 005C68E3 68 00736E00 PUSH Rance03T.006E7300 ; ASCII "S_ASSIGN"
* 005C68E8 56 PUSH ESI
* 005C68E9 E8 12BBFFFF CALL Rance03T.005C2400
* 005C68EE 83C4 0C ADD ESP,0xC
* 005C68F1 5F POP EDI
* 005C68F2 5E POP ESI
*/
bool attach(ULONG startAddress, ULONG stopAddress)
{
const uint8_t bytes[] = {
0x53, // 005D3D90 53 PUSH EBX
0x56, // 005D3D91 56 PUSH ESI
0x8B,0x74,0x24, 0x0C, // 005D3D92 8B7424 0C MOV ESI,DWORD PTR SS:[ESP+0xC]
0x57, // 005D3D96 57 PUSH EDI
0x8B,0xF9, // 005D3D97 8BF9 MOV EDI,ECX
0x83,0x7E, 0x0C, 0x00, // 005D3D99 837E 0C 00 CMP DWORD PTR DS:[ESI+0xC],0x0
0x74, 0x1C, // 005D3D9D 74 1C JE SHORT Rance03T.005D3DBB
0x8B,0x56, 0x08, // 005D3D9F 8B56 08 MOV EDX,DWORD PTR DS:[ESI+0x8]
0x85,0xD2, // 005D3DA2 85D2 TEST EDX,EDX
0x74, 0x15, // 005D3DA4 74 15 JE SHORT Rance03T.005D3DBB
0x8D,0x4A, 0x01, // 005D3DA6 8D4A 01 LEA ECX,DWORD PTR DS:[EDX+0x1]
0x8D,0xA4,0x24, 0x00,0x00,0x00,0x00, // 005D3DA9 8DA424 00000000 LEA ESP,DWORD PTR SS:[ESP]
0x8A,0x02, // 005D3DB0 8A02 MOV AL,BYTE PTR DS:[EDX]
0x42, // 005D3DB2 42 INC EDX
0x84,0xC0 // 005D3DB3 84C0 TEST AL,AL
};
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), startAddress, stopAddress);
if (!addr)
return false;
//addr = MemDbg::findEnclosingAlignedFunction(addr);
//if (!addr)
// return false;
//addr = 0x005D3D90;
//return winhook::hook_before(addr, Private::hookBefore);
int count = 0;
auto fun = [&count](ULONG addr) -> bool {
auto retaddr = addr + 5;
// 005C68DA 84C0 TEST AL,AL
if (*(WORD *)retaddr == 0xc084)
//auto before = std::bind(Private::hookBefore, addr + 5, std::placeholders::_1);
count +=1;
HookParam hp;
hp.address=addr;
hp.type=EMBED_ABLE|EMBED_DYNA_SJIS;
hp.hook_before=Private::hookBefore;
hp.hook_after=Private::hookafter2;
auto succ=NewHook(hp,"EmbedSysmtem44");
hp.address=addr+5;
hp.hook_before=Private::hookAfter;
succ|=NewHook(hp,"EmbedSysmtem44");
return succ; // replace all functions
};
MemDbg::iterNearCallAddress(fun, addr, startAddress, stopAddress);
return count;
}
} // namespace ScenarioHook
} // unnamed namespace
bool attachSystem44(ULONG startAddress, ULONG stopAddress)
{ return ScenarioHook::attach(startAddress, stopAddress); }
namespace { // unnamed
// - Search -
ULONG searchScenarioAddress(ULONG startAddress, ULONG stopAddress)
{
const uint8_t bytes[] = {
0xe8, XX4, // 005c71e0 e8 2bcfffff call .005c4110 ; original function call
0xeb, 0xa5, // 005c71e5 ^eb a5 jmp short .005c718c
0x8b,0x47, 0x08, // 005c71e7 8b47 08 mov eax,dword ptr ds:[edi+0x8]
0x8b,0x4f, 0x0c // 005c71ea 8b4f 0c mov ecx,dword ptr ds:[edi+0xc]
};
return MemDbg::findBytes(bytes, sizeof(bytes), startAddress, stopAddress);
}
ULONG searchNameAddress(ULONG startAddress, ULONG stopAddress)
{
const uint8_t bytes[] = {
0xe8, XX4, // 004eeb34 e8 67cb0100 call .0050b6a0 ; jichi: hook here
0x39,0x6c,0x24, 0x28, // 004eeb39 396c24 28 cmp dword ptr ss:[esp+0x28],ebp
0x72, 0x0d, // 004eeb3d 72 0d jb short .004eeb4c
0x8b,0x4c,0x24, 0x14, // 004eeb3f 8b4c24 14 mov ecx,dword ptr ss:[esp+0x14]
0x51, // 004eeb43 51 push ecx
0xe8 //, XX4, // 004eeb44 e8 42dc1900 call .0068c78b
};
return MemDbg::findBytes(bytes, sizeof(bytes), startAddress, stopAddress);
}
ULONG searchOtherAddress(ULONG startAddress, ULONG stopAddress)
{
const char *pattern = "S_ASSIGN";
const uint8_t bytes[] = {
//0xc3, // 005b6492 c3 retn
//0x52, // 005b6493 52 push edx
0xe8, XX4, // 005b6494 e8 77dc0000 call .005c4110 ; jichi: hook here
0x84,0xc0, // 005b6499 84c0 test al,al
0x75, XX, // 005b649b 75 16 jnz short .005b64b3
0x68, XX4, // 005b649d 68 d4757200 push .007275d4
0xb9 //, XX4, // 005b64a2 b9 f0757200 mov ecx,.007275f0 ; ascii "S_ASSIGN"
//0xe8, XX4 // 005b64a7 e8 84c8ffff call .005b2d30
};
for (ULONG addr = startAddress; addr < stopAddress;) {
addr = MemDbg::findBytes(bytes, sizeof(bytes), addr, stopAddress);
if (!addr)
return 0;
addr += sizeof(bytes);
DWORD ecx = *(DWORD *)addr;
if (::strcmp((LPCSTR)ecx, pattern) == 0)
return addr - sizeof(bytes);
};
return 0;
}
// - Hook -
struct TextHookBase
{
struct TextArgument // first argument of the scenario hook
{
DWORD unknown1,
unknown2;
LPCSTR text;
DWORD size; // text data size, length = size - 1
//DWORD split; // not a good split to distinguish translable text out
};
bool enabled_,
editable_; // for debugging only, whether text is not read-only
std::string buffer_; // persistent storage, which makes this function not thread-safe
TextArgument *arg_; // last argument
LPCSTR text_; // last text
DWORD size_; // last size
TextHookBase()
: enabled_(true)
, editable_(true)
, arg_(nullptr)
, text_(nullptr)
, size_(0)
{}
};
class ScenarioHook43 : protected TextHookBase
{
public:
bool hookBefore(hook_stack*s,void* data, size_t* len,uintptr_t*role)
{
// See ATcode patch:
// 0070A12E 8B87 B0000000 MOV EAX,DWORD PTR DS:[EDI+0xB0]
// 0070A134 66:8138 8400 CMP WORD PTR DS:[EAX],0x84
// 0070A139 75 0E JNZ SHORT .0070A149
// 0070A13B 8378 EA 5B CMP DWORD PTR DS:[EAX-0x16],0x5B
// 0070A13F 75 08 JNZ SHORT .0070A149
DWORD split = *(WORD *)(s->edi + 0xb0);
if (split && split != 0x27f2) // new System43 after Evenicle
return false;
if (!split) { // old System43 before Evenicle where edi split is zero
split = s->stack[1];
if (split != 0x84)
return false;
// Stack structure observed from 武想少女隊
// 0012F4BC 07EAFD48 ; text address
// 0012F4C0 000002EC ; use this value as split
// 0012F4C4 00000011
// 0012F4C8 0012F510
// 0012F4CC 00000012
// 0012F4D0 00001BAA
// 0012F4D4 00000012
// 0012F4D8 06D2E24C
// 0012F4DC 00581125 RETURN to .00581125 from .0057DC30
//if (s->stack[1] != 0x84)
// return true;
//if (s->stack[2] != 0x3)
// return true;
}
auto arg = (TextArgument *)s->stack[0]; // top of the stack
LPCSTR text = arg->text;
if (arg->size <= 1 || !text || !*text || all_ascii(text))
return false;
*role = Engine::ScenarioRole ;
2024-03-21 17:57:04 +08:00
return write_string_overwrite(data,len,text);
2024-02-07 20:59:24 +08:00
}
bool hookAfter(hook_stack*s,void* data, size_t* len,uintptr_t*role)
{
if (arg_) {
arg_->text = text_;
arg_->size = size_;
arg_ = nullptr;
}
return true;
}
};
class OtherHook43 : protected TextHookBase
{
public:
bool hookBefore(hook_stack*s,void* data, size_t* len,uintptr_t*role)
{
if (!enabled_)
return false;
DWORD splitBase = *(DWORD *)(s->edi + 0x284); // [edi + 0x284]
if (!Engine::isAddressReadable(splitBase)) {
enabled_ = false;
return false;
}
DWORD split1 = *(WORD *)(splitBase - 0x4), // word [[edi + 0x284] - 0x4]
split2 = *(WORD *)(splitBase - 0x8); // word [[edi + 0x284] - 0x8]
enum : WORD { OtherSplit = 0x46 }; // 0x440046 if use dword split
if (split1 != OtherSplit || split2 <= 2) // split internal system messages
return false;
auto arg = (TextArgument *)s->stack[0]; // top of the stack
// auto g = EngineController::instance();
LPCSTR text = arg->text;
if (arg->size <= 1 || !text || !*text || all_ascii(text))
return false;
2024-03-21 17:57:04 +08:00
return write_string_overwrite(data,len,text);
2024-02-07 20:59:24 +08:00
}
bool hookAfter(hook_stack*s,void* data, size_t* len,uintptr_t*role)
{
if (arg_) {
arg_->text = text_;
arg_->size = size_;
arg_ = nullptr;
}
return false;
}
};
// Text with fixed size
bool fixedTextHook(hook_stack*s,void* data, size_t* len,uintptr_t*role)
{
enum { FixedSize = 0x10 };
struct FixedArgument // first argument of the name hook
{
char text[FixedSize]; // 0x10
DWORD type, // [[esp]+0x10]
type2; // [[esp]+0x14]
};
auto arg = (FixedArgument *)s->stack[0];
if (arg->type2 != 0xf) // non 0xf is garbage text
return false;
char *text = arg->text;
if (!text || !*text || all_ascii(text))
return false;
* role;
long sig;
if (arg->type == 0x6 || arg->type == 0xc) {
*role = Engine::NameRole;
} else if (::strlen(text) <= 2) // skip translating very short other text
return false;
else {
*role = Engine::OtherRole;
}
2024-03-21 17:57:04 +08:00
return write_string_overwrite(data,len,text);
2024-02-07 20:59:24 +08:00
}
} // unnamed namespace
bool attachSystem43(ULONG startAddress, ULONG stopAddress)
{
//太麻煩 放棄。
return false;
{
//ULONG addr = 0x005c71e0;
ULONG addr = ::searchScenarioAddress(startAddress, stopAddress);
if (!addr)
return false;
/* static auto h = new ScenarioHook43; // never deleted
if (!winhook::hook_both(addr,
std::bind(&ScenarioHook43::hookBefore, h, _1),
std::bind(&ScenarioHook43::hookAfter, h, _1)))
return false;
*/
}
/*
if (ULONG addr = ::searchOtherAddress(startAddress, stopAddress)) {
static auto h = new OtherHook; // never deleted
if (!winhook::hook_both(addr,
std::bind(&OtherHook43::hookBefore, h, _1),
std::bind(&OtherHook43::hookAfter, h, _1)))
DOUT("other text NOT FOUND");
else
DOUT("other text address" << QString::number(addr, 16));
}
if (ULONG addr = ::searchNameAddress(startAddress, stopAddress)) {
if (winhook::hook_before(addr, ::fixedTextHook))
DOUT("name text address" << QString::number(addr, 16));
else
DOUT("name text NOT FOUND");
}
*/
//HijackManager::instance()->attachFunction((ULONG)::MultiByteToWideChar);
return true;
}
namespace{
bool system4X(ULONG startAddress, ULONG stopAddress){
if (attachSystem43(startAddress, stopAddress)) {
return true;
} else if (attachSystem44(startAddress, stopAddress)) {
return true;
} else
return false;
}
}
namespace{
bool System42Filter(LPVOID data, size_t *size, HookParam *)
{
auto text = reinterpret_cast<LPSTR>(data);
auto len = reinterpret_cast<size_t *>(size);
if (*len == 1)
return false;
if (all_ascii(text, *len)) {
CharReplacer(text, len, '`', ' ');
CharReplacer(text, len, '\x7D', '-');
}
return true;
}
bool InsertSystem42Hook() {
/*
* Sample games:
* https://vndb.org/v1427
*/
const BYTE bytes[] = {
0x8B, 0x46, 0x04, // mov eax,[esi+04]
0x57, // push edi
0x52, // push edx
0x50, // push eax
0xE8, XX4 // call Sys42VM.DLL+4B5B0
};
HMODULE module = GetModuleHandleW(L"Sys42VM.dll");
auto [minAddress, maxAddress] = Util::QueryModuleLimits(module);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), minAddress, maxAddress);
if (!addr)
return false;
HookParam hp;
hp.address = addr;
hp.offset=get_reg(regs::edx);
hp.split =get_reg(regs::esp);
hp.type = NO_CONTEXT | USING_STRING | USING_SPLIT;
hp.filter_fun = System42Filter;
ConsoleOutput("INSERT System42");
return NewHook(hp, "System42");
}
}
bool System4x::attach_function() {
if (Util::CheckFile(L"DLL/Sys42VM.dll"))
if (InsertSystem42Hook())
return true;
auto _=system4X(processStartAddress,processStopAddress);
return InsertSystem43Hook()||_;
}