c#和pe

起因

最近比较忙,下班之后有点堕落,也不想学习了,加上周末,忙着装修房子.还是切入正题.

在看mono源码的时候,一直在思考几个问题.
  1. c#生成的exe(可执行程序),和c/c++ native等语言生成的exe有什么区别?
  2. c#生成的exe,mono怎么可以直接执行呢?

说到这两点,就得说可执行程序(这里单说Windows),Windows下以exe为后缀名的程序,还有dll/ocx/sys等后缀的文件都是PE(Portable Executable)文件,Linux/Unix等系统的可执行程序的文件格式是ELF(Executable and Linkable Format),不管PE还是ELF都和COFF有很深的渊源.COFF最终被替代.

上面说到PE是种文件格式.c/c++等语言生成native的exe程序是PE.C#生成的exe是不是PE呢? 其实应该先写一篇关于PE的文章,只是学习了一半,所以没有介绍PE的结构.所以先用PE工具看看.

1. 带着c#程序是不是PE的疑问?

有好多查看PE的工具.可以在百度搜索PE工具,还有在看雪工具中有专门的PE工具.这里使用的是PETool 1.0.0.5.
测试c#代码为:

using System;
using System.Collections.Generic;
using System.Linq;

namespace qiufeng.tools
{
    static class Program
    {
        static void Main()
        {
            System.Windows.Forms.MessageBox.Show("Hello PE!");
        }
    }
}

因为代码比较简单,没有进行注释,分别用csc.exe 生成控制台程序和Windows程序(窗体程序)两种版本.

生成控制台程序命令:

csc.exe test.cs -out:csharp-console.exe

生成Windows程序命令:

csc.exe test.cs -out:csharp-gui.exe -target:winexe

接下来用PE工具打开C#的程序(只查看控制台程序).

用PE工具分析c#程序

没有说PE结构,很多没法细说.暂时跳过去.c#生成的exe程序通过PE工具可以进行查看并分析.可以得出c#的exe程序也是PE文件.

2. 来看一下c#程序与native程序的区别

大家都知道c#程序运行是需要CLR运行时的,但在Windows下,双击c#程序就可以运行,那和native程序有什么区别呢?
先看一下c语言的代码:
#include <windows.h>

int  main(int argc,char* argv[])
{
	MessageBox(NULL, TEXT("这是正文呢"), TEXT("这是标题"), 0);
	return 0;
}

生成程序之后,用WinDbg来分析一下运行过程.

c语言程序运行过程

系统内核(ntdll.dll)调用msvcrt.dll(c语言的运行时).
c#的执行过程:
c#的运行过程
c#的程序,由系统内核(ntdll.dll)调用mscoree.dll(Microsoft .NET Runtime Execution Engine),在百度百科上是这样介绍的:MSCOREE.DLL负责选择.NET版本、调用和初始化CLR等工作。非托管程序想要启动CLR也必须引用MSCOREE.DLL,利用它的导出函数加载托管代码和进行定制CLR等操作.
秋风 2018-08-22