Reverse Engineering the Camera

OK, I'm not really going to try and understand the gazillion lines of disassembled .odex files that the Nikon camera app probably has, but applying various android reverse engineering tools might provide some interesting clues, so it is worth looking at.

There are lots of web pages out there already about reverse engineering android apps, and they all point to the same set of essential apps:

apktool can decode the .apk file and restore human readable files (like AndroidManifest.xml).

smali and baksmali for turning .odex files into human readable assembly level code. (A long way from Java source, but it is the best you can get).

Applying apktool to the com.nikon.cp01.camera apk file fetched from the S800c finds some interesting things...

Here is the AndroidManifest.xml file:

<?xml version="1.0" encoding="utf-8"?>
<manifest android:sharedUserId="android.uid.system" android:versionCode="1" android:versionName="1.0" package="com.nikon.cp01.camera"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="10" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="com.nikon.permission.MICKCAMAPPEXT" />
    <application android:label="@string/Q_25" android:icon="@drawable/home_shoot" android:name="com.nikon.cp01.camera.CameraApplication">
        <activity android:theme="@style/Theme.ActivityNoAnimation" android:name=".StartupActivity" android:configChanges="touchscreen|keyboardHidden|orientation">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.media.action.VIDEO_CAPTURE" />
                <action android:name="android.media.action.IMAGE_CAPTURE" />
                <action android:name="android.media.action.STILL_IMAGE_CAMERA" />
                <action android:name="android.media.action.VIDEO_CAMERA" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:theme="@style/Theme.ActivityNoAnimation" android:name=".camera.CameraActivity" android:screenOrientation="landscape" android:configChanges="touchscreen|keyboardHidden|orientation">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:theme="@style/Theme.ActivityNoAnimation" android:name=".camera.VideoCameraActivity" android:screenOrientation="landscape" android:configChanges="touchscreen|keyboardHidden|orientation">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Note the one interesting permission name: com.nikon.permission.MICKCAMAPPEXT. I don't know what it means, but it is certainly unique and different.

Now let's try to disassemble the .odex file (also fetched from the camera). The instructions for using the baksmali tool are another one of those android pages that assume you know what the heck they are talking about. I need to point the tool at a framework directory. Really? What the heck is a framework? Off to google, and I find the framework is usually stored in /system/framework/ on the camera. I look, and there it is, so I fetch it off the camera and stash it where I can point baksmali at it. I try running, and it tells me it can't find baksmali.jar. Poking around, I see the script is looking for the baksmali.jar file in the same directory with the script, but after building baksmali there is no such file. Poking around in the build directory does find some .jar files, but with long version number suffixes. I make a symlink of the long name to the short name in the script directory, and it finally runs (sheesh!).

That gives me an out directory which contains 484,231 lines of code in 426 separate files. Should be trivial to figure this all out :-). One thing is clear: There are zillions of references to all sorts of names with mick in them.

Let's find out what sorts of micks exist on the camera itself:

zooty> adb shell
$ su
# find / -name '*[Mm][Ii][Cc][Kk]*' -print
/dev/mickxx_edit2
/dev/mickxx_edit1
/dev/mickxx_usb_middle
/dev/mickxx_usb_intr
/dev/mickxx_usb_bulk
/dev/mickxx_syscomm
/dev/mickxx_dbg_print
/dev/mickxx_camera4
/dev/mickxx_camera3
/dev/mickxx_camera2
/dev/mickxx_h264_stream
/dev/mickxx_h264_source
/dev/mickxx_h264_device
/dev/mickxx_camera
/dev/mickxx_vfat
/dev/block/mickxx_vsd0p1
/dev/block/mickxx_vsd0
/init.mickxx.rc
/lib/modules/mickxx_battery.ko
/lib/modules/mickxx_bmmod.ko
/lib/modules/mickxx_bright.ko
/lib/modules/mickxx_dswmod.ko
/lib/modules/mickxx_mbox.ko
/lib/modules/mickxx_mbox_util.ko
/lib/modules/mickxx_memctl.ko
/lib/modules/mickxx_thermal.ko
/lib/modules/mickxx_vdrv.ko
/lib/modules/mickxx_vfs.ko
/lib/modules/mickxx_vsd.ko
/proc/irq/300/mickxx_keysc
/sys/devices/platform/mickxx_keysc
/sys/devices/platform/mickxx_overlay.0
/sys/devices/virtual/misc/mickxx_vfat
/sys/devices/virtual/misc/mickxx_camera
/sys/devices/virtual/misc/mickxx_h264_device
/sys/devices/virtual/misc/mickxx_h264_source
/sys/devices/virtual/misc/mickxx_h264_stream
/sys/devices/virtual/misc/mickxx_camera2
/sys/devices/virtual/misc/mickxx_camera3
/sys/devices/virtual/misc/mickxx_camera4
/sys/devices/virtual/misc/mickxx_dbg_print
/sys/devices/virtual/misc/mickxx_syscomm
/sys/devices/virtual/misc/mickxx_usb_bulk
/sys/devices/virtual/misc/mickxx_usb_intr
/sys/devices/virtual/misc/mickxx_usb_middle
/sys/devices/virtual/misc/mickxx_edit1
/sys/devices/virtual/misc/mickxx_edit2
/sys/devices/virtual/block/mickxx_vsd0
/sys/devices/virtual/block/mickxx_vsd0/mickxx_vsd0p1
/sys/devices/virtual/mickxx_thermal
/sys/bus/platform/devices/mickxx_keysc
/sys/bus/platform/devices/mickxx_overlay.0
/sys/bus/platform/drivers/mickxx_keysc
/sys/bus/platform/drivers/mickxx_keysc/mickxx_keysc
/sys/bus/platform/drivers/mickxx_overlay
/sys/bus/platform/drivers/mickxx_overlay/mickxx_overlay.0
/sys/class/block/mickxx_vsd0
/sys/class/block/mickxx_vsd0p1
/sys/class/misc/mickxx_vfat
/sys/class/misc/mickxx_camera
/sys/class/misc/mickxx_h264_device
/sys/class/misc/mickxx_h264_source
/sys/class/misc/mickxx_h264_stream
/sys/class/misc/mickxx_camera2
/sys/class/misc/mickxx_camera3
/sys/class/misc/mickxx_camera4
/sys/class/misc/mickxx_dbg_print
/sys/class/misc/mickxx_syscomm
/sys/class/misc/mickxx_usb_bulk
/sys/class/misc/mickxx_usb_intr
/sys/class/misc/mickxx_usb_middle
/sys/class/misc/mickxx_edit1
/sys/class/misc/mickxx_edit2
/sys/class/mickxx_thermal
/sys/module/mickxx_keyscan
/sys/module/mickxx_vsd
/sys/module/mickxx_mbox
/sys/module/mickxx_mbox/holders/mickxx_vsd
/sys/module/mickxx_mbox/holders/mickxx_vdrv
/sys/module/mickxx_mbox/holders/mickxx_memctl
/sys/module/mickxx_vfs
/sys/module/mickxx_vfs/parameters/mickxx_shmem_size
/sys/module/mickxx_vfs/parameters/mickxx_shmem_addr
/sys/module/mickxx_mbox_util
/sys/module/mickxx_mbox_util/holders/mickxx_thermal
/sys/module/mickxx_mbox_util/holders/mickxx_battery
/sys/module/mickxx_vdrv
/sys/module/mickxx_thermal
/sys/module/mickxx_battery
/sys/module/mickxx_memctl
/sys/module/mickxx_bmmod
/sys/module/mickxx_dswmod
/sys/module/mickxx_bright
/sys/block/mickxx_vsd0
/system/bin/mickadjustserver
/system/bin/mickcamextserver
/system/bin/mickxx_fat
/system/bin/mickxx_fat_chk
/system/bin/mickxx_fat_fmt
/system/bin/mickxx_fwup
/system/bin/mickxx_syscomm
/system/etc/init.mickxx.sh
/system/etc/omx_mickxx.cfg
/system/lib/hw/gps.mickxx.so
/system/lib/hw/overlay.mickxx.so
/system/lib/libmickadjust.so
/system/lib/libmickadjust_client.so
/system/lib/libmickadjustservice.so
/system/lib/libmickcamappext_jni.so
/system/lib/libmickcamappexthdmi.so
/system/lib/libmickcamappexthdmiservice.so
/system/lib/libmickcamappextstate.so
/system/lib/libmickcamappextstateservice.so
/system/lib/libmickcamextlogutil.so
/system/lib/libmickimageedit_client.so
/system/lib/libmickimageedit_jni.so
/system/lib/libmickimageeditcommon.so
/system/lib/libmickimageeditservice.so
/system/lib/libmickimageobject.so
/system/lib/libmickmemdev.so
/system/lib/libmickmemdev_client.so
/system/lib/libmickmemdevrtc.so
/system/lib/libmickmemdevservice.so
/system/lib/libmickmemorymanager.so
/system/lib/libmickxx_adp_test_if.so
/system/lib/libmickxx_backupapi.so
/system/lib/libmickxx_exif.so
/system/lib/libmickxx_h264enc.so
/system/lib/libmickxx_imageedit.so
/system/lib/libmickxx_mboxapi.so
/system/lib/libmickxx_sicif.so
/system/lib/libmickxx_stream.so
/system/lib/libmickxx_version.so
/system/lib/libmickxx_wlan_if.so
/system/lib/libomx_me_h264e_mickxx.so
/system/vendor/lib/hw/gralloc.mickxx.so
/ueventd.mickxx.rc

