如何快速判断我拥有的EXE或DLL是否为托管代码?

我最近花了一些时间试图反汇编文件,后来又通过代码中的一些跟踪了解跳过所有工作,仅使用ILspy。我如何避免将来重复这种经历?

#1 楼


托管DLL /应用程序将主要依赖MSCOREE.dll ...因此,如果在Dependency Walker中打开DLL,则从非托管库中告诉托管库没有问题。

    http://www.dependencywalker.com/



这里引用了

以及其他有用的链接:msdn; msdn2

评论


查看百老汇和彼得·弗里的答案。检查mscoree.dll依赖关系有些可靠,但不是100%。

–达斯塔
13年4月8日在22:01

为了确认,我将PoC导入mscoree.dll,甚至具有伪造的.NET外观EntryPoint,但没有.COM目录。

–天使
13年4月10日在8:26

这不是一个很有建设性的评论。我只是想证明,对于此问题,COM目录比导入或EntryPoint更可靠。

–天使
13年4月13日在5:23

#2 楼

检查PE标头中偏移0xE8(32位)或0xF8(64位)处的双字。如果非零,则它是指向CLR标头的指针。那是一个托管文件(您不能在其中放置随机数据,因为XP和更高版本内置了直接的.NET解析支持,因此如果数据无效,则不会加载该文件)。仅凭mscoree.dll的存在是不够的,因为该应用程序可能正在使用托管文件来做事,但不能对其本身进行托管。

评论


这个答案值得最高的帐单。除了您的大脑和对PE标头的了解之外,您无需任何其他工具即可获得答案。

–avgvstvs
2014年4月1日23:00

偏移量可以不同,具体取决于它是PE32还是PE32 +。

– Karsten Hahn
2014年5月14日晚上8:39

@Veitch,我终于编辑了答案以包括该答案。

–彼得·弗里
2014年5月14日15:47

仅供参考,这等效于@broadway的答案和Karsten Hahn的答案:偏移量0xe8或0xf8是IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR的虚拟地址。

–点
4月2日下午16:47

@pts有一个显着的区别:使用#define意味着32位程序只能识别32位程序,而64位程序只能识别64位。这就是为什么我建议使用硬编码值的原因。

–彼得·弗里
4月9日下午3:48

#3 楼

检查PE标头的数据目录部分中的DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress是否为非零值可能是最快的方法。

#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor

参考文献:


IMAGE_DATA_DIRECTORY结构
.NET程序集的剖析– PE标头


评论


这是我使用的方法。数据目录数组的第14个成员是IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR,因为该帖子未列出。我们应该避免像这样的绝对引用。

–达斯塔
13年4月7日在1:03

但是,十六进制编辑器没有数据目录的概念,因此没有绝对偏移量。

–彼得·弗里
2013年4月7日23:57

确实取决于十六进制编辑器。 010有PE模板。

–百老汇
13年4月9日在18:49

#4 楼

手动地,我更喜欢观察PE标头中的以下符号:

1-导入表中存在mscoree!_CorExeMain。

2- VirtualAddress和CLR的大小标头/ * Com描述符*数据目录已设置。大小设置为0x48。

3-基本重定位数据目录的大小设置为0x0C,即仅一个固定。

此外,一个小符号是:

4- SectionAlignment设置为0x2000。

#5 楼

尝试先在ILSpy中打开它。它应该告诉您是否未管理程序集。

评论


这意味着ILSpy能够打开它,但情况并非总是如此。

–天使
13年4月10日在19:32

如果未管理程序集,则ILSpy会显示一条特定消息。如果由于其他原因无法加载,我确定会有不同的消息:)您能告诉我一个ILSpy说不被管理的托管程序集吗?

–彼得·安德森(Peter Andersson)
13年4月10日在19:39

如果无法加载PE(是否使用托管代码),则会出现Mono.Cecil.PE.ImageReader错误。 TinyNet正在使用常见的恶意软件技巧,即使用小型NumOfRVA隐藏其COM目录-ILSpy失败-即使它使用的是托管代码。

–天使
13年4月10日在19:47

#6 楼

到目前为止,我发现的最快的启发式方法是检查它是否导入mscoree.dll。在mscoree.dll的版本资源中,Microsoft称之为:Microsoft .NET Runtime Execution Engine。

评论


不,这将不起作用,因为许多其他可执行文件也从非托管程序集的mscoree.dll导入。

–阿贝尔
2013年12月19日15:05

#7 楼

除了彼得渡轮的答案外,还有一些python代码可以检查相同内容:


import sys

def unpack(byte):
    return sum([
        ord(b) << (8 * i) for i, b in enumerate(byte)
    ])

if len(sys.argv) == 1:
    print >> sys.stderr, "No input file given!"
else:
    myfile = sys.argv[1]

    with open(myfile, "r") as f:
        f.seek(0x3c)
        peoffset = unpack(f.read(2))
        optoffset = peoffset + 24
        f.seek(optoffset)
        magic = f.read(2)
        offset = -1
        if magic == '\x0b\x01':
            offset = 208 + optoffset
        else:
            offset = 224 + optoffset
        f.seek(offset)
        clr_address = unpack(f.read(4))
        if clr_address == 0:
            print "no managed executable"
        else:
            print "managed executable"


#8 楼

CorFlags.exe是Windows SDK附带的实用程序。执行该过程,输入有问题的文件的名称,如果它是托管文件,它将告诉您它使用的是什么版本的Dotnet框架,以及该文件是全部托管代码还是混合模式,是否经过签名以及其他一些信息其他有用的信息。