A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about kernel-mode development.
 #22541  by xcteam
 Mon Mar 24, 2014 8:42 pm
hi,

i am trying to perform mouse_event based on conditions met by driver after opening handle to a process. not sure where im going wrong;
Code: Select all
#include<ntifs.h>
#include<Ntstrsafe.h > 
#define  UNREFERENCED_PARAMETER(P) (P)
PDEVICE_OBJECT g_GlobalPointerDevice;

#define DEVICE_FUSION 0x00001234
#define UNREFERENCED_PARAMETER(P) (P)
#define  BUFFER_SIZE 30
//--------------------------------------------

typedef struct _SYSTEM_THREAD_INFORMATION
{
	LARGE_INTEGER KernelTime;
	LARGE_INTEGER UserTime;
	LARGE_INTEGER CreateTime;
	ULONG WaitTime;
	PVOID StartAddress;
	CLIENT_ID ClientId;
	KPRIORITY Priority;
	LONG BasePriority;
	ULONG ContextSwitches;
	ULONG ThreadState;
	KWAIT_REASON WaitReason;
}SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;

typedef struct _SYSTEM_PROCESS_INFO
{
	ULONG NextEntryOffset;
	ULONG NumberOfThreads;
	LARGE_INTEGER WorkingSetPrivateSize;
	ULONG HardFaultCount;
	ULONG NumberOfThreadsHighWatermark;
	ULONGLONG CycleTime;
	LARGE_INTEGER CreateTime;
	LARGE_INTEGER UserTime;
	LARGE_INTEGER KernelTime;
	UNICODE_STRING ImageName;
	KPRIORITY BasePriority;
	HANDLE UniqueProcessId;
	HANDLE InheritedFromUniqueProcessId;
	ULONG HandleCount;
	ULONG SessionId;
	ULONG_PTR UniqueProcessKey;
	SIZE_T PeakVirtualSize;
	SIZE_T VirtualSize;
	ULONG PageFaultCount;
	SIZE_T PeakWorkingSetSize;
	SIZE_T WorkingSetSize;
	SIZE_T QuotaPeakPagedPoolUsage;
	SIZE_T QuotaPagedPoolUsage;
	SIZE_T QuotaPeakNonPagedPoolUsage;
	SIZE_T QuotaNonPagedPoolUsage;
	SIZE_T PagefileUsage;
	SIZE_T PeakPagefileUsage;
	SIZE_T PrivatePageCount;
	LARGE_INTEGER ReadOperationCount;
	LARGE_INTEGER WriteOperationCount;
	LARGE_INTEGER OtherOperationCount;
	LARGE_INTEGER ReadTransferCount;
	LARGE_INTEGER WriteTransferCount;
	LARGE_INTEGER OtherTransferCount;
	SYSTEM_THREAD_INFORMATION Threads[1];
}SYSTEM_PROCESS_INFO, *PSYSTEM_PROCESS_INFO;

typedef struct _LDR_DATA_TABLE_ENTRY
{
	LIST_ENTRY InLoadOrderLinks;
	LIST_ENTRY InMemoryOrderLinks;
	LIST_ENTRY InInitializationOrderLinks;
	PVOID DllBase;
	PVOID EntryPoint;
	ULONG SizeOfImage;
	UNICODE_STRING FullDllName;
	UNICODE_STRING BaseDllName;
	ULONG Flags;
	USHORT LoadCount;
	USHORT TlsIndex;

	union
	{
		LIST_ENTRY HashLinks;

		struct
		{
			PVOID SectionPointer;
			ULONG CheckSum;
		};
	};

	union
	{
		ULONG TimeDateStamp;
		PVOID LoadedImports;
	};

	struct _ACTIVATION_CONTEXT * EntryPointActivationContext;
	PVOID PatchInformation;
	LIST_ENTRY ForwarderLinks;
	LIST_ENTRY ServiceTagLinks;
	LIST_ENTRY StaticLinks;
}LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

