unidbg(2)

参考

Unidbg 的基本使用(二)

hook

frida

进入jadx

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
package com.sina.weibo.security;

import android.util.Base64;
import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;

/* loaded from: classes.dex */
public class WeicoSecurityUtils {
private static final String KEY_ALGORITHM = "RSA";
private static final String KEY_CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";
private static final int MAX_DECRYPT_BLOCK = 128;
private static final int MAX_ENCRYPT_BLOCK = 117;
private static String publicKeyInner = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDWcQcgj60fU8fFev9RlvFPg0GcRgHyGFTN9ytE\nLujvfCwGt7n54Q9+k1rDDo+sRQeYdTwA7ZMS8n1RHjZATgmHw9rBBzk/cHXAVIgrJrZ5txDdW1i4\n8ZxEarcdSrmlk9ZFSsvGXE8/0fZYHM0mr4WaIh2y9E0CNkd0rU9VKAR9RQIDAQAB";
private static final String publicKeyString = "iMxVDGf9f5Z3P3NsFac7tM7SC6DZDJY+H/vXc+xv3HlT2E/LUzWf5fct2P0VauekLzNAaNsH93SZ\n2Z3jUc/0x81FLThPwI8cexCuRT7P1bdnmcwhjZmW3Lc1FCu2K6iBuVQ9I51TR9eTU2lNcq4AW8WV\nEWtwIj6EpLFzQ3qOm3AY4UNgcGrNYYBbF+SiUkchdXbxYRBNFkguDiayaJzMC/5WmTrEnQ0xXwmy\nA2lWpZ6+sUlyDRU/HvPh5Oto0xpuLc6bIjfl0b+PSjxh5e/7/4jXoYoUfdm3r2FtPKJtQ2NeKnsp\nOCdk6HNULtk5WSnkBKjufQqoZblvdrEiixnogQ";
String source = KEY_CIPHER_ALGORITHM;

public static String securityPsd(String password) {
byte[] data = password.getBytes();
try {
String realPublicKeyString = decode(publicKeyString);
byte[] encodedData = encryptByPublicKey(data, realPublicKeyString);
return new String(Base64.encode(encodedData, 2));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

private static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
byte[] cache;
byte[] keyBytes = Base64.decode(publicKey.getBytes(), 2);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(KEY_CIPHER_ALGORITHM);
cipher.init(1, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
int i = 0;
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}

public static String decode(String encryptedStr) throws Exception {
byte[] decodedData = decryptByPublicKey(Base64.decode(encryptedStr, 1), publicKeyInner);
return new String(decodedData);
}

public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {
byte[] cache;
byte[] keyBytes = Base64.decode(publicKey, 1);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(KEY_CIPHER_ALGORITHM);
cipher.init(2, publicK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
int i = 0;
while (inputLen - offSet > 0) {
if (inputLen - offSet > 128) {
cache = cipher.doFinal(encryptedData, offSet, 128);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * 128;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
}

先尝试frida的方法

1
2
3
4
5
6
7
8
9
10
Java.perform(function() {
let WeiboSecurityUtils = Java.use("com.sina.weibo.security.WeiboSecurityUtils");
let current_application = Java.use('android.app.ActivityThread').currentApplication();
let arg1 = current_application.getApplicationContext();
let arg2 = "hello world";
let arg3 = "123456";
let ret = WeiboSecurityUtils.$new().calculateS(arg1, arg2, arg3);
console.log("ret:"+ret);
})

这里使用的是frida附加进程来进行一个主动调用

1
2
3
4
[AOSP on Oriole::com.weico.international ]-> ret:d74a75bb
ret:d74a75bb


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
31
32
33
34
35
36
37
38
39
package com.unidbgtest2;

import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.arm.backend.Unicorn2Factory;
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;

public class WeiBo extends AbstractJni {
private final AndroidEmulator emulator;
private final DvmClass WeiboSecurityUtils;
private final VM vm;

public WeiBo() {
emulator = AndroidEmulatorBuilder
.for32Bit()
.addBackendFactory(new Unicorn2Factory(true))
.setProcessName("com.weico.international")
.build();
Memory memory = emulator.getMemory();
memory.setLibraryResolver(new AndroidResolver(23));
vm = emulator.createDalvikVM(new File("F:\\repwn\\unidbg-master\\unidbg-master\\unidbg-android\\src\\test\\java\\com\\unidbgtest2\\sinaInternational.apk"));
vm.setJni(this);
vm.setVerbose(true);
DalvikModule dm = vm.loadLibrary("utility", true);
WeiboSecurityUtils = vm.resolveClass("com/sina/weibo/security/WeiboSecurityUtils");
dm.callJNI_OnLoad(emulator);
}

public static void main(String[] args) {
WeiBo wb = new WeiBo();
}
}

这里选择32位是以为在lib文件夹里面他就写了一个armeabi

创建虚拟机

1
vm = emulator.createDalvikVM(new File("F:\\repwn\\unidbg-master\\unidbg-master\\unidbg-android\\src\\test\\java\\com\\unidbgtest2\\sinaInternational.apk"));

导入so 获取对应的

两个重载方法

1
2
3
4
5
6
7
//参数一: 动态库或可执行ELF文件
//参数二: 是否必须执行 init_proc、init_array 这些初始化函数
DalvikModule loadLibrary(File elfFile, boolean forceCallInit);

//参数一:动态库或可执行ELF的文件名
//参数二: 是否必须执行 init_proc、init_array 这些初始化函数
DalvikModule loadLibrary(String libname, boolean forceCallInit);
1
2
3
DalvikModule dm = vm.loadLibrary("F:\\repwn\\unidbg-master\\unidbg-master\\unidbg-android\\src\\test\\java\\com\\unidbgtest2\\armeabi\\libutility.so", true);
WeiboSecurityUtils = vm.resolveClass("com/sina/weibo/security/WeiboSecurityUtils");
dm.callJNI_OnLoad(emulator);