首页
社区
课程
招聘
[原创]实现frida版的JustTrustMe(一)JustTrustMe官方源码学习
发表于: 2021-5-6 10:31 21446

[原创]实现frida版的JustTrustMe(一)JustTrustMe官方源码学习

2021-5-6 10:31
21446

对于绕过ssl pinning的产品有很多,其中最著名的当属JustTrustMe。其他的sslUnPinning产品思想很多都是从JustTrustMe那里抄来的,由于JustTrustMe原作者也不更新了但是反sslUnPinning技术一直在前进,所以我决定用1一个月的业余时间来重新打造一款实用的sslUnPinning产品。

JustTrustMe我是很认可他的插桩点位的思路的。但是,本人是不认可xposed的。xposed的hook机制从设计之初就走了一条“不归路”,因为xposed有太多的特征可以被app检测。主要是xposed必须基于替换受精卵进程来实现,并且还要安装对应的app来管理插件,而且插件开发也要是单独的android工程。这个对于被攻击app来讲非常好从多个维度去检测xposed的存在,只是人家不想搞的这么明显大多不会强制退出app罢了。比如微信大家去jadx搜索代码,里面妥妥去检测了xposed,人家早就把你标记了。有些小team拿着官方已经停止更新的xposed改改包名,然后称之为魔改过反检测。其实,我要检测你,你怎么改都反不了。你包名改掉,但是你自定义的包名依然在调用栈里面。通过对比纯净android系统的正常堆栈,你立马被标记为灰度用户。还可以通过扫描已经安装的app列表,发现类似justtrustme之类的应用立马标记。还有你xposed管理本身也是一个app,你怎么隐藏? 改操作系统吗?但是,话又回来了,你都可以改操作系统了那你为什么不直接在framework层直接嵌入hook机制呢?因为,你技术还没到那一步,你只是停留在andorid项目改改包名的阶段,只能靠着这个去收割一些新人的韭菜。不好意思阿,我这人说话就是这么直!你费劲巴拉的搞一个大型项目,完了效果并不是真的全面反检测。我觉得没必要去做。

我想xposed的作者rovo89也是看到了这一点,所以没有再对xposed进行更新了。大庄家都不玩了,我们这些蝼蚁就要认清局势。该废弃的技术废弃,要舍得抛弃陈旧的技术这样你才能不断进步。我要把JustTrustMe用frida实现一版。所以先出一篇JustTrustMe源码分析,等大家熟悉了JustTrustMe源码我再带着大家用frida去搞一个"JustTrustMe":

请大家先打开JustTrustMe的Main.java,我下面会一一列举JustTrustMe的每个方法,以及它的作用和对应java的伪代码。

分析:三个构造方法的目的都是在new DefaultHttpClient之后替换connManager参数。而getSCCM()方法就是返回一个不安全的ClientConnectionManager。
getSCCM()和getCCM()实现如下:

那么,由此我们得到经过hook之后三个方法的伪代码逻辑。

分析:X509TrustManagerExtensions原方法会进行一系列的效应证书和服务器是否可信。这里xposed用了XC_MethodReplacement直接替换方法的执行体。
那么,伪代码逻辑如下:

分析:原NetworkSecurityTrustManager类的checkPins方法List参数原型是List<X509Certificate>。校验X509Certificate集合是否合法,如果不合法就会抛CertificateException。这里xposed用了XC_MethodReplacement直接替换方法的执行体,并且什么都没做。
那么,伪代码逻辑如下:

分析:这个稍微有点复杂,但目的很简单。就是为了替换TrustManager,而TrustManager不可以直接传进来,是内部创建一个sslcontext来包装一个TrustManager[]。所以要new一个自定义的sslcontext然后把ImSureItsLegitTrustManager传进去。sslcontext对象要进行init()所以整个代码看起来比较多。

给你看伪代码,那逻辑将一目了然:

分析:很好理解
伪代码:

分析:强制让isSecure返回true
伪代码:

