Arm does not have a wide array of x86 materials, but it cannot be used at the underlying Android layer. As a beginner, I have taken a lot of detours. Now I use a practical example to analyze the simplest arm function call process, hoping to help you, if your understanding is incorrect, point it out. Note: The command here is actually thumb (thumb2 ?), 2 bytes of C source code for each command :------------------------------------------------------------------
# Include <stdio. h> # include <dlfcn. h> void (* func) (); void sub () {void * p = dlopen ("libxxx. so ", RTLD_NOW); if (! P) {return;} else {// myfn is a function of libxxx. so to print "call myfn ...! "Func = (void (*) () dlsym (p," myfn "); func () ;}} int main () {printf ("RTLD_NOW = % d \ n", RTLD_NOW); sub (); return 0 ;}
Running result --------------------------------------------------------------- disassembly analysis -------------------------------------------------------------
sub:1. 84a0: 4808 ldr r0, [pc, #32] ; (84c4 <printf@plt+0x6c>)2. 84a2: 2100 movs r1, #03. 84a4: b510 push {r4, lr}4. 84a6: 4c08 ldr r4, [pc, #32] ; (84c8 <printf@plt+0x70>)5. 84a8: 4478 add r0, pc6. 84aa: 447c add r4, pc7. 84ac: f7ff efc8 blx 8440 <dlopen@plt>8. 84b0: b138 cbz r0, 84c2 <printf@plt+0x6a>9. 84b2: 4906 ldr r1, [pc, #24] ; (84cc <printf@plt+0x74>)10. 84b4: 4479 add r1, pc11. 84b6: f7ff efca blx 844c <dlsym@plt>12. 84ba: 4905 ldr r1, [pc, #20] ; (84d0 <printf@plt+0x78>)13. 84bc: 5863 ldr r3, [r4, r1]14. 84be: 6018 str r0, [r3, #0]15. 84c0: 4780 blx r016. 84c2: bd10 pop {r4, pc}
// 5. preparation 1. r0 = [0x84a0 + 4 + 32] = [0x84c4] = 0x48 // dlopen parameter 22. r1 = 0 // lr is the return address of sub 3. r4, lr into the stack // 6. prepare // It must be aligned to (0, 4, 8, c), So 0x84ca is changed to 0x84c84. r4 = [0x84a6 + 4 + 32] = [0x84ca] = [0x84c8] = 0xc26 // The parameter 1 of dlopen> 0x84f4 stores the string libxxx. so5. r0 = 0x48 + 0x84a8 + 4 = 0x84f4 // 13. prepare 6. r4 = 0xc26 + 0x84aa + 4 = 0x90D4 // return value r07. call dlopen for r0 & r1 // If r0 is 0, jump to 0x84c28. conditional jump // 10. prepare // ce aligned to cc9. r1 = [0x84b2 + 4 + 24] = [0x84CE] = [0x84cc] = 0x46 // the string is stored in the parameter 2-> 0x84FE of dlsym myfn10. r1 = 0x46 + 0x84b4 + 4 = 0x84FE // parameter r0 & r1, return Value r0. the return value is myfn address 11. call dlsym // 13. prepare // d2 align to d012. r1 = [0x84ba + 4 + 20] = [0x84D2] = [0x84d0] = 0 xfffffffc // What is r3 used for? See Figure 14.13. r3 = [0x90D4 + 0 xfffffffc] = [0x90d0] = 0x90f0 // Save the myfn address 14. [0x90f0] = r0 15. call myfn 16. output the stack and put lr in the pc. The sub returns the modification ------------------------------------------------------------------ according to the above analysis, row 12-14 caches the myfn address to accelerate future repeated calls (this program only calls once). If this analysis is correct, so removing 12-14 lines should not affect the normal execution of the program. The following is the test (replacing 12-14 lines with nop, machine code 0xc046): the modified running result:
The program runs normally.