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;
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