I want to reverse engineer an android game, found a method

public static byte[] MNNOPKMJMFP(byte[] AFFEPNLBIIC, byte[] OENOGNMAMPO, byte[] GLLEHJKGIBK) { }

Names are obfuscated, i know that this is a cryptographic function that takes three arguments - an array of bytes, key and initialization vector, i want to get their specific values, for example, an 256 bit AES key, these are dynamic objects so they have a pointer and they are in heap, this is the code from radare2 disassembler

fcn.00c63d2c ();
│           ; var int32_t var_24h @ fp-0x24
│           0x00c63d2c      f04f2de9       push {r4, r5, r6, r7, r8, sb, sl, fp, lr}
│           0x00c63d30      1cb08de2       add fp, sp, 0x1c
│           0x00c63d34      0cd04de2       sub sp, sp, 0xc
│           0x00c63d38      0080a0e1       mov r8, r0
│           0x00c63d3c      d0029fe5       ldr r0, [0x00c64014]        ; [0xc64014:4]=0x18f53fc
│           0x00c63d40      0260a0e1       mov r6, r2
│           0x00c63d44      0170a0e1       mov r7, r1
│           0x00c63d48      00008fe0       add r0, pc, r0
│           0x00c63d4c      0000d0e5       ldrb r0, [r0]
│           0x00c63d50      000050e3       cmp r0, 0
│       ┌─< 0x00c63d54      0600001a       bne 0xc63d74
│       │   0x00c63d58      b8029fe5       ldr r0, [0x00c64018]        ; [0xc64018:4]=0x1884b04
│       │   0x00c63d5c      00009fe7       ldr r0, [0x00c63d64]        ; [0xc63d64:4]=0xebdc4331
│       │   0x00c63d60      000090e5       ldr r0, [r0]
│       │   ; DATA XREF from fcn.00c63d2c @ 0xc63d5c(r)
│       │   0x00c63d64      3143dceb       bl 0x374a30
│       │   0x00c63d68      ac029fe5       ldr r0, [0x00c6401c]        ; [0xc6401c:4]=0x18f53d4
│       │   0x00c63d6c      0110a0e3       mov r1, 1
│       │   0x00c63d70      0010cfe7       strb r1, [0x00c63d78]
│       └─> 0x00c63d74      a4029fe5       ldr r0, [0x00c64020]        ; [0xc64020:4]=0x186d7dc
│           0x00c63d78      08504de2       sub r5, sp, 8
│           0x00c63d7c      00009fe7       ldr r0, [0x00c63d84]        ; [0xc63d84:4]=0xe5900000
│           0x00c63d80      05d0a0e1       mov sp, r5
│           ; DATA XREF from fcn.00c63d2c @ 0xc63d7c(r)
│           0x00c63d84      000090e5       ldr r0, [r0]
│           0x00c63d88      bf10d0e5       ldrb r1, [r0, 0xbf]
│           0x00c63d8c      020011e3       tst r1, 2
│       ┌─< 0x00c63d90      0300000a       beq 0xc63da4
│       │   0x00c63d94      701090e5       ldr r1, [r0, 0x70]
│       │   0x00c63d98      000051e3       cmp r1, 0
│      ┌──< 0x00c63d9c      0000001a       bne 0xc63da4
│      ││   0x00c63da0      197fdceb       bl 0x383a0c
│      └└─> 0x00c63da4      0000a0e3       mov r0, 0
│           0x00c63da8      baa1eceb       bl 0x78c498
│           0x00c63dac      0040a0e1       mov r4, r0
│           0x00c63db0      000054e3       cmp r4, 0
│           0x00c63db4      24500be5       str r5, [var_24h]           ; 0x24
│       ┌─< 0x00c63db8      0100001a       bne 0xc63dc4
│       │   0x00c63dbc      0000a0e3       mov r0, 0
│       │   0x00c63dc0      7cfddceb       bl 0x3a33b8
│       └─> 0x00c63dc4      000094e5       ldr r0, [r4]
│           0x00c63dc8      283190e5       ldr r3, [r0, 0x128]
│           0x00c63dcc      2c2190e5       ldr r2, [r0, 0x12c]
│           0x00c63dd0      0400a0e1       mov r0, r4
│           0x00c63dd4      0710a0e1       mov r1, r7
│           0x00c63dd8      33ff2fe1       blx r3
│           0x00c63ddc      000094e5       ldr r0, [r4]
│           0x00c63de0      183190e5       ldr r3, [r0, 0x118]
│           0x00c63de4      1c2190e5       ldr r2, [r0, 0x11c]
│           0x00c63de8      0400a0e1       mov r0, r4
│           0x00c63dec      0610a0e1       mov r1, r6
│           0x00c63df0      33ff2fe1       blx r3
│           0x00c63df4      000094e5       ldr r0, [r4]
│           0x00c63df8      241190e5       ldr r1, [r0, 0x124]
│           0x00c63dfc      202190e5       ldr r2, [r0, 0x120]
│           0x00c63e00      0400a0e1       mov r0, r4
│           0x00c63e04      32ff2fe1       blx r2
│           0x00c63e08      0060a0e1       mov r6, r0
│           0x00c63e0c      000094e5       ldr r0, [r4]
│           0x00c63e10      102190e5       ldr r2, [r0, 0x110]
│           0x00c63e14      141190e5       ldr r1, [r0, 0x114]
│           0x00c63e18      0400a0e1       mov r0, r4
│           0x00c63e1c      32ff2fe1       blx r2
│           0x00c63e20      0020a0e1       mov r2, r0
│           0x00c63e24      000094e5       ldr r0, [r4]
│           0x00c63e28      887190e5       ldr r7, [r0, 0x188]
  • what did i understand from this?
  • r0: used to work with pointers,
  • r1, r2, r3 - used to pass arguments and temporary values,
  • r4-r8 - used as temporary registers and, possibly, for storing pointers,
  • sb, sl, fp - used to save stack frame's state and set it, Addresses used as pointers [0x00c64014], [0x00c64018], [0x00c6401c], [0x00c64020] are loaded into register r0 and used to access data in memory [r0] is a pointer that the function operates in several places, Also, will i be able to find the answer to my question in addresses offset from [r0] or not? for example [r0, 0xbf], [r0, 0x70], [r0, 0x128], [r0, 0x12c], [r0, 0x118], [r0, 0x11c], [r0, 0x124], [r0, 0x120], [r0, 0x110], [r0, 0x114], [r0, 0x188], Also this is the method (pattern for building other functions), will xrefs analysis help? Will be thankful for any tip!

