diff --git a/internal/macapp/arch.go b/internal/macapp/arch.go index 4e85461..5d1c04f 100644 --- a/internal/macapp/arch.go +++ b/internal/macapp/arch.go @@ -1,22 +1,71 @@ package macapp -import "debug/macho" +import ( + "debug/macho" + "strings" +) -func resolveArch(arch macho.Cpu) string { - switch arch { +type Architectures struct { + Intel uint + Arm uint + PowerPC uint +} + +// Load loads the architectures from macho.Cpu +func (arch *Architectures) Load(cpu macho.Cpu) { + switch cpu { case macho.Cpu386: - return "Intel 32" + arch.Intel |= 0b01 case macho.CpuAmd64: - return "Intel 64" + arch.Intel |= 0b10 case macho.CpuArm: - return "Arm 32" + arch.Arm |= 0b01 case macho.CpuArm64: - return "Arm 64" + arch.Arm |= 0b10 case macho.CpuPpc: - return "PowerPC 32" + arch.PowerPC |= 0b01 case macho.CpuPpc64: - return "PowerPC 64" - default: + arch.PowerPC |= 0b10 + } +} + +// LoadFromFat loads the architectures from []macho.FatArch +func (arch *Architectures) LoadFromFat(src []macho.FatArch) { + for _, fat := range src { + arch.Load(fat.Cpu) + } +} + +// String returns the architecture in string format +func (arch *Architectures) String() string { + var list []string + + if arch.Intel > 0 { + list = append(list, "Intel "+getBitString(arch.Intel)) + } + if arch.Arm > 0 { + list = append(list, "Arm "+getBitString(arch.Arm)) + } + if arch.PowerPC > 0 { + list = append(list, "PowerPC "+getBitString(arch.PowerPC)) + } + + if len(list) > 0 { + return strings.Join(list, ", ") + } else { return "Unknown" } } + +func getBitString(mask uint) string { + switch mask { + case 0b11: + return "32/64" + case 0b01: + return "32" + case 0b10: + return "64" + default: + return "" + } +} diff --git a/internal/macapp/macapp.go b/internal/macapp/macapp.go index 6c175d9..fdeac9c 100644 --- a/internal/macapp/macapp.go +++ b/internal/macapp/macapp.go @@ -18,7 +18,7 @@ const ( type Application struct { Name string Path string - Architectures []string + Architectures Architectures } type executableDecoded struct { @@ -44,14 +44,10 @@ func (a *Application) GetExecutableName() (string, error) { return plistDecoded.CFBundleExecutable, err } -func (a *Application) GetArchitectures() ([]string, error) { - var ( - architectures []string - ) - +func (a *Application) GetArchitectures() (Architectures, error) { executable, err := a.GetExecutableName() if err != nil { - return nil, err + return a.Architectures, err } // binary file path @@ -60,21 +56,17 @@ func (a *Application) GetArchitectures() ([]string, error) { fat, err := macho.OpenFat(binary) if err == nil { // file is Mach-O universal - for _, arch := range fat.Arches { - architectures = append(architectures, resolveArch(arch.Cpu)) - } + a.Architectures.LoadFromFat(fat.Arches) } else { // file is Mach-O f, err := macho.Open(binary) if err != nil { - return nil, err + return a.Architectures, err } - - architectures = append(architectures, resolveArch(f.Cpu)) + a.Architectures.Load(f.Cpu) } - a.Architectures = architectures - return architectures, nil + return a.Architectures, nil } // GetAllApplications returns all applications diff --git a/internal/output/output.go b/internal/output/output.go index e60ab02..c6c8635 100644 --- a/internal/output/output.go +++ b/internal/output/output.go @@ -2,7 +2,6 @@ package output import ( "os" - "strings" "github.com/harryzcy/ascheck/internal/macapp" "github.com/olekukonko/tablewriter" @@ -14,7 +13,7 @@ func Table(apps []macapp.Application) { table.SetHeader([]string{"Name", "Architectures"}) for _, app := range apps { - table.Append([]string{app.Name, strings.Join(app.Architectures, ", ")}) + table.Append([]string{app.Name, app.Architectures.String()}) } table.Render()