分析:如果存在com.android.org.conscrypt.TrustManagerImpl这个类的,并且返回的TrustManager[]的长度大于0,并且TrustManager[]第0个是com.android.org.conscrypt.TrustManagerImpl实例,则什么都不操作。否则直接把返回值改成TrustManager[]{new ImSureItsLegitTrustManager()}

伪代码:

分析:让setDefaultHostnameVerifier方法失效,让setSSLSocketFactory失效,让setHostnameVerifier失效
伪代码:

分析:不用第0和低2个参数,而第1个参数使用TrustManager[]{new ImSureItsLegitTrustManager()}

伪代码:

分析:由于xposed基于zygote进程孵化app进程,hook非常早。所以如果它想对应用层的类进行hook的话,必须等Application的attach调用之后才能拿到应用级的ClassLoader。那么在attach之后他又进行了processOkHttp、processHttpClientAndroidLib、processXutils方法的调用,分别对应okhttp库的hook、httpclientandroidlib库的hook、org.xutils.http的hook。这三个是应用喜欢用的三方http库。
伪代码:

分析okhttp包名不统一问题:由于okhttp 2.x和3.x包名相差比较大。所以这里第一个hook你可以看到justTrustMe试图去找com.squareup.okhttp.CertificatePinner类,这是为了尽量兼容老安卓项目。

分析CertificatePinner.check:无论是okhttp2.x还是3.x、4.x都是有CertificatePinner.check(String str, List<Certificate> list)这个方法的。可以上面第一二个hook做的是XC_MethodReplacement,并且什么都不操作。对比原check方法,我们知道这个目的是为了阻止check抛SSLPeerUnverifiedException异常。
CertificatePinner.check伪代码:

分析:第三四个hook OkHostnameVerifier.verify(),校验hostname是否合法最终会调用verify(str, (X509Certificate) sSLSession.getPeerCertificates()[0]);说明还是对远程服务证书进行了校验,这里直接用return true替代了原来的逻辑。

分析:一个冷门http库的hook
伪代码:

分析:一个冷门http库的hook
伪代码:

到目前为止,我们已经把JustTrustMe所有的hook点位全部分析了一遍。中间如果大家还是有不解的地方可以去查看每个类对应的源码,下列我帮大家找了一些

JustTrustMe Main.java

apache http DefaultHttpClient.java

android framework X509TrustManagerExtensions.java

android framework NetworkSecurityTrustManager.java

apache http SSLSocketFactory.java

javax TrustManagerFactory.java

javax HttpsURLConnection.java

javax SSLContext.java

android framework TrustManagerImpl.java

okhttp3 CertificatePinner.java

okhttp3 OkHostnameVerifier.java

 
 
/* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
/* public DefaultHttpClient() */
 
findAndHookConstructor(DefaultHttpClient.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
 
                setObjectField(param.thisObject, "defaultParams", null);
                setObjectField(param.thisObject, "connManager", getSCCM());
            }
        });
 
/* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
/* public DefaultHttpClient(HttpParams params) */
findAndHookConstructor(DefaultHttpClient.class, HttpParams.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
 
                setObjectField(param.thisObject, "defaultParams", (HttpParams) param.args[0]);
                setObjectField(param.thisObject, "connManager", getSCCM());
            }
        });
 
/* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
/* public DefaultHttpClient(ClientConnectionManager conman, HttpParams params) */
findAndHookConstructor(DefaultHttpClient.class, ClientConnectionManager.class, HttpParams.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
 
                HttpParams params = (HttpParams) param.args[1];
 
                setObjectField(param.thisObject, "defaultParams", params);
                setObjectField(param.thisObject, "connManager", getCCM(param.args[0], params));
            }
        });
/* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
/* public DefaultHttpClient() */
 
findAndHookConstructor(DefaultHttpClient.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
 
                setObjectField(param.thisObject, "defaultParams", null);
                setObjectField(param.thisObject, "connManager", getSCCM());
            }
        });
 
/* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
/* public DefaultHttpClient(HttpParams params) */
findAndHookConstructor(DefaultHttpClient.class, HttpParams.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
 
                setObjectField(param.thisObject, "defaultParams", (HttpParams) param.args[0]);
                setObjectField(param.thisObject, "connManager", getSCCM());
            }
        });
 
/* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
/* public DefaultHttpClient(ClientConnectionManager conman, HttpParams params) */
findAndHookConstructor(DefaultHttpClient.class, ClientConnectionManager.class, HttpParams.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
 
                HttpParams params = (HttpParams) param.args[1];
 
                setObjectField(param.thisObject, "defaultParams", params);
                setObjectField(param.thisObject, "connManager", getCCM(param.args[0], params));
            }
        });
//Create a SingleClientConnManager that trusts everyone!
public ClientConnectionManager getSCCM() {
 
        KeyStore trustStore;
        try {
 
            trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null, null);
 
            SSLSocketFactory sf = new TrustAllSSLSocketFactory(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
 
            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            registry.register(new Scheme("https", sf, 443));
 
            ClientConnectionManager ccm = new SingleClientConnManager(null, registry);
 
            return ccm;
 
        } catch (Exception e) {
            return null;
        }
    }
 
//This function creates a ThreadSafeClientConnManager that trusts everyone!
public ClientConnectionManager getTSCCM(HttpParams params) {
 
        KeyStore trustStore;
        try {
 
            trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null, null);
 
            SSLSocketFactory sf = new TrustAllSSLSocketFactory(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
 
            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            registry.register(new Scheme("https", sf, 443));
 
            ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
 
            return ccm;
 
        } catch (Exception e) {
            return null;
        }
    }
 
//This function determines what object we are dealing with.
public ClientConnectionManager getCCM(Object o, HttpParams params) {
 
        String className = o.getClass().getSimpleName();
 
        if (className.equals("SingleClientConnManager")) {
            return getSCCM();
        } else if (className.equals("ThreadSafeClientConnManager")) {
            return getTSCCM(params);
        }
 
        return null;
    }
//Create a SingleClientConnManager that trusts everyone!
public ClientConnectionManager getSCCM() {
 
        KeyStore trustStore;
        try {
 
            trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null, null);
 
            SSLSocketFactory sf = new TrustAllSSLSocketFactory(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
 
            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            registry.register(new Scheme("https", sf, 443));
 
            ClientConnectionManager ccm = new SingleClientConnManager(null, registry);
 
            return ccm;
 
        } catch (Exception e) {
            return null;
        }
    }
 
//This function creates a ThreadSafeClientConnManager that trusts everyone!
public ClientConnectionManager getTSCCM(HttpParams params) {
 
        KeyStore trustStore;
        try {
 
            trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null, null);
 
            SSLSocketFactory sf = new TrustAllSSLSocketFactory(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
 
            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            registry.register(new Scheme("https", sf, 443));
 
            ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
 
            return ccm;
 
        } catch (Exception e) {
            return null;
        }
    }
 
//This function determines what object we are dealing with.
public ClientConnectionManager getCCM(Object o, HttpParams params) {
 
        String className = o.getClass().getSimpleName();
 
        if (className.equals("SingleClientConnManager")) {
            return getSCCM();
        } else if (className.equals("ThreadSafeClientConnManager")) {
            return getTSCCM(params);
        }
 
        return null;
    }
public DefaultHttpClient(final ClientConnectionManager conman, final HttpParams params) {
    super(getCCM(conman, params), params);
}
 
 
public DefaultHttpClient(final HttpParams params) {
    super(getSCCM(), params);
}
 
 
public DefaultHttpClient() {
    super(getSCCM(), null);
}
public DefaultHttpClient(final ClientConnectionManager conman, final HttpParams params) {
    super(getCCM(conman, params), params);
}
 
 
public DefaultHttpClient(final HttpParams params) {
    super(getSCCM(), params);
}
 
 
public DefaultHttpClient() {
    super(getSCCM(), null);
}
findAndHookMethod(X509TrustManagerExtensions.class, "checkServerTrusted", X509Certificate[].class, String.class, String.class, new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                return param.args[0];
            }
        });
findAndHookMethod(X509TrustManagerExtensions.class, "checkServerTrusted", X509Certificate[].class, String.class, String.class, new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                return param.args[0];
            }
        });
public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType, String host) throws CertificateException {
        return chain;
}
public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType, String host) throws CertificateException {
        return chain;
}
findAndHookMethod("android.security.net.config.NetworkSecurityTrustManager", lpparam.classLoader, "checkPins", List.class, new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                return null;
            }
        });
findAndHookMethod("android.security.net.config.NetworkSecurityTrustManager", lpparam.classLoader, "checkPins", List.class, new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                return null;
            }
        });
private void checkPins(List<X509Certificate> chain) throws CertificateException {
 
}
private void checkPins(List<X509Certificate> chain) throws CertificateException {
 
}
/* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
/* public SSLSocketFactory( ... ) */
findAndHookConstructor(SSLSocketFactory.class, String.class, KeyStore.class, String.class, KeyStore.class,
                SecureRandom.class, HostNameResolver.class, new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
 
                        String algorithm = (String) param.args[0];
                        KeyStore keystore = (KeyStore) param.args[1];
                        String keystorePassword = (String) param.args[2];
                        SecureRandom random = (SecureRandom) param.args[4];
 
                        KeyManager[] keymanagers = null;
                        TrustManager[] trustmanagers = null;
 
                        if (keystore != null) {
                            keymanagers = (KeyManager[]) callStaticMethod(SSLSocketFactory.class, "createKeyManagers", keystore, keystorePassword);
                        }
 
                        trustmanagers = new TrustManager[]{new ImSureItsLegitTrustManager()};
 
                        setObjectField(param.thisObject, "sslcontext", SSLContext.getInstance(algorithm));
                        callMethod(getObjectField(param.thisObject, "sslcontext"), "init", keymanagers, trustmanagers, random);
                        setObjectField(param.thisObject, "socketfactory",
                                callMethod(getObjectField(param.thisObject, "sslcontext"), "getSocketFactory"));
                    }
 
                });
/* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
/* public SSLSocketFactory( ... ) */
findAndHookConstructor(SSLSocketFactory.class, String.class, KeyStore.class, String.class, KeyStore.class,
                SecureRandom.class, HostNameResolver.class, new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
 
                        String algorithm = (String) param.args[0];
                        KeyStore keystore = (KeyStore) param.args[1];
                        String keystorePassword = (String) param.args[2];
                        SecureRandom random = (SecureRandom) param.args[4];
 
                        KeyManager[] keymanagers = null;
                        TrustManager[] trustmanagers = null;
 
                        if (keystore != null) {
                            keymanagers = (KeyManager[]) callStaticMethod(SSLSocketFactory.class, "createKeyManagers", keystore, keystorePassword);
                        }
 
                        trustmanagers = new TrustManager[]{new ImSureItsLegitTrustManager()};
 
                        setObjectField(param.thisObject, "sslcontext", SSLContext.getInstance(algorithm));
                        callMethod(getObjectField(param.thisObject, "sslcontext"), "init", keymanagers, trustmanagers, random);
                        setObjectField(param.thisObject, "socketfactory",
                                callMethod(getObjectField(param.thisObject, "sslcontext"), "getSocketFactory"));
                    }
 
                });
 
public SSLSocketFactory(
        String algorithm,
        final KeyStore keystore,
        final String keystorePassword,
        final KeyStore truststore,
        final SecureRandom random,
        final HostNameResolver nameResolver)
        throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException
    {
        super();
        if (algorithm == null) {
            algorithm = TLS;
        }
        KeyManager[] keymanagers = null;
        if (keystore != null) {
            keymanagers = createKeyManagers(keystore, keystorePassword);
        }
        TrustManager[] trustmanagers = new TrustManager[]{new ImSureItsLegitTrustManager()};;//这里被替换了,就这么简单
        this.sslcontext = SSLContext.getInstance(algorithm);
        this.sslcontext.init(keymanagers, trustmanagers, random);
        this.socketfactory = this.sslcontext.getSocketFactory();
        this.nameResolver = nameResolver;
    }
