先写一个demo,查看FindWindowW FindWindowExW的函数指针
HMODULE hModule = LoadLibrary(L"user32.dll");
if (hModule != NULL)
{
while (true)
{
FUN_FindWindowW FindWindowWFunc = (FUN_FindWindowW)GetProcAddress(hModule, "FindWindowW");
if (FindWindowWFunc != NULL)
{
printf("FindWindowW 函数指针地址:%p\r\n", FindWindowWFunc);
HWND hWnd = FindWindowWFunc(L"123", NULL);
}
FUN_FindWindowExW FindWindowExWFunc = (FUN_FindWindowExW)GetProcAddress(hModule, "FindWindowExW");
if (FindWindowExWFunc != NULL)
{
printf("FindWindowExW 函数指针地址:%p\r\n", FindWindowExWFunc);
HWND hWnd = FindWindowExWFunc(NULL,NULL, L"DingtalkMsgComming", NULL);
int n = (BYTE*)FindWindowExWFunc - (BYTE*)FindWindowWFunc;
printf("指针偏移:%d 0X%X\r\n",n,n);
FUN_FindWindowExW TextFun = (FUN_FindWindowExW)((BYTE*)FindWindowWFunc + n);
printf("TextFun 函数指针地址:%p\r\n", TextFun);
hWnd = TextFun(NULL, NULL, L"DingtalkMsgComming", NULL);
int wjr = 0;
}
Sleep(5000);
}
FreeLibrary(hModule);
}
windbg调试该程序 设置断点
bu USER32!FindWindowW
可以看到函数指针地址和打印出来的都一样的 都是**68483650
当函数命中时,地址也一致
按F8(t)一直往下走,耐心走
可以看到他掉用了FindWindowExW函数 地址 00007ffc68485f50 和demo程序打印出来的一致
我们继续按F8还可以看到 他内部会调用USER32!InternalFindWindowExW函数,这个函数是未公开的函数地址是68485f6c
用idea工具查看下FindWindowExW函数,他调用一个sub_180025F6C函数
在点进去看
我们尝试定义InternalFindWindowExW函数原型指针
typedef HWND(WINAPI* FUN_InternalFindWindowExW)(HWND hWndParent, HWND hWndChildAfter, LPCWSTR lpClassName, LPCWSTR lpWindowName,int code);
用InternalFindWindowExW 减去 00007ffc68485f6c - FindWindowExW地址 00007ffc68485f50
= 0x1C
此时我们修改下源码
HMODULE hModule = LoadLibrary(L"user32.dll");
if (hModule != NULL)
{
while (true)
{
FUN_FindWindowW FindWindowWFunc = (FUN_FindWindowW)GetProcAddress(hModule, "FindWindowW");
if (FindWindowWFunc != NULL)
{
printf("FindWindowW 函数指针地址:%p\r\n", FindWindowWFunc);
HWND hWnd = FindWindowWFunc(L"123", NULL);
}
FUN_FindWindowExW FindWindowExWFunc = (FUN_FindWindowExW)GetProcAddress(hModule, "FindWindowExW");
if (FindWindowExWFunc != NULL)
{
printf("FindWindowExW 函数指针地址:%p\r\n", FindWindowExWFunc);
HWND hWnd = FindWindowExWFunc(NULL,NULL, L"DingtalkMsgComming", NULL);
int n = (BYTE*)FindWindowExWFunc - (BYTE*)FindWindowWFunc;
printf("指针偏移:%d 0X%X\r\n",n,n);
FUN_FindWindowExW TextFun = (FUN_FindWindowExW)((BYTE*)FindWindowWFunc + n);
printf("TextFun 函数指针地址:%p\r\n", TextFun);
HWND hWnd1 = TextFun(NULL, NULL, L"DingtalkMsgComming", NULL);
//int wjr = 0;
HWND hWnd2 = 0;
FUN_InternalFindWindowExW InternalFindWindowExWFunc = (FUN_InternalFindWindowExW)((BYTE*)FindWindowExWFunc + 0x1c);
if (InternalFindWindowExWFunc != NULL)
{
hWnd2 = InternalFindWindowExWFunc(NULL, NULL, L"DingtalkMsgComming", NULL,0);
}
int wjr = 0;
}
Sleep(5000);
}
FreeLibrary(hModule);
}
可以发现InternalFindWindowExWFunc 返回值和 FindWindowExW 一致
今天发现win7下从win10拷贝的windgb.exe不能用,后来查资料
Windows下调试工具Windbg入门_windbg core解析-CSDN博客
需要从微软官网下载win7 sdk ,其他都是win10版本
https://www.microsoft.com/en-us/download/details.aspx?id=8279
win7下如何查找Query_PrivateExW函数指针,一定要下好符号表pdb
#define WIN32_LEAN_AND_MEAN // 从 Windows 头中排除极少使用的资料
#include <windows.h>
#include <WS2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
void main()
{
WSADATA wsaData = { 0 };
WSAStartup(MAKEWORD(2, 2), &wsaData);
HMODULE hModule = LoadLibrary(L"DNSAPI.dll");
if (hModule == NULL)
{
printf("加载DNSAPI.dll失败\r\n");
return;
}
FARPROC DnsApiAlloc = GetProcAddress(hModule, "DnsApiAlloc");
if (DnsApiAlloc != NULL)
{
printf("DnsApiAlloc 函数地址: %p\r\n", DnsApiAlloc);
}
else
{
printf("DnsApiAlloc 函数地址没有找到\r\n");
}
struct addrinfoW hints;
struct addrinfoW* res, * cur;
memset(&hints, 0, sizeof(addrinfo));
res = NULL;
cur = NULL;
//初始化 hints
memset(&hints, 0, sizeof(addrinfo));
hints.ai_family = AF_UNSPEC; //IPv4/IPV6
hints.ai_flags = AI_PASSIVE; //匹配所有 IP 地址
hints.ai_protocol = 0; //匹配所有协议
hints.ai_socktype = SOCK_STREAM; //流类型
hints.ai_flags = AI_ALL;
GetAddrInfoW(L"www.baidu.com", NULL, &hints, &res);
}
写一个测试demo 调用获取dns函数
使用x64dbg调试下
先在符号 ws2_32.dll GetAddrInfoW 按F2下个断点
选择dnsapi.dll 点击右键 弹出菜单 选择下载符号,一定要下载好符号
Downloading symbol dnsapi.pdb
Signature: 70BE754EAC24444F93D3381A96404BBE2
Destination: C:\mysymbol\dnsapi.pdb\70BE754EAC24444F93D3381A96404BBE2\dnsapi.pdb
URL: https://msdl.microsoft.com/download/symbols/dnsapi.pdb/70BE754EAC24444F93D3381A96404BBE2/dnsapi.pdb
InternetOpenUrl failed ()...
如果出现下载失败,手动复制连接
https://msdl.microsoft.com/download/symbols/dnsapi.pdb/70BE754EAC24444F93D3381A96404BBE2/dnsapi.pdb
会下载一个blob文件 其实就是pdb
改个名字dnsapi.pdb然后拷贝到对应的目录下
此时从新来一遍调试
此时就可以看到符号表了
000007FEFC3E19AC - 000007FEFC3E1408 = 0x5A4 此时就可以知道
Query_PrivateExW 距离DnsApiAlloc 的便宜量是0x5A4了
在用windgb调试下,先设置好符号表
设置断点 bu WS2_32!GetAddrInfoW
但运行到断点时,查询命令x DNSAPI!Query_PrivateExW
就看到query_privateExW的函数地址了