前言
在分析华为 agps 的位置获取具体实现逻辑时,通过抓包发现有一条发送到高德的数据流;
agps 的原理是手机通过移动网络向基站的 agps 服务器请求得到当前位置的卫星星历信息(包括仰角、轨道等),拿到星历信息后再 进行运算出当前设备的伪距信息,最后将伪距信息传送到 agps 服务器并最终得到手机终端的具体 gps 信息返回到设备。
通过抓包得到的是一条 走 wifi 流量的高德数据;是在返回当前位置的时候开始发送的(onLocationChanged 函数返回);
当前的手机是华为手机,在打算分析华为 rom 的时候,拆解 rom,发现有个 高德位置服务.apk ,遂分析该 apk。
包名是: com.amap.android.ams
结论:
高德位置服务会采集当前设备内很多信息。
抓到的数据流
上报的数据是经过 gzip 的编码处理;
可以将抓包数据转成 byte 流之后,再试用 gzip -d filename 命令解码;
POST /APS/r?ver=4.9&q=0&csid=5ff08bb5-bda6-47fc-38ca-30f5b5d2f33b HTTP/1.1
gzipped: 1
Accept-Encoding: gzip
et: 111
Content-Type: application/octet-stream
User-Agent: Dalvik/2.1.0 (Linux; U; Android 8.0.0; EDI-AL10 Build/HUAWEIEDISON-AL10)
Host: aps.amap.com
Connection: Keep-Alive
Content-Length: 895
HTTP/1.1 200
Date: Thu, 04 Jun 2020 06:18:51 GMT
Content-Type: application/octet-stream;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
retype: -1
rdesc:
content-encoding: gzip
Server: Tengine/Aserver
EagleEye-TraceId: 0e0fb40115912515318368299efd77
Timing-Allow-Origin: *
gzip 的解码代码
#include
#include
int inflate_read(char *source,int len,char **dest,int gzip) {
LOGTEST("[inflate_read][IN]");
int CHUNK = 2048;
int ret;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
int totalsize = 0;
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
LOGTEST("[inflate_read][step 0]");
if (gzip)
ret = inflateInit2(&strm, 47);
else
ret = inflateInit(&strm);
LOGTEST("[inflate_read][step 1 ret %d ]", ret);
if (ret != Z_OK)
return ret;
strm.avail_in = 975;
strm.next_in = (Bytef*)source;
LOGTEST("[inflate_read][step 2]");
/* run inflate() on input until output buffer not full */
strm.avail_out = 2048;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret) {
//Z_OK
//Z_STREAM_END 1
//Z_NEED_DICT 2
//Z_ERRNO (-1)
//Z_STREAM_ERROR (-2)
//Z_DATA_ERROR (-3)
//Z_MEM_ERROR (-4)
//Z_BUF_ERROR (-5)
//Z_VERSION_ERROR (-6)
case Z_NEED_DICT:
ret = Z_DATA_ERROR;