就把某鱼叫X鱼吧,懂的都懂
某(X)鱼app整个get/post请求中,基本必须在请求头中携带Cookie,这个Cookie的相关操作并不是在 mtopsdk这个包中
,并且
- anetwork.channel.entity.RequestImpl
- mtopsdk.network.domain.Request
- mtopsdk.network.domain.Request.Builder
这几个类中的成员变量Map<String, String> headers中也没有cookie,
它是在android.taobao.windvane.connect.HttpConnector类中setConnectProp方法时添加的
private void setConnectProp(HttpURLConnection paramHttpURLConnection, HttpRequest paramHttpRequest) {
int i = paramHttpRequest.getRetryTime();
paramHttpURLConnection.setConnectTimeout(paramHttpRequest.getConnectTimeout() * (i + 1));
paramHttpURLConnection.setReadTimeout(paramHttpRequest.getReadTimeout() * (i + 1));
paramHttpURLConnection.setInstanceFollowRedirects(false);
paramHttpURLConnection.setRequestProperty("Host", paramHttpRequest.getUri().getHost());
paramHttpURLConnection.setRequestProperty("Connection", "close");
paramHttpURLConnection.setRequestProperty("Accept-Encoding", "gzip");
String str = WVCookieManager.getCookie(paramHttpURLConnection.getURL().toString());
if (str != null)
paramHttpURLConnection.setRequestProperty("Cookie", str);
Map<String, String> map = paramHttpRequest.getHeaders();
if (map != null)
for (Map.Entry<String, String> entry : map.entrySet())
paramHttpURLConnection.setRequestProperty((String)entry.getKey(), (String)entry.getValue());
paramHttpURLConnection.setUseCaches(false);
}
这里的静态方法
WVCookieManager.getCookie();只是个代理类,放一下内容吧
package android.taobao.windvane;
import android.content.Context;
import android.text.TextUtils;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import com.taobao.codetrack.sdk.util.ReportUtil;
public class WVCookieManager {
private static final String TAG = "WVCookieManager";
static {
ReportUtil.dj(-953400378);
}
public static String getCookie(String paramString) {
return TextUtils.isEmpty(paramString) ? null : CookieManager.getInstance().getCookie(paramString);
}
public static void onCreate(Context paramContext) {
CookieSyncManager.createInstance(paramContext);
}
public static void setCookie(String paramString1, String paramString2) {
if (!TextUtils.isEmpty(paramString1) && paramString2 != null) {
if (!CookieManager.getInstance().acceptCookie())
CookieManager.getInstance().setAcceptCookie(true);
CookieManager.getInstance().setCookie(paramString1, paramString2);
}
}
}
所以真是的还是来看看,此时你以为事情就清晰了不,当在jd_gui中想转跳到CookieManager.getInstance()内部实现时,发现进不去,而且发现这里引用的是import android.webkit.CookieManager类,而hook起到作用的是anetwork.channel.cookie.CookieManager这个类的public static String getCookie(String paramString){…}才被调用,所以这个是骗人的
但是再次搜索在
- anetwork.channel.unified.DegradeTask
- anetwork.channel.unified.NetworkTask
放下代码
package anetwork.channel.unified;
import android.text.TextUtils;
import anet.channel.RequestCb;
import anet.channel.bytes.ByteArray;
import anet.channel.request.Cancelable;
import anet.channel.request.Request;
import anet.channel.session.HttpConnector;
import anet.channel.statist.RequestStatistic;
import anet.channel.util.ALog;
import anet.channel.util.HttpHelper;
import anet.channel.util.StringUtils;
import anetwork.channel.aidl.DefaultFinishEvent;
import anetwork.channel.cookie.CookieManager;
import com.taobao.codetrack.sdk.util.ReportUtil;
import java.util.List;
import java.util.Map;
public class DegradeTask implements IUnifiedTask {
private static final String TAG = "anet.DegradeTask";
volatile Cancelable a;
private RequestContext a = null;
private int bc = 0;
private int contentLength = 0;
private volatile boolean isCanceled = false;
private Request request;
static {
ReportUtil.dj(655715856);
ReportUtil.dj(471853369);
}
public DegradeTask(RequestContext paramRequestContext) {
this.a = paramRequestContext;
this.request = paramRequestContext.config.b();
}
public void cancel() {
this.isCanceled = true;
if (this.a != null)
this.a.cancel();
}
public void run() {
if (!this.isCanceled) {
if (this.a.config.aW()) {//这里注意待会看看这个判断aw是什么,有意义
String str = CookieManager.getCookie(this.a.config.getUrlString());
if (!TextUtils.isEmpty(str)) {
Request.Builder builder = this.request.a();
String str1 = (String)this.request.getHeaders().get("Cookie");//这里注意1
String str2 = str;
if (!TextUtils.isEmpty(str1))
str2 = StringUtils.b(str1, "; ", str);
builder.a("Cookie", str2);//这里在看看builder.a方法是不是添加头键值对
this.request = builder.a();
}
}
this.request.rs.degraded = 2;
this.request.rs.sendBeforeTime = System.currentTimeMillis() - this.request.rs.reqStart;
HttpConnector.a(this.request, new RequestCb(this) {
public void onDataReceive(ByteArray param1ByteArray, boolean param1Boolean) {
if (!(DegradeTask.a(this.a)).isDone.get()) {
DegradeTask.a(this.a);
if ((DegradeTask.a(this.a)).a != null)
(DegradeTask.a(this.a)).a.onDataReceiveSize(DegradeTask.b(this.a), DegradeTask.c(this.a), param1ByteArray);
}
}
public void onFinish(int param1Int, String param1String, RequestStatistic param1RequestStatistic) {....}
public void onResponseCode(int param1Int, Map<String, List<String>> param1Map) {....}
}
}
下面放一下另一个基本差不多
package anetwork.channel.unified;
import android.text.TextUtils;
import anet.channel.Config;
import anet.channel.GlobalAppRuntimeInfo;
import anet.channel.NoAvailStrategyException;
import anet.channel.RequestCb;
import anet.channel.Session;
import anet.channel.SessionCenter;
import anet.channel.SessionGetCallback;
import anet.channel.appmonitor.AppMonitor;
import anet.channel.bytes.ByteArray;
import anet.channel.entity.ConnInfo;
import anet.channel.entity.ENV;
import anet.channel.entity.SessionType;
import anet.channel.request.Cancelable;
import anet.channel.request.Request;
import anet.channel.session.HttpSession;
import anet.channel.statist.ExceptionStatistic;
import anet.channel.statist.RequestStatistic;
import anet.channel.statist.StatObject;
import anet.channel.status.NetworkStatusHelper;
import anet.channel.thread.ThreadPoolExecutorFactory;
import anet.channel.util.ALog;
import anet.channel.util.AppLifecycle;
import anet.channel.util.ErrorConstant;
import anet.channel.util.HttpHelper;
import anet.channel.util.HttpUrl;
import anet.channel.util.StringUtils;
import anetwork.channel.aidl.DefaultFinishEvent;
import anetwork.channel.cache.Cache;
import anetwork.channel.cache.CacheHelper;
import anetwork.channel.config.NetworkConfigCenter;
import anetwork.channel.cookie.CookieManager;
import anetwork.channel.http.NetworkSdkSetting;
import anetwork.channel.interceptor.Callback;
import com.taobao.codetrack.sdk.util.ReportUtil;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
class NetworkTask implements IUnifiedTask {
public static final int MAX_RSP_BUFFER_LENGTH = 131072;
public static final String TAG = "anet.NetworkTask";
volatile Cancelable a;
Cache.Entry a;
Cache a;
ResponseBuffer a;
RequestContext a = null;
int bc;
boolean br;
boolean bs;
ByteArrayOutputStream c;
int contentLength;
String f_refer;
volatile boolean isCanceled;
volatile AtomicBoolean isDone;
static {
ReportUtil.dj(-2085384120);
ReportUtil.dj(471853369);
}
NetworkTask(RequestContext paramRequestContext, Cache paramCache, Cache.Entry paramEntry) {.....}
private Session a() {
......
return a(null, sessionCenter, httpUrl, bool);
}
private Session a(Session paramSession, SessionCenter paramSessionCenter, HttpUrl paramHttpUrl, boolean paramBoolean) {
return (Session)httpSession;
}
private SessionCenter a() {
String str1 = this.a.config.getRequestProperty("APPKEY");
if (TextUtils.isEmpty(str1))
return SessionCenter.getInstance();
ENV eNV = ENV.ONLINE;//这里很熟悉,在抓包的头里面出现过这个
String str2 = this.a.config.getRequestProperty("ENVIRONMENT");
if ("pre".equalsIgnoreCase(str2)) {
eNV = ENV.PREPARE;
} else if ("test".equalsIgnoreCase(str2)) {
eNV = ENV.TEST;
}
if (eNV != NetworkSdkSetting.CURRENT_ENV) {
NetworkSdkSetting.CURRENT_ENV = eNV;
SessionCenter.switchEnvironment(eNV);
}
Config config2 = Config.a(str1, eNV);
Config config1 = config2;
if (config2 == null)
config1 = (new Config.Builder()).b(str1).a(eNV).c(this.a.config.getRequestProperty("AuthCode")).a();
return SessionCenter.getInstance(config1);
}
private Request a(Request paramRequest) {
Request.Builder builder1 = null;
Request.Builder builder2 = builder1;
if (this.a.config.aW()) {//差不多一样先判断
String str = CookieManager.getCookie(this.a.config.getUrlString());
builder2 = builder1;
if (!TextUtils.isEmpty(str)) {
builder1 = paramRequest.a();
String str2 = (String)paramRequest.getHeaders().get("Cookie");
String str1 = str;
if (!TextUtils.isEmpty(str2))
str1 = StringUtils.b(str2, "; ", str);
builder1.a("Cookie", str1);
builder2 = builder1;
}
}
Request.Builder builder3 = builder2;
if (this.a != null) {
builder1 = builder2;
if (builder2 == null)
builder1 = paramRequest.a();
if (((Cache.Entry)this.a).etag != null)
builder1.a("If-None-Match", ((Cache.Entry)this.a).etag);
builder3 = builder1;
if (((Cache.Entry)this.a).lastModified > 0L) {
builder1.a("If-Modified-Since", CacheHelper.e(((Cache.Entry)this.a).lastModified));
builder3 = builder1;
}
}
builder2 = builder3;
if (this.a.config.bb == 0) {
builder2 = builder3;
if ("weex".equalsIgnoreCase(this.f_refer)) {
builder2 = builder3;
if (builder3 == null)
builder2 = paramRequest.a();
builder2.b(3000);
}
}
if (builder2 != null)
paramRequest = builder2.a();
return paramRequest;
}
private static class ResponseBuffer {
int code;
Map<String, List<String>> header;
List<ByteArray> v = new ArrayList<ByteArray>();
static {
ReportUtil.dj(229651421);
}
ResponseBuffer(int param1Int, Map<String, List<String>> param1Map) {
this.code = param1Int;
this.header = param1Map;
}
int a(Callback param1Callback, int param1Int) {....}
void release() {...}
}
hook结果是NetworkTask在中操作的,接着看看if (this.a.config.aW()) {…}
- anetwork.channel.entity. RequestConfig
public boolean aW() {
return !"false".equalsIgnoreCase(this.a.getExtProperty("EnableCookie"));
}
我只能说用的属性名叫"EnableCookie"却用等于false取反,水太深了
在
- anetwork.channel.entity.RequestImpl
明显有相关方法
@Deprecated
public void setCookieEnabled(boolean paramBoolean) {
String str;
if (paramBoolean) {
str = "true";
} else {
str = "false";
}
setExtProperty("EnableCookie", str);
}
public void setExtProperty(String paramString1, String paramString2) {
if (!TextUtils.isEmpty(paramString1)) {
if (this.extProperties == null)
this.extProperties = new HashMap<String, String>();
this.extProperties.put(paramString1, paramString2);
}
}
hook这个方法发现确实有调用
(String)paramRequest.getHeaders().get(“Cookie”);
这个paramRequest是anet.channel.request.Request类应该很有操作性但是到现在已经够清楚了,这个是不是就不太重要了,之接放
public Map<String, String> getHeaders() {
return Collections.unmodifiableMap(this.headers);
}
来看看这个 builder1.a(“Cookie”, str1);是不是调用了 hook监听下
if (!TextUtils.isEmpty(str)) {
builder1 = paramRequest.a();
String str2 = (String)paramRequest.getHeaders().get("Cookie");
String str1 = str;
if (!TextUtils.isEmpty(str2))
str1 = StringUtils.b(str2, "; ", str);
builder1.a("Cookie", str1);//看看这个实现
builder2 = builder1;
}
顺便直接跳到Request类下面的Builder类a的实现
public Builder a(String param1String1, String param1String2) {
this.headers.put(param1String1, param1String2);
return this;
}
结果就是完全hook住了说明确实调用了
10019 10284 I EdXposed-Bridge: anet.channel.request.Request$Builder中public Builder a(String param1String1, String param1String2)
08-15 19:14:29.857 10019 10284 I EdXposed-Bridge: 参数1Content-Type 参数2application/x-www-form-urlencoded;charset=UTF-8
08-15 19:14:29.948 10019 10342 I EdXposed-Bridge: setCookieEnabled:false
08-15 19:14:29.948 10019 10342 I EdXposed-Bridge: setExtProperty方法 键:EnableCookie 值:false
08-15 19:14:29.948 10019 10342 I EdXposed-Bridge: addHeader方法 键:f-refer 值:picture
08-15 19:14:29.948 10019 10342 I EdXposed-Bridge: addHeader方法 键:User-Agent 值:TBAndroid/Native
08-15 19:14:29.949 10019 10342 I EdXposed-Bridge: setExtProperty方法 键:f-netReqStart 值:1629026069949
08-15 19:14:29.949 10019 10342 I EdXposed-Bridge: setExtProperty方法 键:f-traceId 值:null
08-15 19:14:29.949 10019 10342 I EdXposed-Bridge: setExtProperty方法 键:f-reqProcess 值:com.taobao.idlefish
08-15 19:14:29.971 10019 10319 I EdXposed-Bridge: setCookieEnabled:false
08-15 19:14:29.971 10019 10319 I EdXposed-Bridge: setExtProperty方法 键:EnableCookie 值:false
08-15 19:14:29.971 10019 10319 I EdXposed-Bridge: addHeader方法 键:f-refer 值:picture
08-15 19:14:29.971 10019 10319 I EdXposed-Bridge: addHeader方法 键:User-Agent 值:TBAndroid/Native
08-15 19:14:29.972 10019 10319 I EdXposed-Bridge: setExtProperty方法 键:f-netReqStart 值:1629026069972
08-15 19:14:29.972 10019 10319 I EdXposed-Bridge: setExtProperty方法 键:f-traceId 值:null
08-15 19:14:29.972 10019 10319 I EdXposed-Bridge: setExtProperty方法 键:f-reqProcess 值:com.taobao.idlefish
08-15 19:14:29.973 10019 10341 I EdXposed-Bridge: setCookieEnabled:false
08-15 19:14:29.973 10019 10341 I EdXposed-Bridge: setExtProperty方法 键:EnableCookie 值:false
08-15 19:14:29.973 10019 10341 I EdXposed-Bridge: addHeader方法 键:f-refer 值:picture
08-15 19:14:29.973 10019 10341 I EdXposed-Bridge: addHeader方法 键:User-Agent 值:TBAndroid/Native
08-15 19:14:29.973 10019 10341 I EdXposed-Bridge: setExtProperty方法 键:f-netReqStart 值:1629026069973
08-15 19:14:29.973 10019 10341 I EdXposed-Bridge: setExtProperty方法 键:f-traceId 值:null
08-15 19:14:29.973 10019 10341 I EdXposed-Bridge: setExtProperty方法 键:f-reqProcess 值:com.taobao.idlefish
08-15 19:14:30.034 10019 10284 I EdXposed-Bridge: NetworkTask:private Request a(Request paramRequest)中String str = CookieManager.getCookie(this.a.config.getUrlString());
08-15 19:14:30.034 10019 10272 I EdXposed-Bridge: NetworkTask:private Request a(Request paramRequest)中String str = CookieManager.getCookie(this.a.config.getUrlString());
08-15 19:14:30.035 10019 10272 I EdXposed-Bridge: NetworkTask:private Request a(Request paramRequest)中String str = CookieManager.getCookie(this.a.config.getUrlString());
08-15 19:14:30.272 10019 10309 I EdXposed-Bridge: setExtProperty方法 键:f-pTraceId 值:null
由此某鱼的Cookie就整的明明白白,但是虽然getCookie虽然要传入一个String参数 观察发现其实就是所请求的api,本以为请求的api得到的cookie字符串里面会有部分不同结果发现,不管用什么参数都返回相同cookie,本来想进去看一下这个方法但是…
public static String getCookie(String paramString) {
// Byte code:
// 0: aconst_null
// 1: astore_1
// 2: ldc anetwork/channel/cookie/CookieManager
// 4: monitorenter
// 5: aload_1
// 6: astore_2
// 7: invokestatic checkSetup : ()Z
// 10: ifeq -> 23
// 13: getstatic anetwork/channel/cookie/CookieManager.bn : Z
// 16: istore_3
// 17: iload_3
// 18: ifne -> 28
// 21: aload_1
// 22: astore_2
// 23: ldc anetwork/channel/cookie/CookieManager
// 25: monitorexit
// 26: aload_2
// 27: areturn
// 28: aconst_null
// 29: astore_2
// 30: getstatic anetwork/channel/cookie/CookieManager.webkitCookMgr : Landroid/webkit/CookieManager;
// 33: aload_0
// 34: invokevirtual getCookie : (Ljava/lang/String;)Ljava/lang/String;
// 37: astore_1
// 38: aload_1
// 39: astore_2
// 40: aload_0
// 41: aload_2
// 42: invokestatic g : (Ljava/lang/String;Ljava/lang/String;)V
// 45: goto -> 23
// 48: astore_0
// 49: ldc anetwork/channel/cookie/CookieManager
// 51: monitorexit
// 52: aload_0
// 53: athrow
// 54: astore #4
// 56: new java/lang/StringBuilder
// 59: astore_1
// 60: aload_1
// 61: invokespecial <init> : ()V
// 64: ldc 'anet.CookieManager'
// 66: aload_1
// 67: ldc 'get cookie failed. url='
// 69: invokevirtual append : (Ljava/lang/String;)Ljava/lang/StringBuilder;
// 72: aload_0
// 73: invokevirtual append : (Ljava/lang/String;)Ljava/lang/StringBuilder;
// 76: invokevirtual toString : ()Ljava/lang/String;
// 79: aconst_null
// 80: aload #4
// 82: iconst_0
// 83: anewarray java/lang/Object
// 86: invokestatic b : (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;[Ljava/lang/Object;)V
// 89: goto -> 40
// Exception table:
// from to target type
// 7 17 48 finally
// 30 38 54 java/lang/Throwable
// 30 38 48 finally
// 40 45 48 finally
// 56 89 48 finally
}
那就这样吧