JDApp_sign算法2

JDApp_sign算法2

sign计算代码在libjdbitmapkit.so中,函数名:Java_com_jingdong_common_utils_BitmapkitUtils_getSignFromJni

尝试使用unidbg模拟执行,出现如下报错:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[10:06:47 642]  WARN [com.github.unidbg.linux.android.dvm.jni.ProxyJni] (ProxyJni:698) - getStaticObjectField
java.lang.ClassNotFoundException: com.jingdong.common.utils.BitmapkitUtils
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at com.github.unidbg.linux.android.dvm.jni.ProxyClassLoader.loadClass(ProxyClassLoader.java:22)
at com.github.unidbg.linux.android.dvm.jni.ProxyJni.getStaticObjectField(ProxyJni.java:693)
at com.github.unidbg.linux.android.dvm.DvmField.getStaticObjectField(DvmField.java:39)
at com.github.unidbg.linux.android.dvm.DalvikVM$142.handle(DalvikVM.java:2268)
at com.github.unidbg.linux.ARM32SyscallHandler.hook(ARM32SyscallHandler.java:132)
at com.github.unidbg.arm.backend.UnicornBackend$11.hook(UnicornBackend.java:345)
at unicorn.Unicorn$NewHook.onInterrupt(Unicorn.java:128)
at unicorn.Unicorn.emu_start(Native Method)
at com.github.unidbg.arm.backend.UnicornBackend.emu_start(UnicornBackend.java:376)
at com.github.unidbg.AbstractEmulator.emulate(AbstractEmulator.java:386)
at com.github.unidbg.thread.Function32.run(Function32.java:39)
at com.github.unidbg.thread.MainTask.dispatch(MainTask.java:19)
at com.github.unidbg.thread.UniThreadDispatcher.run(UniThreadDispatcher.java:172)
at com.github.unidbg.thread.UniThreadDispatcher.runMainForResult(UniThreadDispatcher.java:96)
at com.github.unidbg.AbstractEmulator.runMainForResult(AbstractEmulator.java:346)
at com.github.unidbg.arm.AbstractARMEmulator.eFunc(AbstractARMEmulator.java:229)
at com.github.unidbg.Module.emulateFunction(Module.java:159)
at com.github.unidbg.linux.LinuxModule.callFunction(LinuxModule.java:257)
at com.github.unidbg.linux.LinuxSymbol.call(LinuxSymbol.java:27)
at com.github.unidbg.linux.android.dvm.DalvikModule.callJNI_OnLoad(DalvikModule.java:33)
at com.jingdong.mall.app.SignUtil.<init>(SignUtil.java:47)
at com.jingdong.mall.app.SignUtil.main(SignUtil.java:111)
[10:06:47 646] WARN [com.github.unidbg.linux.ARM32SyscallHandler] (ARM32SyscallHandler:530) - handleInterrupt intno=2, NR=-128688, svcNumber=0x18d, PC=unidbg@0xfffe0964, LR=RX@0x400037ad[libjdbitmapkit.so]0x37ad, syscall=null
java.lang.UnsupportedOperationException: com/jingdong/common/utils/BitmapkitUtils->a:Landroid/app/Application;
...

这是因为加载so文件时,会执行JNI_OnLoad函数,这个函数会执行一些疑似签名检查的代码(int __fastcall check_status(_JNIEnv *a1)),要么需要在unidbg中构造出环境,要么需要patch这些代码。

image-20220113101121444

PATCH前:

image-20220113101246146

PATCH后:

image-20220113101307115

image-20220113101335837

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package com.jingdong.mall.app;

