MCPcopy Create free account
hub / github.com/assetnote/hyoketsu / IsNETAssembly

Function IsNETAssembly

pe/pe.go:14–68  ·  view source on GitHub ↗

IsNETAssembly checks if a PE file is a .NET assembly by looking for a non-zero CLR Runtime Header data directory entry.

(path string)

Source from the content-addressed store, hash-verified

12// IsNETAssembly checks if a PE file is a .NET assembly by looking for a
13// non-zero CLR Runtime Header data directory entry.
14func IsNETAssembly(path string) (bool, error) {
15 f, err := os.Open(path)
16 if err != nil {
17 return false, err
18 }
19 defer f.Close()
20
21 buf := make([]byte, 512)
22 n, err := f.Read(buf)
23 if err != nil {
24 return false, fmt.Errorf("read PE header: %w", err)
25 }
26 buf = buf[:n]
27
28 if n < 2 || buf[0] != 'M' || buf[1] != 'Z' {
29 return false, nil
30 }
31 if n < 0x3C+4 {
32 return false, nil
33 }
34 peOffset := int(binary.LittleEndian.Uint32(buf[0x3C:]))
35
36 if peOffset+4 > n {
37 return false, nil
38 }
39 if buf[peOffset] != 'P' || buf[peOffset+1] != 'E' || buf[peOffset+2] != 0 || buf[peOffset+3] != 0 {
40 return false, nil
41 }
42
43 optHeaderOffset := peOffset + 4 + 20
44 if optHeaderOffset+2 > n {
45 return false, nil
46 }
47 magic := binary.LittleEndian.Uint16(buf[optHeaderOffset:])
48
49 var dataDirOffset int
50 switch magic {
51 case 0x10b: // PE32
52 dataDirOffset = optHeaderOffset + 96
53 case 0x20b: // PE32+
54 dataDirOffset = optHeaderOffset + 112
55 default:
56 return false, nil
57 }
58
59 clrEntryOffset := dataDirOffset + 14*8
60 if clrEntryOffset+8 > n {
61 return false, nil
62 }
63
64 rva := binary.LittleEndian.Uint32(buf[clrEntryOffset:])
65 size := binary.LittleEndian.Uint32(buf[clrEntryOffset+4:])
66
67 return rva != 0 && size != 0, nil
68}
69
70var microsoftTokens = map[string]bool{
71 "b77a5c561934e089": true, // ECMA key (System.*, mscorlib)

Callers 1

ScanFunction · 0.92

Calls 2

ReadMethod · 0.80
CloseMethod · 0.45

Tested by

no test coverage detected