1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
| typedef struct TBBUTTON64 { int iBitmap; int idCommand; BYTE fsState; // TBSTATE_CHECKED 等 BYTE fsStyle; // TBSTYLE_BUTTON 等 BYTE bReserved[6]; int64_t dwData; int64_t iString; BYTE test[100]; } ; struct TRAYDATA64 { int64_t hWnd; uint32_t uID; uint32_t uCallbackMessage; uint32_t Reserved1[2]; int64_t hIcon; uint32_t Reserved2[4]; TCHAR szExePath[MAX_PATH]; TCHAR szTip[128]; };
struct TRAYDATA32 { HWND hwnd; UINT uID; UINT uCallbackMessage; DWORD Reserved[2]; HICON hIcon; DWORD Reserved2[3]; TCHAR szExePath[MAX_PATH]; TCHAR szTip[128]; };
bool IsWow64ProcessEx( HANDLE hProcess ) { /*判断ntdll中的导出函数,可知是否是64位OS*/ HMODULE hMod = GetModuleHandle(_T("ntdll.dll")); FARPROC x64fun = ::GetProcAddress(hMod,"ZwWow64ReadVirtualMemory64"); if(!x64fun) { return false; }
/*利用IsWow64Process判断是否是x64进程*/ typedef BOOL(WINAPI *pfnIsWow64Process)(HANDLE,PBOOL); pfnIsWow64Process fnIsWow64Process = NULL;
hMod = GetModuleHandle(_T("kernel32.dll")); fnIsWow64Process = (pfnIsWow64Process)GetProcAddress(hMod,"IsWow64Process"); if(!fnIsWow64Process) //如果没有导出则判定为32位 { return false; }
BOOL bX64; if(!fnIsWow64Process(hProcess, &bX64)) { return false; }
return !bX64; }
template<typename BUTTONTYPE, typename TRAYDATA_TYPE> void EnumIcons(size_t buttonNumber, HANDLE hProcess, LPVOID pAddress, HWND hWnd) { for( int i=0; i< buttonNumber; i++ ) { long lRet = 0;
// 读取图标结构体 BUTTONTYPE buttonInfo = {0}; DWORD dwBytes = 0; ::WriteProcessMemory(hProcess, pAddress, &buttonInfo, sizeof(buttonInfo), &dwBytes); lRet = ::SendMessage( hWnd, TB_GETBUTTON, i, long(pAddress) ); lRet = ReadProcessMemory( hProcess, pAddress, &buttonInfo, sizeof(buttonInfo), &dwBytes);
// 读取TrayData TRAYDATA_TYPE trayData; lRet = ::ReadProcessMemory(hProcess, (LPVOID)buttonInfo.dwData, &trayData, sizeof(trayData), NULL);
// 方法1. 直接从ButtonInfo成员的string地址读取图标标题 TCHAR szTips[1024]; ::ReadProcessMemory(hProcess, (void*)(buttonInfo.iString),szTips, 1024, &dwBytes); OutputDebugString(szTips);
// 方法2. 从TrayData中读取图标标题和程序路径 OutputDebugString(trayData.szTip); OutputDebugString(trayData.szExePath);
// 方法3. 发送消息,读取图标标题 SendMessage(hWnd, TB_GETBUTTONTEXT, buttonInfo.idCommand, LPARAM(LPARAM(pAddress) + sizeof(buttonInfo))); ::ReadProcessMemory(hProcess, (void*)(LPARAM(pAddress) + sizeof(buttonInfo)),szTips, 1024, &dwBytes); OutputDebugString(szTips); } }
// 判断在通知区域是否有托盘图标 BOOL IsTrayIconExsitInNotifyArea() { HWND hWnd = NULL, hWndPager = NULL; unsigned long ulPID = 0; long lRet = 0, lButtons = 0; HANDLE hProcess = NULL; LPVOID pAddress = NULL; long lTextAdr = 0, lHwndAdr = 0, lHwnd = 0, lButtonID = 0; char strBuff[1024] = { 0 }; char_t *pStr = NULL; char *pTemp = NULL;
hWnd = ::FindWindow( _T("Shell_TrayWnd"), NULL ); hWnd = ::FindWindowEx( hWnd, 0, _T("TrayNotifyWnd"), NULL ); hWndPager = ::FindWindowEx( hWnd, 0, _T("SysPager"), NULL ); if( hWndPager == NULL ) { hWnd = ::FindWindowEx( hWnd, 0, _T("ToolbarWindow32"), NULL ); // 对于Win2000,没有SysPager窗口 } else { hWnd = ::FindWindowEx( hWndPager, 0, _T("ToolbarWindow32"), NULL ); }
lRet = GetWindowThreadProcessId( hWnd, &ulPID ); hProcess = OpenProcess(PROCESS_ALL_ACCESS|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, 0, ulPID ); pAddress = VirtualAllocEx( hProcess, 0, 0x4096, MEM_COMMIT, PAGE_READWRITE ); lButtons = ::SendMessage( hWnd, TB_BUTTONCOUNT, 0, 0 );
if (IsWow64ProcessEx(hProcess)) { EnumIcons<TBBUTTON64, TRAYDATA64>(lButtons, hProcess, pAddress, hWnd); } else { EnumIcons<TBBUTTON, TRAYDATA32>(lButtons, hProcess, pAddress, hWnd); }
VirtualFreeEx( hProcess, pAddress, 0X4096, MEM_RELEASE ); CloseHandle( hProcess );
return FALSE; }
// 判断在托盘溢出区域是否有托盘图标 BOOL IsTrayIconExsitInOverflowWindow() { HWND hWnd = NULL, hWndPager = NULL; unsigned long ulPID = 0; long lRet = 0, lButtons = 0; HANDLE hProcess = NULL; LPVOID pAddress = NULL; long lTextAdr = 0, lHwndAdr = 0, lHwnd = 0, lButtonID = 0; char strBuff[1024] = { 0 }; char_t *pStr = NULL; char *pTemp = NULL;
// 对于Win7、Win8系统,新增了通知溢出区域,所以要检查该区域中是否有托盘图标 hWnd = ::FindWindow( _T("NotifyIconOverflowWindow"), NULL ); hWnd = ::FindWindowEx( hWnd, 0, _T("ToolbarWindow32"), NULL );
lRet = GetWindowThreadProcessId( hWnd, &ulPID ); hProcess = OpenProcess(PROCESS_ALL_ACCESS|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, 0, ulPID ); pAddress = VirtualAllocEx( hProcess, 0, 0x4096, MEM_COMMIT, PAGE_READWRITE ); lButtons = ::SendMessage( hWnd, TB_BUTTONCOUNT, 0, 0 );
if (IsWow64ProcessEx(hProcess)) { EnumIcons<TBBUTTON64, TRAYDATA64>(lButtons, hProcess, pAddress, hWnd); } else { EnumIcons<TBBUTTON, TRAYDATA32>(lButtons, hProcess, pAddress, hWnd); }
VirtualFreeEx( hProcess, pAddress, 0X4096, MEM_RELEASE ); CloseHandle( hProcess );
return FALSE; }
|