【APP逆向42】unidbg之补环境
- 简介:当我们使用unidbg调用so文件时,如果so中的c语言调用了java代码,则我们需要补充完整
- 1.如,在某vip app中,我们在逆向时,找到了gsNav方法,它是在so文件实现的。我们正常按照unidbg操作
package com.nb.demo;
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Module;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.*;
import com.github.unidbg.linux.android.dvm.jni.ProxyDvmObject;
import com.github.unidbg.memory.Memory;
import java.io.File;
import java.util.TreeMap;
public class VIP2 extends AbstractJni {
public static AndroidEmulator emulator;
public static Memory memory;
public static VM vm;
public static Module module;
public VIP2() {
// 1.创建设备(32位或64位模拟器), 具体看so文件在哪个目录。 在armeabi-v7a就选择32位
emulator = AndroidEmulatorBuilder.for32Bit().setProcessName("com.che168.autotradercloud").build();
// 2.获取内存对象(可以操作内存)
memory = emulator.getMemory();
// 3.设置安卓sdk版本(只支持19、23)
memory.setLibraryResolver(new AndroidResolver(23));
// 4.创建虚拟机(运行安卓代码需要虚拟机,就想运行py代码需要python解释器一样)
vm = emulator.createDalvikVM(new File("unidbg-android/apks/vip/v7.83.3.apk"));
vm.setJni(this);
//vm.setVerbose(true); //执行日志
//5.加载so文件
DalvikModule dm = vm.loadLibrary(new File("unidbg-android/apks/vip/libkeyinfo.so"), false);
dm.callJNI_OnLoad(emulator);
// 6.dm代表so文件,dm.getModule()得到module对象,基于module对象可以访问so中的成员。
module = dm.getModule();
}
public void getSign() {
TreeMap<String, String> map = new TreeMap<String, String>();
map.put("app_name", "achievo_ad");
map.put("app_version", "7.83.3");
map.put("channel", "oziq7dxw:::");
map.put("device", "M2007J17C");
map.put("device_token", "2bc523e3-b5b9-3ee1-9156-af6bcd9d0f30");
map.put("manufacturer", "Xiaomi");
map.put("mf_cid", "HaUTI3uMj5Kamj1KNFU/rDuLk2GTx4yTGrQDuEgDtjmeKVraHn6r7YHRyKgntGhL");
map.put("mf_regPlat", "1");
map.put("os_version", "29");
map.put("regPlat", "1");
map.put("regid", "HaUTI3uMj5Kamj1KNFU/rDuLk2GTx4yTGrQDuEgDtjmeKVraHn6r7YHRyKgntGhL");
map.put("rom", "Dalvik/2.1.0 (Linux; U; Android 10; M2007J17C MIUI/V12.0.11.0.QJSCNXM)");
map.put("skey", "6692c461c3810ab150c9a980d0c275ec");
map.put("status", "1");
map.put("vipruid", "");
map.put("warehouse", "VIP_NH");
DvmClass ctxClass = vm.resolveClass("android/content/Context");
DvmObject<?> ctxObject = ctxClass.newObject(null); //创建对象
//找到类
DvmClass cls = vm.resolveClass("com/vip/vcsp/KeyInfo");
String method = "gsNav(Landroid/content/Context;Ljava/util/Map;Ljava/lang/String;Ljava/lang/Boolean;)Ljava/lang/String;";
// 调用方法
StringObject obj = cls.callStaticJniMethodObject(
emulator,
method,
ctxObject,
ProxyDvmObject.createObject(vm, map),
new StringObject(vm, ""),
false
);
String dataString = obj.getValue();
System.out.println(dataString);
}
public static void main(String[] args) {
VIP2 obj = new VIP2();
obj.getSign();
}
}
-
2.执行以上代码,我们发现会报错,如下:
![]()
-
3.补环境,根据报错一个一个补充
![]()
- 3.1:补充前
![]()
- 3.2:补充后
![]()
- 3.1:补充前
-
4.按照上面的方法,逐一补充完,最终完整代码
package com.nb.demo;
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Module;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.*;
import com.github.unidbg.linux.android.dvm.jni.ProxyDvmObject;
import com.github.unidbg.memory.Memory;
import java.io.File;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class VIP2 extends AbstractJni {
public static AndroidEmulator emulator;
public static Memory memory;
public static VM vm;
public static Module module;
public VIP2() {
// 1.创建设备(32位或64位模拟器), 具体看so文件在哪个目录。 在armeabi-v7a就选择32位
emulator = AndroidEmulatorBuilder.for32Bit().setProcessName("com.che168.autotradercloud").build();
// 2.获取内存对象(可以操作内存)
memory = emulator.getMemory();
// 3.设置安卓sdk版本(只支持19、23)
memory.setLibraryResolver(new AndroidResolver(23));
// 4.创建虚拟机(运行安卓代码需要虚拟机,就想运行py代码需要python解释器一样)
vm = emulator.createDalvikVM(new File("unidbg-android/apks/vip/v7.83.3.apk"));
vm.setJni(this);
//vm.setVerbose(true); //执行日志
//5.加载so文件
DalvikModule dm = vm.loadLibrary(new File("unidbg-android/apks/vip/libkeyinfo.so"), false);
dm.callJNI_OnLoad(emulator);
// 6.dm代表so文件,dm.getModule()得到module对象,基于module对象可以访问so中的成员。
module = dm.getModule();
}
public void getSign() {
TreeMap<String, String> map = new TreeMap<String, String>();
map.put("app_name", "achievo_ad");
map.put("app_version", "7.83.3");
map.put("channel", "oziq7dxw:::");
map.put("device", "M2007J17C");
map.put("device_token", "2bc523e3-b5b9-3ee1-9156-af6bcd9d0f30");
map.put("manufacturer", "Xiaomi");
map.put("mf_cid", "HaUTI3uMj5Kamj1KNFU/rDuLk2GTx4yTGrQDuEgDtjmeKVraHn6r7YHRyKgntGhL");
map.put("mf_regPlat", "1");
map.put("os_version", "29");
map.put("regPlat", "1");
map.put("regid", "HaUTI3uMj5Kamj1KNFU/rDuLk2GTx4yTGrQDuEgDtjmeKVraHn6r7YHRyKgntGhL");
map.put("rom", "Dalvik/2.1.0 (Linux; U; Android 10; M2007J17C MIUI/V12.0.11.0.QJSCNXM)");
map.put("skey", "6692c461c3810ab150c9a980d0c275ec");
map.put("status", "1");
map.put("vipruid", "");
map.put("warehouse", "VIP_NH");
DvmClass ctxClass = vm.resolveClass("android/content/Context");
DvmObject<?> ctxObject = ctxClass.newObject(null); //创建对象
//找到类
DvmClass cls = vm.resolveClass("com/vip/vcsp/KeyInfo");
String method = "gsNav(Landroid/content/Context;Ljava/util/Map;Ljava/lang/String;Ljava/lang/Boolean;)Ljava/lang/String;";
// 调用方法
StringObject obj = cls.callStaticJniMethodObject(
emulator,
method,
ctxObject,
ProxyDvmObject.createObject(vm, map),
new StringObject(vm, ""),
false
);
String dataString = obj.getValue();
System.out.println(dataString);
}
public static void main(String[] args) {
VIP2 obj = new VIP2();
obj.getSign();
}
@Override
public DvmObject<?> callObjectMethod(BaseVM vm, DvmObject<?> dvmObject, String signature, VarArg varArg) {
// 类型 方法 签名
if(signature.equals("java/util/TreeMap->entrySet()Ljava/util/Set;")){
TreeMap map = (TreeMap) dvmObject.getValue();
Set set = map.entrySet();
return vm.resolveClass("java/util/Set").newObject(set);
}
if(signature.equals("java/util/Set->iterator()Ljava/util/Iterator;")){
Set set = (Set) dvmObject.getValue();
Iterator it = set.iterator();
return vm.resolveClass("java/util/Iterator").newObject(it);
}
if(signature.equals("java/util/Iterator->next()Ljava/lang/Object;")){
Iterator it = (Iterator) dvmObject.getValue();
Object obj = it.next(); // Object是泛型,要用ProxyDvmObject.createObject处理下
return ProxyDvmObject.createObject(vm,obj);
}
if(signature.equals("java/util/Map$Entry->getKey()Ljava/lang/Object;")){
Map.Entry et = (Map.Entry) dvmObject.getValue();
return ProxyDvmObject.createObject(vm,et.getKey());
}
if(signature.equals("java/util/Map$Entry->getValue()Ljava/lang/Object;")){
Map.Entry v = (Map.Entry) dvmObject.getValue();
return ProxyDvmObject.createObject(vm,v.getValue());
}
return super.callObjectMethod(vm, dvmObject, signature, varArg);
}
@Override
public boolean callBooleanMethod(BaseVM vm, DvmObject<?> dvmObject, String signature, VarArg varArg) {
if(signature.equals("java/util/Iterator->hasNext()Z")){
Iterator it = (Iterator) dvmObject.getValue();
return it.hasNext(); //布尔值,直接返回即可
}
return super.callBooleanMethod(vm, dvmObject, signature, varArg);
}
}
- 5.至此,环境补充结束,得到结果
![]()






浙公网安备 33010602011771号