Google壁纸
话说这个 Google 出的壁纸应用倒还是挺好看的嘛,不过只能在手机上使用未免有些可惜……于是决定找一找有没有什么网址之类的……
手上明明有一堆 ddl ,却偏要挖坑给自己跳。
那么首先总先要搞到网址:这很简单,拿 apktool
反编译一下 apk 文件,再用 grep
匹配出 https 开头的地址就可以了,于是我们得到了:
bfg.smali: const-string v4, "https://clients3.google.com/cast/chromecast/home/wallpaper/collections?rt=b"
bfg.smali: const-string v4, "https://clients3.google.com/cast/chromecast/home/wallpaper/collection-images?rt=b"
bfg.smali: const-string v4, "https://clients3.google.com/cast/chromecast/home/wallpaper/image?rt=b"
bjq.smali: const-string v1, "https://app-measurement.com/a"
这TM是啥?似乎 https://clients3.google.com/cast/chromecast/home/wallpaper/collections?rt=b
并查不到任何东西……那试试 https://clients3.google.com/cast/chromecast/home/
(请一定要尝试)。
原来这个是chromecast的待机画面(来源请求)!好吧,那图片是从哪里来的呢?
……
……
审查元素大法好!
<script type="text/javascript">angular.module(...)</script>
这一段似乎很可疑,拿出来看一下……
angular.module('home.constants', []).constant('initialStateJson', JSON.parse('[[[\x22https:\/\/lh6.googleusercontent...
哇!看起来像是和app上面的分类有对应关系。
Terminal中运行 node
, parse 一下这个数组……
哎等等……突然想到其实有可能只是服务端渲染好了页面代码,再发送到本地,然后本地 angular 载入代码获取图片……不禁陷入了沉思……
手机端截包有困难……因为难以搭建两层代理(因为天朝网络原因),所以决定通过观察的方式获得图片:
https://www.gstatic.com/chromecast/home/geo/1920x1080/earth-[001-201].jpg
https://ssl.gstatic.com/chromecast/customize/customize-photos-[01-03].jpg
(那怎么还有像 https://www.gstatic.com/chromecast/home/geo/1920x1080/earth-6510.jpg
这种地址呢???)
终于下决心折腾一下,于是在 Windows 下载了 Fiddler 截包,欢天喜地拿到了数据包,然后用 curl
试了一下发现……为毛 curl
总是要把数据包开头的换行符 0x0a
扔掉啊喂!!!
非常无奈,于是只好用 node.js 写这个东西,总之就是通过观察总结一下规律,用正则表达式拎出图片地址,再写到文件里去就好了。
嗯又是一个flag:因为用 node.js 又埋下了不少坑。简单地说,用到了一些 deprecated 的方法,然后有些地方没有写二进制 flag 。
这件事先折腾这么多吧……
P.S: bash代码(简单粗暴……可以调整一下上限……)
for i in `seq 1 200`; do wget "https://www.gstatic.com/chromecast/home/geo/1920x1080/earth-"`printf "%03d" $i`".jpg"; done
P.P.S: node.js代码(用法 node wallpaper.js path/to/save/pictures)
'use strict'
const request = require('request-promise')
const fs = require('fs')
let options = process.argv
options = options.slice(-1)
request
.post({
url: 'https://clients3.google.com/cast/chromecast/home/wallpaper/collections?rt=b',
headers: { "Content-Type": "application/protobuf"},
body: "\x0a\x05\x7a\x68\x2d\x43\x4e"
})
.then(body => {
// No actual uses.
})
.catch(err => {
console.log("Error!")
console.log(err.message)
exit(0)
})
.then(() => {
return request
.post({
url: 'https://clients3.google.com/cast/chromecast/home/wallpaper/collection-images?rt=b',
headers: { "Content-Type": "application/protobuf"},
body: "\x0a\x04\x63\x69\x74\x79\x12\x05\x7a\x68\x2d\x43\x4e" // city
// "\x0a\x09\x73\x61\x74\x65\x6c\x6c\x69\x74\x65\x12\x05\x7a\x68\x2d\x43\x4e" // satellite
// "\x0a\x09\x6c\x61\x6e\x64\x73\x63\x61\x70\x65\x12\x05\x7a\x68\x2d\x43\x4e" // landscape
// "\x0a\x10\x6d\x61\x74\x65\x72\x69\x61\x6c\x2d\x74\x65\x78\x74\x75\x72\x65\x12\x05\x7a\x68\x2d\x43\x4e" // texture
// "\x0a\x08\x61\x62\x73\x74\x72\x61\x63\x74\x12\x05\x7a\x68\x2d\x43\x4e" // abstract
})
})
.then(res => {
let wallpaperUrls = res.match(/\x01https.*\x1a.http/g).map(str => {return str.slice(1, -6)})
console.log(wallpaperUrls.length + " pictures!")
let index = 0
for (let url of wallpaperUrls) {
request
.get({
url: url + "=s2880-l90",
//: url + "=s612-v1",
//: url + "=s50-v1",
headers: {'Accept-Encoding': 'identity'},
//encoding: 'binary'
})
.pipe(fs.createWriteStream(`${options[0]}/city_${index++}.jpg`))
}
})