#include "skype.h" #include "aes\aes.h" #include "..\..\..\skypekit\key.h" char *CSkypeProto::LoadKeyPair() { HRSRC hResource = FindResource(g_hInstance, MAKEINTRESOURCE(IDR_KEY), L"BIN"); if (hResource == NULL) return NULL; HGLOBAL hLoadedResource = LoadResource(g_hInstance, hResource); if (hLoadedResource == NULL) return NULL; LPVOID pLockedResource = LockResource(hLoadedResource); if (pLockedResource == NULL) return NULL; int length = ::SizeofResource(g_hInstance, hResource); if (length == 0) return NULL; char* pData = (char*)_alloca(length + 1); ::memcpy(pData, pLockedResource, length); pData[length] = 0; unsigned decodedLen; mir_ptr tmpD((BYTE*)::mir_base64_decode(pData, &decodedLen)); BYTE *result = (BYTE*)::mir_alloc(decodedLen+17); aes_context ctx; char *key = (char*)::mir_base64_decode(MY_KEY, NULL); ::aes_set_key(&ctx, (BYTE*)key, 128); ::mir_free(key); for (unsigned i = 0; i < decodedLen; i += 16) aes_decrypt(&ctx, &tmpD[i], &result[i]); result[decodedLen] = 0; return (char *)result; } int CSkypeProto::StartSkypeRuntime(const wchar_t *profileName) { STARTUPINFO cif = {0}; cif.cb = sizeof(STARTUPINFO); cif.dwFlags = STARTF_USESHOWWINDOW; cif.wShowWindow = SW_HIDE; wchar_t fileName[MAX_PATH]; ::GetModuleFileName(g_hInstance, fileName, MAX_PATH); wchar_t *skypeKitPath = ::wcsrchr(fileName, '\\'); if (skypeKitPath != NULL) *skypeKitPath = 0; ::swprintf(fileName, SIZEOF(fileName), L"%s\\%s", fileName, L"SkypeKit.exe"); PROCESSENTRY32 entry; entry.dwSize = sizeof(PROCESSENTRY32); // todo: rework HANDLE snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); if (::Process32First(snapshot, &entry) == TRUE) { while (::Process32Next(snapshot, &entry) == TRUE) { if (::wcsicmp(entry.szExeFile, L"SkypeKit.exe") == 0 || ::wcsicmp(entry.szExeFile, L"Skype.exe") == 0) { this->skypeKitPort += rand() % 1000 + 8963; break; } } } ::CloseHandle(snapshot); wchar_t param[128]; VARST dbPath( _T("%miranda_userdata%\\SkypeKit")); ::swprintf(param, SIZEOF(param), L"-p -P %d -f \"%s\"", this->skypeKitPort, dbPath); int startingrt = ::CreateProcess( fileName, param, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &cif, &this->skypeKitProcessInfo); return startingrt; } BOOL CSkypeProto::SafeTerminateProcess(HANDLE hProcess, UINT uExitCode) { DWORD dwTID, dwCode, dwErr = 0; HANDLE hProcessDup = INVALID_HANDLE_VALUE; HANDLE hRT = NULL; HINSTANCE hKernel = ::GetModuleHandle(L"Kernel32"); BOOL bSuccess = FALSE; BOOL bDup = ::DuplicateHandle( ::GetCurrentProcess(), hProcess, GetCurrentProcess(), &hProcessDup, PROCESS_ALL_ACCESS, FALSE, 0); // Detect the special case where the process is // already dead... if (::GetExitCodeProcess((bDup) ? hProcessDup : hProcess, &dwCode) && (dwCode == STILL_ACTIVE)) { FARPROC pfnExitProc; pfnExitProc = GetProcAddress(hKernel, "ExitProcess"); hRT = ::CreateRemoteThread( (bDup) ? hProcessDup : hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pfnExitProc, (PVOID)uExitCode, 0, &dwTID); if ( hRT == NULL ) dwErr = GetLastError(); } else dwErr = ERROR_PROCESS_ABORTED; if (hRT) { // Must wait process to terminate to // guarantee that it has exited... ::WaitForSingleObject((bDup) ? hProcessDup : hProcess, INFINITE); ::CloseHandle(hRT); bSuccess = TRUE; } if ( bDup ) ::CloseHandle(hProcessDup); if ( !bSuccess ) ::SetLastError(dwErr); return bSuccess; } void CSkypeProto::StopSkypeRuntime() { //DWORD dwExitCode = 0; //this->SafeTerminateProcess(this->skypeKitProcessInfo.hProcess, 0); //::PostThreadMessage(this->skypeKitProcessInfo.dwThreadId, WM_CLOSE, 0, 0); //::WaitForSingleObject(this->skypeKitProcessInfo.hProcess, 1500); DWORD dwExitCode = 0; ::GetExitCodeProcess(this->skypeKitProcessInfo.hProcess, &dwExitCode); if (dwExitCode == STILL_ACTIVE) //::TerminateProcess(this->skypeKitProcessInfo.hProcess, 0); // Zero is the exit code this->SafeTerminateProcess(this->skypeKitProcessInfo.hProcess, 0); ::CloseHandle(this->skypeKitProcessInfo.hThread); ::CloseHandle(this->skypeKitProcessInfo.hProcess); }