format binary include '../../macros.inc' use32 db 'MENUET01' dd 1 dd start dd i_end dd used_mem dd used_mem dd i_param dd 0 ;----------------------------------------------------------------------------- REG_MODE_CPU equ 1 REG_MODE_MMX equ 2 REG_MODE_SSE equ 3 REG_MODE_AVX equ 4 ;----------------------------------------------------------------------------- include 'gui.inc' ; GUI routines ;----------------------------------------------------------------------------- ; Find command in list 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 ; find command .x5: 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DEBUGGING ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;----------------------------------------------------------------------------- ; Help event 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 ;----------------------------------------------------------------------------- ; Quit event OnQuit: mcall -1 ;----------------------------------------------------------------------------- ; Working with debug context 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 mcall 69, 1, [debuggee_pid], 28h, context ret set_context: ;push 2 ;pop ebx ;push 69 ;pop eax ;mov ecx, [debuggee_pid] ;mov esi, context ;push 28h ;pop edx mcall 69, 2, [debuggee_pid], 28h, context 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 mcall 69, 6, [debuggee_pid] 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 ; in: edi=buffer,eax=size,esi=address restore_from_breaks: 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 ;----------------------------------------------------------------------------- ; Load executable event 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 get_arg.skip_spaces cmp al, 0 jz @f mov [load_params], esi @@: and [dumppos], 0 mov ecx, [symbols] jecxz do_reload mcall 68, 13 and [symbols], 0 and [num_symbols], 0 ; TODO: make it local do_reload: ;push 18 ;pop eax ;push 7 ;pop ebx mcall 18, 7 mov [dbgwnd], eax xchg ecx, eax ;push 70 ;pop eax ;mov ebx, fn70_load_block mcall 70, fn70_load_block 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 mcall 18, 3 call redraw_title call draw_registers.redraw ; read and draw dump of memory call get_dump call draw_dump.redraw call update_disasm_eip_force mov esi, load_succ_msg push [debuggee_pid] call put_message_nodraw call draw_messages ; try to load symbols mov esi, loadname mov edi, symbolsfile push edi @@: lodsb stosb test al, al jnz @b lea ecx, [edi-1] @@: dec edi cmp edi, symbolsfile jb @f cmp byte [edi], '/' jz @f cmp byte [edi], '.' jnz @b mov ecx, edi @@: mov dword [ecx], '.dbg' mov byte [ecx+4], 0 pop esi mov ebp, esi call OnLoadSymbols.silent ; 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 mcall 40, 7 .wait: ;push 10 ;pop eax mcall 10 dec eax jz .redraw dec eax jz .key or eax, -1 mcall .redraw: call draw_window call hide_cursor jmp .wait .key: mov al, 2 mcall 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 mcall 40, 0x107 call draw_cursor mov esi, aN_str jmp put_message .yes: ;push 40 ;pop eax ;mov ebx, 0x107 mcall 40, 0x107 call draw_cursor mov esi, aY_str call put_message call OnUnpack ret ;----------------------------------------------------------------------------- ; Searching signatures 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 ;----------------------------------------------------------------------------- ; Reload executable event OnReload: cmp [debuggee_pid], 0 jnz terminate_reload mov esi, need_debuggee cmp byte [loadname], 0 jnz do_reload jz put_message ; TODO: make it local terminate_reload: mov [bReload], 1 ;----------------------------------------------------------------------------- ; Terminate process event OnTerminate: ;mov ecx, [debuggee_pid] ;push 8 ;pop ebx ;push 69 ;pop eax mcall 69, 8, [debuggee_pid] ret ;----------------------------------------------------------------------------- ; Suspend process event AfterSuspend: mov [bSuspended], 1 call get_new_context call get_dump call redraw_title call draw_registers.redraw call draw_dump.redraw call update_disasm_eip ret OnSuspend: ;mov ecx, [debuggee_pid] ;push 4 ;pop ebx ;push 69 ;pop eax mcall 69, 4, [debuggee_pid] call AfterSuspend mov esi, aSuspended jmp put_message ;----------------------------------------------------------------------------- ; Resume process event DoResume: ;mov ecx, [debuggee_pid] ;push 5 ;pop ebx ;push 69 ;pop eax mcall 69, 5, [debuggee_pid] 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 draw_registers.redraw call draw_dump.redraw ret ;----------------------------------------------------------------------------- ; Detach process event OnDetach: ;mov ecx, [debuggee_pid] ;push 3 ;pop ebx ;push 69 ;pop eax mcall 69, 3, [debuggee_pid] and [debuggee_pid], 0 call redraw_title call draw_registers.redraw call draw_dump.redraw call free_symbols 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: ; TODO: split it out debugmsg: neg [dbgbufsize] mov esi, dbgbuf ; TODO: make it local 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 ; TODO: WTF? Need for meaning label names .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 ; TODO: make it local 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 jnz exception.done call free_symbols 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 ; TODO: fix for useful name .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 mcall 69, 6, [debuggee_pid], 1, [_eip], esp 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] mcall 18, 3, [dbgwnd] ; activate dbg window call redraw_title call draw_registers.redraw call draw_dump.redraw 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 ; TODO: make it local F7: cmp [debuggee_pid], 0 jz .no call OnStep .no: jmp waitevent ; TODO: make it local F8: cmp [debuggee_pid], 0 jz F7.no call OnProceed jmp F7.no ;----------------------------------------------------------------------------- ; Step execution event ;Here we get [] argument at do step times OnStepMultiple: cmp [bSuspended], 0 jz OnStep.running mov [step_num], 1 mov esi, [curarg] test esi, esi jz .do cmp byte [esi], 0 jz .do call get_hex_number jc .ret cmp eax, 0 ; check if lesser or equal than 0 jle .ret mov [step_num], eax .do: call OnStep dec [step_num] jnz .do .ret: ret 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] mcall 69, 6, [debuggee_pid], 3, [_eip], esp cmp eax, edx pop eax jnz .doit cmp al, 0xCD jz .int cmp ax, 0x050F jz .syscall cmp ax, 0x340F jz .sysenter ; resume process .doit: call GoOn cmp [bAfterGo], 0 jz @f mov [bAfterGo], 2 @@: ret ; return address is [ebp-4] .sysenter: push 0 ;push 69 ;pop eax inc edx ; read 4 bytes mov esi, [_ebp] sub esi, 4 mcall 69 cmp eax, edx pop eax jnz .syscall push eax and byte [_eflags+1], not 1 call set_context pop eax jmp @f .syscall: and byte [_eflags+1], not 1 ; clear TF - avoid system halt (!) call set_context .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 ;----------------------------------------------------------------------------- ; Proceed process event OnProceed: cmp [bSuspended], 0 jz OnStep.running cmp [proc_num], 0 jg .procone mov esi, [curarg] cmp esi, 0 jz .procone cmp byte [esi], 0 jz .procone call get_hex_number jc .ret cmp eax, 0 ; check if lesser than 0 jle .ret mov [proc_num], eax mov [curarg], 0 .procone: 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 ; FF /2 = call .noloop: 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 @f mov eax, esi mov bl, 5 call add_breakpoint jmp OnStep.doit @@: mov eax, [proc_num] dec eax cmp eax, 0 jle .ret mov [proc_num], eax jmp .procone .ret: mov [proc_num], 0 ret ;----------------------------------------------------------------------------- ; Read next byte of machine code 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 mcall 69, 6, [debuggee_pid] dec eax clc jz @f stc @@: pop eax ret include 'parser.inc' ;----------------------------------------------------------------------------- ; Calculate expression event OnCalc: mov esi, [curarg] call calc_expression jc .ret push ebp mov esi, calc_string call put_message_nodraw jmp draw_messages .ret: ret ;----------------------------------------------------------------------------- ; Dump memory event 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 draw_dump.redraw .ret: ret ;----------------------------------------------------------------------------- ; Dissassemble block of executable event OnUnassemble: mov esi, [curarg] cmp byte [esi], 0 jnz .param mov eax, [disasm_start_pos] mov ecx, disasm_height mov [disasm_cur_pos], eax .l: mov eax, [disasm_cur_pos] call find_symbol jc @f dec ecx jz .m @@: push ecx call disasm_instr pop ecx jc .err loop .l .m: 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 ;----------------------------------------------------------------------------- ; Access to register value event OnReg: mov esi, [curarg] call get_arg.skip_spaces call find_reg jnc @f .err: mov esi, RSyntax jmp put_message @@: call get_arg.skip_spaces test al, al jz .err cmp al, '=' jnz @f inc esi call get_arg.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 draw_registers.redraw ;----------------------------------------------------------------------------- ; 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 draw_disasm.redraw 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 mcall 69, 9, [debuggee_pid] 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 ; TODO: split it out in parser.inc get_hex_number: call get_arg.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 ;----------------------------------------------------------------------------- ; Breakpoints list event 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 and EAX = breakpoint number add_breakpoint: 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 ;----------------------------------------------------------------------------- ; Remove breakpoint 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 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] mcall 69, 7, [debuggee_pid], 1, [edi-5] 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] mcall 69, 9, [debuggee_pid] ret ;----------------------------------------------------------------------------- ; Enable breakpoint 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 mcall 69, 6, [debuggee_pid], 1, [edi-5] dec eax jnz .err ;mov al, 69 push 0xCC mov edi, esp inc ebx mcall 69 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 mcall 69, 9, [debuggee_pid] test eax, eax jnz .err pop esi ret ;----------------------------------------------------------------------------- ; Find breakpoint 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 ; TODO: add find_disabled_breakpoint ;----------------------------------------------------------------------------- ; Unpack executable event 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 mcall 69 test eax, eax jz .breakok inc edx cmp dl, 4 jb @b .breakok: call GoOn ; now wait for event .wait: ;push 10 ;pop eax mcall 10 dec eax jz .redraw dec eax jz .key dec eax jnz .debug ; button; we have only one button, close or eax, -1 mcall .redraw: call draw_window jmp .wait .key: mov al, 2 mcall 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] mcall 69, 9, [debuggee_pid] 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] mcall 69, 9, [debuggee_pid] 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 mcall 69, 6, [debuggee_pid], 4, 0xC, esp pop eax pop edx cmp eax, [_eip] jz .done call DoResume jmp .wait .done: mov esi, aUnpacked jmp .x1 ;----------------------------------------------------------------------------- ; Working with program symbols ; ; TODO: split to symbols.inc include 'sort.inc' ; compare what? Add context-relative comment and name compare: cmpsd jnz @f cmp esi, edi @@: ret ; purpose of this function? compare2: cmpsd @@: cmpsb jnz @f cmp byte [esi-1], 0 jnz @b cmp esi, edi @@: ret free_symbols: mov ecx, [symbols] jecxz @f mcall 68, 13 and [symbols], 0 and [num_symbols], 0 @@: ret ;----------------------------------------------------------------------------- ; Load symbols event OnLoadSymbols.fileerr: test ebp, ebp jz @f mcall 68, 13, edi ret @@: push eax mcall 68, 13, edi mov esi, aCannotLoadFile call put_message_nodraw pop eax cmp eax, 0x20 jae .unk mov esi, [load_err_msgs + eax*4] test esi, esi jnz put_message .unk: mov esi, unk_err_msg2 jmp put_message OnLoadSymbols: xor ebp, ebp ; load input file mov esi, [curarg] call free_symbols .silent: xor edi, edi cmp [num_symbols], edi jz @f call free_symbols ;ret @@: mov ebx, fn70_attr_block mov [ebx+21], esi mcall 70 test eax, eax jnz .fileerr cmp dword [fileattr+36], edi jnz .memerr mov ecx, dword [fileattr+32] mcall 68, 12 test eax, eax jz .memerr mov edi, eax mov ebx, fn70_read_block mov [ebx+12], ecx mov [ebx+16], edi mov [ebx+21], esi mcall 70 test eax, eax jnz .fileerr ; calculate memory requirements lea edx, [ecx+edi-1] ; edx = EOF-1 mov esi, edi xor ecx, ecx .calcloop: cmp esi, edx jae .calcdone cmp word [esi], '0x' jnz .skipline inc esi inc esi @@: cmp esi, edx jae .calcdone lodsb or al, 20h sub al, '0' cmp al, 9 jbe @b sub al, 'a'-'0'-10 cmp al, 15 jbe @b dec esi @@: cmp esi, edx ja .calcdone lodsb cmp al, 20h jz @b jb .calcloop cmp al, 9 jz @b add ecx, 12+1 inc [num_symbols] @@: inc ecx cmp esi, edx ja .calcdone lodsb cmp al, 0xD jz .calcloop cmp al, 0xA jz .calcloop jmp @b .skipline: cmp esi, edx jae .calcdone lodsb cmp al, 0xD jz .calcloop cmp al, 0xA jz .calcloop jmp .skipline .calcdone: mcall 68, 12 test eax, eax jnz .memok inc ebx mov ecx, edi mov al, 68 mcall .memerr: mov esi, aNoMemory jmp put_message .memok: mov [symbols], eax mov ebx, eax push edi mov esi, edi mov edi, [num_symbols] lea ebp, [eax+edi*4] lea edi, [eax+edi*8] ; parse input data, ; esi->input, edx->EOF, ebx->ptrs, edi->names .readloop: cmp esi, edx jae .readdone cmp word [esi], '0x' jnz .readline inc esi inc esi xor eax, eax xor ecx, ecx @@: shl ecx, 4 add ecx, eax cmp esi, edx jae .readdone lodsb or al, 20h sub al, '0' cmp al, 9 jbe @b sub al, 'a'-'0'-10 cmp al, 15 jbe @b dec esi @@: cmp esi, edx ja .readdone lodsb cmp al, 20h jz @b jb .readloop cmp al, 9 jz @b mov dword [ebx], edi add ebx, 4 mov dword [ebp], edi add ebp, 4 mov dword [edi], ecx add edi, 4 stosb @@: xor eax, eax stosb cmp esi, edx ja .readdone lodsb cmp al, 0xD jz .readloop cmp al, 0xA jz .readloop mov byte [edi-1], al jmp @b .readline: cmp esi, edx jae .readdone lodsb cmp al, 0xD jz .readloop cmp al, 0xA jz .readloop jmp .readline .readdone: pop ecx mcall 68, 13 mov ecx, [num_symbols] mov edx, [symbols] mov ebx, compare call sort mov ecx, [num_symbols] lea edx, [edx+ecx*4] mov ebx, compare2 call sort mov esi, aSymbolsLoaded call put_message jmp draw_disasm.redraw ;----------------------------------------------------------------------------- ; ; in: EAX = address ; out: ESI, CF find_symbol: cmp [num_symbols], 0 jnz @f .ret0: xor esi, esi stc ret @@: push ebx ecx edx xor edx, edx mov esi, [symbols] mov ecx, [num_symbols] mov ebx, [esi] cmp [ebx], eax jz .donez jb @f pop edx ecx ebx jmp .ret0 @@: ; invariant: symbols_addr[edx] < eax < symbols_addr[ecx] ; TODO: add meaningful label names .0: push edx .1: add edx, ecx sar edx, 1 cmp edx, [esp] jz .done2 mov ebx, [esi+edx*4] cmp [ebx], eax jz .done ja .2 mov [esp], edx jmp .1 .2: mov ecx, edx pop edx jmp .0 .donecont: dec edx .done: test edx, edx jz @f mov ebx, [esi+edx*4-4] cmp [ebx], eax jz .donecont @@: pop ecx .donez: mov esi, [esi+edx*4] add esi, 4 pop edx ecx ebx clc ret .done2: lea esi, [esi+edx*4] pop ecx edx ecx ebx stc ret ;----------------------------------------------------------------------------- ; ; in: esi->name ; out: if found: CF = 0, EAX = value ; otherwise CF = 1 find_symbol_name: cmp [num_symbols], 0 jnz @f .stc_ret: stc ret @@: push ebx ecx edx edi push -1 pop edx mov ebx, [symbols] mov ecx, [num_symbols] lea ebx, [ebx+ecx*4] ; invariant: symbols_name[edx] < name < symbols_name[ecx] .0: push edx .1: add edx, ecx sar edx, 1 cmp edx, [esp] jz .done2 call .cmp jz .done jb .2 mov [esp], edx jmp .1 .2: mov ecx, edx pop edx jmp .0 .done: pop ecx .donez: mov eax, [ebx+edx*4] mov eax, [eax] pop edi edx ecx ebx clc ret .done2: pop edx edi edx ecx ebx stc ret .cmp: mov edi, [ebx+edx*4] push esi add edi, 4 @@: cmpsb jnz @f cmp byte [esi-1], 0 jnz @b @@: pop esi ret ;----------------------------------------------------------------------------- ; Include disassembler engine include 'disasm.inc' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATA ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; caption_str db 'Kolibri Debugger',0 caption_len = $ - caption_str begin_str db 'Kolibri Debugger, version 0.33',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 ;----------------------------------------------------------------------------- ; Commands format definitions ; TODO: make it with macros ; 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, OnStepMultiple, StepSyntax, StepHelp db 0Bh dd aProceed, OnProceed, ProceedSyntax, ProceedHelp db 0Bh 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 aLoadSymbols, OnLoadSymbols, LoadSymbolsSyntax, LoadSymbolsHelp db 0Ah dd 0 ;----------------------------------------------------------------------------- ; Help messages for commands groups 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 ; Control commands group 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 [params] - load program for debugging',10 db 'reload - reload debugging program',10 db 'load-symbols - load information on symbols for 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 [] - go on (resume execution of debugging program)',10 db 's [] - program step, also ',10 db 'p [] - program wide step, also ',10 db 'unpack - try to bypass unpacker code (heuristic)',10,0 ; Data commands group aData db 5,'data',0 help_data_msg db 'List of data commands:',10 db '? - calculate value of expression',10 db 'd [] - dump data at given address',10 db 'u [] - unassemble instructions at given address',10 db 'r or',10 db 'r = - set register value',10,0 ; Breakpoints commands group aBreakpoints db 12,'breakpoints',0 help_breaks_msg db 'List of breakpoints commands:',10 db 'bp - set breakpoint on execution',10 db 'bpm[b|w|d] - set breakpoint on memory access',10 db 'bl [] - breakpoint(s) info',10 db 'bc ... - clear breakpoint',10 db 'bd ... - disable breakpoint',10 db 'be ... - enable breakpoint',10,0 ;----------------------------------------------------------------------------- ; Individual command help messages 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 [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 - 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 - 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: ? ',10,0 aUnassemble db 2,'u',0 UnassembleHelp db 'Unassemble',10 UnassembleSyntax db 'Usage: u - 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 ',10 db ' or: r = - set value of to ',10,0 aBp db 3,'bp',0 BpHelp db 'set BreakPoint on execution',10 BpSyntax db 'Usage: bp ',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] ',10 db ' bpmw [w] ',10 db ' bpmd [w] ',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 - display info on particular breakpoint',10,0 aBc db 3,'bc',0 BcHelp db 'Breakpoint Clear',10 BcSyntax db 'Usage: bc ',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 ',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 ',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 aLoadSymbols db 13,'load-symbols',0 LoadSymbolsHelp db 'Load symbolic information for executable',10 LoadSymbolsSyntax db 'Usage: load-symbols ',10,0 aUnknownCommand db 'Unknown command',10,0 ;----------------------------------------------------------------------------- ; Error messages load_err_msg db 'Cannot load program. ',0 unk_err_msg db 'Unknown error code -%4X',10,0 aCannotLoadFile db 'Cannot load file. ',0 unk_err_msg2 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' aMain db '[ CPU ]' aSSE db '[ SSE ]' aAVX db '[ AVX ]' aMSR db '[ MSR ]' aPoint db 0x1C aMinus db '-' aColon db ':' aSpace db ' ' aQuests db '??' aDots db '...' aParseError db 'Parse error',10,0 aDivByZero db 'Division by 0',10,0 calc_string db '%8X',10,0 aNoMemory db 'No memory',10,0 aSymbolsLoaded db 'Symbols loaded',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 ;----------------------------------------------------------------------------- ; Registers strings regs_strs: db 'EAX=' db 'EBX=' db 'ECX=' db 'EDX=' db 'ESI=' db 'EDI=' db 'EBP=' db 'ESP=' db 'EIP=' db 'EFLAGS=' fpu_strs: db 'ST0=' db 'ST1=' db 'ST2=' db 'ST3=' db 'ST4=' db 'ST5=' db 'ST6=' db 'ST7=' mmx_strs: db 'MM0=' db 'MM1=' db 'MM2=' db 'MM3=' db 'MM4=' db 'MM5=' db 'MM6=' db 'MM7=' sse_strs: db '-XMM0-' db '-XMM1-' db '-XMM2-' db '-XMM3-' db '-XMM4-' db '-XMM5-' db '-XMM6-' db '-XMM7-' avx_strs: db '-YMM0-' db '-YMM1-' db '-YMM2-' db '-YMM3-' db '-YMM4-' db '-YMM5-' db '-YMM6-' db '-YMM7-' debuggee_pid dd 0 bSuspended db 0 bAfterGo db 0 temp_break dd 0 reg_mode db 1 include 'disasm_tbl.inc' 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 IncludeIGlobals fn70_read_block: dd 0 dq 0 dd ? dd ? db 0 dd ? fn70_attr_block: dd 5 dd 0,0,0 dd fileattr db 0 dd ? fn70_load_block: dd 7 dd 1 load_params dd 0 dd 0 dd 0 i_end: loadname: db 0 rb 255 symbolsfile rb 260 prgname_ptr dd ? prgname_len dd ? IncludeUGlobals dbgwnd dd ? messages rb messages_height*messages_width messages_pos dd ? cmdline rb cmdline_width+1 cmdline_len dd ? cmdline_pos dd ? curarg dd ? cmdline_prev rb cmdline_width+1 was_temp_break db ? dbgbufsize dd ? dbgbuflen dd ? dbgbuf rb 256 fileattr rb 40 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 mmx_context: _mm0 dq ? _mm1 dq ? _mm2 dq ? _mm3 dq ? _mm4 dq ? _mm5 dq ? _mm6 dq ? _mm7 dq ? oldmmxcontext rb $-mmx_context fpu_context: _st0 dq ? _st1 dq ? _st2 dq ? _st3 dq ? _st4 dq ? _st5 dq ? _st6 dq ? _st7 dq ? oldfpucontext rb $-fpu_context sse_context: _xmm0 dq 2 dup ? _xmm1 dq 2 dup ? _xmm2 dq 2 dup ? _xmm3 dq 2 dup ? _xmm4 dq 2 dup ? _xmm5 dq 2 dup ? _xmm6 dq 2 dup ? _xmm7 dq 2 dup ? oldssecontext rb $-sse_context avx_context: _ymm0 dq 4 dup ? _ymm1 dq 4 dup ? _ymm2 dq 4 dup ? _ymm3 dq 4 dup ? _ymm4 dq 4 dup ? _ymm5 dq 4 dup ? _ymm6 dq 4 dup ? _ymm7 dq 4 dup ? oldavxcontext rb $-avx_context step_num dd 0 proc_num dd 0 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 ? symbols dd ? num_symbols 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: ; vim: ft=fasm tabstop=4