import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Emulator;
import com.github.unidbg.arm.context.RegisterContext;
import com.github.unidbg.hook.hookzz.HookEntryInfo;
import com.github.unidbg.hook.hookzz.HookZz;
import com.github.unidbg.hook.hookzz.IHookZz;
import com.github.unidbg.hook.hookzz.WrapCallback;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.DalvikModule;
import com.github.unidbg.linux.android.dvm.DvmClass;
import com.github.unidbg.linux.android.dvm.StringObject;
import com.github.unidbg.linux.android.dvm.VM;
import com.github.unidbg.linux.android.dvm.jni.ProxyClassFactory;
import com.github.unidbg.linux.android.dvm.jni.ProxyDvmObject;
import com.github.unidbg.memory.Memory;
import com.github.unidbg.utils.Inspector;
import com.sun.jna.Pointer;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class SignUtil {

private final AndroidEmulator emulator;

private final DvmClass BitmapkitUtils;
private final VM vm;

public SignUtil() {
emulator = AndroidEmulatorBuilder.for32Bit()
.setProcessName("com.jingdong.mall.app")
.build();
Memory memory = emulator.getMemory();
memory.setLibraryResolver(new AndroidResolver(23));
vm = emulator.createDalvikVM();
vm.setDvmClassFactory(new ProxyClassFactory());
vm.setVerbose(false);
DalvikModule dm = vm.loadLibrary(new File("unidbg-android/src/test/resources/example_binaries/armeabi-v7a/test.so"), false);
BitmapkitUtils = vm.resolveClass("com/jingdong/common/utils/BitmapkitUtils");
dm.callJNI_OnLoad(emulator);

IHookZz hookZz = HookZz.getInstance(emulator);
System.out.println(String.format("0x%x",dm.getModule().findSymbolByName("Java_com_jingdong_common_utils_BitmapkitUtils_getSignFromJni").getAddress()));


// emulator.traceCode(dm.getModule().base+0x0012F68, dm.getModule().base+0x0012FA4);
hookZz.wrap(dm.getModule().base+0x10DE5,new WrapCallback<RegisterContext>() {

@Override
public void preCall(Emulator<?> emulator, RegisterContext ctx, HookEntryInfo info) {
Pointer pointer = ctx.getPointerArg(2);
int length = ctx.getIntArg(3);
byte[] key = pointer.getByteArray(0, length);
Inspector.inspect(key, "");
System.out.println(length);

}
});

hookZz.wrap(dm.getModule().base+0x18b9,new WrapCallback<RegisterContext>() {
@Override
public void preCall(Emulator<?> emulator, RegisterContext ctx, HookEntryInfo info) {
Pointer pointer = ctx.getPointerArg(1);
int length = ctx.getIntArg(2);
byte[] key = pointer.getByteArray(0, length);
Inspector.inspect(key, "calc");
System.out.println();
}
});

hookZz.wrap(dm.getModule().base+0x227d,new WrapCallback<RegisterContext>() {

@Override
public void preCall(Emulator<?> emulator, RegisterContext ctx, HookEntryInfo info) {
Pointer pointer = ctx.getPointerArg(0);
int length = ctx.getIntArg(1);
byte[] key = pointer.getByteArray(0, length);
Inspector.inspect(key, "get_md5_input");
System.out.println();
}
});
}

public void destroy() throws IOException {
emulator.close();
}


public String getSignFromJni(Object p1, String p2, String p3, String p4,String p5,String p6) {
String methodSign = "getSignFromJni(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;";
StringObject obj = BitmapkitUtils.callStaticJniMethodObject(emulator, methodSign, p1, p2, p3, p4,p5,p6);
return obj.getValue();
}



public static void main(String[] args) throws Exception {
SignUtil signUtil = new SignUtil();
String sign = signUtil.getSignFromJni(null, "1","2","3","4","5");
System.out.println(sign);
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

>-----------------------------------------------------------------------------<
[10:16:22 004], md5=faf10be6aca7e3274e186ff287c78ef6, hex=66756e6374696f6e49643d3126626f64793d3226757569643d3326636c69656e743d3426636c69656e7456657273696f6e3d352673743d313037393537382673763d313131
size: 69
0000: 66 75 6E 63 74 69 6F 6E 49 64 3D 31 26 62 6F 64 functionId=1&bod
0010: 79 3D 32 26 75 75 69 64 3D 33 26 63 6C 69 65 6E y=2&uuid=3&clien
0020: 74 3D 34 26 63 6C 69 65 6E 74 56 65 72 73 69 6F t=4&clientVersio
0030: 6E 3D 35 26 73 74 3D 31 30 37 39 35 37 38 26 73 n=5&st=1079578&s
0040: 76 3D 31 31 31 v=111
^-----------------------------------------------------------------------------^
69

>-----------------------------------------------------------------------------<
[10:16:22 011]calc, md5=96757b66478e419f83237a4d7242f4a3, hex=afcb2afb1f349bed06555aa934c4460ea293febe1830a5ebfa244fdb7ad37c08bd93f0be062fa5e42b657fdd40d540099793f1be163769b0ed2846ad05a2391dbf93fd89d4
size: 69
0000: AF CB 2A FB 1F 34 9B ED 06 55 5A A9 34 C4 46 0E ..*..4...UZ.4.F.
0010: A2 93 FE BE 18 30 A5 EB FA 24 4F DB 7A D3 7C 08 .....0...$O.z.|.
0020: BD 93 F0 BE 06 2F A5 E4 2B 65 7F DD 40 D5 40 09 ...../..+e..@.@.
0030: 97 93 F1 BE 16 37 69 B0 ED 28 46 AD 05 A2 39 1D .....7i..(F...9.
0040: BF 93 FD 89 D4 .....
^-----------------------------------------------------------------------------^


>-----------------------------------------------------------------------------<
[10:16:22 012]get_md5_input, md5=d7895d8bb0affd5aa1ce888b1cbd3b12, hex=723873712b7838306d2b3047565671704e4d524744714b542f7234594d4b58722b69525032337254664169396b2f432b42692b6c3543746c663931413155414a6c35507876685933616244744b4561744261493548622b542f596e55
size: 92
0000: 72 38 73 71 2B 78 38 30 6D 2B 30 47 56 56 71 70 r8sq+x80m+0GVVqp
0010: 4E 4D 52 47 44 71 4B 54 2F 72 34 59 4D 4B 58 72 NMRGDqKT/r4YMKXr
0020: 2B 69 52 50 32 33 72 54 66 41 69 39 6B 2F 43 2B +iRP23rTfAi9k/C+
0030: 42 69 2B 6C 35 43 74 6C 66 39 31 41 31 55 41 4A Bi+l5Ctlf91A1UAJ
0040: 6C 35 50 78 76 68 59 33 61 62 44 74 4B 45 61 74 l5PxvhY3abDtKEat
0050: 42 61 49 35 48 62 2B 54 2F 59 6E 55 BaI5Hb+T/YnU
^-----------------------------------------------------------------------------^

st=1079578&sign=d7895d8bb0affd5aa1ce888b1cbd3b12&sv=111

Process finished with exit code 0

image-20220113101757283