开发应用识别软件遇到的一些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;
}






你可能感兴趣的:(win32)