Last active
August 30, 2023 11:19
-
-
Save Zheaoli/f37bc1fb04917fdfac36d644ee69f7e9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.global _start | |
.section .text | |
_start: | |
# Setup stack frame | |
movq %rsp, %rbp | |
# Load argc | |
movq (%rbp), %r8 # %r8 now holds argc | |
# Load argv | |
leaq 8(%rbp), %r9 # %r9 now points to argv[0] | |
# Find envp by iterating through argv until NULL is found | |
movq %r9, %r10 # %r10 will be used to find envp | |
find_envp: | |
movq (%r10), %rdi # Load the current pointer in argv | |
cmpq $0, %rdi # Compare it to NULL | |
je envp_found # If NULL, we've found the end of argv | |
addq $8, %r10 # Otherwise, move to the next pointer in argv | |
jmp find_envp | |
envp_found: | |
addq $8, %r10 # Move one more step to point to the start of envp | |
# Allocate space on the stack for the new argv array | |
subq $8, %rsp # Space for NULL termination | |
subq %r8, %rsp | |
subq %r8, %rsp # Space for argc pointers (including argv[0]) | |
movq %rsp, %r11 # %r11 now points to the start of the new argv array | |
# Copy argv pointers to the new array | |
movq $0, %rcx # Counter | |
copy_loop: | |
cmpq %rcx, %r8 | |
je copy_done | |
movq (%r9, %rcx, 8), %rdi | |
movq %rdi, (%r11, %rcx, 8) | |
incq %rcx | |
jmp copy_loop | |
copy_done: | |
movq $0, (%r11, %rcx, 8) # NULL-terminate the new argv array | |
# Check if argc > 0 | |
cmpq $0, %r8 | |
jle .Lexit | |
# Execute execve syscall | |
movq $59, %rax # syscall number for execve | |
movq (%r11), %rdi # filename is argv[0] | |
movq %r11, %rsi # New argv array | |
movq %r10, %rdx # envp | |
syscall | |
.Lexit: | |
# Exit the program using the exit syscall | |
movq $60, %rax | |
xorq %rdi, %rdi | |
syscall |
Author
Zheaoli
commented
Aug 29, 2023
Quite cool! You can nonetheless speed up the whole thing by jumping directly to environment
which is basically &argv[argc + 1]
(you can test in C code if you want to be sure about it).
I would say something like this should do the trick but I am not an expert in amd64 assembly (or assembly at all):
movq r9, r11
add $1, r11 # r11 is argc + 1
movq (%r9, %r11, 8), r10 # r10 is &argv[argc + 1], i.e. environment
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment