Exemplo n.º 1
0
ResultType Clipboard::Open()
{
	if (mIsOpen)
		return OK;

#ifdef _WIN64
	DWORD aThreadID = __readgsdword(0x48); // Used to identify if code is called from different thread (AutoHotkey.dll)
#else
	DWORD aThreadID = __readfsdword(0x24);
#endif

	for (DWORD start_time = GetTickCount();;)
	{
		if (OpenClipboard(g_hWnd))
		{
			mIsOpen = true;
			return OK;
		}
		if (g_ClipboardTimeout != -1) // We were not told to wait indefinitely...
			if (!g_ClipboardTimeout   // ...and we were told to make only one attempt, or ...
				|| (int)(g_ClipboardTimeout - (GetTickCount() - start_time)) <= SLEEP_INTERVAL_HALF) //...it timed out.
				// Above must cast to int or any negative result will be lost due to DWORD type.
				return FAIL;
		// Use SLEEP_WITHOUT_INTERRUPTION to prevent MainWindowProc() from accepting new hotkeys
		// during our operation, since a new hotkey subroutine might interfere with
		// what we're doing here (e.g. if it tries to use the clipboard, or perhaps overwrites
		// the deref buffer if this object's caller gave it any pointers into that memory area):
		SLEEP_WITHOUT_INTERRUPTION(INTERVAL_UNSPECIFIED)
	}
}
Exemplo n.º 2
0
__declspec(dllexport) int APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
#endif

{
	unsigned long TID = __readgsdword(0x48);

	if (loadSystemDebugControl == NULL)
	{
		HMODULE dNTdll = GetModuleHandleA("ntdll.dll");
		loadSystemDebugControl = (NtSystemDebugControl)GetProcAddress(dNTdll, "NtSystemDebugControl");
	}

	if (reason == DLL_PROCESS_ATTACH)
	{
		if (AllocConsole()) {
			freopen("CONOUT$", "w", stdout);
			SetConsoleTitle(L"EhTrace Debug Window");
			wprintf(L"DLL loaded.\n");
			if (loadSystemDebugControl != NULL)
				wprintf(L"also ready for DEBUG MSR WRITE");
		}
		ConfigMap = ConnectConfig();
		wprintf(L"Connecting ConfigMap %p\n", ConfigMap);

		// logger will spin the thread if logs are not picked up fast enough
		SetupLogger(STRACE_LOG_BUFFER_SIZE);
		Initalize(NULL);

		InstallThread(TID, 2);
		//hPulseThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PulseThreads, 0, 0, NULL);
		//NoLogThrId = GetThreadId(hPulseThread);

		//wprintf(L"Symbol count is %llx\n", ConfigMap->SymCnt);
		//ConnectSymbols(ConfigMap->SymCnt);

	}
	else if (reason == DLL_THREAD_ATTACH)
	{
		// setup monitoring of this thread
		UnTracedThreadCount++;
		InstallThread(TID, 3);
	}
	else if (reason == DLL_THREAD_DETACH)
	{
		ExitThreadTable(TID, true);
		
		if(CtxTable[TID].insn != NULL)
			cs_free(CtxTable[TID].insn, 1);

		memset(&CtxTable[TID], 0, sizeof(ExecutionBlock));
		wprintf(L"Cleaned up thread %d\n", TID);

	}
	wprintf(L"done in dllmain\n");
	return TRUE;
}
Exemplo n.º 3
0
// In the spirt of so many exceptions! =D blah! https://msdn.microsoft.com/en-us/library/1eyas8tf.aspx
LONG WINAPI vEhTracer(PEXCEPTION_POINTERS ExceptionInfo)
{
	DWORD OldPerm;
	PExecutionBlock pCtx = NULL;

	ULONG64 dwThr = __readgsdword(0x48);


	// TODO: just put the whole context in the array to remove an indirect anyhow
	if (CtxTable != NULL && CtxTable[dwThr].TID != 0)
		pCtx = &CtxTable[dwThr];
	else
		pCtx = InitBlock(dwThr);

	// allow exec
	//pCtx->DisabledUntil = (LPVOID)((ULONG64) ExceptionInfo->ExceptionRecord->ExceptionAddress & ~0x4095);
	
	pCtx->pExeption = ExceptionInfo;
	pCtx->TSC = __rdtsc();

	// check if my thread is a thread that's already entered into the VEH logging something lower on the stack
	// this means were probably getting an exception for something we did ourselves during the logging 
	// which is sort of pointless
	// we could test all Exception address against known entries we provide
	if (AmIinThreadTable())
		return EXCEPTION_CONTINUE_EXECUTION;


	if (ExceptionInfo->ExceptionRecord->ExceptionCode != STATUS_SINGLE_STEP)
		return EXCEPTION_CONTINUE_SEARCH;

	// no re-entrance while servicing exceptions
	EnterThreadTable(dwThr, false);

	// since we like to do logging
	//LogRIP(pCtx);
	// to dump info 
	//_DumpContext(pCtx);

	// Loop through all of the block fighters
	Fight(pCtx);

	// Thanks Feryno
	// http://x86asm.net/articles/backdoor-support-for-control-transfer-breakpoint-features/
	// 
	ExceptionInfo->ContextRecord->EFlags |= 0x100; // single step
	ExceptionInfo->ContextRecord->Dr7 |= 0x300; // setup branch tracing 

	// record keeping
	pCtx->BlockFrom = ExceptionInfo->ContextRecord->Rip;

	// exit lock
	ExitThreadTable(dwThr, false);
	
	return EXCEPTION_CONTINUE_EXECUTION;
}
Exemplo n.º 4
0
HANDLE Clipboard::GetClipboardDataTimeout(UINT uFormat, BOOL *aNullIsOkay)
// Update for v1.1.16: The comments below are obsolete; search for "v1.1.16" for related comments.
// Same as GetClipboardData() except that it doesn't give up if the first call to GetClipboardData() fails.
// Instead, it continues to retry the operation for the number of milliseconds in g_ClipboardTimeout.
// This is necessary because GetClipboardData() has been observed to fail in repeatable situations (this
// is strange because our thread already has the clipboard locked open -- presumably it happens because the
// GetClipboardData() is unable to start a data stream from the application that actually serves up the data).
// If cases where the first call to GetClipboardData() fails, a subsequent call will often succeed if you give
// the owning application (such as Excel and Word) a little time to catch up.  This is especially necessary in
// the OnClipboardChange label, where sometimes a clipboard-change notification comes in before the owning
// app has finished preparing its data for subsequent readers of the clipboard.
{
#ifdef DEBUG_BY_LOGGING_CLIPBOARD_FORMATS  // Provides a convenient log of clipboard formats for analysis.
	static FILE *fp = fopen("c:\\debug_clipboard_formats.txt", "w");
#endif

	if (aNullIsOkay)
		*aNullIsOkay = FALSE; // Set default.

	TCHAR format_name[MAX_PATH + 1]; // MSDN's RegisterClipboardFormat() doesn't document any max length, but the ones we're interested in certainly don't exceed MAX_PATH.
	if (uFormat < 0xC000 || uFormat > 0xFFFF) // It's a registered format (you're supposed to verify in-range before calling GetClipboardFormatName()).  Also helps performance.
		*format_name = '\0'; // Don't need the name if it's a standard/CF_* format.
	else
	{
		// v1.0.42.04:
		// Probably need to call GetClipboardFormatName() rather than comparing directly to uFormat because
		// MSDN implies that OwnerLink and other registered formats might not always have the same ID under
		// all OSes (past and future).
		GetClipboardFormatName(uFormat, format_name, MAX_PATH);
		// Since RegisterClipboardFormat() is case insensitive, the case might vary.  So use stricmp() when
		// comparing format_name to anything.
		// "Link Source", "Link Source Descriptor" , and anything else starting with "Link Source" is likely
		// to be data that should not be attempted to be retrieved because:
		// 1) It causes unwanted bookmark effects in various versions of MS Word.
		// 2) Tests show that these formats are on the clipboard only if MS Word is open at the time
		//    ClipboardAll is accessed.  That implies they're transitory formats that aren't as essential
		//    or well suited to ClipboardAll as the other formats (but if it weren't for #1 above, this
		//    wouldn't be enough reason to omit it).
		// 3) Although there is hardly any documentation to be found at MSDN or elsewhere about these formats,
		//    it seems they're related to OLE, with further implications that the data is transitory.
		// Here are the formats that Word 2002 removes from the clipboard when it the app closes:
		// 0xC002 ObjectLink  >>> Causes WORD bookmarking problem.
		// 0xC003 OwnerLink
		// 0xC00D Link Source  >>> Causes WORD bookmarking problem.
		// 0xC00F Link Source Descriptor  >>> Doesn't directly cause bookmarking, but probably goes with above.
		// 0xC0DC Hyperlink
		if (   !_tcsnicmp(format_name, _T("Link Source"), 11) || !_tcsicmp(format_name, _T("ObjectLink"))
			|| !_tcsicmp(format_name, _T("OwnerLink"))
			// v1.0.44.07: The following were added to solve interference with MS Outlook's MS Word editor.
			// If a hotkey like ^F1::ClipboardSave:=ClipboardAll is pressed after pressing Ctrl-C in that
			// editor (perhaps only when copying HTML), two of the following error dialogs would otherwise
			// be displayed (this occurs in Outlook 2002 and probably later versions):
			// "An outgoing call cannot be made since the application is dispatching an input-synchronous call."
			|| !_tcsicmp(format_name, _T("Native")) || !_tcsicmp(format_name, _T("Embed Source"))   )
			return NULL;
		if (!_tcsicmp(format_name, _T("MSDEVColumnSelect")) || !_tcsicmp(format_name, _T("MSDEVLineSelect")))
		{
			// v1.1.16: These formats are used by Visual Studio, Scintilla controls and perhaps others for
			// copying whole lines and rectangular blocks.  Because their very presence/absence is used as
			// a boolean indicator, the data is irrelevant.  Presumably for this reason, Scintilla controls
			// set NULL data, though doing so and then not handling WM_RENDERFORMAT is probably invalid.
			// Note newer versions of Visual Studio use "VisualStudioEditorOperationsLineCutCopyClipboardTag"
			// for line copy, but that doesn't need to be handled here because it has non-NULL data (and the
			// latest unreleased Scintilla [as at 2014-08-19] uses both, so we can discard the long one).
			// Since we just want to preserve this format's presence, indicate to caller that NULL is okay:
			if (aNullIsOkay) // i.e. caller passed a variable for us to set.
				*aNullIsOkay = TRUE;
			return NULL;
		}
	}

#ifdef DEBUG_BY_LOGGING_CLIPBOARD_FORMATS
	_ftprintf(fp, _T("%04X\t%s\n"), uFormat, format_name);  // Since fclose() is never called, the program has to exit to close/release the file.
#endif

#ifndef ENABLE_CLIPBOARDGETDATA_TIMEOUT
	// v1.1.16: The timeout and retry behaviour of this function is currently disabled, since it does more
	// harm than good.  It previously did NO GOOD WHATSOEVER, because SLEEP_WITHOUT_INTERRUPTION indirectly
	// calls g_clip.Close() via CLOSE_CLIPBOARD_IF_OPEN, so any subsequent attempts to retrieve data by us
	// or our caller always fail.  The main point of failure where retrying helps is OpenClipboard(), when
	// another program has the clipboard open -- and that's handled elsewhere.  If the timeout is re-enabled
	// for this function, the following format will need to be excluded to prevent unnecessary delays:
	//  - FileContents (CSTR_FILECONTENTS): MSDN says it is used "to transfer data as if it were a file,
	//    regardless of how it is actually stored".  For example, it could be a file inside a zip folder.
	//    However, on Windows 8 it seems to also be present for normal files.  It might be possible to
	//    retrieve its data via OleGetClipboard(), though it could be very large.

	// Just return the data, even if NULL:
	return GetClipboardData(uFormat);
#else
	HANDLE h;

#ifdef _WIN64
	DWORD aThreadID = __readgsdword(0x48); // Used to identify if code is called from different thread (AutoHotkey.dll)
#else
	DWORD aThreadID = __readfsdword(0x24);
#endif

	for (DWORD start_time = GetTickCount();;)
	{
		// Known failure conditions:
		// GetClipboardData() apparently fails when the text on the clipboard is greater than a certain size
		// (Even though GetLastError() reports "Operation completed successfully").  The data size at which
		// this occurs is somewhere between 20 to 96 MB (perhaps depending on system's memory and CPU speed).
		if (h = GetClipboardData(uFormat)) // Assign
			return h;

		// It failed, so act according to the type of format and the timeout that's in effect.
		// Certain standard (numerically constant) clipboard formats are known to validly yield NULL from a
		// call to GetClipboardData().  Never retry these because it would only cause unnecessary delays
		// (i.e. a failure until timeout).
		// v1.0.42.04: More importantly, retrying them appears to cause problems with saving a Word/Excel
		// clipboard via ClipboardAll.
		if (uFormat == CF_HDROP // This format can fail "normally" for the reasons described at "clipboard_contains_files".
			|| !_tcsicmp(format_name, _T("OwnerLink"))) // Known to validly yield NULL from a call to GetClipboardData(), so don't retry it to avoid having to wait the full timeout period.
			return NULL;

		if (g_ClipboardTimeout != -1) // We were not told to wait indefinitely and...
			if (!g_ClipboardTimeout   // ...we were told to make only one attempt, or ...
				|| (int)(g_ClipboardTimeout - (GetTickCount() - start_time)) <= SLEEP_INTERVAL_HALF) //...it timed out.
				// Above must cast to int or any negative result will be lost due to DWORD type.
				return NULL;

		// Use SLEEP_WITHOUT_INTERRUPTION to prevent MainWindowProc() from accepting new hotkeys
		// during our operation, since a new hotkey subroutine might interfere with
		// what we're doing here (e.g. if it tries to use the clipboard, or perhaps overwrites
		// the deref buffer if this object's caller gave it any pointers into that memory area):
		SLEEP_WITHOUT_INTERRUPTION(INTERVAL_UNSPECIFIED)
	}
#endif
}