IDA Snippets

Started by nanomad, December 09, 2012, 03:03:24 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

nanomad

Let's share some idc we find useful while reverse engineering.

I'll start with this simple IDC that finds all the un-explored STMFD and converts them to code


#include <idc.idc>

static main(void)
{
    auto addr = 0xFF0C0000;
    auto dis;
    while(1) {
        addr = FindUnexplored(addr,SEARCH_DOWN);
        MakeCode(addr);
        dis = GetDisasm(addr);
        if(strstr(dis,"STMFD") == 0) {
            print("#############");
            print(addr);
            print(dis);
            print("#############");
        } else {
            MakeUnkn(addr, DOUNK_EXPAND);
        }
        if(addr > 0xFF7EDFAC) {
            break;
        }
    }
}
EOS 1100D | EOS 650 (No, I didn't forget the D) | Ye Olde Canon EF Lenses ('87): 50 f/1.8 - 28 f/2.8 - 70-210 f/4 | EF-S 18-55 f/3.5-5.6 | Metz 36 AF-5

g3gg0


engio_writes.idc: select first entry of the list passed to engio_writes (that one with a list of registers and their values)
and it will put a readable comment at the first entry. this comment will show up whenever this memory location is referenced.

#include <idc.idc>
static main()
{
    auto counter,reg,val,address,base_address;
    auto comment = "";

    base_address = ScreenEA();
    address = base_address;

    for(counter=0;counter<128;counter++)
    {
        reg = Dword(address);
        val = Dword(address+4);
       
        if (reg == 0xFFFFFFFF)
        {
            MakeDword(address);
            MakeDword(address+4);
            MakeRptCmt(base_address, comment);
            return;
        }
       
        if (((reg & 0xFFF00000) != 0xC0F00000) && ((reg & 0xFFF00000) != 0xC0200000))
        {
            Message("Invalid register: 0x%08X", reg);
            return;
        }

        MakeDword(address);
        MakeDword(address+4);
       
        address = address + 8;
       
        comment = sprintf("%s\r\n[0x%08X] <- [0x%08X]", comment, reg, val);
    }
}
Help us with datasheets - Help us with register dumps
magic lantern: 1Magic9991E1eWbGvrsx186GovYCXFbppY, server expenses: [email protected]
ONLY donate for things we have done, not for things you expect!

nanomad

This one should automatically name most of the the FC_ functions in the firmware, you can easily change it to name FM_ calls too.


#include <idc.idc>

static main(void)
{
    auto start_addr = ScreenEA();
    auto addr;
    auto space_addr;
    auto dis,name,str_ptr, possible_name, func_start, response;
    response = 0;
    while(1) {
        Message("Looking @ %x\n", start_addr);
        addr =  FindText(start_addr,SEARCH_DOWN|SEARCH_NEXT|SEARCH_REGEX, 0, 0, "FC_");
        dis = GetDisasm(addr);
        if ( addr == BADADDR )
            break;
        if(strstr(dis,"ADR") == 0) {
            str_ptr = GetOperandValue(addr,1);
            possible_name = GetString(str_ptr, -1, ASCSTR_C);
            space_addr = strstr(possible_name," ");
            possible_name = substr(possible_name, 0, space_addr);
            //Message("%s\n", possible_name);
            name = GetFunctionName(addr);
            if(strlen(name) != 0) {
                func_start = LocByName(name);
                if(addr - func_start < 32 && strstr(name,"sub_") == 0) {
                    Jump(func_start);
                    Message("Renaming %s to %s @ %x", name, possible_name + "_maybe", func_start);
                    response = AskYN(0, "OK?");
                    if(response == 1) {           
                        MakeName(func_start, possible_name + "_maybe");
                    }
                } else {
                    Message("No sub or too far away: %d \n", addr - func_start);
                }
            }           
        } else {
            dis = GetDisasm(addr);
            Message("No ADR: %s\n", dis);
            if(strstr(dis,"DCB")==0) {
                addr = addr + strlen(GetString(addr,-1,ASCSTR_C))+1;
            }
        }
        start_addr = addr + 4;
        Message("%x <-> %x\n", addr, start_addr);
    }
}
EOS 1100D | EOS 650 (No, I didn't forget the D) | Ye Olde Canon EF Lenses ('87): 50 f/1.8 - 28 f/2.8 - 70-210 f/4 | EF-S 18-55 f/3.5-5.6 | Metz 36 AF-5

g3gg0

if you have RAM functions like the 0x4B0 interrupt handler they often have a lot of references.
these references are due to constant values like 0x4BD that are accidentally treated as offsets into RAM.

using this script you can remove all those references by marking the offending instruction offsets as numbers. (OpNumber)
simply select the first instruction of the function you want to clean up and run the script.
you will have to run it multiple times as it only removes a few of those references (not sure why).

its based on a script i found on OpenRCE (findstrangerefs.idc)


#include <idc.idc>

static main(void)
{
    auto ea, f_end, source;
    auto offset;
    auto f_start = ScreenEA();

    f_end = FindFuncEnd(f_start);
    ea = NextNotTail(f_start);
   
    while (ea < f_end && ea != BADADDR)
    {
        for(offset = 0; offset < 4; offset++)
        {
            auto address = ea + offset;
           
            source = RfirstB0(address);
            while (source != BADADDR)
            {
                if (source < f_start || f_end <= source)
                {
                    Message("strange code ref: %08lx %s from 0x%08X\n", address, Name(ea), source);
                    OpNumber(source,1);
                    OpNumber(source,0);
                    break;
                }
                source = RnextB0(address, source);
            }
           
            source = DfirstB(address);
            while (source != BADADDR)
            {
                if (source < f_start || f_end <= source)
                {
                    Message("strange data ref: %08lx %s from 0x%08X\n", address, Name(ea), source);
                    OpNumber(source,1);
                    OpNumber(source,0);
                    break;
                }
                source = DnextB(address, source);
            }
        }
        ea = NextNotTail(ea);
    }
}

Help us with datasheets - Help us with register dumps
magic lantern: 1Magic9991E1eWbGvrsx186GovYCXFbppY, server expenses: [email protected]
ONLY donate for things we have done, not for things you expect!

g3gg0

go over a "StateObject" and it will name all states in the state matrix that are unnamed yet and show all transitions etc.


    auto state,event,reg,val,address, name_sets;
    auto comment = "";

    address = ScreenEA();
    name_sets = 0;
   
    auto type = GetString(Dword(address), -1, ASCSTR_C);
    auto name = GetString(Dword(address + 0x04), -1, ASCSTR_C);
   
    if(type == "StateObject")
    {
        MakeDword(address + 0x00);
        MakeDword(address + 0x04);
        MakeDword(address + 0x08);
        MakeDword(address + 0x0C);
        MakeDword(address + 0x10);
        OpOff(address + 0x00, 0, 0);
        OpOff(address + 0x04, 0, 0);
        OpOff(address + 0x0C, 0, 0);
        OpOff(address + 0x10, 0, 0);
        MakeRptCmt(address + 0x10, "State Matrix");
           
        auto state_matrix = Dword(address + 0x10);
        auto event_count = Dword(address + 0x14);
        auto state_count = Dword(address + 0x18);

        for(event=0;event<event_count;event++)
        {
            for(state=0;state<state_count;state++)
            {   
                auto entry = state_matrix + 8 * (event * state_count + state);
                auto transition_func = Dword(entry + 0x04);

                comment = sprintf("State %02i  <- Event %02i  (NextState %02i)", state, event, Dword(entry + 0x00));

                MakeDword(entry + 0x00);
                MakeDword(entry + 0x04);
               
                if(transition_func != 0)
                {
                    comment = comment + " (Transition function)";
                    OpOff(entry + 0x04, 0, 0);
                   
                    if(substr(GetFunctionName(transition_func), 0, 4) == "sub_")
                    {
                        auto func_name = "";
                        func_name = sprintf("%s_state_%i_event_%i", name, state, event);
                        MakeNameEx(transition_func, func_name, SN_NOCHECK);
                        name_sets++;
                    }
                }
               
                MakeRptCmt(entry + 0x00, comment);
                MakeRptCmt(entry + 0x04, "");
            }
        }
        Message("Commented the table of %i states with %i events each. Named %i functions, because they had default names.\n", state_count, event_count, name_sets);
    }
    else
    {
        Message("Invalid structure, you have to run this script on a StateObject\n");
    }
   
Help us with datasheets - Help us with register dumps
magic lantern: 1Magic9991E1eWbGvrsx186GovYCXFbppY, server expenses: [email protected]
ONLY donate for things we have done, not for things you expect!

g3gg0

StateObject snippet was faulty. updated it.
Help us with datasheets - Help us with register dumps
magic lantern: 1Magic9991E1eWbGvrsx186GovYCXFbppY, server expenses: [email protected]
ONLY donate for things we have done, not for things you expect!

