阿里移动端产品网络层大多使用Mtop、ANetwork框架,Mtop是阿里云的移动端网关SDk,ANetwork是比较底层的网络实现库,分析这两个框架就能找出App抓不到包的原因。本文将逆向分析smali
文件,找出阿里系App网络的开关,最终能使用Charles
实现抓包的功能。
以《大麦网》App为例子,从应用宝将APK下载下来将文件后缀改为zip然后解压,然后使用baksmail
将dex文件转成smali文件:
java -jar baksmali-2.3.4.jar d classes.dex -o damai
java -jar baksmali-2.3.4.jar d classes2.dex -o damai
...
注意classes.dex会有多个,每个文件都执行一次上面的命令,确保所有的dex文件都被反编译再来分析。
《大麦网》的网络是使用Service的形式,所以首先打开anetwork/channel/aidl/NetworkService.smali
这个文件,分析里面的onBind
方法:
.method public onBind(Landroid/content/Intent;)Landroid/os/IBinder;
...
new-instance v1, Lanetwork/channel/degrade/DegradableNetworkDelegate;
iget-object v2, p0, Lanetwork/channel/aidl/NetworkService;->context:Landroid/content/Context;
invoke-direct {v1, v2}, Lanetwork/channel/degrade/DegradableNetworkDelegate;-><init>(Landroid/content/Context;)V
iput-object v1, p0, Lanetwork/channel/aidl/NetworkService;->degradeableNetwork:Lanetwork/channel/aidl/RemoteNetwork$Stub;
new-instance v1, Lanetwork/channel/http/HttpNetworkDelegate;
iget-object v2, p0, Lanetwork/channel/aidl/NetworkService;->context:Landroid/content/Context;
invoke-direct {v1, v2}, Lanetwork/channel/http/HttpNetworkDelegate;-><init>(Landroid/content/Context;)V
iput-object v1, p0, Lanetwork/channel/aidl/NetworkService;->httpNetwork:Lanetwork/channel/aidl/RemoteNetwork$Stub;
const-class v1, Lanetwork/channel/aidl/IRemoteNetworkGetter;
...
.end method
去掉一些无用的代码,可以看到几个关键的类:
- IRemoteNetworkGetter
- DegradableNetworkDelegate
- HttpNetworkDelegate
IRemoteNetworkGetter
看名字大概就能猜测是获取某个东西的类,它是一个AIDL生成的类,它就只有一个方法:
.method public abstract get(I)Lanetwork/channel/aidl/RemoteNetwork;
接收一个Int型参数,用于获取RemoteNetwork
实例。它的实现类在anetwork/channel/aidl/NetworkService$1.smali
文件中:
.method public get(I)Lanetwork/channel/aidl/RemoteNetwork;
.registers 3
.param p1, "type" # I
.annotation system Ldalvik/annotation/Throws;
value = {
Landroid/os/RemoteException;
}
.end annotation
.prologue
.line 36
const/4 v0, 0x1
if-ne p1, v0, :cond_a
iget-object v0, p0, Lanetwork/channel/aidl/NetworkService$1;->this$0:Lanetwork/channel/aidl/NetworkService;
# getter for: Lanetwork/channel/aidl/NetworkService;->degradeableNetwork:Lanetwork/channel/aidl/RemoteNetwork$Stub;
invoke-static {v0}, Lanetwork/channel/aidl/NetworkService;->access$000(Lanetwork/channel/aidl/NetworkService;)Lanetwork/channel/aidl/RemoteNetwork$Stub;
move-result-object v0
:goto_9
return-object v0
:cond_a
iget-object v0, p0, Lanetwork/channel/aidl/NetworkService$1;->this$0:Lanetwork/channel/aidl/NetworkService;
# getter for: Lanetwork/channel/aidl/NetworkService;->httpNetwork:Lanetwork/channel/aidl/RemoteNetwork$Stub;
invoke-static {v0}, Lanetwork/channel/aidl/NetworkService;->access$100(Lanetwork/channel/aidl/NetworkService;)Lanetwork/channel/aidl/RemoteNetwork$Stub;
move-result-object v0
goto :goto_9
.end method
大概意思就是判断type
是0就返回httpNetwork
其他的就返回degradeableNetwork
,这两个实例都是NetworkServie
中的onBind
方法中创建的。
经过上面的分析就能确定《大麦网》中有两种网络实现一种是比较熟悉的httpNetwork
和目前不知道有啥区别的degradeableNetwork
,由于咱们的主要目的是实现抓包,具体的网络实现啥的就不去探索了,有兴趣的可以去研究哈。
现在都知道《大麦网》的网络请求是使用AIDL的方式发送的,大家都知道AIDL会自动生成Proxy
和Stub
, Stub
就不去分析了,他的实现类就是DegradableNetworkDelegate
和HttpNetworkDelegate
,下面得找出绑定NetworkService
服务的代码,要使用网络那也要绑定服务才行,打开AndroidManifest.xml
文件,找到服务的声明如下:
<service android:exported="false" android:name="anetwork.channel.aidl.NetworkService">
<intent-filter>
<action android:name="anetwork.channel.aidl.IRemoteNetworkGetter"/>
</intent-filter>
</service>
现在要去找到绑定NetworkService
服务的代码,全局搜索anetwork.channel.aidl.IRemoteNetworkGetter
这action没有发现有相关的代码,后来发现这个action其实就是IRemoteNetworkGetter
这个类的类名,所以通过全局搜索找到了一个RemoteGetterHelper
的类,这个类主要用来绑定服务,获取IRemoteNetworkGetter
实例,然后获取网络实现类:
invoke-virtual {v3}, Ljava/lang/Class;->getName()Ljava/lang/String;
move-result-object v3
invoke-virtual {v2, v3}, Landroid/content/Intent;->setAction(Ljava/lang/String;)Landroid/content/Intent;
const-string/jumbo v3, "android.intent.category.DEFAULT"
invoke-virtual {v2, v3}, Landroid/content/Intent;->addCategory(Ljava/lang/String;)Landroid/content/Intent;
sget-object v3, Lanetwork/channel/aidl/adapter/RemoteGetterHelper;->conn:Landroid/content/ServiceConnection;
invoke-virtual {p0, v2, v3, v0}, Landroid/content/Context;->bindService(Landroid/content/Intent;Landroid/content/ServiceConnection;I)Z
自此可以确定获取网络实例会经过以下步骤:
- 使用RemoteGetterHelper绑定服务
- 获取到IRemoteNetworkGetter
- 调用IRemoteNetworkGetter.get(int)方法获取实例
网络就分析到这里啦,要想实现抓包还得分析Mtop,第二部分再来分析Mtop然后实现抓包,最后简单画个图,理一理:
最后欢迎大家关注我的公众号,获取最新的进展。
免责声明: 本文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请读者自负。