| BlackWhite |
11-01-2023 16:42 |
Fix S-ICE 2.80 to Let It Update User Screen on Every Step
S-ICE 2.80 has a bug which concerns with denying updating user screen when we command p to step over one instruction, for example, the following code will not have the expected result if we step it from 684:0000 to 684:001A, neither the data window nor the user screen will be updated.
Code:
EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000 SP=FFFE
EBP=00000000 ESI=00000000 EDI=00000000 FS=0000 GS=0000
DS=0674 ES=0674 SS=0684 CS=0684 IP=0000 o d I s z a p c t
--------------------------------------------------------------------------
B800:0000 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07 . . . . . . . .
B800:0010 20 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07 . . . . . . . .
--------------------------------------------------------------------------
0684:0000 B800B8 MOV AX,B800
0684:0003 8EC0 MOV ES,AX
0684:0005 BF0000 MOV DI,0000
0684:0008 B041 MOV AL,41
0684:000A B471 MOV AH,71
0684:000C B9D007 MOV CX,07D0
0684:000F 268905 MOV ES:[DI],AX
0684:0012 83C702 ADD DI,+02
0684:0015 83E901 SUB CX,+01
0684:0018 75F5 JNZ 000F
0684:001A B401 MOV AH,01
0684:001C CD21 INT 21
0684:001E B44C MOV AH,4C
0684:0020 CD21 INT 21
If we set a breakpoint at 684:001A and command x, then the code will
have the expected result, both of the data window and the user screen
will be updated well.
So I debug S-ICE in Bochs and compare the code for command x with that
for command p, and finally figure out the variable which controls whether to
update user screen.
Here are the solution and analysis(Because I have no privilege to upload
an attatchment, the screenshots and the patched exe are not available).
(0) How to fix
Code:
Search hex bytes : C6063D5F01
Replace them with: C6063D5F00
(1) ds:[5F3D] controls whether to recover & back up user screen
Code:
0040:0000EEE2(00FAFEF2) 33C0 xor ax, ax
0040:0000EEE4(00FAFEF4) C606385FFF mov byte ptr ds:[0x5F38], 0xFF
0040:0000EEE9(00FAFEF9) C6063D5F01 mov byte ptr ds:[0x5F3D], 0x01; command p will set it to 1
; which means no need for
; recovering & backing up
; user screen
0040:0000EEEE(00FAFEFE) 803EE1C202 cmp byte ptr ds:[0xC2E1], 0x02
0040:0000EEF3(00FAFF03) 7520 jnz 0xEF15
0040:0000EEF5(00FAFF05) C6063F5F01 mov byte ptr ds:[0x5F3F], 0x01
0040:0000EEFA(00FAFF0A) B82600 mov ax, 0x0026
0040:0000EEFD(00FAFF0D) E8C66D call 0x5CC6
0040:0000EF00(00FAFF10) A3F063 mov word ptr ds:[0x63f0], ax
0040:0000EF03(00FAFF13) B82A00 mov ax, 0x002A
0040:0000EF06(00FAFF16) E8BD6D call 0x5CC6
0040:0000EF09(00FAFF19) A3EE63 mov word ptr ds:[0x63ee], ax
0040:0000EF0C(00FAFF1C) B83200 mov ax, 0x0032
0040:0000EF0F(00FAFF1F) E8B46D call 0x5CC6
0040:0000EF12(00FAFF22) A3F263 mov word ptr ds:[0x63f2], ax
0040:0000EF15(00FAFF25) 33C0 xor ax, ax
0040:0000EF17(00FAFF27) C3 ret
(2) If ds:[5F3D]==0 then do recovering user screen from S-ICE's buffer
Code:
0040:00000356(00FA1366) C606385F00 mov byte ptr ds:[0x5F38], 0x00
0040:0000035B(00FA136B) E8F5C3 call 0xC753
0040:0000035E(00FA136E) E89FE2 call 0xE600
0040:00000361(00FA1371) 803E385F00 cmp byte ptr ds:[0x5F38], 0x00; FF
0040:00000366(00FA1376) 74EE jz 0x0356
0040:00000368(00FA1378) 803E30E500 cmp byte ptr ds:[0xE530], 0x00; 00
0040:0000036D(00FA137D) 750E jnz 0x037D
0040:0000036F(00FA137F) 803E3D5F00 cmp byte ptr ds:[0x5F3D], 0x00; if(byte ptr ds:[5F3D]==0)
0040:00000374(00FA1384) 7407 jz 0x037D ; ==>037D
0040:00000376(00FA1386) 803E3E5F00 cmp byte ptr ds:[0x5F3E], 0x00; 00
0040:0000037B(00FA138B) 7403 jz 0x0380
0040:0000037D(00FA138D) E8120B call 0x0E92; recover_user_screen_from_sice_buffer
0040:00000380(00FA1390) 07 pop es
0040:00000381(00FA1391) B001 mov al, 0x01
0040:00000383(00FA1393) C3 ret
||
\||/
\/
;*recover_user_screen_from_sice_buffer
0040:00000E92(00FA1EA2) 803EC10A00 cmp byte ptr ds:[0x0AC1], 0x00; 00
0040:00000E97(00FA1EA7) 0F851200 jnz 0x0EAD
0040:00000E9B(00FA1EAB) 6651 push ecx
0040:00000E9D(00FA1EAD) B80000 mov ax, 0x0000
0040:00000EA0(00FA1EB0) BB0100 mov bx, 0x0001
0040:00000EA3(00FA1EB3) E8D50D call 0x1C7B
0040:00000EA6(00FA1EB6) 6659 pop ecx
0040:00000EA8(00FA1EB8) E8200D call 0x1BCB
0040:00000EAB(00FA1EBB) EB05 jmp 0x0EB2
0040:00000EAD(00FA1EBD) C606791001 mov byte ptr ds:[0x1079], 0x01
0040:00000EB2(00FA1EC2) B80100 mov ax, 0x0001
0040:00000EB5(00FA1EC5) BB0000 mov bx, 0x0000
0040:00000EB8(00FA1EC8) E8C00D call 0x1C7B; do_recover_or_backup
0040:00000EBB(00FA1ECB) C3 ret
||
\||/
\/
;*do_recover_or_backup
0040:00001C7B(00FA2C8B) F606507A80 test byte ptr ds:[0x7A50], 0x80; 00
0040:00001C80(00FA2C90) 741F jz 0x1CA1; ==>1CA1
0040:00001C82(00FA2C92) 0BC0 or ax, ax
0040:00001C84(00FA2C94) 751A jnz 0x1CA0
0040:00001C86(00FA2C96) 0BDB or bx, bx
0040:00001C88(00FA2C98) 7516 jnz 0x1CA0
0040:00001C8A(00FA2C9A) B061 mov al, 0x61
0040:00001C8C(00FA2C9C) E620 out 0x20, al
0040:00001C8E(00FA2C9E) E800FF call 0x1B91
0040:00001C91(00FA2CA1) B064 mov al, 0x64
0040:00001C93(00FA2CA3) E6A0 out 0xA0, al
0040:00001C95(00FA2CA5) E8F9FE call 0x1B91
0040:00001C98(00FA2CA8) B062 mov al, 0x62
0040:00001C9A(00FA2CAA) E620 out 0x20, al
0040:00001C9C(00FA2CAC) E8F2FE call 0x1B91
0040:00001C9F(00FA2CAF) FB sti
0040:00001CA0(00FA2CB0) C3 ret
0040:00001CA1(00FA2CB1) 55 push bp
0040:00001CA2(00FA2CB2) 83EC04 sub sp, 0x0004
0040:00001CA5(00FA2CB5) 8BEC mov bp, sp
0040:00001CA7(00FA2CB7) 894600 mov word ptr ss:[bp], ax
0040:00001CAA(00FA2CBA) 895E02 mov word ptr ss:[bp+0x0002], bx
0040:00001CAD(00FA2CBD) 83F902 cmp cx, 0x0002; cx=1
0040:00001CB0(00FA2CC0) 7402 jz 0x1CB4 ; no
0040:00001CB2(00FA2CC2) 33C9 xor cx, cx
0040:00001CB4(00FA2CC4) E85300 call 0x1D0A; CF=0
0040:00001CB7(00FA2CC7) 724C jb 0x1D05 ; no
0040:00001CB9(00FA2CC9) 33C0 xor ax, ax
0040:00001CBB(00FA2CCB) E8EFF2 call 0x0FAD
0040:00001CBE(00FA2CCE) 668B3E9064 mov edi, dword ptr ds:[0x6490] ; EDI=10000h
0040:00001CC3(00FA2CD3) 837E0200 cmp word ptr ss:[bp+0x0002], 0x0000; 0
0040:00001CC7(00FA2CD7) 7405 jz 0x1CCE ; ==>1CCE
0040:00001CC9(00FA2CD9) 668B3E9464 mov edi, dword ptr ds:[0x6494]
0040:00001CCE(00FA2CDE) 6633F6 xor esi, esi
0040:00001CD1(00FA2CE1) FC cld
0040:00001CD2(00FA2CE2) 66B900100000 mov ecx, 0x00001000
0040:00001CD8(00FA2CE8) 0FA0 push fs
0040:00001CDA(00FA2CEA) 06 push es
0040:00001CDB(00FA2CEB) E851FE call 0x1B2F
0040:00001CDE(00FA2CEE) 8E264A7A mov fs, word ptr ds:[0x7A4A]; FS=30h(base addr=B8000h)
0040:00001CE2(00FA2CF2) 8E069000 mov es, word ptr ds:[0x0090]; ES=50h(base addr=F74000h)
0040:00001CE6(00FA2CF6) 837E0000 cmp word ptr ss:[bp], 0x0000; 0001
; 1 for recovering user screen
; 0 for backing up user screen
0040:00001CEA(00FA2CFA) 7409 jz 0x1CF5 ; no
0040:00001CEC(00FA2CFC) 6687F7 xchg edi, esi; ESI=10000h, EDI=0
0040:00001CEF(00FA2CFF) 0FA0 push fs
0040:00001CF1(00FA2D01) 06 push es
0040:00001CF2(00FA2D02) 0FA1 pop fs ; FS=50h(base addr=F74000h)
0040:00001CF4(00FA2D04) 07 pop es ; ES=30h(base addr=B8000h)
0040:00001CF5(00FA2D05) F36764A5 rep movsw word ptr es:[edi], word ptr fs:[esi]
; copy 2000h bytes from buffer to B800:0000,
; thus recovering user screen
0040:00001CFA(00FA2D0A) 0FA1 pop fs
0040:00001CFC(00FA2D0C) E866FE call 0x1B65
0040:00001CFF(00FA2D0F) B80100 mov ax, 0x0001
0040:00001D02(00FA2D12) E8A8F2 call 0x0FAD
0040:00001D05(00FA2D15) 83C404 add sp, 0x0004
0040:00001D08(00FA2D18) 5D pop bp
0040:00001D09(00FA2D19) C3 ret
(3) If DS:[5F3D]==0 then do backing up user screen to S-ICE's buffer
Code:
0040:000002A3(00FA12B3) 33C0 xor ax, ax
0040:000002A5(00FA12B5) 86063D5F xchg byte ptr ds:[0x5F3D], al; AL=ds:[5F3D]
0040:000002A9(00FA12B9) 0AC0 or al, al ; if(AL==0)
0040:000002AB(00FA12BB) 7406 jz 0x02B3 ; ==>02B3
0040:000002AD(00FA12BD) 38263E5F cmp byte ptr ds:[0x5F3E], ah
0040:000002B1(00FA12C1) 740B jz 0x02BE
0040:000002B3(00FA12C3) E89A0B call 0x0E50 ; back_up_user_screen_to_sice_buffer
||
\||/
\/
;*back_up_user_screen_to_sice_buffer
0040:00000E50(00FA1E60) 1E push ds
0040:00000E51(00FA1E61) 07 pop es ; ES=08h
0040:00000E52(00FA1E62) 803EAA6400 cmp byte ptr ds:[0x64AA], 0x00; 0001
0040:00000E57(00FA1E67) 7507 jnz 0x0E60 ; ==>0E60
0040:00000E59(00FA1E69) FE06AA64 inc byte ptr ds:[0x64AA]
0040:00000E5D(00FA1E6D) E85C00 call 0x0EBC
0040:00000E60(00FA1E70) 06 push es
0040:00000E61(00FA1E71) B82000 mov ax, 0x0020
0040:00000E64(00FA1E74) 8EC0 mov es, ax
0040:00000E66(00FA1E76) 26A08404 mov al, byte ptr es:[0x0484] ; AL=18h
0040:00000E6A(00FA1E7A) 40 inc ax
0040:00000E6B(00FA1E7B) A2677A mov byte ptr ds:[0x7a67], al
0040:00000E6E(00FA1E7E) 07 pop es
0040:00000E6F(00FA1E7F) 6651 push ecx
0040:00000E71(00FA1E81) B80000 mov ax, 0x0000
0040:00000E74(00FA1E84) BB0000 mov bx, 0x0000
0040:00000E77(00FA1E87) E8010E call 0x1C7B; do_recover_or_backup
|