Unpack, modify and rebuild an APK

This is NOT an “Android hacker HOW-TO”. This is only a quick reference for myself.

  • Step 1 : decompile APK using apktool d -f -r app_name.apk
  • Step 2 : delete the original apk
  • Step 2 : Modify SMALI files
  • Step 3 : Rebuild apk using apktool b app_name
  • Step 4 : Generate a signing key with keytool -genkey -keystore test.keystore -validity 10000 -alias test
  • Step 5 : Sign the new APK jarsigner -keystore test.keystore -verbose app_name.apk test
  • Step 7 : Install apk and enjoy!
apktool d -f -r app_name.apk
delete app_name.apk
--- modify smali files ---
apktool b app_name
keytool -genkey -keystore test.keystore -validity 10000 -alias test
jarsigner -keystore test.keystore -verbose app_name.apk test
adb install -r app_name.apk

Error building i9515 kernel

My linux build machine died some days ago, and then I lost my working build environment.
Luckily I found this helpful post on XDA with a working VM out-of-the-box and then, after the usual repo sync… I found a strange error during kernel build

/bin/sh: -c: line 0: syntax error near unexpected token `('
/home/android/i9515/kernel/samsung/jf/scripts/Makefile.build:307: recipe for target 'scripts/mod/empty.o' failed

Changing the /bin/sh from /bin/dash to /bin/bash the error changes a little bit and shows some other infos

/bin/sh: -c: line 0: `set -e; echo ' CC scripts/mod/empty.o'; /home/android/i9515/kernel/samsung/jf/scripts/gcc-wrapper.py /home/android/i9515/prebuilts/misc/linux-x86/ccache/ccache /home/android/i9515/prebuilts/gcc/linux-x86/arm/arm-eabi-4.9/bin/arm-eabi-gcc -Wp,-MD,scripts/mod/.empty.o.d -nostdinc -isystem ccache: FATAL: /home/android/i9515/prebuilts/gcc/linux-x86/arm/arm-eabi-4.9/bin/arm-eabi-gcc: execv returned (No such file or directory)
[...]

So…this is simple an error with my cross compiler configuration. Google team changes the compiler name from arm-eabi to arm-linux-androideabi, and so it’s very simple to fix.
This is the diff for the “BoardConfigCommon.mk” file

diff --git a/BoardConfigCommon.mk b/BoardConfigCommon.mk
index 872bdc9..fe64f87 100644
--- a/BoardConfigCommon.mk
+++ b/BoardConfigCommon.mk
@@ -43,8 +43,8 @@ BOARD_MKBOOTIMG_ARGS := --ramdisk_offset 0x02000000
BOARD_KERNEL_PAGESIZE := 2048
TARGET_KERNEL_CONFIG := cyanogen_jfve_defconfig
TARGET_KERNEL_SOURCE := kernel/samsung/jf
-KERNEL_TOOLCHAIN := $(ANDROID_BUILD_TOP)/prebuilts/gcc/$(HOST_OS)-x86/arm/arm-eabi-4.9/bin
-KERNEL_TOOLCHAIN_PREFIX := arm-eabi-
+KERNEL_TOOLCHAIN := $(ANDROID_BUILD_TOP)/prebuilts/gcc/$(HOST_OS)-x86/arm/arm-linux-androideabi-4.9/bin
+KERNEL_TOOLCHAIN_PREFIX := arm-linux-androideabi-

How to build cm13 on i9515 (Samsung s4 Value Edition) [UPDATED]

XDA user “sombree” has ported CM 13.0 on Samsung Galaxy S4 Value Edition (i9515)

In order to build a working rom you need to add a local manifest with the right device configuration and kernel

mkdir .repo/local_manifests
vim .repo/local_manifests/roomservice.xml

Edit the file and add the following XML

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <project name="jfvelte-dev/proprietary_vendor_samsung" path="vendor/samsung" remote="github" />
  <project name="CyanogenMod/android_device_qcom_common" path="device/qcom/common" remote="github" />
  <project name="CyanogenMod/android_device_samsung_qcom-common" path="device/samsung/qcom-common" remote="github" />
  <project name="jfvelte-dev/android_device_samsung_jfvelte" path="device/samsung/jfvelte" remote="github" />
  <project name="jfvelte-dev/android_device_samsung_jf-common" path="device/samsung/jf-common" remote="github" />
  <project name="jfvelte-dev/android_kernel_samsung_jf" path="kernel/samsung/jf" remote="github" />
</manifest>

Then do a simply

brunch jfvelte

Thanks to Sombree for the hints about roomservice.xml and for the porting, of course 🙂

Source: XDA Forum

Some thoughts about WhatsApp + VoIP

Today WhatsApp has released a new version with the green blue read notification icon.

I downloaded it and tried to inspect the APK in searching of something interesting.

Tools:

  • WhatsApp APK
  • Apktool – in order to analyze XML resources
  • Dex2Jar – if you want to analyze the (obfuscated) source code

These are some thoughts about the next VoIP feature after a fast and quick analysis. I think that with enough time it’s possible to find a lot of interesting things (for example: it is possible to enable VoIP feature hacking the smali files?).

VoIP engine is fully implemented (I think). The native library libwhatsapp.so contains a lot of PJSIP references. This is an excerpt of a “strings libwhatsapp.so” command

Error creating stream: %d
pjmedia_stream_get_port error
Error creating conf bridge
stream_port
Error adding stream port to conf bridge
pjmedia_stream_start error
....
Unspecified audio device error (PJMEDIA_EAUD_ERR)
Unknown error from audio driver (PJMEDIA_EAUD_SYSERR)
Audio subsystem not initialized (PJMEDIA_EAUD_INIT)
Invalid audio device (PJMEDIA_EAUD_INVDEV)
Found no audio devices (PJMEDIA_EAUD_NODEV)

Another interesting thing is that there are a lot of references to SRTP protocol. SRTP is implemented by default in PjSIP but there are also some little references in .class files, so maybe the VoIP calls will be made using SRTP encryption.

error during srtp key copy for offer
error during srtp key copy for offer accept
pjmedia_transport_srtp_create failed
pjmedia_transport_srtp_start failed: %d
incompatible-srtp-key-exchange
....
%s: function srtp_protect
%s: srtp auth tag: %s
%s: function srtp_unprotect

The last interesting thing is the VoipActivity layout and the visual rendering made by Eclipse. This will be the “In call activity” ?

WhatsApp Voip Activity

Below you can analyze the Activity XML file (sorry for the bad XML rendering on this page…I need to find a better WordPress Template)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:background="@*android:color/black" android:layout_width="fill_parent" android:layout_height="fill_parent"
  xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
    <TextView android:textSize="27.0sp" android:textColor="@*android:color/white" android:gravity="left" android:id="@id/name" android:paddingLeft="16.0dip" android:paddingTop="10.0dip" android:paddingRight="16.0dip" android:paddingBottom="10.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:fontFamily="sans-serif-light" />
    <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignTop="@id/name" android:layout_alignRight="@id/name" android:layout_alignBottom="@id/name">
        <View android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="2.0" />
        <Button android:id="@id/report_audio_quality_btn" android:background="@*android:color/transparent" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0" />
    </LinearLayout>
    <LinearLayout android:orientation="vertical" android:id="@id/footer" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true">
        <com.whatsapp.AnswerCallView android:id="@id/answer_call_slider" android:layout_width="fill_parent" android:layout_height="78.0dip" />
        <FrameLayout android:id="@id/answer_call_btns" android:layout_width="fill_parent" android:layout_height="78.0dip">
            <ImageButton android:layout_gravity="center" android:id="@id/reject_with_message" android:background="@drawable/reject_with_message_btn_background" android:padding="12.0dip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_reject_with_message" android:contentDescription="@string/voip_call_goto_chat_description" />
        </FrameLayout>
        <LinearLayout android:orientation="horizontal" android:id="@id/call_btns" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="78.0dip">
            <ImageButton android:id="@id/end_call_btn" android:background="@drawable/btn_end_call_background" android:layout_width="0.0dip" android:layout_height="fill_parent" android:src="@drawable/btn_end_call" android:layout_weight="1.0" android:contentDescription="@string/voip_call_end_button_description" />
            <ImageButton android:id="@id/voip_call_btn" android:background="@drawable/btn_start_call_background" android:visibility="gone" android:layout_width="0.0dip" android:layout_height="fill_parent" android:src="@drawable/btn_start_call" android:layout_weight="1.0" android:contentDescription="@string/voip_call_start_button_description" />
        </LinearLayout>
        <LinearLayout android:orientation="horizontal" android:id="@id/audio_btns" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="78.0dip">
            <LinearLayout android:orientation="vertical" android:layout_width="0.0dip" android:layout_height="wrap_content" android:layout_weight="1.0">
                <ImageButton android:id="@id/speaker_btn" android:background="#ff111111" android:paddingTop="17.0dip" android:paddingBottom="17.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:src="@drawable/ic_speaker" android:contentDescription="@string/voip_call_speakerphone_toggle_description" />
                <View android:id="@id/speaker_btn_on" android:background="#b238caff" android:visibility="invisible" android:layout_width="wrap_content" android:layout_height="10.0dip" />
            </LinearLayout>
            <LinearLayout android:orientation="vertical" android:layout_width="0.0dip" android:layout_height="wrap_content" android:layout_weight="1.0">
                <ImageButton android:id="@id/chat_btn" android:background="#ff111111" android:paddingTop="17.0dip" android:paddingBottom="17.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:src="@drawable/ic_chat" android:contentDescription="@string/voip_call_goto_chat_description" />
                <View android:id="@id/chat_btn_on" android:background="#b238caff" android:visibility="invisible" android:layout_width="wrap_content" android:layout_height="10.0dip" />
            </LinearLayout>
            <LinearLayout android:orientation="vertical" android:layout_width="0.0dip" android:layout_height="wrap_content" android:layout_weight="1.0">
                <ImageButton android:id="@id/mute_btn" android:background="#ff111111" android:paddingTop="17.0dip" android:paddingBottom="17.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:src="@drawable/ic_mute" android:contentDescription="@string/voip_call_mute_toggle_description" />
                <View android:id="@id/mute_btn_on" android:background="#b238caff" android:visibility="invisible" android:layout_width="wrap_content" android:layout_height="10.0dip" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
    <FrameLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="@id/footer" android:layout_below="@id/name">
        <ImageView android:id="@id/profile_picture" android:layout_width="fill_parent" android:layout_height="fill_parent" android:src="@drawable/ic_pic_contact_xlarge" android:scaleType="centerCrop" android:contentDescription="@string/contact_avatar_image" />
        <View android:layout_gravity="bottom" android:background="@drawable/call_photo_overlay" android:layout_width="fill_parent" android:layout_height="4.0dip" />
        <TextView android:textSize="28.0sp" android:textColor="@*android:color/white" android:gravity="center" android:layout_gravity="bottom" android:id="@id/user_hint" android:padding="12.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:shadowColor="@*android:color/black" android:shadowDx="1.0" android:shadowDy="1.0" android:shadowRadius="2.0" android:fontFamily="sans-serif-light" />
    </FrameLayout>
    <LinearLayout android:gravity="center" android:orientation="horizontal" android:id="@id/call_status_bar" android:background="#cc4abc34" android:paddingLeft="16.0dip" android:paddingTop="7.0dip" android:paddingRight="16.0dip" android:paddingBottom="7.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="@id/name" android:animateLayoutChanges="true">
        <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="6.0dip" android:src="@drawable/call_icon" android:contentDescription="@string/call_icon_content_description" />
        <TextView android:textSize="16.0sp" android:textColor="#c6ffffff" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/voip_call_label" />
        <View android:layout_width="0.0dip" android:layout_height="1.0dip" android:layout_weight="1.0" />
        <TextView android:textSize="16.0sp" android:textColor="#c6ffffff" android:id="@id/call_status" android:layout_width="wrap_content" android:layout_height="wrap_content" />
    </LinearLayout>
</RelativeLayout>

Submit a changeset to Gerrit based on another user change

I’ve submited another change to CyanogenMod project that add the “Delete application” menu to the “Developer Option” advanced menu (link to gerrit)

An user has requested an edit to a file in order to change the string displayed in the setting application, and initially I’ve thought that the change was related to my submit (but after I realized that is another CM project…)

BTW the question is: “How to amend a commit that another user has previously changed with another changeset not in my working copy?” (…a little bit obscure….)

For example, the commit status on Gerrit is:

  • Patchset 1 : author Sarbyn
  • Patchset 2 : author Sarbyn
  • Patchset 3 : author Sarbyn
  • Patchset 4 : author XYZ

My working copy is on patchset 3 and I need to submit a change about patchset 4.

Solution

The steps are:

  • git stash
  • click on the checkout-link in Download on the right patch set and copy&paste the git command in your working copy
  • git stash pop
  • Edit the file
  • git commit –amend and keep the Change-Id the same

HOWTO – Debug an AOSP – CM java application

Just a little reminder for the future

Run DDMS and select the process that you want to debug (for example, com.android.calendar).

Now, in eclipse, you can attach to the emulator or device:

  1. Run > Open Debug Dialog…
  2. Right-click “Remote Java Application”, select “New”.
  3. Pick a name, i.e. “android-debug” or anything you like.
  4. Set the “Project” to your project name.
  5. Keep the Host set to “localhost”, but change Port to 8700.
  6. Click the “Debug” button and you should be all set.

Note that port 8700 is attached to whatever process is currently selected in the DDMS console, so you need to sure that DDMS has selected the process you want to debug