kolibrios-gitea/programs/develop/mtdbg/mtdbg.asm

4826 lines
81 KiB
NASM
Raw Normal View History

format binary
use32
db 'MENUET01'
dd 1
dd start
dd i_end
dd used_mem
dd used_mem
dd i_param
dd 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GUI ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
data_width equ 80
data_x_pos equ 12
data_x_size equ data_width*6
title_x_pos equ 30
title_y_pos equ 32
title_y_size equ 10
registers_x_pos equ data_x_pos
registers_y_pos equ (title_y_pos + title_y_size)
registers_y_size equ 30
dump_y_pos equ (registers_y_pos + registers_y_size + 5)
dump_height equ 4
dump_y_size equ (dump_height*10)
disasm_y_pos equ (dump_y_pos + dump_y_size + 4)
disasm_height equ 16
disasm_y_size equ (disasm_height*10)
messages_width equ data_width
messages_height equ 12
messages_x_pos equ data_x_pos
messages_y_pos equ (disasm_y_pos + disasm_y_size + 4)
messages_x_size equ messages_width*6
messages_y_size equ messages_height*10
cmdline_width equ data_width
cmdline_x_pos equ data_x_pos
cmdline_y_pos equ (messages_y_pos + messages_y_size + 10)
cmdline_x_size equ messages_x_size
cmdline_y_size equ 10
wnd_x_size equ (data_x_pos + messages_x_size + data_x_pos)
wnd_y_size equ (cmdline_y_pos + cmdline_y_size + data_x_pos)
start:
mov edi, messages
mov ecx, messages_width*messages_height
mov al, ' '
rep stosb
xor eax, eax
mov [messages_pos], eax
mov [cmdline_len], eax
mov [cmdline_pos], eax
mov edi, needzerostart
mov ecx, (needzeroend-needzerostart+3)/4
rep stosd
mov esi, begin_str
call put_message_nodraw
; set event mask - default events and debugging events
push 40
pop eax
mov ebx, 0x107
int 40h
; set debug messages buffer
mov ecx, dbgbufsize
mov dword [ecx], 256
xor ebx, ebx
mov [ecx+4], ebx
mov al, 69
int 40h
mov esi, i_param
call skip_spaces
test al, al
jz dodraw
push esi
call draw_window
pop esi
call OnLoadInit
jmp waitevent
dodraw:
call draw_window
waitevent:
push 10
pop eax
int 40h
cmp al, 9
jz debugmsg
dec eax
jz dodraw
dec eax
jz keypressed
dec eax
jnz waitevent
; button pressed - we have only one button (close)
push -1
pop eax
int 40h
keypressed:
mov al, 2
int 40h
shr eax, 8
cmp al, 8
jz .backspace
cmp al, 0xB0
jz .left
cmp al, 0xB3
jz .right
cmp al, 0x0D
jz .enter
cmp al, 0xB6
jz .del
cmp al, 0xB4
jz .home
cmp al, 0xB5
jz .end
cmp al, 0xB1
jz .down
cmp al, 0xB2
jz .up
cmp al, 0xD8
jz CtrlF7
cmp al, 0xD9
jz CtrlF8
cmp [cmdline_len], cmdline_width
jae waitevent
push eax
call clear_cmdline_end
pop eax
mov edi, cmdline
mov ecx, [cmdline_len]
add edi, ecx
lea esi, [edi-1]
sub ecx, [cmdline_pos]
std
rep movsb
cld
stosb
inc [cmdline_len]
call draw_cmdline_end
inc [cmdline_pos]
call draw_cursor
jmp waitevent
.backspace:
cmp [cmdline_pos], 0
jz waitevent
dec [cmdline_pos]
.delchar:
call clear_cmdline_end
mov edi, [cmdline_pos]
dec [cmdline_len]
mov ecx, [cmdline_len]
sub ecx, edi
add edi, cmdline
lea esi, [edi+1]
rep movsb
call draw_cmdline_end
call draw_cursor
jmp waitevent
.del:
mov eax, [cmdline_pos]
cmp eax, [cmdline_len]
jae waitevent
jmp .delchar
.left:
cmp [cmdline_pos], 0
jz waitevent
call hide_cursor
dec [cmdline_pos]
call draw_cursor
jmp waitevent
.right:
mov eax, [cmdline_pos]
cmp eax, [cmdline_len]
jae waitevent
call hide_cursor
inc [cmdline_pos]
call draw_cursor
jmp waitevent
.home:
call hide_cursor
and [cmdline_pos], 0
call draw_cursor
jmp waitevent
.end:
call hide_cursor
mov eax, [cmdline_len]
mov [cmdline_pos], eax
call draw_cursor
.up:
.down:
jmp waitevent
.enter:
mov ecx, [cmdline_len]
test ecx, ecx
jz waitevent
mov esi, cmdline
mov byte [esi+ecx], 0
and [cmdline_pos], 0
push esi
call clear_cmdline_end
call draw_cursor
pop esi
and [cmdline_len], 0
; skip leading spaces
call skip_spaces
cmp al, 0
jz waitevent
; now esi points to command
push esi
mov esi, prompt
call put_message_nodraw
pop esi
push esi
call put_message_nodraw
z1: mov esi, newline
call put_message
pop esi
push esi
call get_arg
mov [curarg], esi
pop edi
mov esi, commands
call find_cmd
mov eax, aUnknownCommand
jc .x11
; check command requirements
; flags field:
; &1: command may be called without parameters
; &2: command may be called with parameters
; &4: command may be called without loaded program
; &8: command may be called with loaded program
mov eax, [esi+8]
mov ecx, [curarg]
cmp byte [ecx], 0
jz .noargs
test byte [esi+16], 2
jz .x11
jmp @f
.noargs:
test byte [esi+16], 1
jz .x11
@@:
cmp [debuggee_pid], 0
jz .nodebuggee
mov eax, aAlreadyLoaded
test byte [esi+16], 8
jz .x11
jmp .x9
.nodebuggee:
mov eax, need_debuggee
test byte [esi+16], 4
jnz .x9
.x11:
xchg esi, eax
call put_message
.x10:
jmp waitevent
.x9:
call dword [esi+4]
jmp .x10
find_cmd:
; all commands are case-insensitive
push edi
.x4:
mov al, [edi]
cmp al, 0
jz .x5
cmp al, 'A'
jb @f
cmp al, 'Z'
ja @f
or al, 20h
@@:
stosb
jmp .x4
.x5:
; find command
pop edi
.x6:
cmp dword [esi], 0
jz .x7
push esi
mov esi, [esi]
lodsb
movzx ecx, al
push edi
repz cmpsb
pop edi
pop esi
jz .x8
add esi, 17
jmp .x6
.x7:
stc
.x8:
ret
get_arg:
lodsb
cmp al, ' '
ja get_arg
mov byte [esi-1], 0
cmp al, 0
jnz skip_spaces
dec esi
skip_spaces:
lodsb
cmp al, 0
jz @f
cmp al, ' '
jbe skip_spaces
@@: dec esi
ret
clear_cmdline_end:
mov ebx, [cmdline_pos]
mov ecx, [cmdline_len]
sub ecx, ebx
push 13
pop eax
imul ebx, 6
imul ecx, 6
inc ecx
add ebx, cmdline_x_pos
shl ebx, 16
or ebx, ecx
mov ecx, cmdline_y_pos*10000h + cmdline_y_size
mov edx, 0xFFFFFF
int 40h
ret
draw_cmdline:
xor ebx, ebx
jmp @f
draw_cmdline_end:
mov ebx, [cmdline_pos]
@@:
mov esi, [cmdline_len]
sub esi, ebx
push 4
pop eax
xor ecx, ecx
lea edx, [cmdline+ebx]
imul ebx, 6
add ebx, cmdline_x_pos
shl ebx, 16
or ebx, cmdline_y_pos+1
int 40h
ret
put_message_nodraw:
; in: esi->ASCIZ message
mov edx, [messages_pos]
.m:
lea edi, [messages+edx]
.l:
lodsb
cmp al, 0
jz .done
call test_scroll
cmp al, 10
jz .newline
cmp al, '%'
jnz @f
cmp dword [esp], z1
jnz .format
@@:
stosb
inc edx
jmp .l
.newline:
push edx
mov ecx, messages_width
xor eax, eax
xchg eax, edx
div ecx
xchg eax, edx
pop edx
test eax, eax
jz .m
sub edx, eax
add edx, ecx
jmp .m
.done:
mov [messages_pos], edx
ret
.format:
; at moment all format specs must be %<digit>X
lodsb ; get <digit>
sub al, '0'
movzx ecx, al
lodsb
pop eax
pop ebp
push eax
; write number in ebp with ecx digits
dec ecx
shl ecx, 2
.writenibble:
push ecx
call test_scroll
pop ecx
mov eax, ebp
shr eax, cl
and al, 0xF
cmp al, 10
sbb al, 69h
das
stosb
inc edx
sub ecx, 4
jns .writenibble
jmp .l
test_scroll:
cmp edx, messages_width*messages_height
jnz .ret
push esi
mov edi, messages
lea esi, [edi+messages_width]
mov ecx, (messages_height-1)*messages_width/4
rep movsd
push eax
mov al, ' '
push edi
push messages_width
pop ecx
sub edx, ecx
rep stosb
pop edi
pop eax
pop esi
.ret: ret
put_message:
call put_message_nodraw
draw_messages:
push 13
pop eax
mov edx, 0xFFFFFF
mov ebx, messages_x_pos*10000h+messages_x_size
mov ecx, messages_y_pos*10000h+messages_y_size
int 40h
mov edx, messages
push messages_width
pop esi
xor ecx, ecx
mov al, 4
mov ebx, messages_x_pos*10000h+messages_y_pos
@@:
int 40h
add edx, esi
add ebx, 10
cmp edx, messages+messages_width*messages_height
jb @b
ret
draw_cursor:
push 38
pop eax
mov ecx, cmdline_y_pos*10001h+cmdline_y_size-1
mov ebx, [cmdline_pos]
imul ebx, 6
add ebx, cmdline_x_pos
mov edx, ebx
shl ebx, 16
or ebx, edx
xor edx, edx
int 40h
ret
hide_cursor:
mov ebx, [cmdline_pos]
push 13
pop eax
imul ebx, 6
add ebx, cmdline_x_pos
shl ebx, 16
inc ebx
mov ecx, cmdline_y_pos*10000h + cmdline_y_size
mov edx, 0xFFFFFF
int 40h
mov ebx, [cmdline_pos]
cmp ebx, [cmdline_len]
jae .ret
mov al, 4
xor ecx, ecx
lea edx, [cmdline+ebx]
imul ebx, 6
add ebx, cmdline_x_pos
shl ebx, 16
or ebx, cmdline_y_pos+1
push 1
pop esi
int 40h
.ret:
ret
redraw_title:
push 13
pop eax
mov edx, 0xFFFFFF
mov ebx, title_x_pos*10000h + data_x_pos+data_x_size-title_x_pos
mov ecx, title_y_pos*10000h + title_y_size
int 40h
draw_title:
mov al, 38
mov ebx, (data_x_pos-2)*10000h + title_x_pos-5
mov ecx, (title_y_pos+5)*10001h
xor edx, edx
int 40h
push NoPrgLoaded_len
pop esi
cmp [debuggee_pid], 0
jz @f
mov esi, [prgname_len]
@@: imul ebx, esi, 6
add ebx, title_x_pos+4
shl ebx, 16
mov bx, data_x_pos+data_x_size-10-5-6*7
cmp [bSuspended], 0
jz @f
add ebx, 6
@@:
int 40h
mov ebx, (data_x_pos+data_x_size-10+4)*0x10000 + data_x_pos+data_x_size+2
int 40h
mov al, 4
mov ebx, title_x_pos*10000h+title_y_pos
xor ecx, ecx
mov edx, NoPrgLoaded_str
cmp [debuggee_pid], 0
jz @f
mov edx, [prgname_ptr]
@@:
int 40h
cmp [debuggee_pid], 0
jz .nodebuggee
mov ebx, (data_x_pos+data_x_size-10-6*7)*10000h + title_y_pos
mov edx, aRunning
push 7
pop esi
cmp [bSuspended], 0
jz @f
add ebx, 6*10000h
mov edx, aPaused
dec esi
@@:
int 40h
ret
.nodebuggee:
mov al, 38
mov ebx, (data_x_pos+data_x_size-10-6*7-5)*0x10000 + data_x_pos+data_x_size+2
mov ecx, (title_y_pos+5)*10001h
xor edx, edx
jmp @b
draw_register:
; in: esi->value, edx->string, ecx=string len, ebx=coord
push edx
push ecx
push esi
mov eax, esi
mov esi, ecx
; color
mov ecx, 808080h
cmp [debuggee_pid], 0
jz .cd
cmp [bSuspended], 0
jz .cd
xor ecx, ecx
mov edi, [eax]
cmp dword [eax+oldcontext-context], edi
jz .cd
mov ecx, 0x00AA00
.cd:
push 4
pop eax
int 40h
imul esi, 60000h
lea edx, [ebx+esi]
mov al, 47
mov ebx, 80101h
mov esi, ecx
pop ecx
int 40h
lea ebx, [edx+60000h*18]
mov esi, ecx
pop ecx
pop edx
add edx, ecx
ret
draw_flag:
movzx edi, byte [edx+7]
bt [_eflags], edi
jc .on
or byte [edx], 20h
jmp .onoff
.on:
and byte [edx], not 20h
.onoff:
mov ecx, 808080h
cmp [debuggee_pid], 0
jz .doit
cmp [bSuspended], 0
jz .doit
xor ecx, ecx
bt [_eflags], edi
lahf
bt dword [_eflags + oldcontext - context], edi
rcl ah, 1
test ah, 3
jp .doit
mov ecx, 0x00AA00
.doit:
mov ah, 0
int 40h
ret
redraw_registers:
push 13
pop eax
mov edx, 0xFFFFFF
mov ebx, data_x_pos*10000h + data_x_size
mov ecx, registers_y_pos*10000h + registers_y_size
int 40h
draw_registers:
mov esi, _eax
push 4
pop ecx
mov edx, regs_strs
mov ebx, registers_x_pos*10000h+registers_y_pos
call draw_register
add esi, _ebx-_eax
call draw_register
add esi, _ecx-_ebx
call draw_register
add esi, _edx-_ecx
call draw_register
mov ebx, registers_x_pos*10000h+registers_y_pos+10
add esi, _esi-_edx
call draw_register
add esi, _edi-_esi
call draw_register
add esi, _ebp-_edi
call draw_register
add esi, _esp-_ebp
call draw_register
mov ebx, registers_x_pos*10000h+registers_y_pos+20
add esi, _eip-_esp
call draw_register
mov cl, 7
add esi, _eflags-_eip
call draw_register
mov al, 4
mov ecx, 808080h
cmp [debuggee_pid], 0
jz @f
cmp [bSuspended], 0
jz @f
xor ecx, ecx
@@:
mov edx, aColon
xor esi, esi
inc esi
mov ebx, (registers_x_pos+37*6)*10000h + registers_y_pos+20
int 40h
mov edx, flags
@@:
add ebx, 2*6*10000h
call draw_flag
inc edx
cmp dl, flags_bits and 0xFF
jnz @b
ret
redraw_dump:
push 13
pop eax
mov edx, 0xFFFFFF
mov ebx, data_x_pos*10000h + data_x_size
mov ecx, dump_y_pos*10000h + dump_y_size
int 40h
draw_dump:
; addresses
mov al, 47
mov ebx, 80100h
mov edx, data_x_pos*10000h + dump_y_pos
mov ecx, [dumppos]
mov esi, 808080h
cmp [debuggee_pid], 0
jz @f
cmp [bSuspended], 0
jz @f
xor esi, esi
@@:
int 40h
add ecx, 10h
add edx, 10
cmp dl, dump_y_pos + dump_y_size
jb @b
; hex dump of data
mov ebx, 20101h
mov ecx, dumpdata
push ecx
xor edi, edi
mov edx, (data_x_pos+12*6)*10000h + dump_y_pos
cmp [dumpread], edi
jz .hexdumpdone1
.hexdumploop1:
int 40h
add edx, 3*6*10000h
inc ecx
inc edi
test edi, 15
jz .16
test edi, 7
jnz @f
add edx, 2*6*10000h - 10 + 6*(3*10h+2)*10000h
.16:
add edx, 10 - 6*(3*10h+2)*10000h
@@:
cmp edi, [dumpread]
jb .hexdumploop1
.hexdumpdone1:
mov al, 4
mov ecx, esi
mov ebx, edx
push 2
pop esi
mov edx, aQuests
.hexdumploop2:
cmp edi, dump_height*10h
jae .hexdumpdone2
int 40h
add ebx, 3*6*10000h
inc edi
test edi, 15
jz .16x
test edi, 7
jnz .hexdumploop2
add ebx, 2*6*10000h - 10 + 6*(3*10h+2)*10000h
.16x:
add ebx, 10 - 6*(3*10h+2)*10000h
jmp .hexdumploop2
.hexdumpdone2:
dec esi
; colon, minus signs
mov ebx, (data_x_pos+8*6)*10000h + dump_y_pos
mov edx, aColon
@@:
int 40h
add ebx, 10
cmp bl, dump_y_pos+dump_height*10
jb @b
mov ebx, (data_x_pos+(12+3*8)*6)*10000h + dump_y_pos
mov edx, aMinus
@@:
int 40h
add ebx, 10
cmp bl, dump_y_pos+dump_height*10
jb @b
; ASCII data
mov ebx, (data_x_pos+(12+3*10h+2+2)*6)*10000h + dump_y_pos
mov edi, dump_height*10h
pop edx
.asciiloop:
push edx
cmp byte [edx], 20h
jae @f
mov edx, aPoint
@@:
int 40h
pop edx
inc edx
add ebx, 6*10000h
dec edi
jz .asciidone
test edi, 15
jnz .asciiloop
add ebx, 10 - 6*10h*10000h
jmp .asciiloop
.asciidone:
ret
redraw_disasm:
push 13
pop eax
mov edx, 0xFFFFFF
mov ebx, data_x_pos*10000h + data_x_size
mov ecx, (disasm_y_pos-1)*10000h + (disasm_y_size+1)
int 40h
draw_disasm:
mov eax, [disasm_start_pos]
mov [disasm_cur_pos], eax
and [disasm_cur_str], 0
.loop:
push [disasm_cur_pos]
call disasm_instr
pop ebp
jc .loopend
xor esi, esi ; default color: black
mov ebx, data_x_pos*10000h + data_x_size
mov ecx, [disasm_cur_str]
imul ecx, 10*10000h
add ecx, (disasm_y_pos-1)*10000h + 10
mov eax, ebp
pushad
call find_enabled_breakpoint
popad
jnz .nored
push 13
pop eax
mov edx, 0xFF0000
int 40h
.nored:
mov eax, [_eip]
cmp eax, ebp
jnz .noblue
push 13
pop eax
mov edx, 0x0000FF
int 40h
mov esi, 0xFFFFFF ; on blue bgr, use white color
.noblue:
push 47
pop eax
mov ebx, 80100h
mov edx, [disasm_cur_str]
imul edx, 10
add edx, data_x_pos*10000h + disasm_y_pos
mov ecx, ebp
int 40h
mov al, 4
lea ebx, [edx+8*6*10000h]
mov ecx, esi
push 1
pop esi
mov edx, aColon
int 40h
push 9
pop edi
lea edx, [ebx+2*6*10000h]
mov esi, ecx
mov al, 47
mov ebx, 20101h
mov ecx, ebp
sub ecx, [disasm_start_pos]
add ecx, disasm_buffer
.drawhex:
int 40h
add edx, 6*3*10000h
inc ecx
inc ebp
cmp ebp, [disasm_cur_pos]
jae .hexdone
dec edi
jnz .drawhex
push esi
mov esi, [disasm_cur_pos]
dec esi
cmp esi, ebp
pop esi
jbe .drawhex
mov al, 4
lea ebx, [edx-6*10000h]
mov ecx, esi
push 3
pop esi
mov edx, aDots
int 40h
mov esi, ecx
.hexdone:
xor eax, eax
mov edi, disasm_string
mov edx, edi
or ecx, -1
repnz scasb
not ecx
dec ecx
xchg ecx, esi
mov ebx, [disasm_cur_str]
imul ebx, 10
add ebx, (data_x_pos+6*40)*10000h+disasm_y_pos
mov al, 4
int 40h
inc [disasm_cur_str]
cmp [disasm_cur_str], disasm_height
jb .loop
.loopend:
ret
update_disasm_eip:
; test if instruction at eip is showed
mov ecx, disasm_height
mov eax, [disasm_start_pos]
mov [disasm_cur_pos], eax
@@:
mov eax, [_eip]
cmp [disasm_cur_pos], eax
jz redraw_disasm
push ecx
call disasm_instr
pop ecx
jc @f
loop @b
@@:
update_disasm_eip_force:
mov eax, [_eip]
mov [disasm_start_pos], eax
update_disasm:
cmp [debuggee_pid], 0
jz .no
push 69
pop eax
push 6
pop ebx
mov ecx, [debuggee_pid]
mov edi, disasm_buffer
mov edx, 256
mov esi, [disasm_start_pos]
int 40h
cmp eax, -1
jnz @f
mov esi, read_mem_err
call put_message
.no:
xor eax, eax
@@:
mov [disasm_buf_size], eax
call restore_from_breaks
jmp redraw_disasm
draw_window:
; start redraw
push 12
pop eax
push 1
pop ebx
int 40h
; define window
xor eax, eax
mov ebx, wnd_x_size
mov ecx, wnd_y_size
mov edx, 3FFFFFFh
int 40h
; caption
mov al, 4
mov ecx, 0xFFFFFF
mov ebx, 80008h
mov edx, caption_str
push caption_len
pop esi
int 40h
; messages frame
mov al, 38
mov ebx, (messages_x_pos-2)*10000h + (messages_x_pos+messages_x_size+2)
push ebx
mov ecx, (messages_y_pos-2)*10001h
xor edx, edx
int 40h
mov ecx, (messages_y_pos+messages_y_size+2)*10001h
int 40h
mov ebx, (messages_x_pos-2)*10001h
push ebx
mov ecx, (messages_y_pos-2)*10000h + (messages_y_pos+messages_y_size+2)
int 40h
mov ebx, (messages_x_pos+messages_x_size+2)*10001h
push ebx
int 40h
; command line frame
mov ecx, (cmdline_y_pos-2)*10000h + (cmdline_y_pos+cmdline_y_size+2)
pop ebx
int 40h
pop ebx
int 40h
pop ebx
mov ecx, (cmdline_y_pos+cmdline_y_size+2)*10001h
int 40h
mov ecx, (cmdline_y_pos-2)*10001h
int 40h
; messages
call draw_messages
; command line & cursor
call draw_cmdline
call draw_cursor
; title & registers & dump & disasm
mov al, 38
mov ebx, (data_x_pos-2)*10001h
mov ecx, (title_y_pos+5)*10000h + (messages_y_pos-2)
int 40h
mov ebx, (data_x_pos+data_x_size+2)*10001h
int 40h
mov ebx, (data_x_pos-2)*10000h + (data_x_pos+data_x_size+2)
mov ecx, (dump_y_pos-3)*10001h
int 40h
mov ecx, (disasm_y_pos-4)*10001h
int 40h
call draw_title
call draw_registers
call draw_dump
call draw_disasm
; end redraw
mov al, 12
push 2
pop ebx
int 40h
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DEBUGGING ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
OnHelp:
mov esi, help_msg
mov edi, [curarg]
cmp byte [edi], 0
jz .x
mov esi, help_groups
call find_cmd
jc .nocmd
mov esi, [esi+12]
.x:
jmp put_message
.nocmd:
mov esi, aUnknownCommand
jmp .x
OnQuit:
xor eax, eax
dec eax
int 40h
get_new_context:
mov esi, context
mov edi, oldcontext
mov ecx, 10
rep movsd
get_context:
push 1
pop ebx
push 69
pop eax
mov ecx, [debuggee_pid]
mov esi, context
push 28h
pop edx
int 40h
ret
set_context:
push 2
pop ebx
push 69
pop eax
mov ecx, [debuggee_pid]
mov esi, context
push 28h
pop edx
int 40h
ret
get_dump:
mov edi, dumpdata
mov esi, [edi-4]
mov edx, dump_height*10h
mov ecx, edx
xor eax, eax
push edi
rep stosb
pop edi
mov ecx, [debuggee_pid]
mov al, 69
push 6
pop ebx
int 40h
cmp eax, -1
jnz @f
mov esi, read_mem_err
call put_message
xor eax, eax
@@:
mov [edi-8], eax
; call restore_from_breaks
; ret
restore_from_breaks:
; in: edi=buffer,eax=size,esi=address
mov ebx, breakpoints
@@:
test byte [ebx+4], 1
jz .cont ; ignore invalid
test byte [ebx+4], 2 or 8
jnz .cont ; ignore disabled and memory breaks
mov ecx, [ebx]
sub ecx, esi
cmp ecx, eax
jae .cont
mov dl, [ebx+5]
mov [edi+ecx], dl
.cont:
add ebx, 6
cmp ebx, breakpoints+breakpoints_n*6
jb @b
ret
OnLoad:
mov esi, [curarg]
OnLoadInit:
mov edi, loadname
or [prgname_len], -1
mov [prgname_ptr], edi
.copyname:
lodsb
stosb
inc [prgname_len]
cmp al, '/'
jnz @f
or [prgname_len], -1
mov [prgname_ptr], edi
@@:
cmp al, ' '
ja .copyname
mov byte [edi-1], 0
and [load_params], 0
dec esi
call skip_spaces
cmp al, 0
jz @f
mov [load_params], esi
@@:
and [dumppos], 0
do_reload:
push 18
pop eax
push 7
pop ebx
int 40h
mov [dbgwnd], eax
xchg ecx, eax
push 70
pop eax
mov ebx, fn70_load_block
int 40h
test eax, eax
jns .load_ok
.load_err:
push eax
mov esi, load_err_msg
call put_message
pop eax
not eax
cmp eax, 0x20
jae .unk_err
mov esi, [load_err_msgs+eax*4]
test esi, esi
jnz put_message
.unk_err:
mov esi, unk_err_msg
inc eax
push eax
call put_message_nodraw
jmp draw_messages
.load_ok:
mov [debuggee_pid], eax
mov [bSuspended], 1
push ecx
call get_context
mov edi, oldcontext
mov ecx, 10
rep movsd
; activate debugger window
pop ecx
mov bl, 3
push 18
pop eax
int 40h
call redraw_title
call redraw_registers
call get_dump
call redraw_dump
call update_disasm_eip_force
mov esi, load_succ_msg
push [debuggee_pid]
call put_message_nodraw
call draw_messages
; now test for packed progs
cmp [disasm_buf_size], 100h
jz @f
ret
@@:
mov esi, mxp_nrv_sig
mov ebp, disasm_buffer
mov edi, ebp
push 3
pop ecx
repz cmpsb
jnz .not_mxp_nrv
cmpsb
mov cl, mxp_nrv_sig_size-4
repz cmpsb
mov esi, mxp_nrv_name
jz .packed
.not_mxp_nrv:
mov esi, mxp_sig
mov edi, ebp
mov cl, mxp_sig_size
repz cmpsb
mov esi, mxp_name
jz .packed
.not_mxp:
mov esi, mxp_lzo_sig1
mov edi, ebp
mov cl, mxp_lzo_sig1_size
repz cmpsb
mov esi, mxp_lzo_name
jz .packed
mov esi, mxp_lzo_sig2
mov edi, ebp
mov cl, 8
repz cmpsb
jnz .not_mxp_lzo
cmpsb
mov cl, mxp_lzo_sig2_size - 9
repz cmpsb
mov esi, mxp_lzo_name
jz .packed
.not_mxp_lzo:
mov esi, mtappack_name
cmp dword [ebp], 0xBF5E246A
jnz .not_mtappack
cmp dword [ebp+8], 0xEC4E8B57
jnz .not_mtappack1
cmp dword [ebp+12], 0x8D5EA4F3
jnz .not_mtappack1
cmp byte [ebp+12h], 0xE9
jz .packed
.not_mtappack1:
cmp word [ebp+8], 0xB957
jnz .not_mtappack
cmp dword [ebp+14], 0x575EA4F3
jnz .not_mtappack2
cmp byte [ebp+17h], 0xE9
jz .packed
.not_mtappack2:
cmp dword [ebp+14], 0x5F8DA4F3
jnz .not_mtappack3
cmp word [ebp+18], 0xE9FC
jz .packed
.not_mtappack3:
cmp word [ebp+14], 0xA4F3
jnz .not_mtappack
cmp byte [ebp+15h], 0xE9
jz .packed
.not_mtappack:
ret
.packed:
push esi
mov esi, aPacked1
call put_message_nodraw
pop esi
call put_message_nodraw
mov esi, aPacked2
call put_message
call hide_cursor
push 40
pop eax
push 7
pop ebx
int 40h
.wait:
push 10
pop eax
int 40h
dec eax
jz .redraw
dec eax
jz .key
or eax, -1
int 40h
.redraw:
call draw_window
call hide_cursor
jmp .wait
.key:
mov al, 2
int 40h
cmp ah, 'y'
jz .yes
cmp ah, 'Y'
jz .yes
cmp ah, 0xD
jz .yes
cmp ah, 'n'
jz .no
cmp ah, 'N'
jnz .wait
.no:
push 40
pop eax
mov ebx, 0x107
int 40h
call draw_cursor
mov esi, aN_str
jmp put_message
.yes:
push 40
pop eax
mov ebx, 0x107
int 40h
call draw_cursor
mov esi, aY_str
call put_message
call OnUnpack
ret
mxp_nrv_sig:
xor eax, eax
mov ecx, 0x95 ; 0xA1 for programs with parameters
mov [eax], ecx
add ecx, [eax+24h]
push 40h
pop esi
mov edi, [eax+20h]
push edi
rep movsb
jmp dword [esp]
pop esi
add esi, [eax]
xor edi, edi
mxp_nrv_sig_size = $ - mxp_nrv_sig
mxp_sig:
mov ecx, 1CBh
push 46h
pop esi
mov edi, [20h]
rep movsb
mov ecx, [24h]
rep movsb
jmp dword [20h]
mov eax, [20h]
add eax, 1CBh
push eax
push dword [24h]
push 0
push 8
call $+0x25
mxp_sig_size = $ - mxp_sig
mxp_lzo_sig1:
xor eax, eax
mov ebp, 0FFh
mov ecx, 175h
mov [eax], ecx
add ecx, [eax+24h]
push 45h
pop esi
mov edi, [eax+20h]
push edi
rep movsb
jmp dword [esp]
pop ebx
add ebx, [eax]
xor edi, edi
cmp byte [ebx], 11h
jbe $+0x1A
mxp_lzo_sig1_size = $ - mxp_lzo_sig1
mxp_lzo_sig2:
xor eax, eax
mov ebp, 0FFh
mov ecx, 188h ; or 177h
mov [eax], ecx
add ecx, [eax+24h]
push 44h
pop esi
mov edi, [eax+20h]
rep movsb
jmp dword [eax+20h]
mov ebx, [eax+20h]
add ebx, [eax]
mxp_lzo_sig2_size = $ - mxp_lzo_sig2
OnReload:
cmp [debuggee_pid], 0
jnz terminate_reload
mov esi, need_debuggee
cmp byte [loadname], 0
jnz do_reload
jz put_message
terminate_reload:
mov [bReload], 1
OnTerminate:
mov ecx, [debuggee_pid]
push 8
pop ebx
push 69
pop eax
int 40h
ret
AfterSuspend:
mov [bSuspended], 1
call get_new_context
call get_dump
call redraw_title
call redraw_registers
call redraw_dump
call update_disasm_eip
ret
OnSuspend:
mov ecx, [debuggee_pid]
push 4
pop ebx
push 69
pop eax
int 40h
call AfterSuspend
mov esi, aSuspended
jmp put_message
DoResume:
mov ecx, [debuggee_pid]
push 5
pop ebx
push 69
pop eax
int 40h
mov [bSuspended], 0
ret
OnResume:
mov esi, [curarg]
cmp byte [esi], 0
jz GoOn
call calc_expression
jc .ret
mov eax, ebp
push eax
call find_enabled_breakpoint
pop eax
jz GoOn
mov bl, 5 ; valid enabled one-shot
call add_breakpoint
jnc GoOn
mov esi, aBreakpointLimitExceeded
call put_message
.ret:
ret
GoOn:
; test for enabled breakpoint at eip
mov eax, [_eip]
call find_enabled_breakpoint
jnz .nobreak
; temporarily disable breakpoint, make step, enable breakpoint, continue
inc eax
mov [temp_break], eax
mov [bAfterGo], 1
dec eax
call disable_breakpoint
call get_context
or byte [_eflags+1], 1 ; set TF
call set_context
and byte [_eflags+1], not 1
call DoResume
ret
.nobreak:
call DoResume
call redraw_title
call redraw_registers
call redraw_dump
ret
OnDetach:
mov ecx, [debuggee_pid]
push 3
pop ebx
push 69
pop eax
int 40h
and [debuggee_pid], 0
call redraw_title
call redraw_registers
call redraw_dump
mov esi, aContinued
jmp put_message
after_go_exception:
push eax
mov eax, [temp_break]
dec eax
push esi
call enable_breakpoint
; in any case, clear TF and RF
call get_new_context
and [_eflags], not 10100h ; clear TF,RF
call set_context
xor edx, edx
mov [temp_break], edx
xchg dl, [bAfterGo]
pop esi
pop eax
cmp dl, 2
jnz @f
lodsd
push esi
call get_dump
jmp exception.done
@@: test eax, eax
jz .notint1
; if exception is result of single step, simply ignore it and continue
test dword [esi], 0xF
jnz dbgmsgstart.5
lodsd
push esi
mov esi, oldcontext
mov edi, context
mov ecx, 28h/4
rep movsd
call DoResume
jmp dbgmsgend
.notint1:
; in other case, work as without temp_break
lodsd
push esi
push eax
jmp exception.4
.notour:
debugmsg:
neg [dbgbufsize]
mov esi, dbgbuf
dbgmsgstart:
lodsd
; push eax esi
; push dword [esi]
; mov esi, dbgmsg_str
; call put_message_nodraw
; pop esi eax
add esi, 4
dec eax
jz exception
dec eax
jz terminated
mov [bSuspended], 1
cmp [bAfterGo], 0
jnz after_go_exception
push esi
call get_new_context
and [_eflags], not 10100h ; clear TF,RF
call set_context
pop esi
.5:
push esi
call get_dump
pop esi
lodsd
xor ecx, ecx
.6:
bt eax, ecx
jnc .7
mov ebx, [drx_break+ecx*4]
test ebx, ebx
jz .7
pushad
dec ebx
push ebx
mov esi, aBreakStop
call put_message_nodraw
popad
.7:
inc ecx
cmp cl, 4
jb .6
push esi
jmp exception.done_draw
terminated:
push esi
mov esi, terminated_msg
call put_message
and [debuggee_pid], 0
and [temp_break], 0
mov [bAfterGo], 0
xor eax, eax
mov ecx, breakpoints_n*6/4+4
mov edi, breakpoints
rep stosd
cmp [bReload], 1
sbb [bReload], -1
jmp exception.done
exception:
mov [bSuspended], 1
cmp [bAfterGo], 0
jnz after_go_exception
lodsd
push esi
push eax
call get_new_context
and [_eflags], not 10100h ; clear TF,RF
call set_context
.4:
call get_dump
pop eax
; int3 command generates exception 0D, #GP
push eax
cmp al, 0Dh
jnz .notdbg
; check for 0xCC byte at eip
push 0
push 69
pop eax
push 6
pop ebx
mov ecx, [debuggee_pid]
mov edi, esp
mov esi, [_eip]
push 1
pop edx
int 40h
pop eax
cmp al, 0xCC
jnz .notdbg
; this is either dbg breakpoint or int3 cmd in debuggee
mov eax, [_eip]
call find_enabled_breakpoint
jnz .user_int3
; dbg breakpoint; clear if one-shot
pop ecx
push eax
mov esi, aBreakStop
test byte [edi+4], 4
jz .put_msg_eax
pop ecx
call clear_breakpoint
jmp .done
.user_int3:
mov eax, [_eip]
inc [_eip]
pop ecx
push eax
call set_context
mov esi, aUserBreak
jmp .put_msg_eax
.notdbg:
mov esi, aException
.put_msg_eax:
call put_message_nodraw
.done_draw:
call draw_messages
.done:
push 18
pop eax
push 3
pop ebx
mov ecx, [dbgwnd]
int 40h ; activate dbg window
call redraw_title
call redraw_registers
call redraw_dump
call update_disasm_eip
dbgmsgend:
pop esi
mov ecx, [dbgbuflen]
add ecx, dbgbuf
cmp esi, ecx
jnz dbgmsgstart
and [dbgbuflen], 0
neg [dbgbufsize]
cmp [bReload], 2
jnz @f
mov [bReload], 0
call do_reload
@@:
jmp waitevent
CtrlF7:
cmp [debuggee_pid], 0
jz .no
call OnStep
.no:
jmp waitevent
CtrlF8:
cmp [debuggee_pid], 0
jz CtrlF7.no
call OnProceed
jmp CtrlF7.no
OnStep:
cmp [bSuspended], 0
jz .running
call get_context
or byte [_eflags+1], 1 ; set TF
call set_context
and byte [_eflags+1], not 1
; if instruction at eip is "int xx", set one-shot breakpoint immediately after
mov eax, [_eip]
call find_enabled_breakpoint
jnz @f
cmp byte [edi+5], 0xCD
jz .int
@@:
push 0
push 69
pop eax
push 6
pop ebx
mov ecx, [debuggee_pid]
push 3
pop edx
mov edi, esp
mov esi, [_eip]
int 40h
cmp eax, edx
pop eax
jnz .doit
cmp al, 0xCD
jz .int
; resume process
.doit:
call GoOn
cmp [bAfterGo], 0
jz @f
mov [bAfterGo], 2
@@:
ret
.int:
mov eax, [_eip]
inc eax
inc eax
push eax
call find_enabled_breakpoint
pop eax
jz .doit
; there is no enabled breakpoint yet; set temporary breakpoint
mov bl, 5
call add_breakpoint
jmp .doit
.running:
mov esi, aRunningErr
jmp put_message
OnProceed:
cmp [bSuspended], 0
jz OnStep.running
mov esi, [_eip]
@@:
call get_byte_nobreak
jc OnStep
inc esi
; skip prefixes
call is_prefix
jz @b
cmp al, 0xE8 ; call
jnz @f
add esi, 4
jmp .doit
@@: ; A4,A5 = movs, A6,A7=cmps
cmp al, 0xA4
jb @f
cmp al, 0xA8
jb .doit
@@: ; AA,AB=stos, AC,AD=lods, AE,AF=scas
cmp al, 0xAA
jb @f
cmp al, 0xB0
jb .doit
@@: ; E0=loopnz,E1=loopz,E2=loop
cmp al, 0xE0
jb .noloop
cmp al, 0xE2
ja .noloop
inc esi
jmp .doit
.noloop: ; FF /2 = call
cmp al, 0xFF
jnz OnStep
call get_byte_nobreak
jc OnStep
inc esi
mov cl, al
and al, 00111000b
cmp al, 00010000b
jnz OnStep
; skip instruction
mov al, cl
and eax, 7
shr cl, 6
jz .mod0
jp .doit
cmp al, 4
jnz @f
inc esi
@@:
inc esi
dec cl
jz @f
add esi, 3
@@:
jmp .doit
.mod0:
cmp al, 4
jnz @f
call get_byte_nobreak
jc OnStep
inc esi
and al, 7
@@:
cmp al, 5
jnz .doit
add esi, 4
.doit:
; insert one-shot breakpoint at esi and resume
call get_byte_nobreak
jc OnStep
mov eax, esi
call find_enabled_breakpoint
jz .ret
mov eax, esi
mov bl, 5
call add_breakpoint
jmp OnStep.doit
.ret:
ret
get_byte_nobreak:
mov eax, esi
call find_enabled_breakpoint
jnz .nobreak
mov al, [edi+5]
clc
ret
.nobreak:
push 69
pop eax
push 6
pop ebx
mov ecx, [debuggee_pid]
xor edx, edx
push edx
inc edx
mov edi, esp
int 40h
dec eax
clc
jz @f
stc
@@: pop eax
ret
is_prefix:
cmp al, 0x64 ; fs:
jz .ret
cmp al, 0x65 ; gs:
jz .ret
cmp al, 0x66 ; use16/32
jz .ret
cmp al, 0x67 ; addr16/32
jz .ret
cmp al, 0xF0 ; lock
jz .ret
cmp al, 0xF2 ; repnz
jz .ret
cmp al, 0xF3 ; rep(z)
jz .ret
cmp al, 0x2E ; cs:
jz .ret
cmp al, 0x36 ; ss:
jz .ret
cmp al, 0x3E ; ds:
jz .ret
cmp al, 0x26 ; es:
.ret: ret
token_end equ 1
token_reg equ 2
token_hex equ 3
token_add equ 4
token_sub equ 5
token_mul equ 6
token_div equ 7
token_lp equ 8
token_rp equ 9
token_err equ -1
is_hex_digit:
cmp al, '0'
jb .no
cmp al, '9'
jbe .09
cmp al, 'A'
jb .no
cmp al, 'F'
jbe .AF
cmp al, 'a'
jb .no
cmp al, 'f'
jbe .af
.no:
stc
ret
.09:
sub al, '0'
; clc
ret
.AF:
sub al, 'A'-10
; clc
ret
.af:
sub al, 'a'-10
; clc
ret
find_reg:
mov edi, reg_table
.findreg:
movzx ecx, byte [edi]
stc
jecxz .regnotfound
inc edi
push esi edi ecx
@@:
lodsb
or al, 20h
scasb
loopz @b
pop ecx edi esi
lea edi, [edi+ecx+1]
jnz .findreg
movzx edi, byte [edi-1]
add esi, ecx
.regnotfound:
ret
expr_get_token:
lodsb
cmp al, 0
jz .end_token
cmp al, ' '
jbe expr_get_token
cmp al, '+'
jz .add
cmp al, '-'
jz .sub
cmp al, '*'
jz .mul
cmp al, '/'
jz .div
cmp al, '('
jz .lp
cmp al, ')'
jnz .notsign
.rp:
mov al, token_rp
ret
.div:
mov al, token_div
ret
.end_token:
mov al, token_end
ret
.add:
mov al, token_add
ret
.sub:
mov al, token_sub
ret
.mul:
mov al, token_mul
ret
.lp:
mov al, token_lp
ret
.notsign:
dec esi
call find_reg
jc .regnotfound
mov al, token_reg
ret
.regnotfound:
; test for hex number
xor ecx, ecx
xor edi, edi
xor eax, eax
@@:
lodsb
call is_hex_digit
jc @f
shl edi, 4
or edi, eax
inc ecx
jmp @b
@@:
dec esi
jecxz .err
cmp ecx, 8
ja .err
mov al, token_hex
ret
.err:
mov al, token_err
mov esi, aParseError
ret
expr_read2:
cmp al, token_hex
jz .hex
cmp al, token_reg
jz .reg
cmp al, token_lp
jz .lp
mov al, token_err
mov esi, aParseError
ret
.hex:
mov ebp, edi
.ret:
jmp expr_get_token
.reg:
cmp edi, 24
jz .eip
sub edi, 4
jb .8lo
sub edi, 4
jb .8hi
sub edi, 8
jb .16
mov ebp, [_eax+edi*4]
jmp .ret
.16:
movzx ebp, word [_eax+(edi+8)*4]
jmp .ret
.8lo:
movzx ebp, byte [_eax+(edi+4)*4]
jmp .ret
.8hi:
movzx ebp, byte [_eax+(edi+4)*4+1]
jmp .ret
.eip:
mov ebp, [_eip]
jmp .ret
.lp:
call expr_get_token
call expr_read0
cmp al, token_err
jz @f
cmp al, token_rp
jz expr_get_token
mov al, token_err
mov esi, aParseError
@@: ret
expr_read1:
call expr_read2
.1:
cmp al, token_mul
jz .mul
cmp al, token_div
jz .div
ret
.mul:
push ebp
call expr_get_token
call expr_read2
pop edx
; ebp := edx*ebp
imul ebp, edx
jmp .1
.div:
push ebp
call expr_get_token
call expr_read2
pop edx
; ebp := edx/ebp
test ebp, ebp
jz .div0
push eax
xor eax, eax
xchg eax, edx
div ebp
xchg eax, ebp
pop eax
jmp .1
.div0:
mov al, token_err
mov esi, aDivByZero
ret
expr_read0:
xor ebp, ebp
cmp al, token_add
jz .add
cmp al, token_sub
jz .sub
call expr_read1
.1:
cmp al, token_add
jz .add
cmp al, token_sub
jz .sub
ret
.add:
push ebp
call expr_get_token
call expr_read1
pop edx
; ebp := edx+ebp
add ebp, edx
jmp .1
.sub:
push ebp
call expr_get_token
call expr_read1
pop edx
; ebp := edx-ebp
xchg edx, ebp
sub ebp, edx
jmp .1
calc_expression:
; in: esi->expression
; out: CF=1 if error
; CF=0 and ebp=value if ok
call expr_get_token
call expr_read0
cmp al, token_end
jz .end
cmp al, token_err
jz @f
mov esi, aParseError
@@:
call put_message
stc
ret
.end:
clc
ret
OnCalc:
mov esi, [curarg]
call calc_expression
jc .ret
push ebp
mov esi, calc_string
call put_message_nodraw
jmp draw_messages
.ret:
ret
OnDump:
mov esi, [curarg]
cmp byte [esi], 0
jnz .param
add [dumppos], dump_height*10h
jmp .doit
.param:
call calc_expression
jc .ret
mov [dumppos], ebp
.doit:
call get_dump
call redraw_dump
.ret:
ret
OnUnassemble:
mov esi, [curarg]
cmp byte [esi], 0
jnz .param
mov eax, [disasm_start_pos]
mov ecx, disasm_height
mov [disasm_cur_pos], eax
@@:
push ecx
call disasm_instr
pop ecx
jc .err
loop @b
mov eax, [disasm_cur_pos]
jmp .doit
.param:
call calc_expression
jc .ret
mov eax, ebp
.doit:
push eax
push [disasm_start_pos]
mov [disasm_start_pos], eax
call update_disasm
pop [disasm_start_pos]
pop eax
cmp [disasm_cur_str], 0
jz @f
mov [disasm_start_pos], eax
.ret:
ret
@@:
call update_disasm
.err:
mov esi, aInvAddr
jmp put_message
OnReg:
mov esi, [curarg]
call skip_spaces
call find_reg
jnc @f
.err:
mov esi, RSyntax
jmp put_message
@@:
call skip_spaces
test al, al
jz .err
cmp al, '='
jnz @f
inc esi
call skip_spaces
test al, al
jz .err
@@:
push edi
call calc_expression
pop edi
jc .ret
; now edi=register id, ebp=value
cmp [bSuspended], 0
mov esi, aRunningErr
jz put_message
xchg eax, ebp
cmp edi, 24
jz .eip
sub edi, 4
jb .8lo
sub edi, 4
jb .8hi
sub edi, 8
jb .16
mov [_eax+edi*4], eax
jmp .ret
.16:
mov word [_eax+(edi+8)*4], ax
jmp .ret
.8lo:
mov byte [_eax+(edi+4)*4], al
jmp .ret
.8hi:
mov byte [_eax+(edi+4)*4+1], al
jmp .ret
.eip:
mov [_eip], eax
call update_disasm_eip
.ret:
call set_context
jmp redraw_registers
; Breakpoints manipulation
OnBp:
mov esi, [curarg]
call calc_expression
jc .ret
xchg eax, ebp
push eax
call find_breakpoint
inc eax
pop eax
jz .notfound
mov esi, aDuplicateBreakpoint
jmp .sayerr
.notfound:
mov bl, 1
call add_breakpoint
jnc .ret
mov esi, aBreakpointLimitExceeded
.sayerr:
call put_message
.ret:
jmp redraw_disasm
OnBpmb:
mov dh, 0011b
jmp DoBpm
OnBpmw:
mov dh, 0111b
jmp DoBpm
OnBpmd:
mov dh, 1111b
DoBpm:
mov esi, [curarg]
cmp byte [esi], 'w'
jnz @f
and dh, not 2
inc esi
@@:
push edx
call calc_expression
pop edx
jnc @f
ret
@@:
; ebp=expression, dh=flags
movzx eax, dh
shr eax, 2
test ebp, eax
jz @f
mov esi, aUnaligned
jmp put_message
@@:
mov eax, ebp
mov bl, 0Bh
call add_breakpoint
jnc @f
mov esi, aBreakpointLimitExceeded
jmp put_message
@@:
; now find index
push eax
xor ecx, ecx
.l1:
cmp [drx_break+ecx*4], 0
jnz .l2
push 69
pop eax
push ecx
mov dl, cl
mov ecx, [debuggee_pid]
mov esi, ebp
push 9
pop ebx
int 40h
test eax, eax
jz .ok
pop ecx
.l2:
inc ecx
cmp ecx, 4
jb .l1
pop eax
call clear_breakpoint
mov esi, aBreakpointLimitExceeded
jmp put_message
.ok:
pop ecx
pop eax
and byte [edi], not 2 ; breakpoint is enabled
shl dl, 6
or dl, dh
mov byte [edi+1], dl
inc eax
mov [drx_break+ecx*4], eax
ret
OnBc:
mov esi, [curarg]
@@: call get_hex_number
jc OnBp.ret
call clear_breakpoint
jmp @b
OnBd:
mov esi, [curarg]
@@: call get_hex_number
jc OnBp.ret
call disable_breakpoint
jmp @b
OnBe:
mov esi, [curarg]
@@: call get_hex_number
jc OnBp.ret
push eax
call find_enabled_breakpoint
pop eax
jz .err
call enable_breakpoint
jmp @b
.err:
mov esi, OnBeErrMsg
jmp put_message
get_hex_number:
call skip_spaces
xor ecx, ecx
xor edx, edx
@@:
lodsb
call is_hex_digit
jc .ret
shl edx, 4
or dl, al
inc ecx
jmp @b
.ret:
dec esi
cmp ecx, 1
xchg eax, edx
ret
OnBl:
mov esi, [curarg]
cmp byte [esi], 0
jz .listall
call get_hex_number
jc .ret
cmp eax, breakpoints_n
jae .err
push eax
add eax, eax
lea edi, [breakpoints + eax + eax*2]
pop eax
test byte [edi+4], 1
jz .err
call show_break_info
.ret:
ret
.err:
mov esi, aInvalidBreak
jmp put_message
.listall:
mov edi, breakpoints
xor eax, eax
@@:
test byte [edi+4], 1
jz .cont
push edi eax
call show_break_info
pop eax edi
.cont:
add edi, 6
inc eax
cmp eax, breakpoints_n
jb @b
ret
show_break_info:
push edi
test byte [edi+4], 8
jnz .dr
push dword [edi]
push eax
mov esi, aBreakNum
call put_message_nodraw
jmp .cmn
.dr:
push eax
mov esi, aMemBreak1
call put_message_nodraw
pop edi
push edi
mov esi, aMemBreak2
test byte [edi+5], 2
jz @f
mov esi, aMemBreak3
@@:
call put_message_nodraw
pop edi
push edi
mov esi, aMemBreak6
test byte [edi+5], 8
jnz @f
mov esi, aMemBreak5
test byte [edi+5], 4
jnz @f
mov esi, aMemBreak4
@@:
call put_message_nodraw
pop edi
push edi
push dword [edi]
mov esi, aMemBreak7
call put_message_nodraw
.cmn:
pop edi
test byte [edi+4], 2
jz @f
push edi
mov esi, aDisabled
call put_message_nodraw
pop edi
@@:
test byte [edi+4], 4
jz @f
mov esi, aOneShot
call put_message_nodraw
@@:
mov esi, newline
jmp put_message
add_breakpoint:
; in: eax=address, bl=flags
; out: CF=1 => error, CF=0 => eax=breakpoint number
xor ecx, ecx
mov edi, breakpoints
@@:
test byte [edi+4], 1
jz .found
add edi, 6
inc ecx
cmp ecx, breakpoints_n
jb @b
stc
ret
.found:
stosd
xchg eax, ecx
mov [edi], bl
test bl, 2
jnz @f
or byte [edi], 2
push eax
call enable_breakpoint
pop eax
@@:
clc
ret
clear_breakpoint:
cmp eax, breakpoints_n
jae .ret
mov ecx, 4
inc eax
.1:
cmp [drx_break-4+ecx*4], eax
jnz @f
and [drx_break-4+ecx*4], 0
@@: loop .1
dec eax
push eax
add eax, eax
lea edi, [breakpoints + eax + eax*2 + 4]
test byte [edi], 1
pop eax
jz .ret
push edi
call disable_breakpoint
pop edi
mov byte [edi], 0
.ret:
ret
disable_breakpoint:
cmp eax, breakpoints_n
jae .ret
add eax, eax
lea edi, [breakpoints + eax + eax*2 + 5]
test byte [edi-1], 1
jz .ret
test byte [edi-1], 2
jnz .ret
or byte [edi-1], 2
test byte [edi-1], 8
jnz .dr
push esi
push 7
pop ebx
push 69
pop eax
mov ecx, [debuggee_pid]
xor edx, edx
inc edx
mov esi, [edi-5]
int 40h
pop esi
.ret:
ret
.dr:
mov dl, [edi]
shr dl, 6
mov dh, 80h
push 69
pop eax
push 9
pop ebx
mov ecx, [debuggee_pid]
int 40h
ret
enable_breakpoint:
push esi
cmp eax, breakpoints_n
jae .ret
add eax, eax
lea edi, [breakpoints + eax + eax*2 + 5]
test byte [edi-1], 1
jz .ret
test byte [edi-1], 2
jz .ret
and byte [edi-1], not 2
test byte [edi-1], 8
jnz .dr
push 6
pop ebx
push 69
pop eax
mov esi, [edi-5]
mov ecx, [debuggee_pid]
xor edx, edx
inc edx
int 40h
dec eax
jnz .err
mov al, 69
push 0xCC
mov edi, esp
inc ebx
int 40h
pop eax
.ret:
pop esi
ret
.err:
or byte [edi-1], 2
mov esi, aBreakErr
call put_message
pop esi
ret
.dr:
push 9
pop ebx
push 69
pop eax
mov esi, [edi-5]
mov ecx, [debuggee_pid]
mov dl, [edi]
shr dl, 6
mov dh, [edi]
and dh, 0xF
int 40h
test eax, eax
jnz .err
pop esi
ret
find_breakpoint:
xor ecx, ecx
xchg eax, ecx
mov edi, breakpoints
@@:
test byte [edi+4], 1
jz .cont
test byte [edi+4], 8
jnz .cont
cmp [edi], ecx
jz .found
.cont:
add edi, 6
inc eax
cmp eax, breakpoints_n
jb @b
or eax, -1
.found:
ret
find_enabled_breakpoint:
xor ecx, ecx
xchg eax, ecx
mov edi, breakpoints
@@:
test byte [edi+4], 1
jz .cont
test byte [edi+4], 2 or 8
jnz .cont
cmp [edi], ecx
jz .found
.cont:
add edi, 6
inc eax
cmp eax, breakpoints_n
jb @b
or eax, -1
.found:
ret
OnUnpack:
; program must be loaded - checked when command was parsed
; program must be stopped
mov esi, aRunningErr
cmp [bSuspended], 0
jz put_message
; all breakpoints must be disabled
mov edi, breakpoints
@@:
test byte [edi+4], 1
jz .cont
test byte [edi+4], 2
jnz .cont
mov esi, aEnabledBreakErr
jmp put_message
.cont:
add edi, 6
cmp edi, breakpoints+breakpoints_n*6
jb @b
; ok, now do it
; set breakpoint on 0xC dword access
push 9
pop ebx
mov ecx, [debuggee_pid]
mov dx, 1111b*256
push 0xC
pop esi
@@:
push 69
pop eax
int 40h
test eax, eax
jz .breakok
inc edx
cmp dl, 4
jb @b
.breakok:
call GoOn
; now wait for event
.wait:
push 10
pop eax
int 40h
dec eax
jz .redraw
dec eax
jz .key
dec eax
jnz .debug
; button; we have only one button, close
or eax, -1
int 40h
.redraw:
call draw_window
jmp .wait
.key:
mov al, 2
int 40h
cmp ah, 3 ; Ctrl+C
jnz .wait
.userbreak:
mov esi, aInterrupted
.x1:
push edx esi
call put_message
pop esi edx
or dh, 80h
push 69
pop eax
push 9
pop ebx
mov ecx, [debuggee_pid]
int 40h
cmp esi, aUnpacked
jnz OnSuspend
jmp AfterSuspend
.debug:
cmp [dbgbuflen], 4*3
jnz .notour
cmp dword [dbgbuf], 3
jnz .notour
test byte [dbgbuf+8], 1
jnz .our
.notour:
mov esi, aInterrupted
push edx
call put_message
pop edx
or dh, 80h
push 69
pop eax
push 9
pop ebx
mov ecx, [debuggee_pid]
int 40h
jmp debugmsg
.our:
and [dbgbuflen], 0
push edx
call get_context
push eax
mov al, 69
mov bl, 6
mov ecx, [debuggee_pid]
mov edi, esp
push 4
pop edx
push 0xC
pop esi
int 40h
pop eax
pop edx
cmp eax, [_eip]
jz .done
call DoResume
jmp .wait
.done:
mov esi, aUnpacked
jmp .x1
disasm_get_byte:
; out: al=byte
push ecx
mov ecx, [disasm_cur_pos]
sub ecx, [disasm_start_pos]
cmp ecx, [disasm_buf_size]
jae disasm_err
mov al, [disasm_buffer+ecx]
pop ecx
inc [disasm_cur_pos]
ret
disasm_get_word:
push ecx
mov ecx, [disasm_cur_pos]
sub ecx, [disasm_start_pos]
inc ecx
cmp ecx, [disasm_buf_size]
jae disasm_err
mov ax, word [disasm_buffer-1+ecx]
pop ecx
add [disasm_cur_pos], 2
ret
disasm_get_dword:
push ecx
mov ecx, [disasm_cur_pos]
sub ecx, [disasm_start_pos]
add ecx, 3
cmp ecx, [disasm_buf_size]
jae disasm_err
mov eax, dword [disasm_buffer-3+ecx]
pop ecx
add [disasm_cur_pos], 4
ret
disasm_err:
mov esp, ebp
stc_ret:
stc
ret
disasm_ret:
mov esp, ebp
and byte [edi], 0
ret
disasm_instr:
mov ebp, esp
cmp [debuggee_pid], 0
jz stc_ret
mov edi, disasm_string
xor ecx, ecx
; ecx=flags
disasm_loop1:
xor eax, eax
call disasm_get_byte
jmp dword [disasm_table_1 + eax*4]
cop0:
clock:
crepnz:
crep:
csegcs:
csegds:
cseges:
csegss:
csegfs:
cseggs:
call @f
db 0x2E,3,'cs:'
db 0x36,3,'ss:'
db 0x3E,3,'ds:'
db 0x26,3,'es:'
db 0x64,3,'fs:'
db 0x65,3,'gs:'
db 0x06,10,'push es'
db 0x07,10,'pop es'
db 0x0E,10,'push cs'
db 0x16,10,'push ss'
db 0x17,10,'pop ss'
db 0x1E,10,'push ds'
db 0x1F,10,'pop ds'
db 0x27,3,'daa'
db 0x2F,3,'das'
db 0x37,3,'aaa'
db 0x3F,3,'aas'
db 0x60,6,0,'pusha'
db 0x61,5,0,'popa'
db 0x90,3,'nop'
db 0x9B,5,'fwait'
db 0x9C,6,0,'pushf'
db 0x9D,5,0,'popf'
db 0x9E,4,'sahf'
db 0x9F,4,'lahf'
db 0xA4,5,'movsb'
db 0xA5,5,0,'movs'
db 0xA6,5,'cmpsb'
db 0xA7,5,0,'cmps'
db 0xAA,5,'stosb'
db 0xAB,5,0,'stos'
db 0xAC,5,'lodsb'
db 0xAD,5,0,'lods'
db 0xAE,5,'scasb'
db 0xAF,5,0,'scas'
db 0xC3,3,'ret'
db 0xC9,5,'leave'
db 0xCC,4,'int3'
db 0xF0,4,'lock'
db 0xF2,5,'repnz'
db 0xF3,6,'rep(z)'
db 0xF5,3,'cmc'
db 0xF8,3,'clc'
db 0xF9,3,'stc'
db 0xFA,3,'cli'
db 0xFB,3,'sti'
db 0xFC,3,'cld'
db 0xFD,3,'std'
@@:
pop esi
@@:
cmp al, [esi]
jz .found
inc esi
movzx edx, byte [esi]
inc esi
add esi, edx
jmp @b
.found:
inc esi
lodsb
cmp byte [esi], 0
jz @f
movzx ecx, al
disasm_1:
rep movsb
and byte [edi], 0
ret
@@:
mov dl, ch
movzx ecx, al
dec ecx
inc esi
rep movsb
test dl, 1
mov al, 'w'
jnz @f
mov al, 'd'
@@: stosb
and byte [edi], 0
ret
c67:
or ch, 2
jmp disasm_loop1
c66:
or ch, 1
jmp disasm_loop1
center:
caam:
cxlat:
crdtsc:
csysenter:
ccpuid:
ccmpxchg:
cbsf:
cbsr:
ccmpxchg8b:
cunk:
cerr:
mov eax, '???'
stosd
clc
ret
cF:
call disasm_get_byte
jmp dword [disasm_table_2 + eax*4]
macro disasm_set_modew
{
test al, 1
jz @f
or ch, 80h
@@:
}
cmov2:
disasm_set_modew
; mov r/m,i
call disasm_get_byte
dec [disasm_cur_pos]
test al, 00111000b
jnz cunk
mov eax, 'mov '
stosd
mov eax, ' '
stosd
call disasm_readrmop
mov ax, ', '
stosw
xor eax, eax
test ch, 80h
jnz .1
call disasm_get_byte
jmp .3
.1:
test ch, 1
jnz .2
call disasm_get_dword
jmp .3
.2:
call disasm_get_word
.3:
call disasm_write_num
and byte [edi], 0
ret
cret2:
mov eax, 'ret '
stosd
mov eax, ' '
stosd
xor eax, eax
jmp cmov2.2
disasm_write_num:
push ecx eax
inc edi
@@:
mov ecx, eax
shr eax, 4
jz @f
inc edi
jmp @b
@@:
pop eax
cmp ecx, 10
jb @f
inc edi
@@:
push edi eax
@@:
mov ecx, eax
and al, 0xF
cmp al, 10
sbb al, 69h
das
dec edi
mov [edi], al
mov eax, ecx
shr eax, 4
jnz @b
cmp ecx, 10
jb @f
mov byte [edi-1], '0'
@@:
pop eax edi ecx
cmp eax, 10
jb @f
mov byte [edi], 'h'
inc edi
@@:
ret
label disasm_regs32 dword
label disasm_regs dword
db 'eax',0
db 'ecx',0
db 'edx',0
db 'ebx',0
db 'esp',0
db 'ebp',0
db 'esi',0
db 'edi',0
disasm_regs16 dw 'ax','cx','dx','bx','sp','bp','si','di'
disasm_regs8 dw 'al','cl','dl','bl','ah','ch','dh','bh'
disasm_scale db '1248'
disasm_readrmop:
call disasm_get_byte
test ch, 40h
jnz .skip_size
push eax
and al, 0xC0
cmp al, 0xC0
pop eax
jz .skip_size
test ch, 80h
jz .byte
test ch, 1
jnz .word
mov dword [edi], 'dwor'
mov byte [edi+4], 'd'
inc edi
jmp @f
.byte:
test ch, 20h
jz .qb
mov byte [edi], 't'
inc edi
.qb:
mov dword [edi], 'byte'
jmp @f
.word:
test ch, 20h
jz .qw
mov byte [edi], 'q'
inc edi
.qw:
mov dword [edi], 'word'
@@:
mov byte [edi+4], ' '
add edi, 5
.skip_size:
test ch, 2
jnz disasm_readrmop16
push ecx
movzx ecx, al
and eax, 7
shr ecx, 6
jz .vmod0
jp .vmod3
mov byte [edi], '['
inc edi
cmp al, 4
jz .sib1
mov eax, [disasm_regs+eax*4]
stosd
dec edi
jmp @f
.sib1:
call .parse_sib
@@:
mov al, '+'
stosb
dec ecx
jz .vmod1
call disasm_get_dword
jmp @f
.vmod1:
call disasm_get_byte
movsx eax, al
@@:
test eax, eax
jns .2
neg eax
mov byte [edi-1], '-'
.2:
call disasm_write_num
mov al, ']'
stosb
pop ecx
ret
.vmod3:
pop ecx
test ch, 80h
jz .vmod3_byte
test ch, 1
jnz .vmod3_word
test ch, 20h
jnz .vmod3_sti
mov eax, [disasm_regs32+eax*4]
stosd
dec edi
ret
.vmod3_byte:
mov ax, [disasm_regs8+eax*2]
@@:
stosw
ret
.vmod3_word:
mov ax, [disasm_regs16+eax*2]
jmp @b
.vmod3_sti:
mov word [edi], 'st'
add al, '0'
mov byte [edi+2], al
add edi, 3
ret
.vmod0:
mov byte [edi], '['
inc edi
cmp al, 4
jz .sib2
cmp al, 5
jz .ofs32
mov eax, [disasm_regs+eax*4]
stosd
mov byte [edi-1], ']'
pop ecx
ret
.ofs32:
call disasm_get_dword
jmp .2
.sib2:
call .parse_sib
mov al, ']'
stosb
pop ecx
ret
.parse_sib:
call disasm_get_byte
push edx
mov dl, al
mov dh, 0
and eax, 7
cmp al, 5
jnz @f
jecxz .sib0
@@:
mov eax, [disasm_regs+eax*4]
stosd
dec edi
mov dh, 1
.sib0:
mov al, dl
shr eax, 3
and eax, 7
cmp al, 4
jz .sibret
test dh, dh
jz @f
mov byte [edi], '+'
inc edi
@@:
mov eax, [disasm_regs+eax*4]
stosd
dec edi
shr dl, 6
jz @f
mov al, '*'
stosb
movzx eax, dl
mov al, [disasm_scale+eax]
stosb
@@:
.sibret:
test dh, dh
jnz .sibret2
call disasm_get_dword
cmp byte [edi-1], '['
jz @f
mov byte [edi], '+'
test eax, eax
jns .sibns
neg eax
mov byte [edi], '-'
.sibns:
inc edi
@@:
call disasm_write_num
.sibret2:
pop edx
ret
disasm_rm16_1 dd 'bxsi','bxdi','bpsi','bpdi'
disasm_rm16_2 dw 'si','di','bp','bx'
disasm_readrmop16:
push ecx
movzx ecx, al
and eax, 7
shr ecx, 6
jz .vmod0
jp disasm_readrmop.vmod3 ; mod=3 is the same in 16- and 32-bit code
; 1 or 2
mov byte [edi], '['
inc edi
cmp al, 4
jae @f
mov eax, [disasm_rm16_1+eax*4]
stosw
mov al, '+'
stosb
shr eax, 16
jmp .1
@@:
mov eax, dword [disasm_rm16_2+eax*2-4*2]
.1:
stosw
mov al, '+'
stosb
xor eax, eax
dec ecx
jnz .2
call disasm_get_byte
cbw
jmp @f
.2:
call disasm_get_word
@@:
test ax, ax
jns @f
mov byte [edi-1], '-'
neg ax
@@:
call disasm_write_num
.done1:
mov al, ']'
stosb
pop ecx
ret
.vmod0:
mov byte [edi], '['
inc edi
cmp al, 6
jz .ofs16
cmp al, 4
jae @f
mov eax, [disasm_rm16_1+eax*4]
stosw
mov al, '+'
stosb
shr eax, 16
jmp .3
@@:
mov eax, dword [disasm_rm16_2+eax*2-4*2]
.3:
stosw
jmp .done1
.ofs16:
xor eax, eax
call disasm_get_word
call disasm_write_num
jmp .done1
cpush21:
mov eax, 'push'
stosd
mov eax, ' '
stosd
disasm_i32:
call disasm_get_dword
call disasm_write_num
and byte [edi], 0
ret
cpush22:
mov eax, 'push'
stosd
mov eax, ' '
stosd
call disasm_get_byte
movsx eax, al
call disasm_write_num
and byte [edi], 0
ret
cinc1:
; inc reg32
cdec1:
; dec reg32
cpush1:
; push reg32
cpop1:
; pop reg32
cbswap:
; bswap reg32
mov edx, eax
and edx, 7
shr eax, 3
sub al, 8
mov esi, 'inc '
jz @f
mov esi, 'dec '
dec al
jz @f
mov esi, 'push'
dec al
jz @f
mov esi, 'pop '
dec al
jz @f
mov esi, 'bswa'
@@:
xchg eax, esi
stosd
mov eax, ' '
jz @f
mov al, 'p'
@@:
stosd
xchg eax, edx
call disasm_write_reg1632
and byte [edi], 0
ret
cxchg1:
; xchg eax,reg32
and eax, 7
xchg eax, edx
mov eax, 'xchg'
stosd
mov eax, ' '
stosd
xor eax, eax
call disasm_write_reg1632
mov ax, ', '
stosw
xchg eax, edx
call disasm_write_reg1632
and byte [edi], 0
ret
cint:
mov eax, 'int '
stosd
mov eax, ' '
stosd
disasm_i8u:
xor eax, eax
call disasm_get_byte
call disasm_write_num
and byte [edi], 0
ret
cmov11:
; mov r8,i8
mov ecx, eax
mov eax, 'mov '
stosd
mov eax, ' '
stosd
and ecx, 7
mov ax, [disasm_regs8+ecx*2]
stosw
mov ax, ', '
stosw
jmp disasm_i8u
cmov12:
; mov r32,i32
xchg eax, edx
mov eax, 'mov '
stosd
mov eax, ' '
stosd
xchg eax, edx
and eax, 7
call disasm_write_reg1632
mov ax, ', '
stosw
jmp cmov2.1
disasm_shifts dd 'rol ','ror ','rcl ','rcr ','shl ','shr ','sal ','sar '
cshift2:
; shift r/m,1 = D0/D1
cshift3:
; shift r/m,cl = D2/D3
disasm_set_modew
mov dl, al
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
mov eax, [disasm_shifts+eax*4]
stosd
mov eax, ' '
stosd
call disasm_readrmop
cmp dl, 0xD2
jb .s1
mov eax, ', cl'
stosd
and byte [edi], 0
ret
.s1:
mov eax, ', 1'
stosd
clc
ret
cshift1:
; shift r/m,i8 = C0/C1
disasm_set_modew
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
mov eax, [disasm_shifts+eax*4]
stosd
mov eax, ' '
stosd
call disasm_readrmop
mov ax, ', '
stosw
jmp disasm_i8u
cmov3:
; A0: mov al,[ofs32]
; A1: mov ax/eax,[ofs32]
; A2: mov [ofs32],al
; A3: mov [ofs32],ax/eax
mov edx, 'mov '
xchg eax, edx
stosd
mov eax, ' '
stosd
test dl, 2
jnz .1
call .write_acc
mov ax, ', '
stosw
call .write_ofs32
jmp .2
.1:
call .write_ofs32
mov ax, ', '
stosw
call .write_acc
.2: and byte [edi], 0
ret
.write_acc:
test dl, 1
jz .8bit
test ch, 1
jnz .16bit
mov eax, 'eax'
stosd
dec edi
ret
.16bit:
mov ax, 'ax'
stosw
ret
.8bit:
mov ax, 'al'
stosw
ret
.write_ofs32:
mov al, '['
stosb
call disasm_get_dword
call disasm_write_num
mov al, ']'
stosb
ret
disasm_write_reg:
test ch, 80h
jnz disasm_write_reg1632
mov ax, [disasm_regs8+eax*2]
stosw
ret
disasm_write_reg1632:
test ch, 1
jnz @f
mov eax, [disasm_regs32+eax*4]
stosd
dec edi
ret
@@:
mov ax, [disasm_regs16+eax*2]
stosw
ret
cmovzx: ; 0F B6/B7
cmovsx: ; 0F BE/BF
mov edx, eax
disasm_set_modew
mov eax, 'movz'
cmp dl, 0xB8
jb @f
mov eax, 'movs'
@@:
stosd
mov eax, 'x '
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
call disasm_write_reg1632
mov ax, ', '
stosw
or ch, 1 ; 2nd operand - 8 or 16 bits
call disasm_readrmop
and byte [edi], 0
ret
disasm_op2cmds dd 'add ','or ','adc ','sbb ','and ','sub ','xor ','cmp '
cop21:
disasm_set_modew
mov esi, 'test'
cmp al, 0A8h
jae @f
shr al, 3
and eax, 7
mov esi, [disasm_op2cmds+eax*4]
@@:
xchg eax, esi
stosd
mov eax, ' '
stosd
test ch, 80h
jnz .1632
mov eax, 'al, '
stosd
jmp disasm_i8u
.1632:
test ch, 1
jnz .16
mov eax, 'eax,'
stosd
mov al, ' '
stosb
call disasm_get_dword
jmp .x
.16:
mov eax, 'ax, '
stosd
xor eax, eax
call disasm_get_word
.x:
call disasm_write_num
and byte [edi], 0
ret
cop22:
disasm_set_modew
or ch, 40h
mov edx, eax
mov esi, 'lea '
cmp al, 8Dh
jz @f
mov esi, 'imul'
cmp al, 0xAF
jz @f
mov esi, 'mov '
cmp al, 88h
jae @f
mov esi, 'xchg'
cmp al, 86h
jae @f
mov esi, 'test'
cmp al, 84h
jae @f
shr al, 3
and eax, 7
mov esi, [disasm_op2cmds+eax*4]
@@:
xchg eax, esi
stosd
mov eax, ' '
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
cmp dl, 0x8D
jz @f
cmp dl, 0x86
jz @f
cmp dl, 0x87
jz @f
test dl, 2
jz .d0
@@:
call disasm_write_reg
mov ax, ', '
stosw
call disasm_readrmop
and byte [edi], 0
ret
.d0:
push eax
call disasm_readrmop
mov ax, ', '
stosw
pop eax
call disasm_write_reg
and byte [edi], 0
ret
cop23:
disasm_set_modew
xchg eax, edx
call disasm_get_byte
dec [disasm_cur_pos]
shr eax, 3
and eax, 7
mov eax, [disasm_op2cmds+eax*4]
ctest:
stosd
mov eax, ' '
stosd
call disasm_readrmop
mov ax, ', '
stosw
test ch, 80h
jz .i8
cmp dl, 83h
jz .i8
test ch, 1
jnz .i16
call disasm_get_dword
jmp .ic
.i8:
xor eax, eax
call disasm_get_byte
cmp dl, 83h
jnz .ic
movsx eax, al
jmp .ic
.i16:
xor eax, eax
call disasm_get_word
.ic:
call disasm_write_num
and byte [edi], 0
ret
cbtx1:
; btx r/m,i8 = 0F BA
or ch, 80h
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
cmp al, 4
jb cunk
mov eax, [btx1codes+eax*4-4*4]
stosd
mov eax, ' '
stosd
call disasm_readrmop
mov ax, ', '
stosw
jmp disasm_i8u
btx1codes dd 'bt ','bts ','btr ','btc '
cbtx2:
; btx r/m,r = 0F 101xx011 (A3,AB,B3,BB)
shr al, 3
and eax, 3
mov eax, [btx1codes+eax*4]
stosd
mov eax, ' '
stosd
or ch, 0xC0
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
push eax
call disasm_readrmop
mov ax, ', '
stosw
pop eax
call disasm_write_reg1632
and byte [edi], 0
ret
csetcc:
and eax, 0xF
mov ax, [disasm_jcc_codes + eax*2]
mov dword [edi], 'setc'
add edi, 3
stosw
mov ax, ' '
stosw
stosb
call disasm_readrmop
and byte [edi], 0
ret
disasm_jcc_codes dw 'o ','no','b ','ae','z ','nz','be','a ','s ','ns','p ','np','l ','ge','le','g '
cjcc1:
cjmp2:
cmp al, 0xEB
jz .1
and eax, 0xF
mov ax, [disasm_jcc_codes + eax*2]
jmp .2
.1:
mov ax, 'mp'
.2:
mov byte [edi], 'j'
inc edi
stosw
mov eax, ' '
stosb
stosd
call disasm_get_byte
movsx eax, al
disasm_rva:
add eax, [disasm_cur_pos]
call disasm_write_num
and byte [edi], 0
ret
ccall1:
cjmp1:
cjcc2:
mov edx, 'call'
cmp al, 0xE8
jz @f
mov edx, 'jmp '
cmp al, 0xE9
jz @f
mov edx, ' '
and eax, 0xF
mov dx, [disasm_jcc_codes+eax*2]
shl edx, 8
mov dl, 'j'
@@:
xchg eax, edx
stosd
mov eax, ' '
stosd
call disasm_get_dword
jmp disasm_rva
op11codes dd 'test',0,'not ','neg ','mul ','imul','div ','idiv'
op12codes dd 'inc ','dec ','call',0,'jmp ',0,'push',0
cop1:
disasm_set_modew
xchg eax, edx
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
cmp dl, 0xFE
jnz @f
cmp al, 1
ja cunk
@@:
and edx, 8
add eax, edx
mov eax, [op11codes+eax*4]
test eax, eax
jz cunk
cmp eax, 'test'
jz ctest
@@:
stosd
mov eax, ' '
stosd
call disasm_readrmop
and byte [edi], 0
ret
cpop2:
or ch, 80h
call disasm_get_byte
dec [disasm_cur_pos]
test al, 00111000b
jnz cunk
mov eax, 'pop '
jmp @b
cloopnz:
mov eax, 'loop'
stosd
mov eax, 'nz '
test ch, 2
jz @f
mov ah, 'w'
@@: jmp cloop.cmn
cloopz:
mov eax, 'loop'
stosd
mov eax, 'z '
test ch, 2
jz @f
mov eax, 'zw '
@@: jmp cloop.cmn
cjcxz:
cloop:
cmp al, 0xE2
jz .loop
test ch, 2
jnz .jcxz
mov eax, 'jecx'
stosd
mov eax, 'z '
jmp .cmn
.jcxz:
mov eax, 'jcxz'
stosd
mov eax, ' '
jmp .cmn
.loop:
mov eax, 'loop'
stosd
mov eax, ' '
test ch, 2
jz .cmn
mov al, 'w'
.cmn:
stosd
call disasm_get_byte
movsx eax, al
add eax, [disasm_cur_pos]
test ch, 1
jz @f
and eax, 0xFFFF
@@:
disasm_write_num_done:
call disasm_write_num
and byte [edi], 0
ret
cimul1:
; imul r,r/m,i
or ch, 80h ; 32bit operation
xchg eax, edx
mov eax, 'imul'
stosd
mov eax, ' '
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
call disasm_write_reg1632
mov ax, ', '
stosw
call disasm_readrmop
mov ax, ', '
stosw
test ch, 1
jnz .16
cmp dl, 0x69
jz .op32
call disasm_get_byte
movsx eax, al
jmp disasm_write_num_done
.op32:
call disasm_get_dword
jmp disasm_write_num_done
.16:
cmp dl, 0x69
jz .op16
call disasm_get_byte
cbw
jmp disasm_write_num_done
.op16:
xor eax, eax
call disasm_get_word
jmp disasm_write_num_done
cshld:
cshrd:
mov edx, 'shld'
test al, 8
jz @f
mov edx, 'shrd'
@@:
xchg eax, edx
stosd
mov eax, ' '
stosd
call disasm_get_byte
dec [disasm_cur_pos]
shr al, 3
and eax, 7
push eax
or ch, 80h
call disasm_readrmop
mov ax, ', '
stosw
pop eax
call disasm_write_reg1632
mov ax, ', '
stosw
test dl, 1
jz disasm_i8u
mov ax, 'cl'
stosw
and byte [edi], 0
ret
ccbw:
mov eax, 'cbw '
test ch, 1
jnz @f
mov eax, 'cwde'
@@: stosd
and byte [edi+1], 0
ret
ccwd:
mov eax, 'cwd '
test ch, 1
jnz @b
mov eax, 'cdq '
jmp @b
fpuD8 dd 'add ','mul ','com ','comp','sub ','subr','div ','divr'
cD8:
call disasm_get_byte
dec [disasm_cur_pos]
push eax
shr al, 3
and eax, 7
mov byte [edi], 'f'
inc edi
xchg eax, edx
mov eax, [fpuD8+edx*4]
stosd
mov ax, ' '
stosw
stosb
pop eax
cmp dl, 2
jb .1
cmp dl, 3
jbe .2
.1:
cmp al, 0xC0
jb .2
mov eax, 'st0,'
stosd
mov al, ' '
stosb
.2:
or ch, 80h or 20h
and ch, not 1
call disasm_readrmop
and byte [edi], 0
ret
fpuD9_2:
dq 'fchs ','fabs ',0,0,'ftst ','fxam ',0,0
db 'fld1 fldl2t fldl2e fldpi fldlg2 fldln2 fldz '
dq 0
db 'f2xm1 fyl2x fptan fpatan fxtract fprem1 fdecstp fincstp '
db 'fprem fyl2xp1 fsqrt fsincos frndint fscale fsin fcos '
fpuD9_fnop db 'fnop '
cD9:
call disasm_get_byte
sub al, 0xC0
jae .l1
dec [disasm_cur_pos]
shr al, 3
and eax, 7
cmp al, 7
jnz @f
mov eax, 'fnst'
stosd
mov eax, 'cw '
jmp .x1
@@:
cmp al, 5
jnz @f
mov eax, 'fldc'
stosd
mov eax, 'w '
.x1:
stosd
or ch, 0C1h
jmp .cmn
@@:
mov edx, 'fld '
test al, al
jz @f
mov edx, 'fst '
cmp al, 2
jz @f
mov edx, 'fstp'
cmp al, 3
jnz cunk
@@:
xchg eax, edx
stosd
mov eax, ' '
stosd
or ch, 80h
and ch, not 1
.cmn:
call disasm_readrmop
and byte [edi], 0
ret
.l1:
cmp al, 10h
jae .l2
mov edx, 'fld '
cmp al, 8
jb @f
mov edx, 'fxch'
@@:
xchg eax, edx
stosd
mov eax, ' '
stosd
xchg eax, edx
and al, 7
add al, '0'
shl eax, 16
mov ax, 'st'
stosd
clc
ret
.l2:
cmp al, 0x10
jnz @f
mov esi, fpuD9_fnop
jmp .l3
@@:
sub al, 0x20
jb cerr
lea esi, [fpuD9_2+eax*8]
cmp byte [esi], 0
jz cerr
.l3:
movsd
movsd
and byte [edi-1], 0
ret
cDA:
call disasm_get_byte
cmp al, 0xC0
jae cunk
dec [disasm_cur_pos]
shr al, 3
and eax, 7
mov word [edi], 'fi'
inc edi
inc edi
mov eax, [fpuD8+eax*4]
stosd
mov ax, ' '
stosw
or ch, 80h
and ch, not 1 ; 32-bit operand
call disasm_readrmop
and byte [edi], 0
ret
fpuDB dd 'ild ',0,'ist ','istp',0,'ld ',0,'stp '
cDB:
call disasm_get_byte
cmp al, 0xC0
jae .1
dec [disasm_cur_pos]
shr al, 3
and eax, 7
xchg eax, edx
mov eax, [fpuDB+edx*4]
test eax, eax
jz cerr
mov byte [edi], 'f'
inc edi
stosd
mov ax, ' '
stosw
stosb
or ch, 80h
and ch, not 1 ; 32-bit operand
cmp dl, 4
jb @f
or ch, 20h
and ch, not 80h ; 80-bit operand
@@:
call disasm_readrmop
and byte [edi], 0
ret
.1:
cmp al, 0xE3
jnz cunk
mov eax, 'fnin'
stosd
mov eax, 'it'
stosd
dec edi
ret ; CF cleared
fpuDC dd 'add ','mul ',0,0,'subr','sub ','divr','div '
cDC:
call disasm_get_byte
cmp al, 0xC0
jae .1
dec [disasm_cur_pos]
shr al, 3
and eax, 7
mov byte [edi], 'f'
inc edi
mov eax, [fpuD8+eax*4]
stosd
mov ax, ' '
stosw
stosb
or ch, 0A1h ; qword
call disasm_readrmop
and byte [edi], 0
ret
.1:
mov dl, al
shr al, 3
and eax, 7
mov eax, [fpuDC+eax*4]
test eax, eax
jz cerr
mov byte [edi], 'f'
inc edi
stosd
mov eax, ' s'
stosd
mov al, 't'
stosb
and edx, 7
lea eax, [edx+'0']
stosb
mov eax, ', st'
stosd
mov ax, '0'
stosw
ret ; CF cleared
fpuDD dd 'fld ',0,'fst ','fstp',0,0,0,0
fpuDD_2 dq 'ffree ',0,'fst ','fstp ','fucom ','fucomp ',0,0
cDD:
call disasm_get_byte
cmp al, 0xC0
jae .1
dec [disasm_cur_pos]
shr al, 3
and eax, 7
xchg eax, edx
mov eax, [fpuDD+edx*4]
test eax, eax
jz cunk
stosd
mov eax, ' '
stosd
or ch, 0A1h ; qword operand
call disasm_readrmop
and byte [edi], 0
ret
.1:
push eax
shr al, 3
and eax, 7
xchg eax, edx
mov eax, dword [fpuDD_2+edx*8]
test eax, eax
jz cerr
stosd
mov eax, dword [fpuDD_2+4+edx*8]
stosd
mov ax, 'st'
stosw
pop eax
and al, 7
add al, '0'
stosb
and byte [edi], 0
ret
fpuDE dd 'add ','mul ',0,0,'subr','sub ','divr','div '
cDE:
call disasm_get_byte
cmp al, 0xC0
jae .1
dec [disasm_cur_pos]
mov word [edi], 'fi'
inc edi
inc edi
shr al, 3
and eax, 7
mov eax, [fpuD8+eax*4]
stosd
mov ax, ' '
stosw
or ch, 81h ; force 16-bit
call disasm_readrmop
and byte [edi], 0
ret
.1:
push eax
shr al, 3
and eax, 7
xchg eax, edx
mov eax, [fpuDE+edx*4]
test eax, eax
jz .fcompp
mov byte [edi], 'f'
inc edi
stosd
mov al, 'p'
cmp byte [edi-1], ' '
jnz @f
mov byte [edi-1], al
mov al, ' '
@@: stosb
mov eax, ' st'
stosd
pop eax
and al, 7
add al, '0'
stosb
mov ax, ', '
stosw
mov eax, 'st0'
stosd
ret ; CF cleared
.fcompp:
pop eax
cmp al, 0xD9
jnz cerr
mov eax, 'fcom'
stosd
mov ax, 'pp'
stosw
and byte [edi], 0
ret
fpuDF dd 'ild ',0,'ist ','istp','bld ','ild ','bstp','istp'
cDF:
call disasm_get_byte
cmp al, 0xC0
jae .1
dec [disasm_cur_pos]
shr al, 3
and eax, 7
xchg eax, edx
mov eax, [fpuDF+edx*4]
test eax, eax
jz cerr
mov byte [edi], 'f'
inc edi
stosd
mov ax, ' '
stosw
stosb
or ch, 81h ; force 16-bit operand
cmp dl, 4
jb @f
or ch, 20h
test dl, 1
jnz @f
or ch, 40h
@@:
call disasm_readrmop
and byte [edi], 0
ret
.1:
cmp al, 0xE0
jnz cunk
mov eax, 'fnst'
stosd
mov eax, 'sw '
stosd
mov ax, 'ax'
stosw
and byte [edi], 0
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATA ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
caption_str db 'Kolibri Debugger',0
caption_len = $ - caption_str
begin_str db 'Kolibri Debugger, version 0.2',10
db 'Hint: type "help" for help, "quit" for quit'
newline db 10,0
prompt db '> ',0
help_groups:
dd aControl, 0, 0, help_control_msg
db 0
dd aData, 0, 0, help_data_msg
db 0
dd aBreakpoints, 0, 0, help_breaks_msg
db 0
; flags field:
; &1: command may be called without parameters
; &2: command may be called with parameters
; &4: command may be called without loaded program
; &8: command may be called with loaded program
commands:
dd _aH, OnHelp, HelpSyntax, HelpHelp
db 0Fh
dd aHelp, OnHelp, HelpSyntax, HelpHelp
db 0Fh
dd aQuit, OnQuit, QuitSyntax, QuitHelp
db 0Dh
dd aLoad, OnLoad, LoadSyntax, LoadHelp
db 6
dd aReload, OnReload, ReloadSyntax, ReloadHelp
db 0Dh
dd aTerminate, OnTerminate, TerminateSyntax, TerminateHelp
db 9
dd aDetach, OnDetach, DetachSyntax, DetachHelp
db 9
dd aSuspend, OnSuspend, SuspendSyntax, SuspendHelp
db 9
dd aResume, OnResume, ResumeSyntax, ResumeHelp
db 0Bh
dd aStep, OnStep, StepSyntax, StepHelp
db 9
dd aProceed, OnProceed, ProceedSyntax, ProceedHelp
db 9
dd aCalc, OnCalc, CalcSyntax, CalcHelp
db 0Eh
dd aDump, OnDump, DumpSyntax, DumpHelp
db 0Bh
dd aUnassemble, OnUnassemble, UnassembleSyntax, UnassembleHelp
db 0Bh
dd aBp, OnBp, BpSyntax, BpHelp
db 0Ah
dd aBpm, OnBpmb, BpmSyntax, BpmHelp
db 0Ah
dd aBpmb, OnBpmb, BpmSyntax, BpmHelp
db 0Ah
dd aBpmw, OnBpmw, BpmSyntax, BpmHelp
db 0Ah
dd aBpmd, OnBpmd, BpmSyntax, BpmHelp
db 0Ah
dd aBl, OnBl, BlSyntax, BlHelp
db 0Bh
dd aBc, OnBc, BcSyntax, BcHelp
db 0Ah
dd aBd, OnBd, BdSyntax, BdHelp
db 0Ah
dd aBe, OnBe, BeSyntax, BeHelp
db 0Ah
dd aReg, OnReg, RSyntax, RHelp
db 0Ah
dd aUnpack, OnUnpack, UnpackSyntax, UnpackHelp
db 9
dd 0
aHelp db 5,'help',0
_aH db 2,'h',0
HelpHelp db 'Help on specified function',10
HelpSyntax db 'Usage: h or help [group | command]',10,0
help_msg db 'List of known command groups:',10
db '"help control" - display list of control commands',10
db '"help data" - display list of commands concerning data',10
db '"help breakpoints" - display list of commands concerning breakpoints',10,0
aControl db 8,'control',0
help_control_msg db 'List of control commands:',10
db 'h = help - help',10
db 'quit - exit from debugger',10
db 'load <name> [params] - load program for debugging',10
db 'reload - reload debugging program',10
db 'terminate - terminate loaded program',10
db 'detach - detach from debugging program',10
db 'stop - suspend execution of debugging program',10
db 'g [<expression>] - go on (resume execution of debugging program)',10
db 's = <Ctrl+F7> - program step',10
db 'p = <Ctrl+F8> - program wide step',10
db 'unpack - try to bypass unpacker code (heuristic)',10,0
aData db 5,'data',0
help_data_msg db 'List of data commands:',10
db '? <expression> - calculate value of expression',10
db 'd [<expression>] - dump data at given address',10
db 'u [<expression>] - unassemble instructions at given address',10
db 'r <register> <expression> or',10
db 'r <register>=<expression> - set register value',10,0
aBreakpoints db 12,'breakpoints',0
help_breaks_msg db 'List of breakpoints commands:',10
db 'bp <expression> - set breakpoint on execution',10
db 'bpm[b|w|d] <type> <expression> - set breakpoint on memory access',10
db 'bl [<number>] - breakpoint(s) info',10
db 'bc <number>... - clear breakpoint',10
db 'bd <number>... - disable breakpoint',10
db 'be <number>... - enable breakpoint',10,0
aQuit db 5,'quit',0
QuitHelp db 'Quit from debugger',10
QuitSyntax db 'Usage: quit',10,0
aLoad db 5,'load',0
LoadHelp db 'Load program for debugging',10
LoadSyntax db 'Usage: load <program-name> [parameters]',10,0
aReload db 7,'reload',0
ReloadHelp db 'Reload debugging program (restart debug session)',10
ReloadSyntax db 'Usage: reload',10,0
aTerminate db 10,'terminate',0
TerminateHelp db 'Terminate debugged program',10
TerminateSyntax db 'Usage: terminate',10,0
aDetach db 7,'detach',0
DetachHelp db 'Detach from debugged program',10
DetachSyntax db 'Usage: detach',10,0
aSuspend db 5,'stop',0
SuspendHelp db 'Suspend execution of debugged program',10
SuspendSyntax db 'Usage: stop',10,0
aResume db 2,'g',0
ResumeHelp db 'Go (resume execution of debugged program)',10
ResumeSyntax db 'Usage: g',10
db ' or: g <expression> - wait until specified address is reached',10,0
aStep db 2,'s',0
StepHelp db 'Make step in debugged program',10
StepSyntax db 'Usage: s',10,0
aProceed db 2,'p',0
ProceedHelp db 'Make wide step in debugged program (step over CALL, REPxx, LOOP)',10
ProceedSyntax db 'Usage: p',10,0
aDump db 2,'d',0
DumpHelp db 'Dump data of debugged program',10
DumpSyntax db 'Usage: d <expression> - dump data at specified address',10
db ' or: d - continue current dump',10,0
aCalc db 2,'?',0
CalcHelp db 'Calculate value of expression',10
CalcSyntax db 'Usage: ? <expression>',10,0
aUnassemble db 2,'u',0
UnassembleHelp db 'Unassemble',10
UnassembleSyntax:
db 'Usage: u <expression> - unassemble instructions at specified address',10
db ' or: u - continue current unassemble screen',10,0
aReg db 2,'r',0
RHelp db 'Set register value',10
RSyntax:
db 'Usage: r <register> <expression>',10
db ' or: r <register>=<expression> - set value of <register> to <expression>',10,0
aBp db 3,'bp',0
BpHelp db 'set BreakPoint on execution',10
BpSyntax db 'Usage: bp <expression>',10,0
aBpm db 4,'bpm',0
aBpmb db 5,'bpmb',0
aBpmw db 5,'bpmw',0
aBpmd db 5,'bpmd',0
BpmHelp db 'set BreakPoint on Memory access',10
db 'Maximum 4 breakpoints of this type are allowed',10
db 'Note that for this breaks debugger is activated after access',10
BpmSyntax db 'Usage: bpmb [w] <expression>',10
db ' bpmw [w] <expression>',10
db ' bpmd [w] <expression>',10
db ' bpm is synonym for bpmd',10
db '"w" means break only on writes (default is on read/write)',10,0
aBl db 3,'bl',0
BlHelp db 'Breakpoint List',10
BlSyntax db 'Usage: bl - list all breakpoints',10
db ' bl <number> - display info on particular breakpoint',10,0
aBc db 3,'bc',0
BcHelp db 'Breakpoint Clear',10
BcSyntax db 'Usage: bc <number-list>',10
db 'Examples: bc 2',10
db ' bc 1 3 4 A',10,0
aBd db 3,'bd',0
BdHelp db 'Breakpoint Disable',10
BdSyntax db 'Usage: bd <number-list>',10
db 'Examples: bd 2',10
db ' bd 1 3 4 A',10,0
aBe db 3,'be',0
BeHelp db 'Breakpoint Enable',10
BeSyntax db 'Usage: be <number-list>',10
db 'Examples: be 2',10
db ' be 1 3 4 A',10,0
aUnpack db 7,'unpack',0
UnpackHelp db 'Try to bypass unpacker code',10
UnpackSyntax db 'Usage: unpack',10,0
aUnknownCommand db 'Unknown command',10,0
load_err_msg db 'Cannot load program. ',0
unk_err_msg db 'Unknown error code -%4X',10,0
load_err_msgs:
dd .1, 0, .3, 0, .5, .6, 0, 0, .9, .A, 0, 0, 0, 0, 0, 0
dd 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, .1E, .1F, .20
.1 db 'HD undefined.',10,0
.3 db 'Unknown FS.',10,0
.5 db 'File not found.',10,0
.6 db 'Unexpected EOF.',10,0
.9 db 'FAT table corrupted.',10,0
.A db 'Access denied.',10,0
.1E db 'No memory.',10,0
.1F db 'Not Menuet/Kolibri executable.',10,0
.20 db 'Too many processes.',10,0
load_succ_msg db 'Program loaded successfully! PID=%4X. Use "g" to run.',10,0
need_debuggee db 'No program loaded. Use "load" command.',10,0
aAlreadyLoaded db 'Program is already loaded. Use "terminate" or "detach" commands',10,0
terminated_msg db 'Program terminated.',10,0
aException db 'Debugged program caused an exception %2X. '
aSuspended db 'Suspended',10,0
aContinued db 'Continuing',10,0
aRunningErr db 'Program is running',10,0
read_mem_err db 'ERROR: cannot read process memory!!!',10,0
aBreakpointLimitExceeded db 'Breakpoint limit exceeded',10,0
aBreakErr db 'Cannot activate breakpoint, it will be disabled',10,0
aDuplicateBreakpoint db 'Duplicate breakpoint',10,0
aInvalidBreak db 'Invalid breakpoint number',10,0
OnBeErrMsg db 'There is already enabled breakpoint on this address',10,0
aBreakNum db '%2X: at %8X',0
aMemBreak1 db '%2X: on ',0
aMemBreak2 db 'read from ',0
aMemBreak3 db 'access of ',0
aMemBreak4 db 'byte',0
aMemBreak5 db 'word',0
aMemBreak6 db 'dword',0
aMemBreak7 db ' at %8X',0
aOneShot db ', one-shot',0
aDisabled db ', disabled',0
aBreakStop db 'Breakpoint #%2X',10,0
aUserBreak db 'int3 command at %8X',10,0
;dbgmsg_str db 'Debug message for process %4X.',10,0
aInvAddr db 'Invalid address',10,0
NoPrgLoaded_str db 'No program loaded'
NoPrgLoaded_len = $ - NoPrgLoaded_str
aRunning db 'Running'
aPaused db 'Paused'
aPoint db 0x1C
aMinus db '-'
aColon db ':'
aQuests db '??'
aDots db '...'
aParseError db 'Parse error',10,0
aDivByZero db 'Division by 0',10,0
calc_string db '%8X',10,0
aUnaligned db 'Unaligned address',10,0
aEnabledBreakErr db 'Enabled breakpoints are not allowed',10,0
aInterrupted db 'Interrupted',10,0
aUnpacked db 'Unpacked successful!',10,0
aPacked1 db 'Program is probably packed with ',0
aPacked2 db '.',10,'Try to unpack automatically? [y/n]: ',0
aY_str db 'y',10,0
aN_str db 'n',10,0
mxp_nrv_name db 'mxp_nrv',0
mxp_name db 'mxp',0
mxp_lzo_name db 'mxp_lzo',0
mtappack_name db 'mtappack',0
flags db 'CPAZSDO'
flags_bits db 0,2,4,6,7,10,11
regs_strs:
db 'EAX='
db 'EBX='
db 'ECX='
db 'EDX='
db 'ESI='
db 'EDI='
db 'EBP='
db 'ESP='
db 'EIP='
db 'EFLAGS='
debuggee_pid dd 0
bSuspended db 0
bAfterGo db 0
temp_break dd 0
disasm_table_1:
dd cop22, cop22, cop22, cop22, cop21, cop21, cop0, cop0 ; 0x
dd cop22, cop22, cop22, cop22, cop21, cop21, cop0, cF
dd cop22, cop22, cop22, cop22, cop21, cop21, cop0, cop0 ; 1x
dd cop22, cop22, cop22, cop22, cop21, cop21, cop0, cop0
dd cop22, cop22, cop22, cop22, cop21, cop21, cseges,cop0 ; 2x
dd cop22, cop22, cop22, cop22, cop21, cop21, csegcs,cop0
dd cop22, cop22, cop22, cop22, cop21, cop21, csegss,cop0 ; 3x
dd cop22, cop22, cop22, cop22, cop21, cop21, csegds,cop0
dd cinc1, cinc1, cinc1, cinc1, cinc1, cinc1, cinc1, cinc1 ; 4x
dd cdec1, cdec1, cdec1, cdec1, cdec1, cdec1, cdec1, cdec1
dd cpush1,cpush1,cpush1,cpush1,cpush1,cpush1,cpush1,cpush1 ; 5x
dd cpop1, cpop1, cpop1, cpop1, cpop1, cpop1, cpop1, cpop1
dd cop0, cop0, cunk, cunk, csegfs,cseggs,c66, c67 ; 6x
dd cpush21,cimul1,cpush22,cimul1,cunk,cunk, cunk, cunk
dd cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1 ; 7x
dd cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1, cjcc1
dd cop23, cop23, cop23, cop23, cop22, cop22, cop22, cop22 ; 8x
dd cop22, cop22, cop22, cop22, cunk, cop22, cunk, cpop2
dd cop0, cxchg1,cxchg1,cxchg1,cxchg1,cxchg1,cxchg1,cxchg1 ; 9x
dd ccbw, ccwd, cunk, cop0, cop0, cop0, cop0, cop0
dd cmov3, cmov3, cmov3, cmov3, cop0, cop0, cop0, cop0 ; Ax
dd cop21, cop21, cop0, cop0, cop0, cop0, cop0, cop0
dd cmov11,cmov11,cmov11,cmov11,cmov11,cmov11,cmov11,cmov11 ; Bx
dd cmov12,cmov12,cmov12,cmov12,cmov12,cmov12,cmov12,cmov12
dd cshift1,cshift1,cret2,cop0, cunk, cunk, cmov2, cmov2 ; Cx
dd center,cop0, cunk, cunk, cop0, cint, cunk, cunk
dd cshift2,cshift2,cshift3,cshift3,caam,cunk,cunk, cxlat ; Dx
dd cD8, cD9, cDA, cDB, cDC, cDD, cDE, cDF
dd cloopnz,cloopz,cloop,cjcxz, cunk, cunk, cunk, cunk ; Ex
dd ccall1,cjmp1, cunk, cjmp2, cunk, cunk, cunk, cunk
dd clock, cunk, crepnz,crep, cunk, cop0, cop1, cop1 ; Fx
dd cop0, cop0, cop0, cop0, cop0, cop0, cop1, cop1
disasm_table_2:
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk ; 0x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk ; 1x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk ; 2x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cunk, crdtsc,cunk, cunk, csysenter,cunk,cunk, cunk ; 3x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk ; 4x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk ; 5x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk ; 6x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk ; 7x
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2 ; 8x
dd cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2, cjcc2
dd csetcc,csetcc,csetcc,csetcc,csetcc,csetcc,csetcc,csetcc ; 9x
dd csetcc,csetcc,csetcc,csetcc,csetcc,csetcc,csetcc,csetcc
dd cunk, cunk, ccpuid,cbtx2, cshld, cshld, cunk, cunk ; Ax
dd cunk, cunk, cunk, cbtx2, cshrd, cshrd, cunk, cop22
dd ccmpxchg,ccmpxchg,cunk,cbtx2,cunk, cunk, cmovzx,cmovzx ; Bx
dd cunk, cunk, cbtx1, cbtx2, cbsf, cbsr, cmovsx,cmovsx
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, ccmpxchg8b ; Cx
dd cbswap,cbswap,cbswap,cbswap,cbswap,cbswap,cbswap,cbswap
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk ; Dx
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk ; Ex
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk ; Fx
dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk
reg_table:
db 2,'al',0
db 2,'cl',1
db 2,'dl',2
db 2,'bl',3
db 2,'ah',4
db 2,'ch',5
db 2,'dh',6
db 2,'bh',7
db 2,'ax',8
db 2,'cx',9
db 2,'dx',10
db 2,'bx',11
db 2,'sp',12
db 2,'bp',13
db 2,'si',14
db 2,'di',15
db 3,'eax',16
db 3,'ecx',17
db 3,'edx',18
db 3,'ebx',19
db 3,'esp',20
db 3,'ebp',21
db 3,'esi',22
db 3,'edi',23
db 3,'eip',24
db 0
fn70_load_block:
dd 7
dd 1
load_params dd 0
dd 0
dd 0
i_end:
loadname:
db 0
rb 255
prgname_ptr dd ?
prgname_len dd ?
dbgwnd dd ?
messages rb messages_height*messages_width
messages_pos dd ?
cmdline rb cmdline_width+1
cmdline_len dd ?
cmdline_pos dd ?
curarg dd ?
was_temp_break db ?
dbgbufsize dd ?
dbgbuflen dd ?
dbgbuf rb 256
needzerostart:
context:
_eip dd ?
_eflags dd ?
_eax dd ?
_ecx dd ?
_edx dd ?
_ebx dd ?
_esp dd ?
_ebp dd ?
_esi dd ?
_edi dd ?
oldcontext rb $-context
dumpread dd ?
dumppos dd ?
dumpdata rb dump_height*10h
; breakpoint structure:
; dword +0: address
; byte +4: flags
; bit 0: 1 <=> breakpoint valid
; bit 1: 1 <=> breakpoint disabled
; bit 2: 1 <=> one-shot breakpoint
; bit 3: 1 <=> DRx breakpoint
; byte +5: overwritten byte
; for DRx breaks: flags + (index shl 6)
breakpoints_n = 256
breakpoints rb breakpoints_n*6
drx_break rd 4
disasm_buf_size dd ?
bReload db ?
needzeroend:
disasm_buffer rb 256
disasm_start_pos dd ?
disasm_cur_pos dd ?
disasm_cur_str dd ?
disasm_string rb 256
i_param rb 256
; stack
align 400h
rb 400h
used_mem: