~poptart/riscv-business

bbaa742dde977e88f37de2a9abc095edb14670fa — terrorbyte 2 years ago 7f44a60
Continue writing the documentation portions
4 files changed, 60 insertions(+), 26 deletions(-)

M README.md
M src/asm2.s
M src/asm3.s
M src/asm4.s
M README.md => README.md +1 -1
@@ 21,7 21,7 @@ read in the following manner or as described in the coming blogpost:
| files | lesson |
| :----- | :------ |
|`asm1.s`, `asm2.s` | Learn about the basic calling conventions, linux specifics for system calls, data access |
| `asm3.s` | Port a program to not use the rodata section and learn about ebreak, debugging, and endianness |
| `asm3.s` | Port a program to not use the rodata section and learn about PIC |
| `asm4.s` | Graceful shell spawning in assembly |
| `sc1.h`, `asm5.s` | Learn about the pitfalls of shellcode and use a simple shellcode tester to check for null chars |
| `sc2.h`, `asm6.s` | Discover more pitfalls, solutions, and port the more advanced shell exec shellcode |

M src/asm2.s => src/asm2.s +3 -0
@@ 27,6 27,9 @@
# > lui a1,0xa4 # 0x000a4 - Upper 20 bits
# > addiw a1,a1,321 # 0x141 - lower 12 bits
# 
# This can cause issues and make things a bit hard to predict the output
# of the assembler, so be aware when writing the assembly.
# 
# The second part of achieves the same thing as the first but uses the
# assembler macro (TODO right verbiage?) for loading the upper portion
# of the text and then the lower. This is very useful when hand writing

M src/asm3.s => src/asm3.s +28 -11
@@ 1,17 1,34 @@
# This example is pretty much the same as the last, but provides the
# oppurtunity to discuss why we should structure assembly for shellcode
# in a certain manner. One of the first concepts that we are going to
# need is Position Independent Code (PIC). In our last example our long
# string that we printed was read from the .rodata section of the ELF,
# which means that the data is written to the corresponding binary
# itself and either statically referenced or at run time a virtual
# address is generated.
#
# It may not be immediately obvious, but the behavior of having strings
# hardcoded in object sections means that we are not able to reliably
# reuse them in a generic manner when injecting the shellcode into a
# vulnerable target. We now have the restriction of making all the
# shellcode not reference static locations, we can't use labels, can
# only use relative jumps, and are restricted from using library
# functions. Up until this point we were functionally doing that anyway
# based on the simple nature of our programs, but a real assembly
# programmer would most likely be taking more advantage of this.
#
.section .text
.globl _start
_start:
	li 	a0,0x0 #first argument: 
	li 	a2,8
	li	a1,0
	li 	t0,0x0a414141
	li 	a0,0x0	#first argument: fd 0 = STDOUT 
	li 	a2,8	#third argument: sizeof(a1)
	li 	t0,0x0a414141	#example of using temporary registers
	li	t1,0x42424242
	addi	sp,sp,-8
	sd	t1,0(sp)
	sd	t0,4(sp)
	addi	a1,sp,0
	li 	a7, 64              # 64 is the __NR_write syscall 
	addi	sp,sp,-8	#move the stack down sizeof(t0+t1)
	sd	t1,0(sp)	#store 'BBBB'
	sd	t0,4(sp)	#store 'AAA\n'
	addi	a1,sp,0		#point a1 to the top of the stack
	li 	a7, 64		#64 is the __NR_write syscall 
	ecall
	li 	a0, 0x0
	li 	a7, 93
	li 	a7, 93		#exit with retval of previous syscall
	ecall

M src/asm4.s => src/asm4.s +28 -14
@@ 1,18 1,32 @@
# This is the last example of simple assembly that we will write, it is
# a simple call to execve(2) to call /bin/sh. At this point we are still
# no writing any shellcode, but still familiarizing ourselves with using
# position independent code and some of the assembly pain points.
#
# We will simply uses the same techniques as before to make a call to
# execve in order to execute a shell. This combines all that we have
# learned so far and requires the following signature be matched from
# the execve documentation:
#
# execve(const char *filename, char *const argv[],char *const envp[]);
#
# While at first this might be intimidating, but just like with the
# write example all we need to do is set up the stack to contain the
# /bin/sh filename and use the trick of setting the other arguments to 0
# making them NULL values.
.section .text
.globl _start
_start:
	    #execve
	    li a0,0x6e69622f #nib/
	    addi sp,sp,-8
	    sd a0,0(sp)
	    li a0,0x0068732f # \0hs/ 
	    sd a0,4(sp)
	    li a0,0
	    addi a0,sp,0
	    li a2,0x0
	    li a1,0x0
	    li a7, 221 #221 is the __NR_execve 
	    ecall
	    li a0, 0x0
	    li a7, 93
	    #execve(*filename, *argv[], *envp[])
	    li a0,0x6e69622f	#nib/
	    addi sp,sp,-8	#set up the stack
	    sd a0,0(sp)		#store '/bin'
	    li a0,0x0068732f 	#\0hs/ 
	    sd a0,4(sp)		#store '/sh\0'
	    addi a0,sp,0	#set a0 to the top of the stack
	    li a2,0x0		#set argv[] to NULL
	    li a1,0x0		#set envp[] to NULL
	    li a7, 221 		#221 is the __NR_execve 
	    ecall
	    li a7, 93		#exit value of execve is in a0
	    ecall		#exit the program with the retval of execve