typedef struct _IMAGE_DOS_HEADER
{
	USHORT e_magic;
	USHORT e_cblp;
	USHORT e_cp;
	USHORT e_crlc;
	USHORT e_cparhdr;
	USHORT e_minalloc;
	USHORT e_maxalloc;
	USHORT e_ss;
	USHORT e_sp;
	USHORT e_csum;
	USHORT e_ip;
	USHORT e_cs;
	USHORT e_lfarlc;
	USHORT e_ovno;
	USHORT e_res[4];
	USHORT e_oemid;
	USHORT e_oeminfo;
	USHORT e_res2[10];
	LONG e_lfanew;
}IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

typedef struct _IMAGE_DATA_DIRECTORY
{
	ULONG VirtualAddress;
	ULONG Size;
}IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

typedef struct _IMAGE_FILE_HEADER
{
	USHORT Machine;
	USHORT NumberOfSections;
	ULONG TimeDateStamp;
	ULONG PointerToSymbolTable;
	ULONG NumberOfSymbols;
	USHORT SizeOfOptionalHeader;
	USHORT Characteristics;
}IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

typedef struct _IMAGE_OPTIONAL_HEADER
{
	USHORT Magic;
	UCHAR MajorLinkerVersion;
	UCHAR MinorLinkerVersion;
	ULONG SizeOfCode;
	ULONG SizeOfInitializedData;
	ULONG SizeOfUninitializedData;
	ULONG AddressOfEntryPoint;
	ULONG BaseOfCode;
	ULONG BaseOfData;
	ULONG ImageBase;
	ULONG SectionAlignment;
	ULONG FileAlignment;
	USHORT MajorOperatingSystemVersion;
	USHORT MinorOperatingSystemVersion;
	USHORT MajorImageVersion;
	USHORT MinorImageVersion;
	USHORT MajorSubsystemVersion;
	USHORT MinorSubsystemVersion;
	ULONG Win32VersionValue;
	ULONG SizeOfImage;
	ULONG SizeOfHeaders;
	ULONG CheckSum;
	USHORT Subsystem;
	USHORT DllCharacteristics;
	ULONG SizeOfStackReserve;
	ULONG SizeOfStackCommit;
	ULONG SizeOfHeapReserve;
	ULONG SizeOfHeapCommit;
	ULONG LoaderFlags;
	ULONG NumberOfRvaAndSizes;
	IMAGE_DATA_DIRECTORY DataDirectory[16];
}IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;

typedef struct _IMAGE_NT_HEADERS
{
	ULONG Signature;
	IMAGE_FILE_HEADER FileHeader;
	IMAGE_OPTIONAL_HEADER OptionalHeader;
}IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;

typedef struct _IMAGE_EXPORT_DIRECTORY
{
	ULONG   Characteristics;
	ULONG   TimeDateStamp;
	USHORT  MajorVersion;
	USHORT  MinorVersion;
	ULONG   Name;
	ULONG   Base;
	ULONG   NumberOfFunctions;
	ULONG   NumberOfNames;
	ULONG   AddressOfFunctions;
	ULONG   AddressOfNames;
	ULONG   AddressOfNameOrdinals;
}IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

#define IMAGE_DIRECTORY_ENTRY_EXPORT 0

extern  NTSTATUS ZwQuerySystemInformation(ULONG InfoClass, PVOID Buffer, ULONG Length, PULONG ReturnLength);
extern  LPSTR PsGetProcessImageFileName(PEPROCESS Process);

typedef NTSTATUS(*PLDR_LOAD_DLL)(PWSTR, PULONG, PUNICODE_STRING, PVOID*);

typedef struct _INJECT_INFO
{
	HANDLE ProcessId;
	wchar_t DllName[1024];
}INJECT_INFO, *PINJECT_INFO;

typedef struct _KINJECT
{
	UNICODE_STRING DllName;
	wchar_t Buffer[1024];
	PLDR_LOAD_DLL LdrLoadDll;
	PVOID DllBase;
	ULONG Executed;
}KINJECT, *PKINJECT;

typedef enum _KAPC_ENVIRONMENT
{
	OriginalApcEnvironment,
	AttachedApcEnvironment,
	CurrentApcEnvironment,
	InsertApcEnvironment
}KAPC_ENVIRONMENT, *PKAPC_ENVIRONMENT;

typedef VOID(NTAPI *PKNORMAL_ROUTINE)(
	PVOID NormalContext,
	PVOID SystemArgument1,
	PVOID SystemArgument2
	);

