注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

mie

 
 
 

日志

 
 

Windows的进程创建机制、dll的加载、ring0 dll注入问题探讨  

2011-10-07 00:03:08|  分类: sr |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

    由于Windows此前的32位版本的某些参数没有考虑到扩展性,所以,虽然64位系统发布,但是某些目录和文件名称依然沿用了32位的命名,比如kernel32.dll和system32。而仅仅在Program Files等目录中,对于32位,采用Program Files(x86)之类的命名。注意:64位系统中,system32里面的可不是32位的库,而是64位的!而\Windows\SysWOW64目录里面的也不是64位的dll,而是32位的!

    Win32中,一般的应用程序至少引用ntdll.dll库,大部分应用程序必需引用kernel32.dll。在Vista/Win7中,这个有所改变,所有的应用程序至少引用ntdll.dll,而大部分应用程序引用kernelbase.dll,而kernel32.dll还是作为大部分程序引用的组件,但是kernel32.dll不再是直接引用ntdll.dll,而是引用kernelbase.dll,kernelbase.dll再引用ntdll.dll。即:

Win 2k/xp/2k3:exe——》kernel32.dll——》ntdll.dll

Win Vista/7/2008/8:exe——》kernel32.dll——》kernelbase.dll——》ntdll.dll

    Windows的进程创建机制。大致是:

父进程:CreateProcess——》NtCreateProcess——》返回

NtCreateProcess中,首先,建立EPROCESS、KPROCESS(事实上是EPROCESS的子集)、PEB(进程环境块)、进程地址空间、工作集等;其次,创建一个新的线程执行体(ETHREAD)、KTHREAD(事实上是ETHREAD的子集)、TEB(线程环境块)、线程上下文、栈区等。

    至此,新进程就基本上创建成功了。当然了,上面的CreateProcess还得通知csrss子系统进程,告知新进程创建。此时,新进程随时准备运行。

 

    CPU轮转,从而新进程的主线程获得到CPU控制权,主线程开始了一系列初始化操作。

 

    于是,问题来了。初始化的dll加载是在哪儿完成的?对此,各种说法不一。不少人认为,主线程首先进入LdrInitializeThunk函数,LdrInitializeThunk完成所有dll的初始化加载。而也有人这么说,主线程的入口是BaseProcessStart,BaseProcessStart随后调用LdrInitializeThunk来完成dll的初始化加载。

    那么,这种说法本身就自相矛盾了。因为BaseProcessStart是kernel32.dll里面的,而LdrInitializeThunk是ntdll.dll里面的,如果两个dll还没有加载,那又怎么调用他们的函数呢?

    还有一种观点,即,ntdll.dll的加载和其他dll的加载不同,其他dll都是通过ntdll.dll里面的LdrInitializeThunk来完成dll的初始化加载。我认为这种观点应该是正确的。

 

    下面来通过代码获得这个问题的正确答案。
 BOOL bret=FALSE;
 STARTUPINFO StartupInfo={0};
 StartupInfo.cb=sizeof(StartupInfo);
 PROCESS_INFORMATION ProcessInformation={0};
 bret=CreateProcess(
  _T("C:\\Windows\\notepad.exe"),
  NULL,
  NULL,
  NULL,
  TRUE,
  CREATE_SUSPENDED,
  NULL,
  NULL,
  &StartupInfo,
  &ProcessInformation
  );
 ASSERT(bret);

    我们创建一个记事本进程,这个进程处于挂起状态。所以,主线程无法得以运行,所以,我们可以看到CreateProcess之后的进程的完整的状态。此时,进程模块中只有ntdll.dll。

 

    故此,得出进程创建后的dll加载的结论。CreateProcess完成ntdll.dll的加载,而新进程的主线程则依次完成其他dll的加载,然后,进入到应用程序的主入口点。    

 

By:章永辉

  评论这张
 
阅读(2309)| 评论(7)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016