Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Reverse-Engineering apps on the device - how f...

jebstuart
August 26, 2019

Reverse-Engineering apps on the device - how far can we go?

As Android developers, we know that our app is insulated from other apps in the device by the Android Application Sandboxing model. But the reality is that this sandbox only protects your data. Your APK is completely exposed to other apps, including resources, assets, and code. I wanted to know how much reverse-engineering I could do from within an app, so I built an app that can run on your phone and inspect any other app’s resources, looking at image assets and reading string values. It can even load another app’s code, and execute it. All this happens without leaving the device, without classic reverse-engineering tools on a developer machine.

I’ll walk through the APIs that expose your resources, and show how to put them into action. I will demonstrate how we can inspect, and even execute, another app's code. You will come away with a better understanding of what is and is not protected by the Android Application Sandbox, and which parts of your app are freely available for reverse-engineering.

jebstuart

August 26, 2019
Tweet

More Decks by jebstuart

Other Decks in Programming

Transcript

  1. Views expressed here are my own 
 and do not

    necessarily reflect 
 the views of my employer.
  2. App Sandboxing APK Sandbox res dex so asset files db

    shared pref keys APK Sandbox res dex so asset files db shared pref keys APK Sandbox res dex so asset files db shared pref keys
  3. APK • AndroidManifest.xml • assets/ • … • classes.dex •

    classes2.dex • res/ • anim/ • color/ • drawable/ • layout/ • raw/ • …
  4. Enumerating Resources val res: Resources = packageManager.getResourcesForApplication(appId) val name =

    res.getResourceName(0x7f0e0003) val type = res.getResourceTypeName(0x7f0e0003) val entry = res.getResourceEntryName(0x7f0e0003)
  5. Enumerating Resources val res: Resources = packageManager.getResourcesForApplication(appId) val name =

    res.getResourceName(0x7f0e0003) val type = res.getResourceTypeName(0x7f0e0003) val entry = res.getResourceEntryName(0x7f0e0003) “anim” “abc_slide_out_top” “com.example:anim/abc_slide_out_top”
  6. Loading Resource Values val res: Resources = packageManager.getResourcesForApplication(appId) res.getBoolean(0x7f0e0123) res.getColor(0x7f0e0123,

    null) res.getDimension(0x7f0e0123) res.getDrawable(0x7f0e0123, null) res.getInteger(0x7f0e0123) res.getString(0x7f0e0123)
  7. Enumerating Assets val res: Resources = packageManager.getResourcesForApplication(appId) val fileNames =

    res.assets.list("") AMobileConfig.json bar.properties fonts html settings.json
  8. Enumerating Assets val inputStream = res.assets.open(path) // for image val

    bitmap = BitmapFactory.decodeStream(inputStream) // for text file val text = inputStream.reader().readLines()
  9. DEX files val apk = ZipFile(appInfo.publicSourceDir) val dexEntries = apk.entries().toList()

    .filter { it.name.startsWith("classes") && it.name.endsWith(".dex") }
  10. val clazz = targetClassLoader.loadClass(declaringType) val instance = clazz.newInstance() val method

    = clazz.getDeclaredMethod(methodName, String::class.java, Boolean::class.java) val result = method.invoke(instance, "arg1", true)
  11. java.lang.ClassNotFoundException: Didn't find class "android.support.v7.widget.ActivityChooserView$InnerLayout" on path: DexPathList[ [zip file

    “/data/app/com.jebware.appspy-A_W1…2Q==/base.apk”], nativeLibraryDirectories=[ /data/app/com.jebware.appspy-A_W1…2Q==/lib/arm64, /system/lib64
 ] ]