typedef VOID KKERNEL_ROUTINE(
	PRKAPC Apc,
	PKNORMAL_ROUTINE *NormalRoutine,
	PVOID *NormalContext,
	PVOID *SystemArgument1,
	PVOID *SystemArgument2
	);

typedef KKERNEL_ROUTINE(NTAPI *PKKERNEL_ROUTINE);

typedef VOID(NTAPI *PKRUNDOWN_ROUTINE)(
	PRKAPC Apc
	);

extern void KeInitializeApc(
	PRKAPC Apc,
	PRKTHREAD Thread,
	KAPC_ENVIRONMENT Environment,
	PKKERNEL_ROUTINE KernelRoutine,
	PKRUNDOWN_ROUTINE RundownRoutine,
	PKNORMAL_ROUTINE NormalRoutine,
	KPROCESSOR_MODE ProcessorMode,
	PVOID NormalContext
	);

extern BOOLEAN KeInsertQueueApc(
	PRKAPC Apc,
	PVOID SystemArgument1,
	PVOID SystemArgument2,
	KPRIORITY Increment
	);

ULONG dwSysenterOriginalAddress = 0;
DWORD32 UserProcessId = (DWORD32)-1;

PLDR_LOAD_DLL LdrLoadDll;

NTSTATUS IOOpen(IN PDEVICE_OBJECT theDriverObject, IN PIRP Irp)
{
	UNREFERENCED_PARAMETER(theDriverObject);
	IofCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}
NTSTATUS IOClose(IN PDEVICE_OBJECT theDriverObject, IN PIRP Irp)
{
	UNREFERENCED_PARAMETER(theDriverObject);
	IofCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}
NTSTATUS CheatGame(VOID)
{
	DbgPrint("Now we are in hook mode!");
	PEPROCESS hProcess = 0;
	OBJECT_ATTRIBUTES ObjectAttributes;

	ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
	ObjectAttributes.RootDirectory = NULL;
	ObjectAttributes.ObjectName = NULL;
	ObjectAttributes.Attributes = OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE;
	ObjectAttributes.SecurityDescriptor = NULL;
	ObjectAttributes.SecurityQualityOfService = NULL;

	PsLookupProcessByProcessId((HANDLE)UserProcessId, &hProcess);
	DbgPrint("Trying to Attach!");
	KeAttachProcess(hProcess);
	DbgPrint("ATTACHED!");

	UNICODE_STRING dbgMessage, uniNameNtDLL;
	RtlInitUnicodeString(&uniNameNtDLL, L"client.dll");

	HANDLE hAddress;
	LdrLoadDll(NULL, 0, &uniNameNtDLL, &hAddress);
	

	//Some stuff

	DbgPrint("Deattaching");
	KeDetachProcess();
	DbgPrint("Deattached!");
	ObDereferenceObject(hProcess);

	return STATUS_SUCCESS;
}
NTSTATUS IOFusionControl(IN PDEVICE_OBJECT theDriverObject, IN PIRP Irp)
{
	UNREFERENCED_PARAMETER(theDriverObject);
	switch (Irp->Tail.Overlay.CurrentStackLocation->Parameters.DeviceIoControl.IoControlCode)
	{
	default:
		UserProcessId = Irp->Tail.Overlay.CurrentStackLocation->Parameters.DeviceIoControl.IoControlCode;
		CheatGame();
		break;
	}

	return STATUS_SUCCESS;
}

char * GetProcessNameFromPid(HANDLE pid)
{
	DbgPrint("We are checking for Pid");
	PEPROCESS Process;
	if (PsLookupProcessByProcessId(pid, &Process) == STATUS_INVALID_PARAMETER)
	{
		return "pid???";
	}
	else
	{
		DbgPrint("Did we Find the process?");
		if ((CHAR*)PsGetProcessImageFileName(Process) == "calc.exe")
		{
			DbgPrint("Found it");
			UserProcessId = pid;
			ApplyWork();
		}
	}
	return (CHAR*)PsGetProcessImageFileName(Process);
}


VOID StartCheating(VOID)
{
	PEPROCESS Process;
	PETHREAD Thread;

	PKINJECT mem;
	ULONG size;

	PKAPC_STATE ApcState;
	PKAPC apc;

	PVOID buffer;
	PSYSTEM_PROCESS_INFO pSpi;

	LARGE_INTEGER delay;

	DbgPrint("Now we are going to find process.");
	buffer = ExAllocatePool(NonPagedPool, 1024 * 1024); // Allocate memory for the system information

	if (!buffer)
	{
		DbgPrint("Error: Unable to allocate memory for the process thread list.");
		return FALSE;
	}

	// Get the process list
	DbgPrint("Get Process List");
	if (!NT_SUCCESS(ZwQuerySystemInformation(5, buffer, 1024 * 1024, NULL)))
	{
		DbgPrint("Error: Unable to query process thread list.");

		ExFreePool(buffer);
		return FALSE;
	}
	DbgPrint("Now We will cyle through all processes");
	pSpi = (PSYSTEM_PROCESS_INFO)buffer;

	while (pSpi->NextEntryOffset)
	{
		GetProcessNameFromPid(pSpi->UniqueProcessId);
	}
}
VOID DriverUnload(IN PDRIVER_OBJECT theDriverObject)
{
	UNREFERENCED_PARAMETER(theDriverObject);
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath)
{
	UNREFERENCED_PARAMETER(theRegistryPath);

	DbgPrint("Hello World!");

	PDEVICE_OBJECT DeviceObject;
	PEPROCESS Process;
	PETHREAD Thread;
	PKAPC_STATE ApcState;

	PVOID KdVersionBlock, NtdllBase;
	PULONG ptr, Functions, Names;
	PUSHORT Ordinals;

	PLDR_DATA_TABLE_ENTRY MmLoadedUserImageList, ModuleEntry;
	ULONG i;

	PIMAGE_DOS_HEADER pIDH;
	PIMAGE_NT_HEADERS pINH;
	PIMAGE_EXPORT_DIRECTORY pIED;
	KdVersionBlock = (PVOID)__readfsdword(0x34); // Get the KdVersionBlock
	MmLoadedUserImageList = *(PLDR_DATA_TABLE_ENTRY*)((PUCHAR)KdVersionBlock + 0x228); // Get the MmLoadUserImageList
	ModuleEntry = (PLDR_DATA_TABLE_ENTRY)MmLoadedUserImageList->InLoadOrderLinks.Flink; // Move to first entry
	NtdllBase = ModuleEntry->DllBase; // ntdll is always located in first entry
	pIDH = (PIMAGE_DOS_HEADER)NtdllBase;
	pINH = (PIMAGE_NT_HEADERS)((PUCHAR)NtdllBase + pIDH->e_lfanew);
	pIED = (PIMAGE_EXPORT_DIRECTORY)((PUCHAR)NtdllBase + pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
	DbgPrint("We are still going...Line 448");
	Functions = (PULONG)((PUCHAR)NtdllBase + pIED->AddressOfFunctions);
	Names = (PULONG)((PUCHAR)NtdllBase + pIED->AddressOfNames);

	Ordinals = (PUSHORT)((PUCHAR)NtdllBase + pIED->AddressOfNameOrdinals);

	// Parse the export table to locate LdrLoadDll
	DbgPrint("Parse the export table to locate LdrLoadDll");
	for (i = 0; i < pIED->NumberOfNames; i++)
	{
		if (!strcmp((char*)NtdllBase + Names[i], "LdrLoadDll"))
		{
			LdrLoadDll = (PLDR_LOAD_DLL)((PUCHAR)NtdllBase + Functions[Ordinals[i]]);
			break;
		}
	}

	DbgPrint("Get Ready to apply");
//mouse_event
//if(GetAsyncKeyState(5) && ID && ID <= 32)
//		{	
//			//Press the left mouse button, wait 2 milliseconds, release left mouse button, wait two milliseconds
//				mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);  Sleep(2);  mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);   Sleep(2);

	theDriverObject->DriverUnload = DriverUnload;
	theDriverObject->MajorFunction[IRP_MJ_CREATE] = &IOOpen;
	theDriverObject->MajorFunction[IRP_MJ_CLOSE] = &IOClose;
	theDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = &IOFusionControl;
	return STATUS_SUCCESS;
}
as you can see if all conditions of the driver are met i want to simulate mouse_event, this would be in a constant loop.

thanks.