Technical Analysis of the Chinese Border Police APK

If you haven’t heard, there have been rumors of a mobile application used by the Chinese border police, which is used to analyze phones owned by tourists to check for any activity they may have linking them to terrorist groups.

3 days ago, apk was shared by VICE’s technology and science section, Motherboard. Apk can be found here.

Readme contains 2 technical reports linked to the application, which i highly recommend because they are conducted by teams way above my level to begin with.

Static Analysis

Anyways, lets dive in. Lets start by checking the nested files, i’ll use ghidra to see the files in a tree format, as well as use binwalk to extract them.

Here is the binwalk results:

But i find it easier to check the files in a tree structure.

Checking around, there are some filenames that look suspicious to begin with, like record_microphone.xml.

Other than that, everything important seems to be located in /assets/xbin/*. Seems like all the executables have 2 versions packed, one for pie and one without (except bk_samples.bin and getVirAccount). Lets start with inspecting the non-binary files. I suspect terrorism_apps.csv might be the list of 73.000 files mentioned in the reports, which you are not allowed to have on your phone.

Interesting, csv file seems to be empty.

Lets check out the id.conf file.

com.tencent.mobileqq	tencent/MobileQQ/	DIR	(^[1-9][0-9]+)
com.tencent.mobileqq	Tencent/MobileQQ/	DIR	(^[1-9][0-9]+)
com.tencent.mobileqq	tencent/QWallet/	DIR	(^[1-9][0-9]+)
com.tencent.mobileqq	Tencent/QWallet/	DIR	(^[1-9][0-9]+)
com.renren.mobile.android	Android/data/com.renren.mobile.android/cache/talk_log/	FILE	talk_log_([0-9]+)_.*
com.duowan.mobile	yymobile/logs/sdklog/	FILE_CONTENT	logs-yypush_.*txt	safeParseInt ([0-9]*)
com.immomo.momo	immomo/users/	DIR	(^[1-9][0-9]+)
cn.com.fetion	Fetion/Fetion/	DIR	(^[1-9][0-9]+)
com.alibaba.android.babylon	Android/data/com.alibaba.android.babylon/cache/dataCache/	FILE	(^[1-9][0-9]+)
com.sdu.didi.psnger	Android/data/com.sdu.didi.psnger/files/omega	FILE_CONTENT	e.cache	"phone":"([0-9]*)"
com.sankuai.meituan	Android/data/com.sankuai.meituan/files/elephent/im/	DIR	(^[1-9][0-9]+)
com.sogou.map.android.maps	Android/data/com.sogou.map.android.maps/cache/	FILE_CONTENT	cache	"a":"([^"]*)"
#com.sina.weibo	loginname=red***@163.com&
com.sina.weibo	sina/weibo/weibolog/	FILE_CONTENT	sinalog.*txt	loginname=([^&]*)&

Hmmm, i don’t really know what to make of this.

Lets move on to the binaries and see if we can get anything out of them. I’ll try my luck with radareorg/cutter. I suck at static analysis of mobile binaries, so a fair warning here, i might be about to embarrass myself here.


Starting off and having absolutely no idea about what to look for, i decide to take a look on defined strings. Only unusual stuff i can see is some file directories, and some chinese strings. Google translate time!

Uuuuuuuh, i guess that is somewhat useful. Too bad there are no references to the strings address so i have no idea where its supposed to be used.

Following the xrefs to those strings, i end up on a function which i believe is the core functionality of this binary.

Block starts with a call to fopen, and left brach is just handling if file does not exist, so im ignoring that section for now.

Following that, there are some unalligned blocks, and i cant really figure out what is going on, so from pure speculation regarding what i could understand from the rest of the binary and the filename, im assuming this is getting the tencent account of the phone owner, if they have one. Take what im saying here with a grain of salt, i might be completely wrong for all i know.

Seeing i completely botched the static analysis of the getVirAccount, i move on to the wifiscan binary.


First thing to notice here is a list of file extensions, and references to bk_samples.bin which is located in the same folder.

So far, im assuming this is the piece of binary scanning the files on the phone for terror-related activities, and looking trough functions i see a subsection which calls opendir. I’ll leave the graph below, feel free to try and reverse it, but i will not.

Seeing i clearly suck at these if i dont have a decompilation result, im moving on to dynamic analysis. Lets boot up an android vm and install this piece of crap.


will do later

Dynamic Analysis

I have downloaded an android vhd from Osboxes. Lets start it up!

Uuuuuh, continue i guess?

Uuuuuuuuuuuuuuuuuuuuh, clearly wrong, lets just reboot in debug.

Sooo, exit?

Nope, that just bootlooped.

After few more attempts, running with nomodeset and exiting the debug seems to do the trick.

I dont know if this has happened because of something i did, or something osboxes did, but at least it is solved, and i finally get a home screen.

Lets just download to apk to android, and save the vm state so we can reset back to pre-install stage. After many attempts of trying to download it directly via browser (and browser crashing immediately after i press download), i give up on that idea. I think downloadProvider does not recognize ethernet as a valid connection for some reason, so it crashes. I just pass it via wget on the guest and python -m SimpleHTTPServer on the host.

I just take a snapshot here, before the install, and continue. I will also keep wireshark open on my host device, to see any network activity.

Only traffic i see during and immediately after the install is between the device and 172.217.18.*, which is android-safebrowsing.google.com

will continue later