public SSLSocketFactory(
        String algorithm,
        final KeyStore keystore,
        final String keystorePassword,
        final KeyStore truststore,
        final SecureRandom random,
        final HostNameResolver nameResolver)
        throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException
    {
        super();
        if (algorithm == null) {
            algorithm = TLS;
        }
        KeyManager[] keymanagers = null;
        if (keystore != null) {
            keymanagers = createKeyManagers(keystore, keystorePassword);
        }
        TrustManager[] trustmanagers = new TrustManager[]{new ImSureItsLegitTrustManager()};;//这里被替换了,就这么简单
        this.sslcontext = SSLContext.getInstance(algorithm);
        this.sslcontext.init(keymanagers, trustmanagers, random);
        this.socketfactory = this.sslcontext.getSocketFactory();
        this.nameResolver = nameResolver;
    }
findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "getSocketFactory", new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                return (SSLSocketFactory) newInstance(SSLSocketFactory.class);
            }
        });
findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "getSocketFactory", new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                return (SSLSocketFactory) newInstance(SSLSocketFactory.class);
            }
        });
public static SSLSocketFactory getSocketFactory() {
    //return NoPreloadHolder.DEFAULT_FACTORY;
    return new SSLSocketFactory();
}
public static SSLSocketFactory getSocketFactory() {
    //return NoPreloadHolder.DEFAULT_FACTORY;
    return new SSLSocketFactory();
}
findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "isSecure", Socket.class, new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                return true;
            }
        });
findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "isSecure", Socket.class, new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                return true;
            }
        });
public boolean isSecure(Socket sock)
        throws IllegalArgumentException {
        return true;
}
public boolean isSecure(Socket sock)
        throws IllegalArgumentException {
        return true;
}
findAndHookMethod("javax.net.ssl.TrustManagerFactory", lpparam.classLoader, "getTrustManagers", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
 
                if (hasTrustManagerImpl()) {
                    Class<?> cls = findClass("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader);
 
                    TrustManager[] managers = (TrustManager[]) param.getResult();
                    if (managers.length > 0 && cls.isInstance(managers[0]))
                        return;
                }
 
                param.setResult(new TrustManager[]{new ImSureItsLegitTrustManager()});
            }
        });
findAndHookMethod("javax.net.ssl.TrustManagerFactory", lpparam.classLoader, "getTrustManagers", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
 
                if (hasTrustManagerImpl()) {
                    Class<?> cls = findClass("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader);
 
                    TrustManager[] managers = (TrustManager[]) param.getResult();
                    if (managers.length > 0 && cls.isInstance(managers[0]))
                        return;
                }
 
                param.setResult(new TrustManager[]{new ImSureItsLegitTrustManager()});
            }
        });
 
