C# hijack NSQuery::LookupServiceNext(DNS解析)

为什么要这方面的研究?这是由于“PaperAirplane”的NSP(名称服务提供者) 开发过程受到一些挫折 主要是Ws32调用了MY-NSP解析 但它还需要调用其它的NSP解析 通过分析它是通过NSQuery::LookupServiceDispatch函数 循环派发调用多个NSP解析 然后组合这些数据 这就造成了MY-NSP解析的Fuck A记录不在最顶部 而且Ws32只会调用一次后就不在调用 NSQuery有一些优化策略会预先查询DNS缓存、

而为了此解决问题 过而想剑走偏锋试试一试 不过后面在不断的探索与琢磨“Proxifer”NSP部分 解决了这个问题 本文提出的方法也就被丢弃 本身这个技术就不是那么好 而且需要用到hook

NSQuery不知道是一个静态类还是实例类 似乎看见它在操作RCX 但不知带是否代表实例地址~~~首先说明我研究测试de代码是在Win10 x64 14393.10上面 其它Win32版本 应该是不可用的 hook的目标函数RVA对称是不同的

NSQuery::LookupServiceNext位于Ws_32.dll Module被映射地址空间的0x97e0处 即只要[Ws_32.dll] + 0x97e0 即可 那么hook NSQuery::LookupServiceNext有什么意义?实际上应用层调用getaddrinfo、gethostbyname、DNSQuery等函数。它们都只是针对WSALookupServiceXXX函数

的一个函数封装 最终都会调用到这几个函数身上

它们先调用 WSALookupServiceBegin 分配hLookup句柄、然后在循环解析的部分调用WSALookupServiceNext直到它返回SOCKET_ERROR终止在调用

WSALookupServiceEnd关闭hLookup句柄。

WSALookupServiceNext函数会调用NSQuery::LookupServiceNext函数 而WSALookupServiceNext函数是分A、W字符串版本的 而它们调用的

NSQuery::LookupServiceNext函数是不区分统一是W版本 A版本调用效率是不如W版的它需要经过至少一层转换与拷贝。主要是拷贝struct WSAQUERYSETA为

struct WSAQUERYSETW本质上没什么区别就是字符串有些区别。

另一个好的方面是NSQuery导出的“LookupServiceNext”、“LookupServiceEnd”、“LookupServiceBegin”函数参数个数 与“WSALookupServiceEnd”...是完全一

致的 唯一不同的是它是真正循环调用多个NSP执行任务的入口

        NetHook_x64 DNSQUERY_LookupServiceNext = new NetHook_x64();
        IntPtr hModule = LoadLibrary("ws2_32.dll");
        DNSQUERY_LookupServiceNext.Install(
            (IntPtr)(hModule.ToInt64() + 0x97e0), DNSQUERY_LookupServiceNext.GetProcAddress(new LPDNSQUERY_LookupServiceNext(
                delegate (IntPtr hLookup, uint dwControlFlags, uint* lpdwBufferLength, WSAQUERYSETW* lpqsResults)
                {
                    if (lpqsResults->lpszServiceInstanceName != null)
                    {
                        Console.WriteLine(new string(lpqsResults->lpszServiceInstanceName));
                    }
                    DNSQUERY_LookupServiceNext.Suspend();
                    int error = WSALookupServiceNextW(hLookup, dwControlFlags, lpdwBufferLength, lpqsResults);
                    DNSQUERY_LookupServiceNext.Resume();
                    if (lpqsResults->dwNumberOfCsAddrs > 0)
                    {
                        CSADDR_INFO* addr = lpqsResults->lpcsaBuffer;
                        for (int i = 0; i < lpqsResults->dwNumberOfCsAddrs; i++)
                        {
                            sockaddr_in* remote = addr->RemoteAddr.lpSockaddr;
                            remote->sin_addr = 0x80000001;
                            addr++;
                        }
                    }
                    return error;
        })));
Nethook的代码可以从https://github.com/liulilittle/NetHook/blob/master/NetHook_x64.cs处获取、上述代码中利用hook成功的串改了通过nsp解析出的dns地址

但它没有区分被修改过的address是AF_INNET or AF_INNET6 所以可能会造成一些错误~如果你需要完整的测试de c#代码

你可以从 https://pan.baidu.com/s/1c1NyPMw 获取~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值