CreateProcess 内部实现

调用CreateProcessW
   调用CreateProcessInternalW
      参数检查
      获取进程文件路径
      调用 BasepMapFile 映射文件(内部调用NtCreateSection)
      判断是否是一个DLL文件
      判断子系统类型(只能是GUI和CUI中的一种)
      是GUI时,则去掉CREATE_NEW_CONSOLE标志,增加DETACHED_PROCESS
      如果dwCreationFlags参数中包含DEBUG_PROCESS|DEBUG_ONLY_THIS_PROCESS,则调用DbgUiConnectToDbg创建调试对象(debugPort)
      调用NtCreateProcess开始创建进程
         调用NtCreateProcessEx
             调用PspCreateProcess
                关联相关句柄的内核对象(SectionHandle,DebugPort,ExceptionPort)
                创建进程空间( MmCreateProcessAddressSpace )
                初始化进程内核对象(KeInitializeProcess)
                复制父进程的Token(PspInitializeProcessSecurity)
                初始化进程句柄表(ObInitProcess)
                把进程模块映射进内存(MmInitializeProcessAddressSpace-->MmMapViewOfSection)
                映射系统模块(PspMapSystemDll-->MmMapViewOfSection)
                把该内核对象加入到进程线程对象表(PspCidTable)中,并得到进程ID
                创建PEB(MmCreatePeb)
                获取进程句柄(ObInsertObject)
                权限检查(SeAccessCheck)
                执行(监控进程创建)回调函数(PspRunCreateProcessNotifyRoutines)
      设置进程优先级
      设置进程参数(BasePushProcessParameters)
      关闭由BasepMapFile函数创建的section句柄
      复制标准输入、输出、错误设备句柄
      调用BasepNotifyCsrOfCreation
      创建第一个线程BasepCreateFirstThread
       创建线程栈(BaseCreateStack)
       初始化线程环境块(BaseInitializeContext)
          设置寄存器
          eax = 入口点
          ebx = 参数
          esp = 栈底指针
          eip = BaseProcessStartThunk
       创建线程内核对象(NtCreateThread)
          调用PspCreateThread
             创建线程对象(ObCreateObject)
             得到线程ID(ExCreateHandle)
             初始化相关链表
             创建TEB(MmCreateTeb)
             设置线程的起始地址
             初始化线程对象(KeInitThread)
                 第三个参数传入的是:PspUserThreadStartup
                 调用KiInitializeContextThread
                     CtxSwitchFrame->RetAddr = KiThreadStartup;
      启动第一个线程NtResumeThread
      
      
      
线程是怎么启动的?
    KiThreadStartup
     调用 PspUserThreadStartup
插入APC回调 LdrInitializeThunk函数
1. 线程启动时会先执行APC回调
   LdrInitializeThunk内部实现
      调用LdrpInit
          如果是进程中第一个线程
               调用LdrpInitializeProcess
               初始化NLS
               创建堆(RtlCreateHeap)
               初始化Loader Data
               把进程模块和NTDLL模块信息写入Loader Data中
               遍历主模块输入表并加载相关模块(LdrpWalkImportDescriptor)
               修正主模块重定位(LdrRelocateImageWithBias)
               初始化TLS(LdrpInitializeTls) 计算TLS占用的空间大小
               如果有调试器,通知调试器
               调用模块入口点LdrpRunInitializeRoutines(包括TLS CALLBACK)(DLL_PROCESS_ATTACH)
          非第一个线程
            调用LdrpInitializeThread
               循环调用各个模块的TLS callback
                入口点
                (DLL_THREAD_ATTACH)

          测试Alart(NtTestAlert)

2. APC执行完后执行PspUserThreadStartup函数

PspUserThreadStartup函数调用线程入口地址,开始执行线程



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值