Guest User

DumpInfo.idc for IDA

a guest
Oct 16th, 2016
246
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 48.17 KB | None | 0 0
  1. /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2. ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
  3. DumpInfo.IDC  v0.0.0                      By: J.C. Roberts                                <freeware>                          
  4. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  5.     The idea behind DumpInfo was to dump only _user_ created information from the disassembly into
  6.     text a file for your notes or into and IDC script for porting to a new disassembly. Since the
  7.     accuracy of IDA is constantly improving, sometimes the only thing I've wanted to save are my
  8.     comments and names from an old disassembly and just let a newer version of IDA do what it does
  9.     best when creating a new disassembly.
  10.  
  11.     Unfortunately, a lot of automatically created names, comments and such are maked as _user_
  12.     created rather than auto-generated. I've worked around this where possible by using filters.
  13.  
  14.     I hope you find it useful.
  15.    
  16.     -JCR
  17.  
  18. ----------------------------------------------------------------------------------------------------
  19. Features:    
  20.  
  21. --> The scope of operation is user defined.
  22.         1.) The Entire Disassembly.        
  23.         2.) Currently Selected Area.              
  24.         3.) A Single Segment.           //If you've ever screwed up your segmentation...
  25.         4.) A Single Function.
  26.  
  27. --> It can export the following types of IDA information:
  28.         1.) Regular Function Comments
  29.         2.) Repeatable Function Comments
  30.         3.) Regular Indented Comments
  31.         4.) Repeatable Indented Comments
  32.         5.) Anterior Lines
  33.         6.) Posterior lines
  34.         7.) User Defined Names
  35.         8.) Code String References      (Not Exported To IDC Format)
  36.         9.) Data String References
  37.  
  38. --> It can write the output to either a file or the message window in case you just want
  39.     to quicky see what's in an area rather than save the information.
  40.  
  41. --> It can create two different types of output, either simple text or an IDC script for
  42.     reimporting the information into a new disassembly.
  43.    
  44. --> Since dumping information from the entire data base can take some time, I've incorporated a
  45.     simple progress meter, so you know what's happening. Even the IDC files that this produces for
  46.     porting your info into a new disassembly have a progress indicator of sorts.
  47.    
  48. --> I've done what I can for the speed of this thing but it's just a first draft. I'll probably
  49.     optimize it further in future revisions.
  50.  
  51. ----------------------------------------------------------------------------------------------------
  52. Usage:
  53.     There are defined options (OPT_...) and defined types (TYP_...). The OPTions are used to either
  54.     allow of disallow specific info from being written as well as where (file or message window) and
  55.     how (as IDC or simple text).  You can control the options in main() by commenting out the info
  56.     you don't want. On the other hand, the TYPes are used during the program execution to tell the
  57.     writeLine() function _WHAT_ kind of info it's supposed to write so it can decide _HOW_ it will
  58.     be written.
  59.    
  60.     Decide if you want a file written                                 -    OPT_MAK_FILE
  61.     Decide the if you want an IDC script or a text file               -    OPT_IDC_FILE
  62.     Decide what kind of info you want dumped                          -    All the rest :)
  63.    
  64.         Comments:
  65.             OPT_REG_FCOM   -   Regular Function Comments                        (Reg FCom)
  66.             OPT_RPT_FCOM   -   Repeatable Function Comments                     (Rpt FCom)
  67.             OPT_REG_ICOM   -   Regular Indented Comments                        (Reg ICom)
  68.             OPT_RPT_ICOM   -   Repeatable Indented Comments                     (Rep ICom)
  69.  
  70.         Lines:
  71.             OPT_ANT_LINE   -   Anterior Lines                                   (AntLn#X)
  72.             OPT_POS_LINE   -   Posterior Lines                                  (PosLn#X)
  73.        
  74.         Names:
  75.             OPT_USR_NAME   -   User Names (Non-Autogenerated)                   (UserName)
  76.  
  77.         Strings:
  78.             OPT_STR_CODE   -   String References From Code (Operand = Offset)   (StrCodeX)
  79.             OPT_STR_DATA   -   String References In Data                        (Str Data)              
  80.  
  81.  
  82.     The text files created are marked the information type with the text shown above in parenthesis
  83.     where the "X" is a number. On lines the number represents the Anterior/Posterior line number. On
  84.     string references from code, the "X" number represents the operand where the data was found.
  85.    
  86.     All string gathering is based on the NAME of the string. If the name of the string doesn't start
  87.     with the default "a" or the more useful "str_" it will not be found. Since I couldn't figure out
  88.     how to get the string prefix from the IDA settings in IDA.CFG (assuming it's even possible), we
  89.     are stuck with the hard coded prefixes above and you'll need to change them if you use a
  90.     different prefix.
  91.  
  92.     Sting references from code are not included in IDC files, since there's no point in it.
  93.  
  94. ----------------------------------------------------------------------------------------------------
  95. Annoyances & Work-Arounds:
  96.     0.) There's no way that I've found to REALLY differentiate between USER created and script/IDA
  97.         created comments, names et al... I'm still looking for a way. Until I figure it out
  98.         (assuming it's actually possible), we're stuck with _ALL_ non-autogenerated comments, names,
  99.         lines & etc... Major Bummer!
  100.    
  101.         Using the FF_NAME, FF_COMM and FF_LINE flags still results in tons of stuff that was either
  102.         autogenerated during the disassembly or created via other IDC scripts.
  103.  
  104.         I've dealt with this by using a (slow) string filter, xFiter(), to look for the commonly
  105.         created strings. This filter can be shut off in main() via the OPT_USE_FLTR. The function
  106.         is set for win32 stuff, so you may need to edit it as you see fit.
  107.        
  108.         THERE ARE SOME SERIOUS DISADVANTAGES TO USING A TEXT FILTER TO IGNORE SPECIFIC TEXT
  109.         PATTERNS, SO BE AWARE OF WHAT TEXT STRINGS WILL BE FILTERED OUT...
  110.    
  111.    
  112.     1.) You may get a "varriable not defined" error on IDA_STATUS_WORK or IDA_STATUS_READY if your
  113.         IDC.IDC hasn't been updated. There was a missing #endif/#ifdef pair in the v4.1.4 release.
  114.         It should  read:
  115.             #endif                                                                            
  116.             #define IDA_STATUS_READY    0 // READY     IDA is idle                            
  117.             #define IDA_STATUS_THINKING 1 // THINKING  Analyzing but the user may press keys  
  118.             #define IDA_STATUS_WAITING  2 // WAITING   Waiting for the user input              
  119.             #define IDA_STATUS_WORK     3 // BUSY      IDA is busy                            
  120.             #ifdef _notdefinedsymbol                                                          
  121.  
  122.  
  123.     2.) The FindA() function has a bug on lines greater than 999, so getting more anterior lines
  124.         than that isn't possible even though the MAX_ITEM_LINES value set in IDA.CFG is 5000. Also,
  125.         there's currently no way to read the MAX_ITEM_LINES value set by IDA.CFG -In a nutshell, if
  126.         you have more than 999 Anterior Lines on a single EA, then you're hosed.
  127.        
  128.         The Ant/Pos Line loop is hard coded to read from 0 to 999. If we're ever able to get the
  129.         info from IDA.CFG and the LineA() gets fixed, I'll have to recode things to access the full
  130.         number of lines.
  131.  
  132.  
  133.     3.) Both FindA() and FindB() return 0 (Failure) if a line contains nothing more than a
  134.         NewLine (/n). I've gotten around this problem by using a reverse counter from 999 to 0
  135.         to find the last line with any text. If empty lines are used at the end (the higher line
  136.         numbers) of an Anterior or posterior comment, they are not read and/or saved. The reverse
  137.         counter is necessary because if you have text on line #1 and nothing on line #0 then import
  138.         only Line #1 and not the empty Line #0, the line with text is not visible.
  139.    
  140.  
  141.     4.) There's a 64K limit to main(), so I used the same type of IDC stucture as Ilfak does when
  142.         creating the IDC file from the "Dump Database to IDC" menu function. e.g.
  143.             main(){ parts();}
  144.             part_0() { }
  145.             part_1() { }
  146.             part_X...
  147.             parts() { part_0(); part_1(); partX... }
  148.    
  149.         I've got it set so each part_X has 1000 instruction lines but this could be increased.
  150.  
  151. ----------------------------------------------------------------------------------------------------
  152. Future Plans:
  153.     1.) Make a decent UI for entering options rather than (un)commenting lines.
  154.    
  155.     2.) Add a BaseAddress0/AskBase/ChooseFunction kind of thing, so you can port comments to specific
  156.         places in the new disassembly. It would be real a useful addition for restoring _ALL_ your
  157.         comments when you're dealing with a new version of an executable or you've augmented the
  158.         line by line comments of a FLIRT recognized function or library.
  159.  
  160.     3.) Figure out how to write this as a plugin -It might be faster that way and make it easier for
  161.         adding plan #1.
  162.    
  163. ----------------------------------------------------------------------------------------------------
  164. Bugs:    -Tested On IDA Version 4.1.4.483 (With Fixes)
  165.     No Known Bugs... :)
  166.  
  167. ----------------------------------------------------------------------------------------------------
  168. Revisions:
  169.     2000.10.17      First Version       v0.0.0      
  170.    
  171. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
  172.  
  173. //__________________________________________________________________________________________________
  174. //ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
  175. // Start Code
  176. //--------------------------------------------------------------------------------------------------
  177. #include <idc.idc>
  178.  
  179. #define FALSE 0
  180. #define TRUE 1
  181.  
  182. #define OPT_MAK_FILE 0x00000001L    //  Write to file   - OR - Write to message window
  183. #define OPT_IDC_FILE 0x00000002L    //  Create IDC file - OR - Create text file.
  184. #define OPT_USE_FLTR 0x00000004L    //  Use Text Filter
  185.  
  186. #define OPT_REG_FCOM 0x00000010L    //  Regular Function Comments      
  187. #define OPT_RPT_FCOM 0x00000020L    //  Repeatable Function Comments  
  188. #define OPT_REG_ICOM 0x00000040L    //  Regular Indented Comments      
  189. #define OPT_RPT_ICOM 0x00000080L    //  Repeatable Indented Comments  
  190. #define OPT_ANT_LINE 0x00000100L    //  Anterior Lines                
  191. #define OPT_POS_LINE 0x00000200L    //  Posterior Lines                
  192. #define OPT_USR_NAME 0x00000400L    //  User Names (Non-Autogenerated)
  193. #define OPT_STR_CODE 0x00000800L    //  String References From Code (Operand = Offset)
  194. #define OPT_STR_DATA 0x00001000L    //  String References In Data
  195.                                
  196. #define TYP_REG_FCOM 0x00010000L    //  Regular Function Comments      
  197. #define TYP_RPT_FCOM 0x00020000L    //  Repeatable Function Comments  
  198. #define TYP_REG_ICOM 0x00040000L    //  Regular Indented Comments      
  199. #define TYP_RPT_ICOM 0x00080000L    //  Repeatable Indented Comments  
  200. #define TYP_ANT_LINE 0x00100000L    //  Anterior Lines                
  201. #define TYP_POS_LINE 0x00200000L    //  Posterior Lines                
  202. #define TYP_USR_NAME 0x00400000L    //  User Names (Non-Autogenerated)
  203. #define TYP_STR_CODE 0x00800000L    //  String References From Code (Operand = Offset)
  204. #define TYP_STR_DATA 0x01000000L    //  String References In Data
  205.  
  206.  
  207.  
  208. //__________________________________________________________________________________________________
  209. //ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
  210. // FUNCTION: char* xFilter(char *)
  211. //--------------------------------------------------------------------------------------------------
  212. // Purpose: To find and remove commonly autogenerated comments and names.
  213. //
  214. // NOTES:
  215. //      I did what I could for the speed of this thing but string work is slow by nature.
  216. //      
  217. //--------------------------------------------------------------------------------------------------
  218. static xFilter(xTxt) {
  219.     auto xTmp;
  220.  
  221.     xTmp = substr(xTxt, 0, 1);
  222.    
  223.     // Length 1
  224.     if (xTmp == "_") xTxt = FALSE;                                          //NAME: stdlib
  225.     else if (xTmp == "?") xTxt = FALSE;                                     //NAME: libs
  226.     else xTmp = substr(xTxt, 0, 2);
  227.  
  228.     // Length 2
  229.     if (xTxt != FALSE) {
  230.         if (xTmp == "lp") xTxt = FALSE;                                     //COMMENT:
  231.         else if (xTmp == "dw") xTxt = FALSE;                                //COMMENT:
  232.         else if (xTmp == "fl") xTxt = FALSE;                                //COMMENT:
  233.         else if (xTmp == "j_") xTxt = FALSE;                                //NAME: jump subs
  234.         else xTmp = substr(xTxt, 0, 3);
  235.     }
  236.     // Length 3
  237.     if (xTxt != FALSE) {
  238.         if (xTmp == "int") xTxt = FALSE;                                    //COMMENT:
  239.         else if (xTmp == "int") xTxt = FALSE;                               //COMMENT:
  240.         else if (xTmp == "cch") xTxt = FALSE;                               //COMMENT:
  241.         else if (xTmp == "Msg") xTxt = FALSE;                               //COMMENT:
  242.         else if (xTmp == "unk") xTxt = FALSE;                               //NAME: unkown_libname
  243.         else if (xTmp == "HDC") xTxt = FALSE;                               //COMMENT: HDC
  244.         else xTmp = substr(xTxt, 0, 4);                                  
  245.     }                                                              
  246.     // Length 4                                                      
  247.     if (xTxt != FALSE) {
  248.         if (xTmp == "hWnd") xTxt = FALSE;                                   //COMMENT:
  249.         else if (xTmp == "void") xTxt = FALSE;                              //COMMENT:
  250.         else if (xTmp == "char") xTxt = FALSE;                              //COMMENT:
  251.         else if (xTmp == "hPre") xTxt = FALSE;                              //COMMENT:
  252.         else if (xTmp == "case") xTxt = FALSE;                              //COMMENT:
  253.         else if (xTmp == "hMem") xTxt = FALSE;                              //COMMENT:
  254.         else if (xTmp == "hKey") xTxt = FALSE;                              //COMMENT:
  255.         else if (xTmp == "yBot") xTxt = FALSE;                              //COMMENT: yBot
  256.         else if (xTmp == "xRig") xTxt = FALSE;                              //COMMENT: xRig
  257.         else if (xTmp == "yTop") xTxt = FALSE;                              //COMMENT: yTop
  258.         else if (xTmp == "xLef") xTxt = FALSE;                              //COMMENT: xLef
  259.         else if (xTmp == "wMsg") xTxt = FALSE;                              //COMMENT: wMsg
  260.         else if (xTmp == "UINT") xTxt = FALSE;                              //COMMENT:
  261.         else if (xTmp == "hRes") xTxt = FALSE;                              //COMMENT: hRes
  262.         else if (xTmp == "hDlg") xTxt = FALSE;                              //COMMENT: hDlg
  263.         else if (xTmp == "hCtl") xTxt = FALSE;                              //COMMENT: hCtl
  264.         else if (xTmp == "uCmd") xTxt = FALSE;                              //COMMENT: uCmd
  265.         else if (xTmp == "iMax") xTxt = FALSE;                              //COMMENT: iMax
  266.         else xTmp = substr(xTxt, 0, 5);                              
  267.     }                                                          
  268.     // Length 5
  269.     if (xTxt != FALSE) {
  270.         if (xTmp == "hHeap") xTxt = FALSE;                                  //COMMENT:
  271.         else if (xTmp == "hData") xTxt = FALSE;                             //COMMENT:
  272.         else if (xTmp == "const") xTxt = FALSE;                             //COMMENT:    
  273.         else if (xTmp == "hInst") xTxt = FALSE;                             //COMMENT:
  274.         else if (xTmp == "uExit") xTxt = FALSE;                             //COMMENT:
  275.         else if (xTmp == "hProc") xTxt = FALSE;                             //COMMENT:
  276.         else if (xTmp == "hFile") xTxt = FALSE;                             //COMMENT:
  277.         else if (xTmp == "nSize") xTxt = FALSE;                             //COMMENT:
  278.         else if (xTmp == "uType") xTxt = FALSE;                             //COMMENT: UINT
  279.         else if (xTmp == "hMenu") xTxt = FALSE;                             //COMMENT: hMenu
  280.         else if (xTmp == "nBuff") xTxt = FALSE;                             //COMMENT: nBuff
  281.         else if (xTmp == "nFile") xTxt = FALSE;                             //COMMENT: nFile
  282.         else if (xTmp == "nVolu") xTxt = FALSE;                             //COMMENT: nVolu
  283.         else if (xTmp == "hFind") xTxt = FALSE;                             //COMMENT: hFind
  284.        
  285.         else xTmp = substr(xTxt, 0, 6);
  286.     }
  287.     // Length 6
  288.     if (xTxt != FALSE) {
  289.         if (xTmp == "hModul") xTxt = FALSE;                                 //COMMENT:
  290.         else if (xTmp == "hObjec") xTxt = FALSE;                            //COMMENT:
  291.         else if (xTmp == "hHandl") xTxt = FALSE;                            //COMMENT:
  292.         else if (xTmp == "nStdHa") xTxt = FALSE;                            //COMMENT:
  293.         else if (xTmp == "nIndex") xTxt = FALSE;                            //COMMENT:
  294.         else if (xTmp == "CodePa") xTxt = FALSE;                            //COMMENT:
  295.         else if (xTmp == "uNumbe") xTxt = FALSE;                            //COMMENT:
  296.         else if (xTmp == "uFlags") xTxt = FALSE;                            //COMMENT: uFlags
  297.         else if (xTmp == "switch") xTxt = FALSE;                            //COMMENT:
  298.         else if (xTmp == "Locale") xTxt = FALSE;                            //COMMENT:
  299.         else if (xTmp == "lParam") xTxt = FALSE;                            //COMMENT:
  300.         else if (xTmp == "wParam") xTxt = FALSE;                            //COMMENT:
  301.         else if (xTmp == "size_t") xTxt = FALSE;                            //COMMENT:
  302.         else if (xTmp == "nullsu") xTxt = FALSE;                            //NAME: nullsub
  303.         else if (xTmp == "nNumer") xTxt = FALSE;                            //COMMENT:
  304.         else if (xTmp == "nNumbe") xTxt = FALSE;                            //COMMENT: nNumbe
  305.         else if (xTmp == "nDenom") xTxt = FALSE;                            //COMMENT:
  306.         else if (xTmp == "LPSIZE") xTxt = FALSE;                            //COMMENT: LPSIZE
  307.         else if (xTmp == "LPCSTR") xTxt = FALSE;                            //COMMENT: LPCSTR
  308.         else if (xTmp == "LPPOIN") xTxt = FALSE;                            //COMMENT: LPPOIN
  309.         else if (xTmp == "COLORR") xTxt = FALSE;                            //COMMENT: COLORR
  310.         else if (xTmp == "hSourc") xTxt = FALSE;                            //COMMENT: hSourc
  311.         else if (xTmp == "hTarge") xTxt = FALSE;                            //COMMENT: hTarge
  312.         else if (xTmp == "lDista") xTxt = FALSE;                            //COMMENT: lDista
  313.         else if (xTmp == "uBytes") xTxt = FALSE;                            //COMMENT: uBytes
  314.         else if (xTmp == "HGDIOB") xTxt = FALSE;                            //COMMENT: HGDIOB
  315.         else if (xTmp == "bEnabl") xTxt = FALSE;                            //COMMENT: bEnabl
  316.         else if (xTmp == "wRemov") xTxt = FALSE;                            //COMMENT: wRemov
  317.         else if (xTmp == "LPVOID") xTxt = FALSE;                            //COMMENT: LPVOID
  318. //        else if (xTmp == "jump t") xTxt = FALSE;                            //COMMENT: jump table
  319.     }
  320.    
  321.     return xTxt;
  322.  
  323. }
  324.  
  325. //__________________________________________________________________________________________________
  326. //ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
  327. //FUNCTION: writeLine(long oOption, handle oFileH, long oEA, char* oTxt, long oNum, long oLineX)
  328. //--------------------------------------------------------------------------------------------------
  329. //PURPOSE:  Write formated information to file. Returns number of the line it wrote.
  330. //--------------------------------------------------------------------------------------------------
  331. //NOTES:
  332. //    oOption - (long)      Holds OPTion and TYPe information.
  333. //    oFileH  - (file*)     File handle
  334. //    oEA     - (long)      Current Effective Address
  335. //    oTxt    - (char*)     Text info from the EA
  336. //    oNum    - (long)      General Number
  337. //                                Used for Line Number in Anterior & Posterior Lines.
  338. //                                Used for FIRST _OR_ SECOND Operand in x_STR_CODE
  339. //                                Used for String Length in x_STR_DATA
  340. //    oLineX  - (long)      Information Line Number of Output File
  341. //
  342. //    outTxt  - (char*)     Text to be written to file. (Also used in part_X and killing /n)
  343. //    oTypTxt - (char*)     Use in text files to show information Type.
  344. //    oTxtPos - (long)      Position in character array.
  345. //    oMsg    -
  346. //
  347. //----------------------------------------------------------------------------------------------------
  348. static writeLine(oOption, oFileH, oEA, oTxt, oNum, oLineX) {
  349.     auto outTxt, oTypTxt, oTxtPos, oMsg;
  350.  
  351.     //Create "part_X()" subs.
  352.     if (oOption & OPT_IDC_FILE) {
  353.         if ((oLineX%1000) == 0) {                                       //Test 1000 Printed Lines
  354.             if ((oLineX/1000)==0) outTxt = "";                          //Test First run of loop.
  355.             else outTxt = form("}\n\n");                                //Close Previous part_X sub
  356.             outTxt = outTxt + form("\nstatic part_%d() {\n",(oLineX/1000));     //Create New part_X sub
  357.             fprintf(oFileH, outTxt);
  358.         }
  359.     }
  360.  
  361.     //Parse Input String For "\n" New Line
  362.     oTxtPos = 1;
  363.     outTxt = oTxt;
  364.     while(oTxtPos != -1) {
  365.         oTxtPos = strstr(oTxt,"\n");                                    //Find NewLine
  366.         if (oTxtPos != -1) {
  367.             outTxt = substr(oTxt,0,oTxtPos);                            //Get Text up to NewLine
  368.             outTxt = outTxt + "\\n";                                    //Append Text "\n"
  369.             outTxt = outTxt + substr(oTxt,(oTxtPos+1),strlen(oTxt));    //Append Rest of String
  370.         }
  371.         oTxt = outTxt;                                                  //Rewite Original String
  372.     }
  373.  
  374.     //Create IDC string
  375.     if (oOption & OPT_IDC_FILE) {
  376.         if (oOption & TYP_REG_FCOM) {                                   //Regular Function Comment
  377.             outTxt = form("\tSetFunctionCmt(0x%s, \"%s\", 0);\n", ltoa(oEA,16), oTxt);
  378.         } else if (oOption & TYP_RPT_FCOM) {                            //Repeatable Function Comm.
  379.             outTxt = form("\tSetFunctionCmt(0x%s, \"%s\", 1);\n", ltoa(oEA,16), oTxt);
  380.         } else if (oOption & TYP_REG_ICOM) {                            //Regular Indented Comment
  381.             outTxt = form("\tMakeComm(0x%s, \"%s\");\n", ltoa(oEA,16), oTxt);
  382.         } else if (oOption & TYP_RPT_ICOM) {                            //Repeatable Indented Comm.
  383.             outTxt = form("\tMakeRptCmt(0x%s, \"%s\");\n", ltoa(oEA,16), oTxt);
  384.         } else if (oOption & TYP_ANT_LINE) {                            //Anterior Lines
  385.             outTxt = form("\tExtLinA(0x%s, %d, \"%s\");\n", ltoa(oEA,16), oNum, oTxt);
  386.         } else if (oOption & TYP_POS_LINE) {                            //Posterior Lines
  387.             outTxt = form("\tExtLinB(0x%s, %d, \"%s\");\n", ltoa(oEA,16), oNum, oTxt);
  388.         } else if (oOption & TYP_USR_NAME) {                            //User Defined Names
  389.             outTxt = form("\tMakeName(0x%s, \"%s\");\n", ltoa(oEA,16), oTxt);
  390. //      } else if (oOption & TYP_STR_CODE) {                            //Strings From Code
  391.         } else if (oOption & TYP_STR_DATA) {                            //Strings in Data
  392.             outTxt = form("\tMakeStr(0x%s, 0x%s);\n",ltoa(oEA,16),ltoa((oEA+oNum),16));
  393.         }                                  
  394.    
  395.     //Create TEXT string
  396.     } else {
  397.         if      (oOption & TYP_REG_FCOM)  oTypTxt = "(Reg FCom)";
  398.         else if (oOption & TYP_RPT_FCOM)  oTypTxt = "(Rpt FCom)";
  399.         else if (oOption & TYP_REG_ICOM)  oTypTxt = "(Reg ICom)";
  400.         else if (oOption & TYP_RPT_ICOM)  oTypTxt = "(Rep ICom)";
  401.         else if (oOption & TYP_ANT_LINE)  oTypTxt = "(AntLn#";
  402.         else if (oOption & TYP_POS_LINE)  oTypTxt = "(PosLn#";
  403.         else if (oOption & TYP_USR_NAME)  oTypTxt = "(UserName)";
  404.         else if (oOption & TYP_STR_CODE)  oTypTxt = "(StrCode";    
  405.         else if (oOption & TYP_STR_DATA)  oTypTxt = "(Str Data)";    
  406.  
  407.         if ((oOption & TYP_ANT_LINE) || (oOption & TYP_POS_LINE)) {
  408.             outTxt = form("%a %s%2d)\t%s\n", oEA, oTypTxt, oNum, oTxt);
  409.        
  410.         }else if (oOption & TYP_STR_CODE) {
  411.             outTxt = form("%a %s%d)\t%s\n", oEA, oTypTxt, oNum, oTxt);
  412.        
  413.         }else if (oOption & TYP_STR_DATA) {
  414.             outTxt = form("%a %s\t%s\n", oEA, oTypTxt, oTxt);
  415.         }else outTxt = form("%a %s\t%s\n", oEA, oTypTxt, oTxt);
  416.     }
  417.  
  418.     //Output to File
  419.     if (oOption & OPT_MAK_FILE) {
  420.         fprintf(oFileH, outTxt);
  421.  
  422.     //Output to Message Window
  423.     } else {
  424.         Message (outTxt);
  425.     }
  426.  
  427.     oLineX++;
  428.     return oLineX;
  429. }
  430.  
  431. //__________________________________________________________________________________________________
  432. //ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
  433. //FUNCTION: findInfo(lonh fOption, handle fFile, long fCurEA, long fEndEA)
  434. //--------------------------------------------------------------------------------------------------
  435. //PURPOSE: To find, retrieve and sometimes format the desired information.
  436. //--------------------------------------------------------------------------------------------------
  437. //NOTES:
  438. //  fOption -   (long)      Holds option and type info
  439. //  fFileH  -   (handle)    File Handle
  440. //  fCurEA  -   (long)      Starting/Current EA
  441. //  fEndEA  -   (long)      Ending EA
  442. //  
  443. //  i, j, k -   (long?)     Counters
  444. //  fSrtEA  -   (long)      Starting EA
  445. //  fTmpEA  -   (long)      Temporary EA used for gathering string bytes.
  446. //  fTxt    -   (char*)     Holds String to be written
  447. //  fNum    -   (long)      Holds Ant/Pos Line #, _OR_ 1st/2nd Operand _OR_ Length of String
  448. //  fFlags  -   (long)      Holds the flags for the current EA
  449. //  fLineX  -   (long)      Number of written lines.
  450. //  ProgNum -   (long)      Progress Number
  451. //  ProgPer -   (long)      Progress Percent (5%)
  452. //  ProgDot -   (long)      Progress * Mark  (1%)
  453. //--------------------------------------------------------------------------------------------------
  454.  
  455. static findInfo(fOption, fFileH, fCurEA, fEndEA) {
  456.     auto i, j, k, fSrtEA, fTmpEA, fNum, fTxt, fFlags, fLineX, ProgNum, ProgPer, ProgDot;
  457.  
  458.     SetStatus(IDA_STATUS_WORK);                                         //Set Status: 'Busy'
  459.     ProgPer = 4;                                                        //Initial Percent
  460.     ProgDot = 0;                                                        
  461.     Message("\nPercent Complete:  0 ");                                
  462.     fSrtEA = fCurEA;                                                    //Save Start for %Prog
  463.     fNum = 0;
  464.     fLineX = 0;
  465.    
  466.     while ( (fCurEA != BADADDR) && (fCurEA < fEndEA) ) {
  467.         fFlags = GetFlags(fCurEA);
  468.         if ( (fFlags & FF_COMM) || (fFlags & FF_LINE) || (fFlags & FF_NAME) ||\
  469.         (fFlags & FF_0OFF) || (fFlags & FF_1OFF)) {                             //Big IF
  470.             for (i=0; i < 10; i++) {
  471.                 fOption = fOption & 0x0000FFFFL;                                //Clear BitMask        
  472.                 fTxt = FALSE;                                                   //Clear Text
  473.                 fNum = 0;
  474.                 //Type 0:  Regular Function Comment
  475.                 if ( (i==0) && (fOption & OPT_REG_FCOM)) {
  476.                     if (fFlags & FF_FUNC) {
  477.                         fOption = fOption + TYP_REG_FCOM;                       //Set Type
  478.                         fTxt = GetFunctionCmt(fCurEA, 0);                       //Get Comment
  479.                     }                                                          
  480.                 //Type 1:  Repeatable Function Comment                          
  481.                 }else if ( (i==1) && (fOption & OPT_RPT_FCOM) ) {              
  482.                     if (fFlags & FF_FUNC) {
  483.                         fOption = fOption + TYP_RPT_FCOM;                       //Set Type
  484.                         fTxt = GetFunctionCmt(fCurEA, 1);                       //Get Comment
  485.                     }                                                          
  486.                 //Type 2:  Regular Indented Comment                            
  487.                 }else if ( (i==2) && (fOption & OPT_REG_ICOM) ){                
  488.                     if (fFlags & FF_COMM)  {                                    
  489.                         fOption = fOption + TYP_REG_ICOM;                       //Set Type
  490.                         fTxt = Comment(fCurEA);                                 //Get Comment
  491.                     }                                                          
  492.                 //Type 3:  Repeatable Indented Comment                          
  493.                 }else if ( (i==3) && (fOption & OPT_RPT_ICOM)) {                
  494.                     if (fFlags & FF_COMM)  {                                    
  495.                         fOption = fOption + TYP_RPT_ICOM;                       //Set Type
  496.                         fTxt = RptCmt(fCurEA);                                  //Get Comment
  497.                     }                                                          
  498.                 //Type 4:  Anterior Line                                        
  499.                 }else if ( (i==4) && (fOption & OPT_ANT_LINE) ){                
  500.                     if (fFlags & FF_LINE)  {                                    
  501.                         fOption = fOption + TYP_ANT_LINE;                       //Set Type
  502.                         for (k=998; k >=0; k--) if (LineA(fCurEA,k)!="") break; //Find Last Line
  503.                         for(j=0;j <= k; j++) {                                  //LineA() bug >1000t
  504.                             fTxt = LineA(fCurEA, j);                            //Get Ant Line j
  505.                             fLineX = writeLine(fOption, fFileH, fCurEA, fTxt, j, fLineX);
  506.                         }
  507.                     }
  508.                 //Type 5:  posterior Line
  509.                 }else if ( (i==5) && (fOption & OPT_POS_LINE) ){
  510.                     if (fFlags & FF_LINE)  {
  511.                         fOption = fOption + TYP_POS_LINE;                       //Set Type
  512.                         for (k=998; k >=0; k--) if (LineB(fCurEA,k)!="") break; //Find Last Line
  513.                         for(j=0;j <= k; j++) {                                  //Get All Lines
  514.                             fTxt = LineB(fCurEA, j);                            //Get Pos Line j
  515.                             fLineX = writeLine(fOption, fFileH, fCurEA, fTxt, j, fLineX);
  516.                         }
  517.                     }
  518.                 //Type 6: User Defined Names
  519.                 }else if ( (i==6) && (fOption & OPT_USR_NAME) ){
  520.                     if (fFlags & FF_NAME)  {
  521.                         fOption = fOption + TYP_USR_NAME;                       //Set Type
  522.                         fTxt = Name(fCurEA);                                    //Get Name
  523.                     }
  524.                 //Type 7: String References in CODE Opnd0
  525.                 }else if ( (i==7)  && (fOption & OPT_STR_CODE) ){
  526.                     //isCode(F) // is code byte?
  527.                     if (fFlags & FF_0OFF) {                                     //Test First Operand
  528.                         fTxt = GetOpnd(fCurEA,0);                               //Get 1st Op Name
  529.                         if ((substr(fTxt,0,11) == "offset str_") || \
  530.                         (substr(fTxt,0,8) == "offset a")) {
  531.                             fTxt = substr(fTxt,7,-1);                           //Trim "offset "
  532.                             fOption = fOption + TYP_STR_CODE;                   //Set Type
  533.                             fTmpEA = LocByName(fTxt);                           //Get String EA
  534.                             fNum = ItemSize(fTmpEA);                            //Get String Length
  535.                             fTxt = form("\"");                                  //Add Quote (")
  536.                             for (j=0; j<=fNum; j++) {                           //Get Each Str Byte
  537.                                 fTxt = fTxt + byteValue(GetFlags(fTmpEA));      //Append Byte to Str
  538.                                 fTmpEA = fTmpEA + 1;                            //Inc EA by 1 Byte
  539.                             }
  540.                             fTxt = fTxt + form("\"");                           //Add End Quote (")
  541.                             fNum = 0;                                           //Set num for Code0
  542.                         }else fTxt = FALSE;                                     //Delete if not Str
  543.                         if (fOption & OPT_IDC_FILE) fTxt = FALSE;               //Delete if IDC
  544.                     }
  545.                 //Type 7: String References in CODE Opnd1
  546.                 }else if ( (i==8)  && (fOption & OPT_STR_CODE) ){
  547.                     if (fFlags & FF_1OFF) {                                     //Test Second Opernd
  548.                         fTxt = GetOpnd(fCurEA,1);                               //Get 2nd Op Name
  549.                         if ((substr(fTxt,0,11) == "offset str_") || \
  550.                         (substr(fTxt,0,8) == "offset a")) {
  551.                             fTxt = substr(fTxt,7,-1);                           //Trim "offset "
  552.                             fOption = fOption + TYP_STR_CODE;                   //Set Type
  553.                             fTmpEA = LocByName(fTxt);                           //Get String EA
  554.                             fNum = ItemSize(fTmpEA);                            //Get String Length
  555.                             fTxt = form("\"");                                  //Add Quote (")
  556.                             for (j=0; j<=fNum; j++) {                           //Get Each Str Byte
  557.                                 fTxt = fTxt + byteValue(GetFlags(fTmpEA));      //Append Byte  to Str
  558.                                 fTmpEA = fTmpEA + 1;                            //Inc EA by 1 Byte
  559.                             }
  560.                             fTxt = fTxt + form("\"");                           //Add End Quote (")
  561.                             fNum = 1;                                           //Set num for Code1
  562.                         }else fTxt = FALSE;                                     //Delete if not Str
  563.                         if (fOption & OPT_IDC_FILE) fTxt = FALSE;               //Delete if IDC
  564.                     }
  565.                 //Type 8: String References in DATA
  566.                 }else if ( (i==9)  && (fOption & OPT_STR_DATA) ){
  567.                     //isData(F) // is data byte?
  568.                     if (fFlags & FF_NAME) {                                     //Test for Name
  569.                         fTxt = Name(fCurEA);                                    //Get Name
  570.                         if ((substr(fTxt,0,4) == "str_") || (substr(fTxt,0,1) == "a")) {
  571.                             fOption = fOption + TYP_STR_DATA;                   //Set Type
  572.                             fTmpEA = fCurEA;                                    //Set Str EA
  573.                             fNum = ItemSize(fTmpEA);                            //Get String Length
  574.                             fTxt = form("\"");                                  //Add Quote (")
  575.                             for (j=0; j<=fNum; j++) {                           //Get Each Str Byte
  576.                                 fTxt = fTxt + byteValue(GetFlags(fTmpEA));      //Append Byte to Str
  577.                                 fTmpEA = fTmpEA + 1;                            //Inc EA by 1 Byte
  578.                             }
  579.                             fTxt = fTxt + form("\"");                           //Add End Quote (")
  580.                         }else fTxt = FALSE;                            
  581.                     }
  582.                 }
  583.                
  584.                 //Filter Output
  585.                 if ( (fTxt != FALSE) && (fOption & OPT_USE_FLTR) ) fTxt = xFilter(fTxt);
  586.                
  587.                 //Write Output
  588.                 if ( (fTxt != FALSE) && (i != 4) && (i!=5) ){                   //Print ?
  589.                     fLineX = writeLine(fOption, fFileH, fCurEA, fTxt, fNum, fLineX);
  590.                 }                                                    
  591.                
  592.             } //End FOR Loop        
  593.         }  //End BIG IF
  594.        
  595.  
  596.  
  597.         //Message Percent Complete
  598.         ProgNum = ((fCurEA - fSrtEA) * 100) / (fEndEA - fSrtEA) ;     //Get Percent Finsihed
  599.         if (ProgNum > ProgPer) {                                      //If serious gain (5%) write.
  600.             fTxt = form("\nPercent Complete:  %d ",ProgNum);          //Full Message
  601.             Message(fTxt);                                            
  602.             ProgPer = ProgNum + 4;                                    
  603.         } else if (ProgNum > ProgDot) {                               //Else write a "*" for 1% gain
  604.             Message("*");                                            
  605.             ProgDot = ProgNum;
  606.         }
  607.  
  608.         //Increment Current EA
  609.         fCurEA = NextAddr(fCurEA);
  610.     }   //End WHILE Loop    
  611.  
  612.     //Write "parts()" Function
  613.     if (fOption & OPT_IDC_FILE) {
  614.         fLineX = fLineX/1000;
  615.         fTxt = form("}\n\nstatic parts() {\n\tMessage(\"\\nSTART!\\n\");\n"); //parts() and Message
  616.         fprintf(fFileH, fTxt);
  617.         for(i=0; i <= fLineX; i++) {                                          //write part_X subs
  618.               fTxt = form("\tpart_%d();\n",i);
  619.               fTxt = fTxt + form("\tMessage(\"Part %d of %d Completed\\n\");\n", i, fLineX);
  620.               fprintf(fFileH, fTxt);
  621.         }
  622.         fTxt = form("\tMessage(\"\\nFINISHED!\\n\");\n}\n");                  //End parts() & Msg.
  623.         fprintf(fFileH, fTxt);
  624.     }
  625.     //Change Status
  626.     Message("\nPercent Complete:  100\n");
  627.     SetStatus(IDA_STATUS_READY);                                              //Set Status 'Ready'
  628. }      
  629.  
  630.  
  631. //__________________________________________________________________________________________________
  632. //ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
  633. //FUNCTION: void main()
  634. //--------------------------------------------------------------------------------------------------
  635. //NOTES:
  636. //    i, j        -   (long)      Counters
  637. //    mOption     -   (long)      Holds program option and type info
  638. //    mStartEA    -   (long)      For the starting address
  639. //    mEndEA      -   (long)      For the ending address
  640. //    mFName      -   (char*)     Name for output file
  641. //    mFileH      -   (handle)    File Handle
  642. //    mStartTxt   -   (char*)    
  643. //    mStrLine    -   (char*)    
  644. //    mError      -   (bool)      Error Status
  645. //--------------------------------------------------------------------------------------------------
  646. static main() {
  647.     auto i, j, mOption, mStartEA, mEndEA, mFName, mFileH, mStartTxt, mStrLine, mError;
  648.        
  649.     mError = TRUE;                                                  //Set Error Status True
  650.     Message("\n\nBegin Dump:  DumpInfo.idc. \n");                   //Show Start Message To Window
  651.  
  652.     //Program Options  -I should really build a UI prompt of some sort...
  653.     //Control the program by commenting/uncommenting the information types you want.
  654.     mOption = 0x00000000L;                         //Initialize Option Var
  655.     mOption = mOption + OPT_MAK_FILE;              //Set Option:  Write File (Or MessageWindow)
  656.     //mOption = mOption + OPT_IDC_FILE;              //Set Option:  Create IDC (Or Text File)
  657.     //mOption = mOption + OPT_USE_FLTR;              //Set Option:  Use Filter
  658.     //mOption = mOption + OPT_REG_FCOM;              //Set Option:  Regular Function Comments
  659.     //mOption = mOption + OPT_RPT_FCOM;              //Set Option:  Repeatable Function Comments
  660.     //mOption = mOption + OPT_REG_ICOM;              //Set Option:  Regular Indented Comments
  661.     //mOption = mOption + OPT_RPT_ICOM;              //Set Option:  Repeatable Indented Comments
  662.     //mOption = mOption + OPT_ANT_LINE;              //Set Option:  Anterior Lines
  663.     //mOption = mOption + OPT_POS_LINE;              //Set Option:  Posterior Lines
  664.     mOption = mOption + OPT_USR_NAME;              //Set Option:  User Created Names
  665.     //mOption = mOption + OPT_STR_CODE;              //Set Option:  String References From CODE
  666.     //mOption = mOption + OPT_STR_DATA;              //Set Option:  String References In DATA
  667.  
  668.  
  669.     //Prompt User For Starting/Ending Point
  670.     mStartTxt = form("Start Dump From\n   (E)tire Disassembly - From %s To %s\n", \
  671.     ltoa(MinEA(),16),ltoa(MaxEA(),16));
  672.     mStartTxt = mStartTxt + form("   (C)urent Selection - From %s to %s\n", \
  673.     ltoa(SelStart(),16),ltoa(SelEnd(),16));
  674.     mStartTxt = mStartTxt + form("   (S)egment Only - (You'll Select a Single Segment)\n");
  675.     mStartTxt = mStartTxt + form("   (F)unction Only - (You'll Select a Single Function)\n");
  676.     mStartTxt = AskIdent("E", mStartTxt);
  677.  
  678.     //(E)ntire File
  679.     if ((mStartTxt == "E") || (mStartTxt == "b")) {
  680.         mStartEA = MinEA();
  681.         mEndEA = MaxEA();
  682.         if ((mStartEA != 0) || (mEndEA != 0))  mError = FALSE;            //Error Checking
  683.     //(C)urrent Selection
  684.     } else if ((mStartTxt == "C") || (mStartTxt == "c")) {
  685.         mStartEA = SelStart();                                            //Get Selection Start
  686.         mEndEA = SelEnd();                                                //Get Selection End
  687.         if ((mStartEA != BADADDR) || (mEndEA != BADADDR)) mError = FALSE; //Error Checking
  688.         else Warning("There Is No Currently Selected Area");              //No Selection Warning
  689.     //(S)egment Only -A "ChooseSegment()" Function would be nice... :)
  690.     } else if ((mStartTxt == "S") || (mStartTxt == "s")) {
  691.         i = 1;
  692.         mStartEA = FirstSeg();                                            //Set StartEA
  693.         mStartTxt = "Please Choose Segment By Number:\n";                 //Create Text for UI
  694.         do {mStartTxt = mStartTxt + form("    (%d) %s", i, SegName(mStartEA));
  695.             mStartEA = NextSeg(mStartEA);                                 //Get Text Seg Name
  696.             i++;
  697.         } while ( mStartEA != BADADDR);
  698.         j = AskLong("1", mStartTxt);                                      //Get User Input (long)
  699.         mStartEA = FirstSeg();                                            //Set StartEA First Seg  
  700.         mEndEA = SegEnd(mStartEA);                                        //Set EndEA to End of Seg
  701.         for (i=1; i<j; i++) {                                             //Loop to user selected -
  702.             mStartEA = NextSeg(mStartEA);                                 //segment setting start -
  703.             mEndEA = SegEnd(mStartEA);                                    //and end
  704.         }
  705.         if ((mStartEA != BADADDR) || (mEndEA != BADADDR)) mError = FALSE; //Error Checking
  706.     //(F)unction Only
  707.     } else if ((mStartTxt == "F") || (mStartTxt == "f")) {
  708.         mStartEA = ChooseFunction("Choose Function");
  709.         mEndEA = FindFuncEnd(mStartEA);
  710.         if ((mStartEA != -1)  || (mEndEA != BADADDR))  mError = FALSE;    //Error Checking
  711.     }
  712.  
  713.     //Show Status Messages
  714.     if (mOption & OPT_MAK_FILE) Message("Create File:  TRUE \n");
  715.     else Message("Create File:  FALSE \n");
  716.     if (mOption & OPT_IDC_FILE) Message("Create  IDC:  TRUE \n");
  717.     else Message("Create  IDC:  FALSE \n");
  718.  
  719.  
  720.     //Error Test
  721.     if (mError == TRUE)  Message("\nThere was an error getting address info. \n");
  722.     else {
  723.     //Setup Output
  724.         //Create IDC string
  725.         if (mOption & OPT_IDC_FILE) {
  726.             mStrLine =  form("// User Dump: IDC Format\n// Autogenerated by DumpInfo.IDC \n");
  727.             mStrLine = mStrLine + form("// IDC script for porting info to a new disassembly.\n");
  728.             mStrLine = mStrLine + form("// Disassembled File: %s\n",GetInputFile());
  729.             mStrLine = mStrLine + form("// Cursor  Address: %s\n",ltoa(BeginEA(),16));
  730.             mStrLine = mStrLine + form("// Minimum Address: %s\n",ltoa(MinEA(),16));
  731.             mStrLine = mStrLine + form("// Maximum Address: %s\n",ltoa(MaxEA(),16));
  732.             mStrLine = mStrLine + form("// Segment Address: %s\n",ltoa(SegStart(mStartEA),16));
  733.             mStrLine = mStrLine + form("// Segment Name...: %s\n",SegName(mStartEA));
  734.             mStrLine = mStrLine + form("// StartingAddress: %s\n",ltoa(mStartEA,16));
  735.             mStrLine = mStrLine + form("// Ending  Address: %s\n\n",ltoa(mEndEA,16));
  736.             mStrLine = mStrLine + form("#include <idc.idc>\n\nstatic main ( ) {\n");
  737.             mStrLine = mStrLine + form("\t parts();\n}\n\n");
  738.        
  739.         //Create TEXT string
  740.         } else {
  741.             mStrLine =  form("User Dump: Text Format\nAutogenerated by DumpInfo.IDC \n");
  742.             mStrLine = mStrLine + form("Disassembled File: %s\n",GetInputFile());
  743.             mStrLine = mStrLine + form("Cursor  Address: %s\n",ltoa(BeginEA(),16));
  744.             mStrLine = mStrLine + form("Minimum Address: %s\n",ltoa(MinEA(),16));
  745.             mStrLine = mStrLine + form("Maximum Address: %s\n",ltoa(MaxEA(),16));
  746.             mStrLine = mStrLine + form("Segment Address: %s\n",ltoa(SegStart(mStartEA),16));
  747.             mStrLine = mStrLine + form("Segment Name...: %s\n",SegName(mStartEA));
  748.             mStrLine = mStrLine + form("StartingAddress: %s\n",ltoa(mStartEA,16));
  749.             mStrLine = mStrLine + form("Ending  Address: %s\n\n",ltoa(mEndEA,16));
  750.         }
  751.    
  752.         //Output To File
  753.         if (mOption & OPT_MAK_FILE) {
  754.             if (mOption & OPT_IDC_FILE)
  755.                  mFName = AskFile(1,"*.idc", "Output File Name?");         //Get *.IDC File Name
  756.             else mFName = AskFile(1,"*.txt", "Output File Name?");         //Get *.TXT File Name
  757.            
  758.             mFileH = fopen(mFName, "wt");                                  //Open File for Output
  759.    
  760.             if (mFileH == 0)  Warning("Error opening output file!\n");     //Error Opening File
  761.             else {
  762.                 fprintf(mFileH, mStrLine);                                 //Else Run Program
  763.                 findInfo(mOption,mFileH,mStartEA,mEndEA);
  764.             }
  765.    
  766.         //Output to Message Window
  767.         } else {
  768.             Message (mStrLine);
  769.             findInfo(mOption,mFileH,mStartEA,mEndEA);
  770.         }
  771.    
  772.         //Cleanup
  773.         if (mFileH != 0) {
  774.             if (mOption & OPT_IDC_FILE)  mStrLine = form("\n\n// End of IDC File.");  
  775.             else mStrLine = form("\n\nEnd of Text File.");                            
  776.             fprintf(mFileH, mStrLine);                                                
  777.             fclose(mFileH);                                                          
  778.         }
  779.     }
  780.  
  781.     //Show End Message
  782.     Message("\nEnd of DumpInfo.idc. \n");
  783. }
Add Comment
Please, Sign In to add comment