Skip to content

Instantly share code, notes, and snippets.

@Zheaoli
Last active August 30, 2023 11:19
Show Gist options
  • Save Zheaoli/f37bc1fb04917fdfac36d644ee69f7e9 to your computer and use it in GitHub Desktop.
Save Zheaoli/f37bc1fb04917fdfac36d644ee69f7e9 to your computer and use it in GitHub Desktop.
.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
@eiffel-fl
Copy link

eiffel-fl commented Aug 30, 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