We have released the IFPS Format package for all licenses of Cerbero Suite. IFPS (RemObjects PascalScript) bytecode files are utilized by InnoSetup, a popular script-driven Windows installation system, to enhance the installer’s functionality through custom scripts and can potentially be used by malware to execute malicious code.
Tag: Script
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!
Stripping symbols from a Mach-O
A common mistake many developers do is to leave names of local symbols inside applications built on OS X. Using the strip utility combined with the compiler visibility flags is, unfortunately, not enough.
So I wrote a small script for Profiler to be run from the command line and I integrated it in the build process.
The syntax to execute the script is:
cerpro -c -r path/to/strip.py:stripMachO source destination
Here’s the whole code:
# name: strip.py
from Pro.Core import *
from Pro.MachO 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")
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))
if newc.save(dstname):
print("successfully stripped all local symbols!")
else:
print("error: couldn't save stripped binary to '%s'" % (dstname,))
The code zeroes names of symbols which are not associated to any section in the binary.
Easy. 🙂