您的位置:首页 > 产品设计 > UI/UE

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

2017-09-17 09:24 381 查看
为什么要这方面的研究?这是由于“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 获取~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: