memory - MIPS program to replicate itself? -
how can create mips program such in main function prints out version1 , copies entire code memory , finaly executes copied version. copied version of code must print version2. cannot add in data section other version1 , version2.
how copy entire code memory , execute it? i've never done before don't know start.
.data version1: .asciiz "this version1" version2: .asciiz "this version2" main: li $v0, 4 la $a0, version1 syscall #(how copy code , execute it?????)
the ability self modify code dependent on environment of execution.
mars option can enabled. code assume little endianness data memory (no assumption code memory).
what professor want this:
- that recognize
la
pseudo instruction made ofori
,lui
correctly count instruction copied four. - that reserve space in program flow 4 instructions using
nop
. - that recognize instruction format edit operands.
the copy process simple. can aided assembler cleaver use of labels: put label right after code copy (and right before if there none) , copy data between these two.
since know length of code copy , small, can copy hand.
in order modify copied code need see how likes machine code
addiu $v0, 0, 4 #24020004 lui $at, hhhh #3c01hhhh ori $a0, $at, llll #3424llll syscall #0000000c
as can see have replace lower hw of 2nd , 3rd instruction.
value use address of version2.
upper , lower hw of address can obtained basic bits manipulations.
you have add code terminate program nicely.
here intentional simplified working example made mars (activate self modify code in settings).
.data version1: .asciiz "this version1" version2: .asciiz "this version2" .text main: li $v0, 4 #1 instruction addiu $v0, $0, 4 la $a0, version1 #2 instructions lui $a0, h ori $a0, l syscall #1 instruction #load src , dest address la $t0, main la $t1, new_code #copy 4 words of code lw $t2, ($t0) sw $t2, ($t1) lw $t2, 4($t0) sw $t2, 4($t1) lw $t2, 8($t0) sw $t2, 8($t1) lw $t2, 0xc($t0) sw $t2, 0xc($t1) #load address of version2 la $t0, version2 add $t2, $0, $0 lui $t2, 0xffff #t2 = 0ffff0000h andi $t3, $t0, 0xffff #t3 = lower hw of address srl $t0, $t0, 0x10 #t0 = upper hw of address #edit ori $a0, l lw $t4, 8($t1) #load instruction in register , $t4, $t4, $t2 #clear lower hw or $t4, $t4, $t3 #set lower hw sw $t4, 8($t1) #save instruction #edit lui $a0, h lw $t4, 4($t1) #load instruction in register , $t4, $t4, $t2 #clear lower hw or $t4, $t4, $t0 #set lower hw sw $t4, 4($t1) #save instruction new_code: nop nop nop nop li $v0, 10 syscall
if interested in more generic version dynamically allocate memory (with syscall 9), align returned pointer, copy code, modify , add call syscall 10, here is
.data version1: .asciiz "this version1" version2: .asciiz "this version2" .text main: __copy_start__: #sign start of code copy li $v0, 4 #1 instruction addiu $v0, $0, 4 la $a0, version1 #2 instruction2 lui $a0, h ori $a0, l syscall #1 instruction __copy_end__: li $v0, 9 #allocate buffer li $a0, 27 #16 bytes (4 instructions) + 8 bytes (2 instructions) + 3 byte aligning syscall #align pointer consuming first bytes (this not needed, completeness) addi $v0, $v0, 3 andi $v0, $v0, 0xfffffffc #prepare copy la $t0, __copy_start__ #t0 = source start la $t1, __copy_end__ #t1 = source end (exclusive) add $t2, $0, $v0 #t2 = destination start ori $t4, $0, 1 #t4 = 1: code copied 0: code copied do_copy: #move source dest lw $t3, ($t0) sw $t3, ($t2) #increment pointers addi $t0, $t0, 4 addi $t2, $t2, 4 #if not reached source end, copy again bne $t0, $t1, do_copy #copy done #if code has been copied, jump new code beqz $t4, do_jump #extra code need copied la $t0, __copy_extra__ #new source start la $t1, __copy_extra_end__ #new source end add $t4, $0, $0 #signal code being copied #copy again b do_copy do_jump: #get address of version2 la $t0, version2 #save low half word low halfword of 3rd instruction (ori $a0, l) sh $t0, 8($v0) #get upper hw in lower hw of $t0 srl $t0, $t0, 16 #save high half word low hw of 2nd instruction (lui $a0, h) sh $t0, 4($v0) #jump indirect jr $v0 #extra code append end of new code __copy_extra__: li $v0, 10 syscall __copy_extra_end__:
Comments
Post a Comment