0,0 → 1,4825 |
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: |