Code:

#include <idc.idc> // Step 2: idc to resolve EBP offsets to real addresses static resolve_offsets ( ea , n ) { auto OpVal , realaddress , patchoffset , i ; OpVal = GetOperandValue ( ea , n ); if ( OpVal > 0x400000 ) { return; // we've already converted this operand } // calculate the real address realaddress = GetOperandValue ( ea , n ) + 0x102200 ; // calculate the offset where the operand begins in the instruction for ( i = 0 ; i < ItemSize ( ea ) - 3 ; i ++) { if ( Dword ( ea + i ) == OpVal ) { // Pattern found patchoffset = ( ea + i ); } } // patch in the real displacement PatchDword ( patchoffset , realaddress ); // undefine the instruction so it will be reanalyzed fresh later MakeUnkn ( ea , 0 ); } static main () { auto startea , endea , ea , n , nextea , OpVal , uFlags , count1 , count2 , count3 ; startea = 0x403270 ; // first occurence of [ebp+30xxxx] offset endea = 0x404DCC ; // determined from idc in Step 1 // Use some counters to check that all operands were handled properly. // Remaining errors likely mean we didn't make the correct analysis // after running the decrypt script in Step 1. // Go back, correct those instructions and rerun this script. count1 = 0 ; count2 = 0 ; count3 = 0 ; ///////////////////////////////////////////////////////////////////////// // Step 1: // Convert operands of the form "[ebp+30xxxxh]" to a real offset ///////////////////////////////////////////////////////////////////////// ea = startea ; Message ( "

Converting EBP offset operands to real addresses

" ); while ( ea != BADADDR ) { // calculate next instruction pointer before we modify anything nextea = NextHead ( ea , endea ); // check both the first(0) and second(1) operand of the instruction for ( n = 0 ; n < 2 ; n ++) { // for all instructions with an offset in the form of "[ebp+" if( strstr ( GetOpnd ( ea , n ), "[ebp+" ) != - 1 ) { count1 = count1 + 1 ; resolve_offsets ( ea , n ); } } ea = nextea ; // next instruction } // Reanalyze AnalyzeArea ( startea , endea ); ///////////////////////////////////////////////////////////////////////// // Step 2: // Make a second pass at autoanalysing operands // still in the form of "[ebp+" ///////////////////////////////////////////////////////////////////////// ea = startea ; Message ( "Running a second pass at autoanalysis

" ); while ( ea != BADADDR ) { nextea = NextHead ( ea , endea ); for ( n = 0 ; n < 2 ; n ++) { // for all instructions with an offset in the form of "[ebp+" if( strstr ( GetOpnd ( ea , n ), "[ebp+" ) != - 1 ) { count2 = count2 + 1 ; // Get operand value OpVal = GetOperandValue ( ea , n ); // Get value of internal flags to see how IDA // has defined the operand to this point uFlags = GetFlags ( OpVal ); if( isData ( uFlags )) { // If operand offset is already defined as 'data' // then we only need to reanalyze the instruction // to get IDA to resolve the xref // undefine the instruction so it will be reanalyzed fresh MakeUnkn ( ea , 0 ); } else if( isUnknown ( uFlags )) { // If operand offset is defined as 'unknown', create // a data xref at the operand address and reanalyze add_dref ( ea , OpVal , XREF_USER | dr_O ); MakeUnkn ( ea , 0 ); } else { // GetFlags(OpVal) indicates that what is left over is // defined as 'isTail'. Undefine both the operand address // and the calling instruction and let IDA reanalyze MakeUnkn ( OpVal , 0 ); MakeUnkn ( ea , 0 ); } } } ea = nextea ; } // Reanalyze AnalyzeArea ( startea , endea ); ///////////////////////////////////////////////////////////////////////// // Step 3: // Finally, let's inform ourselves of which instructions are still // in the form of "[ebp+" and should be checked manually. // The offsets will be highlighted in red by IDA as well. ///////////////////////////////////////////////////////////////////////// ea = startea ; Message ( "The following instructions (if any) are still in error and \ should be fixed manually before rerunning this script

" ); while ( ea != BADADDR ) { nextea = NextHead ( ea , endea ); for ( n = 0 ; n < 2 ; n ++) { // for all instructions with offset *still* // in the form of "[ebp+" if( strstr ( GetOpnd ( ea , n ), "[ebp+" ) != - 1 ) { count3 = count3 + 1 ; Message ( "%d 0x%08X %s

" , count3 , ea , GetOpnd ( ea , n )); } } ea = nextea ; } Message ( "

%d / %d operands analysed correctly on first pass

" , count1 - count2 , count1 ); Message ( "%d / %d operands corrected on second pass

" , count2 - count3 , count1 ); ///////////////////////////////////////////////////////////////////////// Message ( "...Done

" ); }