Created
March 19, 2016 04:58
-
-
Save x56/8a16c8e30c954aec014d to your computer and use it in GitHub Desktop.
IDAPython script to name and create structs for all CFLString objects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import idaapi | |
import idc | |
#import idautils | |
import sys | |
#NOTE: may have to run this a few times to get to the end of the IDB, haven't bothered fixing this | |
def add_struct_to_idb(name): | |
idc.Til2Idb(-1, name) | |
def find_or_create_struct(name): | |
sid = idc.GetStrucIdByName(name) | |
if sid == idc.BADADDR: | |
sid = idc.AddStrucEx(-1, name, 0) | |
print "added struct \"{0}\", id: {1}".format(name, sid) | |
else: | |
print "struct \"{0}\" already exists, id: ".format(name, sid) | |
add_struct_to_idb(name) | |
return sid | |
def create_CFLString_struct(): | |
sid = find_or_create_struct("CFLString") | |
print idc.AddStrucMember(sid, "magic", -1, idc.FF_DWRD, -1, 4) | |
print idc.AddStrucMember(sid, "unk4", -1, idc.FF_DWRD, -1, 4) | |
print idc.AddStrucMember(sid, "cstr", -1, idc.FF_BYTE, -1, 0) | |
return sid | |
def apply_struct(ea, sid, size): | |
if size == -1: | |
size = idc.GetStrucSize(sid) | |
idc.MakeUnknown(ea, size, idc.DOUNK_DELNAMES) | |
idaapi.doStruct(ea, size, sid) | |
return size | |
def main(): | |
CFLString_sid = create_CFLString_struct() | |
# limit search to .rodata | |
seg_sel = idc.SegByName(".rodata") | |
ea = idc.SegByBase(seg_sel) | |
end_ea = idc.SegEnd(ea) | |
while ea < end_ea: | |
#find all instances of magic==0x756 and unk4==0x7FFFFFFF | |
if (idc.Dword(ea), idc.Dword(ea + 4)) == (0x756, 0x7FFFFFFF): | |
# read bytes until NULL is found | |
index = 0 | |
cstr = "" | |
while True: | |
char = chr(idc.Byte(ea + 8 + index)) | |
if char == "\x00": | |
break | |
index += 1 | |
cstr += char | |
name_str = cstr | |
for bad_char in ["-", ":", ";", "=", "(", ")", " ", "/", "\\", "<", ">"]: | |
name_str = name_str.replace(bad_char, "_") | |
#XXX: lazy/unreliable way to deal with name collisions | |
suffix = 0 | |
while not idc.MakeNameEx(ea, "cflstr_{0}__{1}".format(name_str, suffix), idc.SN_CHECK | idc.SN_NOWARN): | |
suffix += 1 | |
# something probably went horribly wrong | |
if suffix > 100: | |
print "error creating name at address {0}".format(hex(ea)) | |
sys.exit(1) | |
# size = magic + unk4 + string_length + NULL_byte | |
print "applying at {0}".format(hex(ea)) | |
struct_size = apply_struct(ea, CFLString_sid, 8 + len(cstr) + 1) | |
# preserve alignment | |
ea += (struct_size & ~3) | |
else: | |
ea += 4 | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment