X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=sped.asm;h=d7dcb8de8a7a55ed4bddc4917be6192cc886f130;hb=aab6303fb9c43a2d727774c25b3c50a4b1fcae8d;hp=110bf98378f1bd5e012172bb48a69c768c38c04b;hpb=fb894149783dd18e6ecf1271153193a342e80433;p=sped.git diff --git a/sped.asm b/sped.asm index 110bf98..d7dcb8d 100644 --- a/sped.asm +++ b/sped.asm @@ -3,12 +3,37 @@ %include "fileutils.S" -global main extern printf +extern fflush +extern stdout +extern free + +global main + +; macros +%macro write_str 2 + mov eax, 4 + mov ebx, 1 + mov ecx, %1 + mov edx, %2 + int 0x80 +%endmacro section .data banner_str db `SPED - the stupidly pointless editor\n`, 0x00 nofile_str db `no file provided\n`, 0x00 + readlines_str db `opened file with %i lines\n`, 0x00 + prompt_str db `sped > `, 0x00 + invalidcmd_str db `invalid command\n`, 0x00 + invalidaddr_str db `invalid address\n`, 0x00 + charcount_str db `read %i chars\n`, 0x00 + currentline_str db `current line: %i\n`, 0x00 + echo_str db `%s`, 0x00 ; print strings without format exploit + +section .bss + buffer resb 4 + buffer_lines resb 4 + cur_line resb 4 section .text main: @@ -35,10 +60,24 @@ main: push DWORD [ebx] call readFile + mov [buffer], eax + mov [buffer_lines], ecx + mov DWORD [cur_line], 0x00 + + push DWORD [buffer_lines] + push readlines_str + call printf + + call repl + mov eax, 0 jmp _main_exit _main_exit: + + ; free string array + + %undef _ARGC %undef _ARGV @@ -46,3 +85,178 @@ main: pop ebp ret +; prompt for user +; no args - reads from globals +repl: + + %define CMDSTR 4 ; the previous line read from user + + push ebp + mov ebp, esp + + sub esp, 4 + + _repl_loop: + + ; print the prompt + push prompt_str + call printf + push DWORD [stdout] + call fflush + + ; read line from stdin + push 0 + call readLine + + mov DWORD [ebp-CMDSTR], eax + + ; commands are single char for now + cmp ecx, 1 + jne _repl_invalid_cmd + + ; parse commands + mov eax, DWORD [ebp-CMDSTR] + mov eax, [eax] + + ; q exists program =-=-=-=-=-=-=-=-=-=-=-=-= + mov eax, DWORD [ebp-CMDSTR] + cmp BYTE [eax], 'q' + jne _repl_cmd_quit_end + jmp _repl_exit + _repl_cmd_quit_end: + + ; p prints current line =-=-=-=-=-=-=-=-=-=-= + mov eax, DWORD [ebp-CMDSTR] + cmp BYTE [eax], 'p' + jne _repl_cmd_print_end + + mov eax, DWORD [cur_line] + mov ecx, 4 + mul ecx + add eax, [buffer] + push DWORD [eax] + push echo_str + call printf + jmp _repl_continue + _repl_cmd_print_end: + + ; n prints the current line number =-=-=-=-=-=-=-= + mov eax, DWORD [ebp-CMDSTR] + cmp BYTE [eax], 'n' + jne _repl_cmd_number_end + + push DWORD [cur_line] + push currentline_str + call printf + + jmp _repl_continue + _repl_cmd_number_end: + + ; - goes to prev line =-=-=-=-=-=-=-=-=-=-=-=-= + mov eax, DWORD [ebp-CMDSTR] + cmp BYTE [eax], '-' + jne _repl_cmd_decline_end + + ; make sure we are within bounds + mov eax, DWORD [cur_line] + sub eax, 1 + cmp eax, 0 + jl _repl_invalid_addr + + sub DWORD [cur_line], 1 + + jmp _repl_continue + _repl_cmd_decline_end: + + ; + goes to next line =-=-=-=-=-=-=-=-=-=-=-=-= + mov eax, DWORD [ebp-CMDSTR] + cmp BYTE [eax], '+' + jne _repl_cmd_incline_end + + ; make sure we are within bounds + mov eax, DWORD [cur_line] + add eax, 1 + cmp eax, [buffer_lines] + jge _repl_invalid_addr + + add DWORD [cur_line], 1 + + jmp _repl_continue + _repl_cmd_incline_end: + + ; g goes to first line =-=-=-=-=-=-=-=-=-=-=-=-= + mov eax, DWORD [ebp-CMDSTR] + cmp BYTE [eax], 'g' + jne _repl_cmd_jumptop_end + + mov DWORD [cur_line], 0x00 + + jmp _repl_continue + _repl_cmd_jumptop_end: + + ; G goes to last line =-=-=-=-=-=-=-=-=-=-=-=-= + mov eax, DWORD [ebp-CMDSTR] + cmp BYTE [eax], 'G' + jne _repl_cmd_jumpbot_end + + mov eax, DWORD [buffer_lines] + sub eax, 1 + mov DWORD [cur_line], eax + + jmp _repl_continue + _repl_cmd_jumpbot_end: + + ; c changes the current line =-=-=-=-=-=-=-=-=-= + mov eax, DWORD [ebp-CMDSTR] + cmp BYTE [eax], 'c' + jne _repl_cmd_change_end + + ; read a new line to use + push 0 + call readLine + + mov esi, eax + + ; free old string + mov eax, [cur_line] + mov ecx, 4 + mul ecx + add eax, [buffer] + push DWORD [eax] + call free + + ; insert new string + mov eax, [cur_line] + mov ecx, 4 + mul ecx + add eax, DWORD [buffer] + mov [eax], esi + + jmp _repl_continue + _repl_cmd_change_end: + + + jmp _repl_invalid_cmd + + ; some error messages + _repl_invalid_cmd: + push invalidcmd_str + call printf + jmp _repl_continue + + _repl_invalid_addr: + push invalidaddr_str + call printf + jmp _repl_continue + + _repl_continue: + jmp _repl_loop + + _repl_exit: + + %undef CMDSTR + + mov esp, ebp + pop ebp + ret +