summaryrefslogtreecommitdiff
path: root/escaper.s
diff options
context:
space:
mode:
Diffstat (limited to 'escaper.s')
-rw-r--r--escaper.s139
1 files changed, 139 insertions, 0 deletions
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
+