A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about kernel-mode development.
 #26993  by myid
 Sat Oct 17, 2015 5:03 pm
Hi, everyone. I use ZwQueueApcThread to inject dll, it works well for NATIVE process (both WIN32 and WIN64 system).
But it cannot inject dll to WOW64 process (makes process crashed, not BSOD).
Code: Select all
void NtApcInjectDll(HANDLE pid, HANDLE tid, CHAR *szDllPath)
{
	HANDLE hProcess,hThread;
	SIZE_T size = MAX_PATH;
	PVOID BaseAddress=0;
	NTSTATUS st=0;
	hProcess = OpenProcess(pid);
	if(!hProcess)
	{
		DbgPrint("cannot open process.\n");
		return;
	}
	hThread = OpenThread(tid);
	if(!hThread)
	{
		DbgPrint("cannot open thread.\n");
		return;
	}
	st = ZwAllocateVirtualMemory(hProcess,
								&BaseAddress,
								0,
								&size,
								MEM_COMMIT,
								PAGE_READWRITE);
	if(NT_SUCCESS(st))
	{
		PEPROCESS ep = LookupProcess(pid);
		PETHREAD et = LookupThread(tid);
		ObDereferenceObject(ep);ObDereferenceObject(et);
		KeAttachProcess(ep);
		RtlCopyMemory(BaseAddress,szDllPath,strlen(szDllPath));
		KeDetachProcess();
		st=ZwQueueApcThread(hThread,
							g_pfnRtlDispatchApc,   //I try to get address of 32 and 64 bit DLL, but both failed (makes process crashed, not BSOD)
							g_pfnLoadLibraryA,  //I try to get address of 32 and 64 bit DLL, but both failed (makes process crashed, not BSOD)
							BaseAddress,
							NULL);
		if(NT_SUCCESS(st))
			DbgPrint("Inject dll OK!\n");
		else
			DbgPrint("Inject dll failed!\n");
		*(PUCHAR)((SIZE_T)et+OFFSET_KTHREAD_ApcState_UserApcPending) = 1; //mark thread alertable.
	}
	else
	{
		DbgPrint("cannot Allocate Virtual Memory.\n");
	}
}
Who can tell me the reason.
 #26994  by Brock
 Sat Oct 17, 2015 7:12 pm
You should be using KeStackAttachProcess/KeUnstackDetachProcess and why are you dereferencing an object then using it in the call immediately after? To answer your question, for WOW64 processes you should be using PsWrapApcWow64Thread and KeInitializeApc with KeInsertQueueApc. Forcing APC delivery by modifying the ETHREAD structure of the target thread is ill advised and obviously these offsets change when manipulating the alertable state. Try this with single threaded programs like calc.exe and watch it crash the process. Call that code multiple times and see what happens
 #27000  by myid
 Sun Oct 18, 2015 6:51 am
Brock wrote:You should be using KeStackAttachProcess/KeUnstackDetachProcess and why are you dereferencing an object then using it in the call immediately after? To answer your question, for WOW64 processes you should be using PsWrapApcWow64Thread and KeInitializeApc with KeInsertQueueApc. Forcing APC delivery by modifying the ETHREAD structure of the target thread is ill advised and obviously these offsets change when manipulating the alertable state. Try this with single threaded programs like calc.exe and watch it crash the process. Call that code multiple times and see what happens
Thanks for your tips. My problem have been resolved. :D