add selfbind functionality
This commit is contained in:
@ -7,9 +7,11 @@ import (
|
||||
"math/rand"
|
||||
"time"
|
||||
"strings"
|
||||
"encoding/binary"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"ios-wrapper/pkg/protomodel"
|
||||
. "ios-wrapper/pkg/ios"
|
||||
)
|
||||
|
||||
@ -681,3 +683,130 @@ func (mc *MachoContext) RemoveExportTrie() {
|
||||
// should never occur unless this binary is modified
|
||||
}
|
||||
}
|
||||
|
||||
func (mc *MachoContext) AddSection(segname string, name string, size int) Section {
|
||||
// mc.file.WriteAt(mc.header.Serialize(mc), 0)
|
||||
var ret Section
|
||||
var buffer bytes.Buffer
|
||||
for _, command := range mc.commands {
|
||||
switch command.(type) {
|
||||
case *Segment64:
|
||||
var virtualAddr uint64
|
||||
var fileOffset uint64
|
||||
|
||||
var segment = command.(*Segment64)
|
||||
if bytes.Compare(bytes.Trim(segment.SegName(), "\x00"), []byte(segname)) != 0 {
|
||||
buffer.Write(segment.Serialize(mc))
|
||||
continue
|
||||
} else {
|
||||
virtualAddr = segment.Vmaddr()
|
||||
fileOffset = segment.Fileoff()
|
||||
for _, section := range segment.Sections() {
|
||||
virtualAddr += section.Size()
|
||||
// if section.Offset() != 0 {
|
||||
fileOffset += section.Size()
|
||||
// }
|
||||
}
|
||||
|
||||
align := uint64(4)
|
||||
alignment := align - (fileOffset % align)
|
||||
fileOffset += alignment
|
||||
virtualAddr += alignment
|
||||
|
||||
enoughSpace := segment.Fileoff() + segment.Filesize() >= fileOffset + uint64(size)
|
||||
if !enoughSpace {
|
||||
fmt.Println("Not enough space to store saved info in __DATA segment, need resize (not supported now)")
|
||||
panic("Not enough space to store saved info in __DATA segment, need resize (not supported now)")
|
||||
}
|
||||
}
|
||||
|
||||
var section Section64
|
||||
section.sectname = make([]byte, 16)
|
||||
copy(section.sectname, name)
|
||||
section.segname = make([]byte, 16)
|
||||
copy(section.segname, segname)
|
||||
section.size = uint64(size)
|
||||
section.reloff = 0
|
||||
section.nreloc = 0
|
||||
section.flags = 0
|
||||
section.align = 3
|
||||
section.reserved1 = 0
|
||||
section.reserved2 = 0
|
||||
section.reserved3 = 0
|
||||
|
||||
// addr will increment from the last section
|
||||
// offset will increment from the last section + size
|
||||
// be careful of Virtual section (bss)
|
||||
section.addr = virtualAddr
|
||||
section.offset = uint32(fileOffset)
|
||||
segment.nsects += 1
|
||||
buffer.Write(segment.Serialize(mc))
|
||||
buffer.Write(section.Serialize(mc))
|
||||
|
||||
fmt.Printf("Add a new section with addr=0x%x, fileoffset=0x%x\n", section.addr, section.offset)
|
||||
|
||||
ret = §ion
|
||||
continue
|
||||
|
||||
default:
|
||||
buffer.Write(command.Serialize(mc))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
mc.header.sizeofcmds = uint32(buffer.Len())
|
||||
header := mc.header.Serialize(mc)
|
||||
mc.file.WriteAt(header, 0)
|
||||
mc.file.WriteAt(buffer.Bytes(), int64(len(header)))
|
||||
return ret
|
||||
}
|
||||
|
||||
func (mc *MachoContext) WriteInfoToData(info *protomodel.MachoInfo) {
|
||||
encode := func () []byte {
|
||||
buffer := new(bytes.Buffer)
|
||||
for _, table := range info.Symbols.Tables {
|
||||
binary.Write(buffer, mc.byteorder, table.LibIndex)
|
||||
binary.Write(buffer, mc.byteorder, table.Nsymbols)
|
||||
for _, symbol := range table.Symbols {
|
||||
binary.Write(buffer, mc.byteorder, (symbol.SymbolIndex<<8)|symbol.SegmentIndex)
|
||||
binary.Write(buffer, mc.byteorder, symbol.Offset)
|
||||
}
|
||||
}
|
||||
instructions := buffer.Bytes()
|
||||
|
||||
buffer = new(bytes.Buffer)
|
||||
for _, lib := range info.Symbols.Libs {
|
||||
buffer.WriteString(lib)
|
||||
buffer.WriteByte(0)
|
||||
}
|
||||
liblist := buffer.Bytes()
|
||||
|
||||
buffer = new(bytes.Buffer)
|
||||
for _, symbol := range info.Symbols.Symbols {
|
||||
buffer.WriteString(symbol)
|
||||
buffer.WriteByte(0)
|
||||
}
|
||||
symbollist := buffer.Bytes()
|
||||
|
||||
buffer = new(bytes.Buffer)
|
||||
// offset to liblist
|
||||
binary.Write(buffer, mc.byteorder, uint32(len(instructions)))
|
||||
// offset to symbollist
|
||||
binary.Write(buffer, mc.byteorder, uint32(len(instructions) + len(liblist)))
|
||||
buffer.Write(instructions)
|
||||
buffer.Write(liblist)
|
||||
buffer.Write(symbollist)
|
||||
|
||||
return buffer.Bytes()
|
||||
}
|
||||
encoded := encode()
|
||||
// encoded := []byte{0x11,0x22,0x33, 0x44}
|
||||
section := mc.AddSection("__DATA", "selfbind", len(encoded))
|
||||
if mc.Is64bit() {
|
||||
var s *Section64 = section.(*Section64)
|
||||
mc.file.WriteAt(encoded, int64(s.Offset()))
|
||||
} else {
|
||||
var s *Section32 = section.(*Section32)
|
||||
mc.file.WriteAt(encoded, int64(s.Offset()))
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user