上回讲到用tcpdump抓取系统网络访问记录 [Android实战篇] 系统网络访问记录
通过wireshark查看到系统访问了(貌似有域名,文章发布不了,以下全部用AAA指代下图域名)
但是是哪里访问的呢?
有同学可能说这个容易,源码里全局搜索下域名,就能定位了。骚年,要是能直接搜索到地址也不会有这边文章了
一.获取应用包名
首先在netd中添加日志信息,注意高版本android可能需要修改selinux权限
system/netd/server/DnsProxyListener.cpp添加一个通过pid获取apk包名的方法
static int getProcessNameByPid(int pid, char * processName)
{
int ret;
char cmdline[256] = {0};
sprintf(cmdline, "/proc/%d/cmdline", pid);
int fd = open(cmdline, O_RDONLY);
if (fd == -1) {
return -1;
}
ret = read(fd, processName, 128);
if (ret == -1) {
close(fd);
return -1;
}
close(fd);
return 0;
}
接下来添加日志输出
int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli,
int argc, char **argv) {
...
+ uid_t pid = cli->getPid();
+ char processName[256] = {0};
+ getProcessNameByPid(pid, processName);
+ ALOGW("getaddrinfo uid = %u (%s), pid = %u, name = %s", uid, processName, pid, name);
uint32_t mark = mDnsProxyListener->mNetCtrl->getNetworkForDns(&netId, uid);
...
}
二.查询访问逻辑
增加日志后,有了日志:
W/DnsProxyListener( 469): getaddrinfo uid = 10008 (android.process.media), pid = 1741, name = AAA
终于知道是android.process.media访问的,前面也说了无法搜到这个字符串,现在只能看源码了。
android.process.media只是进程名,与这个进程有关的模块其实有好几个。
先把/data/system/packages.xml pull出来,查看
<shared-user name="android.media" userId="10007">
然后搜索10007,可以看到与之相关的模块有
com.android.providers.media
com.android.providers.downloads
com.android.providers.downloads.ui
com.android.mtp
这里涉及到的模块不多,并且由于该问题是必现的,我们可以从系统里删除了这个应用,然后再看日志排查。当然可以先猜测下,这几个里面与网络相关的比较可能是com.android.providers.downloads,我们可以先删除它看看。这里最后定位到就是它。
接下来就是看代码逻辑了,首先看下这个应用开机时怎么起来的,查看AndroidManifest.xml,我们看到DownloadReceiver会监听开机广播,我们去这个里面加些日志查看吧。开机广播里调用了handleBootCompleted,这里涉及到DownloadInfo,查看这个对象,有mUri变量。我们直接输出DownloadInfo相关信息查看
updateFromDatabase::::DownloadInfo:
mId=1 mLastMod=1636519104700 mPackage=com.google.android.tts mUid=10049
mUri=https://AAA/edgedl/android/tts/v16/cmn-cn-r2.zvoice
mMimeType=null mCookies=no mReferer=no mUserAgent=null
mFileName=null mDestination=4
mStatus=PAUSED_BY_APP mCurrentBytes=0 mTotalBytes=-1
mNumFailed=0 mRetryAfter=0 mETag=null mIsPublicApi=true
mAllowedNetworkTypes=-1 mAllowRoaming=true mAllowMetered=false mFlags=0
谜底揭晓,原来是google的语音引擎下载语音资源文件。
三.总结
整个过程其实并不困难,关键是如何找到突破口,一步步缩小范围。其实到了最后看了源码,我们发现涉及到了ContentProvider,说明应该是有数据库的。我们去机器里查找下这个数据库
adb shell
cd /data/data
grep "域名" -rn ./
可以看到
Binary file ./com.android.providers.downloads/databases/downloads.db matches
这个时候我们可以反思下,源码中搜不到的,会不会是运行时产生的文件。如果我们一开始就在/data/data/下搜索,是不是可以快速定位到与之相关的源码