Security analysis of spy camera sold by Chinese suppliers: iMiniCam app

Lately, I bought some random, noname spy camera from usual Chinese sources. Just after unboxing, one detail seemed a bit suspicious to me: together with the camera there comes a link to Android app, that is meant to control the camera. What is worse, the link leads to some Chinese app shop, obviously with only one language available (notice the version – 1.0.33, as it is not the only one in the wild):

http://m.app.so.com/detail/index?pname=com.hbwy.fan.iminicams&id=3646142

As I’ve already seen apps that i.e. calls home, despite having no need to open a single socket and then sending data like IMEI, IMSI, MAC addresses and so on, red lamp turned on and I said to myself: stop. Let’s reverse engineer the thing first!

OSINT

Before I begun my reverse engineering, I attempted to ask uncle Google (and his friends 🙂 ) to gain some knowledge. Usual virustotal gives me this:

Results of virustotal scan of original link (click for details)

Not bad for such a simple application. Searching other shops for the same name leaded to exactly the same application (shared objects included matches), but older version (1.0.25) and in their case virustotal stopped complaining. For me there are two possible reason for that:

  1. Google Play app is not supported by vendor anymore
  2. There is special edition for Chinese, with few surprises

In favor of the second option is the fact that Java code of only the China edition is heavily bloated and usual decompilers cannot reverse the code properly, so somebody tried to make reverse engineer’s life harder. In apk downloaded from downloadapk.net and apkplz.com, everything seem to be fine.

Below are the links, I’ve used in comparison:

  1. Google Play: https://play.google.com/store/apps/details?id=com.hbwy.fan.iminicams (1.0.25)
  2. downloadapk.net: https://downloadapk.net/down_IPLiveCam.html (1.0.25)
  3. apkplz.com: https://apkplz.com/android-apps/iplivecam-apk-download (1.0.25)

Just for completeness, below is the name and webpage of suspected vendor of the stuff, I found accidentally: Albert Technology Co., Ltd. Shenzhenshihong Bo, and their webpage is here: http://www.honest-tech.com/en/

Let’s reverse then

First thing,I’ve noticed after decompilation of APK’s Java classes is:

  public static String a(String paramString)
  {
    if (paramString == null)
      return "";
    if (paramString.length() == 0)
      return "";
    paramString = new BigInteger(paramString.getBytes());
    return new BigInteger("0933910847463829232312312").xor(paramString).toString(16);
  }

  public static String b(String paramString)
  {
    if (paramString == null)
      return "";
    if (paramString.length() == 0)
      return "";
    BigInteger localBigInteger = new BigInteger("0933910847463829232312312");
    try
    {
      paramString = new String(new BigInteger(paramString, 16).xor(localBigInteger).toByteArray());
      return paramString;
    }
    catch (Exception paramString)
    {
    }
    return "";
  }

So, it’s gonna be interesting… As it turns out this one seem to be unused. But, after going a bit further and searching for all hardcoded strings I found this:

cfans/ufo/sdk/d/a.java:37:    PPPP_APIs.PPPP_Initialize("EBGDEIBIKEJOGCJNEBGBFDEOHJNDHANKGEFCBNCJAPJILDLIDEABCLOKGMLNJBKDALMNLKDOONMGAFCJJKNHJN".getBytes());

PPPP is shared object linked to the app via NDK, so I started reversing this libPPPP_API.so. Not so long time later, I was able to see decoded string by running the library and connecting gdb to it:

(gdb) p (char*)$sp+0xc
$16 = 0xbefff78c "121.40.184.33,120.25.151.105,120.25.157.75,"

I’ve check the addresses in whois database and all of them leads to Hangzhou, Zhejiang, China.

Next to decoding of these addresses, there is UDP socket opening routine and at least two ports are used: 32100 and 32108, where first one is used to connect to these services (all three of them) and port 32108 seem to be the port of camera.

What is my IP address?

So far, I identified at least one request that for sure goes to the hardcoded server, so in fact it is used to call home. This is the so called hello request. It sends nothing at all, as can be seen below:

00000000  f1 00 00 00                                       |....|
00000004

[len] [magic] [typ]

And in response it gets packet like that:

