前言
繼續跟着龍哥的unidbg學習:SO逆向入門實戰教程五:qxs_白龍~的博客-CSDN博客
還是那句,我會借鑑龍哥的文章,以一個初學者的角度,加上自己的理解,把內容豐富一下,儘量做到不在龍哥的基礎上畫蛇添足,哈哈。感謝觀看的朋友
分析
首先,安裝app,發現龍哥給的apk包已經安裝不上,網上重新找了個最新版,安裝後,正常打開,然後,抓個包:
ok,這個sfsecurity參數就是今天的重點了。
這個app有ajm的殼,沒事,脫殼手段上,結果搞半天沒脫出來,臥槽了,而且還有 frida反調試
脫殼機也不在身邊,那沒法,直接黑盒調用,unidbg就是幹這個的。
調試
1.搭架子
運行沒問題
不過這裏,unidbg並沒有打印出來我們要的方法和地址
2.ida找地址
這時候就需要用ida找地址了,結果發現,這個so文件有點奇怪,搜不到,但是在導出表裏看得到,這就很奇怪了,根據分析,猜測是有一定的保護,也沒辦法通過F5反編譯
很快就找到這裏了,【0xAB2C】 ,注意,這裏我用的是最新版,所以地址跟龍哥博客的地址不一樣
3.黑盒調用&補環境
這裏,我選用的是32位,所以得加1,因爲我把apk解包,從lib\armeabi-v7a裏找的這個so文件,所以他一定是32位的(根據安卓開發規範)
ok,報了個環境的錯,補一補:
ok,又有新的報錯,繼續補:
ok,搞定
這裏,由於我是根據龍哥的博客,知道是哪個so方法,所以直接黑盒調用,也沒有用objection hook,它有frida反調試(objection基於frida),那就尷尬了,所以這裏沒法驗證hook值和主動調用值是否一致了。那就暫時這樣,反正值是有了
完整代碼:
package com.qxs;
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.api.Binder;
import com.github.unidbg.linux.android.dvm.api.ServiceManager;
import com.github.unidbg.memory.Memory;
import java.io.File;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
public class qxs extends AbstractJni {
private final AndroidEmulator emulator;
private final VM vm;
private final Module module;
qxs() {
// 創建模擬器實例,進程名建議依照實際進程名填寫,可以規避針對進程名的校驗
emulator = AndroidEmulatorBuilder.for32Bit().setProcessName("com.sina.oasis").build();
// 獲取模擬器的內存操作接口
final Memory memory = emulator.getMemory();
// 設置系統類庫解析
memory.setLibraryResolver(new AndroidResolver(23));
// 創建Android虛擬機,傳入APK,Unidbg可以替我們做部分簽名校驗的工作
vm = emulator.createDalvikVM(new File("unidbg-android\\src\\test\\java\\com\\qxs\\com.sfacg.apk"));
// 加載目標SO
DalvikModule dm = vm.loadLibrary(new File("unidbg-android\\src\\test\\java\\com\\qxs\\libsfdata.so"), true); // 加載so到虛擬內存
//獲取本SO模塊的句柄,後續需要用它
module = dm.getModule();
vm.setJni(this); // 設置JNI
vm.setVerbose(true); // 打印日誌
dm.callJNI_OnLoad(emulator); // 調用JNI OnLoad
}
public static void main(String[] args) {
qxs test = new qxs();
System.out.println(test.sfsecurity());
}
public String sfsecurity(){
List<Object> list = new ArrayList<>(10);
list.add(vm.getJNIEnv());
list.add(0);
DvmObject<?> context = vm.resolveClass("android/content/Context").newObject(null);
list.add(vm.addGlobalObject(context));
list.add(vm.addLocalObject(new StringObject(vm,"test")));
Number number = module.callFunction(emulator,0xAB2C+1,list.toArray());
String result = vm.getObject(number.intValue()).getValue().toString();
return result;
}
@Override
public DvmObject<?> callStaticObjectMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
switch (signature) {
case "java/util/UUID->randomUUID()Ljava/util/UUID;":
return dvmClass.newObject(UUID.randomUUID());
}
return super.callStaticObjectMethodV(vm, dvmClass, signature, vaList);
}
@Override
public DvmObject<?> callObjectMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {
switch (signature) {
case "java/util/UUID->toString()Ljava/lang/String;":
String uuid = dvmObject.getValue().toString();
return new StringObject(vm, uuid);
}
return super.callObjectMethodV(vm, dvmObject, signature, vaList);
}
}
知識點總結
本篇和上一篇感覺的挺簡單的,所以沒有啥總結的