吾爱汇编

 找回密码
 立即注册

QQ登录

绑定QQ避免忘记帐号

查看: 1872|回复: 3

[易语言] 【原创文章】浅析MSIL中间语言——基础篇

[复制链接]
BattleHeart 发表于 2014-10-24 20:35 | 显示全部楼层 |阅读模式

本帖最后由 BattleHeart 于 2014-10-24 20:58 编辑

浅析MSIL中间语言——基础篇                 
一、开篇
  研究MSIL纯属于个人喜好,说在前面MSIL应用于开发的地方很少,但是很大程度上能够帮着我们理解底层的原理,这是我了解MSIL的主要原因。托管代码表示应用程序的方法的功能,它们以微软的中间语言(Microsoft intermediate language,MSIL)或公共语言运行(common intermediate language,CIL)的抽象二进制形式进行编码。
  MSIL代码由CLR“托管”。CLR托管至少包括三个主要的活动:类型控制,结构化异常和垃圾收集。类型控制设计在执行期间项类型的验证和转换。托管异常处理在功能上与“非托管的”结构化异常处理类似,但它是由CLR执行的而不是有操作系统执行的。垃圾收集涉及对不再使用的对象进行自动标识和释放。
  在CLR环境下,.NET应用程序由一个或多个托管可执行体组成,其中每一个都携带着源数据和托管代码。托管的可执行体成为模块,主要包括两个组件:元数据和MSIL代码。CLR处理这两个组件的主要子系统是加载程序(Loader)和JIT(Just-in-time,即时)编译器。
  接下来我们主要讲的是托管可执行体里面的MSIL(中间语言),再讲MSIL时,先把微软的整个框架体系简单概括下:(见下图一)
171716236298232.jpg          

     简要概述下整个过程,首先是我们编写的C#源文件hello.cs通过C#编译器进行编译,编译成.NET 的PE文件结构,也就是exe文件格式,当程序运行时,Windows的Loader加载器不会负责该程序的内存分配,线程管理等工作,而是只负责跳转到CLR的执行引擎(EE)中,将控制权交由CLR,由CLR进行分配内存,线程管理,异常处理等。
  通过查看.NET 的PE文件导入表中只有一个API,exe对应mscoree.dll的_CorExeMain;而dll对应mscoree.dll的_CorDllMain。这就说明windows的loader加载器载入.NET PE后,只负责跳转到相应的DLL,随后改程序边运行在EE的监管中。查看导入表如下图所示:
171718161148129.jpg

二、初探MSIL
  我觉得学习每一项知识时,一些技巧性的东西是靠一步一步去积累的,但是我认为底层的探索也是学习当中必不可缺的一部分。有些时候底层的知识可以呈现出原理性的东西,越接近底层的知识就越靠近实现部分,好了废话也不多说接下来我们就来探讨MSIL中间语言,MSIL中间语言是基于堆栈的面向对象语言。
  借助一个简单的例子进行分析MSIL中间语言,每个编程技术人员都是从Hello World开始那我们也从Hello World开始。 
  1. 1 class Program
  2. 2  {
  3. 3         static void Main(string[] args)
  4. 4        {
  5. 5               string hello = "Hello World";
  6. 6               Console.WriteLine(hello);
  7. 7               Console.Read();
  8. 8        }
  9. 9   }
复制代码
输出结果很明显是:Hello World,如下图所示:
   171721505827816.jpg
  接下来我们将要分析该程序的MSIL代码,通过ILDASM.EXE工具将exe文件进行反编译成MSIL中间语言。如下图所示:
171723084897218.jpg
  简要概述:
  关键字:.method表示方法的意思,.method private hidebysig static void  Main(string[] args) cil managed表示的意思就是static void main(string[] args)
  .entrypoint标志方法的入口
  .maxstack表示分配堆栈大小
  .locals init中存放的是当前方法的局部变量,这里面是string类型,它的名称叫hello。Init指令表示对变量应以对应的类型默认值进行初始化,通常情况下变量名可以省略,在代码中将以零基索引来引用
  例如:stloc.0表示将Envaluation Stack中的一个栈顶数值保存到局部变量0(Call Stack)中。
  先介绍几个关于MSIL内部知识点:
  ①.Managed Heap:这是动态配置(Dynamic Allocation)的记忆体,由 Garbage Collector(GC)在执行时自动管理,整个 Process 共用一个 Managed Heap,可以理解为引用类型的东西都放在这个Managed Heap中。
  ②.Call Stack:这是由 .NET CLR 在执行时自动管理的记忆体,每个Thread都有自己的Call Stack堆栈。每调用一次method,就会使得Call Stack上多了一个Record Frame;调用完毕之后,此Record Frame会被丢弃。一般来说,Record Frame内记录着method参数(Parameter)、返回位址(Return Address)、以及局部变量(Local Variable)。.NET CLR都是使用0, 1, 2…编号的方式来识别局部变量。
  ③.Evaluation Stack:这是由.NET CLR在执行时自动管理的记忆体,每个Thread都有自己专属的Evaluation Stack。压入的到Evaluation Stack的值,当方法调用结束时必须保持这个堆栈的平衡,这里面存放例如局部变量值,以及引用类型的地址。
  指令ldc是将参数存储至堆栈Evaluation Stack
  指令stloc是将变量存储至堆栈Call Stack
  技巧:ld开头就是加载数据到Evaluation Stack中,而st开头就是将Envaluation Stack中的数据保存到Call StackCall Stack存放局部变量值。
  接下来我们将演示代码的堆栈情况。
  首先进入的是IL_0000段的代码为nop,这段代码表明了没有任何操作。
   181507584571344.jpg
  接下来就要到了IL_0001段代码为ldstr “hello World”,ldstr加载字符串是将字符串的引用放在了Envaluation Stack中,而真正的字符串放在了Managed Heap中,详情请见下图:
   181508506144812.jpg
  接下来就要运行到了stloc.0这条指令的意思就是讲参数保存到局部变量中。
   181509470048740.jpg
  将Envaluation Stack中的值保存到 Call Stack中,因为Envaluation Stack中存放的是“hello World”字符串的地址,所以V0存放的也是字符串的地址。
接下来要运行到了ldloc.0加载到Envaluation Stack中局部变量0的地址。
181510424261039.jpg

  接下来运行MSIL的call语句,从 Evaluation Stack 中取出一个值,此值为 Reference Type,调用 mscorlib.dll 所提供的 System.Console::WriteLine(string),注意这里用的call,因为这个是静态方法(static method),而不能用CallVirt方法。结构图如下所示:
181512014895425.jpg
  接下来就要调用静态方法System.Console::Read()等待用户输入之后,将输入值放入到Envaluation中去,最后再用pop指令将数值从Envaluation Stack中弹出来,最后就到达了ret这个地方,此指令的意思是:结束此次调用(也就是 Main 的调用)。此时会检查 Evaluation Stack 内剩下的资料,由于 Main() 告知不需要传出值(void),所以 Evaluation Stack 内必须是空的,本范例符合这样的情况,所以此时可以顺利结束此次调用。而 Main 的调用一结束,程序也随之结束。
三、结束语
  通过这篇文章可以清晰的了解MSIL中间语言的运行机制,是基于堆栈的形式操作。再次声明学习MSIL只是由于个人兴趣,希望各位能够提出宝贵的意见以及上述有错的地方能够指正,小丁虚心求教。
  方便大家阅读将文档放入百度网盘中共享,地址如下所示:
  链接: http://pan.baidu.com/s/1c0GhVck 密码: gj5m


本文内容皆为原创(转载请注明出处)










评分

参与人数 11威望 +1 HB +25 THX +5 收起 理由
29590 + 1
消逝的过去 + 1
zxjzzh + 2 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
agan8888 + 1
ldljlzw + 1
EMT + 1 + 1
ding520 + 1 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
小柯师傅 + 1 + 1 太好了,这个为什么没有人顶呢
tony2526 + 2 + 1 评分=感恩!简单却充满爱!感谢您的作品!
Shark恒 + 1 + 10 + 1 你将受到所有人的崇拜!这才叫图文教程!
能隐能显 + 5 积极评分从我做起,感谢!

查看全部评分

吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
能隐能显 发表于 2014-10-24 23:15 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
Shark恒 发表于 2014-10-25 00:09 | 显示全部楼层

这才叫图文教程,太详细了!
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
tony2526 发表于 2015-6-15 15:43 | 显示全部楼层

楼主的教程写的好详细,并且感觉大部分论坛会员IL语言方面都很薄弱,并且网上教程也不是太多,Net程序就不敢轻易入手
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

警告:本站严惩灌水回复,尊重自己从尊重他人开始!

1层
2层
3层
4层

免责声明

吾爱汇编(www.52hb.com)所讨论的技术及相关工具仅限用于研究学习,皆在提高软件产品的安全性,严禁用于不良动机。任何个人、团体、组织不得将其用于非法目的,否则,一切后果自行承担。吾爱汇编不承担任何因为技术滥用所产生的连带责任。吾爱汇编内容源于网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除。如有侵权请邮件或微信与我们联系处理。

站长邮箱:SharkHeng@sina.com
站长QQ:1140549900


QQ|RSS|手机版|小黑屋|帮助|吾爱汇编 ( 京公网安备11011502005403号 , 京ICP备20003498号-6 )|网站地图

Powered by Discuz!

吾爱汇编 www.52hb.com

快速回复 返回顶部 返回列表