• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

E:/PROJECTS/cvsed/mixed/VIRTUA~1/kdclient/32to64.cpp

Go to the documentation of this file.
00001 
00007 #include "stdafx.h"
00008 #include "32to64.h"
00009 #include <bzscmn/cmndef.h>
00010 #include <bzswin/wow64.h>
00011 #include <shellapi.h>
00012 
00013 #include "patchapi.h"
00014 
00015 extern HMODULE g_hThisDll;
00016 
00017 static const TCHAR tszPipeFmt[] = _T("\\\\.\\pipe\\KDCLIENT_32TO64PIPE_%X");
00018 
00019 
00020 struct PipeMessage
00021 {
00022         ULONGLONG LongResult;
00023         wchar_t wszStringResult[256];
00024 };
00025 
00026 #ifndef _WIN64
00027 
00028 static bool s_bUserWarned = false;
00029 
00030 ULONGLONG Call64BitKDCLIENT(KDClientCommand cmd, unsigned PID, LPWSTR lpStringResult, size_t StringSize)
00031 {
00032         if (lpStringResult)
00033                 lpStringResult[0] = 0;
00034 
00035         TCHAR tszModule[MAX_PATH + 6] = {0,};
00036         GetModuleFileName(g_hThisDll, tszModule, __countof(tszModule));
00037         TCHAR *p = _tcsrchr(tszModule, '.');
00038         if (!p)
00039                 return -1;
00040         _tcsncpy(p, _T("64.dll"), __countof(tszModule) - (p - tszModule));
00041         HANDLE hFile = CreateFile(tszModule, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
00042         if (hFile == INVALID_HANDLE_VALUE)
00043         {
00044                 if (!s_bUserWarned)
00045                 {
00046                         TCHAR tszMsg[MAX_PATH + 100] = {0,};
00047                         _sntprintf(tszMsg, __countof(tszMsg), _T("Cannot patch 64-bit VM!\r\n%s not found.\r\nInstall the DLL and retry patching."), tszModule);
00048                         MessageBox(0, tszMsg, 0, MB_ICONERROR | MB_TASKMODAL);
00049                         s_bUserWarned = true;
00050                 }
00051                 return -1;
00052         }
00053         CloseHandle(hFile);
00054         s_bUserWarned = false;
00055 
00056 
00057         TCHAR tszCmdLine[MAX_PATH + 100];
00058         unsigned pidCurrent = GetCurrentProcessId();
00059 
00060         _sntprintf(tszCmdLine, __countof(tszCmdLine), tszPipeFmt, pidCurrent);
00061         HANDLE hPipe = CreateNamedPipe(tszCmdLine, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE, 1, 0, 0, 0, NULL);
00062         if (hPipe == INVALID_HANDLE_VALUE)
00063                 return -1;
00064 
00065         _sntprintf(tszCmdLine, __countof(tszCmdLine), _T("rundll32 \"%s\",KdClient32To64Entry %d %d %d"), tszModule, pidCurrent, cmd, PID);
00066         STARTUPINFO SI = {0,};
00067         SI.cb = sizeof(SI);
00068         PROCESS_INFORMATION PI = {0,};
00069         
00070         BOOL bCreated = FALSE;
00071         {
00072                 BazisLib::WOW64FSRedirHolder holder;
00073                 bCreated = CreateProcess(NULL, tszCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &SI, &PI);
00074         }
00075 
00076         if (!bCreated)
00077         {
00078                 if (hPipe != INVALID_HANDLE_VALUE)
00079                         CloseHandle(hPipe);
00080                 return -1;
00081         }
00082 
00083         OVERLAPPED pipeOverlapped = {0,};
00084         pipeOverlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
00085         ConnectNamedPipe(hPipe, &pipeOverlapped);
00086 
00087         HANDLE hhWait[2] = {pipeOverlapped.hEvent, PI.hProcess};
00088         PipeMessage msg = {0,};
00089 
00090         if ((GetLastError() == ERROR_PIPE_CONNECTED) || (WaitForMultipleObjects(2, hhWait, FALSE, INFINITE) == WAIT_OBJECT_0))
00091         {
00092                 DWORD dwDone = 0;
00093                 if (ReadFile(hPipe, &msg, sizeof(msg), &dwDone, NULL) || WaitForMultipleObjects(2, hhWait, FALSE, INFINITE) == WAIT_OBJECT_0)
00094                 {
00095                         if (!dwDone)
00096                                 GetOverlappedResult(hPipe, &pipeOverlapped, &dwDone, TRUE);
00097                         if (dwDone != sizeof(msg))
00098                                 memset(&msg, 0, sizeof(msg));
00099                 }
00100         }
00101         msg.wszStringResult[__countof(msg.wszStringResult) - 1] = 0;
00102 
00103         if (lpStringResult)
00104                 wcsncpy(lpStringResult, msg.wszStringResult, StringSize);
00105 
00106         CloseHandle(hPipe);
00107         WaitForSingleObject(PI.hProcess, INFINITE);
00108         CloseHandle(PI.hProcess);
00109         CloseHandle(PI.hThread);
00110         return msg.LongResult;
00111 }
00112 
00113 #else
00114 
00115 HANDLE StartPatcherThread( unsigned PID, DWORD *pPatcherThreadID = NULL);
00116 HANDLE StartUnpatcherThread( unsigned PID, DWORD *pPatcherThreadID = NULL);
00117 
00118 ULONGLONG KdClient32To64Dispatch(KDClientCommand cmd, unsigned PID, LPWSTR lpStringResult, size_t StringSize)
00119 {
00120         DWORD ID = 0;
00121         HANDLE hThread;
00122 
00123         switch (cmd)
00124         {
00125         case kGetVMSessionName:
00126                 return GetVMSessionNameW(PID, lpStringResult, StringSize);
00127         case kIsSessionPatched:
00128                 return IsVMSessionPatched(PID);
00129         case kStartVMSessionPatching:
00130         case kStartVMSessionUnpatching:
00131                 hThread = (cmd == kStartVMSessionPatching) ? StartPatcherThread(PID, &ID) : StartUnpatcherThread(PID, &ID);
00132                 if (hThread == NULL)
00133                         return 0;       //Already done
00134                 else if (hThread == INVALID_HANDLE_VALUE)
00135                         return -1LL;
00136                 else
00137                 {
00138                         CloseHandle(hThread);
00139                         return ID;
00140                 }
00141                 return -1LL;
00142         case kPatchAndWait:
00143                 return PatchVMSessionIfNeeded(PID);
00144         case kUnpatchAndWait:
00145                 return UnpatchVMSessionIfNeeded(PID);
00146         default:
00147                 return -1LL;
00148         }
00149 }
00150 
00151 void KdClient32To64Entry()
00152 {
00153         TCHAR *pCmdLine = GetCommandLine();
00154         int argc = 0;
00155         LPWSTR *pArgv = CommandLineToArgvW(GetCommandLineW(), &argc);
00156         if (!pArgv)
00157                 return;
00158 
00159         if (argc < 5)
00160                 return;
00161 
00162         int CallerPID = _wtoi(pArgv[2]);
00163         int Cmd = _wtoi(pArgv[3]);
00164         int TargetPID = _wtoi(pArgv[4]);
00165 
00166         TCHAR tszPipeName[MAX_PATH];
00167         unsigned pidCurrent = GetCurrentProcessId();
00168 
00169         _sntprintf(tszPipeName, __countof(tszPipeName), tszPipeFmt, CallerPID);
00170         HANDLE hPipe = CreateFile(tszPipeName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
00171         if (hPipe == INVALID_HANDLE_VALUE)
00172                 return;
00173 
00174         PipeMessage msg = {0,};
00175         msg.LongResult = KdClient32To64Dispatch((KDClientCommand)Cmd, TargetPID, msg.wszStringResult, __countof(msg.wszStringResult));
00176         DWORD dwDone = 0;
00177         WriteFile(hPipe, &msg, sizeof(msg), &dwDone, NULL);
00178         CloseHandle(hPipe);
00179 }
00180 
00181 #endif