Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
from pkg_resources import require
require("altgraph")
import os
import sys
import stat
import operator
import struct
import shutil
from modulegraph.util import *
from macholib import mach_o
MAGIC = [
struct.pack('!L', getattr(mach_o, 'MH_' + _))
for _ in ['MAGIC', 'CIGAM', 'MAGIC_64', 'CIGAM_64']
]
FAT_MAGIC_BYTES = struct.pack('!L', mach_o.FAT_MAGIC)
MAGIC_LEN = 4
STRIPCMD = ['/usr/bin/strip', '-x', '-S', '-']
def fsencoding(s, encoding=sys.getfilesystemencoding()):
"""
Ensure the given argument is in filesystem encoding (not unicode)
"""
if isinstance(s, unicode):
s = s.encode(encoding)
return s
def move(src, dst):
def readSymTab(header, fp, bits):
cmd = header.getSymbolTableCommand()
fp.seek(cmd.stroff)
strtab = fp.read(cmd.strsize)
fp.seek(cmd.symoff)
if bits == 64:
nlist = mach_o.nlist_64
else:
nlist = mach_o.nlist
syms = []
for i in xrange(cmd.nsyms):
n = nlist.from_fileobj(fp, _endian_=header.endian)
syms.append((strtab[n.n_un:strtab.find('\0', n.n_un)], n))
return OrderedDict(syms)
def map_segments(self):
if self.elf:
for s in self.elf.iter_segments():
addr, size = s['p_paddr'], s['p_memsz']
if not size:
continue
self.mem_map(addr, size)
self.mem_write(addr, s.data())
elif self.macho:
for lc, cmd, data in self.macho.commands:
if lc.cmd in (mach_o.LC_SEGMENT, mach_o.LC_SEGMENT_64):
c = self.fp.tell()
for seg in data:
self.fp.seek(seg.offset)
sd = self.fp.read(seg.size)
self.mem_map(seg.addr, seg.size)
self.mem_write(seg.addr, sd)
self.fp.seek(c)
self.stack = self.mmap(STACK_SIZE, STACK_BASE)
self.reg_write(self.sp, self.stack + STACK_SIZE - self.bsz)
def segments(self):
for lc, cmd, data in self.header.commands:
if lc.cmd in (mach_o.LC_SEGMENT, mach_o.LC_SEGMENT_64):
for seg in data:
self.fp.seek(seg.offset)
sd = self.fp.read(seg.size)
yield seg.addr, seg.size, sd
cmd.nundefsym = 0
cmd.tocoff = 0
cmd.ntoc = 0
cmd.modtaboff = 0
cmd.nmodtab = 0
cmd.extrefsymoff = 0
cmd.nextrefsyms = 0
cmd.indirectsymoff = 0
cmd.nindirectsyms = 0
cmd.extreloff = 0
cmd.nextrel = 0
cmd.locreloff = 0
cmd.nlocrel = 0
'''
if type(cmd) == mach_o.uuid_command:
print '[+]Erasing data for segment LC_UUID'
cmd.uuid = '\0'
if type(cmd) == mach_o.linkedit_data_command:
if lc.cmd == 0x26:
print '[+]Erasing data for segment LC_FUNCTION_STARTS'
cmd.dataoff = os.path.getsize(sys.argv[1])
cmd.datassize = 4
#add more removeable load commands here
print
return
def hash_macho0(exe):
headers = MachO.MachO(exe).headers
if len(headers) > 1:
logging.debug('Mach-O binary is FAT')
with open(exe, 'rb') as f:
data = bytes()
for header in headers:
f.seek(header.offset, 0)
start, end = sys.maxsize, 0
for (lc, segment, sections) in header.commands:
if (mach_o.LC_CODE_SIGNATURE == lc.cmd):
logging.warning('Mach-O binary has a signature section')
# The minimum section offset of all load commands is the start of VMP signing part
if (lc.cmd in (mach_o.LC_SEGMENT_64, mach_o.LC_SEGMENT) and
segment.segname.startswith(mach_o.SEG_TEXT.encode('utf-8'))):
for section in sections:
start = min(start, section.offset)
# Expect the String Table is at the end of unsigned binary followed by the code
# signature, so the end of String Table is the end of VMP signing part
if (mach_o.LC_SYMTAB == lc.cmd):
end = segment.stroff + segment.strsize
if (start >= end):
logging.error('Failed to assemble VMP/Mach-O signing body: %d-%d', start, end)
raise ValueError('Failed to assemble VMP/Mach-O signing body: %d-%d' % (start, end))
f.seek(start, 1)
data += f.read(end - start)
return compute_sha512(data)
def hash_macho0(exe):
headers = MachO.MachO(exe).headers
if len(headers) > 1:
logging.debug('Mach-O binary is FAT')
with open(exe, 'rb') as f:
data = bytes()
for header in headers:
f.seek(header.offset, 0)
start, end = sys.maxsize, 0
for (lc, segment, sections) in header.commands:
if (mach_o.LC_CODE_SIGNATURE == lc.cmd):
logging.warning('Mach-O binary has a signature section')
# The minimum section offset of all load commands is the start of VMP signing part
if (lc.cmd in (mach_o.LC_SEGMENT_64, mach_o.LC_SEGMENT) and
segment.segname.startswith(mach_o.SEG_TEXT.encode('utf-8'))):
for section in sections:
start = min(start, section.offset)
# Expect the String Table is at the end of unsigned binary followed by the code
# signature, so the end of String Table is the end of VMP signing part
if (mach_o.LC_SYMTAB == lc.cmd):
end = segment.stroff + segment.strsize
if (start >= end):
logging.error('Failed to assemble VMP/Mach-O signing body: %d-%d', start, end)
raise ValueError('Failed to assemble VMP/Mach-O signing body: %d-%d' % (start, end))
f.seek(start, 1)
data += f.read(end - start)
return compute_sha512(data)
print '[+]Erasing data for segment LC_SYMTAB'
#Save Original Value
SYMTAB["symoff"]=cmd.symoff
SYMTAB["nsyms"]=cmd.nsyms
SYMTAB["stroff"]=cmd.stroff
SYMTAB["strsize"]=cmd.strsize
#Change
cmd.symoff = 0
cmd.nsyms = 0
cmd.stroff = 0
cmd.strsize = 0
if type(cmd) == mach_o.dysymtab_command:
print '[+]Erasing data for segment LC_DYSYMTAB'
cmd.ilocalsym = 0
cmd.nlocalsym = 0
cmd.iextdefsym = 0
cmd.nextdefsym = 0
cmd.iundefsym = 0
cmd.nundefsym = 0
cmd.tocoff = 0
cmd.ntoc = 0
cmd.modtaboff = 0
cmd.nmodtab = 0
cmd.extrefsymoff = 0
cmd.nextrefsyms = 0
cmd.indirectsymoff = 0
cmd.nindirectsyms = 0