b站app so层sign逆向(使用unidbg调用)
样本:aHR0cHM6Ly93d3cud2FuZG91amlhLmNvbS9hcHBzLzI4MTI5MS9oaXN0b3J5X3Y2MTgwNTAw
版本: 6.18.0
定位sign生成位置,可以用frida hook定位,我这里直接贴出位置:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/fe2b7b0d3d1a441382965f653cc7db10.png)
由此看出调用s方法,参数是map类型
unidbg调用so函数时的参数
public String call_func_s(){
TreeMap<String,String> map = new TreeMap<>();
map.put("build","6180500");
map.put("mobi_app","android");
map.put("channel","shenma069");
map.put("appkey","1d8b6e7d45233436");
map.put("s_locale","zh_CH");
DvmObject mapObj = ProxyDvmObject.createObject(vm,map);
String result = String.valueOf(dvmClass.callStaticJniMethodObject(emulator,"s(Ljava/util/SortedMap;)Lcom/bilibili/nativelibrary/SignedQuery;",mapObj).getValue());
return result;
}
需要注意的是参数是JDK标准库的类型所以需要使用ProxyDvmObject.createObject来创建对象
最终unidbg补环境代码:
package com.dta.bilibili;
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Emulator;
import com.github.unidbg.Module;
import com.github.unidbg.arm.backend.Unicorn2Factory;
import com.github.unidbg.file.FileResult;
import com.github.unidbg.file.IOResolver;
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.Map;
import java.util.TreeMap;
public class NativeLibrary extends AbstractJni implements IOResolver {
private final AndroidEmulator emulator;
private final VM vm;
private final Module module;
private final DvmClass dvmClass;
public NativeLibrary(){
emulator = AndroidEmulatorBuilder
.for32Bit()
.addBackendFactory(new Unicorn2Factory(true))
.setProcessName("tv.danmaku.bli")
.build();
Memory memory = emulator.getMemory();
memory.setLibraryResolver(new AndroidResolver(23));
vm = emulator.createDalvikVM(new File("unidbg-android/src/test/java/com/dta/bilibili/bilibli.apk"));
vm.setVerbose(true);
vm.setJni(this);
DalvikModule dm = vm.loadLibrary(new File("unidbg-android/src/test/java/com/dta/bilibili/libbili.so"),false);
module = dm.getModule();
vm.callJNI_OnLoad(emulator,module);
emulator.getBackend().registerEmuCountHook(1000);
emulator.getSyscallHandler().setVerbose(true);
emulator.getSyscallHandler().setEnableThreadDispatcher(true);
emulator.getSyscallHandler().addIOResolver(this);
dvmClass = vm.resolveClass("com/bilibili/nativelibrary/LibBili");
}
public static void main(String[] args) {
NativeLibrary nativeLibrary = new NativeLibrary();
String result = nativeLibrary.call_func_s();
System.out.println("result===>"+result);
}
public String call_func_s(){
TreeMap<String,String> map = new TreeMap<>();
map.put("build","6180500");
map.put("mobi_app","android");
map.put("channel","shenma069");
map.put("appkey","1d8b6e7d45233436");
map.put("s_locale","zh_CH");
DvmObject mapObj = ProxyDvmObject.createObject(vm,map);
String result = String.valueOf(dvmClass.callStaticJniMethodObject(emulator,"s(Ljava/util/SortedMap;)Lcom/bilibili/nativelibrary/SignedQuery;",mapObj).getValue());
return result;
}
@Override
public boolean callBooleanMethod(BaseVM vm, DvmObject<?> dvmObject, String signature, VarArg varArg) {
switch (signature){
case "java/util/Map->isEmpty()Z":{
Map map = (Map) dvmObject.getValue();
return map.isEmpty();
}
}
return super.callBooleanMethod(vm, dvmObject, signature, varArg);
}
@Override
public DvmObject<?> callObjectMethod(BaseVM vm, DvmObject<?> dvmObject, String signature, VarArg varArg) {
switch (signature){
case "java/util/Map->get(Ljava/lang/Object;)Ljava/lang/Object;":{
Map map = (Map) dvmObject.getValue();
Object key = varArg.getObjectArg(0).getValue();
return ProxyDvmObject.createObject(vm,map.get(key));
}
case "java/util/Map->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;":{
Map map = (Map) dvmObject.getValue();
Object key = varArg.getObjectArg(0).getValue();
Object value = varArg.getObjectArg(1).getValue();
return ProxyDvmObject.createObject(vm,map.put(key,value));
}
}
return super.callObjectMethod(vm, dvmObject, signature, varArg);
}
@Override
public DvmObject<?> callStaticObjectMethod(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {
switch (signature){
case "com/bilibili/nativelibrary/SignedQuery->r(Ljava/util/Map;)Ljava/lang/String;":{
Map map = (Map) varArg.getObjectArg(0).getValue();
return new StringObject(vm,SignedQuery.r(map));
}
}
return super.callStaticObjectMethod(vm, dvmClass, signature, varArg);
}
@Override
public DvmObject<?> newObject(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {
if (signature.equals("com/bilibili/nativelibrary/SignedQuery-><init>(Ljava/lang/String;Ljava/lang/String;)V")){
String arg0 = (String) varArg.getObjectArg(0).getValue();
String arg1 = (String) varArg.getObjectArg(1).getValue();
return vm.resolveClass("com/dta/bilibili/SignedQuery").newObject(new SignedQuery(arg0,arg1));
}
return super.newObject(vm, dvmClass, signature, varArg);
}
@Override
public FileResult resolve(Emulator emulator, String pathname, int oflags) {
System.out.println("pathname==>"+pathname);
return null;
}
}
注意:补环境需要SignedQuery这个类所以需要去jadx把这个类以及相关类扣下来放到unidbg中
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/836d0ed003d64ba4801b3e3c241e63c9.png)
最终运行结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/2f1bba7df0f042eeaece0fbc0e4fba38.png)