public final TrustManager[] getTrustManagers() {
     TrustManager[] originResult = factorySpi.engineGetTrustManagers();//原代码是直接return factorySpi.engineGetTrustManagers()
    if (hasTrustManagerImpl()) {
        Class<?> cls = Class.from("com.android.org.conscrypt.TrustManagerImpl");
        if (originResult.length > 0 && cls.isInstance(originResult[0])) {
            return originResult;
        }
    }
    return new TrustManager[]{new ImSureItsLegitTrustManager()};
}
public final TrustManager[] getTrustManagers() {
     TrustManager[] originResult = factorySpi.engineGetTrustManagers();//原代码是直接return factorySpi.engineGetTrustManagers()
    if (hasTrustManagerImpl()) {
        Class<?> cls = Class.from("com.android.org.conscrypt.TrustManagerImpl");

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2021-5-6 10:34 被爬虫不看学历编辑 ,原因:
收藏
免费 6
支持
分享
最新回复 (77)
雪    币: 14824
活跃值: (6063)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
xposed能被检测到,你说得好像frida不能被检测到?
2021-5-6 11:26
0
雪    币: 831
活跃值: (2830)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
tDasm xposed能被检测到,你说得好像frida不能被检测到?
检测frida比xposed难,而且frida可以用gadget做嵌入式。
不要跟我耍嘴皮子,你就拿一个xposed做不到的来到frida这边试试。如果我frida也做不到我什么都不说。在这打嘴仗有什么用?实践才是检验真理的唯一标准!
2021-5-6 11:48
1
雪    币: 1867
活跃值: (3958)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
笑死了,对抗是无穷的。Frida gadget就检测不到了么,artmethod这么多痕迹。
就算不看虚拟机层面
1. 普通方式使用frida,你的root痕迹,ptrace痕迹
2. gadget你的重打包痕迹
3. 你引入了其他的so,/proc/maps

再比如,我自己hook了一下虚拟机的classloader,或者class,那么所有class被加载的过程一样被监控到。方法执行可以被trace。

只要你搞了,总会留痕迹的。

另外不要说我们打嘴炮,因为你发文章也是同样的带着攻击色彩的嘴炮,反而如果你真要实践检验真理,我可以配合你。当然你要给配合费用。要不凭什么为你的无知付出我们的精力呢?
2021-5-6 12:47
3
雪    币: 3355
活跃值: (14008)
能力值: ( LV9,RANK:230 )
在线值:
发帖
回帖
粉丝
5
"本人是不认可xposed的。xposed的hook机制从设计之初就走了一条“不归路”,因为xposed有太多的特征可以被app检测。"

当看完这句话的时候我就觉得帖子没必要往下看了。
一个喝水的人说别人挖的井不好。
2021-5-6 12:58
8
雪    币: 3907
活跃值: (5817)
能力值: ( LV12,RANK:200 )
在线值:
发帖
回帖
粉丝
6
https://github.com/r0ysue/r0capture
2021-5-6 13:19
11
雪    币: 18
活跃值: (1059)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
7
楼上几位是有问题吗?人家只是发表一下自己观点有必要互相针对性言语攻击?大家平静的讨论就好了.
2021-5-6 13:40
0
雪    币: 1867
活跃值: (3958)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
8
猪会被杀掉 楼上几位是有问题吗?人家只是发表一下自己观点有必要互相针对性言语攻击?大家平静的讨论就好了[em_10].
可以发表自己观点啊,但是他的观点本身带有偏见。

首先,如果观点是不完美的,这个是看读者的接受能力,和作者自己的功底。允许观点不完美是很正常的。
如果观点是错误的,那么可能误导读者,对读者来说增加负担,这是不太好的。
如果观点是错误的,并且带有了偏见。这就是需要批判的。

怼他的主要原因是,它本身观点不能闭环,在主文章内容中就带有攻击色彩,别人对他的评论就事论事而已,他说别人打嘴炮。既然这样,为啥要容忍?从我来看,他很狂,但是并没有达到能过让他狂傲的资本。
2021-5-6 13:55
5
雪    币: 831
活跃值: (2830)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
@virjar 我知道你是谁,你开了班。教了些用xposed、ast的技术,还有一些所谓的对抗风控。不过是糊弄人而已,骗骗新人还可以。
2021-5-6 14:00
0
雪    币: 831
活跃值: (2830)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
@virjar 你的教程里面就没有破绽吗?要不要我针对你教程专门做几篇专题,来让大家看看你割韭菜套路。别在这跟我扯,你那一套根本不行。如果逆向的技术好比武功,我可以打死你!!!
2021-5-6 14:03
0
雪    币: 831
活跃值: (2830)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
@virjar 我是没有狂傲的资本,但是对付你还是绰绰有余的。
2021-5-6 14:11
0
雪    币: 1867
活跃值: (3958)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
12
风控对抗是无尽的,我从开班那天的公开课就说过,我已经看到了风控对抗的终点,这个终点是以攻击侧失败作为结局。你要是真了解过我不应该不知道我的基本观点。

1. 证明你无知,对技术没有敬畏,对要怼的人不了解。
2. 我从来不认为我的逆向功底多牛逼。我做爬虫5年,到现在一个so都不会破解。但是你又咋滴,这样你就比我牛么??
3. 本人985毕业,从10年前开始不谈恋爱天天研究技术,痴迷到魔怔的地步。你就B占录个视频,发表个爬虫不看学历,发表仇视学历高的言论。就好像你真的能在技术上打死我了?你想啥呢??

广告:本人收学生,教风控对抗、沙箱开发、中间件开发等技术,有需求同学欢迎报名
2021-5-6 14:18
9
雪    币: 831
活跃值: (2830)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
@virjar 切,还靠开班赚钱。证明你技术不到家,灰产搞不了。只能靠割割新人的韭菜来赚钱!你开班一年能赚几个W?。你是被新人天天拍马屁,有点不习惯人家口气牛一点是吧。而且你教程里还有拿人家商业的app来教课的,这是有法律风险的。要是想弄你,那真是分分钟的事儿。
2021-5-6 14:34
0
雪    币: 1867
活跃值: (3958)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
14
爬虫不看学历 @virjar 切,还靠开班赚钱。证明你技术不到家,灰产搞不了。只能靠割割新人的韭菜来赚钱!你开班一年能赚几个W?。你是被新人天天拍马屁,有点不习惯人家口气牛一点是吧。而且你教程里还有拿人家商业的ap ...
滚吧,我课程app我自己写的框架。开班赚钱随手而为。你哪里的证据看到我用了别人商业app?
还是刚刚那个问题,你知道我在做啥业务?不了解就不要瞎怼,越怼越证明你无知。

如果你要怼我,是需要相互回答和反驳对方的提问。请你不要一个问题没有回答完成就快速切换话题。我所有对你提出的疑问,请你一一标记好回答。不要打太极拳,说你这里不行你怼哪里。小丑一样

怼人需要有条理,要不然其他看官不会认同你。基本的辩论知识还是有的。如果你不会这些知识,你可以去报一个成人本科,参加参加社团活动,比如辩论队啊,拉拉队啊啥的
2021-5-6 14:51
4
雪    币: 268
活跃值: (786)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
2021-5-6 14:54
0
雪    币: 853
活跃值: (488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
2021-5-6 14:57
0
雪    币: 831
活跃值: (2830)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
17

@virjar ********。我的文章不欢迎你看!**************!!!

最后于 2021-5-6 15:03 被kanxue编辑 ,原因: 就事论事,文明用语,勿人身攻击
2021-5-6 14:59
0
雪    币: 154
活跃值: (3786)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
18
2021-5-6 15:03
0
雪    币: 178
活跃值: (156)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
2021-5-6 15:05
0
雪    币: 529
活跃值: (2681)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
20
赞成就事论事的辩论态度,辩论也是一种逆向分析和对抗,直接人身攻击和掀桌子玩不起的人(看不起...
2021-5-6 15:07
6
雪    币: 1122
活跃值: (1928)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
21
爬虫不看学历 检测frida比xposed难,而且frida可以用gadget做嵌入式。 不要跟我耍嘴皮子,你就拿一个xposed做不到的来到frida这边试试。如果我frida也做不到我什么都不说。在这打嘴仗有 ...

检测frida一些方式,不过是英文的,看不懂你可以用翻译工具:
1. Detect Frida for Android

2. The Jiu-Jitsu of Detecting Frida
3. b-mueller/frida-detection-demo


最后于 2021-5-6 15:43 被lushanu编辑 ,原因:
2021-5-6 15:12
3
雪    币: 1985
活跃值: (1800)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
2021-5-6 15:14
0
雪    币: 3071
活跃值: (4152)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
2021-5-6 15:15
0
雪    币: 181
活跃值: (2943)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
2021-5-6 15:17
0
雪    币: 20
活跃值: (35)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
roysue https://github.com/r0ysue/r0capture
为何楼主不喷你 你要好好反思一下了[手动狗头]
2021-5-6 15:18
0
游客
登录 | 注册 方可回帖
返回
//