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

E:/PROJECTS/cvsed/mixed/VIRTUA~1/kdclient/loader.h

Go to the documentation of this file.
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 //              char szName[MAX_PATH] = {0,};
00113 //              WideCharToMultiByte(CP_ACP, 0, pDllName, -1, szName, sizeof(szName), "?", NULL);
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 };