solotimes
11/4/2015 - 9:05 AM

用命令行调用android虚拟机里native so文件JNI接口

用命令行调用android虚拟机里native so文件JNI接口

用命令行调用android虚拟机里so库文件JNI接口
可用于破解用native代码签名接口调用的手机应用, 而无需反编译so代码

参考: https://davanum.wordpress.com/2007/12/04/command-line-java-on-dalvikvm/

1.com/app/safe目录下放JNI声明文件sign.java(对应于从要破解的手机应用apk内lib文件夹内复制出的sign.so文件):
package com.app.safe;
public class sign
{
    static
    {
        System.load("/data/libs/sign.so");
    }
    public static native byte[] getSign();
}

2.命令行执行的java代码get.java:
package mycmd;
import com.app.safe.sign;
public class get
{
    public static void main(String[] args)
    {
        //System.out.println(System.getProperty("java.library.path"));
        System.out.println(String.valueOf(sign.getSign()));
    }
}

3.编译:
javac -d . -g get.java

4.压缩:
jar -cvf Temp.jar *

5.转换为dex:
/var/lib/android_sdk/build-tools/23.0.1/dx --dex --output=classes.dex Temp.jar

6.再放到jar:
/var/lib/android_sdk/build-tools/23.0.1/aapt add CmdLine.jar classes.dex

7.将jar放到android虚拟机内(虚拟机内需要先su;setprop service.adb.tcp.port 5555;stop adbd;start adbd):
adb connect 127.0.0.1      #后面虚拟机安装的段落讲到modifyvm端口映射来实现上行的setprop
adb push CmdLine.jar /sdcard/

8.将从要破解的手机应用apk内lib文件夹内的so文件复制到android虚拟机的/data目录下(/sdcard下无法load):
adb push sign.so /sdcard/
adb shell
su
mkdir /data/libs
cp /sdcard/sign.so /data/libs/sign.so
exit

9.执行命令行获得接口签名(ubuntu服务器直接apt-get install android-tools-adb, 而centos则要yum install android-tools(需先yum install epel-release)):
adb shell /system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar mycmd.get

注意so代码反编译成c后可能会看到用context.getPackageName()来判断自己是在apk内而不是在jar内跑, 需要对着反汇编代码用hex编辑器修改跳过,
比如判断条件if x!=0对应arm汇编指令cbz ..., 在hex里看是b1, 而if x==0对应arm汇编指令cbnz, 在hex里是b9, 修改起来只要改b1为b9或b9为b1, 非常简单
还比如判断条件if x==0对应arm汇编指令cmp x, 0再beq ..., 简单把cmp x, 0改成cmp x, 1逻辑就反过来了

安装安卓虚拟机:
sudo yum install VirtualBox-5.0-5.0.8_103449_el6-1.x86_64.rpm
VBoxManage import /home/user1/genymotion_vbox86p_4.1.1_150610_092200.ova
VBoxManage list vms
VBoxManage startvm --type headless <VM name>
VBoxManage showvminfo <VM name> | grep Settings    #看到NIC后面数字是多少下面一行指令的natpf后数字就是多少
VBoxManage modifyvm ""genymotion_vbox86p_4.1.1_150610_092200"" --natpf2 adb,tcp,*,5555,*,5555
#还要把Genymotion-ARM-Translation_v1.1.zip(http://forum.xda-developers.com/showthread.php?t=2528952)里的/system/lib/arm, /system/lib/libdvm_houdini.so, /system/lib/libhoudini.so 搞到虚拟机里
#如果要把/home/<user1>/VirtualBox VMs/<VM names>/(内含*.vmdk及*.vbox)克隆到别的机器, 复制后需要执行:
VBoxManage registervm "/home/<user1>/VirtualBox VMs/<VM name>/*.vbox"
#实际是记到了/home/<user1>/.config/VirtualBox/VirtualBox.xml