文档章节

apc启动新进程

simpower
 simpower
发布于 2019/11/18 11:14
字数 1511
阅读 8
收藏 0

3 月,跳不动了?>>>

http://www.codeproject.com/Articles/13572/Starting-a-Process-from-KernelMode

#include "Process.h"

typedef enum
{
    OriginalApcEnvironment,
	AttachedApcEnvironment,
	CurrentApcEnvironment
} KAPC_ENVIRONMENT;
 
void ApcKernelRoutine( IN struct _KAPC *Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2 ) ;
NTSTATUS InstallUserModeApc(LPSTR lpProcess, PKTHREAD pTargetThread, PEPROCESS pTargetProcess);
void ApcCreateProcess(PVOID NormalContext, PVOID  SystemArgument1, PVOID SystemArgument2);
void ApcCreateProcessEnd();
 
 
#pragma alloc_text(PAGE, RunProcess)
#pragma alloc_text(PAGE, ApcKernelRoutine)
#pragma alloc_text(PAGE, InstallUserModeApc)
#pragma alloc_text(PAGE, ApcCreateProcess)
#pragma alloc_text(PAGE, ApcCreateProcessEnd)
 
 
//=====================================================================================//
//Name: void RunProcess()                                                              //
//                                                                                     //
//Descripion: This routine retrieves the list of all processes running on the machine, //
//            searches for 'explorer.exe', gets one thread from it's PEPROCESS struct, //
//            then it queues an APC to that thread                                     //
//=====================================================================================//
void RunProcess(LPSTR lpProcess)
{
 
	PEPROCESS pTargetProcess = NULL;     //self explanatory
	PKTHREAD pTargetThread = NULL;       //thread that can be either alerable or non-alertable
	PKTHREAD pNotAlertableThread = NULL; //non-alertable thread
	PEPROCESS pSystemProcess = NULL;     //May not necessarily be the 'System' process
	
	PETHREAD pTempThread = NULL;
	PLIST_ENTRY	pNextEntry, pListHead, pThNextEntry; 
 
 
	if(strlen(lpProcess)>300) return; //name not longer than 300 characters
 
	pSystemProcess = PsGetCurrentProcess(); //make sure you are running at IRQL PASSIVE_LEVEL
 
	if(!pSystemProcess) 
	{
		DbgPrint("KernelExec -> Cannot find 'System' process!");
		return;
	}
	
	if(IsListEmpty(&pSystemProcess->ActiveProcessLinks))
		DbgPrint("KernelExec -> No processes found!");
	else
	{
		pListHead = &pSystemProcess->ActiveProcessLinks;
		pNextEntry = pListHead->Flink;
 
		while(pNextEntry != pListHead) //start looping through the available processes
		{
			pSystemProcess = CONTAINING_RECORD(pNextEntry,EPROCESS,ActiveProcessLinks);
 
			if(pSystemProcess->ActiveThreads)
			{
				if(!IsListEmpty(&pSystemProcess->ThreadListHead))
				{
					//Is this explorer.exe? 
					if(_strnicmp(pSystemProcess->ImageFileName,"explorer.exe",12)==0)
					{
						pTargetProcess = pSystemProcess; //Yes,we have found it!
						pTargetThread = pNotAlertableThread = NULL;
 
						pThNextEntry = pSystemProcess->ThreadListHead.Flink;
						
						//Now we loop through it's threads, seeking an alertable thread
						while(pThNextEntry != &pSystemProcess->ThreadListHead)
						{
							pTempThread = CONTAINING_RECORD(pThNextEntry,ETHREAD,ThreadListEntry);							
						
							if(pTempThread->Tcb.Alertable) //Tcb is the KTHREAD of this ETHREAD and stands for 'Thread Control Block'
							{
								//Good, an alertable thread was found. 
								pTargetThread = &pTempThread->Tcb;
 
								DbgPrint("KernelExec -> Found alertable thread");
								//We will be using this one, so break now
								break;
							}
							else
							{
								//Didn't find an alertable thread yet, so we'll keep this one
								//just in case we won't find ANY alertable threads
								pNotAlertableThread = &pTempThread->Tcb;
							}
 
							pThNextEntry = pThNextEntry->Flink; //check next thread
						}
						break;	
					}
				}		
			}
			
			pSystemProcess = NULL;
			pNextEntry = pNextEntry->Flink; //get next process
		}
	}
	
	if(!pTargetProcess)
	{
		DbgPrint("KernelExec -> Couldn't find Explorer.exe!"); 
		return;
	}
	
	if(!pTargetThread)
	{
		//No alertable thread was found, so let's hope we've at least got a non-alertable one (we'll set its alertable flag ON)
		//There's no problem with non-alertable threads, except for the fact that it takes
		//a little longer for them to return from KernelMode. (that means our process execution will be delayed)
		pTargetThread = pNotAlertableThread;
	}
 
	if(pTargetThread)
	{
		DbgPrint("KernelExec -> Targeted thread: 0x%p",pTargetThread);
		//We have one thread (alertable or n/a), now install the APC
		InstallUserModeApc(lpProcess, pTargetThread,pTargetProcess);
	}
	else
		DbgPrint("KernelExec -> No thread found!"); //Explorer exe with NO threads (???)
}
 
 
 
