LunaHook-mirror/LunaHook/engine32/NeXAS.cpp
恍兮惚兮 06e881ede5 issues/63
2024-06-16 16:34:02 +08:00

343 lines
18 KiB
C++

#include"NeXAS.h"
/** jichi 7/6/2014 NeXAS
* Sample game: BALDRSKYZERO EXTREME
*
* Call graph:
* - GetGlyphOutlineA x 2 functions
* - Caller 503620: char = [arg1 + 0x1a8]
* - Caller: 500039, 4ffff0
* edi = [esi+0x1a0] # stack size 4x3
* arg1 = eax = [edi]
*
* 0050361f cc int3
* 00503620 /$ 55 push ebp
* 00503621 |. 8bec mov ebp,esp
* 00503623 |. 83e4 f8 and esp,0xfffffff8
* 00503626 |. 64:a1 00000000 mov eax,dword ptr fs:[0]
* 0050362c |. 6a ff push -0x1
* 0050362e |. 68 15815900 push bszex.00598115
* 00503633 |. 50 push eax
* 00503634 |. 64:8925 000000>mov dword ptr fs:[0],esp
* 0050363b |. 81ec 78010000 sub esp,0x178
* 00503641 |. 53 push ebx
* 00503642 |. 8b5d 08 mov ebx,dword ptr ss:[ebp+0x8]
* 00503645 |. 80bb ed010000 >cmp byte ptr ds:[ebx+0x1ed],0x0
* 0050364c |. 56 push esi
* 0050364d |. 57 push edi
* 0050364e |. 0f85 6e0b0000 jnz bszex.005041c2
* 00503654 |. 8db3 a8010000 lea esi,dword ptr ds:[ebx+0x1a8]
* 0050365a |. c683 ed010000 >mov byte ptr ds:[ebx+0x1ed],0x1
* 00503661 |. 837e 14 10 cmp dword ptr ds:[esi+0x14],0x10
* 00503665 |. 72 04 jb short bszex.0050366b
* 00503667 |. 8b06 mov eax,dword ptr ds:[esi]
* 00503669 |. eb 02 jmp short bszex.0050366d
* 0050366b |> 8bc6 mov eax,esi
* 0050366d |> 8038 20 cmp byte ptr ds:[eax],0x20
* 00503670 |. 0f84 ef0a0000 je bszex.00504165
* 00503676 |. b9 fcc97400 mov ecx,bszex.0074c9fc
* 0050367b |. 8bfe mov edi,esi
* 0050367d |. e8 2e20f1ff call bszex.004156b0
* 00503682 |. 84c0 test al,al
* 00503684 |. 0f85 db0a0000 jnz bszex.00504165
* 0050368a |. 8b93 38010000 mov edx,dword ptr ds:[ebx+0x138]
* 00503690 |. 33c0 xor eax,eax
* 00503692 |. 3bd0 cmp edx,eax
* 00503694 |. 0f84 8d0a0000 je bszex.00504127
* 0050369a |. 8b8b 3c010000 mov ecx,dword ptr ds:[ebx+0x13c]
* 005036a0 |. 3bc8 cmp ecx,eax
* 005036a2 |. 0f84 7f0a0000 je bszex.00504127
* 005036a8 |. 894424 40 mov dword ptr ss:[esp+0x40],eax
* 005036ac |. 894424 44 mov dword ptr ss:[esp+0x44],eax
* 005036b0 |. 894424 48 mov dword ptr ss:[esp+0x48],eax
* 005036b4 |. 898424 8c01000>mov dword ptr ss:[esp+0x18c],eax
* 005036bb |. 33ff xor edi,edi
* 005036bd |. 66:897c24 60 mov word ptr ss:[esp+0x60],di
* 005036c2 |. bf 01000000 mov edi,0x1
* 005036c7 |. 66:897c24 62 mov word ptr ss:[esp+0x62],di
* 005036cc |. 33ff xor edi,edi
* 005036ce |. 66:897c24 64 mov word ptr ss:[esp+0x64],di
* 005036d3 |. 66:897c24 66 mov word ptr ss:[esp+0x66],di
* 005036d8 |. 66:897c24 68 mov word ptr ss:[esp+0x68],di
* 005036dd |. 66:897c24 6a mov word ptr ss:[esp+0x6a],di
* 005036e2 |. 66:897c24 6c mov word ptr ss:[esp+0x6c],di
* 005036e7 |. bf 01000000 mov edi,0x1
* 005036ec |. 66:897c24 6e mov word ptr ss:[esp+0x6e],di
* 005036f1 |. 894424 0c mov dword ptr ss:[esp+0xc],eax
* 005036f5 |. 894424 10 mov dword ptr ss:[esp+0x10],eax
* 005036f9 |. 3883 ec010000 cmp byte ptr ds:[ebx+0x1ec],al
* 005036ff |. 0f84 39010000 je bszex.0050383e
* 00503705 |. c78424 f000000>mov dword ptr ss:[esp+0xf0],bszex.00780e>
* 00503710 |. 898424 3001000>mov dword ptr ss:[esp+0x130],eax
* 00503717 |. 898424 1001000>mov dword ptr ss:[esp+0x110],eax
* 0050371e |. 898424 1401000>mov dword ptr ss:[esp+0x114],eax
* 00503725 |. c68424 8c01000>mov byte ptr ss:[esp+0x18c],0x1
* 0050372d |. 837e 14 10 cmp dword ptr ds:[esi+0x14],0x10
* 00503731 |. 72 02 jb short bszex.00503735
* 00503733 |. 8b36 mov esi,dword ptr ds:[esi]
* 00503735 |> 51 push ecx
* 00503736 |. 52 push edx
* 00503737 |. 56 push esi
* 00503738 |. 8d8424 ec00000>lea eax,dword ptr ss:[esp+0xec]
* 0050373f |. 68 00ca7400 push bszex.0074ca00 ; ascii "gaiji%s%02d%02d.fil"
* 00503744 |. 50 push eax
* 00503745 |. e8 cec6f7ff call bszex.0047fe18
* 0050374a |. 83c4 14 add esp,0x14
* 0050374d |. 8d8c24 e000000>lea ecx,dword ptr ss:[esp+0xe0]
* 00503754 |. 51 push ecx ; /arg1
* 00503755 |. 8d8c24 9400000>lea ecx,dword ptr ss:[esp+0x94] ; |
* 0050375c |. e8 dfeaefff call bszex.00402240 ; \bszex.00402240
* 00503761 |. 6a 00 push 0x0 ; /arg4 = 00000000
* 00503763 |. 8d9424 9400000>lea edx,dword ptr ss:[esp+0x94] ; |
* 0050376a |. c68424 9001000>mov byte ptr ss:[esp+0x190],0x2 ; |
* 00503772 |. a1 a8a78200 mov eax,dword ptr ds:[0x82a7a8] ; |
* 00503777 |. 52 push edx ; |arg3
* 00503778 |. 50 push eax ; |arg2 => 00000000
* 00503779 |. 8d8c24 fc00000>lea ecx,dword ptr ss:[esp+0xfc] ; |
* 00503780 |. 51 push ecx ; |arg1
* 00503781 |. e8 2a0dfeff call bszex.004e44b0 ; \bszex.004e44b0
* 00503786 |. 84c0 test al,al
* 00503788 |. 8d8c24 9000000>lea ecx,dword ptr ss:[esp+0x90]
* 0050378f |. 0f95c3 setne bl
* 00503792 |. c68424 8c01000>mov byte ptr ss:[esp+0x18c],0x1
* 0050379a |. e8 a1baf1ff call bszex.0041f240
* 0050379f |. 84db test bl,bl
* 005037a1 |. 74 40 je short bszex.005037e3
* 005037a3 |. 8db424 f000000>lea esi,dword ptr ss:[esp+0xf0]
* 005037aa |. e8 6106feff call bszex.004e3e10
* 005037af |. 8bd8 mov ebx,eax
* 005037b1 |. 895c24 0c mov dword ptr ss:[esp+0xc],ebx
* 005037b5 |. e8 5606feff call bszex.004e3e10
* 005037ba |. 8bf8 mov edi,eax
* 005037bc |. 0faffb imul edi,ebx
* 005037bf |. 894424 10 mov dword ptr ss:[esp+0x10],eax
* 005037c3 |. 8bc7 mov eax,edi
* 005037c5 |. 8d7424 40 lea esi,dword ptr ss:[esp+0x40]
* 005037c9 |. e8 e219f1ff call bszex.004151b0
* 005037ce |. 8b5424 40 mov edx,dword ptr ss:[esp+0x40]
* 005037d2 |. 52 push edx ; /arg1
* 005037d3 |. 8bc7 mov eax,edi ; |
* 005037d5 |. 8db424 f400000>lea esi,dword ptr ss:[esp+0xf4] ; |
* 005037dc |. e8 8f03feff call bszex.004e3b70 ; \bszex.004e3b70
* 005037e1 |. eb 10 jmp short bszex.005037f3
* 005037e3 |> 8d8424 e000000>lea eax,dword ptr ss:[esp+0xe0]
* 005037ea |. 50 push eax
* 005037eb |. e8 60c5f2ff call bszex.0042fd50
* 005037f0 |. 83c4 04 add esp,0x4
* 005037f3 |> 8b5c24 10 mov ebx,dword ptr ss:[esp+0x10]
* 005037f7 |. 8b7c24 40 mov edi,dword ptr ss:[esp+0x40]
* 005037fb |. 8bcb mov ecx,ebx
* 005037fd |. 0faf4c24 0c imul ecx,dword ptr ss:[esp+0xc]
* 00503802 |. 33c0 xor eax,eax
* 00503804 |. 85c9 test ecx,ecx
* 00503806 |. 7e 09 jle short bszex.00503811
* 00503808 |> c02c07 02 /shr byte ptr ds:[edi+eax],0x2
* 0050380c |. 40 |inc eax
* 0050380d |. 3bc1 |cmp eax,ecx
* 0050380f |.^7c f7 \jl short bszex.00503808
* 00503811 |> 8b4d 08 mov ecx,dword ptr ss:[ebp+0x8]
* 00503814 |. 33c0 xor eax,eax
* 00503816 |. 8db424 f000000>lea esi,dword ptr ss:[esp+0xf0]
* 0050381d |. 8981 dc010000 mov dword ptr ds:[ecx+0x1dc],eax
* 00503823 |. 8981 e0010000 mov dword ptr ds:[ecx+0x1e0],eax
* 00503829 |. c78424 f000000>mov dword ptr ss:[esp+0xf0],bszex.00780e>
* 00503834 |. e8 4702feff call bszex.004e3a80
* 00503839 |. e9 68010000 jmp bszex.005039a6
* 0050383e |> 8b0d 08a58200 mov ecx,dword ptr ds:[0x82a508]
* 00503844 |. 51 push ecx ; /hwnd => null
* 00503845 |. ff15 d4e26f00 call dword ptr ds:[<&user32.getdc>] ; \getdc
* 0050384b |. 68 50b08200 push bszex.0082b050 ; /facename = ""
* 00503850 |. 6a 00 push 0x0 ; |pitchandfamily = default_pitch|ff_dontcare
* 00503852 |. 6a 02 push 0x2 ; |quality = proof_quality
* 00503854 |. 6a 00 push 0x0 ; |clipprecision = clip_default_precis
* 00503856 |. 6a 07 push 0x7 ; |outputprecision = out_tt_only_precis
* 00503858 |. 68 80000000 push 0x80 ; |charset = 128.
* 0050385d |. 6a 00 push 0x0 ; |strikeout = false
* 0050385f |. 6a 00 push 0x0 ; |underline = false
* 00503861 |. 8bf8 mov edi,eax ; |
* 00503863 |. 8b83 38010000 mov eax,dword ptr ds:[ebx+0x138] ; |
* 00503869 |. 6a 00 push 0x0 ; |italic = false
* 0050386b |. 68 84030000 push 0x384 ; |weight = fw_heavy
* 00503870 |. 99 cdq ; |
* 00503871 |. 6a 00 push 0x0 ; |orientation = 0x0
* 00503873 |. 2bc2 sub eax,edx ; |
* 00503875 |. 8b93 3c010000 mov edx,dword ptr ds:[ebx+0x13c] ; |
* 0050387b |. 6a 00 push 0x0 ; |escapement = 0x0
* 0050387d |. d1f8 sar eax,1 ; |
* 0050387f |. 50 push eax ; |width
* 00503880 |. 52 push edx ; |height
* 00503881 |. ff15 48e06f00 call dword ptr ds:[<&gdi32.createfonta>] ; \createfonta
* 00503887 |. 50 push eax ; /hobject
* 00503888 |. 57 push edi ; |hdc
* 00503889 |. 894424 30 mov dword ptr ss:[esp+0x30],eax ; |
* 0050388d |. ff15 4ce06f00 call dword ptr ds:[<&gdi32.selectobject>>; \selectobject
* 00503893 |. 894424 1c mov dword ptr ss:[esp+0x1c],eax
* 00503897 |. 8d8424 4801000>lea eax,dword ptr ss:[esp+0x148]
* 0050389e |. 50 push eax ; /ptextmetric
* 0050389f |. 57 push edi ; |hdc
* 005038a0 |. ff15 50e06f00 call dword ptr ds:[<&gdi32.gettextmetric>; \gettextmetricsa
* 005038a6 |. 837e 14 10 cmp dword ptr ds:[esi+0x14],0x10
* 005038aa |. 72 02 jb short bszex.005038ae
* 005038ac |. 8b36 mov esi,dword ptr ds:[esi]
* 005038ae |> 56 push esi ; /arg1
* 005038af |. e8 deccf7ff call bszex.00480592 ; \bszex.00480592
* 005038b4 |. 83c4 04 add esp,0x4
* 005038b7 |. 8d4c24 60 lea ecx,dword ptr ss:[esp+0x60]
* 005038bb |. 51 push ecx ; /pmat2
* 005038bc |. 6a 00 push 0x0 ; |buffer = null
* 005038be |. 6a 00 push 0x0 ; |bufsize = 0x0
* 005038c0 |. 8d9424 d800000>lea edx,dword ptr ss:[esp+0xd8] ; |
* 005038c7 |. 52 push edx ; |pmetrics
* 005038c8 |. 6a 06 push 0x6 ; |format = ggo_gray8_bitmap
* 005038ca |. 50 push eax ; |char
* 005038cb |. 57 push edi ; |hdc
* 005038cc |. 894424 30 mov dword ptr ss:[esp+0x30],eax ; |
* 005038d0 |. ff15 54e06f00 call dword ptr ds:[<&gdi32.getglyphoutli>; \getglyphoutlinea
* 005038d6 |. 8bd8 mov ebx,eax
* 005038d8 |. 85db test ebx,ebx
* 005038da |. 0f84 d5070000 je bszex.005040b5
* 005038e0 |. 83fb ff cmp ebx,-0x1
* 005038e3 |. 0f84 cc070000 je bszex.005040b5
* 005038e9 |. 8d7424 40 lea esi,dword ptr ss:[esp+0x40]
* 005038ed |. e8 be18f1ff call bszex.004151b0
* 005038f2 |. 8b4c24 40 mov ecx,dword ptr ss:[esp+0x40]
* 005038f6 |. 8d4424 60 lea eax,dword ptr ss:[esp+0x60]
* 005038fa |. 50 push eax ; /pmat2
* 005038fb |. 8b4424 18 mov eax,dword ptr ss:[esp+0x18] ; |
* 005038ff |. 51 push ecx ; |buffer
* 00503900 |. 53 push ebx ; |bufsize
* 00503901 |. 8d9424 d800000>lea edx,dword ptr ss:[esp+0xd8] ; |
* 00503908 |. 52 push edx ; |pmetrics
* 00503909 |. 6a 06 push 0x6 ; |format = ggo_gray8_bitmap
* 0050390b |. 50 push eax ; |char
* 0050390c |. 57 push edi ; |hdc
* 0050390d |. ff15 54e06f00 call dword ptr ds:[<&gdi32.getglyphoutli>; \getglyphoutlinea
* 00503913 |. 8b4c24 1c mov ecx,dword ptr ss:[esp+0x1c]
* 00503917 |. 51 push ecx ; /hobject
* 00503918 |. 57 push edi ; |hdc
* 00503919 |. ff15 4ce06f00 call dword ptr ds:[<&gdi32.selectobject>>; \selectobject
* 0050391f |. 8b15 08a58200 mov edx,dword ptr ds:[0x82a508]
* 00503925 |. 57 push edi ; /hdc
* 00503926 |. 52 push edx ; |hwnd => null
* 00503927 |. ff15 a4e26f00 call dword ptr ds:[<&user32.releasedc>] ; \releasedc
* 0050392d |. 8b4424 28 mov eax,dword ptr ss:[esp+0x28]
* 00503931 |. 50 push eax ; /hobject
* 00503932 |. ff15 58e06f00 call dword ptr ds:[<&gdi32.deleteobject>>; \deleteobject
* 00503938 |. 8bb424 cc00000>mov esi,dword ptr ss:[esp+0xcc]
* 0050393f |. 8b8c24 d000000>mov ecx,dword ptr ss:[esp+0xd0]
* 00503946 |. 83c6 03 add esi,0x3
* 00503949 |. 81e6 fcff0000 and esi,0xfffc
* 0050394f |. 8bd1 mov edx,ecx
* 00503951 |. 0fafd6 imul edx,esi
* 00503954 |. 897424 0c mov dword ptr ss:[esp+0xc],esi
* 00503958 |. 894c24 10 mov dword ptr ss:[esp+0x10],ecx
* 0050395c |. 3bda cmp ebx,edx
* 0050395e |. 74 1a je short bszex.0050397a
*/
bool InsertNeXASHook()
{
// There are two GetGlyphOutlineA, both of which seem to have the same texts
ULONG addr = MemDbg::findCallAddress((ULONG)::GetGlyphOutlineA, processStartAddress, processStopAddress);
if (!addr) {
ConsoleOutput("NexAS: failed");
return false;
}
// DWORD GetGlyphOutline(
// _In_ HDC hdc,
// _In_ UINT uChar,
// _In_ UINT uFormat,
// _Out_ LPGLYPHMETRICS lpgm,
// _In_ DWORD cbBuffer,
// _Out_ LPVOID lpvBuffer,
// _In_ const MAT2 *lpmat2
// );
HookParam hp;
//hp.address = (DWORD)::GetGlyphOutlineA;
hp.address = addr;
//hp.type = USING_STRING|USING_SPLIT;
hp.type = CODEC_ANSI_BE|NO_CONTEXT|USING_SPLIT;
hp.offset = get_stack(1);
// Either lpgm or lpmat2 are good choices
hp.split = get_stack(3);
//hp.split = arg7_lpmat2; // = 0x18, arg7
ConsoleOutput("INSERT NeXAS");
return NewHook(hp, "NeXAS");
}
namespace {
bool _2(){
//飛ぶ山羊はさかさまの木の夢を見るか
BYTE bs[]={
0x8B,0x56,0x68,
0x8a,0x04,0x3a,
0x8d,0x0c,0x3a,
0x33,0xdb,
0x3c,0x40
};
auto addr=MemDbg::findBytes(bs,sizeof(bs),processStartAddress,processStopAddress);
if(addr==0)return 0;
HookParam hp;
hp.address = addr+9;
hp.type = DATA_INDIRECT;
hp.index=0;
hp.offset=get_reg(regs::ecx);
hp.filter_fun=[](LPVOID data, size_t *size, HookParam *)
{
auto text = reinterpret_cast<LPSTR>(data);
if (text[0] == '@') {
return false;
}
return true;
};
return NewHook(hp, "NeXAS2");
}
}
namespace
{
bool _3(){
//真剣で私に恋しなさい!A-5
char atv[] ="@v";
auto aV=MemDbg::findBytes(atv,sizeof(atv),processStartAddress,processStopAddress);
if(!aV)return false;
aV=MemDbg::findBytes(atv,sizeof(atv),aV+1,processStopAddress);//第一个是历史,第二个才是当前文本
if(!aV)return false;
auto addr=MemDbg::findPushAddress(aV,processStartAddress,processStopAddress);
if(addr==0)return 0;
addr=MemDbg::findEnclosingAlignedFunction(addr);
if(addr==0)return 0;
HookParam hp;
hp.address = addr;
hp.type=USING_STRING;
hp.text_fun=[](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len){
auto a2=(TextUnionA*)stack->stack[1];//std::string*
*data=(DWORD)a2->getText();
*len=strlen(a2->getText());
};
hp.filter_fun=[](void* data, size_t* len, HookParam* hp){
auto s=std::string((char*)data,*len);
if(startWith(s,"@")){
if(startWith(s,"@v")){
//S001_L1_0001
s=std::regex_replace(s, std::regex("@v[a-zA-Z0-9]{4}_[a-zA-Z0-9]{2}_[a-zA-Z0-9]{4}"), "");
return write_string_overwrite(data,len,s);
}
else{
return false;
}
}
return true;
};
hp.newlineseperator=L"@n";
return NewHook(hp, "NeXAS3");
}
}
bool NeXAS::attach_function() {
auto _=_2()||_3();
return InsertNeXASHook()||_;
}