整体过程如下:

需要说明两点:

1.在XP中,新进程主线程的启动,会先执行一个用户态的APC,会执行ntdll!LdrInitializeThunk进行程序执行前的一些列初始化操作。其中很重要任务就是加载从Kernel32.dll开始的系统DLL。注意的是,这个APC的插入,根据WRK中的代码看来是在PspUserThreadStartup中进行的:

但实际调试XP SP3发现,该函数并未有这个动作。并且在进入这个函数的时候APC已经插入好了。于是追踪到在XP SP3中,该APC的插入时机是在nt!PspCreateThread中进行的。

2.虽然XP和Win7都会在主线程Ring3入口(XP是BaseProcessStart,Win7是RtlUserThreadStart)前执行LdrInitializeThunk进行初始化,但二者细节处还是不同。

对于XP,如上所述,是通过nt!PspCreateThread在创建线程完成后插入APC,等到新进程主线程得到调度,在nt!KiThreadStartup完成后,跳到nt!_KiSystemExit处返回到用户模式时,该APC得到交付从而执行到。

而对于Win7,创建进程路径发生了大变化,不再有nt!PspCreateThread,而是nt! PspAllocateThread,这里面也没有插入APC的动作。即使追踪到nt!KiThreadStartup即将跳到nt!_KiSystemExit的位置,KTHREAD中的APC队列仍然没有LdrInitializeThunk这一项。按理说,这个时候返回就会到线程启动入口ntdll!RtlUserThreadStart才对。那LdrInitializeThunk怎么会执行呢?调试发现,在即将跳到nt!_KiSystemExit的时候,线程的KTRAP_FRAME中的EIP已经是LdrInitializeThunk而不是RtlUserThreadStart了。进一步跟踪发现,原来是在nt!PspCreateThread返回的前夕,通过nt!PspInitializeThunkContext—> nt!PspSetContextThreadInternal-->nt!PspGetSetContextSpecialApc-->nt!KeContextToKframes进行对KTRAP_FRAME进行修改了。通过函数名字也可以看出,这个动作是在模拟交付用户模式APC的动作。

因此,总结一下就是,对于XP,是通过正常的插入APC的形式,在线程内核启动函数完成后返回到用户模式时,触发了APC的交付。而对于Win7,则是在内核启动函数完成时,模拟出一个APC交付的过程,提前修改了KTRAP_FRAME,等到返回到用户模式时直接就从LdrInitializeThunk处开始执行。

LdrInitializeThunk执行完成后需要进入内核(通过NtContinue),重新进入到线程的用户态执行入口。由于在XP中是通过APC进入的,所以这个工作就不用LdrInitializeThunk来做,APC的执行器ntdll!KiUserApcDispatcher会负责这件事。但在Win7上并非通过APC执行的,所以调用NtContinue的工作需要LdrInitializeThunk自己来完成了。
Win7: 

最后说一下,经常见到在LoadImageNotify回调中做(用户态)APC注入。由图可见exe&ntdll的回调通知和后面加载的dll回调通知执行的路径不一样。最开始这两个模块是在DbgkCreateThread中执行回调的,后面的是通过MmMapViewOfSection-->MiMapViewOfImageSection执行的回调。而MmMapViewOfSection在回调执行之前会通过LOCK_ADDRESS_SPACE进行进程地址空间的锁定。这个时候再进行(用户态)APC注入,在使用ZwAllocateVirtualMemory分配shellcode的内存空间时会卡死在这里。所以(用户态)APC注入的时机是在ntdll的回调中,这之后就会面临卡死的问题。