1 Answer 1


I am strongly recommend to you use Ghidra. It can provide much more clear 'C-like' output. For example, for your function, it gives

void FUN_00000000(undefined4 param_1,undefined4 param_2,undefined4 param_3)
  int *piVar1;
  undefined auStack_38 [12];
  undefined *local_2c;
  if (PTR_000002e8[0x24] == '\0') {
    func_0xff710d04(**(undefined4 **)(PTR_000002ec + 0x38));
    PTR_000002f0[0x4c] = 1;
  if (((*(byte *)(**(int **)(PTR_000002f4 + 0x58) + 0xbf) & 2) != 0) &&
     (*(int *)(**(int **)(PTR_000002f4 + 0x58) + 0x70) == 0)) {
  piVar1 = (int *)func_0xffb2876c(0);
  local_2c = auStack_38;
  if (piVar1 == NULL) {
  (**(code **)(*piVar1 + 0x128))(piVar1,param_2,*(undefined4 *)(*piVar1 + 300));
  (**(code **)(*piVar1 + 0x118))(piVar1,param_3,*(undefined4 *)(*piVar1 + 0x11c));
  (**(code **)(*piVar1 + 0x120))(piVar1,*(undefined4 *)(*piVar1 + 0x124));
  (**(code **)(*piVar1 + 0x110))(piVar1,*(undefined4 *)(*piVar1 + 0x114));
                    // WARNING: Bad instruction - Truncating control flow here

Looks like func_0xffb2876c() something like GetSingletonInstance() and subsequent 4 calls is a virtual methods.

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.