Th09/Binary hacks

From Touhou Patch Center
Jump to: navigation, search

Bugs

Safe sprintf (first call)
(sprintf_call_1)
Address
v1.50a0x43bdde
Code
  1. 50
  2. e8 [strings_vsprintf]
  3. 8945 80
  1. push eax
  2. call [strings_vsprintf]
  3. mov dword ptr ss:[ebp-0x80],eax
Safe sprintf (second call)
(sprintf_call_2)
Address
v1.50a0x43be7d
Code
  1. 50
  2. e8 [strings_vsprintf]
  3. 8945 b8
  1. push eax
  2. call [strings_vsprintf]
  3. mov dword ptr ss:[ebp-0x48],eax
Safe sprintf (replace pointer)
(sprintf_rep)
Address
v1.50a0x43be01, 0x43beb2
Code
  1. 8b
  1. mov ???,dword ptr ss:[ebp-

Music Room

Prepare Music Room title parameter fetching
(music_title_prepare)
Description th09's code optimization certainly was better than those of earlier games, but there's still room for improvement. The original code calculates the same address twice. By optimizing this calculation and spilling the result to the stack, we save 13 bytes - enough to load both the track string and the track number into registers.
Address
v1.50a0x42748a
Code
  1. 8d8c0f dca30100
  2. 51
  3. 53
  4. 51
  5. 8b8e 901b0100
  6. e8 61c9fdff
  7. 59
  8. 8b45 ec
  9. 803c18 00
  10. 74 2b
  11. 8d93 61ffffff
  12. 8b45 f4
  13. 50
  14. 68 80203000
  15. 68 ffe0d000
  16. 90 90 90 90 90 90
  1. lea ecx,[ecx+edi+0x1a3dc]          ; we'll need this address twice
  2. push ecx                           ; spill to stack
  3. push ebx
  4. push ecx
  5. mov ecx,dword ptr ds:[esi+0x11b90] ; yup, this is a function parameter
  6. call th09.00403e00
  7. pop ecx                            ; recover our address to the register expected later
  8. mov eax,dword ptr ss:[ebp-0x14]
  9. cmp byte ptr ds:[ebx+eax],0
  10. je short th09.004274d4
  11. lea edx,[ebx-0x9f]                 ; EDX = track number
  12. mov eax,dword ptr ss:[ebp-0x0c]    ; EAX = string
  13. push eax                           ; insert breakpoint here
  14. push 0x302080
  15. push 0x0d0eff
  16. nop (*6)
Rewrite Music Room comment render calls
(music_cmt_rewrite)
Description Because it would have been completely impossible to add music comment breakpoints to the original function with its 8 case statements, one for each comment line. Turns out that all necessary structure offsets can be easily calculated and the switch statement isn't necessary at all. This removes a total of 391 bytes from the function!
Address
v1.50a0x426e2a
Code
  1. d1e8
  2. 72 06
  3. 48
  4. 83f8 07
  5. 76 05
  6. e9 ee010000
  7. 69f8 a4020000
  8. c68437 029f0100 01
  9. 8dbc37 049d0100
  10. 8b9e 741b0100
  11. 80bb ac814a00 00
  12. 74 19
  13. 6bd0 42
  14. 69cb 92020000
  15. 01ca
  16. 8d8c32 b6c90000
  17. 9090909090
  18. eb 07
  19. 8b0c85 bc1d4a00
  20. 89f8
  21. 51
  22. 31db
  23. e9 87010000
  24. 90909090909090909090909090909090
  25. 90909090909090909090909090909090
  26. 90909090909090909090909090909090
  27. 90909090909090909090909090909090
  28. 90909090909090909090909090909090
  29. 90909090909090909090909090909090
  30. 90909090909090909090909090909090
  31. 90909090909090909090909090909090
  32. 90909090909090909090909090909090
  33. 90909090909090909090909090909090
  34. 90909090909090909090909090909090
  35. 90909090909090909090909090909090
  36. 90909090909090909090909090909090
  37. 90909090909090909090909090909090
  38. 90909090909090909090909090909090
  39. 90909090909090909090909090909090
  40. 90909090909090909090909090909090
  41. 90909090909090909090909090909090
  42. 90909090909090909090909090909090
  43. 90909090909090909090909090909090
  44. 90909090909090909090909090909090
  45. 90909090909090909090909090909090
  46. 90909090909090909090909090909090
  47. 90909090909090909090909090909090
  48. 90909090909090
  1. shr eax,1                                              ; frame / 2
  2. jb short +6                                            ; Only display a line on even frames
  3. dec eax                                                ; EAX = line number
  4. cmp eax,7                                              ; maximum of 8 lines
  5. jbe short +5
  6. jmp +0x1ee                                             ; don't print anything
  7. imul edi,eax,0x2a4                                     ; prepare offset to something
  8. mov byte ptr ds:[esi+edi+0x19f02],1                    ; set something to 1
  9. lea edi,[esi+edi+0x19d04]                              ; EDI = pointer to something
  10. mov ebx,dword ptr ds:[esi+0x11b74]                     ; EBX = track number
  11. cmp byte ptr ds:[ebx+th09.music_unlock_table],0        ; Unlocked?
  12. je short +0x19                                         ; No
  13. imul edx,eax,0x42                                      ; Yes; prepare line offset
  14. imul ecx,ebx,0x292                                     ; prepare track offset
  15. add edx,ecx
  16. lea ecx,[esi+edx+0x0c9b6]                              ; ECX = original string
  17. nop (*5)                                               ; insert breakpoint here
  18. jmp short +7
  19. mov ecx,dword ptr ds:[eax*4+th09.music_spoiler_table]  ; ECX = spoiler message
  20. mov eax,edi                                            ; EAX = pointer to something
  21. push ecx                                               ; Push string
  22. xor ebx,ebx                                            ; reset EBX
  23. jmp +0x187
  24. nop (*0x187)