00001
00007 #pragma once
00008
00009 #include <bzscmn/bzscmn.h>
00010 #include "../rpcdispatch/status.h"
00011 #include "hook64.h"
00012
00014 class RemoteDllLoader
00015 {
00016 private:
00017 TCHAR m_DllName[MAX_PATH];
00018
00019 private:
00020 wchar_t *GetDllName(bool ShortName)
00021 {
00022 wchar_t *pDllName = m_DllName;
00023 if (ShortName)
00024 {
00025 pDllName = wcsrchr(pDllName, '\\');
00026 if (pDllName)
00027 pDllName++;
00028 else
00029 pDllName = m_DllName;
00030 }
00031 return pDllName;
00032 }
00033
00034 public:
00036 RemoteDllLoader(HINSTANCE hDll, bool FreeLibraryAfterInit = true)
00037 {
00038 memset(m_DllName, 0, sizeof(m_DllName));
00039 unsigned cnt = GetModuleFileName(hDll, m_DllName, __countof(m_DllName));
00040 ASSERT(cnt);
00041 if (FreeLibraryAfterInit)
00042 FreeLibrary(hDll);
00043 }
00044
00045 ~RemoteDllLoader()
00046 {
00047 }
00048
00049 static ULONGLONG GetRemoteProcAddress(unsigned PID, TCHAR *pDllName, char *pFuncName)
00050 {
00051 ULONGLONG pFunc = GetRemoteModuleHandle64Aware(PID, pDllName);
00052 if (!pFunc)
00053 return 0;
00054 size_t off = (char *)GetProcAddress(GetModuleHandle(pDllName), pFuncName) - (char *)GetModuleHandle(pDllName);
00055 pFunc += off;
00056 ASSERT(!(pFunc & 0xFFFFFFFF00000000LL));
00057 return pFunc;
00058 }
00059
00061 HANDLE InitiateDLLLoading(unsigned PID, DWORD *pThreadID = NULL)
00062 {
00063 ULONGLONG p = GetRemoteProcAddress(PID, L"kernel32.dll", "LoadLibraryW");
00064 if (!p)
00065 return INVALID_HANDLE_VALUE;
00066 HANDLE hProc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE, FALSE, PID);
00067 if (hProc == INVALID_HANDLE_VALUE)
00068 return INVALID_HANDLE_VALUE;
00069 LPVOID lp = VirtualAllocEx(hProc, 0, 4096, MEM_COMMIT, PAGE_READWRITE);
00070 if (!lp)
00071 {
00072 CloseHandle(hProc);
00073 return INVALID_HANDLE_VALUE;
00074 }
00075 SIZE_T dwOk = 0;
00076 BOOL b = WriteProcessMemory(hProc, lp, m_DllName, wcslen(m_DllName)*2 + 2, &dwOk);
00077 if (!b)
00078 {
00079 CloseHandle(hProc);
00080 return INVALID_HANDLE_VALUE;
00081 }
00082 DWORD ID = 0;
00083 HANDLE hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)p, lp, 0, &ID);
00084 CloseHandle(hProc);
00085 if (pThreadID)
00086 *pThreadID = ID;
00087 return hThread;
00088 }
00089
00091 HANDLE InitiateDLLUnloading(unsigned PID, bool UseShortName = true, DWORD *pThreadID = NULL)
00092 {
00093 ULONGLONG p = GetRemoteProcAddress(PID, L"kernel32.dll", "FreeLibrary");
00094 if (!p)
00095 return INVALID_HANDLE_VALUE;
00096 HANDLE hProc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE, FALSE, PID);
00097 if (hProc == INVALID_HANDLE_VALUE)
00098 return INVALID_HANDLE_VALUE;
00099 DWORD ID = 0;
00100 HINSTANCE hInst = FindLibraryInProcess(PID, UseShortName);
00101 HANDLE hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)p, (LPVOID)hInst, 0, &ID);
00102 CloseHandle(hProc);
00103 if (pThreadID)
00104 *pThreadID = ID;
00105 return hThread;
00106 }
00107
00109 HINSTANCE FindLibraryInProcess(unsigned PID, bool UseShortName = true)
00110 {
00111 wchar_t *pDllName = GetDllName(UseShortName);
00112
00113
00114 return (HINSTANCE)GetRemoteModuleHandle64Aware(PID, pDllName, UseShortName);
00115 }
00116
00117 static int GetRemoteCommandLineW(unsigned PID, wchar_t *pCmdLine, size_t MaxNameLength)
00118 {
00119 ULONGLONG pFunc = GetRemoteProcAddress(PID, L"kernel32.dll", "GetCommandLineW");
00120 if (!pFunc)
00121 return 0;
00122
00123 HANDLE hProc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_QUERY_INFORMATION, FALSE, PID);
00124 if (hProc == INVALID_HANDLE_VALUE)
00125 return 0;
00126
00127 DWORD ID;
00128 HANDLE hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)pFunc, NULL, 0, &ID);
00129 if ((hThread == INVALID_HANDLE_VALUE) || !hThread)
00130 {
00131 CloseHandle(hProc);
00132 return 0;
00133 }
00134 WaitForSingleObject(hThread, INFINITE);
00135 DWORD dwCode = 0;
00136 GetExitCodeThread(hThread, &dwCode);
00137 CloseHandle(hThread);
00138
00139 if (!dwCode)
00140 return 0;
00141
00142 MEMORY_BASIC_INFORMATION info = {0,};
00143 VirtualQueryEx(hProc, (LPVOID)dwCode, &info, sizeof(info));
00144 size_t todo = MaxNameLength * sizeof(wchar_t);
00145 size_t avail = ((unsigned)info.BaseAddress + info.RegionSize) - dwCode;
00146
00147 if (avail < todo)
00148 todo = avail;
00149
00150 SIZE_T dwDone = 0;
00151 ReadProcessMemory(hProc, (LPVOID)dwCode, pCmdLine, todo, &dwDone);
00152 CloseHandle(hProc);
00153
00154 for (unsigned i = 0; i < (dwDone / sizeof(pCmdLine[0])); i++)
00155 if (!pCmdLine[i])
00156 return i;
00157 pCmdLine[dwDone / sizeof(pCmdLine[0])] = 0;
00158 ASSERT(pCmdLine[0]);
00159 return (int)(dwDone / sizeof(pCmdLine[0])) - 1;
00160 }
00161 };