今天就来聊聊 jd app sign 的 so 加密
跟着大佬走, 逆向不迷路
Unidbg模拟执行大厂so实操教程(一) 先把框架搭起来
Unidbg模拟执行大厂so实操教程(二)
借鸡生蛋之SandHook的使用(一)
借鸡生蛋之某电商App签名so的使用(二)
借鸡生蛋之某电商App签名so的使用(三)
这几篇文章看完后,大概就清楚了, 后面就开始直接撸代码
跟着大佬的步骤走,先把环境搭建起来
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.LibraryResolver;
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.AbstractJni;
import com.github.unidbg.linux.android.dvm.DalvikModule;
import com.github.unidbg.linux.android.dvm.DvmClass;
import com.github.unidbg.linux.android.dvm.VM;
import com.github.unidbg.memory.Memory;
import java.io.File;
import java.io.IOException;
public class JingDong extends AbstractJni {
private final AndroidEmulator emulator;
private final VM vm;
private Module module;
private DvmClass bitMapKitUtils;
// jd apk 文件路径
public String apkPath = "";
// jd apk so 文件路径
public String soPath = "";
private static LibraryResolver createLibraryResolver() {
return new AndroidResolver(23);
}
private static AndroidEmulator createARMEmulator() {
return AndroidEmulatorBuilder.for32Bit().setProcessName("").build();
}
public JingDong() {
emulator = createARMEmulator();
final Memory memory = emulator.getMemory();
memory.setLibraryResolver(createLibraryResolver());
vm = emulator.createDalvikVM(new File(apkPath));
vm.setVerbose(true);
DalvikModule dm = vm.loadLibrary(new File(soPath), false);
vm.setJni(this);
dm.callJNI_OnLoad(emulator);
module = dm.getModule();
}
public static void main(String[] args) throws IOException {
JingDong jd = new JingDong();
jd.destroy();
}
private void destroy() throws IOException {
emulator.close();
}
}
这里运行报错了,错误很明显,缺少环境,我们补上就行,在代码里加上下面这段代码

@Override
public DvmObject<?> getStaticObjectField(BaseVM vm, DvmClass dvmClass, String signature) {
switch (signature) {
case "com/jingdong/common/utils/BitmapkitUtils->a:Landroid/app/Application;":
return vm.resolveClass("android/app/Application",
vm.resolveClass("android/content/ContextWrapper",
vm.resolveClass("android/content/Context"))).newObject(null);
}
return super.getStaticObjectField(vm, dvmClass, signature);
}
再次运行,这次一路顺畅,JNI 调用的函数也一起 打印出来了

继续跟着大佬的节奏走,开始调用 so 函数
分析过 android apk 文件的小伙伴应该都知道,最终是调用 getSignFromJni 函数获取 sign 加密的, 直接上代码
public void runJni() {
DvmClass Context = vm.resolveClass("android/content/Context");
bitMapKitUtils = vm.resolveClass("com/jingdong/common/utils/BitmapkitUtils");
DvmObject<?> strRc = bitMapKitUtils.callStaticJniMethodObject(
emulator,
"getSignFromJni()(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;" +
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
// Context 对象
vm.addLocalObject(null),
// functionId
vm.addLocalObject(new StringObject(vm, "msgEntranceV710")),
// body string
vm.addLocalObject(new StringObject(vm, "{\"flush\":\"0\"}")),
// uuid
vm.addLocalObject(new StringObject(vm, "")),
vm.addLocalObject(new StringObject(vm, "android")),
vm.addLocalObject(new StringObject(vm, "9.2.2")));
System.out.println(strRc.getValue());
}
public static void main(String[] args) throws IOException {
JingDong jd = new JingDong();
jd.runJni();
jd.destroy();
}

加上 runJni 函数之后,继续跑起来(具体参数,自行抓包获取)
在运行的过程中会遇到很很多错误,大多都是缺少环境的问题,补一下就 OK了




通过上面的这些图片可以看到,都是一些常常见的对象,
不过当遇到下图问题的时候就有点麻烦了,这个环境我也不知道怎么补,不过前面说到的大佬文章里有说过解决方案,就是去修改 so 文件的汇编代码
这里这贴一下链接: 借鸡生蛋之某电商App签名so的使用(三)
根据文章里说的步骤修改一下最后在保存就OK了

难点主要在于
so文件汇编代码的patch不过已经有大佬踩过坑了,我们跟着大佬的路走就 OK,后面环境全部补完之后,也就可以运行出sign了

原文链接,博主个人站点:http://www.qinless.com/137
