问题:以下是apc插入代码,也就是在内核执行ring3级程序。用DDK编译后能够执行成功,即可以启动ring3级程序。但是在DriverStudio环境下,将此段代码作为一个功能模块时,编译无误。但在执行时,ring3级程序并没有成功启动,不知道什么原因?(驱动入口函数略)操作系统:XP。
代码如下:
#include "ntddk.h"
#include "ntifs.h"
typedef enum
{
OriginalApcEnvironment,
AttachedApcEnvironment,
CurrentApcEnvironment
} KAPC_ENVIRONMENT;
void RunUserModeProcess(char* command_line);
NTSTATUS InstallUserModeApc(char* CommandLine, PKTHREAD pTargetThread, PEPROCESS pTargetProcess);
void ApcCreateProcess(PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2);
void ApcKernelRoutine( IN struct _KAPC *Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine,
IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2 );
void ApcCreateProcessEnd();
void RunUserModeProcess(char* command_line)
{
//内核中枚举explorer.exe进程,然后调用InstallUserModeApc函数。
}
PMDL pMdl = NULL;
void ApcKernelRoutine( IN struct _KAPC *Apc,
IN OUT PKNORMAL_ROUTINE *NormalRoutine,
IN OUT PVOID *NormalContext,
IN OUT PVOID *SystemArgument1,
IN OUT PVOID *SystemArgument2 )
{
//PKEVENT pEvent;
if (Apc)
ExFreePool(Apc);
//pEvent = (PKEVENT)*SystemArgument1;
//KeSetEvent (pEvent,IO_NO_INCREMENT,FALSE);
}
NTSTATUS InstallUserModeApc(char* CommandLine, PKTHREAD pTargetThread, PEPROCESS pTargetProcess)
{
PRKAPC pApc = NULL; //Our APC
//PKEVENT pEvent = NULL;
PVOID pMappedAddress = NULL; //This is where the UserMode routine's code will be placed at
ULONG dwSize = 0; //Size of code to be executed in Explorer's address space
KAPC_STATE ApcState; // Needed for KeStackAttachProcess
ULONG *data_addr=0; //just a helper to change the address of the 'push' instruction
//in the ApcCreateProcess routine
ULONG dwMappedAddress = 0; //same as above
NTSTATUS Status = STATUS_UNSUCCESSFUL;
if (!pTargetThread || !pTargetProcess)
return STATUS_UNSUCCESSFUL;
DbgPrint("Daytime: command_line = %s \n",CommandLine);
//Allocate memory for our APC
pApc = (PRKAPC) ExAllocatePool (NonPagedPool,sizeof (KAPC));
if (!pApc)
{
DbgPrint("Daytime: Failed to allocate memory for the APC structure \n");
return STATUS_INSUFFICIENT_RESOURCES;
}
//pEvent = (PKEVENT) ExAllocatePool (NonPagedPool,sizeof (KEVENT));
//if (!pEvent)
//{
// ExFreePool (pApc);
// return STATUS_INSUFFICIENT_RESOURCES;
//}
//Get the size of our UserMode code
dwSize = (unsigned char*)ApcCreateProcessEnd-(unsigned char*)ApcCreateProcess;
//Allocate an MDL describing our ApcCreateProcess' memory
pMdl = IoAllocateMdl (ApcCreateProcess, dwSize, FALSE,FALSE,NULL);
if (!pMdl)
{
DbgPrint("Daytime: Failed to allocate MDL \n");
ExFreePool (pApc);
return STATUS_INSUFFICIENT_RESOURCES;
}
__try
{
//Probe the pages for Write access and make them memory resident
MmProbeAndLockPages (pMdl,KernelMode,IoWriteAccess);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("Daytime: Exception during MmProbeAndLockPages \n");
IoFreeMdl (pMdl);
ExFreePool (pApc);
//ExFreePool (pEvent);
return STATUS_UNSUCCESSFUL;
}
//Attach to the Explorer's address space
KeStackAttachProcess(&(pTargetProcess->Pcb),&ApcState);
//Now map the physical pages (our code) described by 'pMdl'
pMappedAddress = MmMapLockedPagesSpecifyCache (pMdl,UserMode,MmCached,NULL,FALSE,NormalPagePriority);
if (!pMappedAddress)
{
DbgPrint("Daytime: Cannot map address \n");
KeUnstackDetachProcess (&ApcState);
IoFreeMdl (pMdl);
ExFreePool (pApc);
//ExFreePool (pEvent);
return STATUS_UNSUCCESSFUL;
}
else
DbgPrint("Daytime: UserMode memory at address: 0x%p \n",pMappedAddress);
dwMappedAddress = (ULONG)pMappedAddress;
// copy commandline
memset ((unsigned char*)pMappedAddress + 163, 0, 260);
memcpy ((unsigned char*)pMappedAddress + 163, CommandLine,strlen (CommandLine));
//all done, detach now
KeUnstackDetachProcess (&ApcState);
//Initialize the APC...
//KeInitializeEvent(pEvent,NotificationEvent,FALSE);
KeInitializeApc(pApc,pTargetThread,
OriginalApcEnvironment,
&ApcKernelRoutine,NULL,
(PKNORMAL_ROUTINE) pMappedAddress, UserMode, (PVOID) NULL);
//...and queue it
if (!KeInsertQueueApc(pApc,NULL,NULL,0))
{
DbgPrint("Daytime: Failed to insert APC \n");
MmUnlockPages(pMdl);
IoFreeMdl (pMdl);
ExFreePool (pApc);
// ExFreePool(pEvent);
return STATUS_UNSUCCESSFUL;
}
else
{
DbgPrint("Daytime: APC delivered \n");
}
//is this a non-alertable thread?
if(!pTargetThread->ApcState.UserApcPending)
{
//if yes then alert it
pTargetThread->ApcState.UserApcPending = TRUE;
}
// apc is fired, wait event to signal completion
//KeWaitForSingleObject (pEvent,Executive,KernelMode,FALSE,NULL);
//DbgPrint("Daytime: Get the Event \n");
// free event
//ExFreePool (pEvent);
if(pMdl)
{
MmUnlockPages(pMdl);
IoFreeMdl (pMdl);
pMdl = NULL;
}
DbgPrint("Daytime: ApcKernelRoutine called. Memory freed. \n");
return 0;
}
__declspec(naked) void ApcCreateProcess(PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2)
{
__asm{
; //代码略
}
}
void ApcCreateProcessEnd(){}