There is no classdump for Android but since its an APK it is possible to view the Smali and Java code through apktool and bytecode-viewer. Using this
This can also be done by tracing the functions that are called using Frida-Trace. Where -U is the Application name and -i is grep for the functions to trace.
$ java -jar FridaAndroidTracer.jar-a,--expand-array expand array values-c,--classes<arg> classes to be hooked-j,--jars<arg> jar files to be included-o,--output<arg> output script path-p,--include-private include private methods-s,--skip<arg> methods to be skipped
// offsets to specific functions identified in disassembler
varoffset_anti_debug_x64=0x000075f0;varoffset_protect_secret64=0x0000779c;varoffset_strncmp_xor64=0x000077ec;functiondo_native_hooks_libfoo(){varp_foo=Module.findBaseAddress("libfoo.so");if(!p_foo){send("p_foo is null (libfoo.so). Returning now...");return0;}// calculate absolute address (base + offset) to each function
varp_protect_secret=p_foo.add(offset_protect_secret64);varp_strncmp_xor64=p_foo.add(offset_strncmp_xor64);send("libfoo.so @ "+p_foo.toString());send("ptr_protect_secret @ "+p_protect_secret.toString());send("ptr_strncmp_xor64 @ "+p_strncmp_xor64.toString());// attach to target functions and dump arguments
Interceptor.attach(p_protect_secret,{onEnter:function(args){send("onEnter() p_protect_secret");send("args[0]: "+args[0]);},onLeave:function(retval){send("onLeave() p_protect_secret");}});Interceptor.attach(p_strncmp_xor64,{onEnter:function(args){send("onEnter() p_strncmp_xor64");send("args[0]: "+args[0]);// hexdump is a custom function that handles raw hex values in memory (for better readability)
send(hexdump(args[0],{offset:0,length:24,header:false,ansi:true}));send("args[1]: "+args[1]);varsecret=hexdump(args[1],{offset:0,length:24,header:false,ansi:true})send(secret);},onLeave:function(retval){send("onLeave() p_strncmp_xor64");send(retval);}});}
Read and Write Floats to an address:
// Find Player::GetWalkingSpeed()
varwalkSpeed=Module.findExportByName("libGameLogic.so","_ZN6Player15GetWalkingSpeedEv");console.log("Player::GetWalkingSpeed() at address: "+walkSpeed);// Check Speed
Interceptor.attach(walkSpeed,{// Get Player * this location
onEnter:function(args){console.log("Player at address: "+args[0]);this.walkingSpeedAddr=ptr(args[0]).add(736)// Offset m_walkingSpeed
console.log("WalkingSpeed at address: "+this.walkingSpeedAddr);},// Get the return value and write the new value
onLeave:function(retval){console.log("Walking Speed: "+Memory.readFloat(this.walkingSpeedAddr));Memory.writeFloat(this.walkingSpeedAddr,9999);}});
Decompiling to smali is great because you don’t have to deal with decompiling and recompiling the application from class/java/jar files. This makes it a bit better to actually change and be able to recompile the application.
apktool d APK_FILE.apk -o outputfolder
These file can be edited and then recompiled back to the binary
This usually means that the APK is doing some weird runtime things using Java Inflection. An error will look like this.
Error: java.lang.ClassNotFoundException: Didn't find class "gi.Km" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib64, /vendor/lib64, /system/lib64, /vendor/lib64]]
There are two functions that will help you figure out what is going on. deflector() will hook the Java loader and show you what is being loaded. MainClassLoader("/data/app/<application_firectory>/base.apk") This will manually load the APK classes in to the Java Virtual Machine.