美文网首页
拦截Android App中的域名解析

拦截Android App中的域名解析

作者: 土豆吞噬者 | 来源:发表于2019-08-27 14:57 被阅读0次

    在App使用域名访问网络时,域名解析是网络请求的第一步,该过程有时候会出现解析慢或域名劫持的情况。

    我们可以通过拦截域名解析直接返回自定义的IP或者使用HTTPDNS解析域名,如果App使用的是OKHttp,可以直接使用OKHttp的DNS接口进行拦截。

    如果App访问网络的库没有提供类似OKHttp的DNS接口,我们还可以通过hook getaddrinfo和android_getaddrinfofornet来实现域名解析拦截。

    #include <jni.h>
    #include <string>
    #include <time.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    #include <map>
    #include <malloc.h>
    #include <mutex>
    #include <string.h>
    #include "xhook/xhook.h"
    
    using namespace std;
    
    namespace {
        typedef int(*pfnAndroidGetAddrInfoForNet)(const char *hostname, const char *servname,
                                                  const struct addrinfo *hints, unsigned netid,
                                                  unsigned mark, struct addrinfo **res);
        typedef int(*pfnGetAddrInfo)(const char* __node, const char* __service,
                                     const struct addrinfo* __hints, struct addrinfo** __result);
    
        map<string,string> g_hosts;
        recursive_mutex g_mtx;
        bool g_hooked=false;
        pfnAndroidGetAddrInfoForNet g_origAndroidGetAddrInfoForNet;
        pfnGetAddrInfo g_origGetAddrInfo;
    
    
        int fakeAndroidGetAddrInfoForNet(const char *hostname, const char *servname,
                                                const struct addrinfo *hints, unsigned netid,
                                                unsigned mark, struct addrinfo **res) {
            lock_guard<recursive_mutex> guard(g_mtx);
            if (hints->ai_flags != AI_NUMERICHOST) {
                auto ip=g_hosts.find(hostname);
                if (ip!=g_hosts.end()){
                    return g_origAndroidGetAddrInfoForNet(ip->second.c_str(),servname,hints,netid,mark,res);
                }
            }
            return g_origAndroidGetAddrInfoForNet(hostname,servname,hints,netid,mark,res);
        }
    
    
        int fakeGetaddrinfo(const char* __node, const char* __service, const struct addrinfo* __hints, struct addrinfo** __result){
            lock_guard<recursive_mutex> guard(g_mtx);
            auto ip=g_hosts.find(__node);
            if (ip!=g_hosts.end()){
                return g_origGetAddrInfo(ip->second.c_str(),__service,__hints,__result);
            }
            return g_origGetAddrInfo(__node,__service,__hints,__result);
        }
    
    }
    
    
    extern "C" JNIEXPORT void JNICALL Java_com_xxxx_addHost(
            JNIEnv *env,jclass,jstring host,jstring name) {
        auto hostRawValue=env->GetStringUTFChars(host, nullptr);
        auto nameRawValue=env->GetStringUTFChars(name, nullptr);
        if (hostRawValue && nameRawValue){
            lock_guard<recursive_mutex> guard(g_mtx);
            g_hosts[nameRawValue]=hostRawValue;
        }
    }
    
    
    extern "C" JNIEXPORT void JNICALL Java_com_xxxx_clearHosts(
            JNIEnv *env,jclass) {
        lock_guard<recursive_mutex> guard(g_mtx);
        g_hosts.clear();
    }
    
    
    
    extern "C" JNIEXPORT jint JNICALL Java_com_xxxx_startHook(
            JNIEnv *env,jclass) {
        if (!g_hooked){
            //xhook_enable_debug(1);
            xhook_register(".*\\.so$", "getaddrinfo",  (void *)&fakeGetaddrinfo,
                    reinterpret_cast<void **>(&g_origGetAddrInfo));
            xhook_register(".*\\.so$", "android_getaddrinfofornet",(void *)fakeAndroidGetAddrInfoForNet,
                    reinterpret_cast<void **>(&g_origAndroidGetAddrInfoForNet));
            xhook_ignore(".*/libxxxx.so$", NULL);
            xhook_refresh(0);
            g_hooked= true;
        }
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:拦截Android App中的域名解析

          本文链接:https://www.haomeiwen.com/subject/uteeectx.html