首页
社区
课程
招聘
[原创]今天写了个apc注入dll代码,可以当工具使用
发表于: 2015-7-3 23:14 9808

[原创]今天写了个apc注入dll代码,可以当工具使用

2015-7-3 23:14
9808

ring0和ring3都有,像我这样菜鸟写这么个代码真累啊
typedef struct _INJECT_INFO
{
        HANDLE ProcessId;
        wchar_t DllName[1024];
}INJECT_INFO,*PINJECT_INFO;

BOOLEAN InjectDll(PINJECT_INFO InjectInfo)
{
        PEPROCESS Process;
        PETHREAD Thread;

        PKINJECT mem;
        ULONG size;

        PKAPC_STATE ApcState;
        PKAPC apc;

        PVOID buffer;
        PSYSTEM_PROCESS_INFO pSpi;

        LARGE_INTEGER delay;

        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 thread list

        if(!NT_SUCCESS(ZwQuerySystemInformation(5,buffer,1024*1024,NULL)))
        {
                DbgPrint("Error: Unable to query process thread list.");
               
                ExFreePool(buffer);
                return FALSE;
        }

        pSpi=(PSYSTEM_PROCESS_INFO)buffer;

        // Find a target thread

        while(pSpi->NextEntryOffset)
        {
                if(pSpi->UniqueProcessId==InjectInfo->ProcessId)
                {
                        DbgPrint("Target thread found. TID: %d",pSpi->Threads[0].ClientId.UniqueThread);
                        break;
                }

                pSpi=(PSYSTEM_PROCESS_INFO)((PUCHAR)pSpi+pSpi->NextEntryOffset);
        }

        // Reference the target process

        if(!NT_SUCCESS(PsLookupProcessByProcessId(InjectInfo->ProcessId,&Process)))
        {
                DbgPrint("Error: Unable to reference the target process.");
               
                ExFreePool(buffer);
                return FALSE;
        }

        DbgPrint("Process name: %s",PsGetProcessImageFileName(Process));
        DbgPrint("EPROCESS address: %#x",Process);

        // Reference the target thread

        if(!NT_SUCCESS(PsLookupThreadByThreadId(pSpi->Threads[0].ClientId.UniqueThread,&Thread)))
        {
                DbgPrint("Error: Unable to reference the target thread.");
                ObDereferenceObject(Process); // Dereference the target process

                ExFreePool(buffer); // Free the allocated memory
                return FALSE;
        }

        DbgPrint("ETHREAD address: %#x",Thread);

        ExFreePool(buffer); // Free the allocated memory
        KeAttachProcess(Process); // Attach to target process's address space

        mem=NULL;
        size=4096;

        // Allocate memory in the target process

        if(!NT_SUCCESS(ZwAllocateVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,0,&size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE)))
        {
            DbgPrint("Error: Unable to allocate memory in the target process.");
                KeDetachProcess(); // Detach from target process's address space

                ObDereferenceObject(Process); // Dereference the target process
                ObDereferenceObject(Thread); // Dereference the target thread

                return FALSE;
        }

        DbgPrint("Memory allocated at %#x",mem);

        mem->LdrLoadDll=LdrLoadDll; // Write the address of LdrLoadDll to target process
        wcscpy(mem->Buffer,InjectInfo->DllName); // Write the DLL name to target process

        RtlInitUnicodeString(&mem->DllName,mem->Buffer); // Initialize the UNICODE_STRING structure
        ApcState=(PKAPC_STATE)((PUCHAR)Thread+ApcStateOffset); // Calculate the address of the ApcState structure

        ApcState->UserApcPending=TRUE; // Force the target thread to execute APC

        memcpy((PKINJECT)(mem+1),InjectDllApc,(ULONG)KernelRoutine-(ULONG)InjectDllApc); // Copy the APC code to target process
        DbgPrint("APC code address: %#x",(PKINJECT)(mem+1));

        apc=(PKAPC)ExAllocatePool(NonPagedPool,sizeof(KAPC)); // Allocate the APC object

        if(!apc)
        {
                DbgPrint("Error: Unable to allocate the APC object.");
                size=0;

                ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE);  // Free the allocated memory
                KeDetachProcess(); // Detach from target process's address space

                ObDereferenceObject(Process); // Dereference the target process
                ObDereferenceObject(Thread); // Dereference the target thread

                return FALSE;
        }

        KeInitializeApc(apc,Thread,OriginalApcEnvironment,KernelRoutine,NULL,(PKNORMAL_ROUTINE)((PKINJECT)mem+1),UserMode,mem); // Initialize the APC
        DbgPrint("Inserting APC to target thread");

        // Insert the APC to the target thread

        if(!KeInsertQueueApc(apc,NULL,NULL,IO_NO_INCREMENT))
        {
                DbgPrint("Error: Unable to insert APC to target thread.");
                size=0;
               
                ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); // Free the allocated memory
                KeDetachProcess(); // Detach from target process's address space

                ObDereferenceObject(Process); // Dereference the target process
                ObDereferenceObject(Thread); // Dereference the target thread

                ExFreePool(apc); // Free the APC object
                return FALSE;
        }

        delay.QuadPart=-100*10000;

        while(!mem->Executed)
        {
                KeDelayExecutionThread(KernelMode,FALSE,&delay); // Wait for the injection to complete
        }

        if(!mem->DllBase)
        {
                DbgPrint("Error: Unable to inject DLL into target process.");
                size=0;

                ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE);
                KeDetachProcess();

                ObDereferenceObject(Process);
                ObDereferenceObject(Thread);
               
                return FALSE;
        }

        DbgPrint("DLL injected at %#x",mem->DllBase);
        size=0;

        ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); // Free the allocated memory
        KeDetachProcess(); // Detach from target process's address space

        ObDereferenceObject(Process); // Dereference the target process
        ObDereferenceObject(Thread);  // Dereference the target thread

        return TRUE;
}


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 3
支持
分享
最新回复 (6)
雪    币: 16436
活跃值: (1695)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
能编 出来能用 就是进步。
2015-7-4 07:30
0
雪    币: 40
活跃值: (702)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
= =怎么和我以前在论坛看的那份相似度90%
2015-7-4 22:43
0
雪    币: 221
活跃值: (2326)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
不错,学习了,能不能增加目标EXE一启动就插入DLL ?
2015-7-8 09:21
0
雪    币: 74
活跃值: (748)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
支持分享,学习下
2015-7-8 09:35
0
雪    币: 12
活跃值: (773)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
x64能用不?
2015-12-21 13:50
0
雪    币: 190
活跃值: (84)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
兹磁win7吗
2015-12-24 14:47
0
游客
登录 | 注册 方可回帖
返回
//