转自:http://www.it165.net/pro/html/201404/12833.html
-
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)

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

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

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

ok,编译。。。你会发现编译速度很是慢长....。
然后看看我们的输出目录:
发现比正常的程序多了个[ilc.out]的目录,这个目录里面的程序就是本文的主角。

我们可以直接看到的差别就是 App1.exe 变的很小,5KB,而多了个App1.dll 7MB多;用CFF Explorer打开App1.exe:

查看其引入表:

发现
App1.exe只对App1.dll有引用,且只引用了App1.dll的导出函数RHBinder__ShimExeMain。
用IDA打开 App1.exe 找到入口函数可看到:

这句可以说明App1.exe是个stub,里面什么代码也没有,直接调用App1.dll的导出函数RHBinder__ShimExeMain。ok,我们直接用IDA打开App1.dll等待分析完毕(dll较大,分析并加载符号较慢):

我们可以看到App1.dll导出了下列函数:(其中就有)RHBinder__ShimExeMain
01.Name Address Ordinal02.---- ------- -------03.$thread_static_index 0000000000AD2DB0104.AppendExceptionStackFrame 000000000076E004205.CheckStaticClassConstruction0000000000765598306.CreateCommandLine 000000000076ABB8407.CtorCharArray 00000000007734A8508.CtorCharArrayStartLength0000000000773190609.CtorCharCount 0000000000772A28710.CtorCharPtr 0000000000772EC0811.CtorCharPtrStartLength 0000000000772C1C912.FailFast 0000000000768E1C1013.GetRuntimeException00000000007690841114.RHBinder__ShimExeMain 0000000000426CF01215.RHBinder__DllMain 0000000000426D24自然,RHBinder__ShimExeMain是此程序的入口点。
下面我们用 CFF Explorer 打开App1.dll:

看其引入表:

把对系统dll(api-ms*)的引用排除,剩下:
mrt100_app.dll
App1.dll
也就是其引用了自身导出的:
1.CtorCharArrayStartLength2.CreateCommandLine3.CtorCharPtrStartLength4.CtorCharPtr5.CtorCharCount6.CtorCharArray引用别的dll的函数并不奇怪,但为什么引用自身导出的函数而不是直接调用这个就比较奇怪了,他是怎么实现的呢?因为连接时这个dll并不存在,也就没有这个dll的导出,不知道怎么链接的,以后分析吧。
明显这个是一些支持函数,并不是主要的,主角看来在另一个dll(mrt100_app.dll)身上:
CFF Explorer 打开 mrt100_app.dll:

看见没 Microsoft .NET Native Runtime......
用vc工具 dumpbin /exports mrt100_app.dll 看其导出:
001.1Microsoft (R) COFF/PE Dumper Version11.00.61030.0002.2Copyright (C) Microsoft Corporation. All rights reserved.003.3004.4005.5Dump of file mrt100_app.dll006.6007.7File Type: DLL008.8009.9Section contains the following exportsformrt100.dll010.10011.1100000000characteristics012.12533689BD time date stamp Sat Mar2916:52:132014013.130.00version014.141ordinal base015.15277number of functions016.16277number of names017.17018.18ordinal hint RVA name019.19020.201000035DD8 GetRuntimeException021.212100036314ProcessFinalizers022.223200001EF8 RegisterCodeManager023.234300034DC0 RhBox024.245400036760RhCanUnloadModule025.2565000367C0 RhCollect026.267600002E00 RhEnableShutdownFinalization027.278700035E5C RhExceptionHandling_FailedAllocation028.2898000361B8 RhExceptionHandling_ThrowClasslibArithmeticException029.291090003622C RhExceptionHandling_ThrowClasslibDivideByZeroException030.3011A00036144RhExceptionHandling_ThrowClasslibIndexOutOfRangeException031.3112B 000362A0 RhExceptionHandling_ThrowClasslibOverflowException032.3213C 00035EDC RhExceptionHandling_ThrowInter033.3314D 000360D8 RhExceptionHandling_ThrowIntra034.3415E00003244RhFindBlob035.3516F00036498RhGcStress_Initialize036.36171000034C74 RhGetArrayElementType037.37181100034C3C RhGetComponentSize038.38191200034BA8 RhGetCorElementType039.39201300003808RhGetCurrentObjSize040.40211400034B5C RhGetEETypeClassification041.41221500034B0C RhGetEETypeHash042.42231600003BAC RhGetExceptionsForCurrentThread043.43241700003830RhGetGCNow044.44251800003618RhGetGcCollectionCount045.45261900003668RhGetGcLatencyMode046.46271A 000368D0 RhGetGcTotalMemory047.47281B 00002CBC RhGetGenericInstantiation048.48291C 00034C10 RhGetInterface049.49301D00003854RhGetLastGCDuration050.50311E 0000383C RhGetLastGCStartTime051.51321F00003114RhGetLoadedModules052.523320000037F8 RhGetLohCompactionMode053.53342100003610RhGetMaxGcGeneration054.54352200003EF0 RhGetModuleFileNameAndBaseFromIP055.553623000031A8 RhGetModuleFromEEType056.56372400034C40 RhGetNonArrayBaseType057.57382500034BBC RhGetNullableType058.58392600034C34 RhGetNumInterfaces059.594027000033E4 RhGetStaticFieldAddress060.604128000034C0 RhGetThreadStaticFieldAddress061.614229000030B0 RhGetValueTypeSize062.62432A00035144RhHandleAlloc063.63442B 000350C8 RhHandleAllocDependent064.64452C 0003504C RhHandleAllocVariable065.65462D 000045E8 RhHandleCompareExchangeVariableType066.66472E00004388RhHandleFree067.67482F 000043BC RhHandleGet068.684930000043C0 RhHandleGetDependent069.6950310000458C RhHandleGetVariableType070.705132000043FC RhHandleSet071.715233000043F4 RhHandleSetDependentSecondary072.725334000045A8 RhHandleSetVariableType073.73543500034BB0 RhHasReferenceFields074.74553600002E10 RhHasShutdownStarted075.75563700034BF4 RhIsArray076.76573800034BCC RhIsNullable077.775839000037E8 RhIsPromoted078.78593A00003680RhIsServerGc079.79603B 00034BDC RhIsString080.80613C 00034C04 RhIsValueType081.81623D 00034C88 RhMemberwiseClone082.82633E 00034EB4 RhNewArray083.83643F 00034FA8 RhNewObject084.84654000036870RhReRegisterForFinalize085.85664100003694RhRegisterGcCallout086.86674200004404RhRegisterRefCountedHandleCallback087.87684300035210RhRethrow088.886944000017E0 RhSetErrorInfoBuffer089.89704500003670RhSetGcLatencyMode090.90714600003800RhSetLohCompactionMode091.91724700002EFC RhSpinWait092.927348000035E8 RhSuppressFinalize093.93744900035CC4 RhThrowEx094.94754A 00035D1C RhThrowHwEx095.95764B00034908RhTypeCast_AreTypesAssignable096.96774C00034728RhTypeCast_AreTypesEquivalent097.97784D 000347D4 RhTypeCast_CheckArrayStore098.98794E00033914RhTypeCast_CheckCast099.99804F 000349F4 RhTypeCast_CheckCastArray100.100815000033ADC RhTypeCast_CheckCastClass101.1018251000344E0 RhTypeCast_CheckCastInterface102.102835200034A84 RhTypeCast_CheckUnbox103.103845300034738RhTypeCast_CheckVectorElemAddr104.104855400034688RhTypeCast_IsInstanceOf105.105865500034610RhTypeCast_IsInstanceOfArray106.106875600033B6C RhTypeCast_IsInstanceOfClass107.1078857000346C4 RhTypeCast_IsInstanceOfInterface108.108895800004D94 RhUnbox109.109905900003750RhUnregisterGcCallout110.110915A 000044B8 RhUnregisterRefCountedHandleCallback111.111925B00003600RhWaitForPendingFinalizers112.112935C 00002F0C RhYield113.113945D00036930RhpAssignRefEDX114.114955E 00036A30 RhpBulkWriteBarrier115.115965F 00036AD0 RhpCheckCctor116.116976000036960RhpCheckedAssignRefEDX117.1179861000369A0 RhpCheckedLockCmpXchg118.1189962000369F0 RhpCheckedXchg119.1191006300003E28 RhpClearThreadDoNotTriggerGC120.1201016400004FBC RhpDbl2IntOvf121.1211026500004FE4 RhpDbl2LngOvf122.1221036600005088RhpDbl2ULng123.123104670000500C RhpDbl2ULngOvf124.1241056800036B70 RhpDblRemRev125.1251066900036D10 RhpEHJumpByref126.1261076A 00036CF0 RhpEHJumpObject127.1271086B 00036CD0 RhpEHJumpScalar128.1281096C00005660RhpETWLogLiveCom129.1291106D00005828RhpETWShouldWalkCom130.1301116E 000351C0 RhpFailFastForPInvokeException131.1311126F 0000502C RhpFlt2IntOvf132.1321137000005058RhpFlt2LngOvf133.1331147100036B30 RhpFltRemRev134.1341157200036CB0 RhpGcPoll135.1351167300036CC0 RhpGcPollStress136.1361177400036F70 RhpGetThread137.1371187500037740RhpInitialInterfaceDispatch138.1381197600036F90 RhpInterfaceDispatch3139.1391207700037080RhpInterfaceDispatch36140.1401217800036FB0 RhpInterfaceDispatch4141.1411227900037170RhpInterfaceDispatch32142.1421237A 00036FD0 RhpInterfaceDispatch4143.1431247B00037360RhpInterfaceDispatch64144.1441257C00037010RhpInterfaceDispatch8145.1451267D 00036DD0 RhpLoopHijack146.1461277E 000379F0 RhpNewArray147.1471287F00037900RhpNewFast148.1481298000037940RhpNewFinalizable149.1491308100003FCC RhpPInvokeExceptionGuard150.1501318200005C2C RhpRegisterModule151.1511328300037870RhpResolveInterfaceMethod152.1521338400037CE0 RhpRethrow153.15313485000382B0 RhpReversePInvoke154.1541358600034D30 RhpReversePInvokeBadTransition155.1551368700038420RhpReversePInvokeReturn156.1561378800003E6C RhpSetThreadDoNotTriggerGC157.1571388900036A70 RhpShutdown158.1581398A 000063C4 RhpSuppressGcStress159.1591408B 00037BD0 RhpThrowEx160.1601418C00043968RhpTrapThreads161.1611428D 000063C4 RhpUnsuppressGcStress162.1621438E00038260RhpWaitForGC163.1631448F 000381D0 RhpWaitForSuspend164.1641459000001FBC UnregisterCodeManager165.1651469100038454_copysign166.166147920003845A _ecvt_s167.1671489300038460acos168.1681499400038466acosf169.169150950003846C asin170.1701519600038472asinf171.1711529700038478atan172.172153980003847E atan2173.1731549900038484atan2f174.1741559A 0003848A atanf175.1751569B00038490ceil176.1761579C00038496ceilf177.1771589D 0003849C copysign178.1781599E 000384A2 copysignf179.1791609F 000384A8 cos180.180161A0 000384AE cosf181.181162A1 000384B4 cosh182.182163A2 000384BA coshf183.183164A3 000384C0 exp184.184165A4 000384C6 expf185.185166A5 000384CC floor186.186167A6 000384D2 floorf187.187168A7 000384D8 fmod188.188169A8 000384DE fmodf189.189170A9 000384E4 log190.190171AA 000384EA log10191.191172AB 000384F0 log10f192.192173AC 000384F6 logf193.193174AD 000384FC memcmp194.194175AE00038502memcpy195.195176AF00038508memmove196.196177B0 0003850E memset197.197178B100038514modf198.198179B2 0003851A pow199.199180B300038520powf200.200181B400038526sin201.201182B5 0003852C sinf202.202183B600038532sinh203.203184B700038538sinhf204.204185B8 0003853E sqrt205.205186B900038544sqrtf206.206187BA 0003BA70 t119207.207188BB 0003ACD0 t13208.208189BC 0003ACE8 t2209.209190BD 0003649C t2.m0210.210191BE00036494t2.m1211.211192BF 0003B2A0 t27212.212193C0 0003B2C0 t28213.213194C1 0003AF78 t3214.214195C200036498t3.m0215.215196C3 000364A4 t3.m1216.216197C4 0003AD00 t32217.217198C5 0003AD78 t35218.218199C6 0003ADB8 t37219.219200C7 0003ADD8 t38220.220201C8 0003ADF8 t39221.221202C9 0003AE18 t40222.222203CA 0003AE30 t41223.223204CB 0003AE80 t44224.224205CC00043010t44static_data225.225206CD00043018t45static_data226.226207CE 000364A8 t5.m1227.227208CF 0003B3A0 t50228.228209D0 0003B450 t56229.229210D100036314t56.m0230.230211D2 0003ACA0 t6231.231212D3 0003B530 t67232.232213D4 0003B548 t68233.233214D500043020t70static_data234.234215D6 0003B5A0 t71235.235216D700036144t71.m10236.236217D8 000360D8 t71.m11237.237218D9 00035EDC t71.m12238.238219DA 00035E5C t71.m13239.239220DB 00035DD8 t71.m14240.240221DC 00035D1C t71.m15241.241222DD 00035CC4 t71.m16242.242223DE00035210t71.m17243.243224DF 000351C0 t71.m25244.244225E0 000362A0 t71.m7245.245226E1 0003622C t71.m8246.246227E2 000361B8 t71.m9247.247228E300043028t71static_data248.248229E400043000t71static_gcdata249.249230E5 0003AF10 t78250.250231E6 0003B6A0 t81251.251232E7 0003ACA8 t82252.252233E8 0003ACB0 t83253.253234E9 0003B6B8 t84254.254235EA 0003AF28 t87255.255236EB 0003B750 t90256.256237EC00035144t90.m0257.257238ED 000350C8 t90.m1258.258239EE 00034C3C t90.m10259.259240EF 00034C34 t90.m11260.260241F0 00034C10 t90.m12261.261242F1 00034C04 t90.m13262.262243F2 00034BF4 t90.m14263.263244F3 00034BDC t90.m15264.264245F4 00034BCC t90.m16265.265246F5 00034BBC t90.m17266.266247F6 00034BB0 t90.m18267.267248F7 00034BA8 t90.m19268.268249F8 0003504C t90.m2269.269250F9 00034B5C t90.m20270.270251FA 00034B0C t90.m21271.271252FB 00034FA8 t90.m3272.272253FC 00034EB4 t90.m4273.273254FD 00034DC0 t90.m5274.274255FE 00034D30 t90.m6275.275256FF 00034C88 t90.m7276.27625710000034C74 t90.m8277.27725810100034C40 t90.m9278.2782591020003B768 t91279.2792601030003B7E8 t95280.28026110400033B6C t95.m0281.28126210500033ADC t95.m1282.282263106000344E0 t95.m11283.283264107000347D4 t95.m12284.28426510800034738t95.m13285.28526610900034728t95.m15286.28626710A00034688t95.m17287.28726810B00033914t95.m18288.28826910C 00034A84 t95.m2289.28927010D00034610t95.m3290.29027110E 000349F4 t95.m4291.29127210F 000346C4 t95.m5292.29227311000034908t95.m9293.2932741110003854A tan294.29427511200038550tanf295.29527611300038556tanh296.2962771140003855C tanhf297.297298.298Summary299.299300.3006000.data301.3013000.pdata302.3029000.rdata303.3031000.reloc304.3041000.rsrc305.30539000.text306.3061000.tls
发现有些函数名称如 t71.m10 貌似是被混淆过呦~~
看其引入:
按照惯例排除(api-ms*)后仅剩下了个msvcr120_app.dll,这个是VC2012 Runtime里面的一个dll,相当于系统dll,就不多分析了。
回头看 App1.dll ,因为是个dll,所以他被加载后首先执行的是其入口点函数 RHBinder__DllMain,而 RHBinder__DllMain 里面没别的代码,仅仅直接调用了 RHBinder__DllProcessAttach:

我们看到其调用了几个类的静态构造函数 cctor.
当dll入口执行完毕后执行的是RHBinder__ShimExeMain


终于看见我们想要看的C#的入口函数$0_App1__Program_Main,很明显在AOT后AOT编译器给入口函数Main重命名了。
相应的托管代码在:C:UsersBinSysDesktopApp1App1objdDebugApp.g.i.cs
01.#if!DISABLE_XAML_GENERATED_MAIN02.publicstaticclassProgram03.{04.[global::System.CodeDom.Compiler.GeneratedCodeAttribute('Microsoft.Windows.UI.Xaml.Build.Tasks',' 4.0.0.0')]05.[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]06.staticvoidMain(string[] args)07.{08.global::Windows.UI.Xaml.Application.Start((p) =>newApp());09.}10.}11.#endif是新new 了个App1的对象:



每个托管代码看来都有对象的Native实现哦。
因篇幅所限,先到这里,这篇看的是表面张什么样,下篇看看他怎么实现的(编译系统用的是MSBUILD,下篇应该着重扒开.net native 的msbuild 部分)。
1639

被折叠的 条评论
为什么被折叠?



