首页 技术 正文
技术 2022年11月17日
0 收藏 880 点赞 3,715 浏览 10360 个字

Microsoft .NET Native Developer Preview 内部初探(1)

MS 前段时间发布了.NET Native Developer Preview,被广大人员赋予“C++的性能,.NET的生产力”之期望。我们暂时不管此技术现在是否有价值的讨论,先来谈谈下其内部实现。

研究环境:
为确保环境纯洁性,我搭建环境为 :
VMware-workstation-full-10.0.2-1744117
WIN 8.1 With update1 MSDN iso
VS2013 CHS + VS2013 UPDATE2 RC
netfx_NativeCompilation.msi(从http://msdn.microsoft.com/en-US/vstudio/dotnetnative下载)

准备研究:

安装完毕并启动VS2013,根据MSDN 的.NET Native 文档(http://msdn.microsoft.com/en-us/library/dn600165(v=vs.110).aspx)
我新建项目:
Visual C# -> 应用商店应用 -> Windows 应用程序 -> 网格应用程序(Windows)
Microsoft .NET Native Developer Preview 内部初探(1)
新建项目后开启Native 编译;

Microsoft .NET Native Developer Preview 内部初探(1)

然后在菜单 [生成] 里面 [活动解决方案平台] 选择 x64,(因为目前的版本仅支持X64和ARM平台);

Microsoft .NET Native Developer Preview 内部初探(1)

在 [项目] 菜单的 [生成] 选项卡里 [Compile with .NET Native tool chain] 上打对号;

Microsoft .NET Native Developer Preview 内部初探(1)

在 [项目] 菜单的 [调试] 选项卡里选中如下:

Microsoft .NET Native Developer Preview 内部初探(1)

ok,编译。。。你会发现编译速度很是慢长….。
然后看看我们的输出目录:

Microsoft .NET Native Developer Preview 内部初探(1)

发现比正常的程序多了个[ilc.out]的目录,这个目录里面的程序就是本文的主角。

Microsoft .NET Native Developer Preview 内部初探(1)
我们可以直接看到的差别就是 App1.exe 变的很小,5KB,而多了个App1.dll 7MB多;用CFF Explorer打开App1.exe:
Microsoft .NET Native Developer Preview 内部初探(1)
查看其引入表:
Microsoft .NET Native Developer Preview 内部初探(1)
发现
App1.exe只对App1.dll有引用,且只引用了App1.dll的导出函数RHBinder__ShimExeMain。
用IDA打开 App1.exe 找到入口函数可看到:
Microsoft .NET Native Developer Preview 内部初探(1)
这句可以说明App1.exe是个stub,里面什么代码也没有,直接调用App1.dll的导出函数RHBinder__ShimExeMain。

ok,我们直接用IDA打开App1.dll等待分析完毕(dll较大,分析并加载符号较慢):

Microsoft .NET Native Developer Preview 内部初探(1)

我们可以看到App1.dll导出了下列函数:(其中就有)RHBinder__ShimExeMain

Name                         Address          Ordinal
---- ------- -------
$thread_static_index 0000000000AD2DB0 1
AppendExceptionStackFrame 000000000076E004 2
CheckStaticClassConstruction 0000000000765598 3
CreateCommandLine 000000000076ABB8 4
CtorCharArray 00000000007734A8 5
CtorCharArrayStartLength 0000000000773190 6
CtorCharCount 0000000000772A28 7
CtorCharPtr 0000000000772EC0 8
CtorCharPtrStartLength 0000000000772C1C 9
FailFast 0000000000768E1C 10
GetRuntimeException 0000000000769084 11
RHBinder__ShimExeMain 0000000000426CF0 12
RHBinder__DllMain 0000000000426D24

自然,RHBinder__ShimExeMain是此程序的入口点。

下面我们用 CFF Explorer 打开App1.dll:

Microsoft .NET Native Developer Preview 内部初探(1)

看其引入表:

Microsoft .NET Native Developer Preview 内部初探(1)

把对系统dll(api-ms*)的引用排除,剩下:

mrt100_app.dll

App1.dll

也就是其引用了自身导出的:

CtorCharArrayStartLength
CreateCommandLine
CtorCharPtrStartLength
CtorCharPtr
CtorCharCount
CtorCharArray

引用别的dll的函数并不奇怪,但为什么引用自身导出的函数而不是直接调用这个就比较奇怪了,他是怎么实现的呢?因为连接时这个dll并不存在,也就没有这个dll的导出,不知道怎么链接的,以后分析吧。

明显这个是一些支持函数,并不是主要的,主角看来在另一个dll(mrt100_app.dll)身上:

CFF Explorer 打开 mrt100_app.dll:

Microsoft .NET Native Developer Preview 内部初探(1)

看见没 Microsoft .NET Native Runtime……

用vc工具 dumpbin /exports mrt100_app.dll 看其导出:

 Microsoft (R) COFF/PE Dumper Version 11.00.61030.0
Copyright (C) Microsoft Corporation. All rights reserved. Dump of file mrt100_app.dll File Type: DLL Section contains the following exports for mrt100.dll 00000000 characteristics
533689BD time date stamp Sat Mar 29 16:52:13 2014
0.00 version
1 ordinal base
277 number of functions
277 number of names ordinal hint RVA name 1 0 00035DD8 GetRuntimeException
2 1 00036314 ProcessFinalizers
3 2 00001EF8 RegisterCodeManager
4 3 00034DC0 RhBox
5 4 00036760 RhCanUnloadModule
6 5 000367C0 RhCollect
7 6 00002E00 RhEnableShutdownFinalization
8 7 00035E5C RhExceptionHandling_FailedAllocation
9 8 000361B8 RhExceptionHandling_ThrowClasslibArithmeticException
10 9 0003622C RhExceptionHandling_ThrowClasslibDivideByZeroException
11 A 00036144 RhExceptionHandling_ThrowClasslibIndexOutOfRangeException
12 B 000362A0 RhExceptionHandling_ThrowClasslibOverflowException
13 C 00035EDC RhExceptionHandling_ThrowInter
14 D 000360D8 RhExceptionHandling_ThrowIntra
15 E 00003244 RhFindBlob
16 F 00036498 RhGcStress_Initialize
17 10 00034C74 RhGetArrayElementType
18 11 00034C3C RhGetComponentSize
19 12 00034BA8 RhGetCorElementType
20 13 00003808 RhGetCurrentObjSize
21 14 00034B5C RhGetEETypeClassification
22 15 00034B0C RhGetEETypeHash
23 16 00003BAC RhGetExceptionsForCurrentThread
24 17 00003830 RhGetGCNow
25 18 00003618 RhGetGcCollectionCount
26 19 00003668 RhGetGcLatencyMode
27 1A 000368D0 RhGetGcTotalMemory
28 1B 00002CBC RhGetGenericInstantiation
29 1C 00034C10 RhGetInterface
30 1D 00003854 RhGetLastGCDuration
31 1E 0000383C RhGetLastGCStartTime
32 1F 00003114 RhGetLoadedModules
33 20 000037F8 RhGetLohCompactionMode
34 21 00003610 RhGetMaxGcGeneration
35 22 00003EF0 RhGetModuleFileNameAndBaseFromIP
36 23 000031A8 RhGetModuleFromEEType
37 24 00034C40 RhGetNonArrayBaseType
38 25 00034BBC RhGetNullableType
39 26 00034C34 RhGetNumInterfaces
40 27 000033E4 RhGetStaticFieldAddress
41 28 000034C0 RhGetThreadStaticFieldAddress
42 29 000030B0 RhGetValueTypeSize
43 2A 00035144 RhHandleAlloc
44 2B 000350C8 RhHandleAllocDependent
45 2C 0003504C RhHandleAllocVariable
46 2D 000045E8 RhHandleCompareExchangeVariableType
47 2E 00004388 RhHandleFree
48 2F 000043BC RhHandleGet
49 30 000043C0 RhHandleGetDependent
50 31 0000458C RhHandleGetVariableType
51 32 000043FC RhHandleSet
52 33 000043F4 RhHandleSetDependentSecondary
53 34 000045A8 RhHandleSetVariableType
54 35 00034BB0 RhHasReferenceFields
55 36 00002E10 RhHasShutdownStarted
56 37 00034BF4 RhIsArray
57 38 00034BCC RhIsNullable
58 39 000037E8 RhIsPromoted
59 3A 00003680 RhIsServerGc
60 3B 00034BDC RhIsString
61 3C 00034C04 RhIsValueType
62 3D 00034C88 RhMemberwiseClone
63 3E 00034EB4 RhNewArray
64 3F 00034FA8 RhNewObject
65 40 00036870 RhReRegisterForFinalize
66 41 00003694 RhRegisterGcCallout
67 42 00004404 RhRegisterRefCountedHandleCallback
68 43 00035210 RhRethrow
69 44 000017E0 RhSetErrorInfoBuffer
70 45 00003670 RhSetGcLatencyMode
71 46 00003800 RhSetLohCompactionMode
72 47 00002EFC RhSpinWait
73 48 000035E8 RhSuppressFinalize
74 49 00035CC4 RhThrowEx
75 4A 00035D1C RhThrowHwEx
76 4B 00034908 RhTypeCast_AreTypesAssignable
77 4C 00034728 RhTypeCast_AreTypesEquivalent
78 4D 000347D4 RhTypeCast_CheckArrayStore
79 4E 00033914 RhTypeCast_CheckCast
80 4F 000349F4 RhTypeCast_CheckCastArray
81 50 00033ADC RhTypeCast_CheckCastClass
82 51 000344E0 RhTypeCast_CheckCastInterface
83 52 00034A84 RhTypeCast_CheckUnbox
84 53 00034738 RhTypeCast_CheckVectorElemAddr
85 54 00034688 RhTypeCast_IsInstanceOf
86 55 00034610 RhTypeCast_IsInstanceOfArray
87 56 00033B6C RhTypeCast_IsInstanceOfClass
88 57 000346C4 RhTypeCast_IsInstanceOfInterface
89 58 00004D94 RhUnbox
90 59 00003750 RhUnregisterGcCallout
91 5A 000044B8 RhUnregisterRefCountedHandleCallback
92 5B 00003600 RhWaitForPendingFinalizers
93 5C 00002F0C RhYield
94 5D 00036930 RhpAssignRefEDX
95 5E 00036A30 RhpBulkWriteBarrier
96 5F 00036AD0 RhpCheckCctor
97 60 00036960 RhpCheckedAssignRefEDX
98 61 000369A0 RhpCheckedLockCmpXchg
99 62 000369F0 RhpCheckedXchg
100 63 00003E28 RhpClearThreadDoNotTriggerGC
101 64 00004FBC RhpDbl2IntOvf
102 65 00004FE4 RhpDbl2LngOvf
103 66 00005088 RhpDbl2ULng
104 67 0000500C RhpDbl2ULngOvf
105 68 00036B70 RhpDblRemRev
106 69 00036D10 RhpEHJumpByref
107 6A 00036CF0 RhpEHJumpObject
108 6B 00036CD0 RhpEHJumpScalar
109 6C 00005660 RhpETWLogLiveCom
110 6D 00005828 RhpETWShouldWalkCom
111 6E 000351C0 RhpFailFastForPInvokeException
112 6F 0000502C RhpFlt2IntOvf
113 70 00005058 RhpFlt2LngOvf
114 71 00036B30 RhpFltRemRev
115 72 00036CB0 RhpGcPoll
116 73 00036CC0 RhpGcPollStress
117 74 00036F70 RhpGetThread
118 75 00037740 RhpInitialInterfaceDispatch
119 76 00036F90 RhpInterfaceDispatch1
120 77 00037080 RhpInterfaceDispatch16
121 78 00036FB0 RhpInterfaceDispatch2
122 79 00037170 RhpInterfaceDispatch32
123 7A 00036FD0 RhpInterfaceDispatch4
124 7B 00037360 RhpInterfaceDispatch64
125 7C 00037010 RhpInterfaceDispatch8
126 7D 00036DD0 RhpLoopHijack
127 7E 000379F0 RhpNewArray
128 7F 00037900 RhpNewFast
129 80 00037940 RhpNewFinalizable
130 81 00003FCC RhpPInvokeExceptionGuard
131 82 00005C2C RhpRegisterModule
132 83 00037870 RhpResolveInterfaceMethod
133 84 00037CE0 RhpRethrow
134 85 000382B0 RhpReversePInvoke
135 86 00034D30 RhpReversePInvokeBadTransition
136 87 00038420 RhpReversePInvokeReturn
137 88 00003E6C RhpSetThreadDoNotTriggerGC
138 89 00036A70 RhpShutdown
139 8A 000063C4 RhpSuppressGcStress
140 8B 00037BD0 RhpThrowEx
141 8C 00043968 RhpTrapThreads
142 8D 000063C4 RhpUnsuppressGcStress
143 8E 00038260 RhpWaitForGC
144 8F 000381D0 RhpWaitForSuspend
145 90 00001FBC UnregisterCodeManager
146 91 00038454 _copysign
147 92 0003845A _ecvt_s
148 93 00038460 acos
149 94 00038466 acosf
150 95 0003846C asin
151 96 00038472 asinf
152 97 00038478 atan
153 98 0003847E atan2
154 99 00038484 atan2f
155 9A 0003848A atanf
156 9B 00038490 ceil
157 9C 00038496 ceilf
158 9D 0003849C copysign
159 9E 000384A2 copysignf
160 9F 000384A8 cos
161 A0 000384AE cosf
162 A1 000384B4 cosh
163 A2 000384BA coshf
164 A3 000384C0 exp
165 A4 000384C6 expf
166 A5 000384CC floor
167 A6 000384D2 floorf
168 A7 000384D8 fmod
169 A8 000384DE fmodf
170 A9 000384E4 log
171 AA 000384EA log10
172 AB 000384F0 log10f
173 AC 000384F6 logf
174 AD 000384FC memcmp
175 AE 00038502 memcpy
176 AF 00038508 memmove
177 B0 0003850E memset
178 B1 00038514 modf
179 B2 0003851A pow
180 B3 00038520 powf
181 B4 00038526 sin
182 B5 0003852C sinf
183 B6 00038532 sinh
184 B7 00038538 sinhf
185 B8 0003853E sqrt
186 B9 00038544 sqrtf
187 BA 0003BA70 t119
188 BB 0003ACD0 t13
189 BC 0003ACE8 t2
190 BD 0003649C t2.m0
191 BE 00036494 t2.m1
192 BF 0003B2A0 t27
193 C0 0003B2C0 t28
194 C1 0003AF78 t3
195 C2 00036498 t3.m0
196 C3 000364A4 t3.m1
197 C4 0003AD00 t32
198 C5 0003AD78 t35
199 C6 0003ADB8 t37
200 C7 0003ADD8 t38
201 C8 0003ADF8 t39
202 C9 0003AE18 t40
203 CA 0003AE30 t41
204 CB 0003AE80 t44
205 CC 00043010 t44static_data
206 CD 00043018 t45static_data
207 CE 000364A8 t5.m1
208 CF 0003B3A0 t50
209 D0 0003B450 t56
210 D1 00036314 t56.m0
211 D2 0003ACA0 t6
212 D3 0003B530 t67
213 D4 0003B548 t68
214 D5 00043020 t70static_data
215 D6 0003B5A0 t71
216 D7 00036144 t71.m10
217 D8 000360D8 t71.m11
218 D9 00035EDC t71.m12
219 DA 00035E5C t71.m13
220 DB 00035DD8 t71.m14
221 DC 00035D1C t71.m15
222 DD 00035CC4 t71.m16
223 DE 00035210 t71.m17
224 DF 000351C0 t71.m25
225 E0 000362A0 t71.m7
226 E1 0003622C t71.m8
227 E2 000361B8 t71.m9
228 E3 00043028 t71static_data
229 E4 00043000 t71static_gcdata
230 E5 0003AF10 t78
231 E6 0003B6A0 t81
232 E7 0003ACA8 t82
233 E8 0003ACB0 t83
234 E9 0003B6B8 t84
235 EA 0003AF28 t87
236 EB 0003B750 t90
237 EC 00035144 t90.m0
238 ED 000350C8 t90.m1
239 EE 00034C3C t90.m10
240 EF 00034C34 t90.m11
241 F0 00034C10 t90.m12
242 F1 00034C04 t90.m13
243 F2 00034BF4 t90.m14
244 F3 00034BDC t90.m15
245 F4 00034BCC t90.m16
246 F5 00034BBC t90.m17
247 F6 00034BB0 t90.m18
248 F7 00034BA8 t90.m19
249 F8 0003504C t90.m2
250 F9 00034B5C t90.m20
251 FA 00034B0C t90.m21
252 FB 00034FA8 t90.m3
253 FC 00034EB4 t90.m4
254 FD 00034DC0 t90.m5
255 FE 00034D30 t90.m6
256 FF 00034C88 t90.m7
257 100 00034C74 t90.m8
258 101 00034C40 t90.m9
259 102 0003B768 t91
260 103 0003B7E8 t95
261 104 00033B6C t95.m0
262 105 00033ADC t95.m1
263 106 000344E0 t95.m11
264 107 000347D4 t95.m12
265 108 00034738 t95.m13
266 109 00034728 t95.m15
267 10A 00034688 t95.m17
268 10B 00033914 t95.m18
269 10C 00034A84 t95.m2
270 10D 00034610 t95.m3
271 10E 000349F4 t95.m4
272 10F 000346C4 t95.m5
273 110 00034908 t95.m9
274 111 0003854A tan
275 112 00038550 tanf
276 113 00038556 tanh
277 114 0003855C tanhf Summary 6000 .data
3000 .pdata
9000 .rdata
1000 .reloc
1000 .rsrc
39000 .text
1000 .tls

发现有些函数名称如 t71.m10 貌似是被混淆过呦~~

看其引入:

按照惯例排除(api-ms*)后仅剩下了个msvcr120_app.dll,这个是VC2012 Runtime里面的一个dll,相当于系统dll,就不多分析了。

回头看 App1.dll ,因为是个dll,所以他被加载后首先执行的是其入口点函数 RHBinder__DllMain,而 RHBinder__DllMain 里面没别的代码,仅仅直接调用了 RHBinder__DllProcessAttach:

Microsoft .NET Native Developer Preview 内部初探(1)

我们看到其调用了几个类的静态构造函数 cctor.

当dll入口执行完毕后执行的是RHBinder__ShimExeMain

Microsoft .NET Native Developer Preview 内部初探(1)

Microsoft .NET Native Developer Preview 内部初探(1)

终于看见我们想要看的C#的入口函数$0_App1__Program_Main,很明显在AOT后AOT编译器给入口函数Main重命名了。

相应的托管代码在:C:\Users\BinSys\Desktop\App1\App1\obj\x64\Debug\App.g.i.cs

#if !DISABLE_XAML_GENERATED_MAIN
public static class Program
{
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
static void Main(string[] args)
{
global::Windows.UI.Xaml.Application.Start((p) => new App());
}
}
#endif

是新new 了个App1的对象:

Microsoft .NET Native Developer Preview 内部初探(1)

Microsoft .NET Native Developer Preview 内部初探(1)

Microsoft .NET Native Developer Preview 内部初探(1)

每个托管代码看来都有对象的Native实现哦。

因篇幅所限,先到这里,这篇看的是表面张什么样,下篇看看他怎么实现的(编译系统用的是MSBUILD,下篇应该着重扒开.net native 的msbuild 部分)。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,088
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,565
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,413
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,186
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,822
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,905