So, it looks like mick is a very popular guy :-). That /system/bin/mickcamextserver program may very well be the program that goes with the mysterious com.nikon.permission.MICKCAMAPPEXT permission? Possibly that program really runs the camera and if only this junk were all documented, I could run it too?

Anyway, I'm not about to try to tackle a half million lines of disassembly to try and understand things better. I think my curiosity is satisfied for now (though I did ask over in this xda developer thread to see if anyone has ever heard of mick :-).

Someone said the build.prop file might have useful info (but I don't see any :-). For what it is worth, here it is:

build.prop

# begin build properties
# autogenerated by buildinfo.sh
ro.build.id=CP01_WW
ro.build.display.id=COOLPIX S800c Ver.1.2
ro.build.version.incremental=4171M
ro.build.version.display=Ver.1.2
ro.build.version.sdk=10
ro.build.version.codename=REL
ro.build.version.release=2.3.3
ro.build.date=2012年 11月 22日 木曜日 09:57:52 JST
ro.build.date.utc=1353545872
ro.build.type=user
ro.build.user=nikon-build
ro.build.host=android-build01
ro.build.tags=release-keys
ro.product.model=COOLPIX S800c
ro.product.brand=COOLPIX
ro.product.name=S800c
ro.product.device=S800c
ro.product.board=
ro.product.cpu.abi=armeabi-v7a
ro.product.cpu.abi2=armeabi
ro.product.manufacturer=NIKON
ro.product.locale.language=en
ro.product.locale.region=US
ro.wifi.channels=
ro.board.platform=S800c
# ro.build.product is obsolete; use ro.product.device
ro.build.product=S800c
# Do not try to parse ro.build.description or .fingerprint
ro.build.description=S800c-user 2.3.3 CP01_WW 4171M release-keys
ro.build.fingerprint=COOLPIX/S800c/S800c:2.3.3/CP01_WW/4171M:user/release-keys
# end build properties
ro.config.sync = yes
ro.sf.lcd_density = 240
ro.simulated.phone=true
keyguard.no_require_sim=1
wifi.interface=mlan0
wifi.ap_interface=uap0

#
# ADDITIONAL_BUILD_PROPERTIES
#
ro.setupwizard.mode=OPTIONAL
ro.com.google.gmsversion=2.3_r10
ro.config.notification_sound=OnTheHunt.ogg
ro.config.alarm_alert=Alarm_Classic.ogg
ro.com.google.clientidbase=android-nikon
dalvik.vm.heapsize=32m
ro.opengles.version=131072
net.bt.name=Android
dalvik.vm.stack-trace-file=/data/anr/traces.txt
persist.sys.timezone=America/New_York

And I might as well include a few other random bits of system info (some of them actually mention mick :-).

uname -a

Linux localhost 2.6.35.14 #1 PREEMPT Thu Nov 22 15:28:35 JST 2012 armv7l GNU/Linux

ls -l /system/lib/hw

-rwxr-xr-x system   system       5548 2012-11-21 20:04 acoustics.default.so
-rwxr-xr-x system   system       9932 2012-11-21 20:04 alsa.default.so
-rwxr-xr-x system   system      38576 2012-11-21 20:04 gps.mickxx.so
-rwxr-xr-x system   system      10112 2012-11-21 20:04 gralloc.default.so
-rwxr-xr-x system   system      30332 2012-11-21 20:04 overlay.mickxx.so
-rwxr-xr-x system   system      14080 2012-11-21 20:04 sensors.default.so

ls -l /system/lib/egl

-rw-r--r-- system   system         35 2012-11-21 19:55 egl.cfg
-rw-r--r-- system   system      93672 2012-11-21 20:05 libGLES_android.so

cat /system/lib/egl/egl.cfg

0 0 android
0 1 POWERVR_SGX540_120

cat /proc/cpuinfo

Processor	: ARMv7 Processor rev 3 (v7l)
BogoMIPS	: 1600.56
Features	: swp half thumb fastmult vfp edsp neon vfpv3 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x2
CPU part	: 0xc09
CPU revision	: 3

Hardware	: mickxx
Revision	: 4120
Serial		: 0000000000000000

cat /proc/meminfo

MemTotal:         254804 kB
MemFree:           11796 kB
Buffers:            4000 kB
Cached:            72744 kB
SwapCached:            0 kB
Active:            78032 kB
Inactive:         127160 kB
Active(anon):      66144 kB
Inactive(anon):    62856 kB
Active(file):      11888 kB
Inactive(file):    64304 kB
Unevictable:           0 kB
Mlocked:               0 kB
HighTotal:             0 kB
HighFree:              0 kB
LowTotal:         254804 kB
LowFree:           11796 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:        128460 kB
Mapped:            45032 kB
Shmem:               552 kB
Slab:               6576 kB
SReclaimable:       1872 kB
SUnreclaim:         4704 kB
KernelStack:        3488 kB
PageTables:        10512 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:      127400 kB
Committed_AS:    1596688 kB
VmallocTotal:     319488 kB
VmallocUsed:       74544 kB
VmallocChunk:     234500 kB

cat /proc/devices

Character devices:
  1 mem
  4 /dev/vc/0
  4 tty
  5 /dev/tty
  5 /dev/console
  5 /dev/ptmx
  7 vcs
 10 misc
 13 input
 29 fb
 81 video4linux
 89 i2c
116 alsa
128 ptm
136 pts
204 ttySC
216 rfcomm
248 bc_example
249 pvrsrvkm
250 mbox
251 pmreg_mem
252 cache_mem
253 static_mem
254 rtc

Block devices:
259 blkext
  7 loop
 31 mtdblock
179 mmc
252 mickxx_vsd
253 mbox_blk
254 device-mapper

cat /proc/interrupts

           CPU0
 33:      68777         GIC  sh_cmt.2
 41:          0         GIC  sh_fsi2
 43:      12632         GIC  SGX ISR
 57:       5718         GIC  mfi_int
 60:      42408         GIC  sh-dmae0.0
 61:     202222         GIC  sh-dmae0.1
 62:      10761         GIC  sh-dmae0.2
 63:      27616         GIC  sh-dmae0.3
 64:          0         GIC  sh-dmae0.4
 65:          0         GIC  sh-dmae0.5
 67:          0         GIC  sh-dmae1.0
 68:          0         GIC  sh-dmae1.1
 69:          0         GIC  sh-dmae1.2
 70:          0         GIC  sh-dmae1.3
 71:          0         GIC  sh-dmae1.4
 72:          0         GIC  sh-dmae1.5
 81:       1229         GIC  USBHS-DMA1
 83:       1998         GIC  r8a66597_udc
 88:          2         GIC  sh_mmc:error
 89:      88507         GIC  sh_mmc:int
102:          0         GIC  i2c-sh_mobile.1
103:          0         GIC  i2c-sh_mobile.1
104:      22918         GIC  i2c-sh_mobile.1
105:       7773         GIC  i2c-sh_mobile.1
130:      36038         GIC  spi_sh_msiof.4
133:          4         GIC  sci
153:          0         GIC  sh_mobile_sdhi.1
154:     174644         GIC  sh_mobile_sdhi.1
155:      14077         GIC  sh_mobile_sdhi.1
184:        385         GIC  rtdmac_irq
190:          0         GIC  rtdmac_irq
245:        237         GIC  spi_sh_msiof.0
267:          0         GIC  sio-pcm0
272:       5297         GIC  mbox
300:         43         GIC  mickxx_keysc
354:          1     IRQ pin  vbus_detect
375:          0     IRQ pin  kxtia-irq
377:       1361     IRQ pin  mxt224_ts
Err:          0

cat /proc/softirqs

                CPU0       
      HI:          0
   TIMER:      44872
  NET_TX:        241
  NET_RX:      11259
   BLOCK:          0
BLOCK_IOPOLL:          0
 TASKLET:     355642
   SCHED:          0
 HRTIMER:         21
     RCU:      35386
Page last modified Thu Jan 31 17:58:18 2013