Th14/Binary hacks

From Touhou Patch Center
Jump to navigation Jump to search

Bugs

Fix buffer overflow in spell name rendering (replace pointer)
(buffer_overflow_spell)
Description The strcpy is replaced by spell_align; this replaces the pointer accordingly.
Address
v0.01a0x47a7a4
v0.01b0x47a2f4
v1.00a0x47de24
v1.00b0x47dd24
Code
8b45 20
90
mov eax, [ebp+0x20]
nop
Safe sprintf (short, call)
(sprintf_call)
Address
v0.01b0x47a159, 0x47a379
v1.00a0x47dc89, 0x47dea9
v1.00b0x47db89, 0x47dda9
Code
50
e8 [strings_vsprintf]
8944e4 34
push eax
call [strings_vsprintf]
mov dword ptr ss:[esp+0x34],eax
Safe sprintf (long, call)
(sprintf_long_call)
Address
v1.00b0x40bb2e, 0x40bdde
Code
50
e8 [strings_vsprintf]
8985 fcfeffff
push eax
call [strings_vsprintf]
mov dword ptr ss:[ebp-0x104],eax
Safe sprintf (short, replace pointer)
(sprintf_rep)
Address
v0.01b0x47a1c8, 0x47a40b
v1.00a0x47dcf8, 0x47df3b
v1.00b0x47dbf8, 0x47de3b
Code
8b44e4 28
mov eax,dword ptr ss:[esp+0x28]
Safe sprintf (long, replace pointer)
(sprintf_long_rep)
Address
v1.00b0x40bb3d, 0x40bded
Code
8b
mov ???,dword ptr ss:[ebp-

Logging

Restore the game's built-in logging
(log_restore)
Description Very useful for debugging.
Address
v0.01b0x4075d0
v1.00b0x4075c0
Code
e9 [log_printf]
jmp [log_printf]

Textbox size

Correct text length calculation for the DDC variety of Fairy Wars-style text boxes
(ddc_textbox_size)
Description In theory, this is the same hack as for th128..

However, th14 starts to use MMX instructions to calculate the size of the text box... and for some reason, thcrap's GetTextExtent clears out the xmm2 register containing the multiplication factor, resulting a box with "length zero".

After removing that unnecessary strlen(), we end up with plenty of space to read the value for xmm2 back from the original, constant position in memory.

This also leaves space for another fix. In case the text length calculation results in a width smaller than 28 pixels (this happens for example with Hime's "You!"), the original code would create an infinitely long text box, due to the width being treated as unsigned. Thus, we clear out eax in this case.
Address
v0.01a0x431590, 0x4317b0
v0.01b0x430b70, 0x430d98
Code
53
e8 [GetTextExtent]
f30f1015 
v0.01ad0ea4b00
v0.01bb8e64b00
v1.00a882e4c00
83e8 1c 73 03 31c0 90
push ebx
call [GetTextExtent]
movss xmm2,dword ptr ds:[th14.4bead0]
sub eax,1ch
jae +3
xor eax,eax
nop
Correct text length calculation for the DDC variety of Fairy Wars-style text boxes
(ddc_textbox_size_full)
Description Same hack as for the trial, just using xmm1 instead.
Address
v1.00a0x4327f0, 0x4329e7
v1.00b0x4327f0, 0x4329e7
Code
53
e8 [GetTextExtent]
f30f100d 
v1.00a882e4c00
v1.00b781a4c00
83e8 1c 73 03 31c0 90
push ebx
call [GetTextExtent]
movss xmm1,dword ptr ds:[th14.4c2e88]
sub eax,1ch
jae +3
xor eax,eax
nop

Spells

Prepare deferred spell name fetching
(spell_name_fetch)
Address
v0.01a0x41cc0b
v0.01b0x41cd7b
v1.00a0x41cefb
v1.00b0x41cefb
Code
8b4d 0c
51
31c9
51
51
51
mov ecx, dword ptr ss:[ebp+0c]
push ecx                       ; insert breakpoint here
xor ecx
push ecx
push ecx
push ecx
Spell card alignment
(spell_align)
Description Kill the strcpy (buffer overflow) and strlen, shift up/optimize part of the original code (because less code is always better), and fudge around so that it looks nice. Fairly straightforward.
Address
v0.01a0x47a6f2
v0.01b0x47a242
v1.00a0x47dd72
v1.00b0x47dc72
Code
8b45 1c
8d1c00
8b46 1c
c1e8 0b
83e0 01
8944e4 14
ff35 
v0.01a3c8f4f00
v0.01b209d4f00
v1.00afcf54f00
v1.00b1cd64f00
ff75 20 e8 [GetTextExtentForFont] 83c0 08 d1e0 8b56 2c eb 1e 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
mov eax, dword ptr ss:[ebp+1c]
lea ebx, [eax+eax]
mov eax, dword ptr ds:[esi+1c]
shr eax, 0b
and eax, 00000001
mov dword ptr ss:[esp+14], eax
push dword ptr ds:[th14.font_spell] ; spell font
push dword ptr ss:[ebp+20]
call [GetTextExtentForFont]
add eax, 8
shl eax, 1
mov edx, dword ptr ds:[esi+2c]
jmp short +0x1e
nop (*0x1e)

Player data

Remove spell "alignment" in the result screen
(result_spell_align)
Description For some reason, ZUN feels the need to do some alignment calculations based on the string length. Why.
Address
v0.01b0x47a3ac
v1.00a0x47dedc
v1.00b0x47dddc
Code
8944e4 14
8b43 08
31d2
eb 19
90 90 90 90 90
90 90 90 90 90
90 90 90 90 90
90 90 90 90 90
90 90 90 90 90
mov dword ptr ss:[esp+0x14], eax
mov eax,dword ptr ds:[ebx+8]
xor edx,edx
jmp short +0x19
nop (*0x19)

Music Room

Prepare music room title fetching
(music_title_prepare)
Description Oh no, a constant memory address. -.-
Address
v1.00b0x46235d
Code
8b4ce4 1c
51
31c0
50
50
50
50
68 ffffff00
56
ff35 cc564f00
90
mov ecx,dword ptr ss:[esp+0x1c]
push ecx                          ; insert breakpoint here
xor eax,eax                       ; eax = theme number
push eax                          ; ecx = theme string
push eax
push eax
push eax
push 0xffffff
push esi
push dword ptr ds:[th14.0x4f56cc]
nop

Workaround for the broken update notification functionality in 2014-01-03

Update notification for 2014-01-03 (jump)
(thcrap_migrate_jump)
Address
v1.00bRx87453
Code
e9 599b0200
jmp th14.004b0fb1
Update notification for 2014-01-03 (check and message)
(thcrap_migrate_msg)
Address
v1.00bRxb0f3c
Code
41206e65772076657273696f6e2028323031342d30312d32372920
6f662074686520257320697320617661696c61626c652e0a
0a
49742063616e20626520646f776e6c6f616465642066726f6d0a
0a
09687474703a2f2f746870617463682e6e65742f
50726f6a6563743a446f776e6c6f616400
00

e8 [PROJECT_VERSION]
3d 27011420
7d 17
e8 [PROJECT_NAME]
50
68 3c0f4b00
6a 40
6a 00
e8 [log_mboxf]
83c4 10

e8 6d1cfeff
e9 7a64fdff
"A new version (2014-01-27) "
"of the %s is available.\n"
"\n"
"It can be downloaded from\n"
"\n"
"	http: //thpatch.net/"
"Project:Download"


call [PROJECT_VERSION]
cmp eax, 0x20140127
jge short +17
call [PROJECT_NAME]
push eax
push th14.004b0f3c
push 40
push 0
call [log_mboxf]
add esp, 10
; Original code below
call th14.00492c46
jmp th14.00487458