9

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.
  • 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 Aug 22 '16 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). – Nicolas Raoul Aug 22 '16 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 Aug 22 '16 at 9:54
  • @Izzy The diff method seems neat... but what if the guys of the app store obfuscated the APK while compiling it? – Death Mask Salesman Aug 22 '16 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 Aug 22 '16 at 16:36
1

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

  • 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. – Nicolas Raoul Aug 15 '17 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 Aug 15 '17 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? – Nicolas Raoul Aug 15 '17 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 Aug 15 '17 at 6:24
0

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

However, the resulting source coed 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.

  • 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? – Nicolas Raoul Sep 5 '16 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 Sep 5 '16 at 4:46
0

You can make a md5sum or SHA128/SHA512 of your version build by the source and the other and then if those numbers are both the same.

  • Are you absolutely certain that if the source is the same, then the APK will be exactly the same bit-by-bit? That means the APK contains no build timestamp nor any information about the build OS, for instance. – Nicolas Raoul Sep 10 '17 at 8:01

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.