开发应用识别软件遇到的一些windows编程技能
(1)winmain函数的参数解析:
/* 对于64位应用程序的处理,64位的SR进程只负责将64位dll注入到64位应用程序中,其他工作都由32位SR进程处理 */ LPWSTR *szArgList; int argCount; szArgList = CommandLineToArgvW(GetCommandLine(), &argCount); if (argCount != 2){ g_log.SR_PRintf("SR argument is wrong (%d)", argCount); return -1; } HWND hWnd = (HWND)_ttol(szArgList[0]); if (!IsWindow(hWnd)){ g_log.SR_printf("Hwnd is invalid in 64 bits sr"); return -1; } HANDLE hEvent = (HANDLE)_ttol(szArgList[1]); (2)向某个线程的消息队列发送消息:需要在线程中创建消息队列才能使用PostThreadMessage发送消息。LRESULT WINAPI DoExchangeThread(LPVOID lp) { MSG msg; PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);/* force the system to create the message queue */ while (GetMessage(&msg, 0, 0, 0)) { switch (msg.message) { case WM_QUIT_THREAD:/* 通知线程退出 */ g_app_manager.ClearInfo(); return 0; case WM_VM_RECOVER: g_app_manager.ReSendInfo(); break; case WM_VM_RESET: g_app_manager.m_qxl.ResetVersion(); break; case WM_HANDLE_SR: DoSrMessage(msg.wParam, msg.lParam); delete[] (BYTE *)msg.lParam; break; } } return 0; }(3)使用WaitForMultipleObjects监控一组进程的退出消息
LRESULT WINAPI ProcessMoniThread(LPVOID lp) { CAppManager *pManager = (CAppManager *)lp; while (!pManager->m_bStop){ size_t size = pManager->m_appSet.size(); HANDLE *handles = new HANDLE[size + 1]; if (handles == NULL){ g_log.SR_printf("New handles failed error=%d", GetLastError()); break; } DWord *ids = new DWORD[size + 1]; if (ids == NULL){ g_log.SR_printf("New ids failed error=%d", GetLastError()); delete[] handles; break; } int nIndex = 1; handles[0] = pManager->m_hNotice; ids[0] = 0; for (auto item : pManager->m_appSet){ DWORD dwProcessId = item->GetProcessId(); HANDLE hProcess = item->GetProcess(); if (hProcess == nullptr){ pManager->Remove(dwProcessId); } else{ handles[nIndex] = hProcess; ids[nIndex] = dwProcessId; nIndex++; } } DWORD dwRet = WaitForMultipleObjects(nIndex, handles, FALSE, INFINITE);/* 等待有事件激活 */ int nStatus = dwRet - WAIT_OBJECT_0; if (nStatus > 0){/* 有进程退出 */ pManager->Remove(ids[nStatus]); } delete[] handles; delete[] ids; if (nStatus < 0){ g_log.SR_printf("Wait process exit failed error=%d", GetLastError()); break; } } return TRUE; }(4)内存映射文件的使用bool CSRParser::MakeConfDataShared() { size_t nItemCount = m_mapAttr.size();/* 需要增加全局配置 */ DWORD dwSize = sizeof(SRSharedConfData) + nItemCount*sizeof(SRConData); m_hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, dwSize, SR_FILE_MAP_NAME); if (m_hMapFile == nullptr){ g_log.SR_printf("File map failed error=%d", GetLastError()); return false; } if (GetLastError() == ERROR_ALREADY_EXISTS){ g_log.SR_printf("File map already exists."); CloseHandle(m_hMapFile); m_hMapFile = nullptr; return false; } m_sharedData = (SRSharedConfData *)MapViewOfFile(m_hMapFile, FILE_MAP_ALL_access, 0, 0, 0); if (m_sharedData == nullptr){ g_log.SR_printf("MapViewOfFile failed error=%d", GetLastError()); CloseHandle(m_hMapFile); m_hMapFile = nullptr; return false; } m_sharedData->nCount = (DWORD)nItemCount; int nIndex = 0; for (auto &item : m_mapAttr){ strcpy_s(m_sharedData->buff[nIndex].szName, item.first.c_str()); m_sharedData->buff[nIndex].attr = item.second; nIndex++; } return true; }(5)子进程继承父进程的内核对象SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE;/* 需要继承,这样子进程可以访问共享该句柄 */ m_hChild = CreateEvent(&sa, FALSE, FALSE, NULL); if (m_hChild == NULL){ g_log.SR_printf("Create child event failed error=%d", GetLastError() ); } void CAppManager::StartSR64(HWND hWnd) { if (m_hChild == NULL){ g_log.SR_printf("Start 64 sr failed,m_hChild is NULL."); return; } STARTUPINFO si; PROCESS_INFORMATION pi; TCHAR szCommandLine[64]; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); swprintf_s(szCommandLine, _T("%ld %ld"), hWnd, m_hChild); TCHAR szPath[MAX_PATH]; GetModuleFileName(NULL, szPath, sizeof(szPath)); TCHAR *p = _tcsrchr(szPath, _T('\\')); if (p != NULL){ *p = _T('\0'); } _tcscat_s(szPath, _T("\\SR64.exe")); if (!CreateProcess(szPath, szCommandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)){ g_log.SR_printf("Create child process failed.(%d)", GetLastError()); } CloseHandle(pi.hThread); CloseHandle(pi.hProcess); } (6)在没有权限的情况下通过进程句柄查询进程信息BOOL IsSRProcess(HANDLE hProcess) { char szFileName[MAX_PATH]; HANDLE hProcessAccAdj; /* 因为hProcess没有查询权限,如果直接调用查询的函数会返回失败,所以需要复制一个句柄并给予查询权限 */ BOOL bRes = DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hProcessAccAdj, PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OperaTION | PROCESS_VM_WRITE, FALSE, 0); if (!bRes || hProcessAccAdj == NULL){ UINT unError = GetLastError(); return 0xffffffff; } GetProcessImageFileNameA(hProcessAccAdj, szFileName, sizeof(szFileName)); const char *p = strrchr(szFileName, '\\'); if (p != NULL){ return _stricmp("SR64.exe", p + 1) == 0 || _stricmp("SR.exe", p + 1) == 0; } else{ return _stricmp("SR.exe", szFileName) == 0 || _stricmp("SR64.exe", szFileName) == 0; } /* win Vista以上系统可使用 QueryFullProcessImageName */ }(6)可等待计时器对象的使用bool CMouseController::SetWheelTimer() { LARGE_INTEGER liDueTime; HANDLE handle = m_handles[STATUS_WHEEL_TIME_TO_SEND]; liDueTime.QuadPart = -10000 * m_scrollTimeval;//SEDN_WHEEL_TIME_INTERVAL; if (!SetWaitableTimer(handle, &liDueTime, 0, NULL, NULL, FALSE)){ SRLog("SetWaitableTimer1 failed error=%d", GetLastError()); m_bIsInvalid = false; return false; } return true; }