11

For the same app, I have:

  • an APK from an app store,
  • what is claimed to be the source code for the same version. With a pretty usual Gradle build script and structure.

I want to check whether the APK was really built from that source code or not.
How to check that?

Notes:

  • The APK is not obfuscated.
  • I have no reason to trust anyone's signature. I only trust the source code.
  • I already built the app for myself, but now I want to know whether the APK was OK or not.
  • Preferably with Linux command-line tools, but any tool is OK.
10
  • 2
    I've not tried that, but you should be able to use Apktool for this purpose: Reverse-engineer both .apk files, then run a diff against the resulting directories. Only difference then should be the signature (which cannot match for obvious reasons). Thinking about it: simply unzipping the .apk files and doing a binary diff should do the same. Both would of course require having used the same library versions etc. when compiling in the first place :)
    – Izzy
    Commented Aug 22, 2016 at 9:38
  • @Izzy: "same library versions": API version is written in the manifest and libraries version in the Gradle script, so that part should be OK, I guess. A list of files/folders that can be ignored would make that a great answer (bonus for the actual command lines). Commented Aug 22, 2016 at 9:42
  • 1
    I could do that if I were on my computer at home, which I am not currently. But for that to be a "honorable answer", I would need to try it out myself first :) In case I forget (and nobody else did it before me), feel free to send me another ping (e.g. in chat) in about 8..10h :)
    – Izzy
    Commented Aug 22, 2016 at 9:54
  • @Izzy The diff method seems neat... but what if the guys of the app store obfuscated the APK while compiling it?
    – Grimoire
    Commented Aug 22, 2016 at 16:32
  • IMHO that's where Apktool comes into play. Have you checked the link? Also take a look at LibRadar which uses this. AFAIR it helps in de-obfuscating (something must, or LibRadar would have a hard job detecting those libraries).
    – Izzy
    Commented Aug 22, 2016 at 16:36

2 Answers 2

2

You can only do this with reproducible builds:

"A build is reproducible if given the same source code, build environment and build instructions, any party can recreate bit-by-bit identical copies of all specified artifacts."

So the app developer or the app store needs to be on board in order for it to work.
Otherwise your only option is to build it yourself.

One example of a developer who currently does this is Open Whisper Systems: https://github.com/WhisperSystems/Signal-Android/wiki/Reproducible-Builds

4
  • Very interesting! So, are you sure comparison can not be done without without the developer being on board? Unfortunately (but understandably) most open source apps do not use Docker or similar for builds, they are just built on whatever system the maintainer happens to run. Commented Aug 15, 2017 at 3:46
  • Doesn't have to be the developer, just as long as whoever builds the app from source makes it possible to recreate their build environment exactly. Dependencies can be a massive pain when setting up these types of builds.
    – andDevW
    Commented Aug 15, 2017 at 5:18
  • "recreate their build environment exactly": Is it possible to guess? For instance, if for some reason building on Mac or Linux produces a different APK, can I guess whether the app store's APK has been built on Mac or Linux? Commented Aug 15, 2017 at 5:56
  • It's not possible to guess and have results that are meaningful. Eventually this will get easier to implement and you'll see more and more open source projects doing it.
    – andDevW
    Commented Aug 15, 2017 at 6:24
1

One great thing about java and APKs is you can completely decompile the APK to java source code.

However, the resulting source code isn't guaranteed to be identical.

One good way to try and match up the resulting source code with a known revision is to check what modifications were made directly before and after the known commit in the repository, and see if those modifications are also present in the decompiled source.

To decompile, use dex2jar and JD-Gui.

edit I just noticed you wanted linux tools. My only experience is with windows, but I'm sure similar tools exist for linux.

4
  • If I understand correctly, your method is to check what the latest change in the source code's repository was, then decompile the APK, and check manually whether the latest change is also found in the decompiled code too, right? Interesting approach, but that will not tell me whether a call-home or embedded ad has been added to the APK version, right? Commented Sep 5, 2016 at 4:00
  • 1
    This is an approach I have used in the office to try and match up an unknown APK to a source revision, which has been good enough if you know you can trust the developers. But as you say, it is probably still possible for an untrustworthy party to sneak something in. I am hoping someone will provide a more definitive answer, would be useful for me too.
    – Mark Ch
    Commented Sep 5, 2016 at 4:46
  • How about compiling the source into the APK yourself, then decompiling it back into source code and comparing that to the decompiled source from Play Store APK? Have anyone tried this? Commented Feb 25, 2019 at 23:20
  • 1
    @SergiyBelozorov sorry I can't answer this, I don't really work with android any more, but it sounds like a very good idea.
    – Mark Ch
    Commented Feb 26, 2019 at 15:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .