C Sddt hook

08/25/2011 16:43 Lazeboy#1
Hey ich bin gerade dabei OpenProcess,Write/ReadProcessMemory wieder zu Unhooken und habe deswegen diesen treiber geschrieben nur das problem ist ZwOpenProcess funktioniert der hook wunderbar aber bei ZwReadVirtualMemory muss ich die ntdll.lib linken und wenn ich das dann erstellt hab lässt sich der treiber nicht starten..... weiß jemand woran das liegt ?
Code:
#include "stdafx.h"

VOID OnUnload(IN PDRIVER_OBJECT DriverObject);

typedef unsigned long DWORD, *PDWORD;
typedef unsigned char BYTE, *PBYTE, *PCHAR;
typedef unsigned long ULONG_PTR;
typedef ULONG_PTR DWORD_PTR;



typedef struct ServiceDescriptorEntry {
	unsigned int *ServiceTable;
	unsigned int *ServiceCounterTableBase; //Used only in checked build
	unsigned int NumberOfServices;
	unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;


__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; 

#define SYSTEMSERVICE( _Call )  \
	KeServiceDescriptorTable.ServiceTable[* ( unsigned int * ) \
	( ( unsigned char * ) _Call + 1 )]




NTSYSAPI NTSTATUS NTAPI NtOpenProcess(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL);
typedef NTSTATUS (*NTOPENPROCESS)(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL);
NTOPENPROCESS OldNtOpenProcess;


NTSYSAPI NTSTATUS NTAPI ZwQueryInformationProcess(HANDLE ProcessHandle,PROCESSINFOCLASS ProcessInformationClass,	PVOID ProcessInformation,ULONG ProcessInformationLength,PULONG ReturnLength	);
typedef NTSTATUS (*ZWQUERYINFORMATIONPROCESS)(HANDLE,PROCESSINFOCLASS,PVOID,ULONG,PULONG);
ZWQUERYINFORMATIONPROCESS OldZwQueryInformationProcess;

NTSYSAPI NTSTATUS NTAPI NtWriteVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN ULONG NumberOfBytesToWrite, OUT PULONG NumberOfBytesWritten OPTIONAL ); 
typedef NTSTATUS (*NTWRITEVIRTUALMEMORY)(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN ULONG NumberOfBytesToWrite, OUT PULONG NumberOfBytesWritten OPTIONAL ); 
NTWRITEVIRTUALMEMORY OldNtWriteVirtualMemory;




long pid = -1;
NTSTATUS NewNtOpenProcess(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL)
{

	LONG nStatus = OldNtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
	if(nStatus != STATUS_SUCCESS)nStatus = STATUS_SUCCESS;

	return nStatus;
}


NTSTATUS NewZwQueryInformationProcess(HANDLE a,PROCESSINFOCLASS b,PVOID c,ULONG d,PULONG e)
{
	if(b == ProcessBasicInformation && a != 0)
	{
		PROCESS_BASIC_INFORMATION* pbi = (PROCESS_BASIC_INFORMATION*)c;
		pbi->UniqueProcessId = (ULONG_PTR)2;
	}

	return OldZwQueryInformationProcess(a,b,c,d,e);;
}



NTSTATUS NewNtWriteVirtualMemory(HANDLE a,PVOID b,PVOID c,ULONG d,PULONG e)
{
	NTSTATUS aa = OldNtWriteVirtualMemory(a,b,c,d,e);
	return aa;
}






LONG nOldProtect;

VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
	(NTOPENPROCESS)(SYSTEMSERVICE(ZwOpenProcess)) = OldNtOpenProcess;
	(ZWQUERYINFORMATIONPROCESS)(SYSTEMSERVICE(ZwQueryInformationProcess)) = OldZwQueryInformationProcess;
	(NTWRITEVIRTUALMEMORY)(SYSTEMSERVICE(NtWriteVirtualMemory)) = OldNtWriteVirtualMemory;
}






NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING theRegistryPath)
{
	NTSTATUS        ntStatus = STATUS_SUCCESS;
	UNICODE_STRING  ntDeviceName;
	UNICODE_STRING  DeviceLinkString;
	PDEVICE_OBJECT  deviceObject = NULL;

	OldNtOpenProcess =SYSTEMSERVICE(ZwOpenProcess);
	SYSTEMSERVICE(ZwOpenProcess) = NewNtOpenProcess;

	OldZwQueryInformationProcess = SYSTEMSERVICE(ZwQueryInformationProcess);
	SYSTEMSERVICE(ZwQueryInformationProcess) = NewZwQueryInformationProcess;


	OldNtWriteVirtualMemory = SYSTEMSERVICE(NtWriteVirtualMemory);
	SYSTEMSERVICE(NtWriteVirtualMemory) = NewNtWriteVirtualMemory;


	return STATUS_SUCCESS;
}
08/25/2011 17:54 link#2
Aber ansonsten funktioniert der Hook?
Musst also nicht Write Protect deaktivieren oder mit InterlockedExchange den Wert überschreiben?

SYSTEM_SERVICE holt sich ja den Tabellenindex für sysenter, funktioniert also nur mit den syscall-Wrappern, wie sehen die Adressen und die ersten 5 Bytes von ZwOpenProcess, ZwQueryInformationProcess, NtWriteVirtualMemory, etc. bei dir denn aus?
Du könntest es auch einfach mal mit hardcoded Indizes testen
08/25/2011 18:34 Lazeboy#3
hey erstmal danke für die Hilfe... also das mit den ersten 5 byte s vertteh ich nicht ganz weil bei jeder Zw funktion ist das doch das selbe Ersten 5 bytes: mov eax,FunktionId.
Wenn ich das
OldNtWriteVirtualMemory = SYSTEMSERVICE(NtWriteVirtualMemory);
SYSTEMSERVICE(NtWriteVirtualMemory) = NewNtWriteVirtualMemory;
raus nehme funktioniert der OpenProcess hook wunderbar....
wie soll ich denn den WriteProtect deaktivieren ?
InterlochExchange führt auch zu keinen ergebnis... ^^

Jetzt hab ich alles ein bissl durcheinander beantwortet ich hoffe du verstehst alles :D
08/25/2011 18:55 link#4
Deswegen mein ich ja, guck mal, ob an [NtWriteVirtualMemory] auch mov eax,index steht oder benutz mal einen hardcoded Index (XP: 115h, 7: 18Fh).

Kompiliert wird der Driver erfolgreich, aber laden lässt er sich nicht?

"raus nehme funktioniert der OpenProcess hook wunderbar...."

Hast es also auch getestet und evtl. mal mit DbgPrint den Wert in der DescriptorTable vor und nach dem Überschreiben ausgegeben und mit der Adresse deiner Funktion abgeglichen?

Edit:
Btw. DriverObject->DriverUnload = OnUnload; scheinst du vergessen zu haben
08/25/2011 21:14 Lazeboy#5
hey also wie ich das sehe ist dort auch mov eax, 18F ich kann nicht auf
SYSTEMSERVICE(NtWriteVirtualMemory) zugreifen sobald das igrendwo im code steht, lässt sich der driver registieren aber nicht mehr starten und somit fällt auch das "Hast es also auch getestet und evtl. mal mit DbgPrint den Wert in der DescriptorTable vor und nach dem Überschreiben ausgegeben und mit der Adresse deiner Funktion abgeglichen?" leider Flach..... leider weiß ich nicht wie ich das mit hardcoded so direkt umsetzen soll aber ich bin dran danke für die hilfe.......hier ist nochmal der funktionierende code
Code:
#include "stdafx.h"

VOID OnUnload(IN PDRIVER_OBJECT DriverObject);

typedef unsigned long DWORD, *PDWORD;
typedef unsigned char BYTE, *PBYTE, *PCHAR;
typedef unsigned long ULONG_PTR;
typedef ULONG_PTR DWORD_PTR;



typedef struct ServiceDescriptorEntry {
	unsigned int *ServiceTable;
	unsigned int *ServiceCounterTableBase; //Used only in checked build
	unsigned int NumberOfServices;
	unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;


__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; 

#define SYSTEMSERVICE( _Call )  \
	KeServiceDescriptorTable.ServiceTable[* ( unsigned int * ) \
	( ( unsigned char * ) _Call + 1 )]




NTSYSAPI NTSTATUS NTAPI NtOpenProcess(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL);
typedef NTSTATUS (*NTOPENPROCESS)(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL);
NTOPENPROCESS OldNtOpenProcess;


NTSYSAPI NTSTATUS NTAPI ZwQueryInformationProcess(HANDLE ProcessHandle,PROCESSINFOCLASS ProcessInformationClass,	PVOID ProcessInformation,ULONG ProcessInformationLength,PULONG ReturnLength	);
typedef NTSTATUS (*ZWQUERYINFORMATIONPROCESS)(HANDLE,PROCESSINFOCLASS,PVOID,ULONG,PULONG);
ZWQUERYINFORMATIONPROCESS OldZwQueryInformationProcess;

NTSYSAPI NTSTATUS NTAPI NtWriteVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN ULONG NumberOfBytesToWrite, OUT PULONG NumberOfBytesWritten OPTIONAL ); 
typedef NTSTATUS (*NTWRITEVIRTUALMEMORY)(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN ULONG NumberOfBytesToWrite, OUT PULONG NumberOfBytesWritten OPTIONAL ); 
NTWRITEVIRTUALMEMORY OldNtWriteVirtualMemory;




long pid = -1;
NTSTATUS NewNtOpenProcess(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL)
{

	LONG nStatus = OldNtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
	if(nStatus != STATUS_SUCCESS)nStatus = STATUS_SUCCESS;

	return nStatus;
}


NTSTATUS NewZwQueryInformationProcess(HANDLE a,PROCESSINFOCLASS b,PVOID c,ULONG d,PULONG e)
{
	if(b == ProcessBasicInformation && a != 0)
	{
		PROCESS_BASIC_INFORMATION* pbi = (PROCESS_BASIC_INFORMATION*)c;
		pbi->UniqueProcessId = (ULONG_PTR)2;
	}

	return OldZwQueryInformationProcess(a,b,c,d,e);;
}


//
//NTSTATUS NewNtWriteVirtualMemory(HANDLE a,PVOID b,PVOID c,ULONG d,PULONG e)
//{
//	NTSTATUS aa = OldNtWriteVirtualMemory(a,b,c,d,e);
//	return a;
//}






LONG nOldProtect;

VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
	(NTOPENPROCESS)(SYSTEMSERVICE(ZwOpenProcess)) = OldNtOpenProcess;
	(ZWQUERYINFORMATIONPROCESS)(SYSTEMSERVICE(ZwQueryInformationProcess)) = OldZwQueryInformationProcess;
	//(NTWRITEVIRTUALMEMORY)(SYSTEMSERVICE(NtWriteVirtualMemory)) = OldNtWriteVirtualMemory;
	DbgPrint("Unloaded");
}






NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING theRegistryPath)
{
	


	DriverObject->DriverUnload = OnUnload;
		

	OldNtOpenProcess =SYSTEMSERVICE(ZwOpenProcess);
	SYSTEMSERVICE(ZwOpenProcess) = NewNtOpenProcess;

	OldZwQueryInformationProcess = SYSTEMSERVICE(ZwQueryInformationProcess);
	SYSTEMSERVICE(ZwQueryInformationProcess) = NewZwQueryInformationProcess;
	
	
	//DbgPrint("%X",SYSTEMSERVICE(NtWriteVirtualMemory));
	//SYSTEMSERVICE(NtWriteVirtualMemory) = NewNtWriteVirtualMemory;
	


	return STATUS_SUCCESS;
}
08/25/2011 22:26 link#6
Code:
OldNtWriteVirtualMemory = KeServiceDescriptorTable.ServiceTable[0x18F];
KeServiceDescriptorTable.ServiceTable[0x18F] = NewNtWriteVirtualMemory;
Wenn das funktionieren sollte, könntest du, um es wieder dynamischer zu gestalten, entweder eine OS-Abfrage implementieren und dann ein Array mit den Indizes von NtWriteVirtualMemory unter 2k, XP, Vista und 7 benutzen oder ntdll.dll manuell mappen und die Exports durchgehen, um so an NtWriteVirtualMemory und somit an das mov eax,index zu kommen

Wenn nicht, kA *hust*
08/25/2011 23:01 Lazeboy#7
hey jo so gehts :D da ich das ehh nur für mich zum testen benutzen möchte ist das bis jetzt schon richtig cool vielen dank für deine hilfe
btw...womit entdeckt hshield ander programme weil mit ZwQuerySystemInformation hab ich den process aus dem TskManager genommen aber wird immer noch entdeckt, dass können ja jetzt nur noch ring 3 detections sein oder ?
und noch ne frage Wie kann ich Read und WriteVirtualMemory failen lassen also STATUS_ACCESS_DENIED oder STATUS_UNSUCCESSFULL oder NULL return geht alles nicht :D
08/26/2011 03:00 link#8
Quote:
womit entdeckt hshield ander programme weil mit ZwQuerySystemInformation hab ich den process aus dem TskManager genommen aber wird immer noch entdeckt
kA.. GG könnte auch über ein EPROCESS-Objekt die Prozessliste durchgehen, da dürfte ein ZwQuerySystemInformation-Hook nicht viel bringen, oder es wird nach Fenstern gesucht, weiß ich leider nicht


Quote:
Wie kann ich Read und WriteVirtualMemory failen lassen also STATUS_ACCESS_DENIED oder STATUS_UNSUCCESSFULL oder NULL return geht alles nicht
Was genau geht dabei denn nicht? Wenn du einfach
mov eax,1
retn 14h

oder
return 1;
an's Ende schreibst, sollte doch auch dieser Wert beim Caller ankommen, der diesen dann als fehlgeschlagen interpretiert.
08/26/2011 10:16 Lazeboy#9
Quote:
Originally Posted by link View Post
kA.. GG könnte auch über ein EPROCESS-Objekt die Prozessliste durchgehen, da dürfte ein ZwQuerySystemInformation-Hook nicht viel bringen, oder es wird nach Fenstern gesucht, weiß ich leider nicht



Was genau geht dabei denn nicht? Wenn du einfach
mov eax,1
retn 14h

oder
return 1;
an's Ende schreibst, sollte doch auch dieser Wert beim Caller ankommen, der diesen dann als fehlgeschlagen interpretiert.


ach ich habs bei Cheat engine getestet und irgendwi kann ce trotzdem scanen aber bei eigenen programmen geht das....

@hackshield das problem ist halt ich würde gerne auch nachdem hackshield geladen ist eine dll injecten können nur ich schalte halt OpenProcess frei und dann wird anscheinend auch noch VirtualAllocEx gehooked aber auf Userebende... und ich würde halt gerne die Funktion auch freischalten aber geht ja nicht weil hackshield die hooks ja entdeckt .... boah das ist alles so kompliziert :D
08/26/2011 13:17 ms​#10
Quote:
Originally Posted by Lazeboy View Post
ach ich habs bei Cheat engine getestet und irgendwi kann ce trotzdem scanen aber bei eigenen programmen geht das....
CE benutzt afaik auch einen eigenen Treiber fürs Memory-Scanning.
08/26/2011 13:21 Lazeboy#11
Quote:
Originally Posted by Metin2Spieler97 View Post
CE benutzt afaik auch einen eigenen Treiber fürs Memory-Scanning.
jop eben :D
ich glaube das problem ist, das ich damit OpenProcess nicht feischalte

Code:
NTSTATUS NTAPI NewZwOpenProcess(
								PHANDLE ProcessHandle,
								ACCESS_MASK DesiredAccess,
								POBJECT_ATTRIBUTES ObjectAttributes,
								PCLIENT_ID ClientId
								)
{
	NTSTATUS status = OldZwOpenProcess(
		ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
	
	return status;
}
ich kann Access denied ausgeben und der blockt alle OpenProcess aber wieso kann der dann so nicht den HackShield hook bypassen ? lol