Beispiel #1
0
int freerdp_client_rdp_file_set_integer_option(rdpFile* file, const char* name, int value)
{
	int index;
	int length;
	char* text;
	rdpFileLine* line;

	line = freerdp_client_rdp_file_find_line_by_name(file, name);

	length = _scprintf("%s:i:%d", name, value);
	text = (char*) malloc(length + 1);
	sprintf_s(text, length + 1, "%s:i:%d", name, value);
	text[length] = '\0';

	if (line)
	{
		line->iValue = value;

		free(line->text);
		line->text = text;
	}
	else
	{
		index = freerdp_client_parse_rdp_file_add_line(file, text, -1);
		line = freerdp_client_rdp_file_find_line_index(file, index);

		freerdp_client_rdp_file_set_integer(file, (char*) name, value, index);

		free(text);
	}

	return 0;
}
void BrowserFactory::LaunchBrowserUsingIELaunchURL(const std::string& initial_url,
                                                   PROCESS_INFORMATION* proc_info,
                                                   std::string* error_message) {
  LOG(TRACE) << "Entering BrowserFactory::IsIELaunchURLAvailable";
  LOG(DEBUG) << "Starting IE using the IELaunchURL API";
  std::wstring wide_initial_url = StringUtilities::ToWString(initial_url);

  HRESULT launch_result = ::IELaunchURL(wide_initial_url.c_str(),
                                        proc_info,
                                        NULL);
  if (FAILED(launch_result)) {
    size_t launch_msg_count = _scprintf(IELAUNCHURL_ERROR_MESSAGE,
                                        launch_result,
                                        initial_url.c_str());
    vector<char> launch_result_msg(launch_msg_count + 1);
    _snprintf_s(&launch_result_msg[0],
                launch_result_msg.size(),
                launch_msg_count + 1,
                IELAUNCHURL_ERROR_MESSAGE,
                launch_result,
                initial_url.c_str());
    std::string launch_error = &launch_result_msg[0];
    *error_message = launch_error;
  }
}
Beispiel #3
0
int freerdp_client_rdp_file_set_string_option(rdpFile* file, const char* name, const char* value)
{
	int index;
	int length;
	char* text;
	rdpFileLine* line;

	line = freerdp_client_rdp_file_find_line_by_name(file, name);

	length = _scprintf("%s:s:%s", name, value);
	text = (char*) malloc(length + 1);
	sprintf_s(text, length + 1, "%s:s:%s", name, value ? value : "");
	text[length] = '\0';

	if (line)
	{
		free(line->sValue);
		line->sValue = _strdup(value);

		free(line->text);
		line->text = text;
	}
	else
	{
		index = freerdp_client_parse_rdp_file_add_line(file, text, -1);
		line = freerdp_client_rdp_file_find_line_index(file, index);

		freerdp_client_rdp_file_set_string(file, name, value, index);

		free(text);
	}

	return 0;
}
Beispiel #4
0
char* FGDump::CreateSessionID()
{
	// Format for the session ID is: YYYY-MM-DD-HH-mm-SS
	// Will be dynamically allocated, caller should free the memory
	SYSTEMTIME st;
	char* szIDBuffer = NULL;

	GetSystemTime(&st);

	size_t nArgSize = _scprintf("%d-%02d-%02d-%02d-%02d-%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
	szIDBuffer = (char*)malloc(nArgSize + 1);
	memset(szIDBuffer, 0, nArgSize + 1);
	_snprintf(szIDBuffer, nArgSize, "%d-%02d-%02d-%02d-%02d-%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);

	return szIDBuffer;
}
Beispiel #5
0
int HtiStifMsg::CheckResponseCommandCode(struct soap *soap, BYTE commandCode)
{
    int result = SOAP_OK;

    if( msgBody[0] != commandCode )
    {
        char msg[] = "incorrect response CommandCode (expected 0x%x, got 0x%x)";
        int msgLen = _scprintf(msg, commandCode, msgBody[0])+1; // +1 for nul char
        char *buf = new char[msgLen];
        sprintf(buf, msg, commandCode, msgBody[0]);
        soap->error = soap_receiver_fault(soap, "HtiError", buf);
        delete buf;
        result = SOAP_FAULT;
    }

    return result;
}
Beispiel #6
0
AppletParameter::AppletParameter(const char *name, const char *value)
: m_isValid(false), m_formattedString(NULL)
{
  _ASSERT(name != NULL);
  _ASSERT(value != NULL);

  m_isValid = isStringValid(name) && isStringValid(value);

  if (isValid()) {
    const char *format = "<PARAM NAME=\"%s\" VALUE=\"%s\" >\n";

    int len = _scprintf(format, name, value) + 1;

    m_formattedString = new char[len];

    sprintf_s(m_formattedString, (size_t)(len), format, name, value);
  }
}
DWORD BrowserFactory::LaunchBrowserProcess(const std::string& initial_url,
                                           const bool ignore_protected_mode_settings,
                                           std::string* error_message) {
  LOG(TRACE) << "Entering BrowserFactory::LaunchBrowserProcess";

  DWORD process_id = NULL;
  bool has_valid_protected_mode_settings = false;
  LOG(DEBUG) << "Ignoring Protected Mode Settings: "
             << ignore_protected_mode_settings;
  if (!ignore_protected_mode_settings) {
    LOG(DEBUG) << "Checking validity of Protected Mode settings.";
    has_valid_protected_mode_settings = this->ProtectedModeSettingsAreValid();
  }
  LOG(DEBUG) << "Has Valid Protected Mode Settings: "
             << has_valid_protected_mode_settings;
  if (ignore_protected_mode_settings || has_valid_protected_mode_settings) {
    STARTUPINFO start_info;
    PROCESS_INFORMATION proc_info;

    ::ZeroMemory(&start_info, sizeof(start_info));
    start_info.cb = sizeof(start_info);
    ::ZeroMemory(&proc_info, sizeof(proc_info));

    std::wstring wide_initial_url(CA2W(initial_url.c_str(), CP_UTF8));

    FARPROC proc_address = 0;
    HMODULE library_handle = ::LoadLibrary(IEFRAME_LIBRARY_NAME);
    if (library_handle != NULL) {
      proc_address = ::GetProcAddress(library_handle, IELAUNCHURL_FUNCTION_NAME);
    }

    std::string launch_api = "The IELaunchURL() API";
    std::string launch_error = "";
    if (proc_address != 0) {
      // If we have the IELaunchURL API, expressly use it. This will
      // guarantee a new session. Simply using CoCreateInstance to 
      // create the browser will merge sessions, making separate cookie
      // handling impossible.
      HRESULT launch_result = ::IELaunchURL(wide_initial_url.c_str(),
                                            &proc_info,
                                            NULL);
      if (FAILED(launch_result)) {
        size_t launch_msg_count = _scprintf(IELAUNCHURL_ERROR_MESSAGE,
                                            launch_result,
                                            initial_url);
        vector<char> launch_result_msg(launch_msg_count + 1);
        _snprintf_s(&launch_result_msg[0],
                    sizeof(launch_result_msg),
                    launch_msg_count + 1,
                    IELAUNCHURL_ERROR_MESSAGE,
                    launch_result,
                    initial_url);
        launch_error = &launch_result_msg[0];
        *error_message = launch_error;
      }
    } else {
      launch_api = "The CreateProcess() API";
      std::wstring executable_and_url = this->ie_executable_location_ +
                                        L" " + wide_initial_url;
      LPWSTR command_line = new WCHAR[executable_and_url.size() + 1];
      wcscpy_s(command_line,
               executable_and_url.size() + 1,
               executable_and_url.c_str());
      command_line[executable_and_url.size()] = L'\0';
      BOOL create_process_result = ::CreateProcess(NULL,
                                                   command_line,
                                                   NULL,
                                                   NULL,
                                                   FALSE,
                                                   0,
                                                   NULL,
                                                   NULL,
                                                   &start_info,
                                                   &proc_info);
      if (!create_process_result) {
        int create_proc_msg_count = _scwprintf(CREATEPROCESS_ERROR_MESSAGE,
                                               command_line);
        vector<wchar_t> create_proc_result_msg(create_proc_msg_count + 1);
        _snwprintf_s(&create_proc_result_msg[0],
                     sizeof(create_proc_result_msg),
                     create_proc_msg_count,
                     CREATEPROCESS_ERROR_MESSAGE,
                     command_line);
        launch_error = CW2A(&create_proc_result_msg[0], CP_UTF8);
        *error_message = launch_error;
      }
      delete[] command_line;
    }

    process_id = proc_info.dwProcessId;
    if (process_id == NULL) {
      // If whatever API we are using failed to launch the browser, we should
      // have a NULL value in the dwProcessId member of the PROCESS_INFORMATION
      // structure. In that case, we will have already set the approprate error
      // message. On the off chance that we haven't yet set the appropriate
      // error message, that means we successfully launched the browser (i.e.,
      // the browser launch API returned a success code), but we still have a
      // NULL process ID.
      if (launch_error.size() == 0) {
        *error_message = launch_api + NULL_PROCESS_ID_ERROR_MESSAGE;
      }
    }

    if (proc_info.hThread != NULL) {
      ::CloseHandle(proc_info.hThread);
    }

    if (proc_info.hProcess != NULL) {
      ::CloseHandle(proc_info.hProcess);
    }

    if (library_handle != NULL) {
      ::FreeLibrary(library_handle);
    }
  } else {
    *error_message = PROTECTED_MODE_SETTING_ERROR_MESSAGE;
  }
  return process_id;
}
bool BrowserFactory::AttachToBrowser(ProcessWindowInfo* process_window_info,
                                     const int timeout_in_milliseconds,
                                     const bool ignore_zoom_setting,
                                     std::string* error_message) {
  LOG(TRACE) << "Entering BrowserFactory::AttachToBrowser";
  clock_t end = clock() + (timeout_in_milliseconds / 1000 * CLOCKS_PER_SEC);
  while (process_window_info->hwndBrowser == NULL) {
    if (timeout_in_milliseconds > 0 && (clock() > end)) {
      break;
    }
    ::EnumWindows(&BrowserFactory::FindBrowserWindow,
                  reinterpret_cast<LPARAM>(process_window_info));
    if (process_window_info->hwndBrowser == NULL) {
      ::Sleep(250);
    }
  }

  if (process_window_info->hwndBrowser == NULL) {
    int attach_fail_msg_count = _scprintf(ATTACH_TIMEOUT_ERROR_MESSAGE,
                                          process_window_info->dwProcessId,
                                          timeout_in_milliseconds);
    vector<char> attach_fail_msg_buffer(attach_fail_msg_count + 1);
    _snprintf_s(&attach_fail_msg_buffer[0],
                attach_fail_msg_buffer.size(),
                attach_fail_msg_count,
                ATTACH_TIMEOUT_ERROR_MESSAGE,
                process_window_info->dwProcessId,
                timeout_in_milliseconds);
    std::string attach_fail_msg = &attach_fail_msg_buffer[0];
    *error_message = attach_fail_msg;
    return false;
  }

  CComPtr<IHTMLDocument2> document;
  if (this->GetDocumentFromWindowHandle(process_window_info->hwndBrowser,
                                        &document)) {
    CComPtr<IHTMLWindow2> window;
    HRESULT hr = document->get_parentWindow(&window);

    // Test for zoom level = 100%
    int zoom_level = 100;
    LOG(DEBUG) << "Ignoring zoom setting: " << ignore_zoom_setting;
    if (!ignore_zoom_setting) {
      zoom_level = this->GetZoomLevel(document, window);
    }
    if (zoom_level != 100) {
      vector<char> zoom_level_buffer(10);
      _itoa_s(zoom_level, &zoom_level_buffer[0], 10, 10);
      std::string zoom(&zoom_level_buffer[0]);
      *error_message = "Browser zoom level was set to " + zoom + "%. It should be set to 100%";
      return false;
    }
    if (SUCCEEDED(hr)) {
      // http://support.microsoft.com/kb/257717
      CComPtr<IServiceProvider> provider;
      window->QueryInterface<IServiceProvider>(&provider);
      if (provider) {
        CComPtr<IServiceProvider> child_provider;
        hr = provider->QueryService(SID_STopLevelBrowser,
                                    IID_IServiceProvider,
                                    reinterpret_cast<void**>(&child_provider));
        if (SUCCEEDED(hr)) {
          IWebBrowser2* browser;
          hr = child_provider->QueryService(SID_SWebBrowserApp,
                                            IID_IWebBrowser2,
                                            reinterpret_cast<void**>(&browser));
          if (SUCCEEDED(hr)) {
            process_window_info->pBrowser = browser;
            return true;
          } else {
            LOGHR(WARN, hr) << "IServiceProvider::QueryService for SID_SWebBrowserApp failed";
          }
        } else {
          LOGHR(WARN, hr) << "IServiceProvider::QueryService for SID_STopLevelBrowser failed";
        }
      } else {
        LOG(WARN) << "QueryInterface for IServiceProvider failed";
      }
    } else {
      LOGHR(WARN, hr) << "Call to IHTMLDocument2::get_parentWindow failed";
    }
  } else {
    *error_message = "Could not get document from window handle";
  }
  return false;
}
Beispiel #9
0
LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS* ptrs)
{
	EXCEPTION_RECORD* rec = ptrs->ExceptionRecord;
	CONTEXT* ctx = ptrs->ContextRecord;
	DWORD base = Vars.pModule ? Vars.pModule->dwBaseAddress : (DWORD)Vars.hModule;

	char path[MAX_PATH+_MAX_FNAME] = "";
	sprintf_s(path, sizeof(path), "%s\\D2BS.bin", Vars.szPath);

	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessId());
	HANDLE hThread = GetCurrentThread();
	CONTEXT context = *ctx;

	unsigned int i;
	int len;
	char* szString;
	char* dllAddrs;

	SymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_FAIL_CRITICAL_ERRORS|SYMOPT_NO_PROMPTS|SYMOPT_DEFERRED_LOADS);
	SymInitialize(hProcess, Vars.szPath, TRUE);
	SymLoadModule64(hProcess, NULL, path, NULL, base, 0);

	STACKFRAME64 stack;
	stack.AddrPC.Offset = context.Eip;
	stack.AddrPC.Mode = AddrModeFlat;
	stack.AddrStack.Offset = context.Esp;
	stack.AddrStack.Mode = AddrModeFlat;
	stack.AddrFrame.Offset = context.Ebp;
	stack.AddrFrame.Mode = AddrModeFlat;

	std::string trace;

	for(i = 0; i < 64; i++)
	{
		if(!StackWalk64(IMAGE_FILE_MACHINE_I386, hProcess, hThread, &stack, &context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
			break;

		// infinite loop
		if(stack.AddrReturn.Offset == stack.AddrPC.Offset)
			break;
		// jump to 0
		if(stack.AddrPC.Offset == 0)
			break;

		SYMBOL_INFO* sym = GetSymFromAddr(hProcess, stack.AddrPC.Offset);

		if(sym)
		{
			char msg[1024];
			ULONG64 base2 = (sym->Address - sym->ModBase);

			IMAGEHLP_LINE64* line = GetLineFromAddr(hProcess, stack.AddrPC.Offset);
			if(line)
				sprintf_s(msg, 1024, "\t%s+0x%08x, File: %s line %d\n",
						sym->Name, base2, strrchr(line->FileName, '\\')+1, line->LineNumber);
			else
				sprintf_s(msg, 1024, "\t%s+0x%08x\n", sym->Name, base2);

			trace.append(msg);
			delete line;
		}
		else
		{
			char addr[100];
			sprintf_s(addr, sizeof(addr), "\t0x%08x\n", stack.AddrFrame.Offset);
			trace.append(addr);
		}

		delete[] (char*)sym;
	}

	SYMBOL_INFO* sym = GetSymFromAddr(hProcess, (DWORD64)rec->ExceptionAddress);

	IMAGEHLP_LINE64* line = GetLineFromAddr(hProcess, (DWORD64)rec->ExceptionAddress);

	len = _scprintf("EXCEPTION!\n*** 0x%08x at 0x%08x (%s in %s line %d)\n"
		"D2BS loaded at: 0x%08x\n"
		"Registers:\n"
		"\tEIP: 0x%08x, ESP: 0x%08x\n"
		"\tCS: 0x%04x, DS: 0x%04x, ES: 0x%04x, SS: 0x%04x, FS: 0x%04x, GS: 0x%04x\n"
		"\tEAX: 0x%08x, EBX: 0x%08x, ECX: 0x%08x, EDX: 0x%08x, ESI: 0x%08x, EDI: 0x%08x, EBP: 0x%08x, FLG: 0x%08x\n"
		"Stack Trace:\n%s\nEnd of stack trace.",
			rec->ExceptionCode, rec->ExceptionAddress,
			sym != NULL ? sym->Name : "Unknown", line != NULL ? strrchr(line->FileName, '\\')+1 : "Unknown", line != NULL ? line->LineNumber : 0,
			base,
			ctx->Eip, ctx->Esp,
			ctx->SegCs, ctx->SegDs, ctx->SegEs, ctx->SegSs, ctx->SegFs, ctx->SegGs,
			ctx->Eax, ctx->Ebx, ctx->Ecx, ctx->Edx, ctx->Esi, ctx->Edi, ctx->Ebp, ctx->EFlags,
			trace.c_str());
	dllAddrs = DllLoadAddrStrs();

	szString = new char[len+1];
	sprintf_s(szString, len+1, "EXCEPTION!\n*** 0x%08x at 0x%08x (%s in %s line %d)\n"
		"D2BS loaded at: 0x%08x\n"
		"Registers:\n"
		"\tEIP: 0x%08x, ESP: 0x%08x\n"
		"\tCS: 0x%04x, DS: 0x%04x, ES: 0x%04x, SS: 0x%04x, FS: 0x%04x, GS: 0x%04x\n"
		"\tEAX: 0x%08x, EBX: 0x%08x, ECX: 0x%08x, EDX: 0x%08x, ESI: 0x%08x, EDI: 0x%08x, EBP: 0x%08x, FLG: 0x%08x\n"
		"Stack Trace:\n%s\nEnd of stack trace.",
			rec->ExceptionCode, rec->ExceptionAddress,
			sym != NULL ? sym->Name : "Unknown", line != NULL ? strrchr(line->FileName, '\\')+1 : "Unknown", line != NULL ? line->LineNumber : 0,
			base,
			ctx->Eip, ctx->Esp,
			ctx->SegCs, ctx->SegDs, ctx->SegEs, ctx->SegSs, ctx->SegFs, ctx->SegGs,
			ctx->Eax, ctx->Ebx, ctx->Ecx, ctx->Edx, ctx->Esi, ctx->Edi, ctx->Ebp, ctx->EFlags,
			trace.c_str());

	Log("%s\n%s", szString, dllAddrs);

	free(dllAddrs);

	delete[] szString;
	delete[] (char*)sym;
	delete line;

	SymCleanup(hProcess);

	return EXCEPTION_EXECUTE_HANDLER;
}
Beispiel #10
0
HRESULT CALLBACK KnownStructOutput (
    IN ULONG  Flag,
    IN ULONG64  Address,
    IN PSTR  StructName,
    OUT PSTR  Buffer,
    IN OUT PULONG  BufferSize
    )
{
  HRESULT hRes=E_FAIL;

    if(Flag==DEBUG_KNOWN_STRUCT_GET_NAMES)
    {
        if ((*BufferSize)<strlen(SYSEXTS_KNOWNSTRUCT_1)+2)
        {
            // Not enough buffer available, return S_FALSE
            (*BufferSize)=strlen(SYSEXTS_KNOWNSTRUCT_1)+2;
            hRes=S_FALSE;
        }
        else
        {
            hRes=StringCchPrintfA(Buffer,(*BufferSize)-2,"%s\0",SYSEXTS_KNOWNSTRUCT_1 ); 
            if (FAILED(hRes))
            {
              dprintf ("Failed to copy the data type name into buffer\n");
            }
        }
    }
  else if(Flag==DEBUG_KNOWN_STRUCT_GET_SINGLE_LINE_OUTPUT)
  {
    ULONG ulData=0;
    ULONG ulLeft=0;
    ULONG ulRight=0;

    if(FAILED(hRes=GetNodeValues(Address, &ulData, &ulLeft, &ulRight)))
    {
		return hRes;
    }    

    DWORD dwLen=_scprintf(SYSEXTS_KNOWNSTRUCT_OUT, 
                          ulData, 
                          ulLeft, 
                          ulRight)+1; 

    if(dwLen>(*BufferSize))
    {
      dprintf("KnownStructOutput unable to fit return data into buffer\n");
      hRes=E_FAIL;
      return hRes;
    }

    hRes=StringCchPrintfA(Buffer, 
                        dwLen, 
                        SYSEXTS_KNOWNSTRUCT_OUT, 
                        ulData, 
                        ulLeft, 
                        ulRight);
    if(FAILED(hRes))
    {
        dprintf ("KnownStructOutput unable to write data into buffer\n");	
    }
  }
  else if(Flag==DEBUG_KNOWN_STRUCT_SUPPRESS_TYPE_NAME)
  {
        return S_OK;
  }
  else 
  {
    dprintf("KnownStructOutput called with invalid flags\n");
  }
  return hRes;
}
Beispiel #11
0
bool CacheDumpControl::Execute(const char* lpszPSExecPath, const char* lpszDumpPath, char* lpszMachine, bool bIs64Bit, char* lpszPipeName)
{
	char* lpszCmdLineFormat;
	int nArgSize;
	char* lpszStopCmdLine;
	char* lpszParams;
	bool result = false;
	
	if (lpszPipeName == NULL)
	{
		// Set the local cachedump path
		if (!bIs64Bit)
			lpszCmdLineFormat = "%s\\cachedump.exe";
		else
			lpszCmdLineFormat = "%s\\cachedump64.exe";

		nArgSize = _scprintf(lpszCmdLineFormat, lpszDumpPath);
		lpszStopCmdLine = new char[nArgSize + 1];
		memset(lpszStopCmdLine, 0, nArgSize + 1);
		_snprintf_s(lpszStopCmdLine, nArgSize, strlen(lpszCmdLineFormat)-1+strlen(lpszDumpPath), lpszCmdLineFormat, lpszDumpPath);

		// Now set the parameters
		lpszCmdLineFormat = " -v";
		lpszParams = new char[nArgSize + 1];
		memset(lpszParams, 0, nArgSize + 1);
		_snprintf_s(lpszParams, nArgSize, strlen(lpszCmdLineFormat)-1, lpszCmdLineFormat);
	}
	else
	{
		lpszStopCmdLine = new char[strlen(lpszPSExecPath) + 1];
		memset(lpszStopCmdLine, 0, strlen(lpszPSExecPath) + 1);
		strncpy_s(lpszStopCmdLine, strlen(lpszPSExecPath) + 1, lpszPSExecPath, strlen(lpszPSExecPath));

		if (!bIs64Bit)
			lpszCmdLineFormat = " -c -n %s %s \"%s\\cachedump.exe\" -v";
		else
			lpszCmdLineFormat = " -c -n %s %s \"%s\\cachedump64.exe\" -v";

		nArgSize = _scprintf(lpszCmdLineFormat, lpszPipeName, lpszMachine, lpszDumpPath);
		lpszParams = new char[nArgSize + 1];
		memset(lpszParams, 0, nArgSize + 1);
		_snprintf_s(lpszParams, nArgSize, strlen(lpszCmdLineFormat)-3+strlen(lpszPipeName)+strlen(lpszMachine)+strlen(lpszDumpPath), lpszCmdLineFormat, lpszPipeName, lpszMachine, lpszDumpPath);
	}

	try
	{
		Process p;

		HANDLE hProcess = p.CreateProcess(lpszStopCmdLine, lpszParams);
		if (hProcess != 0)
		{
			DWORD dwResult = WaitForSingleObject(hProcess, 1200000);	// Wait 20 minutes for process to complete
			if (dwResult != WAIT_OBJECT_0)
			{
				Log.CachedReportError(m_nCacheID, CRITICAL, "Warning: cachedump did not complete in a timely manner - exiting");
				result = false;
			}
			else
			{
				// Read from process's output
				char* szResult;
				int nSize = 65535;

				szResult = new char[nSize];
				memset(szResult, 0, nSize);
				p.ReadFromPipe(&szResult, nSize);

				// Was it successful?
				if (strstr(szResult, "successfully removed") != NULL)
				{
					// Success
					// Write results to a file
					size_t nLen = strlen(lpszMachine) + 10;		// 10 chars accounts for ".cachedump" extension
					char* szTempFilename = new char[nLen + 1];
					memset(szTempFilename, 0, nLen + 1);
					_snprintf_s(szTempFilename, nLen, strlen(lpszMachine)+10, "%s.cachedump", lpszMachine);

					std::ofstream outputFile(szTempFilename, std::ios::out | std::ios::trunc);
					outputFile.write((const char*)szResult, (DWORD)strlen(szResult));
					outputFile.close();
					delete [] szTempFilename;
					Log.CachedReportError(m_nCacheID, CRITICAL, "Cache dumped successfully\n", lpszMachine);
					result = true;
				}
				else
				{
					// Failed
					Log.CachedReportError(m_nCacheID, CRITICAL, "Failed to dump cache (the text returned follows):\n%s", szResult);
					result = false;
				}

				delete [] szResult;
			}
		}
		else
			result = false;
	}
	catch(...)
	{
		result = false;
	}

	delete [] lpszStopCmdLine;
	delete [] lpszParams;

	return result;
}
Beispiel #12
0
int Inject(HANDLE hProcess, const char *dll_dir, const char *dll_fn, const char *func_name, const void *param, const size_t param_size)
{
	// String constants
	const char *injectError1Format =
		"Could not inject %s.\n"
		"\n"
		"If you're running Windows Vista or 7, make sure that you have installed the KB2533623 update:\n"
		"\n"
		"\thttp://support.microsoft.com/kb/2533623/";
	const char *injectError2Format = "Could not load the function: %s";

//------------------------------------------//
// Function variables.                      //
//------------------------------------------//

	// Main DLL we will need to load
	HMODULE kernel32 = GetModuleHandleA("kernel32.dll");

	// Main functions we will need to import.
	// If [dll_fn] is absolute, LoadLibraryEx() with the LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
	// flag is used to guarantee that the injected DLL and its dependencies really
	// are only loaded from the given directory. Otherwise, LoadLibrary() may load
	// a possible other DLL with the same name from the directory of [hProcess].
	FARPROC getcurrentdirectory = GetProcAddress(kernel32, "GetCurrentDirectoryW");
	FARPROC setcurrentdirectory = GetProcAddress(kernel32, "SetCurrentDirectoryW");
	FARPROC loadlibrary = GetProcAddress(kernel32, "LoadLibraryW");
	FARPROC loadlibraryex = GetProcAddress(kernel32, "LoadLibraryExW");
	FARPROC getprocaddress = GetProcAddress(kernel32, "GetProcAddress");
	FARPROC exitthread = GetProcAddress(kernel32, "ExitThread");
	FARPROC freelibraryandexitthread = GetProcAddress(kernel32, "FreeLibraryAndExitThread");
	int have_kb2269637 = GetProcAddress(kernel32, "SetDefaultDllDirectories") != 0;

	// The workspace we will build the codecave on locally.
	// workspaceSize gets incremented with the final length of the error strings.
	size_t workspaceSize = 2048;
	LPBYTE workspace = NULL;
	LPBYTE p = NULL;

	// The memory in the process we write to
	LPBYTE codecaveAddress = NULL;

	// Strings we have to write into the process
	size_t injectError1_len = _scprintf(injectError1Format, dll_fn) + 1;
	size_t injectError2_len = _scprintf(injectError2Format, func_name) + 1;

	char *injectError0 = "Error";
	VLA(char, injectError1, injectError1_len);
	VLA(char, injectError2, injectError2_len);
	char *user32Name = "user32.dll";
	char *msgboxName = "MessageBoxW";

	// Placeholder addresses to use the strings
	LPBYTE user32NameAddr = 0;
	LPBYTE user32Addr = 0;
	LPBYTE msgboxNameAddr = 0;
	LPBYTE msgboxAddr = 0;
	LPBYTE dllAddr = 0;
	LPBYTE dllDirAddr = 0;
	LPBYTE dllNameAddr = 0;
	LPBYTE funcNameAddr = 0;
	LPBYTE funcParamAddr = 0;
	LPBYTE error0Addr = 0;
	LPBYTE error1Addr = 0;
	LPBYTE error2Addr = 0;

	// Where the codecave execution should begin at
	LPTHREAD_START_ROUTINE codecaveExecAddr = 0;

	// Handle to the thread we create in the process
	HANDLE hThread = NULL;

	// Old protection on page we are writing to in the process and the bytes written
	DWORD oldProtect = 0;
	DWORD byte_ret = 0;

	// Return code of injection function
	DWORD injRet;

//------------------------------------------//
// Variable initialization.                 //
//------------------------------------------//

// This section will cause compiler warnings on VS8,
// you can upgrade the functions or ignore them

	// Build error messages
	sprintf(injectError1, injectError1Format, dll_fn);
	sprintf(injectError2, injectError2Format, func_name);

	workspaceSize += (
		strlen(dll_dir) + 1 + strlen(dll_fn) + 1 + strlen(func_name) + 1 +
		param_size + strlen(injectError1) + 1 + strlen(injectError2) + 1
	) * sizeof(wchar_t);

	// Create the workspace
	workspace = (LPBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, workspaceSize);
	p = workspace;

	// Allocate space for the codecave in the process
	codecaveAddress = (LPBYTE)VirtualAllocEx(hProcess, 0, workspaceSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

// Note there is no error checking done above for any functions that return a pointer/handle.
// I could have added them, but it'd just add more messiness to the code and not provide any real
// benefit. It's up to you though in your final code if you want it there or not.

//------------------------------------------//
// Data and string writing.                 //
//------------------------------------------//

	// Reserve space for the user32 dll address, the MessageBox address,
	// and the address of the injected DLL's module.
	user32Addr = (p - workspace) + codecaveAddress;
	p += sizeof(LPBYTE);

	msgboxAddr = (p - workspace) + codecaveAddress;
	p += sizeof(LPBYTE);

	dllAddr = (p - workspace) + codecaveAddress;
	p += sizeof(LPBYTE);

	// User32 Dll Name
	user32NameAddr = (p - workspace) + codecaveAddress;
	p = StringToUTF16_advance_dst(p, user32Name);

	// MessageBox name
	msgboxNameAddr = (p - workspace) + codecaveAddress;
	p = memcpy_advance_dst(p, msgboxName, strlen(msgboxName) + 1);

	// Directory name
	if(dll_dir) {
		dllDirAddr = (p - workspace) + codecaveAddress;
		p = StringToUTF16_advance_dst(p, dll_dir);
	}

	// Dll Name
	dllNameAddr = (p - workspace) + codecaveAddress;
	p = StringToUTF16_advance_dst(p, dll_fn);

	// Function Name
	funcNameAddr = (p - workspace) + codecaveAddress;
	p = memcpy_advance_dst(p, func_name, strlen(func_name) + 1);

	// Function Parameter
	funcParamAddr = (p - workspace) + codecaveAddress;
	p = memcpy_advance_dst(p, param, param_size);

	// Error Message 1
	error0Addr = (p - workspace) + codecaveAddress;
	p = StringToUTF16_advance_dst(p, injectError0);

	// Error Message 2
	error1Addr = (p - workspace) + codecaveAddress;
	p = StringToUTF16_advance_dst(p, injectError1);

	// Error Message 3
	error2Addr = (p - workspace) + codecaveAddress;
	p = StringToUTF16_advance_dst(p, injectError2);

	// Pad a few INT3s after string data is written for seperation
	*p++ = 0xCC;
	*p++ = 0xCC;
	*p++ = 0xCC;

	// Store where the codecave execution should begin
	codecaveExecAddr = (LPTHREAD_START_ROUTINE)((p - workspace) + codecaveAddress);

// For debugging - infinite loop, attach onto process and step over
	//*p++ = 0xEB;
	//*p++ = 0xFE;

//------------------------------------------//
// User32.dll loading.                      //
//------------------------------------------//

// User32 DLL Loading
	// PUSH 0x00000000 - Push the address of the DLL name to use in LoadLibrary
	*p++ = 0x68;
	p = ptrcpy_advance_dst(p, user32NameAddr);

	// MOV EAX, ADDRESS - Move the address of LoadLibrary into EAX
	*p++ = 0xB8;
	p = ptrcpy_advance_dst(p, loadlibrary);

	// CALL EAX - Call LoadLibrary
	*p++ = 0xFF;
	*p++ = 0xD0;

// MessageBox Loading
	// PUSH 0x000000 - Push the address of the function name to load
	*p++ = 0x68;
	p = ptrcpy_advance_dst(p, msgboxNameAddr);

	// Push EAX, module to use in GetProcAddress
	*p++ = 0x50;

	// MOV EAX, ADDRESS - Move the address of GetProcAddress into EAX
	*p++ = 0xB8;
	p = ptrcpy_advance_dst(p, getprocaddress);

	// CALL EAX - Call GetProcAddress
	*p++ = 0xFF;
	*p++ = 0xD0;

	// MOV [ADDRESS], EAX - Save the address to our variable
	*p++ = 0xA3;
	p = ptrcpy_advance_dst(p, msgboxAddr);

//------------------------------------------//
// Injected dll loading.                    //
//------------------------------------------//

/*
	// This is the way the following assembly code would look like in C/C++

	// In case the injected DLL depends on other DLLs,
	// we need to change the current directory to the one given as parameter
	if(dll_dir) {
		size_t cur_dir_len = GetCurrentDirectory(0, NULL) + 1;
		VLA(wchar_t, cur_dir, cur_dir_len);
		GetCurrentDirectory(cur_dir, cur_dir_len);
		SetCurrentDirectory(dll_dir);
	}

	// Load the injected DLL into this process
	HMODULE h = LoadLibraryEx(dll_fn, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
	if(!h) {
		MessageBox(0, injectError1, "Error", MB_ICONERROR);
		ExitThread(1);
	}

	if(dll_dir) {
		SetCurrentDirectory(cur_dir);
	}

	// Get the address of the export function
	FARPROC p = GetProcAddress(h, func_name);
	if(!p) {
		MessageBox(0, injectError2, "Error", MB_ICONERROR);
		FreeLibraryAndExitThread(h, 2);
	}

	// So we do not need a function pointer interface
	__asm call p

	// Exit the thread so the loader continues
	ExitThread(0);
*/

// DLL Loading

	if(dllDirAddr) {
		// Registers:

		// ebp: Base stack frame
		// esi: GetCurrentDirectory / SetCurrentDirectory
		// ebx: Current directory of process (on stack)
		// ecx: byte length of string at ebx

		// mov ebp, esp - Save stack frame
		*p++ = 0x89;
		*p++ = 0xe5;

		// Get length for current directory

		// push 0
		// push 0
		*p++ = 0x6a;
		*p++ = 0x00;
		*p++ = 0x6a;
		*p++ = 0x00;
		// mov esi, GetCurrentDirectory
		*p++ = 0xbe;
		p = ptrcpy_advance_dst(p, getcurrentdirectory);

		// call esi
		*p++ = 0xFF;
		*p++ = 0xD6;

		/// Calculate byte size of directory buffer.
		/// Also do some poor man's DWORD boundary alignment
		/// in order to not f**k up the stack

		// mov ecx, eax
		// shl ecx, 1
		// and ecx, fffffff8
		// add ecx, 4

		*p++ = 0x89;
		*p++ = 0xc1;
		*p++ = 0xd1;
		*p++ = 0xe1;
		*p++ = 0x83;
		*p++ = 0xe1;
		*p++ = 0xf8;
		*p++ = 0x83;
		*p++ = 0xc1;
		*p++ = 0x04;

		/// "Allocate" ecx bytes on stack and store buffer pointer to ebx

		// sub esp, ecx
		// mov ebx, esp

		*p++ = 0x29;
		*p++ = 0xcc;
		*p++ = 0x89;
		*p++ = 0xe3;

		/// Call GetCurrentDirectory
		// push ebx
		// push eax
		// call esi
		*p++ = 0x53;
		*p++ = 0x50;
		*p++ = 0xff;
		*p++ = 0xd6;

		/// PUSH 0x00000000 - Push the address of our directory
		*p++ = 0x68;
		p = ptrcpy_advance_dst(p, dllDirAddr);

		// mov esi, SetCurrentDirectory
		*p++ = 0xbe;
		p = ptrcpy_advance_dst(p, setcurrentdirectory);

		// call esi
		*p++ = 0xFF;
		*p++ = 0xD6;
	}

	if(PathIsRelativeA(dll_fn) || !have_kb2269637) {
		// PUSH 0x00 (dwFlags = 0)
		*p++ = 0x6a;
		*p++ = 0x00;
	} else {
		// PUSH 0x00000900 (dwFlags = LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32)
		*p++ = 0x68;
		*p++ = 0x00;
		*p++ = 0x09;
		*p++ = 0x00;
		*p++ = 0x00;
	}

	// PUSH 0x00 (hFile = NULL)
	*p++ = 0x6a;
	*p++ = 0x00;

	// PUSH 0x00000000 - Push the address of the DLL name to use in LoadLibraryEx
	*p++ = 0x68;
	p = ptrcpy_advance_dst(p, dllNameAddr);

	// MOV EAX, ADDRESS - Move the address of LoadLibraryEx into EAX
	*p++ = 0xB8;
	p = ptrcpy_advance_dst(p, loadlibraryex);

	// CALL EAX - Call LoadLibraryEx
	*p++ = 0xFF;
	*p++ = 0xD0;

	// mov edi, eax - Save return value
	*p++ = 0x89;
	*p++ = 0xc7;

	if(dllDirAddr) {
		/// Reset directory to the original one of the process
		// push ebx
		// call esi
		*p++ = 0x53;
		*p++ = 0xFF;
		*p++ = 0xD6;

		/// Reset stack frame
		// mov esp, ebp
		*p++ = 0x89;
		*p++ = 0xec;
	}

// Error Checking
	// CMP EDI, 0
	*p++ = 0x83;
	*p++ = 0xFF;
	*p++ = 0x00;

// JNZ EIP + 0x1E to skip over eror code
	*p++ = 0x75;
	*p++ = 0x1E;

// Error Code 1
	// MessageBox
		// PUSH 0x10 (MB_ICONHAND)
		*p++ = 0x6A;
		*p++ = 0x10;

		// PUSH 0x000000 - Push the address of the MessageBox title
		*p++ = 0x68;
		p = ptrcpy_advance_dst(p, error0Addr);

		// PUSH 0x000000 - Push the address of the MessageBox message
		*p++ = 0x68;
		p = ptrcpy_advance_dst(p, error1Addr);

		// Push 0
		*p++ = 0x6A;
		*p++ = 0x00;

		// MOV EAX, [ADDRESS] - Move the address of MessageBox into EAX
		*p++ = 0xA1;
		p = ptrcpy_advance_dst(p, msgboxAddr);

		// CALL EAX - Call MessageBoxW
		*p++ = 0xFF;
		*p++ = 0xD0;

	// ExitThread
		// PUSH 1
		*p++ = 0x6A;
		*p++ = 0x01;

		// MOV EAX, ADDRESS - Move the address of ExitThread into EAX
		*p++ = 0xB8;
		p = ptrcpy_advance_dst(p, exitthread);

		// CALL EAX - Call ExitThread
		*p++ = 0xFF;
		*p++ = 0xD0;

//	Now we have the address of the injected DLL, so save the handle

	// MOV [ADDRESS], EAX - Save the address to our variable
	*p++ = 0x89;
	*p++ = 0x3D;
	p = ptrcpy_advance_dst(p, dllAddr);

// Load the initilize function from it

	// PUSH 0x000000 - Push the address of the function name to load
	*p++ = 0x68;
	p = ptrcpy_advance_dst(p, funcNameAddr);

	// Push EDI - module to use in GetProcAddress
	*p++ = 0x57;

	// MOV EAX, ADDRESS - Move the address of GetProcAddress into EAX
	*p++ = 0xB8;
	p = ptrcpy_advance_dst(p, getprocaddress);

	// CALL EAX - Call GetProcAddress
	*p++ = 0xFF;
	*p++ = 0xD0;

// Error Checking
	// CMP EAX, 0
	*p++ = 0x83;
	*p++ = 0xF8;
	*p++ = 0x00;

// JNZ EIP + 0x23 to skip eror code
	*p++ = 0x75;
	*p++ = 0x23;

// Error Code 2
	// MessageBox
		// PUSH 0x10 (MB_ICONHAND)
		*p++ = 0x6A;
		*p++ = 0x10;

		// PUSH 0x000000 - Push the address of the MessageBox title
		*p++ = 0x68;
		p = ptrcpy_advance_dst(p, error0Addr);

		// PUSH 0x000000 - Push the address of the MessageBox message
		*p++ = 0x68;
		p = ptrcpy_advance_dst(p, error2Addr);

		// Push 0
		*p++ = 0x6A;
		*p++ = 0x00;

		// MOV EAX, ADDRESS - Move the address of MessageBox into EAX
		*p++ = 0xA1;
		p = ptrcpy_advance_dst(p, msgboxAddr);

		// CALL EAX - Call MessageBoxA
		*p++ = 0xFF;
		*p++ = 0xD0;

	// FreeLibraryAndExitThread
		// PUSH 2
		*p++ = 0x6A;
		*p++ = 0x02;

		// PUSH 0x000000 - Push the injected DLL's module handle
		*p++ = 0x68;
		p = ptrcpy_advance_dst(p, dllAddr);

		// MOV EAX, ADDRESS - Move the address of FreeLibraryAndExitThread into EAX
		*p++ = 0xB8;
		p = ptrcpy_advance_dst(p, freelibraryandexitthread);

		// CALL EAX - Call ExitThread function
		*p++ = 0xFF;
		*p++ = 0xD0;

	// PUSH 0x000000 - Push the address of the function parameter
	*p++ = 0x68;
	p = ptrcpy_advance_dst(p, funcParamAddr);

	// CALL EAX - Call [func_name]
	*p++ = 0xFF;
	*p++ = 0xD0;

	// If we get here, [func_name] has been called,
	// so it's time to close this thread and optionally unload the DLL.

//------------------------------------------//
// Exiting from the injected dll.           //
//------------------------------------------//

// Call ExitThread to leave the DLL loaded
#if 1
	// PUSH 0 (exit code)
	*p++ = 0x6A;
	*p++ = 0x00;

	// MOV EAX, ADDRESS - Move the address of ExitThread into EAX
	*p++ = 0xB8;
	p = ptrcpy_advance_dst(p, exitthread);

	// CALL EAX - Call ExitThread
	*p++ = 0xFF;
	*p++ = 0xD0;
#endif

// Call FreeLibraryAndExitThread to unload DLL
#if 0
	// Push 0 (exit code)
	*p++ = 0x6A;
	*p++ = 0x00;

	// PUSH [0x000000] - Push the address of the DLL module to unload
	*p++ = 0xFF;
	*p++ = 0x35;
	p = ptrcpy_advance_dst(p, dllAddr);

	// MOV EAX, ADDRESS - Move the address of FreeLibraryAndExitThread into EAX
	*p++ = 0xB8;
	p = ptrcpy_advance_dst(p, freelibraryandexitthread);

	// CALL EAX - Call FreeLibraryAndExitThread
	*p++ = 0xFF;
	*p++ = 0xD0;
#endif

//------------------------------------------//
// Code injection and cleanup.              //
//------------------------------------------//

	// Change page protection so we can write executable code
	VirtualProtectEx(hProcess, codecaveAddress, p - workspace, PAGE_EXECUTE_READWRITE, &oldProtect);

	// Write out the patch
	WriteProcessMemory(hProcess, codecaveAddress, workspace, p - workspace, &byte_ret);

	// Restore page protection
	VirtualProtectEx(hProcess, codecaveAddress, p - workspace, oldProtect, &oldProtect);

	// Make sure our changes are written right away
	FlushInstructionCache(hProcess, codecaveAddress, p - workspace);

	// Free the workspace memory
	HeapFree(GetProcessHeap(), 0, workspace);

	// Execute the thread now and wait for it to exit, note we execute where the code starts, and not the codecave start
	// (since we wrote strings at the start of the codecave)
	hThread = CreateRemoteThread(hProcess, NULL, 0, codecaveExecAddr, 0, 0, NULL);
	WaitForSingleObject(hThread, INFINITE);

	GetExitCodeThread(hThread, &injRet);
	CloseHandle(hThread);

	// Free the memory in the process that we allocated
	VirtualFreeEx(hProcess, codecaveAddress, 0, MEM_RELEASE);

	VLA_FREE(injectError1);
	VLA_FREE(injectError2);
	return injRet;
}