Polishing the file type stuff, and adding a test or two, for prosperity.

This commit is contained in:
Ian A.Mason 2020-11-01 10:49:22 -08:00
parent beca29f43d
commit 4f6a8f5d57
2 changed files with 93 additions and 5 deletions

View File

@ -42,7 +42,7 @@ import (
"strings"
)
//BinaryType is the 'intersection' of elf.Type and macho.Type and partitions
// BinaryType is the 'intersection' of elf.Type and macho.Type and partitions
// the binary world into categories we are most interested in. Missing is
// ARCHIVE but that is because it is not an elf format, so we cannot entirely
// eliminate the use of the 'file' utility (cf getFileType below).
@ -59,6 +59,49 @@ const (
BinaryShared BinaryType = 3
)
func (bt BinaryType) String() string {
switch bt {
case BinaryUnknown:
return "Unknown"
case BinaryObject:
return "Object"
case BinaryExecutable:
return "Executable"
case BinaryShared:
return "Library"
default:
return "Error"
}
}
// GetBinaryType gets the binary type of the given path
func GetBinaryType(path string) (bt BinaryType) {
bt = BinaryUnknown
plain := IsPlainFile(path)
if !plain {
return
}
// try the format that suits the platform first
operatingSys := runtime.GOOS
switch operatingSys {
case "linux", "freebsd":
bt, _ = ElfFileType(path)
case "darwin":
bt, _ = MachoFileType(path)
}
if bt != BinaryUnknown {
return
}
// try the other format instead
switch operatingSys {
case "linux", "freebsd":
bt, _ = MachoFileType(path)
case "darwin":
bt, _ = ElfFileType(path)
}
return
}
func elfType2BinaryType(et elf.Type) (bt BinaryType) {
bt = BinaryUnknown
switch et {
@ -95,8 +138,8 @@ func machoType2BinaryType(mt macho.Type) (bt BinaryType) {
return
}
// isPlainFile returns true if the file is stat-able (i.e. exists etc), and is not a directory, else it returns false.
func isPlainFile(objectFile string) (ok bool) {
// IsPlainFile returns true if the file is stat-able (i.e. exists etc), and is not a directory, else it returns false.
func IsPlainFile(objectFile string) (ok bool) {
info, err := os.Stat(objectFile)
if os.IsNotExist(err) || info.IsDir() {
return
@ -109,7 +152,7 @@ func isPlainFile(objectFile string) (ok bool) {
}
func injectableViaFileType(objectFile string) (ok bool, err error) {
plain := isPlainFile(objectFile)
plain := IsPlainFile(objectFile)
if !plain {
return
}
@ -151,7 +194,7 @@ func MachoFileType(objectFile string) (code BinaryType, err error) {
//IsObjectFileForOS returns true if the given file is an object file for the given OS, using the debug/elf and debug/macho packages.
func IsObjectFileForOS(objectFile string, operatingSys string) (ok bool, err error) {
plain := isPlainFile(objectFile)
plain := IsPlainFile(objectFile)
if !plain {
return
}

View File

@ -100,3 +100,48 @@ func Test_obscure_functionality(t *testing.T) {
fmt.Println("Extraction OK")
}
}
func Test_file_type(t *testing.T) {
fictionalFile := "HopefullyThereIsNotAFileCalledThisNearBy.txt"
dataDir := "../data"
sourceFile := "../data/helloworld.c"
objectFile := "../data/bhello.notanextensionthatwerecognize"
exeFile := "../data/bhello"
fmt.Printf("GetBinaryType(%v) = %v\n", fictionalFile, shared.GetBinaryType(fictionalFile))
fmt.Printf("GetBinaryType(%v) = %v\n", dataDir, shared.GetBinaryType(dataDir))
fmt.Printf("GetBinaryType(%v) = %v\n", sourceFile, shared.GetBinaryType(sourceFile))
fmt.Printf("GetBinaryType(%v) = %v\n", objectFile, shared.GetBinaryType(objectFile))
fmt.Printf("GetBinaryType(%v) = %v\n", exeFile, shared.GetBinaryType(exeFile))
plain := shared.IsPlainFile(fictionalFile)
if plain {
t.Errorf("shared.IsPlainFile(%v) returned %v\n", fictionalFile, plain)
} else {
fmt.Printf("shared.IsPlainFile(%v) returned %v\n", fictionalFile, plain)
}
plain = shared.IsPlainFile(dataDir)
if plain {
t.Errorf("shared.IsPlainFile(%v) returned %v\n", dataDir, plain)
} else {
fmt.Printf("shared.IsPlainFile(%v) returned %v\n", dataDir, plain)
}
plain = shared.IsPlainFile(sourceFile)
if !plain {
t.Errorf("shared.IsPlainFile(%v) returned %v\n", sourceFile, plain)
} else {
fmt.Printf("shared.IsPlainFile(%v) returned %v\n", sourceFile, plain)
}
plain = shared.IsPlainFile(objectFile)
if !plain {
t.Errorf("shared.IsPlainFile(%v) returned %v\n", objectFile, plain)
} else {
fmt.Printf("shared.IsPlainFile(%v) returned %v\n", objectFile, plain)
}
plain = shared.IsPlainFile(exeFile)
if !plain {
t.Errorf("shared.IsPlainFile(%v) returned %v\n", exeFile, plain)
} else {
fmt.Printf("shared.IsPlainFile(%v) returned %v\n", exeFile, plain)
}
}