HWBP on access

06/25/2012 23:59 Lazeboy#16
ein riesen dankeschön. Was mich noch interessieren würde wäre.
1. L0 - L3 gibt an ob da ein bp liegt oder ?
2. G0 - G3 wozu ist das ?
3. sollte nicht für einen Write bp 11 darein weil 01 wäre ja Breakpoint on Read oder ?

danke für die super erklärung werde mich dann mal an ne klasse dran setzen nachdem ichs mit hardcoded werten getestet habe ^^
06/26/2012 00:39 link#17
1. L0 ist für Dr0 (lineare Adresse), R/W0 (Zugriffsbedingung) und LEN0 (Längenbedingung), L1 für Dr1, R/W1 und LEN1, etc.
Wenn z.B. L3 gleich 1 ist, heißt das, dass der vierte Breakpoint aktiv ist und wenn die Bedingungen (also Dr3, R/W3 und LEN3) erfüllt sind, soll getrappt werden.
Wenn L3 gleich 0 ist, wird halt nicht getrappt, auch wenn in Dr3 eine Adresse steht und zusätzlich die Bedingungen in R/W3 und LEN3 erfüllt sind.

2. "Global Level BPs gibt es im Protected Mode nicht, deswegen musst du immer L0-L3 setzen."
Hätte ich besser ausführen sollen: also L0-L3 aktivieren die Local Level und G0-G3 die Global Level Hardware Breakpoints, die letzteren werden bei einem Task Switch nicht gelöscht, die anderen schon. Da im Protected Mode aber jeder Prozess einen eigenen Adressraum hat, gibt es keine globalen, sondern nur Kontext-gebundene (lokale) HW BPs.

3.
R/W:
00b/0d => on execution
01b/1d => on write
11b/3d => on access (read oder write)

LEN:
00b/0d => 1-Byte
01b/1d => 2-Byte
11b/3d => 4-Byte
10b/2d => 8-Byte (x86-64)
06/26/2012 14:46 MrSm!th#18
Was passiert eigentlich, wenn der Wert, auf den zugegriffen wird, mehr Platz benötigt, als in LEN angegeben?

Also wenn ich einen ReadWrite BP auf 4 Byte setze und dann 8 Byte von irgendwo gelesen werden?
Trappt der dann auch?
06/26/2012 15:54 link#19
Jo, LEN gibt wohl nicht die Größe des Zugriffs an, sondern wirklich einen Bereich von Bytes. Heißt wenn auch nur ein Byte bei einem Speicherzugriff in den durch Drx und LENx angegebenen Bereich fällt, wird getrappt (R/Wx muss natürlich auch stimmen).
06/26/2012 16:29 Ende!#20
Wenn die Menschen hier lernen würden die Dokumentation von Intel zu lesen, müsste link nichtmal halb so viel schreiben (im Übrigen meinen Respekt dafür, die Mühe alles genau zu dokumentieren hätte ich mir nicht gemacht). Wirklich jede Frage, die hier bisher gestellt wurde, steht in den rund 10 Seiten (große Schrift) der Dokumentation zum Thema HW-Breakpoints genaustens beschrieben.
06/26/2012 17:23 MrSm!th#21
Na und? Wenn er hier schonmal fleißig Hilfestellung gibt, kann ich ja auch nochmal ne Zwischenfrage stellen :>

So gut wie jede Frage lässt sich über irgendwelche Dokumentationen klären, dann könnte ich hier die ganze Sektion dicht machen.
06/26/2012 20:26 Lazeboy#22
kann mir jemand sagen warum das nicht funktioniert.

Code:
void SetBP()
{
	HANDLE MainThread = OpenMainThread(GetCurrentProcessId());

	SetUnhandledExceptionFilter(ExceptionFilter);
	CONTEXT ctx = {CONTEXT_DEBUG_REGISTERS};
	ctx.Dr0	 = dwBreakPoint;
	ctx.Dr7 = 0x1; // or Dr7, 00 00 00 00 11 01 00 00 00000000 0 0 0 0 0 1 0 0 b 
	if(bla != 0)
	{
		MessageBox(0,"thread",0,0);
		SetThreadContext(MainThread, &ctx);
		SetThreadContext(bla, &ctx);
	}

	CloseHandle(MainThread);



DWORD WINAPI MainThread(LPVOID n)
{

	while(1)
	{
		if(GetAsyncKeyState(VK_F1)&1)
		{
			/*BYTE buffer = 0;
			ReadProcessMemory(GetCurrentProcess(), (LPVOID)dwBreakPoint, &buffer, 1, 0);

			if((BYTE)(buffer) == 0xFF)
			MessageBox(0,0,0,0);*/

			HWND c = (HWND)0x000B0A8A;
			char a[] = "12345";
			DWORD b = 5;

			__asm
			{
				push c
				push a
				push b
				CALL dwBreakPoint
			}
		}
	}
	return 0;
}
}

wenn das hauptprogramm die funktion ausführt wird eine Exception ausgeführt. Wenn ich aber mit meinem Thread diese Funktion calle passiert nichts. Sollte nicht eig. die bps im MainThread reichen ?
Naja es geht weder mit bp im mainthread noch in meinem thread. Es klappt halt nur wenn das hauptprogramm sein gewohnten lauf nimmt.
06/26/2012 22:37 MrSm!th#23
Die Exception Handler sind kontextgebunden, funktionieren also nur in einem Thread und das ist bei deiner Methode natürlich der MainThread.
Wenn das Programm mehrere Threads hat funktionieren deine BPs trotzdem nur im MainThread, nicht in den anderen.

Früher hab ich Techniken gesehen, da hat jemand erst eine Funktion gehookt, die ganz sicher im Ziel-Thread gecalled wurde und von dort dann den HWBP und den Exception Handler gesetzt.

Ende! hat das ganze erst versucht, manuell in die SEH Chain jedes einzelnen Threads einzubauen, bis er darauf gestoßen ist, dass VectoredExceptionHandler prozessweit funktionieren :P
06/26/2012 23:13 Lazeboy#24
ok wenn ich jetzt ein Breakpoint on access darauf setze und mit einer dll versuche diese addresse zu lesen, dann breaked der ja auch nicht. Wie kann ich denn dann nen breakpoint on access setzen um zu gucken wer auf diese code blocks zu greift ? :(
06/26/2012 23:53 MrSm!th#25
Doch, klar, die BPs selbst sind threadübergreifend, nur die Exception Handler müssen für jeden Thread selbst gesetzt werden (oder halt mit VectoredExceptionHandlern).

edit:

Upps, kleiner Fehler, die BPs sind logischerweise auch threadgebunden, man setzt sie ja mit SetThreadContext.

Aber das sollte ja nicht das Problem sein, SetThreadContext kannst du einfach für jeden Thread im Prozess aufrufen und die BPs setzen.
Nur die UnhandledExcptionHandler lassen sich halt nur für den eigenen Thread setzen, aber dafür gibts ja wie gesagt VEH.
06/27/2012 00:18 Lazeboy#26
Quote:
Originally Posted by MrSm!th View Post
Doch, klar, die BPs selbst sind threadübergreifend, nur die Exception Handler müssen für jeden Thread selbst gesetzt werden (oder halt mit VectoredExceptionHandlern).

edit:

Upps, kleiner Fehler, die BPs sind logischerweise auch threadgebunden, man setzt sie ja mit SetThreadContext.

Aber das sollte ja nicht das Problem sein, SetThreadContext kannst du einfach für jeden Thread im Prozess aufrufen und die BPs setzen.
Nur die UnhandledExcptionHandler lassen sich halt nur für den eigenen Thread setzen, aber dafür gibts ja wie gesagt VEH.


Dann sollte das ja eig. so funktionieren:

Code:
DWORD	dwBreakPoint=0x00401000;

LONG WINAPI ExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) 
{
	if(ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
	{
		if((DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress == dwBreakPoint) 
		{
			
			MessageBox(0,"lol",0,0);
			//ExceptionInfo->ContextRecord->Eip  = dwBreakPoint+1;
			return EXCEPTION_CONTINUE_EXECUTION;
		}
	}
	return EXCEPTION_CONTINUE_SEARCH;
}


HANDLE AllThread(DWORD dwPid, CONTEXT ctx)
{
	HANDLE hTool32 = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
	if(hTool32 != INVALID_HANDLE_VALUE) 
	{
		THREADENTRY32 thread_entry32;
		thread_entry32.dwSize = sizeof(THREADENTRY32);
		FILETIME exit_time, kernel_time, user_time;
		FILETIME creation_time;
		FILETIME prev_creation_time;
		prev_creation_time.dwLowDateTime = 0xFFFFFFFF;
		prev_creation_time.dwHighDateTime = INT_MAX;
		HANDLE hMainThread = NULL;

		if(Thread32First(hTool32, &thread_entry32)) 
		{
			do 
			{
				if(thread_entry32.th32OwnerProcessID == GetCurrentProcessId()) 
				{
					HANDLE hThread = OpenThread(THREAD_SET_CONTEXT | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION,
						FALSE, thread_entry32.th32ThreadID);
					
					
					SetThreadContext(hThread, &ctx);
					CloseHandle(hThread);
				}
				thread_entry32.dwSize = sizeof(THREADENTRY32);
			} while(Thread32Next(hTool32, &thread_entry32));

			CloseHandle(hTool32);

			return hMainThread;

		}
	}
}


void SetBP()
{
	//HANDLE MainThread = OpenMainThread(GetCurrentProcessId());

	AddVectoredExceptionHandler (1,ExceptionFilter);
	CONTEXT ctx = {CONTEXT_DEBUG_REGISTERS};
	ctx.Dr6 = 0;
 	ctx.Dr1	 = dwBreakPoint;
 	ctx.Dr7 = 0x000004; // or Dr7, 00 00 00 00 11 01 00 00 00000000 0 0 0 0 0 1 0 0 b 

	AllThread(GetCurrentProcessId(), ctx);//setzt in allen threads den context

	//CloseHandle(MainThread);
}


DWORD WINAPI MainThread(LPVOID n)
{

	while(1)
	{

		if(GetAsyncKeyState(VK_F1)&1)
		{
			//---------------------------------- BP on Access test------------------------------
			BYTE buffer = 0;
			ReadProcessMemory(GetCurrentProcess(), (LPVOID)dwBreakPoint, &buffer, 1, 0);

			if((BYTE)(buffer) == 0x55)
				MessageBox(0,0,0,0);

			
			//---------------------------------- BP on execute test------------------------------
			HWND c = (HWND)0x00230A82;
			char a[] = "12345";
			DWORD b = 5;

			__asm
			{
				push a
				push b
				push c
				call [dwBreakPoint]
			}
		}
	}
	return 0;
}


BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
	switch(ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
			DisableThreadLibraryCalls(GetModuleHandle(NULL));
			
			bla = CreateThread(0,0,&MainThread,0,0,0);
			SetBP();
		break;

		case DLL_PROCESS_DETACH:

		break;
	}

	return true;
}
tut es aber nicht. Wenn ich aus dem Access bp jetzt nen execute mache funkt es wieder wenn vom programm drauf zu gegriffen wird von meiner dll funktioniert es aber nicht.