一张图系列——从CreateProcess到main函数的过程的更多相关文章

  1. 一张图系列——为什么在DllMain里面创建了线程并Wait会卡死

    这是一个老话题了,推荐一篇文章: http://blog.csdn.net/breaksoftware/article/details/8150476#0-tsina-1-83826-39723281 ...

  2. Linux下main函数启动过程【程序员自我修养笔记】【自用】

    1. 入口函数和程序初始化 1.1 程序从main开始吗? 当程序执行到main函数的第一行时,很多事情都已经完成了: [证1]如下是一段C语言代码: 代码中可以看到,在程序刚刚执行到main的时候, ...

  3. .Net程序员学用Oracle系列(7):视图、函数、过程、包

    <.Net程序员学用Oracle系列:导航目录> 本文大纲 1.视图 1.1.创建视图 2.函数 2.1.创建函数 2.2.调用函数 3.过程 3.1.创建过程 3.2.调用过程 4.包 ...

  4. linux编程之main()函数启动过程【转】

    转自:http://blog.csdn.net/gary_ygl/article/details/8506007 1 最简单的程序  1)编辑helloworld程序,$vim helloworld. ...

  5. 精华!一张图进阶 RocketMQ

    前 言 大家好,我是三此君,一个在自我救赎之路上的非典型程序员. "一张图"系列旨在通过"一张图"系统性的解析一个板块的知识点: 三此君向来不喜欢零零散散的知识 ...

  6. Nginx源码分析:3张图看懂启动及进程工作原理

    编者按:高可用架构分享及传播在架构领域具有典型意义的文章,本文由陈科在高可用架构群分享.转载请注明来自高可用架构公众号「ArchNotes」.   导读:很多工程师及架构师都希望了解及掌握高性能服务器 ...

  7. 深入理解javascript作用域系列第五篇——一张图理解执行环境和作用域

    × 目录 [1]图示 [2]概念 [3]说明[4]总结 前面的话 对于执行环境(execution context)和作用域(scope)并不容易区分,甚至很多人认为它们就是一回事,只是高程和犀牛书关 ...

  8. 一张图进阶 RocketMQ - 整体架构

    前 言 三此君看了好几本书,看了很多遍源码整理的 一张图进阶 RocketMQ 图片链接,关于 RocketMQ 你只需要记住这张图!如果你第一次看到这个系列,墙裂建议你打开链接.觉得不错的话,记得点 ...

  9. 一张图进阶 RocketMQ - 消息发送

    前 言 三此君看了好几本书,看了很多遍源码整理的 一张图进阶 RocketMQ 图片链接,关于 RocketMQ 你只需要记住这张图!觉得不错的话,记得点赞关注哦. [重要]视频在 B 站同步更新,欢 ...

随机推荐

  1. 第三方提权之serv-u提权

    文章比较简单,只是做一个科普.给一个好朋友的. 倘若口令更改了大家可以去serv-u的目录(默认路径:C:\Program Files\Serv-U\)找其配置文件(ServUDaemon.ini), ...

  2. Git的用法

    Git的用法 Git 的也可以理解为版本控制器.版本控制器(维基的解释):维护工程蓝图的标准作法,能追踪工程蓝图从诞生一直到定案的过程.此外,版本控制也是一种软件工程技巧,借此能在软件开发的过程中,确 ...

  3. win7系统下的飞秋发送文件失败问题

    飞秋发送文件失败这个问题大多数是由防火墙引起的1.检查windows自带的防火墙设置,在左侧的"允许程序通过windows防火墙"查看飞秋是否存在,不存在则增加之,公网.专网都勾选 ...

  4. HTML页面如何判断是手机访问还是电脑访问

    可以通过js来判断访问设备,代码如下: <script type="text/javascript"> var system ={}; var p = navigato ...

  5. c++顺序表基本功能

    头文件 #define LIST_MAX_SIZE 5#define LISTINCREMENT 2#include<assert.h>#include<string>temp ...

  6. 常用的java正则表达式

    常用的正则表达式主要有以下几种: 匹配中文字符的正则表达式: [\u4e00-\u9fa5] 评注:匹配中文还真是个头疼的事,有了这个表达式就好办了哦 获取日期正则表达式:\d{4}[年|\-|\.] ...

  7. Best code水题之路

    BestCoder 2nd Anniversary: 1001.Oracle There is once a king and queen, rulers of an unnamed city, wh ...

  8. ffmpeg 常用命令

    mp4中的h264编码,而h264有两种封装: 一种是annexb模式,传统模式,有startcode,SPS和PPS是在ES中:另一种是mp4模式,一般mp4.mkv.avi会没有startcode ...

  9. 2. Add Two Numbers——Python

    题目: You are given two linked lists representing two non-negative numbers. The digits are stored in r ...

  10. 解决Maven项目pom.xml文件报xxx\target\classes\META-INF\MANIFEST.MF (系统找不到指定的路径。)问题

    最近自己在公司项目修改一些代码以后,出现如题的错误,后来各种Google等,最终找到了解决办法. 错误环境:Tomcat7 + Eclipse + Maven + Spring + SpringMvc ...