目录
  1. 1. 整源码
    1. 1.1. 找代码
    2. 1.2. 找so
    3. 1.3. 反编so
    4. 1.4. 转变思路抓包!
    5. 1.5. 组装报文
    6. 1.6. 奇思妙想
反编二:Apk反编

上篇说到神奇的支付方式,然后无聊去反编了Apk看看有没有什么漏洞能整整

整源码

解压apk发现里面有两个dex,就感觉应该没有做加固,然后用dex2jar反编成jar包在JD-Gui中查看发现能看到代码,说明这玩意真的没有做加固。然后把Apk拖到AS中点开AndroidManifest.xml 找到包名(因为直接打开是编译后的xml这里就不多做说明了),然后在JD-Gui中找到对应包名的代码,发现。。。 这玩意连混淆都没有。还用上了DataBinding

为了避嫌这里就不把真实的包名什么的显示出来了。

找代码

然后就开始找相关的Api接口,嗯感觉写的还行都封装出来了。 感觉这个并不是普通的 “一刀99 神级装备满地捡”

看代码返现getHost应该就是请求的Url,然后后面的.do就是具体的网关了。
然后找到host,就是String拼接呗无趣,但是看到 Security.decryptComId 觉得这里咋还做了解密了呢,然后点进去发现,并不简单 。

1
2
3
public static String decryptComId(String paramString) {
return decrypt(paramString, JniUtils.getComIdKey());
}

这里做了个解密 , decrypt封装了一个解密方法,看了代码发现用的是AES, 但是问题是解密类型(CBC还是ECB,PKCS)、密钥都是放在了JNI里面的。(说到这里还是要夸一下的,看过很多别人写的代码很多都是明文存在代码的,要不就是存在R.string里面虽然不能一眼就看出来,不多找找还是能出来的。 然后年轻的时候会建一个文件比如.png .json .xml之类的里面放字节码的密钥然后把文件名起的和项目相关一点,然后取出来在转一下。后来看到知乎上有人建议用jni存,也试过不过这样不太复用每次新项目来总不能用相同的密钥把所以每次都要重新编so,所以后来用了两个项目就没用了,不过后来有封装过一个各种加密方式的Jni 不过没有用到我觉得这种是最好的,但是也有问题要考虑适配性 扯远了扯远来。。。)

找so

找到so。 内心想着会不会里面直接就放了个字符串(毕竟我第一次写的时候就直接放了堆字符串进去结果发现这种操作很傻逼,后面会说到为啥傻逼)。
找到JniUtils 找到对应的引用代码

1
2
3
static {
System.loadLibrary("native-data");
}

在lib中找到相关的libnative-data.so如果里面就是放了个字符串的话可以直接用个二进制文本编辑器打开就能看到了。不过我试了这里并不行。所以没办法只能把这个so也给反了。

反编so

打开虚拟机(因为用的MAC 软件在MAC支持不好所以用了win的虚拟机),打开IDA,发现确实不是很简单。
因为汇编不好这里就暂时不分析下去了,不过大概看出了点里面通过反射拿到了App的签名。然后后面干嘛了就不知道了。

转变思路抓包!

但是我就想拿个请求的URL 为啥要这么玩呢直接网络抓包不好嘛
所以打开Charles,然后把手机脸上我的热点改个端口,打开App 嗯有数据进来了

看着好像就 https://api.openinstall.io 比较像接口地址,毕竟其他的bugly,oss.aliyuncs,baidu怎么可能。然后打开了这个地址发现。。。 为毛这么个App敢这么光明正大的做渠道分发的。
没有拿到地址,突然想到会不会是先走oss看应用是否需要更新然后在正式调用接口。
换网络,先把启动页跳过先。
进入到登录页连接上热点,然后获取验证码,这里是真实的请求地址了,

不过这里还是有问题的都是unknow,这里应该就是https+证书的问题了。普通的https是能拿到的。 但是这个就不行了

但是把域名还是拿到了打开postman请求一下

收到返回了。 下面就是那数据模拟请求了。
突然有个想法。 之前用Fiddler的时候有个功能是吧请求转发走的。如果http能走通的话是不是就是能直接把https的数据转发到http上了。然后搜了一下Charles 也有这个用法 map remote 试了试并不行。 (后来想想确实不行 毕竟一个https一个http协议都不一样)

组装报文

回到代码,找到注册的接口。点了n个入口后发现了所有请求的参数封装。。。我又看到了JniUtils。
报文组装的流程大概是,把所有的参数拼接,然后调用JniUtils.getRequestKey()拿到一个Key ,拼接上这个key整个做个md5的签名,和前面的参数一起发送。所以还是不能模拟请求

奇思妙想

  1. 新建个工程把so拿过来建个一模一样的目录然后调用 JniUtils 获取key。
    放弃 -> 因为so的代码里面有拿app的签名来处理的,如果自建项目签名肯定不一样了 不可行
  2. 用GDA 把内存里面的key dump出来。
    理论上可以的,之前也有玩过,不过奈何手上没有root过的手机,没办法拿到进程不能dump
  3. 继续看.so的代码,看到底它对签名怎么处理了。 签名源文件是拿不到的,但是MD5,HASH之类的还是能拿到的。

待续……

文章作者: Fibonacci
文章链接: http://sovwcwsfm.com/blog/page/decompile02.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Blog