目的:能够用Charles或者fiddler抓包
因为版主说文章发的太分散了,所以整理了一下放到里第一片里面,这个系列也不再单独更新 首页地址
本来想抓包看看他的api请求,然后分析api加密和参数等问题呢,结果挂上Charles之后竟然界面没有数据并且 Toast 提示 请关闭代{过}{滤}理重试
。
我能猜测到的引起这种现象的有两种情况:1,证书不匹配,项目固定了证书,或者服务端对客户端证书进行了验证;2,项目里面有代{过}{滤}理检测
进一步猜测并测试,我们再尝试一个别的代{过}{滤}理。用手机上的app,packet capture尝试一下结果竟然可以访问,而且也能够抓到数据。所以猜测证书引起的可能性不大。
并且它Toast 提示 请关闭代{过}{滤}理重试
。这一行提示出卖了他。说明他知道我挂了代{过}{滤}理,那么它里面很有可能进行了网络代{过}{滤}理检测。
网上搜一下判断当前wifi是否使用了代{过}{滤}理的基本方法,都是下面这段代码:
public static boolean isWifiProxy() {
final boolean IS_ICS_OR_LATER = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
String proxyAddress;
int proxyPort;
if (IS_ICS_OR_LATER) {
proxyAddress = System.getProperty("http.proxyHost");
String portStr = System.getProperty("http.proxyPort");
proxyPort = Integer.parseInt((portStr != null ? portStr : "-1"));
} else {
proxyAddress = android.net.Proxy.getHost(context);
proxyPort = android.net.Proxy.getPort(context);
}
return (!TextUtils.isEmpty(proxyAddress)) && (proxyPort != -1);
}
jadx 全局搜索 System.getProperty("http.proxyHost");
得到 com.mh.movie.core.app.i
//不就是特么这个方法吗、
private boolean a(Context context) {
CharSequence property;
int parseInt;
if ((VERSION.SDK_INT >= 14 ? 1 : null) != null) {
property = System.getProperty("http.proxyHost");
String property2 = System.getProperty("http.proxyPort");
if (TextUtils.isEmpty(property2)) {
property2 = "-1";
}
parseInt = Integer.parseInt(property2);
} else {
String host = Proxy.getHost(context);
parseInt = Proxy.getPort(context);
property = host;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("proxyAddress : ");
stringBuilder.append(property);
stringBuilder.append(", port : ");
stringBuilder.append(parseInt);
Log.i("checkWifiProxy", stringBuilder.toString());
if (TextUtils.isEmpty(property) || parseInt == -1) {
return false;
}
return true;
}
直接修改 .class public Lcom/mh/movie/core/app/i;
里面的代码为,直接返回false就行了,表明没有是用代{过}{滤}理:
.method private a(Landroid/content/Context;)Z
.locals 7
const/4 v1, 0x0
return v1
.end method
本来以为事情到这里就结束了,但是,TMD 、虽然能访问网络,但是抓不到包,抓不到包。。。。。why?
对于一些常用的网络库,其实是提供了我们设置的代{过}{滤}理的接口,我们只需要将其设置成无代{过}{滤}理的模式,它就不会去应用系统默认的代{过}{滤}理了。
就拿比较常用的 OkHttp 来举例,在初始化的时候,就可以通过 proxy() 方法,为 OkHttp 设置一个代{过}{滤}理。
var httpBuilder = OkHttpClient.Builder()
.addInterceptor(defaultInterceptor())
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
.proxy(Proxy.NO_PROXY)
全局搜索Proxy.NO_PROXY
这个玩意,都删了。
其实最后锁定到
是这个com.jess.arms.b.b.f
类里面的设置引起,但是目前我也没有办法直接锁定到这个类,因为这个项目用了Dagger 。我尝试出来的,jadx 全局搜索一共就是四五处用到这个NO_PROXY 的地方。然后一个个的改,而这个类最复杂,我放到最后才改。结果发现是这个类影响的。
好了终于可以,终于可以能够抓到包了。
总结一下,他这里的抓包防护总共有两处1,检查是不是用了Http代{过}{滤}理,如果是,那么客户端不再发送网络请求,2,通过Okhttp 设置默认代{过}{滤}理,那么就不会走我们的Charles代{过}{滤}理了。设计很精巧