X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=sped.asm;h=213f3ea0806f7ee5abd2e999a49607b6604db72f;hb=7a7ed6ae81978b84911dab0b902e77ebb7e9b735;hp=d0a634bffc157a522c85b66e28d9112f82752262;hpb=c808c93519b1a3601f59bb6b82afec2c3d1b2a4b;p=sped.git diff --git a/sped.asm b/sped.asm index d0a634b..213f3ea 100644 --- a/sped.asm +++ b/sped.asm @@ -1,12 +1,14 @@ ; sped - the stupidly pointless editor ; written by pinosaur -global main +%include "fileutils.S" + extern printf -extern malloc -extern realloc +extern fflush +extern stdout extern free -extern memset + +global main ; macros %macro write_str 2 @@ -19,12 +21,20 @@ extern memset section .data banner_str db `SPED - the stupidly pointless editor\n`, 0x00 - readfile_str db `reading file %s\n`, 0x00 nofile_str db `no file provided\n`, 0x00 - argcount_str db `there are %d args\n`, 0x00 - wrongfile_str db `unable to open file, error code: %i\n`, 0x00 - char_str db `read this char: %i\n`, 0x00 - printfint_str db `int: %i\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 + buffer_filename resb 4 + cur_line resb 4 section .text main: @@ -47,17 +57,31 @@ main: _main_existing: mov ebx, DWORD [ebp+_ARGV] - add ebx, 4 - push DWORD [ebx] - ; push readfile_str - ; call printf + add ebx, 4 ; first user arg is filename + mov ebx, [ebx] + mov [buffer_filename], ebx + push DWORD [buffer_filename] 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 @@ -65,142 +89,191 @@ main: pop ebp ret +; prompt for user +; no args - reads from globals +repl: -; reads file line by line -; args: filename -; return: -; eax - pointer to mem -; ecx - lines read -readFile: - %define _FILE_NAME 8 - %define FILE_HANDLE 4 + %define CMDSTR 4 ; the previous line read from user push ebp mov ebp, esp - - ; allocate vars - sub esp, 4 - mov DWORD [ebp-FILE_HANDLE], 0x00 - ; open existing file - mov eax, 5 - mov ebx, [ebp+_FILE_NAME] - mov ecx, 0 - mov edx, 0777 - int 0x80 - mov [ebp-FILE_HANDLE], eax + sub esp, 4 - ; check if file was open successfully - cmp eax, 0 - jge _readFile_noerror - push eax - push wrongfile_str + _repl_loop: + + ; print the prompt + push prompt_str call printf - jmp _readFile_exit + 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: - _readFile_noerror: - push DWORD [ebp-FILE_HANDLE] - call readLine + ; n prints the current line number =-=-=-=-=-=-=-= + mov eax, DWORD [ebp-CMDSTR] + cmp BYTE [eax], 'n' + jne _repl_cmd_number_end - push eax + push DWORD [cur_line] + push currentline_str call printf - jmp _readFile_exit - - _readFile_exit: - ; close file - mov eax, 6 - mov ebx, [ebp-FILE_HANDLE] - int 0x80 + jmp _repl_continue + _repl_cmd_number_end: - %undef _FILE_NAME - %undef FILE_HANDLE + ; - goes to prev line =-=-=-=-=-=-=-=-=-=-=-=-= + mov eax, DWORD [ebp-CMDSTR] + cmp BYTE [eax], '-' + jne _repl_cmd_decline_end - mov esp, ebp - pop ebp - ret + ; 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: -; reads a line until newline character is reached -; args: file_handle -; return: -; eax: location to buffer -; ebx: contains eof -readLine: - %define _FILE_HANDLE 8 - %define CHAR_COUNT 4 ; count number of characters read - %define BLOCK_COUNT 8 ; number of 64 blocks we've read - %define STR_PTR 12 ; malloced buffer to store read string + ; + goes to next line =-=-=-=-=-=-=-=-=-=-=-=-= + mov eax, DWORD [ebp-CMDSTR] + cmp BYTE [eax], '+' + jne _repl_cmd_incline_end - push ebp - mov ebp, esp + ; make sure we are within bounds + mov eax, DWORD [cur_line] + add eax, 1 + cmp eax, [buffer_lines] + jge _repl_invalid_addr - ; allocate vars - sub esp, 8 - mov DWORD [ebp-CHAR_COUNT], 0x00 - mov DWORD [ebp-BLOCK_COUNT], 0x00 - - push 64 - call malloc - mov [ebp-STR_PTR], eax - - push DWORD [ebp-STR_PTR] - push 0x00 - push 64 - - _readLine_loop: - ; if buffer is full - cmp BYTE [ebp-CHAR_COUNT], 63 ; leave one byte for null byte - jne _readLine_notfull - jmp _readLine_exit - - _readLine_notfull: - ; read a single character - mov eax, 3 - mov ebx, [ebp+_FILE_HANDLE] - mov ecx, [ebp-STR_PTR] - add ecx, [ebp-CHAR_COUNT] - mov edx, 1 - int 0x80 + add DWORD [cur_line], 1 - ; mov eax, 4 - ; mov ebx, 1 - ; mov ecx, [ebp-STR_PTR] - ; add ecx, [ebp-CHAR_COUNT] - ; mov edx, 1 - ; int 0x80 - - ; check for newline - mov eax, [ebp-STR_PTR] - add eax, [ebp-CHAR_COUNT] - cmp DWORD [eax], 0x0a - jne _readLine_not_newline - mov ebx, 0 - jmp _readLine_exit - _readLine_not_newline: - - ; check for eof - mov eax, [ebp-STR_PTR] - add eax, [ebp-CHAR_COUNT] - cmp DWORD [eax], 0x05 - jne _readLine_not_eof - mov ebx, 1 - jmp _readLine_exit - _readLine_not_eof: + 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 - add DWORD [ebp-CHAR_COUNT], 1 - jmp _readLine_loop + ; free old string + mov eax, [cur_line] + mov ecx, 4 + mul ecx + add eax, [buffer] + push DWORD [eax] + call free - _readLine_exit: + ; insert new string + mov eax, [cur_line] + mov ecx, 4 + mul ecx + add eax, DWORD [buffer] + mov [eax], esi - mov eax, DWORD [ebp-STR_PTR] + jmp _repl_continue + _repl_cmd_change_end: - %undef _FILE_HANDLE - %undef CHAR_COUNT - %undef BLOCK_COUNT - %undef STR_PTR + ; w writes file =-=-=-=-=-=-=-=-=-=-=-=-= + mov eax, DWORD [ebp-CMDSTR] + cmp BYTE [eax], 'w' + jne _repl_cmd_write_end + + push DWORD [buffer_filename] + push DWORD [buffer] + push DWORD [buffer_lines] + call writeFile + + jmp _repl_continue + _repl_cmd_write_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 - +