bilibili - unidbg
http://www.zhuoyue360.com/crack/87.html
老色批想抓哔哩哔哩的全站数据,通过人工智能自动找出美女 (:色
咱们想抓它一个个人信息.
抓包分析
1. android 7.0+ 证书配置
参考这篇文章.
http://www.zhuoyue360.com/crack/60.html
2.抓包.
证书设置好, postern配置好。胸弟们就可以愉快的进行抓包啦~
是它,是它,就是它! 我们的小哪吒,小ki! 轻轻松松的就抓包成功,没有任何的对抗。就很巴适!
3. Sign分析
jadx反编译
经过自己不断的搜搜搜下(网上文章的思路下),至于找到了关键的位置. s
想上找可以找到载入的so文件
static {
c.c("bili");
}
4. IDA分析.
查看导出函数,那可是干干净净的~,那么我们就要看动态注册的函数了.
使用yang神的hook_RegisterNatives.js .即可拿到地址.
s的偏移是0x741d ,过去看看~
简单的跟了一下,发现有轻微的混淆。 先不理。 祭神器,unidbg
Unidbg
从Part2已知, 我们的s 大宝贝入口是0x741d .
把Unidbg 基础代码写好,运行一下,报错了。
@Override
public boolean callBooleanMethod(BaseVM vm, DvmObject<?> dvmObject, String signature, VarArg varArg) {
switch (signature){
case "java/util/Map->isEmpty()Z":
TreeMap<String, String> treeMap = (TreeMap<String, String>)dvmObject.getValue();
return treeMap.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;":
StringObject keyObject = varArg.getObjectArg(0);
String key = keyObject.getValue();
TreeMap<String, String> treeMap = (TreeMap<String, String>)dvmObject.getValue();
String value = treeMap.get(key);
return new StringObject(vm,value);
}
return super.callObjectMethod(vm, dvmObject, signature, varArg);
}
这里把SignedQuery 这个类都拿过来.稍稍修改一番~
package com.danmaku;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
public final class SignedQuery {
public static final String KEY_VALUE_DELIMITER = "=";
public static final String FIELD_DELIMITER = "&";
private static final char[] a = "0123456789ABCDEF".toCharArray();
public final String rawParams;
public final String sign;
public SignedQuery(String str, String str2) {
this.rawParams = str;
this.sign = str2;
}
private static boolean a(char c2, String str) {
return (c2 >= 'A' && c2 <= 'Z') || (c2 >= 'a' && c2 <= 'z') || !((c2 < '0' || c2 > '9') && "-_.~".indexOf(c2) == -1 && (str == null || str.indexOf(c2) == -1));
}
static String b(String str) {
return c(str, null);
}
static String c(String str, String str2) {
StringBuilder sb = null;
if (str == null) {
return null;
}
int length = str.length();
int i = 0;
while (i < length) {
int i2 = i;
while (i2 < length && a(str.charAt(i2), str2)) {
i2++;
}
if (i2 != length) {
if (sb == null) {
sb = new StringBuilder();
}
if (i2 > i) {
sb.append((CharSequence) str, i, i2);
}
i = i2 + 1;
while (i < length && !a(str.charAt(i), str2)) {
i++;
}
try {
byte[] bytes = str.substring(i2, i).getBytes("UTF-8");
int length2 = bytes.length;
for (int i3 = 0; i3 < length2; i3++) {
sb.append('%');
char[] cArr = a;
sb.append(cArr[(bytes[i3] & 240) >> 4]);
sb.append(cArr[bytes[i3] & 15]);
}
} catch (UnsupportedEncodingException e2) {
throw new AssertionError(e2);
}
} else if (i == 0) {
return str;
} else {
sb.append((CharSequence) str, i, length);
return sb.toString();
}
}
return sb == null ? str : sb.toString();
}
static String r(Map<String, String> map) {
if (!(map instanceof SortedMap)) {
map = new TreeMap(map);
}
StringBuilder sb = new StringBuilder(256);
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
if (!key.isEmpty()) {
sb.append(b(key));
sb.append(KEY_VALUE_DELIMITER);
String value = entry.getValue();
sb.append(value == null ? "" : b(value));
sb.append(FIELD_DELIMITER);
}
}
int length = sb.length();
if (length > 0) {
sb.deleteCharAt(length - 1);
}
if (length == 0) {
return null;
}
return sb.toString();
}
public String toString() {
String str = this.rawParams;
if (str == null) {
return "";
}
if (this.sign == null) {
return str;
}
return this.rawParams + "&sign=" + this.sign;
}
}
然后再补环境
@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;":
DvmObject<?> mapObject = varArg.getObjectArg(0);
TreeMap<String, String> mymap = (TreeMap<String, String>) mapObject.getValue();
String value = SignedQuery.r(mymap);
return new StringObject(vm, value);
}
return super.callStaticObjectMethod(vm, dvmClass, signature, varArg);
}
@Override
public DvmObject<?> newObject(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {
switch (signature){
case "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/bilibili/nativelibrary/SignedQuery").newObject(new SignedQuery(arg0, arg1));
}
return super.newObject(vm, dvmClass, signature, varArg);
}
突然,unidbg不报错了,跑出来了hhhhh.
这就是我们要的东西.
诶,真香~
算法还原[待更新]
|