00000000  f1 01 00 10 00 02 7b 3d  xx xx xx xx 00 00 00 00  |......{=........|
00000010  00 00 00 00                                       |....|
00000014

[len] [magic] [sockaddr_in] [typ]

Content of this packet is then cast to sockaddr_in packet and experimentally, I was able to tell that it contains WAN address of requesting side (this is the censored part). I haven’t noticed the original sockaddr_in, that was used to send this hello message in memory, so chances are this is the only purpose of that server.

However, there are a lot of other datagrams crafted from same function as this one (including so called P2P requests), so I cannot guarantee I haven’t missed anything. In my opinion, further dynamic analysis is required. And I want to do one either way.

Other indicators?

Beside these suspicious addresses, I noticed some ioctl usage, but this seem to be quite legit. It just checks configuration of network interfaces (the worst that can happen out of this is sending somewhere MAC address of all interfaces available, that is both WiFi and cellular).

I focused my analysis on libPPPP_API, but beside that, there exists also UFO SDK and Adpcm codec. While Adpcm can be considered safe, as it does not import anything weird, UFO SDK is suspicious, just like PPPP API. Maybe little less, as it does not seem to obfuscate any strings. Nevertheless, it opens some sockets,probably only for RTP, but still.

Conclusion

The most important recommendation is to never trust any source of APKs beside official shops, most notably Google Play, as in it there exist some administration staff, that can react in case of obvious malware (how often and in which cases they do is another story). As can be seen in this case, either app vendor, or a shop is attaching some stuff, which is recognized as malware. In case of Google Play variant (and other Play-cloning shops), things are much better and no alert is raised by VirusTotal.

Second point is how to treat the fact of calling home, especially in situation where app vendor tries to hide the fact by obfuscating the string that contains the addresses. In my opinion, it is enough to not let that app do anything outside some closed network (with no means of sending packet to the internet), at least to be able to check the behavior in practice. And this is probably what I am going to try next. However, I can imagine that I will be using the app, despite that, but after banning these three servers. I can also understand that most people will ignore that fact (or even more – will be unaware of that), as in today’s world there is such a huge amount of services that are gathering our data, that it is impossible to block them all.

To sum up, if you want to use it, download from Google Play and keep in mind, some data might leak somewhere on he Chinese coast.

PS: I am not planning to publish complete API, which I am in theory able to reverse engineer. However, expect some quick summary of what I already know about the protocl 🙂

How to convert Android resource ID back into its name

Few weeks ago I made an attempt to reverse engineer some obscure Android APK. It was available only through some Chinese shop, obviously described in only one language there. Unfortunately, it turned out that every tool designed for reverse engineering APK files outputted source with mysterious resource IDs, as plain integers, which is not the most convenient way to read them. Therefore I started looking for any way to find some meaningful name from these ids. At the end of my development effort I found out, there is one file that usually might be used for that purpose – res/values/public.xml, as produced by apktool (if I remember correctly). However, according to its name it contains only public resources, so some of them are missing there (in my case at least some drawable type resources were missing). Therefore, I am publishing my program to do things even more reliably.

arscutils

This program requires my library created together, but which is separate project – libarsc. It is available, as usually through Github and also as a package to be downloaded from PyPI. Just type:

pip install libarsc

with proper privileges.

This is meant to be utility package, but for now it contains only one such tool: rid2name. Its purpose is to convert resource ID into name in format matching the one, programmers use in their Android apps. Therefore with its help it should be possible to make reversed program looks more similar to compiler input on the developer side. To use it, just feed it with resources.arsc file as first parameter, resource id as second one and optionally one of: fqdn, xmlid or json as third one. As a result you should get resource name as used in Java source, XML files or JSON meant for further processing. Example runs are:

$ python3 rid2name.py ../com.g_zhang.iMiniCam_39/original/resources.arsc 0x7f070000 xmlid
@com.g_zhang.iMiniCam:string/app_name
$ python3 rid2name.py ../com.g_zhang.iMiniCam_39/original/resources.arsc 0x7f070000 fqdn
com.g_zhang.iMiniCam.R.string.app_name
$ python3 rid2name.py ../com.g_zhang.iMiniCam_39/original/resources.arsc 0x7f070000 json
{"package": "com.g_zhang.iMiniCam", "type": "string", "key": "app_name"}
$ python3 rid2name.py ../com.g_zhang.iMiniCam_39/original/resources.arsc 0x7f070000
com.g_zhang.iMiniCam.R.string.app_name

There is also quite convenient interface inside Python source, so the file should be includable into bigger projects.

I have to give one warning now: my implementation of ARSC format is not complete, so some things might not work as expected, but from my tests of libarsc, out of 12 ARSC files, extracted from random APK files, I found on my phone, 3 of them failed (returned different MD5) to rebuild into exactly same binary (did not checked exactly what happened there).

libarsc

This is library that was used underneath arscutils. It is able to parse most of the ARSC file, with special treatment of naming part, that allowed creation of rid2name. It is still missing some important parts and if there will be need from my side to extracting some more things, I will implement the rest of the specification. I am also open to any pull requests to my Github repo.

Future

As you might noticed in usage listing, there is a topic of reverse engineering app, which name was shown there. In case I found something interesting inside, there will be another article, where I will try to share my findings.

Edit: my mistake, this is not my target app, just the package name was similar.

Setting up new v3 Hidden Service with ultimate security: Part 4: Installing client certificates to Firefox for Android

This post is a part of Tor v3 tutorial. Other parts are:

  1. Hidden Service setup
  2. PKI and TLS
  3. Client Authentication
  4. Installing client certificates to Firefox for Android

As we now have Hidden Service, requiring clients to authenticate themselves with proper certificate, it would be great to be able to use Android device to access the service. As I shown before, on desktop Firefox it was quite trivial. Unfortunately, things are different on Android. Mobile Firefox does not have any interface for adding any certificates. Furthermore, unlike Chrome, it does not use default Android certificate vault, providing it own instead. On the other hand, under the hood it is more or less the same Firefox, so the support itself is present. Therefore, we need to hack into Firefox internal databases and add the certificate there. In this part, I will show, how to do that.

Caution: similarly to desktop browser, you should not add any random certificates to your main browser. It is even worse idea to do the same with Orfox, as it might allow attackers to reveal your identity. Newer Androids have ability to create user accounts, furthermore Firefox has profiles features, just like on desktop, but harder to use. If you want to do, what is described here, separating this configuration from any other is first thing to do.

Installing CA certificate

Before we do that with user certificate, let’s start with CA. It is way easier, as Firefox has convenient feature allowing to install certificates by browsing them. All we need to provide is a valid MIME type – application/x-x509-ca-cert. So, all we need is some webserver, which we will configure to treat files with extension .crt to be treated as mentioned type. Just after opening certificate file, Firefox should ask if you are sure about adding the certificate and allow you to choose for what purpose it will be used. It also allows to view the certificate to make sure, it is the one we intended to add.

At first, check the certificate
Then use it only for website identification

In theory there is very similar MIME for user certs – application/x-x509-user-cert, but for some reason, what Firefox says after opening this type of file is:

“Couldn’t install because the certificate file couldn’t be read”

And the same effect is, no matter if the file is password protected or not.

Installing client certificate

  1. Go to /data/data/org.mozilla.firefox/files/mozilla on Android device (root required)
  2. Locate default Firefox profile. If there is only one directory in format [bloat].profile, this is it. If not, file profiles.ini should contain only one profile with Default=1. This is what we are looking for
  3. Download files cert9.db and key4.db to Linux machine
  4. Use pk12util to insert certificate into database:
$ pk12util -i [filename].p12 -d.
Enter password for PKCS12 file:
pk12util: no nickname for cert in PKCS12 file.
pk12util: using nickname: [email] - r4pt0r Test Systems
pk12util: PKCS12 IMPORT SUCCESSFUL
  1. Upload files back to Android. Make sure Firefox is not running
  2. Test it by opening your hidden service with Firefox. You should see messages similar to these:
Request for identification
Certificate details
Finally, working cgit via tor!

[Import]Hacking Vasco translator through binary SMS

NOTE: This post was imported from my previous blog – v3l0c1r4pt0r.tk. It was originally published on 18th February 2017.

Recently I was asked to configure internet browser on a thing called Vasco Translator Premium 7″. The device looks exactly like many of the low-end Android tablets from China. And it happens to be one. The problem is that is was locked to used the only allowed application which is the translator. It has some minor functions like camera and it seems that was a mistake of its authors. They used default Android app as Camera and Gallery applications (and forgot to lock send message button in the latter 🙂 ).

At first I have to highlight the fact, this is not the full unlock or root of the device, but the fact of ease of the process allows me to suppose that rooting the thing should not be too difficult, too. Our goal here is to open up the web browser. Because as it seems the software below the shitty overlay is ordinary Android with all the apps on its place. And how useful might be the tablet without internet browser?

Prerequisites

The tool we will use to do the trick is good ol’ WAP Push protocol. For some reason in newer Android devices this dinosaur has been revived and supported out of the box. The goal is to send such message to our locked device, and since the gallery app mentioned above allows to escape to Messaging app, read it on it. This is probably the hardest part of the process. And possibly may require to buy some additional hardware (if you have access to any service, you know is sending WAP Push, you can use it and skip this part).

And that hardware is a GSM modem. It is highly possible that you already have one that can be used. The thing we will need is the possibility to send SMS through AT commands. Many Android phones allows that, at least if they are rooted, probably LTE/3G modems can do that too (not checked that personally). Ok, since the procedure to get access to AT interface is completely different for any device you can get, I have to leave you alone with getting used to that. After some time, you will probably end up in minicom or some similar program and parameters like 115200/8N1 or 9600/8N1. In my case (Android with Qualcomm processor) it is /dev/smd11 and params are 115200/8N1. Now you could type AT to check if the device you found is really an AT modem (should respond with OK) and AT+SCA? to check your SMS center address. You should be able to recognize it or Google it to check if it really belongs to your mobile operator.

Crafting SMS

Now, since we have all the tools, we can start crafting SMS. I will omit many details here since just general description of PDU format would take whole article and complete one is more than 100 pages long. The only part you need to know about is destination address. This will be the phone number of your device. Trailer of the message is WAP Push payload, which to be described will need another 100 or so pages, so skip it. As a remark, there is some program called wbxml2xml/xml2wbxml that allows to read/write the message. In our case, we want to enforce the device to visit Google.com, so this will be the address of WAP bookmark.

 

Ok, so on the picture above, thing we are interested in are [dest_addr] and [dest_len]. The first encodes telephone number “+37201234567” (note lack of ‘+’ sign), the second its length (as number of digits, 0x0b == 11). The number of your device should be placed here and you could move on to next section.

Or you can try customizing the payload. The important thing here is marked as [WBXML] and can be crafted with program mentioned before. After changing this, adjustment of [ud_len] value to number of bytes in payload (those after the length) is required.

Sending SMS

Since we already have modem, we need to type AT command to initiate message sending. But before that, we need to ensure that we are in binary mode. Type AT+CMGF? and, if value is other than zero, AT+CMGF=0. Now start sending with:

AT+CMGS=55

Where 55 is length of payload in bytes, but without SMSC header (one byte at the beginning). Modem should respond with > prompt, where SMS could be typed.

0041000b917302214365f700042a0605040b8423f0ea0601ae03056a0045c60c03676f6f676c652e636f6d00080103476f6f676c65000101

And after that press CTRL-Z (^Z) in your terminal. This should send SUB (substitute) to modem. It is important not to use any characters in between, like spaces and ENTER. After about a second, you should see that sending was successful and no error was returned.

Receiving and opening

Now, if you have your translator turned on, you should hear that new message was received, but nothing appeared on screen. That is ok. The rest of the procedure is shown on video below:

Postscriptum

After another few minutes of playing with the device I found another method of opening the browser and it is way faster than what was described below. But the first one was much more entertaining for me and is showing one of the many places where serious bugs could be found – forgotten technologies, still being implemented, possibly used, but with lack of knowledge about details in general public.

You can see the other method on video below, and possibly it is the one you want to use.

[Import]Wget with SSL/TLS support for Android

NOTE: This post was imported from my previous blog – v3l0c1r4pt0r.tk. It was originally published on 12th September 2016.

wget dependency tree

Lately I have tried to download some file from a website to my Android smartphone. Simple thing, yeah? Well, not really. Unfortunately mobile browser developers removed many features from their mobile distributions. One of them is a possibility of downloading random page to disk as is. Instead (this is the case at least with Mozilla’s product) they are forcing “Download as PDF” feature. I had a bit of luck, because the file I was trying to download was MP4 movie, which is downloadable, maybe not in an intuitive way, but it is. But before I have found that feature hidden in a player’s context menu, I tried another solution – wget. Since I am great fan of terminals, I have busybox installed on my phone. Those of you, who know what exactly is busybox should know that this is set of lightweight variants of most standard UNIX tools. So, if they are lightweight, they had to cut some part of tool functionality, right? And in case of my busybox’s wget, they cut HTTPS support. And today, it is more likely to encounter site which is only HTTPS than one that is only HTTP, at least when talking about popular sites. So I had to get my own distribution of wget, that will not be such constrained one.

Not to get you bored too much, here you can find binary distribution of what I achieved to compile. It was compiled for ARMv7 platform using NDKr12b and API level 24 (Nougat), so it will probably not work on most of current Android phones, but if you read later, it is probably working on your device or even is outdated. If you are interested in recompiling binaries yourself, you can find detailed how-to in the next part of this article.

Dependencies

Before compiling wget itself, you have to have whole bunch of its dependencies. But at first, you of course need Android compiler. It is distributed as part of NDK and I won’t describe its installation here. Sources of every program compiled here can be grabbed from its official sites (list at the end of this post). The only exception is libtasn1, which required few hacks to be done to make it compile with Android bionic libc. Its source, ported to Android can be get from my github repo.

Let’s start with programs that does not depend on anything. For all projects, the procedure is more or less the same and can be described with simplified bash script:

tar -zxvf program-1.00.tar.gz
mkdir build
mkdir install
cd build
CC=arm-linux-androideabi-gcc AR=arm-linux-androideabi-ar RANLIB=arm-linux-androideabi-ranlib CFLAGS=-pie \
    ../program-1.00/configure --host=arm-linux --prefix=/data/local/root
make
make install DESTDIR=$(dirname `pwd`)/install/
cd ../install
tar -zcvf program.tar.gz *

gmp, libidn and libffi

For these three programs, the procedure above should work without any modification.

nettle

Since nettle depends on gmp, it has to be configured with paths to gmp binaries and headers in its CFLAGS and LDFLAGS variables. They should look like this:

CFLAGS="-pie -I`pwd`/../../gmp/install/data/local/root/include"
LDFLAGS="-L`pwd`/../../gmp/install/data/local/root/lib"

when invoking configure script.

libtasn1

This was the hardest part for me, but should go smoothly now. Script below should do the work correctly:

git clone git@github.com:v3l0c1r4pt0r/android_external_libtasn1.git
mkdir build
mkdir install
cd build
CC=arm-linux-androideabi-gcc AR=arm-linux-androideabi-ar RANLIB=arm-linux-androideabi-ranlib CFLAGS=-pie \
    ../libtasn1/configure --host=arm-linux --prefix=/data/local/root --disable-doc
make
make install DESTDIR=$(dirname `pwd`)/install/
cd ../install
tar -zcvf libtasn1.tar.gz

p11-kit

This is the last dependency of gnutls which is the only, but very important dependency of wget. Just embedding libtasn1 and libffi should do the job well.

CFLAGS="-pie -I`pwd`/../../libtasn1/install/data/local/root/include"
LDFLAGS="-L`pwd`/../../libtasn1/install/data/local/root/lib -L`pwd`/../../libffi/install/data/local/root/lib"

Notice that libffi has no headers, so we add it just to CFLAGS here!

gnutls

This one was more complicated than the rest. As I mentioned above, it is very important to wget functionality. However wget’s dependency on it could probably be turned off, we would not have TLS support then. When compiling it I had some problems that seemed to be serious. There were a few errors while making it, so I had to call make twice and even though it failed. Despite that it seem to work after make install, which obviously failed too. In my case following script did the job:

mkdir build
mkdir install
cd build
CC=arm-linux-androideabi-gcc AR=arm-linux-androideabi-ar RANLIB=arm-linux-androideabi-ranlib \
    CFLAGS="-pie -I`pwd`/../../gmp/install/data/local/root/include -I`pwd`/../../nettle/install/data/local/root/include -I`pwd`/../../libtasn1/install/data/local/root/include -I`pwd`/../../libidn/install/data/local/root/include -I`pwd`/../../p11-kit/install/data/local/root/include" \
    LDFLAGS="-L`pwd`/../../gmp/install/data/local/root/lib -L`pwd`/../../nettle/install/data/local/root/lib -L`pwd`/../../libtasn1/install/data/local/root/lib -L`pwd`/../../libidn/install/data/local/root/lib -L`pwd`/../../p11-kit/install/data/local/root/lib" \
    ../gnutls-3.4.9/configure --host=arm-linux --prefix=/data/local/root --disable-cxx --disable-tools
make || make
make install DESTDIR=$(dirname `pwd`)/install/ || true
cd ../install
tar -zcvf file.tar.gz *

Compilation

Since we should now have all dependencies compiled, we can try compiling wget itself. The procedure here is the same as with dependencies. We just have to pass path to gnutls. And then standard configure, make, make install should work. However if your NDK installation is fairly new and you were not hacking it before, you most likely don’t have <sys/fcntl.h> header and make should complain about that. Luckily Android itself have this header present, but for reason unknown it is kept in include directory directly. To make wget, and any other program that uses it, compile you can just point “sys/” instance to <fcntl.h> with symlink or do something like that:

echo "#include <fcntl.h>" > $TOOLCHAIN/sysroot/usr/include/sys/fcntl.h

where $TOOLCHAIN/sysroot is path at which you have your headers placed. Depending on tutorial you were using for making it work it may have different structure.

Installation

All commands I presented above implies that you have your custom-compiled binaries in “/data/local/root”. I made it that way to have clear separation between default and busybox binaries. If you want to have them somewhere else, you should pass it to configure scripts of all programs you are compiling. After successful compilation of all tools, I have made single tarball containing all compilation output (this file’s link was placed above). Its content can be installed into Android by typing

tar -zxvf wget-with-deps.tar.gz -C/

using adb shell or terminal emulator.

Sources

Below you can find links to sources of all programs nedded to follow this tutorial.

[Import]CP210x (USB to TTL adapter) for Android devices

NOTE: This post was imported from my previous blog – v3l0c1r4pt0r.tk. It was originally published on 22nd August 2014.

Few days ago, while searching for something interesting I can do with my Android phone I found out that Sony is publishing kernel source of all their (and old SE ones too) ROMs. Beside hacking the kernel itself I was wondering if it is possible to compile additional kernel modules (stock ROM provides only internal WiFi module’s drivers). Well.. it was. The first one I tried was driver of my cheap, Chinese USB to serial adapter based on CP2102 chip.

Prerequisites

  • kernel source – it is important to be the same kernel as the one working on your device. Otherwise it would probably be necessary to boot your system with kernel compiled with source you have and it will not be described in this tutorial. The reason it is important is that between kernel version compatibility is not guaranteed. Different configuration could mess with functionality too (but not tried myself). I have Sony Ericsson device so I downloaded from its official repository.
  • cross-compiler – while compiling programs for Android you definitely should get special version of a compiler because Android is different than usual Linux box so compiler options are different too. The easiest way is to download official NDK which has built-in compilers and easy-to-use script to make standalone toolchain out of them. Same toolchain should also work as compiler for kernel but I haven’t tested it myself. In case it didn’t there is very powerful tool for making your own toolchain for any platform supported by GCC so in practice any you can imagine called crosstool-ng (on Arch available on AUR).
  • uucp source code

Kernel module

We will start with a kernel module. First of all we will unpack our kernel. In case of SE kernel need to be uncompressed and then unpacked so I did:

bzcat 4_1_B_0_431_tar.bz2 | tar -xv
cd kernel

And changed dir to kernel. Next thing I had to do was patching Makefile, because it complained about unused variables. If you are using Sony or SE kernel you probably need to do it too. If so create file named Makefile.patch with your favorite editor, i.e.

vim Makefile.patch

and paste following content:

--- Makefile  2012-05-25 12:07:05.000000000 +0200
+++ Makefile.new  2014-08-20 21:16:50.642703198 +0200
@@ -342,7 +342,6 @@
 KBUILD_CPPFLAGS := -D__KERNEL__

 KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-		   -Werror \
 		   -fno-strict-aliasing -fno-common \
 		    -Werror-implicit-function-declaration \
 		    -Wno-format-security \

Now you can patch it with:

patch Makefile < Makefile.patch

Then we can start the compilation process which should end in a second. I assume you have working toolchain in your $PATH and it is prefixed with arm-unknown-eabi- (arm-unknown-eabi-gcc, etc.). If its name is different change all occurrences of arm-unknown-eabi- below.

make mrproper
ARCH=arm CROSS_COMPILE=arm-unknown-eabi- make semc_iyokan_defconfig
ARCH=arm CROSS_COMPILE=arm-unknown-eabi- make prepare
ARCH=arm CROSS_COMPILE=arm-unknown-eabi- make modules_prepare
ARCH=arm CROSS_COMPILE=arm-unknown-eabi- make modules SUBDIRS=drivers/usb/serial CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_CP210X=m

If everything worked you should have your module compiled in drivers/usb/serial directory. It is worth to note you could compile any other module the same way. It is only important to change SUBDIRS to your module location and ensure it is configured to be built by issuing make menuconfig or setting appropriate CONFIG-* variable to ‘m’.

Now you can copy modules to your devices. With adb it will be:

adb push drivers/usb/serial/usbserial.ko /mnt/sdcard/others
adb push drivers/usb/serial/cp210x.ko /mnt/sdcard/others

We have two modules to copy here since cp210x (and any other serial device driver) depends on usbserial and without it being already in kernel it would be impossible to insert cp210x and furthermore it will give you strange error message (tested :). So now, again with help of ADB, we can insert our modules.

adb shell
su
cd /mnt/sdcard/others
insmod ./usbserial.ko
insmod ./cp210x.ko

After that you can connect your device and device you compiled module for and test if it works. Serial adapters should create new device file in /dev and, at least with CP210x, it uses ttyUSB* name so you can list it with:

ls -l /dev/ttyUSB*

You can also read from your port as simply as by typing

cat /dev/ttyUSB0

Now after you connect some device talking UART you should see its output.

Program to easily control our port – cu and the rest of uucp package

Warning: in the following steps I assume that you have directories like /data/local/bin and /data/local/etc already on your device. As far as I remember there is only /data/local by default.

At first we need to unpack our source and create some useful directories. Then we will configure our script in build-uucp so we won’t get garbage in source directory and could easily clean things when something goes wrong.

tar -zxvf uucp-1.07.tar.gz
mkdir build-uucp
mkdir install-uucp
cd build-uucp/

Then we will patch our program so it will work on Android out of the box. If we omitted following patch it would be necessary to create configuration file, configure program to read it before work and whole bunch of similar fun. So it is easier to let him know where he could store his files now. You can obviously use the one you want to. If you stay with my config you won’t be able to start cu as normal user which is no problem because by default you won’t have permission to use serial terminal.

Now the procedure is the same as with previous patch. I assume you used policy.h.patch name and the content is:

--- policy.h  2003-05-29 08:08:45.000000000 +0200
+++ policy.h.new  2014-08-20 12:03:45.595405893 +0200
@@ -297,7 +297,7 @@
    systems the lock files are placed in /etc/locks.  On some they are
    placed in /usr/spool/locks.  On the NeXT they are placed in
    /usr/spool/uucp/LCK.  */
-/* #define LOCKDIR "/usr/spool/uucp" */
+#define LOCKDIR "/data/local/etc/spool/uucp"
 /* #define LOCKDIR "/etc/locks" */
 /* #define LOCKDIR "/usr/spool/locks" */
 /* #define LOCKDIR "/usr/spool/uucp/LCK" */
@@ -572,7 +572,7 @@
 /* The name of the default spool directory.  If HAVE_TAYLOR_CONFIG is
    set to 1, this may be overridden by the ``spool'' command in the
    configuration file.  */
-#define SPOOLDIR "/usr/spool/uucp"
+#define SPOOLDIR "/data/local/etc/spool/uucp"
 /* #define SPOOLDIR "/var/spool/uucp" */

 /* The name of the default public directory.  If HAVE_TAYLOR_CONFIG is
@@ -580,7 +580,7 @@
    configuration file.  Also, a particular system may be given a
    specific public directory by using the ``pubdir'' command in the
    system file.  */
-#define PUBDIR "/usr/spool/uucppublic"
+#define PUBDIR "/data/local/etc/spool/uucppublic"
 /* #define PUBDIR "/var/spool/uucppublic" */

 /* The default command path.  This is a space separated list of
@@ -644,21 +644,21 @@
 /* The default log file when using HAVE_TAYLOR_LOGGING.  When using
    HAVE_TAYLOR_CONFIG, this may be overridden by the ``logfile''
    command in the configuration file.  */
-#define LOGFILE "/usr/spool/uucp/Log"
+#define LOGFILE "/data/local/etc/spool/uucp/Log"
 /* #define LOGFILE "/var/spool/uucp/Log" */
 /* #define LOGFILE "/var/log/uucp/Log" */

 /* The default statistics file when using HAVE_TAYLOR_LOGGING.  When
    using HAVE_TAYLOR_CONFIG, this may be overridden by the
    ``statfile'' command in the configuration file.  */
-#define STATFILE "/usr/spool/uucp/Stats"
+#define STATFILE "/data/local/etc/spool/uucp/Stats"
 /* #define STATFILE "/var/spool/uucp/Stats" */
 /* #define STATFILE "/var/log/uucp/Stats" */

 /* The default debugging file when using HAVE_TAYLOR_LOGGING.  When
    using HAVE_TAYLOR_CONFIG, this may be overridden by the
    ``debugfile'' command in the configuration file.  */
-#define DEBUGFILE "/usr/spool/uucp/Debug"
+#define DEBUGFILE "/data/local/etc/spool/uucp/Debug"
 /* #define DEBUGFILE "/var/spool/uucp/Debug" */
 /* #define DEBUGFILE "/var/log/uucp/Debug" */

@@ -669,17 +669,17 @@
 /* The default log file when using HAVE_V2_LOGGING.  When using
    HAVE_TAYLOR_CONFIG, this may be overridden by the ``logfile''
    command in the configuration file.  */
-#define LOGFILE "/usr/spool/uucp/LOGFILE"
+#define LOGFILE "/data/local/etc/spool/uucp/LOGFILE"

 /* The default statistics file when using HAVE_V2_LOGGING.  When using
    HAVE_TAYLOR_CONFIG, this may be overridden by the ``statfile''
    command in the configuration file.  */
-#define STATFILE "/usr/spool/uucp/SYSLOG"
+#define STATFILE "/data/local/etc/spool/uucp/SYSLOG"

 /* The default debugging file when using HAVE_V2_LOGGING.  When using
    HAVE_TAYLOR_CONFIG, this may be overridden by the ``debugfile''
    command in the configuration file.  */
-#define DEBUGFILE "/usr/spool/uucp/DEBUG"
+#define DEBUGFILE "/data/local/etc/spool/uucp/DEBUG"

 #endif /* HAVE_V2_LOGGING */

@@ -692,16 +692,16 @@
    be replaced by the system name (if there is no appropriate system,
    "ANY" will be used).  No other '%' character may appear in the
    string.  */
-#define LOGFILE "/usr/spool/uucp/.Log/%s/%s"
+#define LOGFILE "/data/local/etc/spool/uucp/.Log/%s/%s"

 /* The default statistics file when using HAVE_HDB_LOGGING.  When using
    HAVE_TAYLOR_CONFIG, this may be overridden by the ``statfile''
    command in the configuration file.  */
-#define STATFILE "/usr/spool/uucp/.Admin/xferstats"
+#define STATFILE "/data/local/etc/spool/uucp/.Admin/xferstats"

 /* The default debugging file when using HAVE_HDB_LOGGING.  When using
    HAVE_TAYLOR_CONFIG, this may be overridden by the ``debugfile''
    command in the configuration file.  */
-#define DEBUGFILE "/usr/spool/uucp/.Admin/audit.local"
+#define DEBUGFILE "/data/local/etc/spool/uucp/.Admin/audit.local"

 #endif /* HAVE_HDB_LOGGING */

If you prefer I have it on my gist so you can just issue one command and get it. Then we are patching as usually:

patch ../uucp-1.07/policy.h < policy.h.patch

As mentioned above you can change path of uucp’s files by issuing the following (remember to escape every occurrence of slash with backslash, otherwise it will fail):

sed -i "s/\/data\/local\/etc/[your-path]/" ../uucp-1.07/policy.h

Now you are ready to compile. It can be done with following commands. Your compiler should have same name (at least if you use NDK’s compiler). It is important to note that I had to switch off HAVE_SYSCONF flag since it was causing ugly errors. In my case makescript couldn’t also find a rule to make ftw.o so I had to make it myself. If you have no trouble here, just omit the line after make.

CC=arm-linux-androideabi-gcc AR=arm-linux-androideabi-ar RANLIB=arm-linux-androideabi-ranlib \
../uucp-1.07/configure --prefix=`pwd`/../install-uucp/ --host=arm-linux-androideabi
sed -i "s/#define HAVE_SYSCONF 1/#define HAVE_SYSCONF 0/" config.h
make
cd unix; make ftw.o; cd ..; make
make install
adb push ../install-uucp/bin/cu /mnt/sdcard/others
adb shell
su
cp /mnt/sdcard/others/cu /data/local/bin/

Finally you can test the program with the following and you should be able to talk RS232 with just a phone/tablet!

cu -lttyUSB0 -s115200

where 115200 is the speed the device you connect to transmits.

BTW: uucp have few other tools and by following this tutorial you compiled them all so you can explore them on your own.

[Import][Android] Odblokowywanie kanałów 12, 13, 14

NOTE: This post was imported from my previous blog – v3l0c1r4pt0r.tk. It was originally published on 18th June 2012.

Jak wspomniałem w swoim pierwszym wpisie dotyczącym Androida na tym systemie niemożliwe jest połączenie się z siecią działającą na kanale wyższym niż 11 (a więc takim, który jest zabroniony w USA). Ja jednak nie mieszkam w Stanach i chciałbym, aby mój telefon miał dostęp przynajmniej do tego co nie jest w Polsce nielegalne. Na szczęście udało mi się znaleźć rozwiązanie tego problemu.

Użycie tej metody wymaga dostępu do roota, więc jeśli twój telefon nie został jeszcze zrootowany odsyłam do strony Zeely’ego. Kolejnym wymaganiem będzie zainstalowanie do folderu bin sqlite’a (nie wiedzieć czemu ten, który można używać prze adb przestaje działać gdy wpiszemy w konsoli su). Potrzebne też będzie SDK Adroida (będę używał go, aby przeklejać komendy do konsoli, nada się też każdy emulator terminala np. Terminal IDE, ale tu trzeba będzie wszystko pisać ręcznie). Radzę też żeby koniecznie wykonać backup systemu z użyciem CWM (mnie przy pierwszej próbie coś poszło nie tak i musiałem przywracać kopię z poprzedniego dnia).

  1. Podłączamy telefon do komputera w trybie debugowania USB. Wchodzimy w Ustawienia=>Aplikacje i zaznaczamy Debugowanie USB.
  2. Potem należy uruchomić konsolę Windowsa (lub terminal gdy używamy Linuksa) i przejść do folderu, w którym zainstalowaliśmy SDK. Wpisujemy adb shell. Gdy wszystko pójdzie dobrze powinniśmy być już w konsoli naszego telefonu (pojawi się znak $). Można teraz wpisać su, aby uzyskać uprawnienia roota (# oznacza sukces).
  3. Aby móc zmodyfikować folder /system należy zamontować go do zapisu. Używamy komendy mount, aby odnaleźć odpowiednie urządzenie:
    $ mount
    mount
    rootfs / rootfs ro,relatime 0 0
    tmpfs /dev tmpfs rw,relatime,mode=755 0 0
    devpts /dev/pts devpts rw,relatime,mode=600 0 0
    proc /proc proc rw,relatime 0 0
    sysfs /sys sysfs rw,relatime 0 0
    tmpfs /mnt/asec tmpfs rw,relatime,mode=755,gid=1000 0 0
    tmpfs /mnt/obb tmpfs rw,relatime,mode=755,gid=1000 0 0
    /dev/block/mtdblock0 /system yaffs2 ro,relatime 0 0
    /dev/block/mtdblock3 /data yaffs2 rw,nosuid,nodev,relatime 0 0
    /dev/block/mtdblock2 /cache yaffs2 rw,nosuid,nodev,relatime 0 0
    /dev/block/mtdblock1 /data/idd yaffs2 rw,nosuid,nodev,relatime 0 0
    [...]
    $

    Właściwa linia została pogrubiona. Wpisujemy więc mount -o remount,rw -t rfs /dev/block/mtdblock0 /system (uwaga! Wartość po /dev/block/ może być inna).

  4. Teraz przenosimy plik sqlite3 (dostępny do pobrania na końcu wpisu) do folderu, w którym zainstalowane jest adb. Otwieramy w tym samym folderze drugie okno konsoli i wpisujemy w nie adb push sqlite3 /sdcard/ czym kopiujemy sqlite3 na kartę pamięci (tutaj ważne jest, żeby karta pamięci NIE była zamontowana w komputerze tj. w trybie MSC).
  5. Wracamy do poprzedniego okna, w którym wpisujemy cp /sdcard/sqlite3 /system/bin oraz chmod 4755 /system/bin/sqlite3.
  6. Na koniec montujemy system znów do odczytu: mount -o remount,ro -t rfs /dev/block/mtdblock0 /system.
  7. Teraz możemy wpisać sqlite3 i sprawdzić czy wszystko poszło pomyślnie. Jeśli tak przechodzimy do modyfikacji właściwego pliku.
  8. Zostajemy w tej samej konsoli (tą drugą można już zamknąć). Wpisujemy: sqlite3 /data/data/com.android.providers.settings/databases/settings.db “INSERT INTO secure (name, value) VALUES (‘wifi_country_code’, ‘JP’);”. Gdybyś nie chciał odblokowywać bądź co bądź zakazanego w Polsce kanału 14 możesz zmienić JP na EU w powyższej linii.
  9. Restartujemy telefon. Gdy system włączy się kanały 12,13 i 14 powinny już zostać odblokowane i powinno być już możliwe połączenie się z siecią na tych kanałach.

Nie jestem w stanie tego teraz sprawdzić, bo już zainstalowałem sqlite3 powyższą metodą, ale najpewniej, aby dokonać jego instalacji wystarczyłoby użyć jakiegokolwiek menadżera umożliwiającego modyfikację folderu /system. Potem wystarczyłoby tym samym programem zmienić chmody tak, aby możliwe byłoby wykonywanie pliku. Tym samym możnaby wtedy pominąć punkty 3-6.