PMDL pMdl = NULL;
//===================================================================//
//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 struct _KAPC *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.");
}
 
 
//===================================================================//
//Name:                                                              //
//     NTSTATUS InstallUserModeApc()                                 //
//                                                                   //
//Paramters:                                                         //
//          lpProcess - Full path of the process to be executes      //
//          pTargetThread - This is where we queue our APC           //
//          pTargetProcess - Should point to Explorer's EPROCESS     //
//                                                                   //
//Descripion: This routine attaches to 'pTargetThread' and it queues //
//            a UserMode APC that will be excuted next time the      //
//            thread returns from KernelMode                         //
//===================================================================//
NTSTATUS 
InstallUserModeApc(LPSTR lpProcess, PKTHREAD pTargetThread, PEPROCESS pTargetProcess)
{
	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
 
	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;
 
 
	//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 = (unsigned char*)ApcCreateProcessEnd-(unsigned char*)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 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("KernelExec -> Cannot map address");
 
		KeUnstackDetachProcess (&ApcState);
		IoFreeMdl (pMdl);
		ExFreePool (pApc);
 
		return STATUS_UNSUCCESSFUL;
	}
	else 
		DbgPrint("KernelExec -> UserMode memory at address: 0x%p",pMappedAddress);
 
	dwMappedAddress = (ULONG)pMappedAddress;
	
	memset ((unsigned char*)pMappedAddress + 0x14, 0, 300);//zero everything out ecxept our assembler code
    memcpy ((unsigned char*)pMappedAddress + 0x14, lpProcess,strlen (lpProcess)); //copy the path to the executable
 
	data_addr = (ULONG*)((char*)pMappedAddress+0x9); //address pushed on the stack (originaly 0xabcd)...
	*data_addr = dwMappedAddress+0x14; //..gets changed to point to our exe's path 
	
	//all done, detach now
	KeUnstackDetachProcess (&ApcState);
	
	//Initialize the APC...
	KeInitializeApc(pApc,pTargetThread,
		OriginalApcEnvironment,
		&ApcKernelRoutine,NULL,
		pMappedAddress, UserMode, (PVOID) NULL);
	
	//...and queue it
	if (!KeInsertQueueApc(pApc,0,NULL,0))
	{
		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(!pTargetThread->ApcState.UserApcPending)
	{
		//if yes then alert it
		pTargetThread->ApcState.UserApcPending = TRUE;
	}
 
	return 0;
}
 
 
//=====================================================================================//
//Name: void ApcCreateProcess()                                                        //
//                                                                                     //
//Descripion: This is the code that runs in UserMode. 0x7X86114D is the address of     //
//            WinExec on WinXP SP2. You can do everything here and not crash the system//
//            (but Explorer WILL crash, if you do something stupid)                    //
//=====================================================================================//
__declspec(naked) void ApcCreateProcess(PVOID NormalContext, PVOID  SystemArgument1, PVOID SystemArgument2)
{
    __asm 
    {
		mov eax,0x7C86114D
		push 1
		nop
		push 0xabcd
		call eax
		jmp end       
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
end:
		nop
		ret 0x0c
    }
 
}
void ApcCreateProcessEnd(){}
    #include "KernelExec.h"
    #include "Process.h"
     
     
    NTSTATUS DriverEntry(PDRIVER_OBJECT  pDriverObject, PUNICODE_STRING  pRegistryPath)
    {
    	
    	NTSTATUS NtStatus = STATUS_SUCCESS;
    	PDEVICE_OBJECT pDeviceObject = NULL;
    	UNICODE_STRING usDriverName, usDosDeviceName;
    	
    	
    	RtlInitUnicodeString(&usDriverName, L"\\Device\\KernelExec");
    	
    	
    	NtStatus = IoCreateDevice(pDriverObject, 0, &usDriverName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject);
    	
    	if(NtStatus == STATUS_SUCCESS)
    	{
    		pDriverObject->MajorFunction[IRP_MJ_CLEANUP]           = KE_Dispatch; 
    		pDriverObject->MajorFunction[IRP_MJ_CLOSE]             = KE_Dispatch;
    		pDriverObject->MajorFunction[IRP_MJ_CREATE]            = KE_Dispatch;
    		pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]    = KE_Dispatch;
    		pDriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = KE_Dispatch;
    		pDriverObject->MajorFunction[IRP_MJ_READ]              = KE_Dispatch;
    		pDriverObject->MajorFunction[IRP_MJ_WRITE]             = KE_Dispatch;
    		pDriverObject->DriverUnload =  KE_Unload;
    		
    		DbgPrint("KernelExec -> Driver Loaded");
    	}
     
    	RunProcess("c:\\rawwrite.exe");
    	
    	return NtStatus;
    }
     
    VOID KE_Unload(PDRIVER_OBJECT  DriverObject)
    {
        IoDeleteDevice(DriverObject->DeviceObject);
    	DbgPrint("KernelExec -> Driver Unloaded");
    }
     
    NTSTATUS KE_Dispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
    {
    	//Nothing to do here, just complete the request and return
    	Irp->IoStatus.Status = STATUS_SUCCESS;
    	IoCompleteRequest(Irp, IO_NO_INCREMENT);
    	
    	return STATUS_SUCCESS;
    }

 

本文转载自:https://blog.csdn.net/sgzwiz/article/details/20415647

simpower
粉丝 29
博文 708
码字总数 53502
作品 0
海淀
程序员
私信 提问
加载中

评论(0)

apache启动后只有一个进程,而且没有生成httpd.pid

apache启动后只有一个httpd进程,并且没有生成httpd.pid,原因为php的扩展apc生成的目录为/tmp/apc/下, apc.mmapfilemask = /tmp/apc/apc.XXXXXX,服务器重启后,apc目录删除,所以apache进...

庆沉
2016/01/13
46
0
php 的opcode缓存apc以及其安装

先说说php程序的执行流程吧,说明了这个,才好开始我们的优化之旅。 客户端(譬如浏览器) —》请求Get hello.php —-》cgi服务器接(譬如apache)收到请求,根据配置寻找php的处理程序(譬如...

晨曦之光
2012/03/09
576
1
PHP APC缓存配置、使用详解

一、APC缓存简介 APC,全称是Alternative PHP Cache,官方翻译叫”可选PHP缓存”。它为我们提供了缓存和优化PHP的中间代码的框架。 APC的缓存分两部分:系统缓存和用户数据缓存。 系统缓存 它...

mysoftsky
2014/03/06
6.5K
0
在ubuntu上安装apc扩展

安装apc扩展 sudo apt-get install php-apc, 在安装之后重启apache就可以使用了,但是重启nginx还不能使用,在/etc/php5/fpm里面也看到了apc扩展,但是为什么没有加载成功呢,原来我们需要将...

真座山雕
2013/08/14
253
0
PHP模块安装说明

@1 php-fpm (FastCGI Process Manager:FastCGI进程管理器 PHP-FPM提供了更好的PHP进程管理方式,可以有效控制内存和进程、可以平滑重载PHP配置,比spawn-fcgi具有更多优点,所以被PHP官方收...

ITCHN
2016/12/26
15
0

没有更多内容

加载失败,请刷新页面

加载更多

如何在Linux中一步更改文件夹及其所有子文件夹和文件的权限? [关闭]

问题: I would like to change permissions of a folder and all its sub folders and files in one step (command) in Linux. 我想在Linux中一步(命令)更改文件夹及其所有子文件夹和文件......

javail
35分钟前
13
0
Gradle 6 针对已有的构建如何创建一个构建扫描

有关构建扫描的定义为: 构建扫描(build scan)是一个中心化并且可以共享的构建记录。这个构建记录通常能够告诉在构建中发生了什么并且为什么会发生。 通过应用构建扫描插件到你的项目中,你...

honeymoose
今天
17
0
C语言动态内存分配:(一)malloc/free的实现及malloc实际分配/释放的内存

一、malloc/free概述 malloc是在C语言中用于在程序运行时在堆中进行动态内存分配的库函数。free是进行内存释放的库函数。 1、函数原型 #include <stdlib.h> void *malloc( size_t size ); v...

shzwork
今天
17
0
什么是JavaBean? - What is a JavaBean exactly?

问题: I understood, I think, that a "Bean" is a Java class with properties and getters/setters. 我认为,“ Bean”是具有属性和getter / setter的Java类。 As much as I understand,......

技术盛宴
今天
27
0
深圳援鄂最后一批工作人员归来,88万元关爱金发放至85人

中国公益在线3月31日深圳讯 深圳援鄂最后一批工作人员归来......深圳市民政局、深圳市卫健委和深圳市慈善会发起了“深爱战疫天使基金”项目,联合龙华区慈善会和 永贤慈善基金会,进行第二次...

传承天下融媒体中心
今天
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部