首页
社区
课程
招聘
[求助]win7下面注入APC线程的问题
发表于: 2014-1-26 02:02 10981

[求助]win7下面注入APC线程的问题

2014-1-26 02:02
10981
我注入explorer.exe会崩溃
其他services.exe也是
只有注入第三方程序才正常运行
上代码
/*
*    使用APC在Winlogon进程的线程队列里面,运行指定程序
*/
NTSTATUS RunProcess(LPSTR lpProcess)
{
    PRKAPC pApc = NULL;                //Our APC
    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
    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
    PKTHREAD pTargetThread = NULL;
    PKAPC_STATE pApcState = NULL;
    PLIST_ENTRY pTempList = NULL;
    PLIST_ENTRY pCurrentList = NULL;
    //PUCHAR lpThreadAlertable = NULL;
	PULONG lpThreadAlertable = NULL;
    PUCHAR lpTargetPath = NULL;
	ULONG u ,un;
        
    if (!g_EProcessWinlogon || !g_WinExec)
        return STATUS_UNSUCCESSFUL;
    
    //枚举线程
    pCurrentList = (PLIST_ENTRY)((PUCHAR)(ULONG)g_EProcessWinlogon + 0x188/*BASE_KPROCESS_THREAD_OFFSET*/);
    pTempList = pCurrentList;

    do {
        //lpThreadAlertable = /*(PUCHAR)*/(PULONG)pTempList - g_KThreadOffset.wOffsetThreadListEntry + g_KThreadOffset.wOffsetAlertable;
		lpThreadAlertable = /*(PUCHAR)*/(PULONG)((ULONG)pTempList - 0x268 + 0x3c);

		u = (ULONG)*lpThreadAlertable;
		un = (ULONG)((u &0x0000003f)&0x20);//(a &0x0000003f)&0x20

		//如果此线程的Alertable为 1 就拿它来开刀
        if (un == 0x20)
        {

            pTargetThread = (PKTHREAD)(((ULONG)lpThreadAlertable - 0x3c/*g_KThreadOffset.wOffsetAlertable*/));
            KdPrint(("Alert Thread: %08x\n", pTargetThread));
            break;
        }
        pTempList = pTempList->Flink;
    } while(pTempList != pCurrentList);

	//////////////////////////////////////////////////////////////////////////
	//pTargetThread = ForceTerminateProcess(g_EProcessWinlogon);

    if (!pTargetThread)
        return STATUS_UNSUCCESSFUL;
    
    KdPrint(("g_EProcessWinlogon:%08x\n", g_EProcessWinlogon));
    
    //Allocate memory for our APC
    pApc = ExAllocatePool(NonPagedPool, sizeof (KAPC)); 
    if (!pApc)
    {
        DbgPrint("KernelExec -> Failed to allocate memory for the APC structure");
        return STATUS_INSUFFICIENT_RESOURCES;
    }


    //Get the size of our UserMode code
    dwSize = (PUCHAR)ApcCreateProcessEnd - (PUCHAR)ApcCreateProcess;
    //Allocate an MDL describing our ApcCreateProcess' memory
    pMdl = IoAllocateMdl(ApcCreateProcess, dwSize, FALSE, FALSE, NULL);
    if (!pMdl)
    {
        DbgPrint("KernelExec -> Failed to allocate MDL");
        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("KernelExec -> Exception during MmProbeAndLockPages");
        IoFreeMdl (pMdl);
        ExFreePool (pApc);
        return STATUS_UNSUCCESSFUL;
    }
    
    //Attach to the winlogon's address space
    KeAttachProcess((PKPROCESS)g_EProcessWinlogon);
    //Now map the physical pages (our code) described by 'pMdl'
    pMappedAddress = MmMapLockedPagesSpecifyCache (pMdl, UserMode, MmCached, NULL, FALSE, NormalPagePriority);
    
    if (!pMappedAddress)
    {
        DbgPrint("KernelExec -> Cannot map address");

        //KeUnstackDetachProcess (&ApcState);
        KeDetachProcess();
        IoFreeMdl (pMdl);
        ExFreePool (pApc);

        return STATUS_UNSUCCESSFUL;
    }
    else 
        DbgPrint("KernelExec -> UserMode memory at address: 0x%p",pMappedAddress);

    dwMappedAddress = (ULONG)pMappedAddress;
    lpTargetPath = (PUCHAR)(dwMappedAddress + 0x12);            //执行路径的首地址
    
    _asm 
    {
        //CLI;                    //dissable interrupt 
        PUSH EAX;
        MOV EAX, CR0;            //move CR0 register into EAX 
        AND EAX, NOT 10000H;    //disable WP bit 
        MOV CR0, EAX;            //write register back 
        POP EAX;
    }
    memcpy((PUCHAR)pMappedAddress + 1, &g_WinExec, 4);            //填写winexec地址
    memset(lpTargetPath, 0, 40);                                //
    memcpy(lpTargetPath, lpProcess, strlen(lpProcess));            //拷贝执行路径(注意长度限制40)
    *(PULONG)((PUCHAR)pMappedAddress + 0x8) = (ULONG)lpTargetPath;
    _asm
    {
        PUSH EAX;
        MOV EAX, CR0;
        OR  EAX, 10000H;
        MOV CR0, EAX;
        POP EAX;
        //STI;
    }
    //all done, detach now
    KeDetachProcess();
    //Initialize the APC...
    KeInitializeApc(pApc,
        pTargetThread,
        OriginalApcEnvironment,
        &ApcKernelRoutine, NULL,
        pMappedAddress, UserMode, (PVOID) NULL);
    
    //set ApcQueueable
    pApcState = (PKAPC_STATE)((PUCHAR)pTargetThread + /*g_KThreadOffset.wOffsetApcState*/0x40); //just for 2003 sp1
    pApcState->_PADDING0_[0] = TRUE;
	pApcState->UserApcPending = TRUE;
	//*(ULONG*)((ULONG)pTargetThread+0x3c) = 1;
    //...and queue it
    if (!KeInsertQueueApc(pApc, NULL, NULL, IO_NO_INCREMENT))
    {
        DbgPrint("KernelExec -> Failed to insert APC");
        MmUnlockPages(pMdl);
        IoFreeMdl (pMdl);
        ExFreePool (pApc);
        return STATUS_UNSUCCESSFUL;
    }
	
    else
    {
        DbgPrint("KernelExec -> APC delivered");
    }
	//is this a non-alertable thread?
// 	if(!pApcState->UserApcPending)
// 	{
// 		//if yes then alert it
// 		pApcState->UserApcPending = TRUE;
// 	}
	return STATUS_SUCCESS;
}

