I got the following code :
int *heap_x_test = (int*) malloc(4*sizeof(int));
heap_x_test[0] = 0x00310033 ; // add zero,sp,gp
heap_x_test[1] = 0x008110b3 ; // sll ra,sp,s0
heap_x_test[2] = 0x00c00313 ; // li t1,12
heap_x_test[3] = 0x00f00493 ; // li s1,15
printk("Target adress is 0x%x\n",heap_x_test);
printk("Code injection is 0x%x\n", heap_x_test[0]);
__asm__("beq x0, x0, %0" : "i"(heap_x_test));
I try to send code inside the heap and make it execute. I use the pmp in a riscv implementation and i want to check if i setup it right to protect the heap.
This specific line of the code doesn't seem to work :
__asm__("beq x0, x0, %0" : "i"(heap_x_test));
I tried to modify "i" with "r" and "=r" but it doesn't work either, i also tried a jr instruction with heap_x_test as label in the asm macro but it doesn't seem to work either. The compiler return :
error: output operand constraint lacks '='
37 | __asm__("beq x0, x0, %0" : "i"(heap_x_test));
Edit : When i use "=r" it compile but in the objdump of main I don't see the beq instruction :
0x80000ab0 < 0>: addi sp,sp,-16
0x80000ab4 < 4>: sw ra,12(sp)
0x80000ab8 < 8>: sw s0,8(sp)
0x80000abc < 12>: li a0,16
0x80000ac0 < 16>: jal ra,0x8000782c <malloc>
0x80000ac4 < 20>: mv s0,a0
0x80000ac8 < 24>: lui a5,0x310
0x80000acc < 28>: addi a5,a5,51 # 0x310033
0x80000ad0 < 32>: sw a5,0(a0)
0x80000ad4 < 36>: lui a5,0x811
0x80000ad8 < 40>: addi a5,a5,179 # 0x8110b3
0x80000adc < 44>: sw a5,4(a0)
0x80000ae0 < 48>: lui a5,0xc00
0x80000ae4 < 52>: addi a5,a5,787 # 0xc00313
0x80000ae8 < 56>: sw a5,8(a0)
0x80000aec < 60>: lui a5,0xf00
0x80000af0 < 64>: addi a5,a5,1171 # 0xf00493
0x80000af4 < 68>: sw a5,12(a0)
0x80000af8 < 72>: mv a1,a0
0x80000afc < 76>: lui a0,0x80008
0x80000b00 < 80>: addi a0,a0,-588 # 0x80007db4
0x80000b04 < 84>: jal ra,0x80001340 <printk>
0x80000b08 < 88>: lw a1,0(s0)
0x80000b0c < 92>: lui a0,0x80008
0x80000b10 < 96>: addi a0,a0,-564 # 0x80007dcc
0x80000b14 < 100>: jal ra,0x80001340 <printk>
0x80000b18 < 104>: lw ra,12(sp)
0x80000b1c < 108>: lw s0,8(sp)
0x80000b20 < 112>: addi sp,sp,16
0x80000b24 < 116>: ret
If i use volatile to avoid compiler optimisation it output :
undefined reference to `a5
Thanks by advance !
CodePudding user response:
The target of a beq
or other simple branch instruction needs to be a label in the code, not a value. In general, to jump to code in the heap, you're going to need an indirect branch. On riscv, the only way to do that is with a jalr
instruction. Something like:
__asm__ volatile("jr %0" :: "r"(heap_x_test));
(jr
being an alias for jalr
with a fixed x0
destination)
CodePudding user response:
With all of what you suggested i finally succeed to write my code, here's a the correction of the code which seems to work just fine :
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <zephyr/kernel.h>
#include <malloc.h>
void dummy_function(){
printk("Inside %s\n", __func__);
}
void main(void)
{
int buffer[12];
int *heap_x_test = (int*) malloc(4*sizeof(int));
heap_x_test[0] = 0x00310033 ; // add zero,sp,gp
heap_x_test[1] = 0x008110b3 ; // sll ra,sp,s0
heap_x_test[2] = 0x00c00313 ; // li t1,12
heap_x_test[3] = 0x00f00493 ; // li s1,15
printk("Target adress is 0x%x\n",heap_x_test);
printk("Code injection is 0x%x\n", heap_x_test[0]);
void (*dummy_function)()__attribute__((used)) = (void (*)())heap_x_test;
dummy_function();
}
Kind regards