void CPluginBackground::UpdateBackground_Exec(struct RegisterBackgroundArg *pPlugin, struct PaintBackgroundArg *pArg) { if (!CheckCallbackPtr(pPlugin->hPlugin, 1, (FARPROC*)&pPlugin->PaintConEmuBackground, TRUE, FALSE, FALSE)) return; pPlugin->PaintConEmuBackground(pArg); //if (!pPlugin->PaintConEmuBackground) //{ // _ASSERTE(pPlugin->PaintConEmuBackground!=NULL); // return; //} //if (((DWORD_PTR)pPlugin->PaintConEmuBackground) < ((DWORD_PTR)pPlugin->hPlugin)) //{ // _ASSERTE(((DWORD_PTR)pPlugin->PaintConEmuBackground) >= ((DWORD_PTR)pPlugin->hPlugin)); // return; //} //#ifdef _DEBUG // if (((DWORD_PTR)pPlugin->PaintConEmuBackground) > ((4<<20) + (DWORD_PTR)pPlugin->hPlugin)) // { // _ASSERTE(((DWORD_PTR)pPlugin->PaintConEmuBackground) <= ((4<<20) + (DWORD_PTR)pPlugin->hPlugin)); // } //#endif }
int CPluginBackground::RegisterSubplugin(RegisterBackgroundArg *pbk) { if (!pbk) { _ASSERTE(pbk != NULL); return esbr_InvalidArg; } if (!gbBgPluginsAllowed) { _ASSERTE(gbBgPluginsAllowed == TRUE); return esbr_PluginForbidden; } if (pbk->cbSize != sizeof(*pbk)) { _ASSERTE(pbk->cbSize == sizeof(*pbk)); return esbr_InvalidArgSize; } if (pbk->Cmd == rbc_Register) { BOOL lbCheckCallback = CheckCallbackPtr(pbk->hPlugin, 1, (FARPROC*)&pbk->PaintConEmuBackground, TRUE, FALSE, FALSE); if (!lbCheckCallback) { _ASSERTE(lbCheckCallback==TRUE); return esbr_InvalidArgProc; } } MSectionLock SC; SC.Lock(csBgPlugins, TRUE); // Выделение памяти под плагины if (mp_BgPlugins == NULL || (mn_BgPluginsCount == mn_BgPluginsMax)) ReallocItems(16); // go //BOOL lbNeedResort = FALSE; if (pbk->Cmd == rbc_Register) { // Память уже выделена int nFound = -1, nFirstEmpty = -1; for(int i = 0; i < mn_BgPluginsCount; i++) { if (mp_BgPlugins[i].Cmd == rbc_Register && mp_BgPlugins[i].hPlugin == pbk->hPlugin && mp_BgPlugins[i].PaintConEmuBackground == pbk->PaintConEmuBackground && mp_BgPlugins[i].lParam == pbk->lParam) { nFound = i; break; } if (nFirstEmpty == -1 && 0 == (int)mp_BgPlugins[i].Cmd) nFirstEmpty = i; } if (nFound == -1) { if (nFirstEmpty >= 0) nFound = nFirstEmpty; else nFound = mn_BgPluginsCount++; //lbNeedResort = (mn_BgPluginsCount>1); } mp_BgPlugins[nFound] = *pbk; } else if (pbk->Cmd == rbc_Unregister) { for(int i = 0; i < mn_BgPluginsCount; i++) { if (mp_BgPlugins[i].Cmd == rbc_Register && mp_BgPlugins[i].hPlugin == pbk->hPlugin && ((pbk->PaintConEmuBackground == NULL) || (mp_BgPlugins[i].PaintConEmuBackground == pbk->PaintConEmuBackground && mp_BgPlugins[i].lParam == pbk->lParam))) { memset(mp_BgPlugins+i, 0, sizeof(*mp_BgPlugins)); //lbNeedResort = TRUE; } } WARNING("Если количество зарегистрированных плагинов уменьшилось до 0"); // Послать в GUI CECMD_SETBACKGROUND{bEnabled = FALSE} // Проверить, чтобы не было противного мелькания при закрытии FAR } else if (pbk->Cmd == rbc_Redraw) { // просто выставить gbNeedBgActivate } ////TODO: Сортировка //if (lbNeedResort) //{ // WARNING("Сортировка зарегистрированных плагинов - CPluginBackground::RegisterBackground"); //} SC.Unlock(); // Когда активируется MainThread - обновить background mn_ReqActions |= ra_UpdateBackground; gbNeedBgActivate = TRUE; // В фар2 сразу дернем Synchro if (IS_SYNCHRO_ALLOWED) { Plugin()->ExecuteSynchro(); } return esbr_OK; }
int WINAPI RequestLocalServer(/*[IN/OUT]*/RequestLocalServerParm* Parm) { int iRc = CERR_SRVLOADFAILED; if (!Parm || (Parm->StructSize != sizeof(*Parm))) { iRc = CERR_CARGUMENT; goto wrap; } //RequestLocalServerParm Parm = {(DWORD)sizeof(Parm)}; if (Parm->Flags & slsf_AltServerStopped) { iRc = 0; // SendStopped посылается из DllStop! goto wrap; } if (!ghSrvDll || !gfRequestLocalServer) { LPCWSTR pszSrvName = WIN3264TEST(L"ConEmuCD.dll",L"ConEmuCD64.dll"); if (!ghSrvDll) { gfRequestLocalServer = NULL; ghSrvDll = GetModuleHandle(pszSrvName); } if (!ghSrvDll) { wchar_t *pszSlash, szFile[MAX_PATH+1] = {}; GetModuleFileName(ghOurModule, szFile, MAX_PATH); pszSlash = wcsrchr(szFile, L'\\'); if (!pszSlash) goto wrap; pszSlash[1] = 0; wcscat_c(szFile, pszSrvName); ghSrvDll = LoadLibrary(szFile); if (!ghSrvDll) goto wrap; } gfRequestLocalServer = (RequestLocalServer_t)GetProcAddress(ghSrvDll, "PrivateEntry"); } if (!gfRequestLocalServer) goto wrap; _ASSERTE(CheckCallbackPtr(ghSrvDll, 1, (FARPROC*)&gfRequestLocalServer, TRUE)); //iRc = gfRequestLocalServer(&gpAnnotationHeader, &ghCurrentOutBuffer); iRc = gfRequestLocalServer(Parm); if ((iRc == 0) && (Parm->Flags & slsf_PrevAltServerPID)) { gnPrevAltServerPID = Parm->nPrevAltServerPID; } wrap: return iRc; }
// 0 - OK, иначе - ошибка // Здесь вызывается CreateRemoteThread int InfiltrateDll(HANDLE hProcess, LPCWSTR asConEmuHk) { int iRc = -150; //if (iRc != -150) //{ // InfiltrateProc(NULL); InfiltrateEnd(); //} //const size_t cb = ((size_t)InfiltrateEnd) - ((size_t)InfiltrateProc); InfiltrateArg dat = {}; HMODULE hKernel = NULL; HANDLE hThread = NULL; DWORD id = 0; LPTHREAD_START_ROUTINE pRemoteProc = NULL; PVOID pRemoteDat = NULL; CreateRemoteThread_t _CreateRemoteThread = NULL; char FuncName[20]; void* ptrCode; size_t cbCode; //_ASSERTE("InfiltrateDll"==(void*)TRUE); cbCode = GetInfiltrateProc(&ptrCode); // Примерно, проверка размера кода созданного компилятором if (cbCode != WIN3264TEST(68,79)) { _ASSERTE(cbCode == WIN3264TEST(68,79)); iRc = -100; goto wrap; } if (lstrlen(asConEmuHk) >= (int)countof(dat.szConEmuHk)) { iRc = -101; goto wrap; } // Исполняемый код загрузки библиотеки pRemoteProc = (LPTHREAD_START_ROUTINE) VirtualAllocEx( hProcess, // Target process NULL, // Let the VMM decide where cbCode, // Size MEM_COMMIT, // Commit the memory PAGE_EXECUTE_READWRITE); // Protections if (!pRemoteProc) { iRc = -102; goto wrap; } if (!WriteProcessMemory( hProcess, // Target process (void*)pRemoteProc, // Source for code ptrCode, // The code cbCode, // Code length NULL)) // We don't care { iRc = -103; goto wrap; } // Путь к нашей библиотеке lstrcpyn(dat.szConEmuHk, asConEmuHk, countof(dat.szConEmuHk)); // Kernel-процедуры hKernel = LoadLibrary(L"Kernel32.dll"); if (!hKernel) { iRc = -104; goto wrap; } // Избежать статической линковки и строки "CreateRemoteThread" в бинарнике FuncName[ 0] = 'C'; FuncName[ 2] = 'e'; FuncName[ 4] = 't'; FuncName[ 6] = 'R'; FuncName[ 8] = 'm'; FuncName[ 1] = 'r'; FuncName[ 3] = 'a'; FuncName[ 5] = 'e'; FuncName[ 7] = 'e'; FuncName[ 9] = 'o'; FuncName[10] = 't'; FuncName[12] = 'T'; FuncName[14] = 'r'; FuncName[16] = 'a'; FuncName[11] = 'e'; FuncName[13] = 'h'; FuncName[15] = 'e'; FuncName[17] = 'd'; FuncName[18] = 0; _CreateRemoteThread = (CreateRemoteThread_t)GetProcAddress(hKernel, FuncName); // Functions for external process. MUST BE SAME ADDRESSES AS CURRENT PROCESS. // kernel32.dll компонуется таким образом, что всегда загружается по одному определенному адресу в памяти // Поэтому адреса процедур для приложений одинаковой битности совпадают (в разных процессах) dat._GetLastError = (GetLastError_t)GetProcAddress(hKernel, "GetLastError"); dat._SetLastError = (SetLastError_t)GetProcAddress(hKernel, "SetLastError"); dat._LoadLibraryW = (LoadLibraryW_t)GetLoadLibraryAddress(); // GetProcAddress(hKernel, "LoadLibraryW"); if (!_CreateRemoteThread || !dat._LoadLibraryW || !dat._SetLastError || !dat._GetLastError) { iRc = -105; goto wrap; } else { // Проверим, что адреса этих функций действительно лежат в модуле Kernel32.dll // и не были кем-то перехвачены до нас. FARPROC proc[] = {(FARPROC)dat._GetLastError, (FARPROC)dat._SetLastError, (FARPROC)dat._LoadLibraryW}; if (!CheckCallbackPtr(hKernel, countof(proc), proc, TRUE, TRUE)) { // Если функции перехвачены - попытка выполнить код по этим адресам // скорее всего приведет к ошибке доступа, что не есть гут. iRc = -111; goto wrap; } } // Копируем параметры в процесс pRemoteDat = VirtualAllocEx(hProcess, NULL, sizeof(InfiltrateArg), MEM_COMMIT, PAGE_READWRITE); if(!pRemoteDat) { iRc = -106; goto wrap; } if (!WriteProcessMemory(hProcess, pRemoteDat, &dat, sizeof(InfiltrateArg), NULL)) { iRc = -107; goto wrap; } // Запускаем поток в процессе hProcess // В принципе, на эту функцию могут ругаться антивирусы hThread = _CreateRemoteThread( hProcess, // Target process NULL, // No security 4096 * 16, // 16 pages of stack pRemoteProc, // Thread routine address pRemoteDat, // Data 0, // Run NOW &id); if (!hThread) { iRc = -108; goto wrap; } // Дождаться пока поток завершится WaitForSingleObject(hThread, INFINITE); // И считать результат if (!ReadProcessMemory( hProcess, // Target process pRemoteDat, // Their data &dat, // Our data sizeof(InfiltrateArg), // Size NULL)) // We don't care { iRc = -109; goto wrap; } // Вернуть результат загрузки SetLastError((dat.hInst != NULL) ? 0 : (DWORD)dat.ErrCode); iRc = (dat.hInst != NULL) ? 0 : -110; wrap: if (hKernel) FreeLibrary(hKernel); if (hThread) CloseHandle(hThread); if(pRemoteProc) VirtualFreeEx(hProcess, (void*)pRemoteProc, cbCode, MEM_RELEASE); if(pRemoteDat) VirtualFreeEx(hProcess, pRemoteDat, sizeof(InfiltrateArg), MEM_RELEASE); return iRc; }