diff options
| author | emmadoth <emmadoth@disroot.org> | 2023-07-27 03:11:26 +0200 |
|---|---|---|
| committer | emmadoth <emmadoth@disroot.org> | 2023-07-27 03:11:26 +0200 |
| commit | b8fa4be54b73b9a9f04bfd5fb68e4929d86fe478 (patch) | |
| tree | 642755ae54c27125a2bf248e913304814d82a9b1 | |
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | Makefile | 13 | ||||
| -rw-r--r-- | escaper.s | 139 |
3 files changed, 155 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b95b722 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +escape + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..deec692 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +SRC = escaper +OUT = escape +WRN = -w+all +FMTN = elf64 +FMTL = elf_x86_64 + +default: + nasm -f $(FMTN) $(WRN) $(SRC).s + ld -m $(FMTL) $(SRC).o -o $(OUT) +debug: + nasm -g -f $(FMTN) $(WRN) $(SRC).s + ld -m $(FMTL) $(SRC).o -o $(OUT) + diff --git a/escaper.s b/escaper.s new file mode 100644 index 0000000..19b0095 --- /dev/null +++ b/escaper.s @@ -0,0 +1,139 @@ +global _start + +%macro write 3 + mov rdi, %1 + mov rsi, %2 + mov rdx, %3 + mov rax, 1 + syscall +%endmacro + +%macro read 3 + mov rdi, %1 + mov rsi, %2 + mov rdx, %3 + xor rax, rax + syscall +%endmacro + +%macro mmap 6 + mov rdi, %1 + mov rsi, %2 + mov rdx, %3 + mov r10, %4 + mov r8, %5 + mov r9, %6 + mov rax, 9 + syscall +%endmacro + +%macro munmap 2 + mov rdi, %1 + mov rsi, %2 + mov rax, 11 + syscall +%endmacro + +%macro exit 1 + mov rdi, %1 + mov rax, 60 + syscall +%endmacro + +section .text +_start: + pop qword [argc] + pop rcx + cmp dword [argc], 1 + jg skip_stdin +stdin_loop: + read 0, buf, 4000 + cmp rax, 1 + jle end + mov rdx, buf + mov rcx, [argc] + jmp count_start +clear_pos: + cmp rbx, rax + je arg_loop + mov byte [pos + rax], 0 + inc rax + jmp clear_pos +skip_stdin: + mov rcx, [argc] +arg_loop: + cmp rcx, 1 + jle end + pop rdx +count_start: + xor rax, rax + xor rbx, rbx +count_loop: + cmp byte [rdx + rax], '~' + je found + cmp byte [rdx + rax], '`' + je found + cmp byte [rdx + rax], '_' + je found + cmp byte [rdx + rax], '*' + je found + cmp byte [rdx + rax], '|' + je found + cmp byte [rdx + rax], '\' + je found + cmp byte [rdx + rax], 0 + je escape + inc rax + jmp count_loop +found: + inc rbx + mov byte [pos + rax], 1 + inc rax + jmp count_loop +escape: + push rcx ; argc counter + push rax ; string length + push rbx ; number of extra characters needed + push rdx ; string memory address + add rbx, rax + inc rbx + mmap 0, rbx, 3, 34, -1, 0 ; 3 = PROT_READ | PROT_WRITE, 34 = MAP_PRIVATE | MAP_ANONYMOUS + pop rdx + pop rbx + pop rsi + add rsi, rbx + xor r8, r8 + xor r9, r9 +escape_loop: + cmp r9, rsi + je escape_loop_end + cmp byte [pos + r8], 1 + jne skip_backslash + mov byte [rax + r9], '\' + inc r9 +skip_backslash: + mov r10b, byte [rdx + r8] + mov byte [rax + r9], r10b + inc r8 + inc r9 + jmp escape_loop +escape_loop_end: + mov byte [rax + r9], 10 + inc r9 + push rax + write 1, rax, r9 + pop rax + munmap rax, r9 + pop rcx +next_arg: + dec rcx + xor rax, rax + jmp clear_pos +end: + exit 0 + +section .bss + argc: resq 1 + buf: resb 4001 + pos: resb 4000 + |
