Hello I'm playing with my native android library, everything was going smoothly till now. I have problem with opcodes, i don't know how to tell radare2 to write str opcode with specifc registry, and point it to stack pointer and local variable.

Details below:

Lib loaded via :

r2 -Aw lib/arm64-v8a/libnative-lib.so

Before changes

|           ; var int local_ch @ sp+0xc
|           ; var int local_10h @ sp+0x10
|           ; var int local_18h @ sp+0x18
|           0x0000946c      e00f00f9       str x0, [sp + local_18h]
|           0x00009470      e10b00f9       str x1, [sp + local_10h]

Applying changes

[0x00009470]> wa str x1,sp+local_10h
Written 4 byte(s) (str x1,sp+local_10h) = wx e10300f9

Unwanted output

[0x00009470]> pd 1
|           0x00009470      e10300f9       str x1, [sp]

Output that i want but don't know how to get it (note the "+ local_10h" label)

  [0x00009470]> pd 1
  |           0x00009470     e10b00f9       str x1, [sp + local_10h]
  • 2
    Did you try to use "wx e10b00f9"? Also, seems like your "before changes" snippet already contains what you are trying to write
    – Megabeets
    Jun 14, 2018 at 14:57
  • Yeah "before changes" contains the output that i want because it is original state, i'm asking this question because i have changed it and now i'm unable to restore it. The command that you have provided works, but exactly as i wanted. However it pointed me in the right direction. I can write it by "wa str x1,sp,0x10".
    – TheKalin
    Jun 14, 2018 at 15:10
  • 1
    @Megabeets. Thanks for help! BTW. I was hoping that "wa str x1,sp,local_10h " will results in the same output as wa str x1,sp,0x10 (local_10h is a label for 0x10) but it doesn't work this way.
    – TheKalin
    Jun 14, 2018 at 15:14
  • Sure! You are welcome :)
    – Megabeets
    Jun 14, 2018 at 15:53

1 Answer 1


So to make an order from the comments - you can do it by using two approaches.

  1. Use the original opcodes and write them using wx which stands for "write hex":

    wx e10b00f9
  2. If you still want to use wa you can do this like this:

    wa str x1,sp,0x10

In general, handling function's local variables can be done using the afv command and subcommands. Execute afv? to see its subcommands:

[0x00000000]> afv?
|Usage: afv[rbs]
| afvr[?]                     manipulate register based arguments
| afvb[?]                     manipulate bp based arguments/locals
| afvs[?]                     manipulate sp based arguments/locals
| afv*                        output r2 command to add args/locals to flagspace
| afvR [varname]              list addresses where vars are accessed (READ)
| afvW [varname]              list addresses where vars are accessed (WRITE)
| afva                        analyze function arguments/locals
| afvd name                   output r2 command for displaying the value of args/locals in the debugger
| afvn [old_name] [new_name]  rename argument/local
| afvt [name] [new_type]      change type for given argument/local
| afv-([name])                remove all or given var

By executing afv you'll see a list of all arguments, and both bp and sp based local variables. For example, by executing afvs you'll see a list of all stack-pointer based variables. Use afvb to see variables that are base-pointer based.

After executing these commands, you'll see how these variable names were defined:

var int local_8h @ rsp+0x8
var int local_10h @ rsp+0x10

For example, you can see that local_8h is defined for rsp+0x8, and local_10h for rsp+0x10.
While debugging, you can use afvd [var_name] to shed more light on the variable.

  • I would add a small note about variable address, you can get it by typing: afvd local_10h and it will result in the output like this "pxr $w @sp+0x10". "
    – TheKalin
    Jun 15, 2018 at 6:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.