티스토리 뷰
/*++
Routine Description:
This routine creates and initializes a process object. It implements the
foundation for NtCreateProcess and for system initialization process
creation.
Arguments:
ProcessHandle - Returns the handle for the new process.
DesiredAccess - Supplies the desired access modes to the new process.
ObjectAttributes - Supplies the object attributes of the new process.
ParentProcess - Supplies a handle to the process' parent process. If this parameter is not specified, then the process has no parent and is created using the system address space.
SectionHandle - Supplies a handle to a section object to be used to create the process' address space. If this parameter is not specified, then the address space is simply a clone of the parent process' address space.
DebugPort - Supplies a handle to a port object that will be used as the process' debug port.
ExceptionPort - Supplies a handle to a port object that will be used as the
process' exception port.
Return Value:
TBD
--*/
NTSTATUS
PspCreateProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess OPTIONAL,
IN BOOLEAN InheritObjectTable,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL) {
NTSTATUS st;
PEPROCESS Process;
PEPROCESS Parent;
KAFFINITY Affinity;
KPRIORITY BasePriority;
PVOID SectionToMap;
PVOID ExceptionPortObject;
PVOID DebugPortObject;
ULONG WorkingSetMinimum, WorkingSetMaximum;
HANDLE LocalProcessHandle;
KPROCESSOR_MODE PreviousMode;
HANDLE NewSection;
NTSTATUS DuplicateStatus;
INITIAL_PEB InitialPeb;
BOOLEAN CreatePeb;
ULONG_PTR DirectoryTableBase[2];
BOOLEAN AccessCheck;
BOOLEAN MemoryAllocated;
PSECURITY_DESCRIPTOR SecurityDescriptor;
SECURITY_SUBJECT_CONTEXT SubjectContext;
NTSTATUS accesst;
NTSTATUS savedst;
BOOLEAN BreakAwayRequested;
PUNICODE_STRING AuditName = NULL ;
PAGED_CODE();
BreakAwayRequested = FALSE;
CreatePeb = FALSE;
DirectoryTableBase[0] = 0;
DirectoryTableBase[1] = 0;
PreviousMode = KeGetPreviousMode();
//
// Parent
//
if (ARGUMENT_PRESENT(ParentProcess) ) {
st = ObReferenceObjectByHandle(
ParentProcess,
PROCESS_CREATE_PROCESS,
PsProcessType,
PreviousMode,
(PVOID *)&Parent,
NULL
);
if ( !NT_SUCCESS(st) ) {
return st;
}
//
// Until CSR understands priority class, don't
// inherit base priority. This just makes things
// worse !
//
BasePriority = (KPRIORITY) NORMAL_BASE_PRIORITY;
//
//BasePriority = Parent->Pcb.BasePriority;
//
Affinity = Parent->Pcb.Affinity;
WorkingSetMinimum = PsMinimumWorkingSet; // FIXFIX
WorkingSetMaximum = PsMaximumWorkingSet;
} else {
Parent = NULL;
Affinity = KeActiveProcessors;
BasePriority = (KPRIORITY) NORMAL_BASE_PRIORITY;
WorkingSetMinimum = PsMinimumWorkingSet; // FIXFIX
WorkingSetMaximum = PsMaximumWorkingSet;
}
//
// Section
//
if (ARGUMENT_PRESENT(SectionHandle) ) {
//
// Use Object manager tag bits to indicate that breakaway is
// desired
//
if ( (UINT_PTR)SectionHandle & 1 ) {
BreakAwayRequested = TRUE;
}
st = ObReferenceObjectByHandle(
SectionHandle,
SECTION_MAP_EXECUTE,
MmSectionObjectType,
PreviousMode,
(PVOID *)&SectionToMap,
NULL
);
if ( !NT_SUCCESS(st) ) {
if (Parent) {
ObDereferenceObject(Parent);
}
return st;
}
} else {
SectionToMap = NULL;
}
//
// DebugPort
//
if (ARGUMENT_PRESENT(DebugPort) ) {
st = ObReferenceObjectByHandle (
DebugPort,
0,
LpcPortObjectType,
KeGetPreviousMode(),
(PVOID *)&DebugPortObject,
NULL
);
if ( !NT_SUCCESS(st) ) {
if (Parent) {
ObDereferenceObject(Parent);
}
if (SectionToMap) {
ObDereferenceObject(SectionToMap);
}
return st;
}
} else {
DebugPortObject = NULL;
}
//
// ExceptionPort
//
if (ARGUMENT_PRESENT(ExceptionPort) ) {
st = ObReferenceObjectByHandle (
ExceptionPort,
0,
LpcPortObjectType,
KeGetPreviousMode(),
(PVOID *)&ExceptionPortObject,
NULL
);
if ( !NT_SUCCESS(st) ) {
if (Parent) {
ObDereferenceObject(Parent);
}
if (SectionToMap) {
ObDereferenceObject(SectionToMap);
}
if (DebugPortObject) {
ObDereferenceObject(DebugPortObject);
}
return st;
}
} else {
ExceptionPortObject = NULL;
}
st = ObCreateObject(
KeGetPreviousMode(),
PsProcessType,
ObjectAttributes,
KeGetPreviousMode(),
NULL,
(ULONG) sizeof(EPROCESS),
0,
0,
(PVOID *)&Process
);
if ( !NT_SUCCESS( st ) ) {
if (Parent) {
ObDereferenceObject(Parent);
}
if (SectionToMap) {
ObDereferenceObject(SectionToMap);
}
if (DebugPortObject) {
ObDereferenceObject(DebugPortObject);
}
if (ExceptionPortObject) {
ObDereferenceObject(ExceptionPortObject);
}
return st;
}
//
// The process object is created set to NULL. Errors
// That occur after this step cause the process delete
// routine to be entered.
//
// Teardown actions that occur in the process delete routine
// do not need to be performed inline.
//
RtlZeroMemory(Process,sizeof(EPROCESS));
InitializeListHead(&Process->ThreadListHead);
Process->CreateProcessReported = FALSE;
Process->DebugPort = DebugPortObject;
Process->ExceptionPort = ExceptionPortObject;
PspInheritQuota(Process,Parent);
ObInheritDeviceMap(Process,Parent);
if ( Parent ) {
Process->DefaultHardErrorProcessing = Parent->DefaultHardErrorProcessing;
Process->InheritedFromUniqueProcessId = Parent->UniqueProcessId;
Process->SessionId = Parent->SessionId;
} else {
Process->DefaultHardErrorProcessing = 1;
Process->InheritedFromUniqueProcessId = NULL;
}
Process->ExitStatus = STATUS_PENDING;
Process->LockCount = 1;
Process->LockOwner = NULL;
KeInitializeEvent(&Process->LockEvent, SynchronizationEvent, FALSE);
//
// Initialize the security fields of the process
// The parent may be null exactly once (during system init).
// Thereafter, a parent is always required so that we have a
// security context to duplicate for the new process.
//
st = PspInitializeProcessSecurity( Parent, Process );
if (!NT_SUCCESS(st)) {
if ( Parent ) {
ObDereferenceObject(Parent);
}
if (SectionToMap) {
ObDereferenceObject(SectionToMap);
}
ObDereferenceObject(Process);
return st;
}
//
// Clone parent's object table.
// If no parent (booting) then use the current object table created in
// ObInitSystem.
//
if (Parent) {
//
// Calculate address space
//
// If Parent == PspInitialSystem
//
if (!MmCreateProcessAddressSpace(WorkingSetMinimum,
Process,
&DirectoryTableBase[0])) {
ObDereferenceObject(Parent);
if (SectionToMap) {
ObDereferenceObject(SectionToMap);
}
PspDeleteProcessSecurity( Process );
ObDereferenceObject(Process);
return STATUS_INSUFFICIENT_RESOURCES;
}
} else {
Process->ObjectTable = PsGetCurrentProcess()->ObjectTable;
DirectoryTableBase[0] = PsGetCurrentProcess()->Pcb.DirectoryTableBase[0];
DirectoryTableBase[1] = PsGetCurrentProcess()->Pcb.DirectoryTableBase[1];
//
// Initialize the Working Set Mutex and address creation mutex
// for this "hand built" process.
// Normally, the call the MmInitializeAddressSpace initializes the
// working set mutex, however, in this case, we have already initialized
// the address space and we are now creating a second process using
// the address space of the idle thread.
//
//KeInitializeMutant(&Process->WorkingSetLock, FALSE);
ExInitializeFastMutex(&Process->WorkingSetLock);
ExInitializeFastMutex(&Process->AddressCreationLock);
KeInitializeSpinLock (&Process->HyperSpaceLock);
//
// Initialize virtual address descriptor root.
//
ASSERT (Process->VadRoot == NULL);
Process->Vm.WorkingSetSize = PsGetCurrentProcess()->Vm.WorkingSetSize;
KeQuerySystemTime(&Process->Vm.LastTrimTime);
Process->Vm.VmWorkingSetList = MmWorkingSetList;
}
Process->Vm.MaximumWorkingSetSize = WorkingSetMaximum;
KeInitializeProcess(
&Process->Pcb,
BasePriority,
Affinity,
&DirectoryTableBase[0],
(BOOLEAN)(Process->DefaultHardErrorProcessing & PROCESS_HARDERROR_ALIGNMENT_BIT)
);
Process->Pcb.ThreadQuantum = PspForegroundQuantum[0];
Process->PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
if (Parent) {
//
// this used to happen in basesrv\srvtask.c
//
if ( Parent->PriorityClass == PROCESS_PRIORITY_CLASS_IDLE ||
Parent->PriorityClass == PROCESS_PRIORITY_CLASS_BELOW_NORMAL ) {
Process->PriorityClass = Parent->PriorityClass;
}
//
// if address space creation worked, then when going through
// delete, we will attach. Of course, attaching means that the kprocess
// must be initialized, so we delay the object stuff till here.
//
st = ObInitProcess(InheritObjectTable ? Parent : (PEPROCESS)NULL,Process);
if (!NT_SUCCESS(st)) {
ObDereferenceObject(Parent);
if (SectionToMap) {
ObDereferenceObject(SectionToMap);
}
PspDeleteProcessSecurity( Process );
ObDereferenceObject(Process);
return st;
}
}
st = STATUS_SUCCESS;
savedst = STATUS_SUCCESS;
//
// Initialize the process address space
// The address space has four possibilities
//
// 1 - Boot Process. Address space is initialized during
// MmInit. Parent is not specified.
//
// 2 - System Process. Address space is a virgin address
// space that only maps system space. Process is same
// as PspInitialSystemProcess.
//
// 3 - User Process (Cloned Address Space). Address space
// is cloned from the specified process.
//
// 4 - User Process (New Image Address Space). Address space
// is initialized so that it maps the specified section.
//
if ( SectionToMap ) {
//
// User Process (New Image Address Space). Don't specify Process to
// clone, just SectionToMap.
//
st = MmInitializeProcessAddressSpace(
Process,
NULL,
SectionToMap,
&AuditName
);
ObDereferenceObject(SectionToMap);
ObInitProcess2(Process);
if ( NT_SUCCESS(st) ) {
//
// In order to support relocating executables, the proper status
// (STATUS_IMAGE_NOT_AT_BASE) must be returned, so save it here.
//
savedst = st;
st = PspMapSystemDll(Process,NULL);
}
CreatePeb = TRUE;
goto insert_process;
}
if ( Parent ) {
if ( Parent != PsInitialSystemProcess ) {
Process->SectionBaseAddress = Parent->SectionBaseAddress;
//
// User Process ( Cloned Address Space ). Don't specify section to
// map, just Process to clone.
//
st = MmInitializeProcessAddressSpace(
Process,
Parent,
NULL,
NULL
);
CreatePeb = TRUE;
} else {
//
// System Process. Don't specify Process to clone or section to map
//
st = MmInitializeProcessAddressSpace(
Process,
NULL,
NULL,
NULL
);
}
}
insert_process:
//
// If MmInitializeProcessAddressSpace was NOT successful, then
// dereference and exit.
//
if ( !NT_SUCCESS(st) ) {
if (Parent) {
ObDereferenceObject(Parent);
}
KeAttachProcess(&Process->Pcb);
ObKillProcess(FALSE, Process);
KeDetachProcess();
PspDeleteProcessSecurity( Process );
ObDereferenceObject(Process);
return st;
}
//
// Reference count of process is not biased here. Each thread in the
// process bias the reference count when they are created.
//
st = ObInsertObject(
Process,
NULL,
DesiredAccess,
0,
(PVOID *)NULL,
&LocalProcessHandle
);
if ( !NT_SUCCESS(st) ) {
if (Parent) {
ObDereferenceObject(Parent);
}
return st;
}
//
// See if the parent has a job. If so reference the job
// and add the process in.
//
if ( Parent && Parent->Job && !(Parent->Job->LimitFlags & JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK) ) {
if ( BreakAwayRequested ) {
if ( !(Parent->Job->LimitFlags & JOB_OBJECT_LIMIT_BREAKAWAY_OK) ) {
st = STATUS_ACCESS_DENIED;
if (Parent) {
ObDereferenceObject(Parent);
}
ZwClose(LocalProcessHandle);
return st;
}
}
else {
ObReferenceObject(Parent->Job);
Process->Job = Parent->Job;
st = PspAddProcessToJob(Process->Job,Process);
if ( !NT_SUCCESS(st) ) {
if (Parent) {
ObDereferenceObject(Parent);
}
ZwClose(LocalProcessHandle);
return st;
}
}
}
PsSetProcessPriorityByClass(Process,PsProcessPriorityBackground);
ExAcquireFastMutex(&PspActiveProcessMutex);
InsertTailList(&PsActiveProcessHead,&Process->ActiveProcessLinks);
ExReleaseFastMutex(&PspActiveProcessMutex);
if (Parent && CreatePeb ) {
//
// For processes created w/ a section,
// a new "virgin" PEB is created. Otherwise,
// for forked processes, uses inherited PEB
// with an updated mutant.
RtlZeroMemory(&InitialPeb, FIELD_OFFSET(INITIAL_PEB, Mutant));
InitialPeb.Mutant = (HANDLE)(-1);
if ( SectionToMap ) {
try {
Process->Peb = MmCreatePeb(Process,&InitialPeb);
} except(EXCEPTION_EXECUTE_HANDLER) {
ObDereferenceObject(Parent);
ZwClose(LocalProcessHandle);
return GetExceptionCode();
}
} else {
InitialPeb.InheritedAddressSpace = TRUE;
Process->Peb = Parent->Peb;
ZwWriteVirtualMemory(
LocalProcessHandle,
Process->Peb,
&InitialPeb,
sizeof(INITIAL_PEB),
NULL
);
}
//
// The new process should have a handle to its
// section. The section is either from the specified
// section, or the section of its parent.
//
if ( ARGUMENT_PRESENT(SectionHandle) ) {
DuplicateStatus = ZwDuplicateObject(
NtCurrentProcess(),
SectionHandle,
LocalProcessHandle,
&NewSection,
0L,
0L,
DUPLICATE_SAME_ACCESS
);
} else {
DuplicateStatus = ZwDuplicateObject(
ParentProcess,
Parent->SectionHandle,
LocalProcessHandle,
&NewSection,
0L,
0L,
DUPLICATE_SAME_ACCESS
);
}
if ( NT_SUCCESS(DuplicateStatus) ) {
Process->SectionHandle = NewSection;
}
ObDereferenceObject(Parent);
}
if ( Parent && ParentProcess != PspInitialSystemProcessHandle ) {
st = ObGetObjectSecurity(
Process,
&SecurityDescriptor,
&MemoryAllocated
);
if ( !NT_SUCCESS(st) ) {
ZwClose(LocalProcessHandle);
return st;
}
//
// Compute the subject security context
//
SubjectContext.ProcessAuditId = Process;
SubjectContext.PrimaryToken = PsReferencePrimaryToken(Process);
SubjectContext.ClientToken = NULL;
AccessCheck = SeAccessCheck(
SecurityDescriptor,
&SubjectContext,
FALSE,
MAXIMUM_ALLOWED,
0,
NULL,
&PsProcessType->TypeInfo.GenericMapping,
PreviousMode,
&Process->GrantedAccess,
&accesst
);
PsDereferencePrimaryToken(SubjectContext.PrimaryToken);
ObReleaseObjectSecurity(
SecurityDescriptor,
MemoryAllocated
);
if ( !AccessCheck ) {
Process->GrantedAccess = 0;
}
//
// It does not make any sense to create a process that can not
// do anything to itself
//
Process->GrantedAccess |= (PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION | PROCESS_TERMINATE | PROCESS_CREATE_THREAD | PROCESS_DUP_HANDLE | PROCESS_CREATE_PROCESS | PROCESS_SET_INFORMATION);
} else {
Process->GrantedAccess = PROCESS_ALL_ACCESS;
}
if ( SeDetailedAuditing ) {
SeAuditProcessCreation( Process, Parent, AuditName );
}
KeQuerySystemTime(&Process->CreateTime);
try {
*ProcessHandle = LocalProcessHandle;
} except(EXCEPTION_EXECUTE_HANDLER) {
return st;
}
if (savedst != STATUS_SUCCESS) {
st = savedst;
}
return st;
}
'보안 > 분석' 카테고리의 다른 글
struct _RTL_USER_PROCESS_PARAMETERS for XP (0) | 2008.03.26 |
---|---|
Hooking functions not exported by ntoskrnl [펌 www.rootkit.com] (0) | 2008.03.25 |
NTSTATUS PsCreateSystemProcess(...) (0) | 2008.03.25 |
ntoskrnl.exe - Exports (0) | 2008.03.24 |
A more stable way to locate real KiServiceTable [펌 www.rootkit.com] (6) | 2008.03.24 |
- Total
- Today
- Yesterday
- 지루박멸연구센타
- 열정의 힘을 믿는다
- Le4rN TO Cr4cK
- 디버깅에관한모든것(DebugLab)
- sysinternals
- FoundStone
- hashtab
- 보안-coderant
- 디바이스드라이버 개발자 포럼
- dualpage.muz.ro
- osronline.com - 드라이버 관련 정보 사이트
- NtInternals - NativeAPI Refere…
- pcthreat - spyware 정보 제공
- rootkit.com - 루트킷 관련 정보
- www.ntinternals.net
- WINE CrossRef. - source.winehq…
- tuts4you
- hex-rays
- idapalace
- idefense
- immunityinc
- threatexpert
- hdp.null2root.org
- www.crackstore.com
- crackmes.de
- www.who.is
- www.cracklab.ru
- community.reverse-engineering.…
- video.reverse-engineering.net
- SnD
- 클레이 키위
- reversengineering.wordpress.co…
- www.openrce.org
- www.woodmann.com
- PEID.Plusins.BobSoft
- roxik.com/pictaps/
- regexlib.com
- spyware-browser.com
- www.usboffice.kr
- regulator
- www.txt2re.com
- ietab.mozdev.org
- zesrever.xstone.org
- www.heaventools.com/PE-file-he…
- www.heaventools.com
- www.innomp3.com
- 울지않는벌새
- exetools.com-forum
- exetools.com
- utf8 conv
- robtex - IP trace
- onsamehost - same IP sites
- JpopSuki
- jsunpack.jeek.org
- wepawet.iseclab.org
- www.jswiff.com
- www.hackeroo.com
- winesearcher.co.kr
- khpga.org
- malwareurl.com
- anubis.iseclab.org
- www.crummy.com-eautifulSoup
- malwarebytes.org/forums
- bbs.janmeng.com
- blackip.ustc.edu.cn
- eureka.cyber-ta.org
- exploit-db.com
- 자동트래이딩
- INVOICE
- 주식
- 매매가격지수
- 피봇
- 맥쿼리인프라
- hai
- ElasticSearch
- 군함도
- ROA
- 시스템트래이딩
- PIR
- 레고랜드
- 다올저축은행
- 사회간접자본
- SBI저축은행
- O365
- 공공인프라
- 주식트래이딩
- 실시간트래이딩
- ChatGPT
- 주택구매력지수
- Pivot
- 신한저축은행
- systemd
- 미국주식
- logrotate
- 전세매매지수
- ubuntu
- CriticalSection
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |