Just as the previous post about stripping symbols from a Mach-O binary, here’s one about stripping them from an ELF binary.
The syntax to execute the script is the same as in the previous post, only the called function changes:
cerpro -c -r path/to/strip.py:stripELF source destination
Here’s the code:
from Pro.Core import *
from Pro.ELF import *
def stripELF(srcname, dstname):
oldc = createContainerFromFile(srcname)
if oldc.isNull():
print("error: couldn't open '%s'" % (srcname,))
return
obj = ELFObject()
if not obj.Load(oldc):
print("error: could't load ELF")
return
newc = oldc.copyToNewContainer()
sects = obj.Sections()
count = 0
it = obj.SymbolTableSections().iterator()
it.next()
while it.hasNext():
s = sects.At(it.next())
# only the .symtab section
if s.Num("sh_type") != 2:
continue
strtaboffs = sects.At(s.Num("sh_link")).Num("sh_offset")
sit = obj.Symbols(s).iterator()
while sit.hasNext():
sym = sit.next()
# only local symbols
if sym.Num("st_shndx") == 0:
continue
nameoffs = sym.Num("st_name") + strtaboffs
name, ret = obj.ReadUInt8String(nameoffs, 0x10000)
newc.fill(nameoffs, 0, len(name))
count += 1
if newc.save(dstname):
print("successfully stripped all %d local symbols!" % (count,))
else:
print("error: couldn't save stripped binary to '%s'" % (dstname,))
That’s it!
And here again the complete script which you can use to strip both a Mach-O and an ELF binary.
# strip.py
from Pro.Core import *
from Pro.MachO import *
from Pro.ELF import *
def stripMachO(srcname, dstname):
oldc = createContainerFromFile(srcname)
if oldc.isNull():
print("error: couldn't open '%s'" % (srcname,))
return
obj = MachObject()
if not obj.Load(oldc):
print("error: could't load Mach-O")
return
obj.ProcessLoadCommands()
newc = oldc.copyToNewContainer()
symlc = obj.SymTableLC()
stroffs = symlc.Num("stroff")
count = 0
it = obj.SymbolNList(symlc).iterator()
while it.hasNext():
syms = it.next()
# only local symbols
if syms.Num("sect") == 0:
continue
nameoffs = obj.AddressToOffset(syms.Num("strx") + stroffs)
name, ret = obj.ReadUInt8String(nameoffs, 0x10000)
newc.fill(nameoffs, 0, len(name))
count += 1
if newc.save(dstname):
print("successfully stripped all %d local symbols!" % (count,))
else:
print("error: couldn't save stripped binary to '%s'" % (dstname,))
def stripELF(srcname, dstname):
oldc = createContainerFromFile(srcname)
if oldc.isNull():
print("error: couldn't open '%s'" % (srcname,))
return
obj = ELFObject()
if not obj.Load(oldc):
print("error: could't load ELF")
return
newc = oldc.copyToNewContainer()
sects = obj.Sections()
count = 0
it = obj.SymbolTableSections().iterator()
it.next()
while it.hasNext():
s = sects.At(it.next())
# only the .symtab section
if s.Num("sh_type") != 2:
continue
strtaboffs = sects.At(s.Num("sh_link")).Num("sh_offset")
sit = obj.Symbols(s).iterator()
while sit.hasNext():
sym = sit.next()
# only local symbols
if sym.Num("st_shndx") == 0:
continue
nameoffs = sym.Num("st_name") + strtaboffs
name, ret = obj.ReadUInt8String(nameoffs, 0x10000)
newc.fill(nameoffs, 0, len(name))
count += 1
if newc.save(dstname):
print("successfully stripped all %d local symbols!" % (count,))
else:
print("error: couldn't save stripped binary to '%s'" % (dstname,))
The Linux x64 version of Profiler should be released soon. So stay tuned!