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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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: mcall 68, 11 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 mcall ; set debug messages buffer mov ecx, dbgbufsize mov dword [ecx], 256 xor ebx, ebx mov [ecx+4], ebx mov al, 69 mcall 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 mcall 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 mcall keypressed: mov al, 2 mcall 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 mcall 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 mcall 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 %X lodsb ; get 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 mcall mov edx, messages push messages_width pop esi xor ecx, ecx mov al, 4 mov ebx, messages_x_pos*10000h+messages_y_pos @@: mcall 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 mcall 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 mcall 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 mcall .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 mcall 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 mcall 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 @@: mcall mov ebx, (data_x_pos+data_x_size-10+4)*0x10000 + data_x_pos+data_x_size+2 mcall 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] @@: mcall 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 @@: mcall 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, 40808080h cmp [debuggee_pid], 0 jz .cd cmp [bSuspended], 0 jz .cd mov ecx, 40000000h push edi mov edi, [eax] cmp dword [eax+oldcontext-context], edi pop edi jz .cd mov ecx, 0x4000AA00 .cd: push 4 pop eax mcall imul esi, 60000h lea edx, [ebx+esi] mov al, 47 mov ebx, 80101h mov esi, ecx pop ecx mcall 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, 40808080h cmp [debuggee_pid], 0 jz .doit cmp [bSuspended], 0 jz .doit mov ecx, 40000000h bt [_eflags], edi lahf bt dword [_eflags + oldcontext - context], edi rcl ah, 1 test ah, 3 jp .doit mov ecx, 0x4000AA00 .doit: mov ah, 0 mov edi, 0xFFFFFF mcall ret draw_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 mcall redraw_registers: mov edi, 0xFFFFFF 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 mcall mov edx, flags @@: add ebx, 2*6*10000h call draw_flag inc edx cmp dl, flags_bits and 0xFF jnz @b ret draw_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 mcall redraw_dump: ; addresses mov al, 47 mov ebx, 80100h mov edx, data_x_pos*10000h + dump_y_pos mov ecx, [dumppos] mov edi, 0xFFFFFF mov esi, 40808080h cmp [debuggee_pid], 0 jz @f cmp [bSuspended], 0 jz @f mov esi, 40000000h @@: mcall add ecx, 10h add edx, 10 cmp dl, dump_y_pos + dump_y_size jb @b ; hex dump of data mov ecx, dumpdata push ecx xor ebx, ebx mov edx, (data_x_pos+12*6)*10000h + dump_y_pos cmp [dumpread], ebx jz .hexdumpdone1 .hexdumploop1: push ebx mov ebx, 20101h mcall pop ebx add edx, 3*6*10000h inc ecx inc ebx test bl, 15 jz .16 test bl, 7 jnz @f add edx, 2*6*10000h - 10 + 6*(3*10h+2)*10000h .16: add edx, 10 - 6*(3*10h+2)*10000h @@: cmp ebx, [dumpread] jb .hexdumploop1 .hexdumpdone1: mov al, 4 mov ecx, esi xchg ebx, edx push 2 pop esi .hexdumploop2: cmp edx, dump_height*10h jae .hexdumpdone2 push edx mov edx, aQuests mcall pop edx add ebx, 3*6*10000h inc edx test dl, 15 jz .16x test dl, 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 @@: mcall 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 @@: mcall 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 pop edx push dump_height*10h .asciiloop: push edx cmp byte [edx], 20h jae @f mov edx, aPoint @@: mcall pop edx inc edx add ebx, 6*10000h dec dword [esp] jz .asciidone test byte [esp], 15 jnz .asciiloop add ebx, 10 - 6*10h*10000h jmp .asciiloop .asciidone: pop ecx 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) ; mcall draw_disasm: mov eax, [disasm_start_pos] mov [disasm_cur_pos], eax and [disasm_cur_str], 0 .loop: mov eax, [disasm_cur_pos] call find_symbol jc .nosymb mov ebx, [disasm_cur_str] imul ebx, 10 push ebx lea ecx, [ebx+disasm_y_pos-1] shl ecx, 16 mov cl, 11 mov edx, 0xFFFFFF mov ebx, data_x_pos*10000h + data_x_size push 13 pop eax mcall pop ebx mov edi, edx add ebx, (data_x_pos+6*2)*10000h+disasm_y_pos mov edx, esi @@: lodsb test al, al jnz @b mov byte [esi-1], ':' sub esi, edx mov ecx, 40000000h mov al, 4 mcall mov byte [esi+edx-1], 0 lea esi, [esi*3] movzx ecx, bx shr ebx, 16 lea ebx, [ebx+esi*2] shl ecx, 16 mov cl, 10 imul ebx, 10001h sub bx, data_x_pos+data_x_size neg bx mov al, 13 mov edx, edi mcall inc [disasm_cur_str] cmp [disasm_cur_str], disasm_height jae .loopend .nosymb: push [disasm_cur_pos] call disasm_instr pop ebp jc .loopend xor esi, esi ; default color: black mov edx, 0xFFFFFF ; default background: white 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 mov edx, 0xFF0000 ; use background: red .nored: mov eax, [_eip] cmp eax, ebp jnz .noblue mov edx, 0x0000FF ; use background: blue mov esi, 0xFFFFFF ; on blue bgr, use white color .noblue: push 13 pop eax mcall mov al, 47 mov ebx, 80100h mov edx, [disasm_cur_str] imul edx, 10 add edx, data_x_pos*10000h + disasm_y_pos mov ecx, ebp mcall mov al, 4 lea ebx, [edx+8*6*10000h] mov ecx, esi push 2 pop esi mov edx, aColon mcall push 9 pop edi lea edx, [ebx+2*6*10000h] mov esi, ecx mov ecx, ebp sub ecx, [disasm_start_pos] add ecx, disasm_buffer .drawhex: mov al, 47 mov ebx, 20101h mcall 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 mcall 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 mcall inc [disasm_cur_str] cmp [disasm_cur_str], disasm_height jb .loop .loopend: mov ecx, disasm_height sub ecx, [disasm_cur_str] jz @f imul ecx, 10 inc ecx mov eax, disasm_y_pos + disasm_y_size sub eax, ecx shl eax, 16 add ecx, eax push 13 pop eax mov ebx, data_x_pos*65536 + data_x_size mov edx, 0xFFFFFF mcall @@: 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 .l: mov eax, [disasm_cur_pos] call find_symbol jc @f dec ecx jz .m @@: cmp [_eip], eax jz redraw_disasm push ecx call disasm_instr pop ecx jc .m loop .l .m: 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] mcall 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 mcall ; define window xor eax, eax mov ebx, wnd_x_size mov ecx, wnd_y_size mov edx, 54FFFFFFh mov edi, caption_str mcall ; clear unused areas mov al, 48 push 4 pop ebx mcall cmp eax, title_y_pos jb @f push registers_y_pos pop eax @@: push registers_y_pos pop ecx push eax sub ecx, eax shl eax, 16 add ecx, eax mov ebx, 5*10000h + (wnd_x_size-9) push 13 pop eax mcall mov ecx, (registers_y_pos+registers_y_size)*10000h + (dump_y_pos-registers_y_pos-registers_y_size) mcall mov ecx, (dump_y_pos+dump_y_size)*10000h + (disasm_y_pos-dump_y_pos-dump_y_size) mcall mov ecx, (disasm_y_pos-1+disasm_y_size)*10000h + (messages_y_pos-disasm_y_pos+1-disasm_y_size) mcall mov ecx, (messages_y_pos+messages_y_size)*10000h + (wnd_y_size-messages_y_pos-messages_y_size-4) mcall mov ebx, 5*10000h + (data_x_pos-5) pop ecx imul ecx, 10001h sub cx, wnd_y_size-4 neg cx mcall mov ebx, (data_x_pos+data_x_size)*10000h + (wnd_x_size-data_x_pos-data_x_size-4) mcall ; 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 mcall mov ecx, (messages_y_pos+messages_y_size+2)*10001h mcall mov ebx, (messages_x_pos-2)*10001h push ebx mov ecx, (messages_y_pos-2)*10000h + (messages_y_pos+messages_y_size+2) mcall mov ebx, (messages_x_pos+messages_x_size+2)*10001h push ebx mcall ; command line frame mov ecx, (cmdline_y_pos-2)*10000h + (cmdline_y_pos+cmdline_y_size+2) pop ebx mcall pop ebx mcall pop ebx mov ecx, (cmdline_y_pos+cmdline_y_size+2)*10001h mcall mov ecx, (cmdline_y_pos-2)*10001h mcall ; 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) mcall mov ebx, (data_x_pos+data_x_size+2)*10001h mcall mov ebx, (data_x_pos-2)*10000h + (data_x_pos+data_x_size+2) mov ecx, (dump_y_pos-3)*10001h mcall mov ecx, (disasm_y_pos-4)*10001h mcall call redraw_title call draw_registers call draw_dump call redraw_disasm ; end redraw push 12 pop eax push 2 pop ebx mcall 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: push -1 pop eax mcall 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 ret set_context: push 2 pop ebx push 69 pop eax mov ecx, [debuggee_pid] mov esi, context push 28h pop edx mcall 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 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 mov ecx, [symbols] jecxz do_reload mcall 68, 13 and [symbols], 0 and [num_symbols], 0 do_reload: push 18 pop eax push 7 pop ebx mcall mov [dbgwnd], eax xchg ecx, eax push 70 pop eax mov ebx, fn70_load_block mcall 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 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 ; 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 .wait: push 10 pop eax mcall 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 call draw_cursor mov esi, aN_str jmp put_message .yes: push 40 pop eax mov ebx, 0x107 mcall 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 mcall 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 mcall call AfterSuspend mov esi, aSuspended jmp put_message DoResume: mov ecx, [debuggee_pid] push 5 pop ebx push 69 pop eax mcall 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 mcall and [debuggee_pid], 0 call redraw_title call redraw_registers call redraw_dump 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: 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 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 .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 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 ; 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] mcall 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 .sysenter: ; return address is [ebp-4] push 0 push 69 pop eax inc edx ; read 4 bytes mov esi, [_ebp] sub esi, 4 mcall 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 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 mcall 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 symbol push esi @@: lodsb cmp al, ' ' ja @b push eax mov byte [esi], 0 xchg esi, [esp+4] call find_symbol_name mov edi, eax pop eax xchg esi, [esp] mov byte [esi], al jc @f add esp, 4 mov al, token_hex ret @@: pop esi ; 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 .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 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 mcall 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] mcall 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 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 mcall dec eax jnz .err mov al, 69 push 0xCC mov edi, esp inc ebx mcall 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 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 mcall 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 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 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 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 pop eax pop edx cmp eax, [_eip] jz .done call DoResume jmp .wait .done: mov esi, aUnpacked jmp .x1 include 'sort.inc' compare: cmpsd jnz @f cmp esi, edi @@: ret 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 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 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 redraw_disasm find_symbol: ; in: eax=address ; out: esi, CF 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] .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 find_symbol_name: ; in: esi->name ; out: if found: CF clear, eax=value ; otherwise CF set 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISASSEMBLER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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: csegcs: csegds: cseges: csegss: csegfs: cseggs: mov esi, cmd1 iglobal cmd1: 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 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' cmd2: db 0x05,7,'syscall' db 0x06,4,'clts' db 0x31,5,'rdtsc' db 0x34,8,'sysenter' db 0xA2,5,'cpuid' db 0x77,4,'emms' endg jmp @f ccpuid: crdtsc: cemms: cop0_F: mov esi, cmd2 @@: 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 cxlat: cunk: cerr: mov eax, '???' stosd clc ret cF: call disasm_get_byte jmp dword [disasm_table_2 + eax*4] crep: push [disasm_cur_pos] call disasm_get_byte cmp al, 0x0F jz .sse mov dl, al mov eax, 'rep ' stosd mov al, dl @@: and eax, not 1 cmp al, 0x66 jnz @f call disasm_get_byte mov dl, al jmp @b @@: cmp al, 0xA6 jz .repz cmp al, 0xAE jz .repz cmp al, 0xA4 jz .prefix cmp al, 0xAA jz .prefix cmp al, 0xAC jz .prefix cmp al, 0x6C jz .prefix cmp al, 0x6E jz .prefix .noprefix: pop [disasm_cur_pos] and byte [edi-1], 0 ret .repz: mov byte [edi-1], 'z' mov al, ' ' stosb .prefix: pop [disasm_cur_pos] jmp disasm_loop1 .sse: pop eax call disasm_get_byte iglobal rep_sse_cmds: db 0x58,3,'add' db 0xC2,3,'cmp' db 0,0 endg mov esi, rep_sse_cmds+1 @@: movzx edx, byte [esi] cmp al, [esi-1] jz @f lea esi, [esi+edx+2] cmp byte [esi], 0 jnz @b sub [disasm_cur_pos], 2 mov eax, 'rep' stosd ret @@: push ecx mov ecx, edx inc esi rep movsb pop ecx mov al, 's' stosb jmp rep_sse_final crepnz: call disasm_get_byte cmp al, 0x0F jz .sse mov dl, al mov eax, 'repn' stosd mov al, 'z' stosb mov al, ' ' stosb movzx eax, dl cmp al, 0x6C jb crep.noprefix cmp al, 0x6F jbe .prefix cmp al, 0xA4 jb crep.noprefix cmp al, 0xA7 jbe .prefix cmp al, 0xAA jb crep.noprefix cmp al, 0xAF ja crep.noprefix .prefix: jmp cop0 .sse: call disasm_get_byte mov esi, rep_sse_cmds+1 @@: movzx edx, byte [esi] cmp al, [esi-1] jz .found0 lea esi, [esi+edx+2] cmp byte [esi], 0 jnz @b mov esi, sse_cmds2+1 @@: movzx edx, byte [esi] cmp al, [esi-1] jz .found1 lea esi, [esi+edx+2] cmp byte [esi], 0 jnz @b sub [disasm_cur_pos], 2 mov eax, 'repn' stosd mov al, 'z' stosb and byte [edi], 0 ret .found0: push ecx mov ecx, edx inc esi rep movsb pop ecx mov al, 's' stosb mov al, 'd' jmp rep_sse_final .found1: push ecx mov ecx, edx inc esi rep movsb pop ecx mov al, 'p' stosb mov al, 's' rep_sse_final: stosb push ecx push 5 pop ecx sub ecx, edx adc ecx, 1 mov al, ' ' rep stosb pop ecx or ch, 1 jmp disasm_mmx1 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 esi cmp eax, 0x80 jl .nosymb lea esi, [eax-1] test eax, esi jz .nosymb call find_symbol jc .nosymb @@: lodsb test al, al jz @f stosb jmp @b @@: pop esi ret .nosymb: pop esi 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 iglobal 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' endg 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 .2a: mov al, ']' stosb pop ecx ret .vmod3: pop ecx test ch, 10h jnz .vmod3_mmi 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 .vmod3_mmi: disasm_write_mmreg = $ test ch, 1 jz @f mov byte [edi], 'x' inc edi @@: mov word [edi], 'mm' 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 iglobal disasm_rm16_1 dd 'bxsi','bxdi','bpsi','bpdi' disasm_rm16_2 dw 'si','di','bp','bx' endg 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 center: mov eax, 'ente' stosd mov eax, 'r ' stosd xor eax, eax call disasm_get_word call disasm_write_num mov al, ',' stosb mov al, ' ' stosb xor eax, eax call disasm_get_byte jmp @b 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 iglobal disasm_shifts dd 'rol ','ror ','rcl ','rcr ','shl ','shr ','sal ','sar ' endg 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 caam: mov eax, 'aam ' jmp @f caad: mov eax, 'aad ' @@: stosd mov eax, ' ' stosd xor eax, eax call disasm_get_byte cmp al, 10 jz @f call disasm_write_num @@: and byte [edi], 0 ret 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 iglobal disasm_op2cmds dd 'add ','or ','adc ','sbb ','and ','sub ','xor ','cmp ' endg 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 carpl: xor edx, edx or ch, 0C1h mov eax, 'arpl' jmp cop22.d2 ccmpxchg: xor edx, edx disasm_set_modew or ch, 40h mov eax, 'cmpx' stosd mov eax, 'chg ' jmp cop22.d1 cbsf: cbsr: or ch, 80h 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, 'bsf ' cmp al, 0BCh jz @f mov esi, 'bsr ' cmp al, 0BDh 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 .d2: stosd mov eax, ' ' .d1: 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 cmp dl, 0xBC jz @f cmp dl, 0xBD 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 cbound: mov edx, eax mov eax, 'boun' stosd mov eax, 'd ' or ch, 0xC0 jmp cop22.d1 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 cmovcc: or ch, 0C0h and eax, 0xF mov ax, [disasm_jcc_codes + eax*2] mov dword [edi], 'cmov' add edi, 4 stosw mov ax, ' ' stosw call disasm_get_byte dec [disasm_cur_pos] shr eax, 3 and eax, 7 call disasm_write_reg1632 mov ax, ', ' stosw call disasm_readrmop 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 iglobal btx1codes dd 'bt ','bts ','btr ','btc ' endg 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 iglobal disasm_jcc_codes dw 'o ','no','b ','ae','z ','nz','be','a ','s ','ns','p ','np','l ','ge','le','g ' endg 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 test ch, 1 jnz @f call disasm_get_dword jmp disasm_rva @@: call disasm_get_word add eax, [disasm_cur_pos] and eax, 0xFFFF call disasm_write_num and byte [edi], 0 ret ccallf: mov eax, 'call' stosd mov eax, ' ' stosd mov al, 'd' test ch, 1 jnz @f mov al, 'p' @@: stosb mov eax, 'word' stosd mov al, ' ' stosb test ch, 1 jnz .1 call disasm_get_dword jmp .2 .1: xor eax, eax call disasm_get_word .2: push eax xor eax, eax call disasm_get_word call disasm_write_num mov al, ':' stosb pop eax call disasm_write_num and byte [edi], 0 ret iglobal op11codes dd 'test',0,'not ','neg ','mul ','imul','div ','idiv' op12codes dd 'inc ','dec ','call',0,'jmp ',0,'push',0 endg cop1: disasm_set_modew xchg eax, edx call disasm_get_byte movzx esi, al dec [disasm_cur_pos] shr al, 3 and eax, 7 cmp dl, 0xFE jnz @f cmp al, 1 jbe @f .0: inc [disasm_cur_pos] jmp cunk @@: and edx, 8 add eax, edx cmp al, 11 jz .callfar cmp al, 13 jz .jmpfar mov eax, [op11codes+eax*4] test eax, eax jz .0 cmp eax, 'test' jz ctest .2: stosd mov eax, ' ' stosd call disasm_readrmop and byte [edi], 0 ret .callfar: mov eax, 'call' .1: cmp esi, 0xC0 jae .0 stosd mov eax, ' ' stosd mov eax, 'far ' stosd mov al, 'd' test ch, 1 jnz @f mov al, 'p' @@: stosb or ch, 1 call disasm_readrmop and byte [edi], 0 ret .jmpfar: mov eax, 'jmp ' jmp .1 cpop2: or ch, 80h call disasm_get_byte dec [disasm_cur_pos] test al, 00111000b jnz cunk mov eax, 'pop ' jmp cop1.2 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], 0 ret ccwd: mov eax, 'cwd ' test ch, 1 jnz @b mov eax, 'cdq ' jmp @b ccmpxchg8b: call disasm_get_byte cmp al, 0xC0 jae cerr shr al, 3 and al, 7 cmp al, 1 jnz cerr dec [disasm_cur_pos] mov eax, 'cmpx' stosd mov eax, 'chg8' stosd mov al, 'b' stosb mov al, ' ' stosb or ch, 40h call disasm_readrmop and byte [edi], 0 ret iglobal fpuD8 dd 'add ','mul ','com ','comp','sub ','subr','div ','divr' endg 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 iglobal 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 ' endg 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 iglobal fpuDB dd 'ild ',0,'ist ','istp',0,'ld ',0,'stp ' endg 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 iglobal fpuDC dd 'add ','mul ',0,0,'subr','sub ','divr','div ' endg 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 iglobal fpuDD dd 'fld ',0,'fst ','fstp',0,0,0,0 fpuDD_2 dq 'ffree ',0,'fst ','fstp ','fucom ','fucomp ',0,0 endg 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 iglobal fpuDE dd 'add ','mul ',0,0,'subr','sub ','divr','div ' endg 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 iglobal fpuDF dd 'ild ',0,'ist ','istp','bld ','ild ','bstp','istp' endg 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 cmovd1: mov eax, 'movd' stosd mov eax, ' ' stosd call disasm_get_byte dec [disasm_cur_pos] shr al, 3 and eax, 7 call disasm_write_mmreg mov ax, ', ' stosw or ch, 0C0h and ch, not 1 call disasm_readrmop and byte [edi], 0 ret cmovd2: mov eax, 'movd' stosd mov eax, ' ' stosd call disasm_get_byte dec [disasm_cur_pos] shr al, 3 and eax, 7 push eax ecx or ch, 0C0h and ch, not 1 call disasm_readrmop mov ax, ', ' stosw pop ecx eax call disasm_write_mmreg and byte [edi], 0 ret cmovq1: test ch, 1 jz .mm mov eax, 'movd' stosd mov eax, 'qa ' stosd jmp disasm_mmx1 .mm: mov eax, 'movq' stosd mov eax, ' ' stosd jmp disasm_mmx1 cmovq2: test ch, 1 jz .mm mov eax, 'movd' stosd mov eax, 'qa ' stosd jmp disasm_mmx3 .mm: mov eax, 'movq' disasm_mmx2: stosd mov eax, ' ' stosd disasm_mmx3: or ch, 50h call disasm_get_byte dec [disasm_cur_pos] push eax call disasm_readrmop mov ax, ', ' stosw pop eax shr al, 3 and eax, 7 call disasm_write_mmreg and byte [edi], 0 ret iglobal mmx_cmds: db 0x60,'unpcklbw' db 0x61,'unpcklwd' db 0x62,'unpckldq' db 0x63,'packsswb' db 0x64,'pcmpgtb ' db 0x65,'pcmpgtw ' db 0x66,'pcmpgtd ' db 0x67,'packuswb' db 0x68,'unpckhbw' db 0x69,'unpckhwd' db 0x6A,'unpckhdq' db 0x6B,'packssdw' db 0x74,'pcmpeqb ' db 0x75,'pcmpeqw ' db 0x76,'pcmpeqd ' db 0xD4,'paddq ' db 0xD5,'pmullw ' db 0xD8,'psubusb ' db 0xD9,'psubusw ' db 0xDA,'pminub ' db 0xDB,'pand ' db 0xDC,'paddusb ' db 0xDD,'paddusw ' db 0xDE,'pmaxub ' db 0xDF,'pandn ' db 0xE0,'pavgb ' db 0xE3,'pavgw ' db 0xE4,'pmulhuw ' db 0xE5,'pmulhw ' db 0xE8,'psubsb ' db 0xE9,'psubsw ' db 0xEA,'pminsw ' db 0xEB,'por ' db 0xEC,'paddsb ' db 0xED,'paddsw ' db 0xEE,'pmaxsw ' db 0xEF,'pxor ' db 0xF4,'pmuludq ' db 0xF5,'pmaddwd ' db 0xF6,'psadbw ' db 0xF8,'psubb ' db 0xF9,'psubw ' db 0xFA,'psubd ' db 0xFB,'psubq ' db 0xFC,'paddb ' db 0xFD,'paddw ' db 0xFE,'paddd ' endg cpcmn: mov esi, mmx_cmds @@: cmp al, [esi] jz @f add esi, 9 jmp @b @@: inc esi mov al, 'p' cmp byte [esi], al jz @f stosb @@: movsd movsd cmp byte [edi-1], ' ' jz @f mov al, ' ' stosb @@: disasm_mmx1: or ch, 50h call disasm_get_byte dec [disasm_cur_pos] shr al, 3 and eax, 7 call disasm_write_mmreg mov ax, ', ' stosw call disasm_readrmop cmp word [disasm_string], 'cm' jz .cmp and byte [edi], 0 ret .cmp: call disasm_get_byte and eax, 7 mov dx, 'eq' dec eax js @f mov dx, 'lt' jz @f mov dh, 'e' dec eax jnz .no2 @@: xchg dx, word [disasm_string+3] mov word [disasm_string+5], dx and byte [edi], 0 ret .no2: dec eax jnz @f add edi, 2 push edi lea esi, [edi-3] lea ecx, [esi-(disasm_string+8)+2] std rep movsb cld mov cx, word [esi-3] mov dword [esi-3], 'unor' mov byte [esi+1], 'd' mov word [esi+2], cx pop edi and byte [edi+1], 0 ret @@: mov edx, 'neq' dec eax jz @f mov edx, 'nlt' dec eax jz @f mov edx, 'nle' dec eax jz @f mov edx, 'ord' @@: push edi lea esi, [edi-1] lea ecx, [esi-(disasm_string+8)+2] std rep movsb cld mov cx, word [esi-3] mov dword [esi-3], edx mov word [esi], cx pop edi and byte [edi+1], 0 ret cpsrlw: mov eax, 'psrl' jmp @f cpsraw: mov eax, 'psra' jmp @f cpsllw: mov eax, 'psll' @@: stosd mov eax, 'w ' stosd jmp disasm_mmx1 cpsrld: mov eax, 'psrl' jmp @f cpsrad: mov eax, 'psra' jmp @f cpslld: mov eax, 'psll' @@: stosd mov eax, 'd ' stosd jmp disasm_mmx1 cpsrlq: mov eax, 'psrl' jmp @f cpsllq: mov eax, 'psll' @@: stosd mov eax, 'q ' stosd jmp disasm_mmx1 csse1: iglobal sse_cmds1: db 0x2F,4,'comi' db 0x54,3,'and' db 0x55,4,'andn' db 0x58,3,'add' db 0xC2,3,'cmp' endg mov esi, sse_cmds1+1 .1: @@: movzx edx, byte [esi] cmp al, [esi-1] jz @f lea esi, [esi+edx+2] jmp @b @@: push ecx mov ecx, edx inc esi rep movsb pop ecx mov al, 's' cmp byte [edi-1], 'i' jz @f mov al, 'p' @@: stosb mov al, 'd' test ch, 1 jnz @f mov al, 's' @@: stosb push ecx push 5 pop ecx sub ecx, edx adc ecx, 1 mov al, ' ' rep stosb pop ecx or ch, 1 ; force XMM reg jmp disasm_mmx1 csse2: iglobal sse_cmds2: db 0xD0,6,'addsub' db 0,0 endg test ch, 1 jz cerr mov esi, sse_cmds2+1 jmp csse1.1 cpshift: mov dl, al mov ax, 'ps' stosw call disasm_get_byte push eax and al, 0xC0 cmp al, 0xC0 jnz .pop_cunk pop eax push eax shr al, 3 and eax, 7 cmp al, 2 jz .rl cmp al, 4 jz .ra cmp al, 6 jz .ll .pop_cunk: pop eax jmp cunk .ll: mov ax, 'll' jmp @f .rl: mov ax, 'rl' jmp @f .ra: cmp dl, 0x73 jz .pop_cunk mov ax, 'ra' @@: stosw mov al, 'w' cmp dl, 0x71 jz @f mov al, 'd' cmp dl, 0x72 jz @f mov al, 'q' @@: stosb mov ax, ' ' stosw stosb pop eax and eax, 7 call disasm_write_mmreg mov ax, ', ' stosw xor eax, eax call disasm_get_byte call disasm_write_num and byte [edi], 0 ret iglobal grp15c1 dq 'fxsave ','fxrstor ','ldmxcsr ','stmxcsr ',0,0,0,'clflush ' endg cgrp15: call disasm_get_byte cmp al, 0xC0 jae cunk shr al, 3 and eax, 7 mov edx, eax mov eax, dword [grp15c1+eax*8] test eax, eax jz cerr dec [disasm_cur_pos] stosd mov eax, dword [grp15c1+4+edx*8] stosd or ch, 40h call disasm_readrmop and byte [edi], 0 ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATA ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; caption_str db 'Kolibri Debugger',0 caption_len = $ - caption_str begin_str db 'Kolibri Debugger, version 0.32',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 aLoadSymbols, OnLoadSymbols, LoadSymbolsSyntax, LoadSymbolsHelp db 0Ah 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 [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',10 db 'p = - 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 '? - 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 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 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 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' 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 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, cbound,carpl, 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, ccallf,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,caad,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, cop0_F,cop0_F,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, csse1 dd cunk, crdtsc,cunk, cunk, cop0_F,cunk, cunk, cunk ; 3x dd cunk, cunk, cunk, cunk, cunk, cunk, cunk, cunk dd cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc ; 4x dd cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc,cmovcc dd cunk, cunk, cunk, cunk, csse1, csse1, cunk, cunk ; 5x dd csse1, cunk, cunk, cunk, cunk, cunk, cunk, cunk dd cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn ; 6x dd cpcmn, cpcmn, cpcmn, cpcmn, cunk, cunk, cmovd1,cmovq1 dd cunk, cpshift,cpshift,cpshift,cpcmn,cpcmn,cpcmn,cemms ; 7x dd cunk, cunk, cunk, cunk, cunk, cunk, cmovd2,cmovq2 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, cgrp15,cop22 dd ccmpxchg,ccmpxchg,cunk,cbtx2,cunk, cunk, cmovzx,cmovzx ; Bx dd cunk, cunk, cbtx1, cbtx2, cbsf, cbsr, cmovsx,cmovsx dd cunk, cunk, csse1, cunk, cunk, cunk, cunk, ccmpxchg8b ; Cx dd cbswap,cbswap,cbswap,cbswap,cbswap,cbswap,cbswap,cbswap dd csse2, cpsrlw,cpsrlw,cpsrlq,cpcmn, cpcmn, cunk, cunk ; Dx dd cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn dd cpcmn, cpsraw,cpsrad,cpcmn, cpcmn, cpcmn, cunk, cunk ; Ex dd cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn dd cunk, cpsllw,cpslld,cpsllq,cpcmn, cpcmn, cpcmn, cunk ; Fx dd cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, cpcmn, 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 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 ? 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 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: