下面跟踪mo10123h() mo10126i() mo10130j() mo10109e()4个函数,分析这4个函数都是数据库查询函数,其中最重要的一句就是数据库查询,以mo10109e()为例,
Cursor query = this.f9841b.query(true, "config", new String[]{"key", "value"}, "key=?", new String[]{this.f9842d.mo10260V()}, null, null, null, null);
从表config中提取key=this.f9842d.mo10260V()的value值,而f9842d为 C3830e的实例
private C3830e f9842d = new C3830e(m13872an());
对应方法分别为mo10123h :mo10268d() mo10126i: mo10266b() mo10130j: mo10267c() mo10109e: mo10260V()
hook com.netease.mkey.core.e类实例的4个方法
找到这4个key,寻找数据库中对应的value
adb pull出数据库 目录/data/data/com.netease.mkey/databases/ekey
很容易找到3个函数产生的key对应的value
这些key和value对应的数据库如何生成呢,以mo10268d 为例,他在mo10107d函数中通过contentvalue 将参数j update进入数据库
ActivationActivity.this.f9569d.mo10107d(bundle.getLong(C3806c.m14238j()));
我们再看mo10260V()在 mo10078a(long j)函数中通过contentvalue 将参数j update进入数据库 ,而参数j为 f9848a,下面我们分析f9848a如何生成
f9848a首先通过mo10109e从数据库中查询生成初始值,然后通过m14035a(long j)函数更新,,在函数onOtpRefreshClick中通过这句代码OtpLib.m14035a(this.f10441j.longValue()),简单观察我们可以猜想,f9848a存储的是上一次的时间戳e,保证当前e>上次运行存储的e,不然时间不就倒回去了嘛,
而我们每次点击刷新触发onOtpRefreshClick,都会将e提前到下一个30s的e,otp也将是下一个,但我们不能无限制刷新,还记得将军令有个冷却吗,就是在这个函数中实现的,刷新时间必须小于f9851d,根据经验大概最多同时出现4个otp,我们就不hook寻找他的值了
str就是你的序列号,他是怎么生成的呢
这里就明白了 bArr是密钥,在函数m13873ao生成,bArr2是查询结果s2用base64decode后的数组
而str在数据库中的keyvalue是通过mo10095b插入的,key的生成在mo10266b是固定的,value需要mo10095b的参数str,查找mo10095b的调用,发现它在ActivationActivity和ChangeMobileNumPreActivity中调用过,猜想是在激活和改变手机号码时将军令初始化调用mo10095b生成了value
str2与str生成类似,也是调用了 m13851E函数,通过m14453c进行aes加密
str2插入数据库是通过mo10101c
ActivationActivity.this.f9569d.mo10101c(bundle.getString(C3806c.m14236h()));
hook得到另一个api:m14236h:https://service.mkey.163.com/WSszq1twyG/api/v3/sms_auth_code_activate
所以app通过f8402a这个handler生成了数据库中的key-value
简单跟一下还可以找到发送信息的函数
hook这个函数重新激活,就可以尝试搞明白他的协议了,这里我们就不深入分析了
我们搞明白了3个参数的生成,回头再看函数
关键函数是一个jin函数,在libmkey.so中,他的3个参数分别为,时间戳e,序列号转化的long类型
我们简单看一下m16044c函数,发现他仅仅具有string转化为byte数组的功能,所以第三个参数str2转化的byte数组。如果只实现otp功能的话,我们直接写一个app调用libmkey.so中的 getOtp就可以了,因为他的第一个参数是时间戳,第二三个参数是激活时通过api获取的,在本地计算后是一个定值,直接hook就可以拿到了
想完整分析参数的生成原理才需要一个一个分析{:1_911:} {:1_911:},下面先放一下本地测试代码,拿到这2个值就可以完全动态生成otp:
https://github.com/conanan/my_mkey
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课