format code

This commit is contained in:
2023-05-31 16:31:52 +07:00
parent e3453ae127
commit 841a50f8e1
12 changed files with 201 additions and 196 deletions

View File

@ -1,12 +1,12 @@
package main
import (
"ios-wrapper/pkg/ios/macho"
"github.com/alecthomas/kong"
"ios-wrapper/pkg/ios/macho"
"os"
"fmt"
"bytes"
"bytes"
"fmt"
"os"
)
type Argument struct {
@ -18,30 +18,30 @@ func main() {
var cli Argument
kong.Parse(&cli)
compare(cli.One, cli.Two)
compare(cli.One, cli.Two)
}
func compare(one string, two string) {
f1, _ := os.OpenFile(one, os.O_RDONLY, 0644)
f2, _ := os.OpenFile(two, os.O_RDONLY, 0644)
var mc1 macho.MachoContext
var mc2 macho.MachoContext
var mc1 macho.MachoContext
var mc2 macho.MachoContext
mc1.ParseFile(f1, 0)
mc2.ParseFile(f2, 0)
s1 := mc1.FindSection("__text")
s2 := mc2.FindSection("__text")
s1 := mc1.FindSection("__text")
s2 := mc2.FindSection("__text")
if (s1.Size() == s2.Size()) {
fmt.Println("Size is equal")
} else {
fmt.Printf("%x <> %x\n", s1.Size(), s2.Size())
}
if s1.Size() == s2.Size() {
fmt.Println("Size is equal")
} else {
fmt.Printf("%x <> %x\n", s1.Size(), s2.Size())
}
data1 := mc1.Cut(uint64(s1.Offset()), s1.Size())
data2 := mc1.Cut(uint64(s2.Offset()), s2.Size())
if (bytes.Compare(data1, data2) == 0) {
fmt.Println("Data is equal")
}
data1 := mc1.Cut(uint64(s1.Offset()), s1.Size())
data2 := mc1.Cut(uint64(s2.Offset()), s2.Size())
if bytes.Compare(data1, data2) == 0 {
fmt.Println("Data is equal")
}
}

View File

@ -57,13 +57,13 @@ func Cli() {
return
} else if command == "lipo split" {
arg := cli.Lipo.Split
fat.FatSplit(arg.Fat)
return
} else if command == "lipo join" {
fat.FatSplit(arg.Fat)
return
} else if command == "lipo join" {
arg := cli.Lipo.Join
fat.FatJoin(arg.Macho, arg.Out)
return
}
fat.FatJoin(arg.Macho, arg.Out)
return
}
var pc ProgramContext
var ofile OFile = nil
@ -81,7 +81,7 @@ func Cli() {
pc.signed = arg.Signed
pc.ReadUserConfig(arg.Config)
case "vltk":
case "vltk":
arg := cli.Vltk
ofile = NewOFile(arg.OFile)
pc.remove_codesign = true

View File

@ -9,14 +9,14 @@ type WrapArgument struct {
}
type VltkArgument struct {
Out string `short:"o" required name:"outfile" help:"Modified Mach-O/Fat binary output file" type:"path"`
OFile string `arg help:"Path to Mach-O/Fat binary file" type:"existingfile"`
Out string `short:"o" required name:"outfile" help:"Modified Mach-O/Fat binary output file" type:"path"`
OFile string `arg help:"Path to Mach-O/Fat binary file" type:"existingfile"`
}
type InfoArgument struct {
OFile string `arg help:"Path to Mach-O/Fat binary file" type:"existingfile"`
All bool `short:"a" help:"If print all information"`
Arch string `help:"Only print information in this arch"`
All bool `short:"a" help:"If print all information"`
Arch string `help:"Only print information in this arch"`
}
type RemoveCodesignArgument struct {
@ -40,17 +40,17 @@ type Addr2LineArgument struct {
}
type LipoArgument struct {
Join struct {
Out string `short:"o" required help:"Output Fat binary file" type:"path"`
Macho []string `arg help:"Macho binaries to join" type:"existingfile"`
} `cmd help:"Join Macho binaries into Fat binary"`
Split struct {
Fat string `arg help:"Fat binary to split" type:"existingfile"`
} `cmd help:"Split fat binary into files, named <name>_<arch>"`
Join struct {
Out string `short:"o" required help:"Output Fat binary file" type:"path"`
Macho []string `arg help:"Macho binaries to join" type:"existingfile"`
} `cmd help:"Join Macho binaries into Fat binary"`
Split struct {
Fat string `arg help:"Fat binary to split" type:"existingfile"`
} `cmd help:"Split fat binary into files, named <name>_<arch>"`
}
type PepeArgument struct {
OFile string `arg help:"Path to Mach-O/Fat binary file" type:"existingfile"`
OFile string `arg help:"Path to Mach-O/Fat binary file" type:"existingfile"`
}
type Argument struct {
@ -59,8 +59,8 @@ type Argument struct {
Info InfoArgument `cmd help:"Show Mach-O/Fat binary information"`
RemoveCodesign RemoveCodesignArgument `cmd aliases:"remove-signature" name:"remove-codesign" help:"Remove LC_CODE_SIGNATURE from Mach-O/Fat binary"`
SignedBcell SignedBcellArgument `cmd name:"signed-bcell" help:"Change Protobuf<BcellFile> into Protobuf<SignedData>"`
DisplayBcell DisplayBcellArgument `cmd name:"display-bcell" help:"Display Protobuf<BcellFile> content"`
Addr2Line Addr2LineArgument `cmd name:"addr2line" help:"Resolve crash address from DWARF file"`
Lipo LipoArgument `cmd help:"split Fat binary or join Mach-O binares"`
Pepe PepeArgument `cmd help:"split Fat binary or join Mach-O binares"`
DisplayBcell DisplayBcellArgument `cmd name:"display-bcell" help:"Display Protobuf<BcellFile> content"`
Addr2Line Addr2LineArgument `cmd name:"addr2line" help:"Resolve crash address from DWARF file"`
Lipo LipoArgument `cmd help:"split Fat binary or join Mach-O binares"`
Pepe PepeArgument `cmd help:"split Fat binary or join Mach-O binares"`
}

View File

@ -34,7 +34,6 @@ func (printer *InfoPrinter) Print() {
fmt.Printf("Init functions at offset %s\n", &fun)
}
symbols := mc.CollectLazyBindSymbols()
if len(symbols) > 0 {
fmt.Println("Lazy Symbols")

View File

@ -92,8 +92,8 @@ const (
LC_VERSION_MIN_TVOS uint32 = 0x2F
LC_VERSION_MIN_WATCHOS uint32 = 0x30
LC_BUILD_VERSION uint32 = 0x32
LC_DYLD_EXPORTS_TRIE uint32 = 0x33 | 0x80000000
LC_DYLD_CHAINED_FIXUPS uint32 = 0x34 | 0x80000000
LC_DYLD_EXPORTS_TRIE uint32 = 0x33 | 0x80000000
LC_DYLD_CHAINED_FIXUPS uint32 = 0x34 | 0x80000000
)
const (

View File

@ -1,8 +1,8 @@
/// Contains the declaration of FatHeader and FatArch
/// These structs are always written using Big-Endian,
/// as documented in the mach-o/fat.h
/// This file also has a CreateFat function to generate
/// Fat file from a list of MachoContext
// / Contains the declaration of FatHeader and FatArch
// / These structs are always written using Big-Endian,
// / as documented in the mach-o/fat.h
// / This file also has a CreateFat function to generate
// / Fat file from a list of MachoContext
package fat
import (
@ -16,8 +16,8 @@ import (
macho "ios-wrapper/pkg/ios/macho"
)
/// Get the alignment for the Mach-O in Fat binary
/// The returned value is the multiplier of 2
// / Get the alignment for the Mach-O in Fat binary
// / The returned value is the multiplier of 2
func GetAlignment(h *macho.Header) uint32 {
switch h.Cputype() {
case CPU_TYPE_ARM, CPU_TYPE_ARM64:
@ -46,17 +46,17 @@ func MachosToFatArchs(machos []*macho.MachoContext) []*FatArch {
return fa
}
/// Create a Fat binary from MachoContext
/// Convert MachoContext to FatArch
/// Calculate the alignment, now using basic calculation
/// because iOS always has valid archs ARM
///
/// Sort the Fat arch as per the cctools/lipo
/// Calculate the offset with each Mach-O
///
/// Write the FatHeader
/// Write the FatArchs
/// Write the Mach-Os
// / Create a Fat binary from MachoContext
// / Convert MachoContext to FatArch
// / Calculate the alignment, now using basic calculation
// / because iOS always has valid archs ARM
// /
// / Sort the Fat arch as per the cctools/lipo
// / Calculate the offset with each Mach-O
// /
// / Write the FatHeader
// / Write the FatArchs
// / Write the Mach-Os
func CreateFat(machos []*macho.MachoContext, outfilename string) error {
archs := MachosToFatArchs(machos)
sort.SliceStable(archs, func(i, j int) bool {
@ -139,9 +139,9 @@ func (fw *fatWriter) WriteFatArchs(w io.Writer, archs []*FatArch) {
}
}
/// for each fat arch sorted, we locate the MachoContext and
/// use it to Write to the buffer
/// locating the macho by its cputype and cpusubtype
// / for each fat arch sorted, we locate the MachoContext and
// / use it to Write to the buffer
// / locating the macho by its cputype and cpusubtype
func (fw *fatWriter) WriteMachos(
w io.WriteSeeker,
archs []*FatArch,

View File

@ -46,41 +46,41 @@ func (sym *ImportSymbol) Stub() uint64 {
}
func (mc *MachoContext) CollectLazyBindSymbols() []*ImportSymbol {
if mc.dyldinfo == nil {
return mc.CollectLazyBindSymbolsModern()
} else {
return mc.CollectLazyBindSymbolsLegacy()
}
if mc.dyldinfo == nil {
return mc.CollectLazyBindSymbolsModern()
} else {
return mc.CollectLazyBindSymbolsLegacy()
}
}
// New convention using LC_DYLD_CHAINED_FIXUPS
func (mc *MachoContext) CollectLazyBindSymbolsModern() []*ImportSymbol {
var buf []byte
for _, cmd := range mc.Linkedits() {
if (cmd.Cmd() != LC_DYLD_CHAINED_FIXUPS) {
continue
}
var buf []byte
for _, cmd := range mc.Linkedits() {
if cmd.Cmd() != LC_DYLD_CHAINED_FIXUPS {
continue
}
count_offset := int64(cmd.Dataoff()) + 16
mc.file.WriteAt([]byte{0, 0, 0, 0}, count_offset)
count_offset := int64(cmd.Dataoff()) + 16
mc.file.WriteAt([]byte{0, 0, 0, 0}, count_offset)
symbol_offset := int64(0x4000)
mc.file.WriteAt([]byte{0, 0, 0, 0, 0, 0, 0, 0}, symbol_offset)
symbol_offset := int64(0x4000)
mc.file.WriteAt([]byte{0, 0, 0, 0, 0, 0, 0, 0}, symbol_offset)
buf = mc.buf[cmd.Dataoff():cmd.Dataoff() + cmd.Datasize()]
break
}
buf = mc.buf[cmd.Dataoff() : cmd.Dataoff()+cmd.Datasize()]
break
}
r := bytes.NewReader(buf)
rr := bufio.NewReader(r)
var fixups_version int32
var starts_offset int32
var imports_offset int32
var symbols_offset int32
var imports_count int32
var imports_format int32
var symbols_format int32
var fixups_version int32
var starts_offset int32
var imports_offset int32
var symbols_offset int32
var imports_count int32
var imports_format int32
var symbols_format int32
binary.Read(rr, mc.byteorder, &fixups_version)
binary.Read(rr, mc.byteorder, &starts_offset)
binary.Read(rr, mc.byteorder, &imports_offset)
@ -88,36 +88,36 @@ func (mc *MachoContext) CollectLazyBindSymbolsModern() []*ImportSymbol {
binary.Read(rr, mc.byteorder, &imports_count)
binary.Read(rr, mc.byteorder, &imports_format)
binary.Read(rr, mc.byteorder, &symbols_format)
fmt.Printf(
"HMMGE %x %x\n",
imports_offset,
imports_count,
)
fmt.Printf(
"HMMGE %x %x\n",
imports_offset,
imports_count,
)
return []*ImportSymbol{}
return []*ImportSymbol{}
}
// Old convention using LC_DYLD_INFO_ONLY section and bytecode runner
func (mc *MachoContext) CollectLazyBindSymbolsLegacy() []*ImportSymbol {
start := mc.dyldinfo.lazy_bind_off
size := mc.dyldinfo.lazy_bind_size
size := mc.dyldinfo.lazy_bind_size
end := start + size
if size == 0 {
return []*ImportSymbol{}
}
// clear this whole section to 0x00 BIND_OPCODE_DONE
dummy := []byte{
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
}
// make LINK EDIT section writable
// mc.file.WriteAt([]byte{0x03}, int64(0x3f8))
// set number of symbols to 0
mc.file.WriteAt([]byte{0, 0, 0, 0}, int64(0x444))
mc.file.WriteAt([]byte{0, 0, 0, 0}, int64(0x44c))
mc.file.WriteAt([]byte{0, 0, 0, 0}, int64(0x48c))
// clear this whole section to 0x00 BIND_OPCODE_DONE
dummy := []byte{
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69,
}
// make LINK EDIT section writable
// mc.file.WriteAt([]byte{0x03}, int64(0x3f8))
// set number of symbols to 0
mc.file.WriteAt([]byte{0, 0, 0, 0}, int64(0x444))
mc.file.WriteAt([]byte{0, 0, 0, 0}, int64(0x44c))
mc.file.WriteAt([]byte{0, 0, 0, 0}, int64(0x48c))
mc.file.WriteAt(dummy, int64(start))
buf := bytes.NewBuffer(mc.buf[start:end])

View File

@ -40,12 +40,13 @@ func rewriteLoadcommandsWithoutCodesignature(mc *MachoContext) {
// CODE_SIGNATURE load commands points to the codesign data offset and size.
// __LINKEDIT section points to data offset and size.
// We have:
// linkedit = (section*) LC_SEGMENT.section[0] // name="__LINKEDIT"
// codesign = (linkedit_data_command*) LC_CODE_SIGNATURE
// BinarySize = { f.seek(0, SEEKEND); return f.tell() }
//
// linkedit->fileoff + linkedit->filesize == codesign->dataOff + codesign->dataSize
// linkedit->fileoff + linkedit->filesize == BinarySize
// linkedit = (section*) LC_SEGMENT.section[0] // name="__LINKEDIT"
// codesign = (linkedit_data_command*) LC_CODE_SIGNATURE
// BinarySize = { f.seek(0, SEEKEND); return f.tell() }
//
// linkedit->fileoff + linkedit->filesize == codesign->dataOff + codesign->dataSize
// linkedit->fileoff + linkedit->filesize == BinarySize
//
// To remove the codesign data, we truncate the file to remove the codesign data.
// Then we update the linkedit->filesize to linkedit->filesize - codesign->dataSize

View File

@ -456,7 +456,7 @@ func (lcmd *Symtab) Cmdsize() uint32 {
}
func (lcmd *Symtab) Cmdname() string {
return fmt.Sprintf("%s symoff:0x%x nsyms:%d stroff:0x%x strsize:0x%x",
return fmt.Sprintf("%s symoff:0x%x nsyms:%d stroff:0x%x strsize:0x%x",
lcmd.c.Cmdname(), lcmd.symoff, lcmd.nsyms, lcmd.stroff, lcmd.strsize)
}

View File

@ -71,10 +71,12 @@ func (mc *MachoContext) WriteBufferTo(w io.Writer) (int, error) {
// Parse the provided Mach-O binary from a file
// The first 4 bytes of the file must be the MachO magic
// That is:
// file.Seek(0, io.SeekStart)
// magic := make([]byte, 4)
// file.Read(magic)
// assert magic == []byte{macho magic bytes}
//
// file.Seek(0, io.SeekStart)
// magic := make([]byte, 4)
// file.Read(magic)
// assert magic == []byte{macho magic bytes}
//
// or else, parsing error is panic
func (mc *MachoContext) ParseFile(file *os.File, length int) error {
file.Seek(0, io.SeekStart)

View File

@ -83,8 +83,8 @@ func (mc *MachoContext) DylibExisted(name string) bool {
// simple check
// Advanced check requires expansion of @rpath
for _, dylib := range mc.dylibs {
dylib_ := bytes.Trim(dylib.name, "\x00")
match := bytes.Compare(dylib_, []byte(name)) == 0
dylib_ := bytes.Trim(dylib.name, "\x00")
match := bytes.Compare(dylib_, []byte(name)) == 0
log.WithFields(log.Fields{
"left": dylib_,
"right": []byte(name),
@ -101,8 +101,8 @@ func (mc *MachoContext) RPathExisted(path string) bool {
// simple check
// Advanced check requires expansion of @rpath
for _, rpath := range mc.rpaths {
rpath_ := bytes.Trim(rpath.path, "\x00")
match := bytes.Compare(rpath_, []byte(path)) == 0
rpath_ := bytes.Trim(rpath.path, "\x00")
match := bytes.Compare(rpath_, []byte(path)) == 0
log.WithFields(log.Fields{
"left": rpath_,
"right": []byte(path),
@ -138,7 +138,7 @@ func (mc *MachoContext) FindSegment(name string) Segment {
}
func (mc *MachoContext) Cut(offset uint64, size uint64) []byte {
return mc.buf[offset : offset + size];
return mc.buf[offset : offset+size]
}
// INIT POINTER