//===================================================================//
//Name: VOID ApcKernelRoutine()                                      //
//                                                                  //
//Descripion: This routine gets called after the APC routine returns //
//            (our process should have been executed by then)        //
//            It frees all the memory allocated by InstallUserModeApc//
//            (APC and MDL)                                          //
//===================================================================//
void ApcKernelRoutine( 
    IN PKAPC Apc, 
    IN OUT PKNORMAL_ROUTINE *NormalRoutine, 
    IN OUT PVOID *NormalContext, 
    IN OUT PVOID *SystemArgument1, 
    IN OUT PVOID *SystemArgument2
    )
{
    //这里都可以正常执行到
    if (Apc)
        ExFreePool(Apc);
    if(pMdl)
    {
        MmUnlockPages(pMdl);
        IoFreeMdl (pMdl);
        pMdl = NULL;
    }
    DbgPrint("KernelExec -> ApcKernelRoutine called. Memory freed.");
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
纯个人感觉,楼主别生气:看到头像,就没有看代码的想法了~。。。。
2014-1-26 09:23
0
雪    币: 608
活跃值: (648)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
1.Win7下如果你的ShellCode存在SMC,就不要用MDL
2.APC的话,如果插已存在的进程的话,是很容易把进程插崩的
3.NT6系统可以用ZwCreateThreadEx,这个给力
2014-1-26 13:04
0
雪    币: 281
活跃值: (202)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
楼上头像更猛!
2014-1-26 13:13
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
SMC是啥?
2014-1-26 16:07
0
雪    币: 608
活跃值: (648)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
代码自修改
2014-1-26 17:38
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
win7可以直接在RING0创建进程的吗 我听说直接就可以的 但不知道怎么弄
2014-1-26 18:36
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
搞定了。。。。。。
2014-1-27 02:53
0
雪    币: 7
活跃值: (73)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
inc
9
为什么win7不能代码自修改??我在WIN7 下APC注入自修改代码时,确实有问题
2014-3-20 10:12
0
雪    币: 288
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
楼主怎么解决的啊?我也是用这个代码,在XP上OK了,win7上始终不行
2014-8-20 15:30
0
游客
登录 | 注册 方可回帖
返回
//