Home > Mobile >  Inline assembly with branch
Inline assembly with branch

Time:01-13

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

  • Related