同一段视频 9 种压法:设得越「清楚」,文件反而越大
同一段 63 秒视频 9 种压法实测:设得越清楚,文件越大画质没变好。

手上有个 160 MB 的安卓包(没有源码,只有安装包),我想改两处:一是弱网下的网络超时太长,二是清单里一堆「申请了也拿不到」的权限。没有源码,就只能拆包、改、重打包、重签名。
拆之前先用 aapt2 dump badging 把它量清楚:
package: name='com.XXXXXX' versionCode='81943' versionName='8.19.43'
sdkVersion:'21' compileSdkVersion='33'
zip 内部 3592 个条目、4 个 dex、清单里 53 行 uses-permission。体量决定了后面每一步都慢:apktool 解包、打包各一趟十几分钟。
想改超时,得先知道原值是多少,否则「改小了」纯靠感觉。写脚本扫 smali,找 setConnectTimeout / setReadTimeout 的调用,再回溯上几行的 const 拿实际数字:
CALL = re.compile(r'->set(Connect|Read|Write)Timeout\(I\)V')
CONST = re.compile(r'\bconst(?:/4|/16|/high16)?\s+v\d+,\s*(0x[0-9a-fA-F]+|-?\d+)')
for i, ln in enumerate(lines):
m = CALL.search(ln)
if not m:
continue
for j in range(i - 1, max(-1, i - 9), -1): # 往回找 8 行
c = CONST.search(lines[j])
if c:
记录取值; break
实测:扫 30773 个 smali 文件、耗时 28.7 秒,能识别出取值的一共 30 处:
| 超时类型 | 取值 | 出现次数 |
|---|---|---|
| Read | 60000 ms | 7 |
| Connect | 10000 ms | 8 |
| Connect | 5000 ms | 6 |
| Connect | 20000 ms | 3 |
| Read | 20000 ms | 2 |
| Connect / Read | 15000 / 5000 / 2500 | 各 1 |
结论:读超时最大是 60 秒,连接超时主流是 10 秒 —— 跟我一开始猜的「一律 20 秒」完全不同。没这一步,改的就是一堆凭印象的数字。
权限:删掉 12 行,全是「申请了也没用」的:
ACCESS_FIND_LOCATION(正确写法是 ACCESS_FINE_LOCATION)READ_LOGS、INTERACT_ACROSS_USERS、MOUNT_UNMOUNT_FILESYSTEMS、WRITE_APN_SETTINGSRESTART_PACKAGES、GET_TASKS超时:setReadTimeout 60000 → 20000,setConnectTimeout 20000 → 10000。
java -jar apktool.jar b src -o out_unsigned.apk --use-aapt2
zipalign -f -p 4 out_unsigned.apk out_aligned.apk
apksigner sign --ks my.keystore --out out.apk out_aligned.apk
apksigner verify -v out.apk
顺序不能反:zipalign 必须在签名之前,签完再对齐会破坏 v2 签名块。
实测对比(同一台机器、同一次改动):
| 项目 | 原包 | 重打包后 |
|---|---|---|
| 体积 | 167,737,045 B(160.0 MB) | 169,288,278 B(161.4 MB) |
| zip 条目 | 3592 | 3540 |
| uses-permission | 53 | 41 |
| 签名证书 | CN=guiqi.yzy, OU=hema | CN=paodan, OU=dong |
| 证书 SHA-256 | 57a7d49d… | 431c5f55… |
| 签名方案 | v1 ✓ v2 ✓ v3 ✗ | v1 ✓ v2 ✓ v3 ✓ |
z = zipfile.ZipFile('out.apk')
print('损坏条目:', z.testzip(), '| 条目数:', len(z.namelist()))
再用 aapt2 dump badging 核对包名、版本号、权限数对不对,然后算一次 MD5 记下来 —— 手机端装完出问题时,这个指纹是唯一能确认「装的是不是同一个包」的东西。
另外,160 MB 的包别指望聊天工具传:IM 的文件上限普遍在 30 MB 左右,走 HTTP 直链让手机浏览器下载才靠谱。
1. 装得上、能开 ≠ 还能用。 重签的包装进手机后启动正常,但一登录就报「网络异常」—— 本地功能全好,只有需要联网的操作失败。可以确认的第一个事实是:重打包后签名证书的 DN 和 SHA-256 全变了。对服务端来说,换了签名的包就是另一份软件,做签名校验的服务完全可以据此拒绝。
2. 定位方法:零改动对照实验。 别急着回滚代码。先造一个「原包一个字都不改」的对照组 —— 只解包、重新打包、重新签名,装上去跑一次:
想把变量分得更干净,还可以只换签名、不重新打包:用 zipfile 逐条搬运原包内容,只剥掉旧签名文件(META-INF/*.SF、*.RSA、MANIFEST.MF),再对这个「内容逐字节相同」的包重签。这样对照组里唯一的变量就是签名。
3. 顺手记下的坑:
apksigner 默认会比原包多打一层 v3 方案(原包只有 v1+v2),apksigner verify -v 一眼能看出来jadx 传 --threads 会直接报 ERROR - Incorrect arguments: Unknown option: --threads,网上抄的参数不一定存在4. 边界。 这套流程适用于自有应用和学习研究;有服务端签名校验的第三方 App,改完签名基本过不了它的校验。未经授权修改别人的商用应用有法律风险,别越线。
同一段 63 秒视频 9 种压法实测:设得越清楚,文件越大画质没变好。
同一张壁纸 674.9 KB 能压到 122.9 KB,站上 15 张配图省到四分之一
三个老推送接口都死了,我用 IndexNow 把新文章推给搜索引擎