=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- From: MJM Subject: Re:contribution .... -------------------------------------------------------------------------------- Hi, Here follow the new file for contribution. --------------8<--------------8<--------------8<--------------8<--------------8<--------------8<-------------- // __FILE__ = "MSVC32.idc" // This file contain helpers mostly for disassembling // Microsoft 32bits executable image... #include // This function returns the segment start address static MySegByName( segName ) { auto segEA; for( segEA = FirstSeg(); segEA != BADADDR; segEA = NextSeg( segEA ) ) { if ( segName == SegName(segEA) ) break; } return segEA; } ////////////////////////////////////// // Ascii(long ea) ////////////////////////////////////// // Returns the exact C string at a // particular ea. This ea require to be // a defined ea, and to be the head of // Could be mixed with Ascii(Head(ea)) static Ascii( ea ) { auto str,c,i; str = ""; for(i=0; i < ItemSize(ea); i++) { str = form("%s%c",str,byteValue(GetFlags(ea+i))); } return str; } ////////////////////////////////////// // ltrim(char* str) ////////////////////////////////////// // Returns a copy of a string without // leading blank characters (space & tab ). static ltrim( str ) { auto i, l, c; l = strlen(str); for(i = 0; i < l; i++) { c = substr( str, i, i+1 ); if ( (c != " " ) && (c != char(9)) ) break; } str = substr(str,i,-1); return str; } ////////////////////////////////////// // rtrim(char *str) ////////////////////////////////////// // Returns a copy of a string without // trailing blank characters (space & tab ). static rtrim( str ) { auto i, l, c; l = strlen(str); for(i = l; i > 0; i--) { c = substr( str, i-1, i ); if ( (c != " ") && ( c != "\t" ) ) break; } str = substr(str,0,i); return str; } ////////////////////////////////////// // trim(char *str) ////////////////////////////////////// // Returns a copy of a string without // both leading & trailing blank characters (space & tab ). static trim( str ) { return rtrim( ltrim( str ) ); } ////////////////////////////////////// // strchr( char* str, char* c) ////////////////////////////////////// // Like in C runtime, recover the first // character c in str s. // Return postion in s or -1 if c does // not exists. static strchr( str, c ) { auto i, l, s; l = strlen( str ); for( i = 0; i < l; i++ ) { s = substr( str, i, i+1 ); if ( s == c ) break; } return ((i==l)?-1:i); } ////////////////////////////////////// // ProposeName(long ea, char* name) ////////////////////////////////////// // Non destructive name a paerticular ea. // If specified ea got no name, it takes // the name, otherwise add a comment at // ea to store the name. static ProposeName( ea , name ) { auto cmt; cmt = RptCmt( ea ); if ( strlen(cmt) != 0 ) cmt = cmt + "\n" + name; else cmt = name; cmt = cmt + "\nproposed name"; if ( (GetFlags(ea) & FF_NAME) == 0) { if (MakeName(ea,name) == 1) { return; } } if (Name(ea) == name) return; MakeRptCmt(ea,cmt); } ////////////////////////////////////// // Head(long ea) ////////////////////////////////////// // Get ea of the first byte of the item // which overlap a specific ea. static Head( ea ) { return PrevHead(NextHead(ea)); } ////////////////////////////////////// // Unknown(long ea, long length) ////////////////////////////////////// // Mark the ea as unknown for a length // of length, but don't propagate. static Unknown( ea, length ) { auto i; for(i=0; i < length; i++) { MakeUnkn(ea+i,0); } } ////////////////////////////////////// // TrueXreferee(long ea) ////////////////////////////////////// // Get the true ea that refer (index) // this ea. This function retrun the // address of the offset corresponding // to that ea static TrueXreferee( ea ) { auto xref, retval; auto i, len, fxoff; for(xref = RfirstB(ea); xref != BADADDR; xref = RnextB(ea,xref)) { len = ItemSize(xref); for(i = 0; i < len; i++) { fxoff = GetFixupTgtOff(xref+i); if (fxoff != ea) continue; return xref+i; } } for(xref = DfirstB(ea); xref != BADADDR; xref = DnextB(ea,xref)) { len = ItemSize(xref); for(i = 0; i < len; i++) { fxoff = GetFixupTgtOff(xref+i); if (fxoff != ea) continue; return xref+i; } } return BADADDR; } ////////////////////////////////////// // T a g W i t h M S _ M a p ////////////////////////////////////// // This command generate debug names // according to a Microsoft specific // MAP file. // static TagWithMS_Map() { auto MapFile, hFile, onHeader; auto str, p, w, w1, w2, w3, w4, w5, i, ea, flg; MapFile = AskFile( "*.map", "Choose a Microsoft MAP file to parse:"); hFile = fopen( MapFile, "r"); if (hFile == 0) { Message("*Aborted*\n"); return; } onHeader = 1; for( str = readstr( hFile ); str != -1; str = readstr( hFile )) { if (onHeader < 0) { onHeader = 0; continue; } for( i=1; i < 6; i++ ) { str = ltrim(str); p = strchr( str, " " ); w = rtrim(substr( str, 0, p)); str = substr( str, p , -1); if (i == 1) w1 = w; if (i == 2) w2 = w; if (i == 3) w3 = w; if (i == 4) w4 = w; if (i == 5) w5 = w; } if (onHeader == 1) { if (w1 =="Address") { onHeader = -1; } } if (onHeader != 0) continue; ea = xtol(w3); if (SegName(ea) == ".idata") continue; MakeName(ea,""); if (LocByName(w2) != BADADDR) { // Already used... Workarround w2 = form("%s_%08x",w2,ea); } if (w4 == "f") { MakeFunction(ea,-1); } else { w5 = w4; } MakeComm(ea,"__FILE__:"+w5); MakeName(ea,w2); } Message("\nMicrosoft debug MAP file loaded!\n"); } ////////////////////////////////////// // M o v e M e m ////////////////////////////////////// // This command allow moving bytes // into IDA memory space. // Select to area to move, start the command, // follow the instructions. // This function works differently depending // on how the selection is made ( begin->end vs end->begin ) // static MoveMem() { auto begin, end, sense, srcEA, tgtEA; auto i, value, fillup, lim; auto fxtyp, fxsel, fxoff, fxdispl; begin = SelStart(); end = SelEnd() - 1; if (begin == BADADDR) { Warning("No memory range selected!\nAction aborted."); return 0; } sense = 1; srcEA = begin; if (ScreenEA() == begin) { sense = -1; srcEA = end; } tgtEA = AskAddr(srcEA,form("Enter new block address for %08Xh (%s)",sense==1?"normal":"REVERSE")); if ((tgtEA > begin) && (tgtEA <= end)) { Warning("Memory block overlap...\nTry use %s mode.",sense==1?"reverse":"forward"); return 0; } if (AskYN(0,form(form("%s\n%s\n%s\n \nSure you want to proceed?", "You are about to move memory block:", " from: %08Xh - %08Xh", " to: %08Xh - %08Xh (data will be lost)"), srcEA, srcEA + ((end - begin)*sense), tgtEA, tgtEA + ((end - begin)*sense))) != 1) return 0; fillup = 0; fillup = AskAddr(fillup,"Enter pattern for quitting region..."); fillup = fillup & 0x0FF; lim = (end - begin) + 1; for(i=0; i < lim; i++) { value = Byte(srcEA + (i*sense)); fxtyp = GetFixupTgtType(srcEA + (i*sense)); fxsel = GetFixupTgtSel(srcEA + (i*sense)); fxoff = GetFixupTgtOff(srcEA + (i*sense)); fxdispl = GetFixupTgtDispl(srcEA + (i*sense)); if (fxsel != BADADDR) DelFixup(srcEA + (i*sense)); PatchByte(srcEA + (i*sense), fillup); PatchByte(tgtEA + (i*sense),value); if (fxsel != BADADDR) SetFixup(tgtEA + (i*sense),fxtyp, fxsel,fxoff,fxdispl); } } ////////////////////////////////////// // M o v e M e m W i t h F i x u p ////////////////////////////////////// // This command allow moving bytes // into IDA memory space, and adjust offsets. // Select to area to move, start the command, // follow the instructions. // This function works differently depending // on how the selection is made ( begin->end vs end->begin ) // static MoveMemWithFixup() { auto begin, end, sense, srcEA, tgtEA; auto i, value, fillup, lim; auto fxtyp, fxsel, fxoff, fxdispl; auto fxtable, fxwas, fxnow, j, sa, ta; begin = SelStart(); end = SelEnd() - 1; if (begin == BADADDR) { Warning("No memory range selected!\nAction aborted."); return 0; } sense = 1; srcEA = begin; if (ScreenEA() == begin) { sense = -1; srcEA = end; } tgtEA = AskAddr(srcEA,form("Enter new block address for %08Xh (%s)",sense==1?"normal":"REVERSE")); if ((tgtEA > begin) && (tgtEA <= end)) { Warning("Memory block overlap...\nTry use %s mode.",sense==1?"reverse":"forward"); return 0; } if (AskYN(0,form(form("%s\n%s\n%s\n \nSure you want to proceed?", "You are about to move memory block:", " from: %08Xh - %08Xh", " to: %08Xh - %08Xh (data will be lost)"), srcEA, srcEA + ((end - begin)*sense), tgtEA, tgtEA + ((end - begin)*sense))) != 1) return 0; fillup = 0; fillup = AskAddr(fillup,"Enter pattern for quitting region..."); fillup = fillup & 0x0FF; lim = (end - begin) + 1; for(i=0; i < lim; i++) { value = Byte(srcEA + (i*sense)); fxtyp = GetFixupTgtType(srcEA + (i*sense)); fxsel = GetFixupTgtSel(srcEA + (i*sense)); fxoff = GetFixupTgtOff(srcEA + (i*sense)); fxdispl = GetFixupTgtDispl(srcEA + (i*sense)); if (fxsel != BADADDR) DelFixup(srcEA + (i*sense)); PatchByte(srcEA + (i*sense), fillup); PatchByte(tgtEA + (i*sense),value); if (fxsel != BADADDR) { SetFixup(tgtEA + (i*sense),fxtyp, fxsel,fxoff,fxdispl); sa = srcEA + (i*sense); ta = tgtEA + (i*sense); fxtable = LocByName(form("FIXUP_%08X",((sa & 0x00FFF000) - 0x00400000))); fxwas = sa & 0x0FFF; fxnow = BADADDR; for(j=fxtable+8; j < fxtable+Dword(fxtable+4); j = j+2) { if ( (Word(j) & 0x0FFF) == fxwas ) { fxnow = (ta & 0x0FFF) | ( Word(j) & 0x0F000 ); Message("fxtable=0x%08lXh, was:0x%04lXh, now:%04lXh\n",fxtable,fxwas,fxnow); PatchWord(j, fxnow ); break; } } if (fxnow == BADADDR) { Warning("Huh! I can't find fixup information for %08lXh / %08lXh", sa,ta); } } } } ////////////////////////////////////// // C o p y M e m ////////////////////////////////////// // This command allow copy bytes // into IDA memory space. // Select to area to move, start the command, // follow the instructions. // This function works differently depending // on how the selection is made ( begin->end vs end->begin ) // static CopyMem() { auto begin, end, sense, srcEA, tgtEA; auto i, value, fillup, lim; auto fxtyp, fxsel, fxoff, fxdispl; begin = SelStart(); end = SelEnd() - 1; if (begin == BADADDR) { Warning("No memory range selected!\nAction aborted."); return 0; } sense = 1; srcEA = begin; if (ScreenEA() == begin) { sense = -1; srcEA = end; } tgtEA = AskAddr(srcEA,form("Enter new block address for %08Xh (%s)",sense==1?"normal":"REVERSE")); if ((tgtEA > begin) && (tgtEA <= end)) { Warning("Memory block overlap...\nTry use %s mode.",sense==1?"reverse":"forward"); return 0; } if (AskYN(0,form(form("%s\n%s\n%s\n \nSure you want to proceed?", "You are about to copy memory block:", " from: %08Xh - %08Xh", " to: %08Xh - %08Xh (data will be lost)"), srcEA, srcEA + ((end - begin)*sense), tgtEA, tgtEA + ((end - begin)*sense))) != 1) return 0; lim = (end - begin) + 1; for(i=0; i < lim; i++) { value = Byte(srcEA + (i*sense)); PatchByte(tgtEA + (i*sense),value); } } --------------8<--------------8<--------------8<--------------8<--------------8<--------------8<-------------- Jean-Marc