g3gg0

this script outputs a graphml document from the state transitions of an StateObject.
put the console output in a .graphml document and open it with yEd (http://www.yworks.com/de/products_yed_about.html).
then layout graph (hierarchical, with labels)
if you set the function names for the state transitions properly, the edges will show the event id and transition function name.


    auto state,event,reg,val,address, name_sets;
    auto comment = "";

    address = ScreenEA();
    name_sets = 0;
   
    auto type = GetString(Dword(address), -1, ASCSTR_C);
    auto name = GetString(Dword(address + 0x04), -1, ASCSTR_C);
   
    if(type == "StateObject")
    {
        auto state_matrix = Dword(address + 0x10);
        auto event_count = Dword(address + 0x14);
        auto state_count = Dword(address + 0x18);
       
        Message("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:y=\"http://www.yworks.com/xml/graphml\" xmlns:yed=\"http://www.yworks.com/xml/yed/3\" xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd\">");
        Message("  <key for=\"graphml\" id=\"d0\" yfiles.type=\"resources\"/><key for=\"port\" id=\"d1\" yfiles.type=\"portgraphics\"/><key for=\"port\" id=\"d2\" yfiles.type=\"portgeometry\"/> <key for=\"port\" id=\"d3\" yfiles.type=\"portuserdata\"/><key attr.name=\"url\" attr.type=\"string\" for=\"node\" id=\"d4\"/><key attr.name=\"description\" attr.type=\"string\" for=\"node\" id=\"d5\"/><key for=\"node\" id=\"d6\" yfiles.type=\"nodegraphics\"/><key attr.name=\"url\" attr.type=\"string\" for=\"edge\" id=\"d7\"/><key attr.name=\"description\" attr.type=\"string\" for=\"edge\" id=\"d8\"/><key for=\"edge\" id=\"d9\" yfiles.type=\"edgegraphics\"/>");
        Message("<graph edgedefault=\"directed\" id=\"G\">");
       
        for(state=0;state<state_count;state++)
        {
            Message("<node id=\"State%i\">", state);
            Message("<data key=\"d6\"><y:ShapeNode><y:NodeLabel alignment=\"center\" autoSizePolicy=\"content\" fontFamily=\"Dialog\" fontSize=\"12\" fontStyle=\"plain\" hasBackgroundColor=\"false\" hasLineColor=\"false\" modelName=\"custom\" textColor=\"#000000\" visible=\"true\">State %i</y:NodeLabel><y:LabelModel><y:Shape type=\"rectangle\"/></y:LabelModel></y:ShapeNode>", state);
            Message("</data></node>");

        }
       
        for(event=0;event<event_count;event++)
        {
            for(state=0;state<state_count;state++)
            {   
                auto entry = state_matrix + 8 * (event * state_count + state);
                auto transition_func = Dword(entry + 0x04);
                auto next_state = Dword(entry + 0x00);

                if(transition_func != 0)
                {
                    Message("<edge id=\"s%ie%i\" source=\"State%i\" target=\"State%i\">", state, event, state, next_state);

Message("<data key=\"d9\"><y:PolyLineEdge><y:Path sx=\"0.0\" sy=\"-15.0\" tx=\"-15.0\" ty=\"0.0\"><y:Point x=\"68.5\" y=\"-15.5\"/><y:Point x=\"38.0\" y=\"-15.5\"/><y:Point x=\"38.0\" y=\"15.0\"/></y:Path><y:LineStyle color=\"#000000\" type=\"line\" width=\"1.0\"/><y:Arrows source=\"none\" target=\"delta\"/><y:EdgeLabel alignment=\"center\" configuration=\"AutoFlippingLabel\" distance=\"2.0\" fontFamily=\"Dialog\" fontSize=\"12\" fontStyle=\"plain\" hasBackgroundColor=\"false\" hasLineColor=\"false\" height=\"18.701171875\" modelName=\"custom\" preferredPlacement=\"anywhere\" ratio=\"0.5\" textColor=\"#000000\" visible=\"true\" width=\"48.6953125\" x=\"5.65234375\" y=\"-20.945312500000007\">[%i] %s", event, GetFunctionName(transition_func));
                    Message("<y:LabelModel><y:SmartEdgeLabelModel autoRotationEnabled=\"false\" defaultAngle=\"0.0\" defaultDistance=\"10.0\"/></y:LabelModel><y:ModelParameter><y:SmartEdgeLabelModelParameter angle=\"0.0\" distance=\"30.0\" distanceToCenter=\"true\" position=\"right\" ratio=\"0.5\" segment=\"0\"/></y:ModelParameter><y:PreferredPlacementDescriptor angle=\"0.0\" angleOffsetOnRightSide=\"0\" angleReference=\"absolute\" angleRotationOnRightSide=\"co\" distance=\"-1.0\" frozen=\"true\" placement=\"anywhere\" side=\"anywhere\" sideReference=\"relative_to_edge_flow\"/></y:EdgeLabel><y:BendStyle smoothed=\"true\"/></y:PolyLineEdge></data>");
                    Message("</edge>");

                }
            }
        }
        Message("</graph></graphml>\n\n");
    }
    else
    {
        Message("Invalid structure, you have to run this script on a StateObject\n");
    }


Help us with datasheets - Help us with register dumps
magic lantern: 1Magic9991E1eWbGvrsx186GovYCXFbppY, server expenses: [email protected]
ONLY donate for things we have done, not for things you expect!

minimimi

I'm made a function rename script by the register_func.
Basically register_func is using function name to 1st argument . and 2nd argument is actual function pointer.

so now I have a problem to comvert &sub_xxxx in this script.(Thanks nanomad. this is based on your script)
sub_xxx is successfully comverted., but &sub_xxx is not successfully get correct function address by GetOperandValue...
Do you know how can I do that?
GetTypesomething(addr16) ????

    auto start_addr = MinEA();
    auto addr;
    auto func;
    auto func_name;
    auto addr16;
    auto dis,name,str_ptr, possible_name, func_start, response;
    response = 0;
    while(1) {
        Message("Looking from %x\n", start_addr);
        addr =  FindText(start_addr,SEARCH_DOWN|SEARCH_NEXT|SEARCH_REGEX, 0, 0, "register_func");
        dis = GetDisasm(addr);
        if ( addr == BADADDR )
            break;
        if(strstr(dis,"BL") == 0) {
           
            str_ptr = GetOperandValue(addr-4,1);
            possible_name = GetString(str_ptr, -1, ASCSTR_C);
            if(strlen(possible_name) == 0){
                 start_addr = addr + 4;
                 continue;
            }
           
            Message("  %s\n", possible_name);
            addr16 = addr-8;
            addr16 = addr16-4;
            func = GetOperandValue(addr16,1);
            dis = GetDisasm(addr16);
            Message("  %s\n", dis);
            func_name = GetFunctionName(func);
            Message("  %s\n", func_name);

            //check func_name length
            if(strlen(func_name) ==0){
                 Message("  Can't get func_name\n");
                 start_addr = addr + 4;
                 continue;
            }

            //check func_name already comverted
            if(strstr(func_name,"sub_") != 0){
                 Message("  Already comverted\n");
                 start_addr = addr + 4;
                 continue;
            }

            MakeName(func, possible_name);
            Message("Converted %s to %s\n", func_name, possible_name);
     
        }
        start_addr = addr + 4;
    }


minimimi

Sorry solved myself.

    auto start_addr = MinEA();
    auto addr;
    auto func;
    auto func_name;
    auto addr16;
    auto optype;
    auto equal_addr;
    auto dis,name,str_ptr, possible_name, func_start, response;
    response = 0;
    while(1) {
        Message("Looking from %x\n", start_addr);
        addr =  FindText(start_addr,SEARCH_DOWN|SEARCH_NEXT|SEARCH_REGEX, 0, 0, "register_func");
        dis = GetDisasm(addr);
        if ( addr == BADADDR )
            break;
        if(strstr(dis,"BL") == 0) {
           
            str_ptr = GetOperandValue(addr-4,1);
            possible_name = GetString(str_ptr, -1, ASCSTR_C);
            if(strlen(possible_name) == 0){
                 start_addr = addr + 4;
                 continue;
            }
           
            Message("  %s\n", possible_name);
            addr16 = addr-8;
            addr16 = addr16-4;
           
            optype = GetOpType(addr16,1);
            dis = GetDisasm(addr16);
            Message("  %s %d\n", dis,optype);
            if(optype==2){
                func_name = GetOpnd(addr16,1);
                func_name = substr(func_name, 1, strlen(func_name));

            Message("  %s", func_name);
            }else{
                func = GetOperandValue(addr16,1);
                func_name = GetFunctionName(func);
            }
           
            Message("  %s\n",func_name);

            //check func_name length
            if(strlen(func_name) ==0){
                 Message("  Can't get func_name\n");
                 start_addr = addr + 4;
                 continue;
            }

            //check func_name already comverted
            if(strstr(func_name,"sub_") != 0){
                 Message("  Already comverted\n");
                 start_addr = addr + 4;
                 continue;
            }

            MakeName(func, possible_name);
            Message("Converted %s to %s\n", func_name, possible_name);
     
        }
        start_addr = addr + 4;
    }

1%

Possible to port some of the arm console stuff to ida? Like the robo naming script and the decompiler?

minimimi

I made a small python code which will guess func name from IDA decompiled text.
Currently only phase one guessing method implemented.

this code automatically guess funcname and output a IDA script.

Current result is
Total func converted = 1258/18275


python code is
# coding=utf-8
import sys
import re

argvs = sys.argv
argc = len(argvs)

def parseDryDbgMsg(strFname,strCode,dicParams):
    lstCode1 = strCode.split('"')
    if(len(lstCode1) < 2):
        return ""

    strRet = ""
    lstRet = []
    lstCode = lstCode1[1].split(" ")
    #parse all lines
    for strT in lstCode:
        if(len(strT) == 0):                   continue;
        if(re.match('.*\\%',strT) != None):   continue;
        if(re.match(":",strT) != None):       continue;
        if(re.match("<-",strT) != None):      continue;
        if(re.match("->",strT) != None):      continue;
        if(re.match("ERR",strT) != None):     continue;
        if(re.match("#",strT) != None):       continue;
        if(re.match("!",strT) != None):       continue;
        if(re.match("=",strT) != None):       continue;
        if(re.match("\\(",strT) != None):     continue;
        if(re.match("\\)",strT) != None):     continue;
        if(re.match("^.*\\.c",strT) != None): continue;
        if(re.match("Unknown",strT) != None): continue;
        if(re.match(">",strT) != None):       continue;
        if(re.match("<",strT) != None):       continue;
        if(re.match("\\+",strT) != None):     continue;
        if(re.match("\\@",strT) != None):     continue;
        if(re.match("\\\n",strT) != None):    continue;
        strT = re.sub("\\*+","",strT)
        strT = re.sub(":","",strT)
        strT = re.sub("\\(","",strT)
        strT = re.sub("\\)","",strT)
        strT = re.sub("\\.+","",strT)
        strT = re.sub("\\,","",strT)
        strT = re.sub("-+","",strT)
        strT = re.sub("\\[","",strT)
#        print strT

        if(len(strT)):
            if(re.search("]",strT) != None):
                strT = re.sub("]","_",strT);
                strRet = strRet + strT
            else:
                strRet = strRet + strT
                strRet = strRet + " ";
    #parse result
    lstRet = strRet.split(" ")
    for strParam in lstRet:
        if(len(strParam)):
            if strParam in dicParams:
                dicParams[strParam] = dicParams[strParam] + 1
#                print "%s      %s " % (dicParams[strParam],strParam)
            else:
                dicParams[strParam] = 1;

def PrepareFuncCode(lstFuncCode):
    #get original funcname
    lstLine = lstFuncCode[0].split('(');
    strFname = re.sub("^.* ","",lstLine[0])
    if(len(strFname) == 0): return

#    print strFname

    dicParams = {}
    for strCode in lstFuncCode:
        if(strCode.find('DryosDebugMsg') != -1):
            parseDryDbgMsg(strFname,strCode,dicParams);

    #find most counted key
    strNFname = "";
    intCount = 0;
    for k, v in dicParams.items():
        if(intCount < v):
            strNFname = k
            intCount = v

    if(len(strNFname) < 8):
        return

#    print "%s      %s " % (dicParams[strNFname],strNFname)
    #Dsiplay result
    if(intCount > 1):
        print "MakeName(%s,%s);" % (strFname,strNFname)
        return 1
    return 0

def main(argvs,argc):
    intFuncnum = 0
    intPrevfuncnum = 0
    lstFunc = list()
    strFname = ""
    intConvNum = 0;

    #read lines
    for strLine in open(argvs[1], 'r'):

        #Split each funcs
        if(strLine.find("//----- ") != -1):
            intFuncnum = intFuncnum + 1

        if(intPrevfuncnum < intFuncnum): #enter newfunc
            if(len(lstFunc)):
#                print lstFunc
                if(PrepareFuncCode(lstFunc)):
                    intConvNum = intConvNum + 1
                del lstFunc[:]
            bFirstLine = 1
            intPrevfuncnum = intFuncnum
        else:
            if(intFuncnum >=1):
                lstFunc.append(strLine)

    print "Total func converted = %d/%d" % (intConvNum,intFuncnum)






main(argvs,argc)

minimimi

Updated . save here for me.
about 3000 funcstions guessed now.

Usage: python ./main.py disasm.c | sort | uniq



Modified
on 6D DryosDebugMessage is moved to RAM space. so you may change a search key from DryosDebugMessage to v67C8

minimimi

Updated func-guess by register_func  .

Previously, not actually convert   names.


minimimi

MakeFunction to STMFD.
When I use CHDK.idc , nanomad's script not working. Because almost STMFD section is already done with MakeCode.
But It's not set a function styles (Keyboard shortcut p). So this script will automachically find STMFD , and MakeFunction those codes.


  auto sb = MinEA();
  auto se = MaxEA();
  auto a, c, w, d;
  auto nexf;

  c = 0;
  for (a=sb; a<se; a=a+4) {
    w = Word(a-2);
    d = Word(a+2);
   //0xBDE8
    if ((d==0xE92D) && (w == 0xE8BD) && !strlen(GetFunctionName(a))) {
   
      MakeFunction(a,BADADDR);
      Message("MakeFunc %x %s\n",a, GetFunctionName(a));
      c = c+1;
    }
  }

nanomad

I used to do that, but then I realized you should also check if the prev instruction is code or not beacuse some functions actually mangle the registers before calling STMFD
EOS 1100D | EOS 650 (No, I didn't forget the D) | Ye Olde Canon EF Lenses ('87): 50 f/1.8 - 28 f/2.8 - 70-210 f/4 | EF-S 18-55 f/3.5-5.6 | Metz 36 AF-5


1%

Problem is getting the ram segment into arm console along with FW. When I run name funcs and make an IDC it gets all confused since ram segment wasn't loaded at the same time.

minimimi

nanomad:
Yes correct! I know this problem but it's not so big problem, I think . So just *now* I'm not supported it.
Do you have a problem on your environment?
I'm checking prev instruction with word(addr -4). Does not enouth?

A1ex:
Thanks for pointing this . But IDA script is really inconvinience. So  I need to learn IDA python first.

1%:
Yes I know it. IDA script is not supported bigger size of split segment current code.  THe "for" function is not working....

minimimi

Oh, Alex you already have simmuler codes.
name_funcx.py is really simmuler with my work. And I think it's a more better with mine.
Anyway, try to port it. but IDA script has no dictionaly...

Quote from: a1ex on April 15, 2013, 10:04:34 AM
You can try to port these (or just use them to save an IDC):

https://github.com/alexdu/ARM-console/blob/master/scripts/guessfunc.py
http://a1ex.magiclantern.fm/bleeding-edge/name_funcx.py

nanomad

You can use the IDA python interface ;)
EOS 1100D | EOS 650 (No, I didn't forget the D) | Ye Olde Canon EF Lenses ('87): 50 f/1.8 - 28 f/2.8 - 70-210 f/4 | EF-S 18-55 f/3.5-5.6 | Metz 36 AF-5

minimimi

Lesson1 IDA python version of my function-nized by STMFD.(lol

from idaapi import *

# Get current ea
adStea = MinEA()
adEdea = MaxEA()

intCount = 0;
for ad in range(adStea,adEdea,4):
    insPre = get_word(ad-2)
    insCur = get_word(ad+2)
    strFname = ""
    strFname = get_func_name(ad)
    if((insCur==0xE92D) and (insPre==0xE8BD) and not (strFname==None)):
        MakeFunction(ad,BADADDR);
        print "MakeFunc %x %s\n" % (ad, strFname)
        intCount = intCount + 1

print "TotalCount=%d\n" % intCount


1%

nanomad's script can also name PD functions

minimimi

code added on bitbacket
https://bitbucket.org/minimimi/ml-idc/src/d6d5e1c6b918cada4a828c54bfd592a04f374078/ml.py?at=default

How to use it.
1: Get and use CHDK.idc and related files.
2: ml.py from IDA menu (File -> script file)

This script is now supporting MakeFunc by STMFD and MakeName by register_func
change log
- [STMFD] added nanomad's suggestion related codes

minimimi

ported Alex's method 1. But something wrong.....

minimimi

https://bitbucket.org/minimimi/ml-idc/src/
porting from Alex's method 2. and solved some valiable bug in method 1