blob: 9946d34afe35f71ac4d9790b6d48711a9ed3b607 [file] [log] [blame]
Colin Cross5498f852018-01-03 23:39:54 -08001// Copyright 2018 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Dan Willemsen2249dc82018-10-15 00:35:59 -070015package symbol_inject
Colin Cross5498f852018-01-03 23:39:54 -080016
17import (
18 "debug/macho"
19 "fmt"
20 "io"
Yabin Cui7f5f22b2022-08-31 16:23:43 -070021 "os/exec"
Colin Crossc4a18e02018-02-23 22:43:24 -080022 "sort"
Colin Cross8673b5b2018-03-01 11:20:25 -080023 "strings"
Colin Cross5498f852018-01-03 23:39:54 -080024)
25
Colin Cross8673b5b2018-03-01 11:20:25 -080026func machoSymbolsFromFile(r io.ReaderAt) (*File, error) {
Colin Cross5498f852018-01-03 23:39:54 -080027 machoFile, err := macho.NewFile(r)
28 if err != nil {
Colin Cross8673b5b2018-03-01 11:20:25 -080029 return nil, cantParseError{err}
Colin Cross5498f852018-01-03 23:39:54 -080030 }
31
Colin Cross8673b5b2018-03-01 11:20:25 -080032 return extractMachoSymbols(machoFile)
33}
Colin Cross5498f852018-01-03 23:39:54 -080034
Colin Cross8673b5b2018-03-01 11:20:25 -080035func extractMachoSymbols(machoFile *macho.File) (*File, error) {
Colin Crossc4a18e02018-02-23 22:43:24 -080036 symbols := machoFile.Symtab.Syms
Colin Cross8673b5b2018-03-01 11:20:25 -080037 sort.SliceStable(symbols, func(i, j int) bool {
Colin Crossc4a18e02018-02-23 22:43:24 -080038 if symbols[i].Sect != symbols[j].Sect {
39 return symbols[i].Sect < symbols[j].Sect
40 }
41 return symbols[i].Value < symbols[j].Value
42 })
43
Yabin Cui7f5f22b2022-08-31 16:23:43 -070044 file := &File{IsMachoFile: true}
Colin Cross8673b5b2018-03-01 11:20:25 -080045
46 for _, section := range machoFile.Sections {
47 file.Sections = append(file.Sections, &Section{
48 Name: section.Name,
49 Addr: section.Addr,
50 Offset: uint64(section.Offset),
51 Size: section.Size,
52 })
53 }
54
Colin Crossdfce7642018-02-28 13:05:39 -080055 for _, symbol := range symbols {
Colin Cross8673b5b2018-03-01 11:20:25 -080056 if symbol.Sect > 0 {
57 section := file.Sections[symbol.Sect-1]
58 file.Symbols = append(file.Symbols, &Symbol{
59 // symbols in macho files seem to be prefixed with an underscore
60 Name: strings.TrimPrefix(symbol.Name, "_"),
61 // MachO symbol value is virtual address of the symbol, convert it to offset into the section.
62 Addr: symbol.Value - section.Addr,
63 // MachO symbols don't have size information.
64 Size: 0,
65 Section: section,
Colin Crossdfce7642018-02-28 13:05:39 -080066 })
Colin Cross5498f852018-01-03 23:39:54 -080067 }
68 }
69
Colin Cross8673b5b2018-03-01 11:20:25 -080070 return file, nil
71}
72
73func dumpMachoSymbols(r io.ReaderAt) error {
74 machoFile, err := macho.NewFile(r)
75 if err != nil {
76 return cantParseError{err}
77 }
78
79 fmt.Println("&macho.File{")
80
81 fmt.Println("\tSections: []*macho.Section{")
82 for _, section := range machoFile.Sections {
83 fmt.Printf("\t\t&macho.Section{SectionHeader: %#v},\n", section.SectionHeader)
84 }
85 fmt.Println("\t},")
86
87 fmt.Println("\tSymtab: &macho.Symtab{")
88 fmt.Println("\t\tSyms: []macho.Symbol{")
89 for _, symbol := range machoFile.Symtab.Syms {
90 fmt.Printf("\t\t\t%#v,\n", symbol)
91 }
92 fmt.Println("\t\t},")
93 fmt.Println("\t},")
94
95 fmt.Println("}")
96
97 return nil
Colin Cross5498f852018-01-03 23:39:54 -080098}
Yabin Cui7f5f22b2022-08-31 16:23:43 -070099
100func CodeSignMachoFile(path string) error {
101 cmd := exec.Command("/usr/bin/codesign", "--force", "-s", "-", path)
102 return cmd.Run()
103}