好友
阅读权限10
听众
最后登录1970-1-1
|
本帖最后由 n0elle 于 2017-2-26 00:17 编辑
现在,绝大多数apk在数据签名验证方面,采用了jni+so的方式增加安全性。
上次遇到一个app,360加固+native签名算法函数,这里不对脱壳做过多的描述。
用Charles对app进行抓包,多次抓包发现FuncTag是每个事件处理函数的一个标识,用于区分请求的模块功能。
发现有一个参数sv,应该是数据的签名字段,应该就是我们的目标。
在Android Killer打开工程,搜索40000020的16进制0x2625A14 定位到该处。
[Asm] 纯文本查看 复制代码 new-instance v0, Ljava/lang/StringBuilder;
invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V
const-string v1, "a:"
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v0
sget v1, Lcom/xxxx/xxxx/a/g;->d:I
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
move-result-object v0
const-string v1, "c"
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v0
const-string v1, ":"
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v0
.line 4636
invoke-static {}, Lcom/xxxx/xxxx/y;->d()Lcom/xxxx/xxxx/y;
move-result-object v1
invoke-virtual {v1}, Lcom/xxxx/xxxx/y;->ap()Ljava/lang/String;
move-result-object v1
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v0
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v0
/*
省略部分
*/
.line 4643
new-instance v1, Ljava/lang/StringBuilder;
invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V
const-string v2, ""
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
invoke-static {}, Lcom/xxxx/xxxx/y;->d()Lcom/xxxx/xxxx/y;
move-result-object v2
invoke-virtual {v2}, Lcom/xxxx/xxxx/y;->aB()J
move-result-wide v2
invoke-virtual {v1, v2, v3}, Ljava/lang/StringBuilder;->append(J)Ljava/lang/StringBuilder;
move-result-object v1
invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v1
invoke-static {v0, v1}, Lcom/xxxx/xxxx/utils/EncodeString;->EncodeMD5(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
move-result-object v1
在这里可以看出,sv的计算方法是把每个参数按照一定的顺序排列拼接起来,再进行EncodeMD5。
[Java] 纯文本查看 复制代码 Object localObject = "a:" + com.xxxx.xxxx.a.g.d + "c" + ":" + com.xxxx.xxxx.y.d().ap();
localObject = (String)localObject + "FuncTag" + ":" + 40000020;
localObject = (String)localObject + "ir" + ":" + paramInt2;
localObject = (String)localObject + "phoneNum" + ":" + paramString;
localObject = (String)localObject + "platform" + ":" + 2;
localObject = (String)localObject + "smsType" + ":" + paramInt1;
String str = EncodeString.EncodeMD5((String)localObject + "userId" + ":", "" + com.xxxx.xxxx.y.d().aB());
str 就是我们要的sv值,他是通过EncodeString类里的EncodeMD5方法来加密的,跟过去看看。
搜索关键字 loadLibrary ,发现在app初始化时加载了两个动态库,很明显,EncodeString类应该在encode这个动态库里面。
看了很久不是很明白他的算法到底是怎么实现的,他修改了MD5的算法,并不是一般的(数据+key)再进行原生的MD5加密。
找到了函数注册到java里的包名,这里就跟上面在java代码里面看到的包名路径是一样的。
在main下新建jniLibs目录,把上面的so库放入armeabi中
在上面jni映射过来的方法在com.xxxx.engine.utils中,这里新建一个包,包名路径相同。
写一个EncodeString类,函数申明在上面反编译出来的代码里面已经有了,直接照搬过来。
在Oncreate下面调用EncodeMD5方法,debug打印出来。
最后按照原来的参数打印出来sv。其实这样相当于是曲线救国,可以把一台手机用于签名,连接电脑进行生产工作。
但是这样的效率相对来说低一点,对模拟器的兼容也不太好。
|
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|