patch.asm (17861B)
1 ;; %define FONT_BOLDING 2 ;; %define WINDOW_BORDER 3 4 FONT_WEIGHT equ 500 5 ; /* WS_BORDER | WS_DLGFRAME =*/ WS_CAPTION | /*WS_GROUP =*/ WS_MINIMIZEBOX | WS_SYSMENU 6 WINDOW_STYLE equ 0xca0000 7 %ifdef WINDOW_BORDER 8 EXTENDED_STYLE equ 0x20200 ; WS_EX_CLIENTEDGE | WS_EX_STATICEDGE 9 %else 10 EXTENDED_STYLE equ 0 11 %endif 12 13 bits 32 14 cpu 386 15 org 0x400c00 16 incbin "game.exe.orig", 0, 0x6010 17 18 AdjustWindowRectEx equ 0x42d8f0 19 CFrameWnd_ctor equ 0x41de32 20 CreateCompatibleDC equ 0x42d53c 21 CreateFontA equ 0x42d55c 22 DeleteObject equ 0x42d550 23 GetDC equ 0x42d8e0 24 GetGlyphOutlineA equ 0x42d558 25 GetModuleHandleA equ 0x42d5e8 26 GetProcAddress equ 0x42d688 27 GetSystemMetrics equ 0x42d8f4 28 GlobalLock equ 0x42d760 29 GlobalUnlock equ 0x42d75c 30 SelectObject equ 0x42d554 31 __ismbclegal equ 0x40ec00 32 rand equ 0x40dd20 33 34 afx_global_new_like equ 0x41774c 35 copy_buf_to_window equ 0x40abd0 36 create_win_wrap0 equ 0x418fd4 37 font_face equ 0x427504 38 free_like equ 0x41777e 39 norm_float_to_u16fp equ 0x40b3f0 40 41 get_text_metrics_cache equ 0x42ca9c 42 43 create_win_wrap1: 44 mov eax,[fs:0x0] 45 push ebp 46 db 0x8b, 0xec ;mov ebp,esp 47 push byte -0x1 48 push dword 0x406d31 49 push eax 50 mov [dword fs:0x0],esp 51 sub esp,byte +0x1c 52 push ebx 53 push esi 54 mov [ebp-0x20],ecx 55 push edi 56 db 0x8b, 0xf1 ; mov esi,ecx 57 call CFrameWnd_ctor 58 59 mov dword [ebp-0x4],0x0 60 mov dword [esi+0x1c8],0x1 61 mov dword [ebp-0x1c],0x0 62 push dword EXTENDED_STYLE 63 mov dword [esi],0x423080 64 push byte +0x0 65 lea eax,[ebp-0x1c] 66 mov dword [ebp-0x14],0x280 67 mov dword [ebp-0x18],0x0 68 mov dword [ebp-0x10],0x190 69 push dword WINDOW_STYLE 70 push eax 71 call [dword AdjustWindowRectEx] 72 73 mov ebx,[ebp-0x14] 74 mov edi,[ebp-0x10] 75 sub ebx,[ebp-0x1c] 76 sub edi,[ebp-0x18] 77 push byte +0x0 78 call [dword CreateCompatibleDC] 79 80 push byte +0x0 81 call [dword GetSystemMetrics] 82 push byte +0x1 83 mov [ebp-0x24],eax 84 call [dword GetSystemMetrics] 85 86 mov [ebp-0x28],eax 87 call 0x420917 88 89 mov ecx,[eax+0x4] 90 push byte +0x0 91 push byte +0x0 92 mov eax,[ebp-0x28] 93 push byte +0x0 94 db 0x2b, 0xc7 ;sub eax,edi 95 cdq 96 push edi 97 db 0x2b, 0xc2 ; sub eax,edx 98 sar eax,byte 0x1 99 push ebx 100 push eax 101 mov eax,[ebp-0x24] 102 db 0x2b, 0xc3 ;sub eax,ebx 103 cdq 104 db 0x2b, 0xc2 ; sub eax,edx 105 sar eax,byte 0x1 106 push eax 107 push dword WINDOW_STYLE 108 push dword 0x4273e8 109 mov ecx,[ecx+0xc0] 110 push ecx 111 push dword EXTENDED_STYLE 112 db 0x8b, 0xce ; mov ecx,esi 113 call create_win_wrap0 114 115 mov dword [esi+0x1d8],0x0 116 mov ecx,[esi+0x1c] 117 db 0x8b, 0xc6 ;mov eax,esi 118 pop edi 119 mov [esi+0x1d4],ecx 120 mov dword [esi+0x28c],0x0 121 mov dword [esi+0x290],0x0 122 mov dword [ebp-0x4],0xffffffff 123 mov ecx,[ebp-0xc] 124 pop esi 125 mov [dword fs:0x0],ecx 126 pop ebx 127 db 0x8b, 0xe5 ;mov esp,ebp 128 pop ebp 129 ret 130 131 times 0x6131-($-$$) int3 132 incbin "game.exe.orig", 0x6131, 0xa470-0x6131 133 134 ; ------------------------------------------------------------------------------ 135 136 struc class 137 resd 1 138 .global: resd 1 139 .window: resd 1 140 .palette: resd 1 141 .font_load_height: resw 1 142 resw 1 143 .char_width: resd 1 144 .line_height: resd 1 145 .rand_height: resd 1 146 .global_locked: resd 1 147 endstruc 148 149 struc glyph_metrics 150 .black_box_x: resd 1 151 .black_box_y: resd 1 152 .origin_x: resd 1 153 .origin_y: resd 1 154 .cell_inc_x: resd 1 155 .cell_inc_y: resd 1 156 endstruc 157 158 GGO_BITMAP equ 1 159 160 draw_text: ; 40b070 161 .extra_locals equ 0x38 162 ; locals 163 .glyph_buf_size equ 0x10 164 .hdc equ 0x14 165 .font equ 0x18 166 .fp_1 equ 0x1c 167 .double_0 equ 0x1c ; overlap 168 .double_1 equ 0x24 169 .x_advance equ 0x2c 170 .orig_xpos equ 0x30 171 .mat equ 0x34 172 .fp_0 equ 0x44 173 .gdi_obj equ 0x48 174 .glyph_metrics equ 0x4c 175 .tmp equ 0x60 176 177 .metrics equ 0x60 ; overlap 178 ; func parameters 179 .str equ .extra_locals+0x68 180 .xpos equ .extra_locals+0x6c 181 .ypos equ .extra_locals+0x70 182 .color equ .extra_locals+0x74 183 .dummy equ .extra_locals+0x78 ; unused parameter of copy_glyph_to_buf 184 185 sub esp, 0x54+.extra_locals 186 push ebx 187 push esi 188 push edi 189 db 0x8b, 0xf1 ; mov esi,ecx 190 push ebp 191 192 push dword font_face ; font face 193 push byte +0x1 ; pitch and family 194 push byte +0x0 ; quality 195 push byte +0x0 ; clip precision 196 push byte +0x0 ; out precision 197 push dword 0x80 ; charset 198 push byte +0x0 ; strikeout 199 push byte +0x0 ; underline 200 db 0x33, 0xc0 ; xor eax,eax 201 mov ax,[esi+class.font_load_height] 202 push byte +0x0 ; italic 203 push dword FONT_WEIGHT ; weight 204 push byte +0x0 ; orientation 205 push byte +0x0 ; escapement 206 push byte +0x0 ; font width 207 push eax ; font height 208 call [dword CreateFontA] 209 210 mov ecx,[esi+class.window] 211 mov ebx,[dword GetDC] 212 mov [esp+.font],eax 213 push ecx 214 call ebx ; GetDC(window) 215 216 mov ecx,[esp+.font] 217 mov [esp+.hdc],eax 218 push ecx ; font 219 push eax ; hdc 220 call [dword SelectObject] 221 mov [esp+.gdi_obj],eax ; SelectObject result 222 223 ; init mat to (1 0; 0 1) 224 mov eax, 65536 225 xor ecx, ecx 226 mov [esp+.mat+0], eax 227 mov [esp+.mat+4], ecx 228 mov [esp+.mat+8], ecx 229 mov [esp+.mat+12], eax 230 231 mov edi,[esp+.str] 232 mov eax,[esp+.xpos] 233 movsx bx,[edi] ; bx = (char)*str 234 test bx,bx 235 mov [esp+.orig_xpos],eax 236 jz near .return 237 238 ; get text metrics 239 mov eax, [get_text_metrics_cache] 240 test eax, eax 241 jnz .has_metrics 242 push gdi32_str 243 call [dword GetModuleHandleA] 244 push get_text_metrics_str 245 push eax 246 call [dword GetProcAddress] 247 mov [get_text_metrics_cache], eax 248 249 .has_metrics: 250 lea ecx,[esp+.metrics] 251 push ecx 252 push dword [esp+4+.hdc] 253 call eax ; GetTextMetricsA 254 255 .loop: 256 cmp dword [esi+class.rand_height],byte +0x1 257 jnz near .no_rand 258 259 db 0x33, 0xed ; xor ebp,ebp 260 push dword font_face ; font face 261 mov bp,[esi+class.font_load_height] 262 push byte +0x1 ; pitch and family 263 push byte +0x0 ; quality 264 push byte +0x0 ; clip precision 265 push byte +0x0 ; out precision 266 push dword 0x80 ; charset 267 push byte +0x0 ; strike out 268 push byte +0x0 ; underline 269 push byte +0x0 ; italic 270 push dword FONT_WEIGHT ; weight 271 push byte +0x0 ; orientation 272 push byte +0x0 ; escapement 273 push byte +0x0 ; font width 274 call rand 275 cdq 276 idiv ebp 277 db 0x8b, 0xc2 ; mov eax,edx 278 mov ecx,0x3 279 cdq 280 db 0x2b, 0xc2 ; sub eax,edx 281 sar eax,byte 0x1 282 mov [esp+0x34+.glyph_buf_size],eax 283 lea eax,[nosplit ebp*2+0x0] 284 cdq 285 idiv ecx 286 add [esp+0x34+.glyph_buf_size],eax 287 mov eax,[esp+0x34+.glyph_buf_size] 288 push eax ; font height 289 call [dword CreateFontA] 290 291 mov ecx,[esp+.hdc] 292 push eax 293 mov [esp+4+.font],eax 294 push ecx 295 call [dword SelectObject] 296 297 call rand 298 mov ecx,0x14 299 sub esp,byte +0x8 300 cdq 301 idiv ecx 302 sub edx,byte +0xa 303 lea eax,[esp+8+.tmp] 304 push eax 305 db 0x8b, 0xce ; mov ecx,esi 306 mov [esp+0xc+.glyph_buf_size],edx 307 fild dword [esp+0xc+.glyph_buf_size] 308 fmul qword [dword 0x423198] 309 fcos 310 fstp qword [esp+0x4] 311 call norm_float_to_u16fp 312 mov ecx,[eax] 313 mov [esp+.mat+0],ecx 314 call rand 315 mov ecx,0x14 316 sub esp,byte +0x8 317 cdq 318 idiv ecx 319 sub edx,byte +0xa 320 mov [esp+8+.glyph_buf_size],edx 321 fild dword [esp+8+.glyph_buf_size] 322 fmul qword [dword 0x423198] 323 fsin 324 fstp qword [esp] 325 lea eax,[esp+8+.fp_0] 326 push eax 327 db 0x8b, 0xce ; mov ecx,esi 328 call norm_float_to_u16fp 329 mov ecx,[eax] 330 mov [esp+.mat+4],ecx 331 call rand 332 mov ecx,0x14 333 sub esp,byte +0x8 334 cdq 335 idiv ecx 336 sub edx,byte +0xa 337 lea eax,[esp+8+.double_1] 338 push eax 339 db 0x8b, 0xce ; mov ecx,esi 340 mov [esp+0xc+.glyph_buf_size],edx 341 fild dword [esp+0xc+.glyph_buf_size] 342 fmul qword [dword 0x423198] 343 fsin 344 fchs 345 fstp qword [esp+0x4] 346 call norm_float_to_u16fp 347 mov ecx,[eax] 348 mov [esp+.mat+8],ecx 349 call rand 350 mov ecx,0x14 351 sub esp,byte +0x8 352 cdq 353 idiv ecx 354 sub edx,byte +0xa 355 lea eax,[esp+8+.fp_1] 356 push eax 357 db 0x8b, 0xce ; mov ecx,esi 358 mov [esp+0xc+.glyph_buf_size],edx 359 fild dword [esp+0xc+.glyph_buf_size] 360 fmul qword [dword 0x423198] 361 fcos 362 fstp qword [esp+0x4] 363 call norm_float_to_u16fp 364 mov ecx,[eax] 365 mov [esp+.mat+12],ecx 366 367 .no_rand: 368 shl bx,byte 0x8 ; bx = cur_char << 8 = str[0] << 8 369 ; cur_char is sign extended, but it is shifted out 370 lea ebp,[edi+0x1] ; ebp = str+1 371 movzx ax,[ebp+0x0] ; ax = (byte) str[1] 372 db 0x66, 0x0b, 0xd8 ; or bx,ax ; bx = (str[0] << 8) | (byte) str[1] 373 movzx ecx,bx ; ecx = (ushort) ((str[0] << 8) | (byte) str[1]) 374 push ecx 375 call __ismbclegal 376 add esp,byte +0x4 377 378 cmp eax,byte +0x1 379 jnz short .illegal_mbc 380 add edi,byte +0x2 ; edi = str+2 381 mov eax,[esi+class.char_width] 382 db 0x03, 0xc0 ;add eax,eax ; eax = 2*char_width 383 jmp short .after_mbc 384 385 .illegal_mbc: 386 shr bx,byte 0x8 ; bx = (byte) str[0] 387 db 0x8b, 0xfd ; mov edi,ebp ; edi = str+1 388 mov eax,[esi+class.char_width] 389 390 .after_mbc: 391 lea ecx,[esp+.glyph_metrics] 392 mov edx,[esp+.hdc] 393 movzx ebp,bx ; ebp = (ushort) cur_char 394 mov [esp+.x_advance],eax 395 lea eax,[esp+.mat] 396 push eax ; &mat 397 push byte +0x0 ; buffer = NULL 398 push byte +0x0 ; buffer_length = 0 399 push ecx ; &glyph_metrics 400 push byte GGO_BITMAP ; format = GGO_BITMAP 401 push ebp ; (uint) (ushort) cur_char 402 push edx ; hdc 403 call [dword GetGlyphOutlineA] 404 mov [esp+.glyph_buf_size],eax 405 406 push eax 407 call afx_global_new_like 408 lea ecx,[esp+4+.mat] 409 lea edx,[esp+4+.glyph_metrics] 410 add esp,byte +0x4 411 db 0x8b, 0xd8 ; mov ebx,eax ; ebx = buf 412 mov eax,[esp+.glyph_buf_size] 413 push ecx ; &mat 414 mov ecx,[esp+4+.hdc] 415 push ebx ; buf 416 push eax ; glyph_buf_size 417 push edx ; &glyph_metrics 418 push byte GGO_BITMAP ; format = GGO_BITMAP 419 push ebp ; (uint) (ushort) cur_char 420 push ecx ; hdc 421 call [dword GetGlyphOutlineA] 422 423 mov ecx,[esp+.dummy] 424 mov edx,[esp+.color] 425 mov eax,[esp+.glyph_metrics+glyph_metrics.black_box_y] 426 push ecx ; dummy 427 push edx ; color 428 and eax,0xffff ; eax = black_box_y & 0xffff 429 mov ecx,[esp+8+.ypos] 430 add ecx,[esp+8+.metrics+4] 431 sub ecx,[esp+8+.glyph_metrics+glyph_metrics.origin_y] 432 push eax ; black_box_y & 0xffff 433 mov eax,[esp+0x0c+.glyph_metrics+glyph_metrics.black_box_x] 434 and eax,0xffff ; eax = black_box_x & 0xffff 435 push eax ; black_box_x & 0xffff 436 push ebx ; buf 437 mov eax,[esp+0x14+.glyph_metrics+glyph_metrics.origin_x] 438 push ecx ; ypos 439 add eax,[esp+0x18+.xpos] ; eax = glyph_metrics.origin_x + xpos 440 mov ecx,[esi+class.global] 441 push eax ; glyph_metrics.origin_x + xpos 442 mov edx,[ecx] ; edx = *global 443 push edx ; *global 444 db 0x8b, 0xce ; mov ecx,esi ; this 445 call copy_glyph_to_buf 446 447 mov ecx,[esp+.x_advance] 448 push ebx ; buf 449 add [esp+4+.xpos],ecx 450 call free_like 451 add esp,byte +0x4 452 453 movsx bx,[edi] ; bx = (char) *next_str 454 test bx,bx 455 jnz near .loop 456 457 .return: 458 mov eax,[esp+.gdi_obj] 459 mov ecx,[esp+.hdc] 460 push eax 461 push ecx 462 call [dword SelectObject] ; (hdc, gdi_obj) 463 464 mov ecx,[esp+.font] 465 push ecx 466 call [dword DeleteObject] 467 468 mov ecx,[esi+class.line_height] 469 mov eax,[esp+.xpos] 470 sub eax,[esp+.orig_xpos] ; eax = xpos - orig_xpos 471 push ecx ; line_height 472 mov ecx,[esp+4+.ypos] 473 push eax ; xpos - orig_xpos 474 mov edx,[esp+8+.orig_xpos] 475 push ecx ; ypos 476 push edx ; orig_xpos 477 db 0x8b, 0xce ;mov ecx,esi 478 call copy_buf_to_window 479 480 pop ebp 481 pop edi 482 pop esi 483 pop ebx 484 add esp, 0x54+.extra_locals 485 ret 0x14 486 487 gdi32_str: 488 db "gdi32.dll", 0 489 get_text_metrics_str: 490 db "GetTextMetricsA", 0 491 492 times 0xa7f0-($-$$) int3 493 incbin "game.exe.orig", 0xa7f0, 0xa810-0xa7f0 494 495 ; ------------------------------------------------------------------------------ 496 497 struc bmi_header 498 .size: resd 1 499 .width: resd 1 500 .height: resd 1 501 .planes: resw 1 502 .bit_count: resw 1 503 .compression: resd 1 504 .size_image: resd 1 505 .x_pels_per_m: resd 1 506 .y_pels_per_m: resd 1 507 .clr_used: resd 1 508 .clr_important: resd 1 509 endstruc 510 511 struc global_struct 512 .bmi: resb bmi_header_size 513 resb 0x428-($-$$) 514 .buf: resb 1 515 endstruc 516 517 copy_glyph_to_buf: ; 0040b410 518 ; locals 519 .loop_y equ 0x10 520 .src_row_ptr equ 0x1c 521 .glob_buf equ 0x14 522 .src_cur_ptr equ 0x18 523 .this equ 0x20 524 .cur_pixel equ 0x24 525 .stride equ 0x28 526 ; func parameters 527 .global equ 0x30 528 .dst_x equ 0x34 529 .dst_y equ 0x38 530 .buf equ 0x3c 531 .width equ 0x40 532 .height equ 0x44 533 .color equ 0x48 534 .dummy equ 0x4a ; unused parameter 535 536 mov eax,[esp-0x2c+.global] 537 sub esp,byte +0x1c 538 mov [esp-0x10+.this],ecx 539 push ebx 540 push esi 541 push edi 542 push ebp 543 push eax 544 call [dword GlobalLock] 545 db 0x8b, 0xf0 ; mov esi,eax ; esi=global 546 547 mov ecx,[esp+.this] 548 lea eax,[esi+global_struct.buf] 549 mov [esp+.glob_buf],eax 550 mov dword [esp+.loop_y],0x0 551 552 cmp dword [esp+.height],byte +0x0 553 jng near .return 554 555 mov eax,[esp+.buf] 556 mov [esp+.src_row_ptr],eax 557 558 mov ebx,[esp+.color] 559 560 mov eax,[esp+.width] 561 add eax,31 562 sar eax,byte 0x3 563 and eax,~3 564 mov [esp+.stride],eax ; stride = (width+31)/32*4 565 566 .row_loop: 567 mov ecx,[esi+bmi_header.height] 568 mov edi,[esp+.dst_x] 569 sub ecx,[esp+.loop_y] ; ecx = bmi_height - loop_y 570 sub ecx,[esp+.dst_y] ; ecx = bmi_height - loop_y - dst_y 571 db 0x33, 0xed ; xor ebp,ebp ; ebp: loop x 572 dec ecx ; ecx = bmi_height - loop_y - dst_y - 1 573 imul ecx,[esi+bmi_header.width] ; ecx = (bmi_height - loop_y - dst_y - 1) * bmi_wdith 574 add ecx,[esp+.glob_buf] ; ecx = glob_buf + (bmi_height - loop_y - dst_y - 1) * bmi_wdith 575 db 0x03, 0xf9 ; add edi,ecx ; edi = glob_buf + (bmi_height - loop_y - dst_y - 1) * bmi_wdith + dst_x 576 mov ecx,[esp+.src_row_ptr] 577 mov [esp+.src_cur_ptr],ecx 578 cmp [esp+.width],ebp 579 jng short .LAB_0040b528 580 581 .column_loop: 582 mov eax,ebp ; eax = loop_x 583 mov ecx,[esp+.src_cur_ptr] 584 and eax,byte +0x7 ; eax = loop_x & 7 585 movsx edx,byte [ecx] ; edx = *src_cur_ptr 586 mov cl,0x7 587 mov [esp+.cur_pixel],edx 588 mov edx,0x1 589 sub cl,al ; cl = 7 - (loop & 7) 590 shl edx,cl ; edx = 1 << cl 591 test [esp+.cur_pixel],edx 592 jz short .skip_pixel ; transparent, skip 593 mov [edi],bl ; *out_pixel = bl = color 594 %ifdef FONT_BOLDING 595 mov ecx,[esi+bmi_header.height] 596 sub ecx,[esp+.loop_y] 597 sub ecx,[esp+.dst_y] 598 sub ecx,byte +0x2 ; ecx = bmi_height - loop_y - dst_y - 2 599 imul ecx,[esi+bmi_header.width] ; ecx = (bmi_height - loop_y - dst_y - 2) * bmi_width 600 add ecx,[esp+.glob_buf] 601 add ecx,[esp+.dst_x] ; ecx = glob_buf + (bmi_height - loop_y - dst_y - 2) * bmi_width + dst_x 602 db 0x03, 0xcd ; add ecx,ebp ; ecx = glob_buf + (bmi_height - loop_y - dst_y - 2) * bmi_width + dst_x + loop_x 603 mov [ecx],bl 604 mov [ecx+0x1],bl 605 %endif 606 607 .skip_pixel: 608 cmp eax,byte +0x7 609 jnz short .skip_ptr_inc 610 inc dword [esp+.src_cur_ptr] 611 612 .skip_ptr_inc: 613 inc edi ; ++out_pixel 614 inc ebp ; ++loop_x 615 cmp [esp+.width],ebp 616 jg short .column_loop 617 618 .LAB_0040b528: 619 mov eax,[esp+0x28] 620 inc dword [esp+.loop_y] 621 mov ecx,[esp+.loop_y] 622 add [esp+.src_row_ptr],eax 623 cmp [esp+.height],ecx 624 jg near .row_loop 625 626 .return: 627 mov eax,[esp+.global] 628 push eax 629 call [dword GlobalUnlock] 630 631 mov ecx,[esp+.this] 632 pop ebp 633 pop edi 634 pop esi 635 pop ebx 636 mov [ecx+class.global_locked],eax 637 mov eax,0x1 638 add esp,byte +0x1c 639 ret 0x20 640 641 times 0xa970-($-$$) int3 642 incbin "game.exe.orig", 0xa970, 0x1da3d-0xa970 643 644 ; ------------------------------------------------------------------------------ 645 646 fuckup_window_style: ;41e63d 647 push esi 648 mov esi,[esp+0x8] 649 cmp dword [esi+0x28],byte +0x0 650 jnz short .LAB_0041e66e 651 call 0x420917 652 test byte [eax+0x18],0x8 653 mov eax,0x1 654 jnz short .LAB_0041e65f 655 push byte +0x8 656 call 0x41b2f2 657 658 .LAB_0041e65f: 659 test eax,eax 660 jnz short .LAB_0041e667 661 db 0x33, 0xc0 ; xor eax,eax 662 jmp short .return 663 664 .LAB_0041e667: 665 mov dword [esi+0x28],0x423b08 666 667 .LAB_0041e66e: 668 mov eax,[esi+0x20] 669 test ah,0x80 670 jz short .return_1 671 cmp dword [dword 0x42b590],byte +0x0 672 jz short .return_1 673 or ah,0x40 674 mov [esi+0x20],eax 675 676 .return_1: 677 mov eax,0x1 678 .return: 679 pop esi 680 ret 0x4 681 682 times 0x1da9b-($-$$) int3 683 incbin "game.exe.orig", 0x1da9b