mirror of
https://github.com/blacktop/ipsw.git
synced 2026-06-07 12:27:36 +00:00
79 lines
2.3 KiB
Go
79 lines
2.3 KiB
Go
package utils
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"io"
|
|
|
|
"github.com/blacktop/arm64-cgo/disassemble"
|
|
"github.com/blacktop/go-macho"
|
|
)
|
|
|
|
// mteMnemonics is the complete list of all MTE instruction mnemonics
|
|
var mteMnemonics = map[disassemble.Operation]bool{
|
|
disassemble.ARM64_ADDG: true, // Add with Tag
|
|
disassemble.ARM64_SUBG: true, // Subtract with Tag
|
|
disassemble.ARM64_IRG: true, // Insert Random Tag
|
|
disassemble.ARM64_GMI: true, // Tag Mask Insert
|
|
disassemble.ARM64_LDG: true, // Load Allocation Tag
|
|
disassemble.ARM64_STG: true, // Store Allocation Tag
|
|
disassemble.ARM64_ST2G: true, // Store Allocation Tags
|
|
disassemble.ARM64_STZG: true, // Store Allocation Tag and Zero
|
|
disassemble.ARM64_STZ2G: true, // Store Allocation Tags and Zero
|
|
disassemble.ARM64_STGP: true, // Store Allocation Tag and Pair
|
|
disassemble.ARM64_LDGM: true, // Load Tag Multiple
|
|
disassemble.ARM64_STGM: true, // Store Tag Multiple
|
|
disassemble.ARM64_STZGM: true, // Store Tag and Zero Multiple
|
|
disassemble.ARM64_SUBP: true, // Subtract Pointer
|
|
disassemble.ARM64_SUBPS: true, // Subtract Pointer, setting Flags
|
|
disassemble.ARM64_CMPP: true, // Compare Pointer (alias of SUBPS)
|
|
}
|
|
|
|
// HasMTEInstructions scans a Mach-O file for MTE (Memory Tagging Extension) instructions.
|
|
// Returns true and the first address if any MTE instructions are found in the executable sections.
|
|
func HasMTEInstructions(m *macho.File) (bool, uint64) {
|
|
var instrValue uint32
|
|
var decoder disassemble.Decoder
|
|
|
|
sections := m.GetSectionsForSegment("__TEXT")
|
|
if len(sections) == 0 {
|
|
return false, 0
|
|
}
|
|
|
|
for _, sec := range sections {
|
|
if !sec.Flags.IsPureInstructions() && !sec.Flags.IsSomeInstructions() {
|
|
continue
|
|
}
|
|
|
|
data := make([]byte, sec.Size)
|
|
if _, err := m.ReadAtAddr(data, sec.Addr); err != nil {
|
|
continue
|
|
}
|
|
|
|
r := bytes.NewReader(data)
|
|
startAddr := sec.Addr
|
|
|
|
for {
|
|
err := binary.Read(r, binary.LittleEndian, &instrValue)
|
|
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
|
|
var inst disassemble.Inst
|
|
if err := decoder.DecomposeInto(startAddr, instrValue, &inst); err != nil {
|
|
startAddr += uint64(binary.Size(uint32(0)))
|
|
continue
|
|
}
|
|
|
|
if isMTE, found := mteMnemonics[inst.Operation]; found {
|
|
return isMTE, startAddr
|
|
}
|
|
|
|
startAddr += uint64(binary.Size(uint32(0)))
|
|
}
|
|
}
|
|
|
|
return false, 0
|
|
}
|