请大侠帮忙解决一下apc插入的问题

chenmengzhong   2009-3-12 08:31 楼主
问题:以下是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(){}

回复评论 (3)

帮顶
点赞  2009-3-12 09:26
帮顶
点赞  2009-3-12 09:26
顶,新手
点赞  2009-3-17 09:42
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复