Stripping symbols from an ELF

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!

Leave a Reply

Your email address will not be published. Required fields are marked *