现在的位置: 首页 > 综合 > 正文

还原NtTerminateProcess

2014年01月24日 ⁄ 综合 ⁄ 共 5757字 ⁄ 字号 评论关闭

在上课吃饱了没事干的情况下,花了点功夫还原了我电脑上的NtTerminateProcess的代码

我的系统是Windows XP Kernel Version 2600 (Service Pack 3) MP (2 procs) Free x86 compatible(来自windbg)

nt!NtTerminateProcess:
mov     edi,edi
push    ebp
mov     ebp,esp
sub     esp,10h
push    ebx
push    esi
push    edi
mov     eax,KPCR.PrcbData.CurrentThread ;eax = CurrentThread
cmp     ProcessHandle,0
mov     edi,eax
mov     eax,CurrentThread.ApcState.Process
mov     Process,eax ;Process = CurrentThread.ApcState.Process
je      nt!NtTerminateProcess+0x25
;if(ProcessHandle)
;{
nt!NtTerminateProcess+0x1f:
mov     ebp_1,1 ;ebp_1 = 1
jmp     nt!NtTerminateProcess+0x2d
;}
;else
;{
nt!NtTerminateProcess+0x25:
or      ProcessHandle,0FFFFFFFFh ;ProcessHandle = NtCurrentProcess()
mov     ebp_1,0 ;ebp_1 = 0
;}
nt!NtTerminateProcess+0x2d:
mov     al,CurrentThread.PreviousMode
push    0
mov     PreviousMode,al ;ebp_8.PreviousMode = CurrentThread.PreviousMode
lea     eax,EPROCESS
push    eax
push    CurrentThread.PreviousMode
push    dword ptr [nt!PsProcessType]
push    1
push    ProcessHandle
call    nt!ObReferenceObjectByHandle ;NTSTATUS = ObReferenceObjectByHandle(ProcessHandle,1,PsProcessType,ebp_8.PreviousMode,&ebp_8.EPROCESS,NULL)
test    eax,eax
mov     esi,EPROCESS ;esi = EPROCESS
mov     ebx,esi ;ebx = esi
jl      nt!NtTerminateProcess+0x144
;if(NT_SUCCESS(NTSTATUS))
;{
nt!NtTerminateProcess+0x5c:
lea     eax,EPROCESS.Flags
test    byte ptr [eax+1],20h
mov     Flags,eax ;Flags = EPROCESS.Flags
je      nt!NtTerminateProcess+0x7d
;if(EPROCESS.Flags.BreakOnTermination)
;{
nt!NtTerminateProcess+0x6b:
lea     eax,EPROCESS.ImageFileName
push    eax
push    esi
push    offset "Terminating critical process 0x%p (%s)"
call    nt!PspCatchCriticalBreak ;PspCatchCriticalBreak("Terminating critical process 0x%p (%s)",EPROCESS,EPROCESS.ImageFileName)
;}
nt!NtTerminateProcess+0x7d:
lea     ecx,EPROCESS.RundownProtect
mov     RundownProtect,ecx ;RundownProtect = &EPROCESS.RundownProtect
call    nt!ExAcquireRundownProtection
test    al,al
jne     nt!NtTerminateProcess+0xa0
;if(!ExAcquireRundownProtection(&EPROCESS.RundownProtect))
;{
nt!NtTerminateProcess+0x8f:
mov     ecx,esi
call    nt!ObfDereferenceObject ;ObfDereferenceObject(EPROCESS)
mov     eax,0C000010Ah ;NTSTATUS = 0xC000010A
jmp     nt!NtTerminateProcess+0x144 ;return
;}
;else
;{
nt!NtTerminateProcess+0xa0:
cmp     ebp_1,0
je      nt!NtTerminateProcess+0xaf
;if(ebp_1)
;{
nt!NtTerminateProcess+0xa6:
mov     ecx,Flags
push    8
pop     eax
lock or dword ptr [ecx],eax;EPROCESS.Flags.ProcessDelete = 1;
;}
nt!NtTerminateProcess+0xaf:
push    0
push    ebx
mov     Flags,122h ;Flags = 0x122
call    nt!PsGetNextProcessThread
mov     esi,eax
test    esi,esi
je      nt!NtTerminateProcess+0xe2
;if(Thread = PsGetNextProcessThread(EPROCESS,NULL))
;{
nt!NtTerminateProcess+0xc4:
and     Flags,0 ;Flags = 0
;do
;{
nt!NtTerminateProcess+0xc8:
cmp     esi,edi
je      nt!NtTerminateProcess+0xd5
;if(Thread != CurrentThread)
;{
nt!NtTerminateProcess+0xcc:
push    ExitStatus
push    esi
call    nt!PspTerminateThreadByPointer ;PspTerminateThreadByPointer(Thread,ExitStatus)
;}
;}
nt!NtTerminateProcess+0xd5:
push    esi
push    ebx
call    nt!PsGetNextProcessThread
mov     esi,eax
test    esi,esi
jne     nt!NtTerminateProcess+0xc8
;while(Thread = PsGetNextProcessThread(EPROCESS,Thread))
;}
nt!NtTerminateProcess+0xe2:
mov     ecx,RundownProtect
call    nt!ExReleaseRundownProtection ;ExReleaseRundownProtection(RundownProtect)
cmp     ebx,Process
jne     nt!NtTerminateProcess+0x107
;if(EPROCESS == Process)
;{
nt!NtTerminateProcess+0xef:
cmp     byte ptr [ebp-1],0
je      nt!NtTerminateProcess+0x118
;if(ebp_1)
;{
nt!NtTerminateProcess+0xf5:
mov     ecx,ebx
call    nt!ObfDereferenceObject ;ObfDereferenceObject(EPROCESS)
push    ExitStatus
push    edi
call    nt!PspTerminateThreadByPointer ;PspTerminateThreadByPointer(CurrentThread,ExitStatus)
jmp     nt!NtTerminateProcess+0x118
;}
;else
;{
nt!NtTerminateProcess+0x107:
cmp     ExitStatus,40010004h
jne     nt!NtTerminateProcess+0x118
;if(ExitStatus == 0x40010004)
;{
nt!NtTerminateProcess+0x110:
push    0
push    ebx
call    nt!DbgkClearProcessDebugObject
;DbgkClearProcessDebugObject(EPROCESS,NULL)
;}
;}
;}
nt!NtTerminateProcess+0x118:
cmp     Flags,122h
je      nt!NtTerminateProcess+0x130

nt!NtTerminateProcess+0x121:
cmp     EPROCESS.DebugPort,0
je      nt!NtTerminateProcess+0x13a

nt!NtTerminateProcess+0x12a:
cmp     ebp_1,0
je      nt!NtTerminateProcess+0x13a
;if(Flags == 0x122 || (EPROCESS.DebugPort == 0 && ebp_1 == 0))
;{
nt!NtTerminateProcess+0x130:
push    ebx
call    nt!ObClearProcessHandleTable ;ObClearProcessHandleTable(EPROCESS)
and     Flags,0 ;Flags = 0
;}
nt!NtTerminateProcess+0x13a:
mov     ecx,ebx
call    nt!ObfDereferenceObject ;ObfDereferenceObject(EPROCESS)
mov     eax,Flags ;NTSTATUS = Flags
;}
;}
nt!NtTerminateProcess+0x144:
pop     edi
pop     esi
pop     ebx
leave
ret     8

大概的C代码如下

//Windows XP Kernel Version 2600 (Service Pack 3) MP (2 procs) Free x86 compatible

NTSTATUS NtTerminateProcess(HANDLE ProcessHandle, NTSTATUS ExitStatus)
{
	NTSTATUS status;
	PEPROCESS eprocess, currentProcess;
	PETHREAD ethread, currendThread;;
	BOOLEAN bHandle;
	
	currendThread = PsGetCurrentThread();
	currentProcess = (EPROCESS)currendThread->Tcb.ApcState.Process;
	if (ProcessHandle)
	{
		bHandle = TRUE;
	}
	else
	{
		ProcessHandle = NtCurrentProcess();
		bHandle = FALSE;
	}
	status = ObReferenceObjectByHandle(ProcessHandle, 1, PsProcessType, currendThread->PreviousMode, &eprocess, NULL);
	if (NT_SUCCESS(status))
	{
		if (eprocess->BreakOnTermination)
		{
			PspCatchCriticalBreak("Terminating critical process 0x%p (%s)", eprocess, eprocess->ImageFileName);
		}
		if (!ExAcquireRundownProtection(&eprocess->RundownProtect))
		{
			ObfDereferenceObject(eprocess);
			return 0xC000010A;
		} 
		else
		{
			if (bHandle)
			{
				eprocess->ProcessDelete = 1;
			}
			status = 0x122;
			if ((ethread = PsGetNextProcessThread(eprocess, NULL)))
			{
				status = STATUS_SUCCESS;
				do 
				{
					if (ethread != currendThread)
					{
						PspTerminateThreadByPointer(ethread, ExitStatus);
					}
				} while ((ethread = PsGetNextProcessThread(eprocess, ethread)));
			}
			ExReleaseRundownProtection(&eprocess->RundownProtect);
			if (eprocess == currentProcess)
			{
				if (bHandle)
				{
					ObfDereferenceObject(eprocess);
					PspTerminateThreadByPointer(currendThread, ExitStatus);
				}
				else
				{
					if (ExitStatus == 0x40010004)
					{
						DbgkClearProcessDebugObject(eprocess, NULL);
					}
				}
			}
			if (status != 0x122 || (eprocess->DebugPort != NULL && bHandle == FALSE))
			{
				ObClearProcessHandleTable(eprocess);
				status = STATUS_SUCCESS;
			}
			ObfDereferenceObject(eprocess);
		}
	}
	return status;
}

再说几句废话...看了下PsTerminateProcess发现其实就是NtTerminateProcess调用ObReferenceObjectByHandle后的部分,既然如此,为什么不直接调用呢,还是有其他原因?在这点还是有点无法理解,莫非是为了防止NtTerminateProcess被修改?比较PsTerminateProcess貌似没被导出...

抱歉!评论已关闭.