Skip to content

Commit 4f6a8f5

Browse files
committed
Polishing the file type stuff, and adding a test or two, for prosperity.
1 parent beca29f commit 4f6a8f5

File tree

2 files changed

+93
-5
lines changed

2 files changed

+93
-5
lines changed

shared/filetypes.go

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import (
4242
"strings"
4343
)
4444

45-
//BinaryType is the 'intersection' of elf.Type and macho.Type and partitions
45+
// BinaryType is the 'intersection' of elf.Type and macho.Type and partitions
4646
// the binary world into categories we are most interested in. Missing is
4747
// ARCHIVE but that is because it is not an elf format, so we cannot entirely
4848
// eliminate the use of the 'file' utility (cf getFileType below).
@@ -59,6 +59,49 @@ const (
5959
BinaryShared BinaryType = 3
6060
)
6161

62+
func (bt BinaryType) String() string {
63+
switch bt {
64+
case BinaryUnknown:
65+
return "Unknown"
66+
case BinaryObject:
67+
return "Object"
68+
case BinaryExecutable:
69+
return "Executable"
70+
case BinaryShared:
71+
return "Library"
72+
default:
73+
return "Error"
74+
}
75+
}
76+
77+
// GetBinaryType gets the binary type of the given path
78+
func GetBinaryType(path string) (bt BinaryType) {
79+
bt = BinaryUnknown
80+
plain := IsPlainFile(path)
81+
if !plain {
82+
return
83+
}
84+
// try the format that suits the platform first
85+
operatingSys := runtime.GOOS
86+
switch operatingSys {
87+
case "linux", "freebsd":
88+
bt, _ = ElfFileType(path)
89+
case "darwin":
90+
bt, _ = MachoFileType(path)
91+
}
92+
if bt != BinaryUnknown {
93+
return
94+
}
95+
// try the other format instead
96+
switch operatingSys {
97+
case "linux", "freebsd":
98+
bt, _ = MachoFileType(path)
99+
case "darwin":
100+
bt, _ = ElfFileType(path)
101+
}
102+
return
103+
}
104+
62105
func elfType2BinaryType(et elf.Type) (bt BinaryType) {
63106
bt = BinaryUnknown
64107
switch et {
@@ -95,8 +138,8 @@ func machoType2BinaryType(mt macho.Type) (bt BinaryType) {
95138
return
96139
}
97140

98-
// isPlainFile returns true if the file is stat-able (i.e. exists etc), and is not a directory, else it returns false.
99-
func isPlainFile(objectFile string) (ok bool) {
141+
// IsPlainFile returns true if the file is stat-able (i.e. exists etc), and is not a directory, else it returns false.
142+
func IsPlainFile(objectFile string) (ok bool) {
100143
info, err := os.Stat(objectFile)
101144
if os.IsNotExist(err) || info.IsDir() {
102145
return
@@ -109,7 +152,7 @@ func isPlainFile(objectFile string) (ok bool) {
109152
}
110153

111154
func injectableViaFileType(objectFile string) (ok bool, err error) {
112-
plain := isPlainFile(objectFile)
155+
plain := IsPlainFile(objectFile)
113156
if !plain {
114157
return
115158
}
@@ -151,7 +194,7 @@ func MachoFileType(objectFile string) (code BinaryType, err error) {
151194

152195
//IsObjectFileForOS returns true if the given file is an object file for the given OS, using the debug/elf and debug/macho packages.
153196
func IsObjectFileForOS(objectFile string, operatingSys string) (ok bool, err error) {
154-
plain := isPlainFile(objectFile)
197+
plain := IsPlainFile(objectFile)
155198
if !plain {
156199
return
157200
}

tests/entry_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,48 @@ func Test_obscure_functionality(t *testing.T) {
100100
fmt.Println("Extraction OK")
101101
}
102102
}
103+
104+
func Test_file_type(t *testing.T) {
105+
fictionalFile := "HopefullyThereIsNotAFileCalledThisNearBy.txt"
106+
dataDir := "../data"
107+
sourceFile := "../data/helloworld.c"
108+
objectFile := "../data/bhello.notanextensionthatwerecognize"
109+
exeFile := "../data/bhello"
110+
fmt.Printf("GetBinaryType(%v) = %v\n", fictionalFile, shared.GetBinaryType(fictionalFile))
111+
fmt.Printf("GetBinaryType(%v) = %v\n", dataDir, shared.GetBinaryType(dataDir))
112+
fmt.Printf("GetBinaryType(%v) = %v\n", sourceFile, shared.GetBinaryType(sourceFile))
113+
fmt.Printf("GetBinaryType(%v) = %v\n", objectFile, shared.GetBinaryType(objectFile))
114+
fmt.Printf("GetBinaryType(%v) = %v\n", exeFile, shared.GetBinaryType(exeFile))
115+
116+
plain := shared.IsPlainFile(fictionalFile)
117+
if plain {
118+
t.Errorf("shared.IsPlainFile(%v) returned %v\n", fictionalFile, plain)
119+
} else {
120+
fmt.Printf("shared.IsPlainFile(%v) returned %v\n", fictionalFile, plain)
121+
}
122+
plain = shared.IsPlainFile(dataDir)
123+
if plain {
124+
t.Errorf("shared.IsPlainFile(%v) returned %v\n", dataDir, plain)
125+
} else {
126+
fmt.Printf("shared.IsPlainFile(%v) returned %v\n", dataDir, plain)
127+
}
128+
plain = shared.IsPlainFile(sourceFile)
129+
if !plain {
130+
t.Errorf("shared.IsPlainFile(%v) returned %v\n", sourceFile, plain)
131+
} else {
132+
fmt.Printf("shared.IsPlainFile(%v) returned %v\n", sourceFile, plain)
133+
}
134+
plain = shared.IsPlainFile(objectFile)
135+
if !plain {
136+
t.Errorf("shared.IsPlainFile(%v) returned %v\n", objectFile, plain)
137+
} else {
138+
fmt.Printf("shared.IsPlainFile(%v) returned %v\n", objectFile, plain)
139+
}
140+
plain = shared.IsPlainFile(exeFile)
141+
if !plain {
142+
t.Errorf("shared.IsPlainFile(%v) returned %v\n", exeFile, plain)
143+
} else {
144+
fmt.Printf("shared.IsPlainFile(%v) returned %v\n", exeFile, plain)
145+
}
146+
147+
}

0 commit comments

Comments
 (0)