home *** CD-ROM | disk | FTP | other *** search
/ Programming Win32 Under the API / ProgrammingWin32UnderTheApiPatVillani.iso / dsasmsrc.zip / main.c < prev    next >
C/C++ Source or Header  |  1999-08-13  |  134KB  |  4,539 lines

  1. //
  2. //
  3. // This program was written by Sang Cho, associate professor at 
  4. //                                       the department of 
  5. //                                       computer science and engineering
  6. //                                       chongju university
  7. // language used: gcc 
  8. //
  9. // date of second release: August 30, 1998 (alpha version)
  10. // many fixed after release: October 9, 1998 
  11. //
  12. //
  13. //      you can contact me: e-mail address: sangcho@alpha94.chongju.ac.kr
  14. //                            hitel id: chokhas
  15. //                        phone number: (0431) 229-8491    +82-431-229-8491
  16. //
  17. //            real address: Sang Cho
  18. //                      Computer and Information Engineering
  19. //                      ChongJu University
  20. //                      NaeDok-Dong 36 
  21. //                      ChongJu 360-764
  22. //                      South Korea
  23. //
  24. //   Copyright (C) 1997,1998,1999                            by Sang Cho.
  25. //
  26. // Permission is granted to make and distribute verbatim copies of this
  27. // program provided the copyright notice and this permission notice are
  28. // preserved on all copies.
  29. //
  30. // File: main.c 
  31.  
  32. # include "disasm.h"        
  33.  
  34. #define  INT_MAX   0x7FFFFFFF
  35.  
  36. #define  jLmax     50000
  37. #define  hMax      5120
  38. #define  hintMax   1024
  39. #define  NAMEMAX   256
  40. #define  COLSIZE   78
  41.  
  42. //FILE     *d_fp;
  43. int      nextMode=0;           // some role in preprocessing
  44. int      printMode=0;  
  45. int      zeroCheckMode=0;
  46. int      lineno=0;
  47. int      errorCount=0;
  48. int      debugx=0;
  49. int      debugTab[256]={0,};
  50. char     mname[NAMEMAX];
  51. int      fsize;
  52. int      showDotsNum=0;
  53. DWORD    debugAdd=0;
  54. DWORD    debugAdd1=0;
  55.  
  56. int      jLc;
  57. _labels  pArray[jLmax];
  58. _labels  suspicious[hMax]; // I am lazy so i will use _labes to store suspicious places...
  59.  
  60. int      dmc=0;
  61. DWORD    dmLabels[32];
  62. int      HintCnt=0;
  63. _key_    Hints[hintMax]; // I am lazy so i will use _key_ structure to store hints...
  64. int      hCnt=0;
  65. history  History[hMax];
  66. int      needJump=0;
  67. DWORD    needJumpNext;
  68. int      needCall=0;
  69. DWORD    needCallRef, needCallNext;
  70. DWORD    fatalPosition;
  71. DWORD    fatalReference;
  72.  
  73. // *********************************************************
  74. // ****************** main here ****************************
  75. // *********************************************************
  76.  
  77. int main(argc,argv)
  78. int argc; char **argv;
  79. {
  80. FILE     *my_fp;
  81. //extern FILE  *d_fp;
  82. int       i, n;
  83. DWORD     r;
  84. char      fname[NAMEMAX];
  85.  
  86.     if (argc == 2)
  87.     {
  88.         strcpy(fname, argv[1]);
  89.         my_fp = fopen (argv[1], "rb");
  90.         if (my_fp == NULL) 
  91.         {
  92.         fprintf (stderr,"canNOTopenFILE: %s", argv[1]);
  93.         exit (0);
  94.         }
  95.     }
  96.     else if (argc == 3)
  97.     {
  98.         strcpy(fname, argv[1]);
  99.         strcpy(mname, argv[2]);
  100.         my_fp = fopen (argv[1], "rb");
  101.         
  102.         if (my_fp == NULL) 
  103.         {
  104.         fprintf (stderr,"canNOTopenFILE: %s", argv[1]);
  105.         exit (0);
  106.         }
  107.         
  108.         readHint();
  109.     }
  110.     else
  111.     {
  112.          fprintf (stderr,"\nusage: dsassm02 input_file_name > output_file_name");
  113.          fprintf (stderr,"\nversion 0.22 released February 22, 1999\n");
  114.          exit (0);
  115.     }
  116.  
  117.     //d_fp  = fopen ("xxxxxx.xxx", "w");
  118.     //if (d_fp == NULL) 
  119.     //{
  120.     //    fprintf (stderr,"canNOTopenFILE: %s", "xxxxxx.xxx");
  121.     //    exit (0);
  122.     //}
  123.     
  124.     fseek (my_fp, 0L, SEEK_END);
  125.     fsize = ftell (my_fp);
  126.     rewind (my_fp);
  127.  
  128.     lpFile = (void *) calloc (fsize,1);
  129.     if (lpFile == NULL)
  130.     {
  131.         fprintf (stderr,"canNOTallocateMEMORY");
  132.         exit (0);
  133.     }
  134.  
  135.     printf ("Disassembly of File: %s\n\n", argv[1]);
  136.     n = fread (lpFile, fsize, 1, my_fp);
  137.  
  138.     if (n == -1)
  139.     {
  140.         fprintf(stderr,"failed to read the FILE");
  141.         exit (0);
  142.     }
  143.  
  144.     // I need to connect pedump and preprocessing.
  145.     
  146.     initHeaders();
  147.  
  148.     pedump (argc, argv);     /* put together */
  149.  
  150.     //Myfinish();
  151.  
  152.     tryAnyAddress();
  153.     tryPascalStrings();
  154.  
  155.     //Myfinish();
  156.     printf ("\n");
  157.     //printf ("\n*************** BEGINNING OF PROCESSING  ************************** \n");
  158.     fprintf (stderr,"\n*************** PREPROCESSING BEGINS ************************** \n");
  159.     
  160.     showDotsNum=0;
  161.     //fprintf(stderr,"entryPoint=%08X imageBase=%08X imagebaseRVA=%08X CodeOffset=%08X\n",
  162.     //                (int)entryPoint, (int)imageBase, (int)imagebaseRVA, CodeOffset);
  163.     //fprintf(stderr,"CodeSize=%08X",CodeSize);
  164.     
  165.     if (entryPoint>0) resetDisassembler(imageBase+entryPoint);
  166.     else              resetDisassembler(imagebaseRVA);
  167.     orMap(imageBase+entryPoint,0x40);
  168.     EnterLabel(2048, imageBase+entryPoint, imageBase);
  169.  
  170.     nextMode = 1;       // to say now preprocessing is started.
  171.     zeroCheckMode=1;
  172.     printMode = 0;
  173.     //printMode= 1;
  174.  
  175.     while (1)
  176.     {
  177.         debugx=0; 
  178.         /*-------------*/pushTrace(1000);
  179.         Disassembler();
  180.         /*-------------*/popTrace();
  181.         if (fatalError) ErrorRecover(); 
  182.  
  183.         // I have to make sure there is no looping.
  184.         // in a micro level or macro level. think BIG.... be happy.... october 27,1997
  185.         /*-------------*/pushTrace(1010);
  186.         r=GetNextOne();
  187.         /*-------------*/popTrace();
  188.         /*-------------*/pushTrace(1020);
  189.         resetDisassembler(r);
  190.         /*-------------*/popTrace();
  191.         if (r==0) break;
  192.     }
  193.  
  194.     if (debugAdd>0) MapSummary();
  195.     //ReportMap();
  196.  
  197.     //Myfinish();
  198.     /*-----------------*/pushTrace(1030);
  199.     PostProcessing1();
  200.     /*-----------------*/popTrace();
  201.     
  202.     //printf ("\n*************** END OF PREPROCESSING **************************** ");
  203.     if (fatalError)
  204.     {   
  205.         //printf("\nError=%d",fatalError);
  206.         fatalError=0;
  207.     }
  208.  
  209.     if (debugAdd>0)
  210.     {
  211.         printf ("\n\n*************** LABELS COLLECTED ARE: source side ******************** ");
  212.         printf ("\n");
  213.  
  214.         sortTrees1();
  215.     
  216.         printf ("\n\n*************** LABELS COLLECTED ARE: destination ******************** ");
  217.         printf ("\n");
  218.     
  219.         sortTrees();
  220.     } 
  221.  
  222.     /*-----------------*/pushTrace(1040);
  223.     LabelProcess();
  224.     /*-----------------*/popTrace();
  225.  
  226.     //ReportMap();
  227.  
  228.     //Myfinish();exit(0);
  229.     
  230.     printf ("\n\n+++++++++++++++++++ ASSEMBLY CODE LISTING +++++++++++++++++++");
  231.     printf ("\n//********************** Start of Code in Object CODE **************");
  232.     printf ("\nProgram Entry Point = %08X (%s File Offset:%08X)\n",
  233.             (int)(imageBase+entryPoint),argv[1],CodeOffset); 
  234.     fprintf (stderr,"\n\n*************** LISTING BEGINS *************************** \n");
  235.     
  236.     showDotsNum=0;
  237.     nextMode = 0;        // to say now preporcessing is finished.
  238.     zeroCheckMode=0;
  239.     printMode=1;
  240.  
  241.     resetDisassembler(imagebaseRVA);
  242.  
  243.     while (!GotEof)
  244.     {
  245.         debugx=0;
  246.         /*-------------*/pushTrace(1050);
  247.         Disassembler();
  248.         /*-------------*/popTrace();
  249.         
  250.         if(GotEof) break;
  251.         if(getOffset(cur_position)<CodeOffset+CodeSize)
  252.            fprintf(stderr,"\na little disassemble error near :%08X\n", (int)cur_position);
  253.         if(getOffset(cur_position)<CodeOffset+CodeSize)
  254.            fprintf(stdout,"\na little disassemble error near :%08X\n", (int)cur_position);
  255.         fatalError=0;
  256.         i=ReadOneByte(); 
  257.         addressfix();
  258.         a_loc++;   i_col=0;
  259.         pr3ntf("\n:%08X %02X",(int)cur_position, i); 
  260.     }
  261.  
  262.     Xreference();
  263.     
  264.     //sortTrees1();sortTrees();
  265.     
  266.     /* close files and release memory NOW */
  267.     if (debugAdd>0) fprintf (stderr,
  268.     "\naddL=%5d reset=%5d ErrorR=%5d eraseU=%5d totalZero=%08X",
  269.      addLabelsNum, resetNum, ErrorRecoverNum, eraseUncertainNum,totZero);    
  270.     
  271.     if (debugAdd>0) reportHistory();
  272.     
  273.     printf ("\n*************** END OF LISTING ********************************** \n");
  274.     fprintf(stderr,"\n");
  275.     
  276.     Myfinish();
  277.     return 1;   
  278. }
  279. // **********************************************************************
  280. // **************************end of main ********************************
  281. // **********************************************************************
  282.  
  283. //
  284. // all the functions used in the main 
  285. //
  286.  
  287. // **************************************
  288. // disassembler block starts here
  289. // **************************************
  290.  
  291. void initDisassembler()
  292. {
  293.     yyfirsttime = 1;                     // to refresh position from the file
  294.     a_loc = 0;
  295.     a_loc_save = 0;
  296.     i_col = 0;
  297.     i_col_save = 0;
  298.     i_psp = 0;
  299.     GotEof =0;
  300.     lineno=0;
  301.     NumberOfBytesProcessed = -1;
  302.     operandOveride = 0;
  303.     addressOveride = 0;
  304.     dmc = 0;
  305.     fatalError = 0;
  306.     needJump=0;
  307.     needCall=0;
  308.     needCallRef=0;
  309.     needCallNext=0;
  310.     needJumpNext=0;
  311. }
  312.  
  313. int   resetNum=0;
  314. DWORD lastReset=0;
  315. int   resetHistogram[256]={0,};
  316.  
  317. void  resetDisassembler(DWORD ref)
  318. {
  319. //int      i;
  320.  
  321.     initDisassembler();
  322.     vCodeOffset = getOffset(ref);
  323.     vCodeSize   = CodeOffset-vCodeOffset+CodeSize;
  324.     delta       = vCodeOffset - CodeOffset;
  325.     
  326.     lastReset    = ref;
  327.     cur_position = ref;
  328.  
  329.     // mark start position here.
  330.     /*----------*/pushTrace(1060);
  331.     if (nextMode) orMap(ref, 0x20);
  332.     /*----------*/popTrace();
  333.  
  334.     //printf("\nresetDisassembler :%08X getByte=%02X",ref,getByteFile(ref));
  335.     //if(nextMode)
  336.     //fprintf(stderr,"\nresetDisassembler :%08X getByte=%02X",ref,getByteFile(ref));
  337.     resetHistogram[getByteFile(ref)]+=1;
  338.     resetNum++;
  339. }
  340.  
  341. int      envSave[32];
  342. void pushEnvironment()
  343. {
  344.     envSave[ 0]=yyfirsttime;
  345.     envSave[ 1]=a_loc;
  346.     envSave[ 2]=a_loc_save;
  347.     envSave[ 3]=i_col;
  348.     envSave[ 4]=i_col_save;
  349.     envSave[ 5]=i_psp;
  350.     envSave[ 6]=NumberOfBytesProcessed;
  351.     envSave[ 7]=operandOveride;
  352.     envSave[ 8]=addressOveride;
  353.     envSave[ 9]=vCodeOffset;
  354.     envSave[10]=vCodeSize;
  355.     envSave[11]=dmc;
  356.     envSave[12]=delta;
  357.     envSave[13]=(int)cur_position;
  358.     envSave[14]=needJump;
  359.     envSave[15]=needCall;
  360.     envSave[16]=GotEof;
  361.     envSave[17]=(int)yyfp;
  362.     envSave[18]=(int)yypmax;
  363.     envSave[19]=nextMode;
  364.     envSave[20]=printMode;
  365.     envSave[21]=zeroCheckMode;
  366.     envSave[22]=needJumpNext;
  367. }
  368.  
  369. void popEnvironment()
  370. {
  371.     yyfirsttime             = envSave[ 0];
  372.     a_loc                   = envSave[ 1];
  373.     a_loc_save              = envSave[ 2];
  374.     i_col                   = envSave[ 3];
  375.     i_col_save              = envSave[ 4];
  376.     i_psp                   = envSave[ 5];
  377.     NumberOfBytesProcessed  = envSave[ 6];
  378.     operandOveride          = envSave[ 7];
  379.     addressOveride          = envSave[ 8];
  380.     vCodeOffset             = envSave[ 9];
  381.     vCodeSize               = envSave[10];
  382.     dmc                     = envSave[11];
  383.     delta                   = envSave[12];
  384.     cur_position     = (DWORD)envSave[13];
  385.     needJump                = envSave[14];
  386.     needCall                = envSave[15];
  387.     GotEof                  = envSave[16];
  388.     yyfp             = (PBYTE)envSave[17];
  389.     yypmax           = (PBYTE)envSave[18];
  390.     nextMode                = envSave[19];
  391.     printMode               = envSave[20];
  392.     zeroCheckMode           = envSave[21];
  393.     needJumpNext            = envSave[22];
  394. }
  395.  
  396. void showDots()
  397. {
  398. static int n=0;
  399.     
  400.     n++;
  401.     if (n%20==0) 
  402.     {
  403.         fprintf(stderr,".");
  404.         showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  405.     }
  406. }
  407.  
  408.  
  409. //
  410. // the engine of this program
  411. //
  412. void Disassembler()
  413. {
  414. //static BYTE   bb=0x00;
  415. int       tok;
  416. BYTE      c;
  417. int       choice;
  418. //int       i;
  419.             
  420.     showDots();
  421.     
  422.     while (!GotEof)
  423.     {        
  424.             /*-----------*/pushTrace(1100);
  425.             addressfix();
  426.             /*-----------*/popTrace();
  427.  
  428.             c = getMap(cur_position);
  429.             
  430.             if (nextMode) 
  431.             { 
  432.                      if (c==0x0E)       {fatalError=256;break;} 
  433.                 else if ((c&0x08)==0x08){needJump=1;    break;} 
  434.                 else if ((c&0x05)==0x05){needJump=1;    break;}  
  435.                 choice=0;
  436.             }
  437.             else 
  438.             {
  439.                       if ((c&0x0F)==0x0E)  choice=1;   // address  
  440.                  else if ((c&0x0F)==0x0D)  choice=6;   // ward
  441.                  else if ((c&0x0F)==0x0F)  choice=2;   // byte data
  442.                  else if ((c&0x0F)==0x0C)  choice=3;   // CC block
  443.                  else if ((c&0x0F)==0x0B)  choice=4;   // Pascal String
  444.                  else if ((c&0x0F)==0x09)  choice=5;   // NULL   String
  445.                  else               choice=0;
  446.             }
  447.             /*------------*/pushTrace(1110);
  448.             addressprint1(choice);
  449.             /*------------*/popTrace();
  450.             /*------------*/pushTrace(1120);
  451.             tok = instruction(choice);
  452.             /*------------*/popTrace();
  453.             if (tok==0) {fatalError=-1; break;}
  454.             /*------------*/pushTrace(1130);
  455.             bodyprint(choice);
  456.             /*------------*/popTrace();         
  457.             lineno++;              
  458.             /*------------*/pushTrace(1140);
  459.             markCodes(); 
  460.             /*------------*/popTrace();
  461.             if (nextMode&&needJump)break;
  462.             //if (nextMode&&needCall)break;
  463.             /*------------*/pushTrace(1150);
  464.             if (zeroCheckMode) 
  465.             {checkZeros(); checkCrossing();}
  466.             /*------------*/popTrace();
  467.             if (fatalError) break;
  468.    }        
  469.    
  470.     /* go round the loop */
  471.     
  472. }
  473.  
  474. void Disassembler1()
  475. {
  476. //static int bb=0;
  477. int       tok;
  478. BYTE      c;
  479. int       i, limit;
  480.  
  481.     if (nextMode) limit=CodeSize; else limit=48;
  482.     for(i=0;i<limit;i++)
  483.     {                          
  484.             /*-----------*/pushTrace(1200);
  485.             addressfix();
  486.             /*-----------*/popTrace();
  487.             c = getMap(cur_position);
  488.             
  489.                  if ((c&0x08)==0x08) return; 
  490.             else if ((c&0x05)==0x05) return;  
  491.             /*-----------*/pushTrace(1210);
  492.             addressprint1(0);
  493.             /*-----------*/popTrace();
  494.             /*-----------*/pushTrace(1220);
  495.             tok = instruction(0);
  496.             /*-----------*/popTrace();
  497.             if (tok==0) {fatalError=-11; break;}
  498.             /*-----------*/pushTrace(1230);
  499.             bodyprint(0);
  500.             /*-----------*/popTrace();
  501.  
  502.             lineno++;             
  503.             /*-----------*/pushTrace(1240);
  504.             markCodes();        
  505.             /*-----------*/popTrace();
  506.             /*-----------*/pushTrace(1250);
  507.             if (zeroCheckMode)
  508.             {
  509.                 checkZeros1();
  510.                 checkCrossing();
  511.             }
  512.             /*-----------*/popTrace();
  513.             if (fatalError) break;
  514.             if (needJump) break;
  515.             //if (needCall||needJump) break;
  516.     }
  517.     /* go round the loop */
  518. }
  519.  
  520. // **************************************************
  521. // disassembler monitoring or surporting functions
  522. // **************************************************
  523.  
  524. /* ---------------------------------------------------------------------
  525.  * the possible error cases:
  526.  *    -1, -11, 100~399, 900, 990 = unrecovable cur_position must be erased.
  527.  *    992 = Address blocks has been decoded as instruction stream
  528.  *          so referenced position must be erased. - emergency case.
  529.  *    -2 = cur instruction passes over the next instruction
  530.  *         3 possible cases: (1) me-OK,you-NOT (2) me-NOT,you-OK (3) me-NOT,you-NOT
  531.  *    -3,-4,-5,-6,-7 = zero check error
  532.  *         2 possible cases: (1) good code - data, (2) bad code
  533.  *    994 = reference of cur instruction touches data 
  534.  *        = reference of cur instruction touches body of some other instruction
  535.  *         3 possible cases: (1) me-OK,you-NOT (2) me-NOT,you-OK (3) me-NOT,you-NOT
  536.  *    999 = some other instruction touches my body
  537.  *         3 possible cases: (1) me-OK,you-NOT (2) me-NOT,you-OK (3) me-NOT,you-NOT
  538.  * ----------------------------------------------------------------------
  539.  */
  540.  
  541. void markCodes()
  542. {
  543. int       i;
  544. DWORD     r;
  545.     
  546.     r=cur_position;
  547.     if (nextMode) 
  548.     {
  549.         if (i_opcode==0xCC && getByteFile(r-1)==0xCC && getByteFile(r+1)==0xCC) 
  550.         {
  551.             /*------------*/pushTrace(1300);
  552.             setMap(r,0x0C); 
  553.             /*------------*/popTrace();
  554.         }
  555.         else
  556.         {
  557.             if (nextMode==1) 
  558.             {   
  559.                 /*-----------*/pushTrace(1310);
  560.                 orMap(r, 0x05);
  561.                 /*-----------*/popTrace();
  562.                 for(i=1;i<i_col_save;i++) 
  563.                 if(getMap(r+(DWORD)i)&0x40) 
  564.                 {
  565.                     fatalError=900;
  566.                     break;
  567.                 }
  568.                 else 
  569.                 {
  570.                     /*--------*/pushTrace(1320);
  571.                     orMap(r+(DWORD)i,0x04);
  572.                     /*--------*/popTrace();
  573.                 }
  574.             }
  575.             else
  576.             {
  577.                 /*------------*/pushTrace(1330);
  578.                 orMap(r, 0x07);
  579.                 /*------------*/popTrace();
  580.                 for(i=1;i<i_col_save;i++) 
  581.                 if(getMap(r+(DWORD)i)&0x40)
  582.                 {
  583.                     fatalError=900;
  584.                     break;
  585.                 }
  586.                 else 
  587.                 {
  588.                     /*--------*/pushTrace(1340);
  589.                     orMap(r+(DWORD)i,0x06);
  590.                     /*--------*/popTrace();
  591.                 }
  592.             }
  593.             if(fatalError==0)
  594.             for(i=1;i<i_col_save;i++)
  595.                 if (getMap(r+(DWORD)i)&0x20)
  596.                 {
  597.                    dmLabels[dmc++]=r+(DWORD)i; 
  598.                    fatalError=999;
  599.                    /*---------*/pushTrace(1350);
  600.                    exMap(r+(DWORD)i,0x20);
  601.                    /*---------*/popTrace();
  602.                 }
  603.         }
  604.     }
  605. }
  606.  
  607. int ErrorRecoverNum=0;
  608. history my_h;
  609. void ErrorRecover()
  610. {
  611. //int     i;    
  612.  
  613.     //printf("\nError Recover %08X::code=%5d  ", cur_position, fatalError);
  614.     my_h.m=nextMode;
  615.     my_h.f=fatalError;
  616.     my_h.r=lastReset;
  617.     my_h.c=cur_position;
  618.  
  619.          if (fatalError==256) 
  620.     {     
  621.         /*------------*/pushTrace(1400);
  622.         trySomeAddress(cur_position);
  623.         /*------------*/popTrace();
  624.     }
  625.     else if (fatalError==999)
  626.     {
  627.          //fprintf(stdout,"\n:%08X ",cur_position);
  628.          //for(i=cur_position-2;i<cur_position+i_col_save+3;i++)
  629.          //fprintf(stdout," %02X",getMap(i));
  630.          //fprintf(stdout,"\n:%08X ",cur_position);
  631.          //for(i=cur_position-2;i<cur_position+i_col_save+3;i++)
  632.          //fprintf(stdout," %02X",getByteFile(i));
  633.  
  634.         /*------------*/pushTrace(1410);
  635.          if (dmc>0) clearSomeBadGuy(&my_h);
  636.         /*------------*/popTrace();
  637.     }
  638.     else if (fatalError!=0)
  639.     {
  640.         //for(i=cur_position-2;i<cur_position+3;i++)
  641.         //fprintf(stdout," %02X",getMap(i));
  642.         /*------------*/pushTrace(1420);
  643.         eraseUncertain(cur_position, &my_h);
  644.         /*------------*/popTrace();
  645.         //fprintf(stderr,"=%d",fatalError);
  646.     }
  647.     //getch();
  648.     /*------------*/pushTrace(1415);
  649.     if (dmc>0) clearSomeBadGuy(&my_h);
  650.     /*------------*/popTrace();
  651.     ErrorRecoverNum++;
  652.     dmc=0;
  653.     fatalError=0;
  654. }
  655.  
  656.  
  657. void clearSomeBadGuy(PHISTORY ph)
  658. {
  659. int   i;
  660.     //fprintf(stderr,"\n Clear Some Bad Guy ");
  661.     for (i=0;i<dmc;i++)
  662.     {
  663.         /*-----------*/pushTrace(1450);
  664.         eraseCarefully(dmLabels[i], ph);
  665.         /*-----------*/popTrace();
  666.     }
  667.     
  668.     dmc=0;
  669.     //for (i=0;i<dmc;i++)
  670.     //   fprintf(stderr,"\ndmLabels==%08X",dmLabels[i]);//,getch();
  671.     if(nextMode==3)
  672.     {
  673.         //fprintf(stderr,"**************** LOOK HERE ********************");
  674.         //getch();
  675.     }
  676. }
  677.  
  678. //
  679. // minimum filter to check if this is code or not. 
  680. //
  681. void checkZeros()
  682. {    
  683. static int  colsave=-1;
  684.     
  685.     if (i_opcode==0x90 && opsave==0 && modsave==0) fatalError=-4;
  686.     if (i_opcode==0 && i_mod==0 && opsave==0x90) fatalError=-5;
  687.     if (i_opcode==0 && i_mod==0 && opsave==0xC3) fatalError=-6;
  688.     if (i_opcode==opsave && i_opcode <0x0A 
  689.      && i_col_save == colsave && i_mod<0x0A && i_mod == modsave) 
  690.     {
  691.        fatalError=-7;
  692.        //fprintf(stderr,"\nWWW %08X -7::",cur_position);
  693.     }
  694.     if (i_opcode==0 && i_mod==0 && opsave==0 && modsave==0) fatalError=-3;
  695.     opclassSave=opclass; opsave=i_opcode; modsave=i_mod; colsave=i_col_save;
  696. }
  697.  
  698. void checkZeros1()
  699. {
  700. static int opsave1=-1, modsave1=-1, colsave1=-1;
  701.     
  702.     if (i_opcode==0x90 && opsave1==0 && modsave1==0) fatalError=-4;
  703.     if (i_opcode==0 && i_mod==0 && opsave1==0x90) fatalError=-5;
  704.     if (i_opcode==0 && i_mod==0 && opsave1==0xC3) fatalError=-6;
  705.     if (i_opcode==opsave1 && i_opcode <0x1F 
  706.      && i_col_save == colsave1 && i_mod<0x1F && i_mod == modsave1) fatalError=-7; 
  707.     if (i_opcode==0 && i_mod==0 && opsave1==0 && modsave1==0) fatalError=-3;
  708.     //if (i_opcode==opsave1 && i_col_save == colsave1) fatalError=-1;
  709.     opsave1=i_opcode; modsave1=i_mod; colsave1=i_col_save;
  710. }
  711.  
  712. //extern FILE *d_fp;
  713.  
  714. void checkCrossing()
  715. {
  716. DWORD      i;
  717. DWORD      r=0;
  718.     
  719.     for(i=cur_position+1;i<cur_position+i_col_save;i++) if (getMap(i)&0x49) break; 
  720.     if (i==cur_position+i_col_save)  return;
  721.     if (getByteFile(cur_position)==0x00) 
  722.     { 
  723.         /*-------------*/pushTrace(1460);
  724.         setMap(cur_position,0x0F); 
  725.         /*-------------*/popTrace();
  726.         return;
  727.     }
  728.     
  729.     //fprintf(d_fp,"\n.cc. %08X: nM=%d :",cur_position,nextMode);
  730.     //for(i=cur_position;i<cur_position+i_col_save;i++) 
  731.     //    fprintf(d_fp,"%02X ",getByteFile(i)); 
  732.     //fprintf(d_fp,"\n.cc. %08X:      :",cur_position);
  733.     //for(i=cur_position;i<cur_position+i_col_save;i++) 
  734.     //    fprintf(d_fp,"%02X ",getMap(i));       
  735.  
  736.     //if ((getMap(i)&0xF0)==0xF0) r=tryToSaveIt(cur_position+i_col_save);
  737.     if (r==0) fatalError=-8;
  738.     else
  739.     {
  740.         //fprintf(stderr," GOTIT %08X-%08X ", cur_position,r);
  741.         /*--------------*/pushTrace(1470);
  742.         for(i=cur_position;i<r;i++) setMap(i,0x00);
  743.         /*--------------*/popTrace();
  744.         /*--------------*/pushTrace(1480);
  745.         saveIt(cur_position);
  746.         /*--------------*/popTrace();
  747.         //getch();
  748.     }
  749. }
  750.  
  751. // *****************************************
  752.  
  753. DWORD GetNextOne()
  754. {
  755. DWORD    r, rr;
  756. BYTE   b;
  757.  
  758.     if (needJump==1)
  759.     {   
  760.         /*--------------*/pushTrace(1490);
  761.         rr=isItStartAnyWay(needJumpNext);
  762.         if (rr) addLabels(needJumpNext, 2);
  763.         /*--------------*/popTrace();
  764.         needJump=0;    needJumpNext=0;
  765.     }
  766.     while(1)
  767.     {
  768.         r=getLabels();
  769.         r=AddressCheck(r);
  770.         if (r==0) break;
  771.         b=getMap(r);
  772.         if((b&0x0F)==0x00) break; 
  773.     }
  774.     return r;
  775. }
  776.  
  777. int isThisGoodRef(DWORD ref, DWORD s, DWORD e)
  778. {
  779. DWORD    r;
  780. _key_  k;
  781. PKEY   pk;
  782.     
  783.     k.c_ref=ref; k.c_pos=-1; k.class=0;
  784.     pk = searchBtree3(&k);
  785.     if (pk==NULL) return 0;
  786.     r=pk->c_pos;
  787.     if (isGoodAddress(r)&&(r<s||e<r)) return 1; 
  788.     return 0;
  789. }
  790.  
  791. int tryToSaveIt(DWORD ref)
  792. {
  793. //int      i, j, n, r, s, pos;
  794. //BYTE     b, d;
  795.     
  796.     if (!isGoodAddress(ref)) return 0;
  797.     
  798.     //if((getMap(ref)&0x05)==0x05)return 1;
  799.     pushEnvironment();
  800.     nextMode=0;
  801.     zeroCheckMode=0;
  802.     //printMode=0;
  803.  
  804.     resetDisassembler(ref);
  805.  
  806.     /*-----------*/pushTrace(1500);
  807.     Disassembler1();
  808.     /*-----------*/popTrace();
  809.  
  810.     if (fatalError==0) 
  811.     {
  812.         popEnvironment();
  813.         fprintf(stderr,"."); 
  814.         showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  815.         return 1;
  816.     }
  817.     popEnvironment();
  818.     return 0;
  819. }
  820.  
  821. void saveIt(DWORD ref)
  822. {
  823. //int      i, j, n, r, s, pos;
  824. //BYTE     b, d;
  825. DWORD      r;
  826.  
  827.     if (!isGoodAddress(ref)) return;
  828.     
  829.     pushEnvironment();
  830.     nextMode=1;
  831.     zeroCheckMode=0;
  832.     //printMode=0;
  833.  
  834.     resetDisassembler(ref);
  835.  
  836.     /*-----------*/pushTrace(1550);
  837.     Disassembler1();
  838.     /*-----------*/popTrace();
  839.  
  840.     if (fatalError==0) 
  841.     {
  842.         r=cur_position;
  843.         popEnvironment();
  844.         return;
  845.     }
  846.     popEnvironment();
  847. }
  848.  
  849. int isItStartAnyWay(DWORD ref)
  850. {
  851. static BYTE    CodeTab[100]={
  852.        0x0F,0x2D,0x31,0x32,0x33,0x39,0x3A,0x3B,0x3D,0x46,0x47,
  853.        0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5D,0x5E,0x5F,
  854.        0x64,0x66,0x68,0x6A,0x7C,0x7D,0x80,0x81,0x83,0x84,0x85,0x88,0x89,0x8A,0x8B,0x8D,
  855.        0xA1,0xA8,0xA9,0xAC,0xB0,0xB2,0xB3,0xB8,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,
  856.        0xC1,0xC2,0xC3,0xC6,0xC7,0xC8,0xD9,0xDB,0xDD,0xDF,0xE8,0xE9,0xEB,0xF6,0xF7,0xFF,0x00,};
  857. int    i, j, tok;
  858. DWORD  r, t;
  859. BYTE   b, c, d;
  860.  
  861.     //fprintf(stderr, "1");
  862.     
  863.     if (ref==0) return 0;
  864.     if (nextMode>0 && ref==needJumpNext)
  865.     {
  866.         r=ref;
  867.         while((b=getByteFile(r))==0x00 && getMap(r)==0x00) {setMap(r++,0x0F);}
  868.         i = getIntFile(r);
  869.         if (i==-1) 
  870.         {
  871.             setMap(r,0x0F); setMap(r+1,0x0F); setMap(r+2,0x0F); setMap(r+3,0x0F);
  872.         }
  873.     }
  874.     b = getByteFile(ref);
  875.     if (b==0) return 0;
  876.     //if (ref==debugAdd)fprintf(stderr,"\nisItstartAnyWay=%08X %02X",ref,getMap(ref)),getch();
  877.     if (strchr(CodeTab,b)==NULL) return 0;
  878.     if (getMap(ref)&0x0F) return 0;
  879.     
  880.     //if (ref==debugAdd){fprintf(stderr,"\nisItstartAnyWay=%08X 2",ref);getch();}
  881.     pushEnvironment();                                                 
  882.     nextMode=0;
  883.     zeroCheckMode=1;
  884.     //printMode=0;
  885.  
  886.     resetDisassembler(ref);
  887.  
  888.     /*-----------*/pushTrace(1600);
  889.     for(i=0;i<48;i++)
  890.     {                          
  891.             addressfix();
  892.             c = getMap(cur_position);
  893.             b = getByteFile(cur_position);
  894.             if (b==0x00)
  895.             {
  896.                 for(r=ref;r<cur_position;r++) if((getMap1(r)&0x04)==0x00) break;
  897.                 if (r>=cur_position-1) {fatalError=-9; break;}
  898.             }
  899.             
  900.                  if ((c&0x08)==0x08) break; 
  901.             else if ((c&0x05)==0x05) break;  
  902.             addressprint1(0);
  903.             tok = instruction(0);
  904.             if (tok==0) {fatalError=-11; break;}
  905.             bodyprint(0);
  906.             for(j=1;j<i_col_save;j++) 
  907.             {
  908.                 d=getMap(cur_position+j);
  909.                 if (d&0x49) { fatalError=-99; break; }
  910.             }
  911.             if (b==0xEB)
  912.             {
  913.                 r=getByteFile(cur_position+1);
  914.                 if(r>127) r-=256;
  915.                 r+=cur_position+2;
  916.                 if ((getMap(r)&0x05)==0x05)
  917.                 {
  918.                     for(t=r;t<r+256;t++) 
  919.                     {
  920.                         if(getMap(t)&0x80 || (getMap(t)&0x04)==0x00) break;
  921.                     }
  922.                     if((getMap(t)&0x04)&&(t<r+256)) break;
  923.                 }
  924.             }
  925.             if (zeroCheckMode)
  926.             {
  927.                 checkZeros1();
  928.             }
  929.             if (fatalError) break;
  930.             if (needJump) break;
  931.     }
  932.     /*-----------*/popTrace();
  933.  
  934.     if (fatalError==0) 
  935.     {
  936.         popEnvironment();
  937.         //if (ref==debugAdd)
  938.         //{fprintf(stderr,"\nisItstartAnyWay=%08X OK ",ref);getch();}
  939.         return ref;
  940.     }     
  941.     //if (ref==debugAdd)
  942.     //{fprintf(stderr,"\nisItstartAnyWay=%08X NOTOK %d",ref,fatalError);
  943.     // getch();}
  944.     fatalError=0;
  945.     popEnvironment();
  946.     return 0;
  947. }
  948.  
  949. void trySomeAddress(DWORD ref)
  950. {
  951. DWORD      i, r, rr, rmax;
  952.  
  953.      r=ref;
  954.      rmax=imageBase+getRVA(CodeOffset+CodeSize-1)+1;
  955.  
  956.      while((getMap(r)&0x0E)==0x0E){r++;}
  957.  
  958.      fprintf(stderr,"."); 
  959.      showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  960.  
  961.      // I don't know why I am doing this way but somehow it makes sense.
  962.      for (i=r;i<rmax;i+=4)
  963.      {
  964.          rr=getIntFile(i);
  965.          if (AddressCheck(rr) > 0)
  966.          {
  967.              if ((getMap(i+0)==0x00)
  968.                &&(getMap(i+1)==0x00)
  969.                &&(getMap(i+2)==0x00)
  970.                &&(getMap(i+3)==0x00))
  971.              {
  972.                  /*---------*/pushTrace(1700);
  973.                  EnterLabel(166, rr,i);
  974.                  /*---------*/popTrace();
  975.              }
  976.          }
  977.          else break;
  978.      }
  979. }
  980.  
  981. void  tryAnyAddress()
  982. {
  983. //static int col=0;
  984. DWORD    r, rmax;
  985. DWORD    rmaxTab[32], rstartTab[32];
  986. int      i, j, k, n, num, c;
  987. DWORD    s, e, ss;
  988. BYTE     b, d;
  989.     
  990.     fprintf(stderr,"."); 
  991.     showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  992.  
  993.     num=nSections;
  994.     if (num>32) {num=32; fprintf(stderr,"\n...please increase the size...");}
  995.     j=0;
  996.     for (i=0;i<num;i++)
  997.     {
  998.         c=(int)shdr[i].Characteristics;
  999.         if ((c&0x60000020)==0x60000020 || c==0xC0000040) 
  1000.         {
  1001.             rstartTab[j]     = imageBase+shdr[i].VirtualAddress;
  1002.             rmaxTab[j]       = imageBase+shdr[i].VirtualAddress+shdr[i].SizeOfRawData;
  1003.             j++;
  1004.         }
  1005.     }
  1006.     num=j;
  1007.  
  1008.     /*
  1009.     for (i=0;i<num;i++)
  1010.     {
  1011.         fprintf(stderr,"\nrstartTab[i]=%08X,rmaxTab[i]=%08X",rstartTab[i],rmaxTab[i]);
  1012.     }*/  
  1013.  
  1014.     fprintf(stderr,".");
  1015.     showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  1016.     for(k=0;k<num;k++)
  1017.     {
  1018.         r=rstartTab[k]; rmax=rmaxTab[k];
  1019.         while(r<rmax)
  1020.         {
  1021.              if (AddressCheck(getIntFile(r)) > 0) 
  1022.              {
  1023.                  if (AddressCheck(getIntFile(r+1)) > 0
  1024.                    ||AddressCheck(getIntFile(r+2)) > 0
  1025.                    ||AddressCheck(getIntFile(r+3)) > 0) 
  1026.                  {
  1027.                      r++;
  1028.                  }
  1029.                  else 
  1030.                  { 
  1031.                      //fprintf(stderr,"\nsetAnyAddress=%08X %08X",r,getIntFile(r)); 
  1032.                      //getch();
  1033.                      setAnyAddress(r); r+=4; 
  1034.                  }
  1035.              }
  1036.              else 
  1037.              {
  1038.                  r++;
  1039.              }
  1040.         }
  1041.     }
  1042.  
  1043.     fprintf(stderr,".");
  1044.     showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  1045.     for(k=0;k<num;k++)
  1046.     {
  1047.         r=rstartTab[k]; rmax=rmaxTab[k];
  1048.         while(r<rmax)
  1049.         {
  1050.              b=getByteFile(r);d=getByteFile(r+4);
  1051.              if ((b==0xE8)&&(isGoodAddress(s=r+5+getIntFile(r+1)))) 
  1052.              {
  1053.                  /*--------------*/pushTrace(1710);
  1054.                  if (!isItAnyAddress(s) && isItFirstTime(s) && isItStartAnyWay(s))
  1055.                  { 
  1056.                      addLabels(s, 64); 
  1057.                      addRef(1710,s,r);
  1058.                      r+=5; 
  1059.                  } 
  1060.                  else r++;
  1061.                  /*--------------*/popTrace();
  1062.              }
  1063.              else r++;
  1064.         }
  1065.         
  1066.         r=rstartTab[k]; rmax=rmaxTab[k];
  1067.         while(r<rmax)
  1068.         {
  1069.              n=trySomeMoreAddress(r,rmax,&ss);
  1070.              if (n==0) r=rmax;
  1071.              else 
  1072.              {
  1073.                  for(s=ss;s<ss+4*n;s+=4)
  1074.                  {
  1075.                      e=getIntFile(s);
  1076.                      /*--------------*/pushTrace(1720);
  1077.                      if (isGoodAddress(e)&&!isItAnyAddress(e)
  1078.                          &&isItFirstTime(e)&&isItStartAnyWay(e))
  1079.                      { addLabels(e, 16); addRef(1720,e,s);} 
  1080.                      //if(e==0x0045605C)fprintf(stderr,"\nGOTaddLabels2 from%08X",s),getch();
  1081.                      /*--------------*/popTrace();
  1082.                  }
  1083.                  r=ss+4*n;
  1084.              }
  1085.         }
  1086.     }
  1087. }
  1088.  
  1089. int tryMoreAddress(DWORD s, DWORD e, PDWORD start)
  1090. {
  1091. DWORD   i, r;
  1092.  
  1093.     //fprintf(stderr,"\ntryMoreAddress s=%08X e=%08X ", (int)s, (int)e);
  1094.     for (i=s;i<e;i++) if (isItAnyAddress(i)) break;
  1095.     if (i==e) {*start=0; return 0;}
  1096.     r=i; 
  1097.     for (i=r+4;getOffset(i)<CodeOffset+CodeSize;i+=4) if (!isItAnyAddress(i)) break;
  1098.     *start=r;
  1099.     return (i-r)/4;
  1100. }
  1101.  
  1102. int trySomeMoreAddress(DWORD s, DWORD e, PDWORD start)
  1103. {
  1104. DWORD   i, r, rmax;
  1105.  
  1106.     r=s;
  1107.     rmax=e+CodeSize;
  1108.     while(1)
  1109.     {
  1110.         for (;r<e;r++) if (isItAnyAddress(r)) break;
  1111.         if (r==e) {*start=0; return 0;}
  1112.         for (i=r+4;i<rmax;i+=4) if (!isItAnyAddress(i)) break;
  1113.         *start=r;
  1114.         if (i-r >12) return (i-r)/4;
  1115.         r++;
  1116.     }
  1117. }
  1118.  
  1119. int looksLikeMenus(DWORD ref)
  1120. {
  1121. DWORD    i, n;
  1122.  
  1123.     for (i=ref;i<ref+12;i++) if (getIntFile(i)==-1) break;
  1124.     if (i==ref+12) return 0;
  1125.     i=ref; while(isprint(getByteFile(i))) i--; n=i;
  1126.     for (i=n;i>n-12;i--) if (getIntFile(i)==-1) break;
  1127.     if (i==n-12) return 0;
  1128.     return 1;
  1129. }
  1130.  
  1131. void showPascalString(DWORD ref)
  1132. {
  1133. DWORD     i;
  1134. int       n;
  1135.     n = getByteFile(ref);
  1136.     orMap1(ref,0x07); 
  1137.     //fprintf(stderr,"\n:%08X..pascalString..",ref);
  1138.     printf("\n:%08X..pascalString..",(int)ref);
  1139.     //for (i=ref+1;i<ref+n+1;i++) fprintf(stderr,"%c",getByteFile(i));
  1140.     for (i=ref+1;i<ref+n+1;i++) {orMap1(i,0x06); printf("%c",getByteFile(i));}
  1141. }
  1142.  
  1143. void showNullString(DWORD ref)
  1144. {
  1145. DWORD     i;
  1146. int       n;
  1147.     //fprintf(stderr,"\n:%08X....NullString..",ref);
  1148.     printf("\n:%08X....NullString..",(int)ref);
  1149.     for (i=ref;i<ref+256;i++) if (!isprint(getByteFile(i))) break;
  1150.     n=i-ref;
  1151.     orMap1(ref,0x05); 
  1152.     //fprintf(stderr,"%c",getByteFile(ref)); 
  1153.     //for (i=ref+1;i<ref+n;i++) fprintf(stderr, "%c",getByteFile(i));
  1154.     printf("%c",getByteFile(ref));
  1155.     for (i=ref+1;i<ref+n;i++) {orMap1(i,0x04); printf("%c",getByteFile(i));}
  1156.     if (getByteFile(i)==0x00) {orMap1(i,0x04);} else
  1157.     if (getByteFile(i)==0x0D && getByteFile(i+1)==0x0A)
  1158.     { orMap1(i,0x04);orMap1(i+1,0x04); printf(" <cr><lf>");} else
  1159.     if (getByteFile(i)==0x0A)
  1160.     { 
  1161.         orMap1(i,0x04); printf(" <lf>");
  1162.         if (getByteFile(i+1)==0x0A) {orMap1(i+1,0x04); printf(" <lf>");} else
  1163.         if (getByteFile(i+1)==0x00) {orMap1(i+1,0x04);}
  1164.     } else
  1165.     if (getByteFile(i)==0x09)
  1166.     { 
  1167.         orMap1(i,0x04); printf(" <t>");
  1168.         if (getByteFile(i+1)==0x09) {orMap1(i+1,0x04); printf(" <t>");} else
  1169.         if (getByteFile(i+1)==0x00) {orMap1(i+1,0x04);}
  1170.     } 
  1171.     if (getByteFile(i)==0x00) {orMap1(i,0x04);}
  1172. }
  1173.  
  1174. void markStrings(DWORD s, DWORD e)
  1175. {
  1176. DWORD    i;
  1177. BYTE     b, d;
  1178.     
  1179.     /*-------------*/pushTrace(1800);
  1180.     i=s;
  1181.     while(i<e)
  1182.     {
  1183.         while(i<e) 
  1184.         {b=getMap1(i); d=getMap(i); if((b&0x05)==0x05 && (d==0x00 || (d&0x08)))break; i++;}
  1185.         if ((b&0x07)==0x07)
  1186.         {
  1187.             setMap(i++,0x0B); 
  1188.             while(i<e+256)
  1189.             {
  1190.                 b=getMap1(i); 
  1191.                 if ((b&0x07)==0x06) setMap(i++,0x0A);
  1192.                 else break;
  1193.             }
  1194.         }
  1195.         else if ((b&0x07)==0x05)
  1196.         {
  1197.             setMap(i++,0x09); 
  1198.             while(i<e+256)
  1199.             {
  1200.                 b=getMap1(i); 
  1201.                 if ((b&0x07)==0x04) setMap(i++,0x08);
  1202.                 else break;
  1203.             }
  1204.         }
  1205.         else i++;
  1206.         if ((b&0x05)!=0x05) i++; 
  1207.     }
  1208.     /*-------------*/popTrace();
  1209. }
  1210.  
  1211. int     maybePartof(DWORD r)
  1212. {
  1213. int   i, m, o;
  1214.     o=opcodeTable[getByteFile(r-1)];
  1215.     if (o==4||o==44) return 1;
  1216.     i=opcodeTable[getByteFile(r-2)];
  1217.     m=modTable[o];
  1218.     if (5<i&&i<12&&(m==3||m==6)) return 1;
  1219.     if (i==11 && (m==1||m==8)) return 1;
  1220.     if (i==13 && rmTable[o]==5 && (m==3||m==6)) return 1;
  1221.     return 0;
  1222. }
  1223.  
  1224. void markAddress(DWORD s, DWORD e)
  1225. {
  1226. DWORD    i;
  1227. int      n;
  1228. BYTE     b, d;
  1229.     
  1230.     /*-------------*/pushTrace(1850);
  1231.     i=s;
  1232.     while (i<e)
  1233.     {
  1234.         b=getMap1(i); d=getMap(i); n=getIntFile(i);
  1235.         if (d==0x00 && getMap(i+1)==0x00 && getMap(i+2)==0x00  && getMap(i+3)==0x00 
  1236.             && (b&0x34)==0x30 && !maybePartof(i)) 
  1237.         {
  1238.             setMap(i,0x0E); setMap(i+1,0x0E); setMap(i+2,0x0E), setMap(i+3,0x0E); 
  1239.             if (isGoodAddress(n) && (getMap(n)&0x25)==0x25 && referCount(n)==0) 
  1240.                 EnterLabel(167,n,i);
  1241.             i+=3;
  1242.         }
  1243.         else if (d==0x00 && n==-1) 
  1244.         {setMap(i,0x0E); setMap(i+1,0x0E); setMap(i+2,0x0E), setMap(i+3,0x0E); i+=3;}
  1245.         i++;
  1246.     }
  1247.     /*-------------*/popTrace();
  1248. }
  1249.  
  1250. void markAddress1(DWORD s, DWORD e)
  1251. {
  1252. DWORD    i;
  1253. int      n;
  1254. BYTE     b, d;
  1255.     
  1256.     /*-------------*/pushTrace(1850);
  1257.     i=s;
  1258.     while (i<e)
  1259.     {
  1260.         b=getMap1(i); d=getMap(i); n=getIntFile(i);
  1261.         if ((b&0x3C)==0x30 && 
  1262.               d==0x0F && getMap(i+1)==0x0F && getMap(i+2)==0x0F  && getMap(i+3)==0x0F) 
  1263.         {setMap(i,0x0E); setMap(i+1,0x0E); setMap(i+2,0x0E), setMap(i+3,0x0E); i+=3;}
  1264.         else if (d==0x0F && n==-1) 
  1265.         {setMap(i,0x0E); setMap(i+1,0x0E); setMap(i+2,0x0E), setMap(i+3,0x0E); i+=3;}
  1266.         i++;
  1267.     }
  1268.     /*-------------*/popTrace();
  1269. }
  1270.  
  1271. void tryPascalStrings()
  1272. {
  1273. //static int col=0;
  1274. DWORD    r, rmax;
  1275. int      num;
  1276. DWORD    rmaxTab[32], rstartTab[32];
  1277. DWORD    i;
  1278. int      j, k, n, c, a, l;
  1279. BYTE     b, d;
  1280.     
  1281.     num=nSections;
  1282.     if (num>32) {num=32; fprintf(stderr,"\n...please increase the size...");}
  1283.     j=0;
  1284.     for (i=0;i<num;i++)
  1285.     {
  1286.         c=(int)shdr[i].Characteristics;
  1287.         if ((c&0x60000020)==0x60000020) 
  1288.         {
  1289.             rstartTab[j]     = imageBase+shdr[i].VirtualAddress;
  1290.             rmaxTab[j]       = rstartTab[j]+shdr[i].SizeOfRawData;
  1291.             j++;
  1292.         }
  1293.     }
  1294.     num=j;
  1295.  
  1296.     fprintf(stderr,".");
  1297.     showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  1298.     printf("\n\n+++++++++++++++++++ Possible Strings Inside Code Block +++++++++++++++++++ \n");
  1299.     for(k=0;k<num;k++)
  1300.     {
  1301.         r=rstartTab[k]; rmax=rmaxTab[k];
  1302.         l=0;
  1303.         while(r<rmax)
  1304.         {
  1305.              
  1306.              while(!isprint(b=getByteFile(r))) r++;
  1307.              if (getMap1(r-1)) n=0; 
  1308.              else n=getByteFile(r-1);
  1309.              i=r;      a=0;     c=0;
  1310.              while(isprint(b=getByteFile(i))) 
  1311.              {if(isalnum(b)||b==0x20||b=='\\')a++;c++;i++;}
  1312.              if ((n>4 || (n>2 && r<l+8)) && n<31 && n<=c && ((n<=a) || (n>8))) 
  1313.              {showPascalString(r-1); r=r+n; l=r;}
  1314.              else if (c>4 
  1315.                       && (   b==0x00 
  1316.                          || (b==0x0A && ((d=getByteFile(i+1))==0x0A || isprint(d) || d==0x00))
  1317.                          || (b==0x0D && ((d=getByteFile(i+1))==0x0A)) 
  1318.                          || (b==0x09 && ((d=getByteFile(i+1))==0x09 || d==0x00))
  1319.                          )       
  1320.                      ) 
  1321.              {
  1322.                  if(c>5||!touchAnyAddress(i-1)||looksLikeMenus(i-1)) 
  1323.                  showNullString(r); 
  1324.                  while (getMap1(i)==0x04) i++; 
  1325.                  if(getByteFile(i)==0x00) i++; r=i; l=r;
  1326.              }
  1327.              else r++;
  1328.         }
  1329.     }
  1330. }
  1331.  
  1332. void checkOneInstructionFiller(DWORD r)
  1333. {
  1334.     /*--------------*/pushTrace(1900);
  1335.     if (getMap(r)==0 && getMap(r+1)==0 && getMap(r+2)!=0 &&
  1336.         getByteFile(r)==0x8B && getByteFile(r+1)==0xC0) 
  1337.     {setMap(r,0x05); setMap(r+1,0x04);}
  1338.     /*--------------*/popTrace();
  1339.     return;
  1340. }
  1341.  
  1342. void changeToAddress(DWORD s, DWORD e)
  1343. {
  1344. }
  1345.  
  1346. void changeToBytes(DWORD s, DWORD e)
  1347. {
  1348. }
  1349.  
  1350. void changeToCode(DWORD s, DWORD e)
  1351. {
  1352. DWORD   i; 
  1353. BYTE    b;
  1354.  
  1355.     //fprintf(stderr,"\nGEE YOU GOT ME s=%08X e=%08X",s,e);getch();
  1356.     for (i=s;i<e;i++) {b=getMap(i);exMap(i,(b&0x0F));}
  1357.     nextMode=3;
  1358.     zeroCheckMode=1;
  1359.     //printMode=0;
  1360.  
  1361.     resetDisassembler(s);
  1362.     Disassembler1();
  1363. }
  1364.  
  1365. void changeToDword(DWORD s, DWORD e)
  1366. {
  1367. }
  1368.  
  1369. void changeToFloat(DWORD s, DWORD e)
  1370. {
  1371. }
  1372.  
  1373. void changeToDouble(DWORD s, DWORD e)
  1374. {
  1375. }
  1376.  
  1377. void changeToQuad(DWORD s, DWORD e)
  1378. {
  1379. }
  1380.  
  1381. void changeTo80Real(DWORD s, DWORD e)
  1382. {
  1383. DWORD    i;
  1384.  
  1385.     //fprintf(stderr,"\nchangeTo80Real %08X %08X",s,e),getch();
  1386.     if (e==0) 
  1387.     {
  1388.         if(getMap(s)&0x20); else setMap(s,0x1F); 
  1389.         for(i=s+1;i<s+10;i++)setMap(i,0x0F);
  1390.     }
  1391.     else if(e>s && (e-s)%10==0)
  1392.     {
  1393.         for(i=s;i<e;i++)
  1394.         {
  1395.             orMap(i,0x0F);
  1396.             if((i-s)%10==0) 
  1397.             {
  1398.                 if(getMap(i)&0x20); else orMap(i,0x10);
  1399.             }
  1400.         }
  1401.     }
  1402. }
  1403.  
  1404. void changeToWord(DWORD s, DWORD e)
  1405. {
  1406. }
  1407.  
  1408. void changeToNullString(DWORD r)
  1409. {
  1410. }
  1411.  
  1412. void changeToPascalString(DWORD r)
  1413. {
  1414. }
  1415.  
  1416. void PostProcessing2(DWORD s, DWORD e)
  1417. {
  1418. DWORD    i, r;
  1419. int      n, nn, nz;
  1420. DWORD    rs, re, ri, rr, rt, rmax;
  1421. DWORD    ts, te;
  1422. int      cBox[256];
  1423. BYTE     b;
  1424.  
  1425.     fprintf(stderr,"*");
  1426.     showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  1427.     r        = s;
  1428.     rmax     = e;
  1429.     r=rmax-1;
  1430.     while(getByteFile(r)==0&&(getMap(r)&0x80)==0)r--;
  1431.     r++;
  1432.     while(r<rmax)
  1433.     {
  1434.         /*---------*/pushTrace(1910);
  1435.         setMap(r, 0x0F); r++;
  1436.         /*---------*/popTrace();
  1437.     }
  1438.     // I got something which is not processed yet.   
  1439.     // I'll set everything to byte data whew...
  1440.     r=s;
  1441.     while(r<rmax) 
  1442.     {   
  1443.         if ((getMap(r)&0x0C)==0)
  1444.         {   
  1445.             //checkOneInstructionFiller(r);
  1446.             /*---------*/pushTrace(1920); 
  1447.             setMap(r, 0x0F); 
  1448.             /*---------*/popTrace();
  1449.         }
  1450.         r++;
  1451.     }
  1452.     // now i am doing something should be done.
  1453.     // i am trying to find code blocks which lies between
  1454.     // some address blocks or byte blocks which is imcomplete
  1455.     // namely, which does not have return or jmp statement.
  1456.     // so it should looks like
  1457.     // {START|address|byte}code{address|byte|END}
  1458.     // if this code block ends with C3 or C2 something or 
  1459.     // one of jmp statment it is OK
  1460.     // otherwise there is some problem.
  1461.     
  1462.     r=s;
  1463.     ri=r;
  1464.     fprintf(stderr,".");
  1465.     showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  1466.     //fprintf(stderr, " p1");
  1467.     while(r<rmax)
  1468.     {
  1469.         while((b=getMap(r))&0x08)
  1470.         {
  1471.             if (b==0x2F)
  1472.             {
  1473.                 /*----------*/pushTrace(1930); 
  1474.                 setMap(r, 0x0F); rr=r; 
  1475.                 /*----------*/popTrace();
  1476.             }
  1477.             r++;
  1478.         }
  1479.         rs=r;n=0;rt=0;
  1480.         for(i=0;i<256;i++)cBox[i]=0;
  1481.         while((r<rmax)&&(((b=getMap(r))&0x08)==0x00))
  1482.         {   
  1483.             if ((getMap(r)&0x05)==0x05)
  1484.             {
  1485.                 cBox[getByteFile(r)]+=1;
  1486.                 n++;ri=r;
  1487.                 if (touchAnyAddress(ri))
  1488.                 {
  1489.                     //if(rs<=debugAdd&&debugAdd<=rs+0x200)  
  1490.                     //    fprintf(stderr,"\ntouchAnyAddress=%08X",ri);
  1491.                     rt++;
  1492.                 }
  1493.                 //{
  1494.                 //    
  1495.                 //}
  1496.             }
  1497.             r++;
  1498.         }
  1499.         re=r;nn=0;nz=0;
  1500.         for(i=0x41;i<0x5B;i++)nn+=cBox[i];
  1501.         for(i=0x61;i<0x7B;i++)nn+=cBox[i];
  1502.         nn+=cBox[0x00]+cBox[0x90];
  1503.         nz+=cBox[0x00]+cBox[0x01]+cBox[0x02]+cBox[0x03];
  1504.         nz+=rt; // I don't know whether this is OK or Not
  1505.  
  1506.         /*
  1507.         if (rs<=debugAdd&&debugAdd<=re)
  1508.         {
  1509.             fprintf(stderr,"\n*********YO YO***********");
  1510.             fprintf(stderr,"\nn=%3d nn=%3d nz=%3d rs=%08X re=%08X rt=%3d getMap()=%02X", 
  1511.                             n,nn,nz,rs,re,rt,getMap(debugAdd)); 
  1512.             getch();
  1513.         }*/
  1514.  
  1515.         if((nn*3>n*2)||(nz*2>n)||(n==1&&isNotGoodJump(rs))||
  1516.         (n<16
  1517.         &&(cBox[0xC2]+cBox[0xC3]==0)
  1518.         &&(getByteFile(ri)!=0xE9)
  1519.         &&(getByteFile(ri)!=0xE8)
  1520.         &&(getByteFile(ri)!=0xFF)))
  1521.         {
  1522.             // try to save partial results
  1523.             r=rs;
  1524.             while(r<re)
  1525.             {
  1526.                 for(i=r;i<re;i++) if ((getMap(i)&0x80)==0x80) break;
  1527.                 if(i<re)te=i+1;else te=i;
  1528.                 for(i=r;i<te;i++) if ((getMap(i)&0x60)&&(isThisGoodRef(i,r,re))) break;
  1529.                 ts=i;
  1530.                 /*--------------*/pushTrace(1940);
  1531.                 for(i=r;i<ts;i++) setMap(i,0x0F);
  1532.                 /*--------------*/popTrace();
  1533.                 if(r<te) r=te;
  1534.                 else r++;
  1535.             }
  1536.         }
  1537.         r=re;
  1538.     }
  1539.  
  1540.     // now for some final touch,,
  1541.     // namely clear some garbage code which clings to byte data
  1542.  
  1543.     //fprintf(stderr, " p2");
  1544.     fprintf(stderr,".");
  1545.     showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  1546.     r=s;
  1547.     while(r<rmax)
  1548.     {
  1549.         //fprintf(stderr, " r==%08X",r);
  1550.         while((r<rmax)&&((getMap(r)&0x0F)==0x0F)){r++;}
  1551.         while((r<rmax)&&((getMap(r)&0x0F)!=0x0F)){r++;}
  1552.         if (getMap(r-1)==0x0C && getMap(r-2)==0x0F) 
  1553.         {
  1554.             /*--------------*/pushTrace(1950);
  1555.             setMap(r-1,0x0F); 
  1556.             /*--------------*/popTrace();
  1557.             continue;
  1558.         }
  1559.         if((getMap(r-1)&0x80)==0)
  1560.         {
  1561.             re=r;r--;
  1562.             while(r>s && ((b=getMap(r))&0x80)==0x00 && !(b&0x40)){r--;}
  1563.             if(((b=getMap(r))&0x40)||(b&0x0C)==0x0C){r=re;continue;}
  1564.             r++;
  1565.  
  1566.             while(r<re)
  1567.             {
  1568.                 if((getMap(r)&0x08)==0x08) { r=re; break; }      // 0x0C -> 0x08 .. check it..
  1569.                 /*------------*/pushTrace(1960);
  1570.                 setMap(r, 0x0F); r++; 
  1571.                 /*------------*/popTrace();
  1572.             }
  1573.         }
  1574.     }
  1575.  
  1576.     // now for some real final touch,,                 nov.10,1997 -sangcho-
  1577.     // namely clear some garbage code which clings hard to byte data
  1578.  
  1579.     //fprintf(stderr, " p3");
  1580.     fprintf(stderr,".");
  1581.     showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  1582.     r=s;
  1583.     while(r<rmax)
  1584.     {
  1585.         while((r<rmax)&&((getMap(r)&0x08)==0x08)){r++;}
  1586.         while((r<rmax)&&((getMap(r)&0x08)!=0x08)){r++;}
  1587.         
  1588.         //if((getMap(r-1)&0x80))
  1589.         {
  1590.             re=r;
  1591.             r--;
  1592.             //if((getMap(r-1)&0x88)==0)
  1593.             if((getMap(r)&0x88)==0)
  1594.             {
  1595.                 r--;
  1596.                 while(((b=getMap(r))&0x88)==0&&!(b&0x40)){r--;}
  1597.                 if(getMap(r)&0x40){r=re;continue;}
  1598.                 r++;
  1599.                 rs=r;n=0;
  1600.                 for(i=0;i<256;i++)cBox[i]=0;
  1601.                 while((r<re)&&((getMap(r)&0x08)==0x00))
  1602.                 {   
  1603.                     if ((getMap(r)&0x05)==0x05){cBox[getByteFile(r)]+=1;n++;ri=r;}
  1604.                     r++;
  1605.                 }
  1606.                 nz=0;
  1607.                 for(i=0;i<0x33;i++)nz+=cBox[i];
  1608.                 nz-=cBox[0xC3]*n+cBox[0xE9]+cBox[0xFF];
  1609.                 //nz=cBox[0x00]+cBox[0x01]+cBox[0x02]+cBox[0x03];
  1610.                 if((nz*2>n)||(n==1&&isNotGoodJump(rs)))
  1611.                 {
  1612.                     r=rs;
  1613.                     while(r<re)
  1614.                     {
  1615.                         if(getMap(r)&0x40){r=re;break;}
  1616.                         /*------------*/pushTrace(1970);
  1617.                         setMap(r, 0x0F); r++; 
  1618.                         /*------------*/popTrace();
  1619.                     }
  1620.                 }
  1621.             }
  1622.             r=re;
  1623.         }
  1624.     }
  1625.  
  1626.     // now for some real final touch,,                 nov.12,1997 -sangcho-
  1627.     // namely clear some garbage code which clings hard to byte data
  1628.     // this time we need to 
  1629.     // find the code block which clings after byte data and which is dead.
  1630.     // so no outside reference is made, then you need to check out 
  1631.     // carefully what is code and what is byte,
  1632.     // so this is what i do:
  1633.     // if each instruction is in ascii character range including
  1634.     // 00 and 20 and 2A you treat them as byte data.
  1635.     // but if you find 55 then you are almost done!
  1636.     // and check if next byte is something 8B or not.
  1637.     // if it is then you are really done.
  1638.     // and convert everything between start to just before 55 to
  1639.     // byte data!
  1640.  
  1641.     //fprintf(stderr, " p4");
  1642.     fprintf(stderr,".");
  1643.     showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  1644.     r=s;
  1645.     while(r<rmax)
  1646.     {
  1647.         while((r<rmax)&&((getMap(r)&0x08)!=0x08)){r++;}
  1648.         while((r<rmax)&&((getMap(r)&0x08)==0x08)){r++;}
  1649.         if(getMap(r)&0x40)   continue;
  1650.         if(!(getMap(r)&0x02))continue;
  1651.         rs=r;
  1652.         while((r<rmax)&&!((b=getMap(r))&0x02)&&!(b&0x80)){r++;}
  1653.         if(!(getMap(r)&0x02))continue;
  1654.         re=r;
  1655.         r=rs;
  1656.         while((r<rmax)&&(getByteFile(r)<0x80)){r++;}
  1657.         if((getByteFile(r)==0x8B)
  1658.          &&(getByteFile(r-1)==0x55)){rr=r-1;}
  1659.         else {r=re;continue;}
  1660.         r=rs;nn=0;
  1661.         while(r<rr)
  1662.         {
  1663.             if((getMap(r)&0x20)&&referCount(r)>0)nn++;
  1664.             r++;
  1665.         }
  1666.         if(nn){r=re;continue;}
  1667.         
  1668.         r=rs;
  1669.         /*--------------*/pushTrace(1980);
  1670.         while(r<rr){ setMap(r, 0x0F); r++; }
  1671.         /*--------------*/popTrace();
  1672.         r=re;
  1673.     }
  1674.  
  1675.     //fprintf(stderr,"1$");
  1676. }
  1677.  
  1678.  
  1679. int checkWellDone(DWORD s, DWORD e)
  1680. {
  1681. DWORD     i;
  1682. BYTE      b;
  1683.  
  1684.     //return PostProcessing2(s, e);
  1685.     for (i=s;i<e;i++)
  1686.     {
  1687.         if((getMap(i)&0x05)==0x05 && touchAnyAddress(i) && isAddressBlock(i)) break; 
  1688.     }
  1689.     if(i<e) 
  1690.     {
  1691.         //fprintf(stdout, "\n**!! fatalError = %3d getMap=%02X cur_position=%08X i=%08X", 
  1692.         //        fatalError, getMap(cur_position), cur_position,i);
  1693.         
  1694.         my_h.m=nextMode;
  1695.         my_h.f=2000;
  1696.         my_h.r=lastReset;
  1697.         my_h.c=cur_position;
  1698.         /*-----------*/pushTrace(2000);
  1699.         eraseUncertain(i, &my_h); 
  1700.         /*-----------*/popTrace();
  1701.         return 0;
  1702.     }
  1703.     if (((b=getMap(cur_position))&0x05)!=0x05&&!(b&0x08)) 
  1704.     {
  1705.         //fprintf(stderr, "\n!! fatalError = %3d getMap=%02X cur_position=%08X ", 
  1706.         //        fatalError, getMap(cur_position), cur_position);
  1707.         //fprintf(stdout, "\n!! fatalError = %3d getMap=%02X cur_position=%08X ", 
  1708.         //        fatalError, getMap(cur_position), cur_position);
  1709.         
  1710.         my_h.m=nextMode;
  1711.         my_h.f=2010;
  1712.         my_h.r=lastReset;
  1713.         my_h.c=cur_position;
  1714.         /*-----------*/pushTrace(2010);
  1715.         eraseUncertain(cur_position, &my_h); 
  1716.         /*-----------*/popTrace();
  1717.     }
  1718.     return 1;
  1719. }
  1720.  
  1721.  
  1722. void PostProcessing1()
  1723. {
  1724. //static   BYTE bb=0xFF;
  1725. DWORD    r, s, e, rmax;
  1726. DWORD    rmaxTab[16], rstartTab[16];
  1727. DWORD    i, ss, pos;
  1728. int      k, n, num;
  1729. //BYTE     b, d;
  1730. _key_    y;
  1731.     
  1732.     //ReportMap();
  1733.     //printMode=1;
  1734.     num=getNumExeSec();
  1735.     if (num>16) {num=16; fprintf(stderr,"\n...please increase the size...");}
  1736.     for (i=0;i<num;i++)
  1737.     {
  1738.         rstartTab[i]     = imageBase+shdr[i].VirtualAddress;
  1739.         rmaxTab[i]       = rstartTab[i]+shdr[i].SizeOfRawData;
  1740.     }
  1741.  
  1742.     //fprintf(stderr,".1.");
  1743.     fprintf(stderr,".");
  1744.     showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  1745.     for(k=0;k<num;k++)
  1746.     {
  1747.         r=rstartTab[k]; rmax=rmaxTab[k]; 
  1748.         s=0; e=0;
  1749.         //{fprintf(stderr," continue1 ");}
  1750.         while(r<rmax)
  1751.         {
  1752.             //{fprintf(stderr,"\n continue2 ");}
  1753.             if (s<r && r<e) s=r;
  1754.             else
  1755.             {
  1756.                 while(r<rmax) 
  1757.                 {
  1758.                     if((getMap(r)&0x0F)==0x00) break; 
  1759.                     r++;
  1760.                 }
  1761.                 s=r; 
  1762.             }
  1763.             if(s<e) e=e;
  1764.             else
  1765.             {
  1766.                 while(r<rmax) 
  1767.                 {
  1768.                     if(getMap(r)&0x0F) break;
  1769.                     r++;
  1770.                 }
  1771.                 e=r; 
  1772.             }
  1773.  
  1774.             //{fprintf(stderr,"\n 11 ");}
  1775.  
  1776.             /*------------*/pushTrace(2110);
  1777.             n=tryMoreAddress(s, e, &pos);
  1778.             /*------------*/popTrace();
  1779.  
  1780.             //{fprintf(stderr,"\n 12 ");}
  1781.  
  1782.             //
  1783.             // this is for some special considerations like instruction which ends
  1784.             // with address that follows address block case.
  1785.             //
  1786.             if (s==pos) ss=s; else ss=pos+4;
  1787.  
  1788.             if (n==0) {r=e; continue;}
  1789.             //
  1790.             // this case deals with CCCC"address" case
  1791.             //
  1792.             if (n==1)
  1793.             {
  1794.                 i=pos;
  1795.                 if ((e-s)<8 
  1796.                  && getByteFile(s)==0xCC 
  1797.                  && isGoodAddress(getIntFile(i))
  1798.                  && referCount(i)>0)
  1799.                 {
  1800.                     /*-------------*/pushTrace(2120);
  1801.                     setMap(i  ,0x0E); setMap(i+1,0x0E);
  1802.                     setMap(i+2,0x0E); setMap(i+3,0x0E);
  1803.                     /*-------------*/popTrace();
  1804.                     /*-------------*/pushTrace(2130);
  1805.                     MyBtreeInsertDual(167, getIntFile(i), i);
  1806.                     /*-------------*/popTrace();
  1807.                     for (i=s;i<e;i++) 
  1808.                         if (getByteFile(i)==0xCC && getMap(i)==0x00) 
  1809.                         { 
  1810.                             /*-------*/pushTrace(2140); 
  1811.                             setMap(i,0x0C); 
  1812.                             /*-------*/popTrace();
  1813.                         }
  1814.                         else break;
  1815.                 }
  1816.             }
  1817.             //
  1818.             // not significant to set address blocks
  1819.             //
  1820.             if (n<=3) 
  1821.             {
  1822.                 // report some suspicious case here...
  1823.                 r=pos+4*n; 
  1824.                 //fprintf(stderr,"\n%08X=%08X+4*%04X",(int)r,(int)pos,n);//getch();
  1825.                 continue;
  1826.             }
  1827.             
  1828.             r=pos+4*n;
  1829.  
  1830.             //fprintf(stderr,"\n...%08X=%08X+4*%04X",(int)r,(int)pos,n);//getch();
  1831.  
  1832.             //
  1833.             // well ss is either pos or pos+4 depending on whether s==pos or not
  1834.             //
  1835.             for(i=ss;i<pos+n*4;i+=4)
  1836.             {
  1837.                 if(isGoodAddress(getIntFile(i)))
  1838.                 {
  1839.                     /*-----------*/pushTrace(2150);
  1840.                     setMap(i  ,0x0E); setMap(i+1,0x0E);
  1841.                     setMap(i+2,0x0E); setMap(i+3,0x0E);
  1842.                     /*-----------*/popTrace();
  1843.                     /*-----------*/pushTrace(2160);
  1844.                     MyBtreeInsertDual(167, getIntFile(i), i);
  1845.                     /*-----------*/popTrace();
  1846.                 }
  1847.             }
  1848.         }
  1849.     }
  1850.  
  1851.     //fprintf(stderr,".2.");
  1852.     fprintf(stderr,".");
  1853.     showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  1854.     for(k=0;k<num;k++)
  1855.     {
  1856.         r=rstartTab[k]; rmax=rmaxTab[k];
  1857.         
  1858.         markStrings(r,rmax);
  1859.  
  1860.         while(r<rmax)
  1861.         {
  1862.             while(r<rmax) 
  1863.             {
  1864.                 if((getMap(r)&0x0F)==0x00) break; r++;
  1865.             }
  1866.             s=r;
  1867.             while(r<rmax) 
  1868.             {
  1869.                 if(getMap(r)&0x0F) break; r++;
  1870.             }
  1871.             e=r;
  1872.             for(i=s;i<e;i++)
  1873.             {
  1874.                 // i don't want to revive nop 0x90
  1875.                 showDots();
  1876.                 while(i<e&&!isItStartAnyWay(i))i++;
  1877.                 
  1878.                 /*
  1879.                 if(s<=debugAdd&&debugAdd<e) 
  1880.                 {
  1881.                 fprintf(stderr, 
  1882.                 "\n...*** reset=%08X map=%02X %02X fatalError=%3d op=%02X m=%02X col=%d",
  1883.                                 i,getMap(i),getMap(i+1),fatalError,i_opcode,i_mod,i_col_save);
  1884.                 }*/
  1885.                 if (fatalError==0) break;
  1886.             }
  1887.             if (i<e)
  1888.             {
  1889.                 nextMode=3;
  1890.                 resetDisassembler(i);
  1891.                 /*-----------*/pushTrace(2210);
  1892.                 Disassembler1();
  1893.                 /*-----------*/popTrace();
  1894.              
  1895.                 if (fatalError) 
  1896.                 {
  1897.                     //fprintf(stderr, "\n! fatalError = %3d getMap=%02X cur_position=%08X ", 
  1898.                     //fatalError, getMap(cur_position), cur_position);
  1899.                     //fprintf(stdout, "\n! fatalError = %3d getMap=%02X cur_position=%08X ", 
  1900.                     //fatalError, getMap(cur_position), cur_position);
  1901.                     
  1902.                     my_h.m=nextMode;
  1903.                     my_h.f=2220;
  1904.                     my_h.r=lastReset;
  1905.                     my_h.c=cur_position;
  1906.                     /*----------*/pushTrace(2220);
  1907.                     eraseUncertain(cur_position, &my_h); 
  1908.                     /*----------*/popTrace();
  1909.                 }
  1910.                 else 
  1911.                 {
  1912.                     /*----------*/pushTrace(2230);
  1913.                     checkWellDone(i, cur_position);
  1914.                     /*----------*/popTrace();
  1915.                 }
  1916.  
  1917.                 r=cur_position+1; // could be very dangerous ...
  1918.             }
  1919.         }
  1920.     }
  1921.  
  1922.     fprintf(stderr,".");
  1923.     showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  1924.     for(k=0;k<num;k++)
  1925.     {
  1926.         r=rstartTab[k]; rmax=rmaxTab[k];
  1927.         /*---------*/pushTrace(2240);
  1928.         PostProcessing2(r, rmax);
  1929.         /*---------*/popTrace();
  1930.         /*---------*/pushTrace(2250);
  1931.         markAddress1(r, rmax);
  1932.         /*---------*/popTrace();
  1933.     }
  1934.  
  1935.     fprintf(stderr,".");
  1936.     showDotsNum++; if (showDotsNum%COLSIZE==0) fprintf(stderr,"\n");
  1937.     for(k=0;k<HintCnt;k++)
  1938.     {
  1939.         y=Hints[k];
  1940.         i=y.class; r=y.c_pos; rmax=y.c_ref;
  1941.         switch(i)
  1942.         {
  1943.             case  1: changeToAddress(r,rmax); break;
  1944.             case  2: changeToBytes(r,rmax);   break;
  1945.             case  3: changeToCode(r, rmax);   break;
  1946.             case  4: changeToDword(r,rmax);   break;
  1947.             case  5: changeToFloat(r,rmax);   break;
  1948.             case  6: changeToDouble(r,rmax);  break;
  1949.             case  7: changeToQuad(r,rmax);    break;
  1950.             case  8: changeTo80Real(r,rmax);  break;
  1951.             case  9: changeToWord(r,rmax);    break;
  1952.             case 10: changeToNullString(r);   break;
  1953.             case 11: changeToPascalString(r); break;
  1954.             case 12:                          break;
  1955.             default: fprintf(stderr,"\nSOMETHING IS WRONG"); Myfinish();
  1956.         }
  1957.     }
  1958. }
  1959.  
  1960. // ***************************************
  1961. // some reporting functions
  1962. // ***************************************
  1963. void  printTrace()
  1964. {
  1965. int i;
  1966.     fprintf(stderr,"\n..Traces are...\n");
  1967.     for (i=0;i<debugx;i++) fprintf(stderr,"%3d:%4d, ",i,debugTab[i]);
  1968.     //getch();
  1969.     debugx=0;
  1970. }
  1971. void  peekTrace()
  1972. {
  1973. int i;
  1974.     fprintf(stderr,"\n..Traces are...\n");
  1975.     for (i=0;i<debugx;i++) fprintf(stderr,"%3d:%4d, ",i,debugTab[i]);
  1976. }
  1977.  
  1978. int totZero=0;
  1979. void  MapSummary()
  1980. {
  1981. DWORD    s, e, r, rmax;
  1982. int      n;
  1983.  
  1984.     r=imagebaseRVA;
  1985.     rmax=imageBase+getRVA(CodeOffset+CodeSize-1)+1;
  1986.     n=0;
  1987.     printf("\n+++++++++++++++++++ Somewhat Suspicious Blocks +++++++++++++++++++ \n");
  1988.     while(r<rmax)
  1989.     {
  1990.         while(r<rmax && getMap(r)>0) r++;
  1991.         s=r;
  1992.         while(r<rmax && getMap(r)==0) r++;
  1993.         e=r;
  1994.         printf("\nzero blocks::%08X-%08X", (int)s, (int)e);
  1995.         n+=e-s;
  1996.     }
  1997.     //printf("\nTotal zero blocks=%08X\n",n);
  1998.     //fprintf(stderr,"\nTotal zero blocks=%08X",n);
  1999.     totZero=n;
  2000. }
  2001.  
  2002. void  ReportMap()
  2003. {
  2004. DWORD    r, rmax;
  2005. int      n;
  2006.  
  2007.     r=imagebaseRVA;
  2008.     rmax=imageBase+getRVA(CodeOffset+CodeSize-1)+1;
  2009.     n=0;
  2010.     while(r<rmax)
  2011.     {
  2012.         if(n%24==0)printf("\n%08X:",(int)r);
  2013.         printf(" %02X",getMap(r));
  2014.          r++; n++;   
  2015.     }
  2016.     printf("\n");
  2017. }
  2018.  
  2019. extern int addLabelsHistogram[];
  2020.  
  2021. void reportHistory()
  2022. {
  2023. history  h;
  2024. int      i;
  2025.  
  2026.     printf("\nListings of History");
  2027.     for (i=0;i<256;i++)
  2028.     {
  2029.         if (i%6==0) printf("\n");
  2030.         printf("%02X:%4d-%4d ",i,resetHistogram[i],addLabelsHistogram[i]);
  2031.     }
  2032.     printf("\nErrors occured..");
  2033.     for (i=0;i<hCnt;i++) 
  2034.     {
  2035.         h=History[i];
  2036.         printf("\ni=%4d m=%3d f=%4d l=%3d r=%08X c=%08X :: s=%08X e=%08X",
  2037.                i+1, h.m, h.f, h.l, (int)(h.r), (int)(h.c), (int)(h.s), (int)(h.e));
  2038.     }
  2039. }
  2040.  
  2041. void readHint()
  2042. {
  2043. FILE           *fp;
  2044. char            line[80];
  2045. int             i;
  2046. int             a, b;
  2047. BYTE            c;
  2048. _key_           k;
  2049.  
  2050.     //fprintf(stderr,"\nreadHint()");
  2051.     fp=fopen(mname, "r");
  2052.     while(1)
  2053.     {
  2054.         for(i=0;i<80;i++)line[i]=0;
  2055.         fscanf(fp,"%s",line);
  2056.         c=line[0];
  2057.         if (c=='x') break;
  2058.         switch(c)
  2059.         {
  2060.             case 'a': k.class= 1; sscanf(line,"%*2c%08X", &a); 
  2061.                       k.c_pos=a; k.c_ref=0;     break;
  2062.             case 'A': k.class= 1; sscanf(line,"%*2c%08X%*c%08X", &a, &b);
  2063.                       k.c_pos=a; k.c_ref=b;     break;
  2064.             case 'b': k.class= 2; sscanf(line,"%*2c%08X", &a); 
  2065.                       k.c_pos=a; k.c_ref=0;     break;
  2066.             case 'B': k.class= 2; sscanf(line,"%*2c%08X%*c%08X", &a, &b);
  2067.                       k.c_pos=a; k.c_ref=b;     break;
  2068.             case 'c': k.class= 3; sscanf(line,"%*2c%08X", &a); 
  2069.                       k.c_pos=a; k.c_ref=0;     break;
  2070.             case 'C': k.class= 3; sscanf(line,"%*2c%08X%*c%08X", &a, &b);
  2071.                       k.c_pos=a; k.c_ref=b;     break;
  2072.             case 'd': k.class= 4; sscanf(line,"%*2c%08X", &a); 
  2073.                       k.c_pos=a; k.c_ref=0;     break;
  2074.             case 'D': k.class= 4; sscanf(line,"%*2c%08X%*c%08X", &a, &b);
  2075.                       k.c_pos=a; k.c_ref=b;     break;
  2076.             case 'f': k.class= 5; sscanf(line,"%*2c%08X", &a); 
  2077.                       k.c_pos=a; k.c_ref=0;     break;
  2078.             case 'F': k.class= 5; sscanf(line,"%*2c%08X%*c%08X", &a, &b);
  2079.                       k.c_pos=a; k.c_ref=b;     break;
  2080.             case 'g': k.class= 6; sscanf(line,"%*2c%08X", &a); 
  2081.                       k.c_pos=a; k.c_ref=0;     break;
  2082.             case 'G': k.class= 6; sscanf(line,"%*2c%08X%*c%08X", &a, &b);
  2083.                       k.c_pos=a; k.c_ref=b;     break;
  2084.             case 'q': k.class= 7; sscanf(line,"%*2c%08X", &a); 
  2085.                       k.c_pos=a; k.c_ref=0;     break;
  2086.             case 'Q': k.class= 7; sscanf(line,"%*2c%08X%*c%08X", &a, &b);
  2087.                       k.c_pos=a; k.c_ref=b;     break;
  2088.             case 'r': case 'R':
  2089.                       moreprint=1;              break;
  2090.             case 't': k.class= 8; sscanf(line,"%*2c%08X", &a); 
  2091.                       k.c_pos=a; k.c_ref=0;     break;
  2092.             case 'T': k.class= 8; sscanf(line,"%*2c%08X%*c%08X", &a, &b);
  2093.                       k.c_pos=a; k.c_ref=b;     break;
  2094.             case 'w': k.class= 9; sscanf(line,"%*2c%08X", &a); 
  2095.                       k.c_pos=a; k.c_ref=0;     break;
  2096.             case 'W': k.class= 9; sscanf(line,"%*2c%08X%*c%08X", &a, &b);
  2097.                       k.c_pos=a; k.c_ref=b;     break;
  2098.             case 'n': k.class=10; sscanf(line,"%*2c%08X", &a); 
  2099.                       k.c_pos=a; k.c_ref=0;     break;
  2100.             case 'N': k.class=10; sscanf(line,"%*2c%08X%*c%08X", &a, &b);
  2101.                       k.c_pos=a; k.c_ref=b;     break;
  2102.             case 'p': k.class=11; sscanf(line,"%*2c%08X", &a); 
  2103.                       k.c_pos=a; k.c_ref=0;     break;
  2104.             case 'P': k.class=11; sscanf(line,"%*2c%08X%*c%08X", &a, &b);
  2105.                       k.c_pos=a; k.c_ref=b;     break;
  2106.             case 'u': k.class=12; sscanf(line,"%*2c%08X%*c%08X", &a, &b);
  2107.                       debugAdd=a; debugAdd1=b;     break; 
  2108.             default:  k.class= 0;                  break;
  2109.         }
  2110.         if (k.class==0) break;
  2111.         Hints[HintCnt++]=k;
  2112.     }
  2113.     fclose(fp);
  2114. }
  2115.  
  2116.  
  2117. int stringCheck(int c, DWORD ref, DWORD pos)
  2118. {
  2119. int    n;
  2120. DWORD  rmax;
  2121. PBYTE  q, qq;
  2122.  
  2123.     rmax=imageBase+getRVA(CodeOffset+CodeSize-1)+1;
  2124.     if(pos<imagebaseRVA) return 1;
  2125.     if(pos>rmax) return 1;
  2126.     q=toFile(ref);
  2127.     switch(c)
  2128.     {
  2129.         case 512: case 513: case 520: case 1024:
  2130.             n=q?strlen(q):0;
  2131.             qq=q;
  2132.             if(n>0) while(qq<q+n&&isprint(*qq))qq++;
  2133.             if(n>0) while(qq<q+n&&isspace(*qq))qq++;
  2134.             if ((n>0&&qq==q+n)||(getMap1(ref)&0x05)==0x05) 
  2135.             {
  2136.                 if (getMap(pos)==0) break;
  2137.                 /*----------*/pushTrace(2300);
  2138.                 if (getMap(pos)&0x05) orMap(pos, 0x10);
  2139.                 /*----------*/popTrace();
  2140.             }
  2141.         default:
  2142.     }
  2143.     return 1;
  2144. }
  2145.  
  2146.  
  2147. void labelBody1(int class, DWORD ref, DWORD pos)
  2148. {
  2149. int    c;
  2150. DWORD  r, rr;
  2151. BYTE   b, bb;
  2152.     
  2153.     c = class;
  2154.     r = ref;
  2155.     rr= pos;
  2156.     //if (r==0x0100139C) fprintf(stderr,"\nTADA...TADA...c=%3d rr=%08X mr=%02X mrr=%02X",
  2157.     //                                c,rr,getMap(r),getMap(rr));
  2158.     if (CodeOffset+CodeSize<=getOffset(r))
  2159.         {stringCheck(c, r, rr); return;}
  2160.     b=getMap(r);     
  2161.     if (b==0)         return;
  2162.     if ((b&0x05)!=0x05 && (b&0x08)==0) return;
  2163.     bb=getMap(rr);
  2164.     if ((b==0x0F)&&(bb==0x0F)) return;
  2165.     
  2166.     switch(c)
  2167.     {
  2168.         case 1: case 2:     
  2169.             if (bb==0)              break;
  2170.             if (b==0x0F)            break;  
  2171.             if ((b&0x20)&&(bb&0x05)==0x05) break;
  2172.             /*-----------*/pushTrace(2310);
  2173.             if (bb&0x05) orMap(r, 0x20);
  2174.             /*-----------*/popTrace();
  2175.             break;
  2176.         case 3: case 4:
  2177.             if (bb==0)              break;
  2178.             if (b==0x0F)            break;  
  2179.             if (b==0x0F)              break;
  2180.             if ((b&0x20)&&(bb&0x05)==0x05) break;
  2181.             /*-----------*/pushTrace(2320);
  2182.             if (bb&0x05) orMap(r, 0x20);  
  2183.             /*-----------*/popTrace();
  2184.             break;
  2185.         case 5: case 7: case 9:
  2186.             if (bb==0)              break;
  2187.             if (b==0x0F)            break;  
  2188.             if ((b&0x20)&&(bb&0x05)==0x05) break;
  2189.             /*-----------*/pushTrace(2330);
  2190.             if (bb&0x05) orMap(r, 0x20);  
  2191.             /*-----------*/popTrace();
  2192.             break;
  2193.         case 11: case 13: case 15: case 17:
  2194.             if (bb==0)              break;
  2195.             if (b==0x0F)            break;  
  2196.             if ((b&0x40)&&(bb&0x05)==0x05) break;
  2197.             /*-----------*/pushTrace(2340);
  2198.             if (bb&0x05) orMap(r, 0x60);  
  2199.             /*-----------*/popTrace();
  2200.             break;
  2201.         case 133:
  2202.             break;
  2203.         case 165: case 166:    case 167:
  2204.             if (bb==0)                      break;
  2205.             if ((b&0x20)&&(bb&0x0E)==0x0E)   break;
  2206.             /*-----------*/pushTrace(2350);
  2207.             if ((bb&0x0E)==0x0E) orMap(r, 0x20);  
  2208.             /*-----------*/popTrace();
  2209.             break;
  2210.         case 514: 
  2211.             if (bb==0)      break;
  2212.             if (b!=0x0E)    break;
  2213.             /*-----------*/pushTrace(2360);
  2214.             orMap(r, 0x20);
  2215.             /*-----------*/popTrace();
  2216.             break;
  2217.         case 516: 
  2218.             if (bb==0)      break;
  2219.             if (b!=0x0D)    break;
  2220.             /*-----------*/pushTrace(2370);
  2221.             orMap(r, 0x20);
  2222.             /*-----------*/popTrace();
  2223.             break;
  2224.         case 515: case 517: case 518: case 519: case 520: case 524: case 528:
  2225.             if (bb==0)      break;
  2226.             if (b!=0x0F)    break;
  2227.             /*-----------*/pushTrace(2372);
  2228.             orMap(r, 0x20);
  2229.             /*-----------*/popTrace();
  2230.             break;
  2231.         case 512: case 513: case 1024:
  2232.             if (bb==0)              break;
  2233.             if ((b&0x08)==0x08) {stringCheck(c, r, rr); break;}
  2234.             if ((b&0x05)==0x05) orMap(r,0x20);
  2235.             break;
  2236.         case 2048:
  2237.             /*-----------*/pushTrace(2380);
  2238.             orMap(r, 0xE0);  
  2239.             /*-----------*/popTrace();
  2240.             break;
  2241.         default:
  2242.     }
  2243. }
  2244.  
  2245. void labelPP(PNODE1 pn, DWORD pos1)
  2246. {
  2247.     if (pn==NULL) return;
  2248.     labelPP(pn->left, pos1);
  2249.     labelBody1(pn->rclass, pos1, pn->pos2);
  2250.     labelPP(pn->right, pos1);
  2251. }
  2252.  
  2253. void labelBody(PNODE pn)
  2254. {
  2255. PNODE1    pc;
  2256.     
  2257.     if (pn->rcount>1)
  2258.     {
  2259.         pc=(PNODE1)(pn->pos2);
  2260.         labelPP(pc, pn->pos1);
  2261.     }
  2262.     else if (pn->rcount==1) labelBody1(pn->rclass, pn->pos1, pn->pos2);
  2263. }
  2264.  
  2265. void labelP(PNODE pn)
  2266. {
  2267.     if (pn==NULL) return;
  2268.     labelP(pn->left);
  2269.     labelBody(pn);
  2270.     labelP(pn->right);
  2271. }
  2272.  
  2273. void LabelProcess()
  2274. {
  2275. int      i, k;
  2276. DWORD    r, rmax;
  2277. BYTE     b;
  2278. PNODE    *ppn;
  2279. _key_    y;
  2280.     // I need to recycle one bit of Map,.... november 16,1997 -sangcho-
  2281.  
  2282.     r=imagebaseRVA;
  2283.     rmax=imageBase+getRVA(CodeOffset+CodeSize-1)+1;
  2284.     /*----------*/pushTrace(2400);
  2285.     while(r<rmax){b=getMap(r); exMap(r, b&0xF0);r++;}
  2286.     /*----------*/popTrace();
  2287.  
  2288.     for (i=0; i<hsize; i++)
  2289.     {
  2290.        ppn=(PNODE *)(headerD+i*4);
  2291.        if ((*ppn)!=NULL) labelP(*ppn);
  2292.     }
  2293.  
  2294.     for(k=0;k<HintCnt;k++)
  2295.     {
  2296.         y=Hints[k];
  2297.         i=y.class; r=y.c_pos; rmax=y.c_ref;
  2298.         switch(i)
  2299.         {
  2300.             case  8: changeTo80Real(r,rmax);  break;
  2301.             default: 
  2302.         }
  2303.     }
  2304. }
  2305.  
  2306. void xrefBody1(int class, DWORD ref, DWORD pos)
  2307. {
  2308. static int   col=0;
  2309. static DWORD sr=0;
  2310. int      c;
  2311. DWORD    r, rr;
  2312. BYTE     b, d;
  2313.    
  2314.     c = class;
  2315.     r = ref;
  2316.     rr= pos;
  2317.     b=getMap(r);     
  2318.     if (b==0)         return;
  2319.     if (b!=0x0F && b!=0x2E && (b&0x25)!=0x25) return;
  2320.     if (c==1||c==2)      return;
  2321.     d=getByteFile(r);
  2322.     
  2323.     if (sr!=r)
  2324.     {
  2325.         if ((b&0x80)&&(d!=0xC3)) 
  2326.         {
  2327.             printf("\n**%08X::",(int)r);printExportName1(r);
  2328.             if(rr>imagebaseRVA) 
  2329.             {printf("\n            %08X,",(int)rr);col=1;}
  2330.             else col=7;
  2331.         }
  2332.         else if (b&0x40)
  2333.         {
  2334.             if (rr>0)printf("\n==%08X::%08X,",(int)r,(int)rr);
  2335.             else     printf("\n==%08X::",(int)r);  col=1;
  2336.         }
  2337.         else if (513<c && c<525)
  2338.         {
  2339.             if (rr>0)printf("\n##%08X::%08X,",(int)r,(int)rr);
  2340.             else     printf("\n##%08X::",(int)r); col=1;
  2341.         }
  2342.         else if (b&0x20)
  2343.         {
  2344.             if (rr>0)printf("\n--%08X::%08X,",(int)r,(int)rr);
  2345.             else     printf("\n--%08X::",(int)r); col=1;
  2346.         }
  2347.     }
  2348.     else 
  2349.     {
  2350.         if (col%7==0) printf("\n            %08X,",(int)rr);
  2351.         else printf("%08X,",(int)rr);           col++;
  2352.     }
  2353.     sr=r;
  2354. }
  2355.  
  2356. void xrefPP(PNODE1 pn, DWORD pos1)
  2357. {
  2358.     if (pn==NULL) return;
  2359.     xrefPP(pn->left, pos1);
  2360.     xrefBody1(pn->rclass, pos1, pn->pos2);
  2361.     xrefPP(pn->right, pos1);
  2362. }
  2363.  
  2364. void xrefBody(PNODE pn)
  2365. {
  2366. PNODE1    pc;
  2367.  
  2368.     if (pn->rcount>1)
  2369.     {
  2370.         pc=(PNODE1)(pn->pos2);
  2371.         xrefPP(pc, pn->pos1);
  2372.     }
  2373.     else if (pn->rcount==1) xrefBody1(pn->rclass, pn->pos1, pn->pos2);
  2374. }
  2375.  
  2376. void xrefP(PNODE pn)
  2377. {
  2378.     if (pn==NULL) return;
  2379.     xrefP(pn->left);
  2380.     xrefBody(pn);
  2381.     xrefP(pn->right);
  2382. }
  2383.  
  2384. void Xreference()
  2385. {
  2386. int      i;
  2387. PNODE    *ppn;
  2388.  
  2389.     printf("\n\n*************** Cross Reference Listing ****************");
  2390.     for (i=0; i<hsize; i++)
  2391.     {
  2392.        ppn=(PNODE *)(headerD+i*4);
  2393.        if ((*ppn)!=NULL) xrefP(*ppn);
  2394.     }
  2395. }
  2396.  
  2397.  
  2398. // ************************************
  2399. // main cleaning agent 
  2400. // ************************************
  2401.  
  2402. int eraseUncertainNum=0;
  2403.  
  2404. void eraseUncertain(DWORD ref, PHISTORY ph)
  2405. {       
  2406. //static   BYTE bb=0xFF;
  2407. int      n;
  2408. DWORD    r, s, e, rmax;
  2409. BYTE     b;
  2410.  
  2411.     //ReportMap();
  2412.     
  2413.     //if (nextMode==1)
  2414.     //{
  2415.     //    fprintf(stderr,"\n>>> THIS SHOULD'NT HAPPEN <<< fatalError=%3d :%08X ",
  2416.     //    fatalError, cur_position);getch();
  2417.     //}
  2418.     
  2419.     rmax=imageBase+getRVA(CodeOffset+CodeSize-1)+1;
  2420.  
  2421.     if (ref>imagebaseRVA)
  2422.     for (r=ref-1;r>imagebaseRVA;r--)
  2423.     {
  2424.         if (((b=getMap(r))==0x00)||(b&0x88)) break;
  2425.         //fprintf(stderr, "b=%02X ",b);
  2426.     }
  2427.     //fprintf(stderr, "b=%02X ",b);
  2428.     // start position to erase
  2429.     s = r+1;
  2430.     if ((b=getMap(r))==0 || (b&0x88))s=r+1; else s=r; 
  2431.     //fprintf(stderr, "\ns==%08X ",s);
  2432.     r=ref;
  2433.     if (getMap(r)) { r++;}
  2434.     for (;r<rmax;r++)
  2435.     if (((b=getMap(r))==0x00)||(b&0x08)||(b&0x60))break;
  2436.     // end position to erase (before this point)
  2437.     e = r;
  2438.     //fprintf(stderr, "\ne==%08X ",e);
  2439.     // I need to do something here, delete labels generated at this point
  2440.     n = 0;  
  2441.  
  2442.     for (r=s;r<e;r++)
  2443.     {
  2444.         if(getMap(r)&0x40){r=e;break;}
  2445.         if (getMap(r)&0x10) 
  2446.         {
  2447.             //fprintf(stderr, " dl ");
  2448.             //fprintf(stdout, " dl ");
  2449.             n++;
  2450.             DeleteLabels(r);  
  2451.             /*-------------*/pushTrace(2500);
  2452.             setMap(r, 0x00);
  2453.             /*-------------*/popTrace();
  2454.         }
  2455.         else 
  2456.         {
  2457.             /*-------------*/pushTrace(2510); 
  2458.             setMap(r, 0x00); 
  2459.             /*-------------*/popTrace();
  2460.         } 
  2461.         //ReportMap();
  2462.     }
  2463.     if (e>s)
  2464.     {
  2465.         //markStrings(s, e);
  2466.         //fprintf(stdout, "\n(%08X)eraseUncertain: %08X - %08X =%3d labels are deleted",
  2467.         //                ref, s, e,n);
  2468.     }
  2469.     ph->s=s; ph->e=e; ph->l=n;
  2470.     //if (e>s)
  2471.     //fprintf(stderr, "\n(%08X)eraseUncertain: %08X - %08X =%3d labels are deleted\n",
  2472.     //                ref, s, e, n);
  2473.     //ReportMap();
  2474.     //exit(0);
  2475.     eraseUncertainNum++;
  2476.     if (hCnt<hMax) History[hCnt++]=*ph; else {fprintf(stderr,"hCnt over");exit(0);}
  2477. }
  2478.  
  2479.  
  2480. void eraseUncertain1(DWORD ref, PHISTORY ph)
  2481. {   
  2482. //static   BYTE  bb=0xFF;
  2483. int            cBox[256];
  2484. int            i, n, nn;
  2485. DWORD          r, s, e, rr, rmax;
  2486. BYTE           b;
  2487.  
  2488.     rmax=imageBase+getRVA(CodeOffset+CodeSize-1)+1;
  2489.     for (r=ref-1;r>imagebaseRVA;r--)
  2490.     if (((b=getMap(r))==0x00)||(b&0x88)) break;
  2491.     // start position to erase
  2492.     s = r+1;
  2493.     r=ref;
  2494.     if (getMap(r)) { r++;}
  2495.     for (;r<rmax;r++)
  2496.     if (((b=getMap(r))==0x00)||(b&0x08)||(b&0x40)||((b&0x22)==0x22))break;
  2497.     // end position to erase (before this point)
  2498.     e = r;
  2499.     // I need to do something here, delete labels generated at this point
  2500.     n = 0;  r=s; nn=0;
  2501.     for(i=0;i<256;i++)cBox[i]=0;
  2502.     while(r<e)
  2503.     {
  2504.         if(getByteFile(r)==0x55&&getByteFile(r+1)>0x80)break;
  2505.         cBox[getByteFile(r)]+=1;r++;nn++;
  2506.     }
  2507.     rr=r;
  2508.     if ((cBox[0xC2]+cBox[0xC3]==0) &&
  2509.        ((cBox[0x81]+cBox[0x83]+cBox[0x89]+cBox[0x8B])*100<nn))
  2510.     {
  2511.         r=s;
  2512.         while(r<rr) 
  2513.         { 
  2514.             /*----------*/pushTrace(2510);
  2515.             if (getMap(r)&0x10) {DeleteLabels(r); n++;}
  2516.             /*----------*/popTrace();
  2517.             /*----------*/pushTrace(2520);
  2518.             setMap(r, 0x00); r++;  
  2519.             /*----------*/popTrace();
  2520.         }
  2521.         while(r<e) 
  2522.         { 
  2523.             /*----------*/pushTrace(2530);
  2524.             if (getMap(r)&0x10) {DeleteLabels(r); n++;}
  2525.             /*----------*/popTrace();
  2526.             /*----------*/pushTrace(2540);
  2527.             setMap(r, 0x00); r++;  
  2528.             /*----------*/popTrace();
  2529.         }
  2530.     }
  2531.     else 
  2532.     for (r=s;r<e;r++)
  2533.     {
  2534.         if(getMap(r)&0x40){r=e;break;}
  2535.         if (getMap(r)&0x10) { DeleteLabels(r); n++; }
  2536.         // i have to take care of very bad situation here.
  2537.         if (getMap(r)&0x20)
  2538.         {
  2539.             if (referCount(r)<3) 
  2540.             {
  2541.                 /*-------*/pushTrace(2550);
  2542.                 setMap(r, 0x00); 
  2543.                 /*-------*/popTrace();
  2544.             } 
  2545.             else 
  2546.             {
  2547.                 /*-------*/pushTrace(2560); 
  2548.                 setMap(r, 0x20); 
  2549.                 /*-------*/popTrace(); 
  2550.             }
  2551.         }
  2552.         else 
  2553.         {
  2554.             /*-----------*/pushTrace(2570); 
  2555.             setMap(r, 0x00); 
  2556.             /*-----------*/popTrace();
  2557.         } 
  2558.     }
  2559.     if (e>s)
  2560.     {
  2561.         //markStrings(s, e);
  2562.           
  2563. //fprintf(stderr, "\n@(%08X)eraseUncertain1: %08X - %08X ... %3d labels are deleted\n",ref,
  2564. //          s,e,n);
  2565. //fprintf(stdout, "\n@(%08X)eraseUncertain1: %08X - %08X ... %3d labels are deleted\n",ref,
  2566. //          s,e,n);
  2567.     }
  2568.     ph->s=s; ph->e=e; ph->l=n;
  2569.     //if(!isGoodAddress(s))
  2570.     //fprintf(stderr,"\nRRR..%08X s=%08X",ref,s),getch();
  2571.     if (hCnt<5012) History[hCnt++]=*ph; else {fprintf(stderr,"hCnt over");exit(0);}   
  2572. }
  2573.  
  2574. void eraseCarefully(DWORD ref, PHISTORY ph)
  2575. {
  2576. //int      i, n;
  2577. _key_    k;
  2578. PKEY     pk;
  2579.     
  2580.     //fprintf(stdout,"\neraseCarefully::%08X=<=%08X",ref,cur_position);
  2581.     k.c_ref=ref; k.c_pos=-1; k.class=0;
  2582.     pk = searchBtree3(&k);
  2583.     if (pk==NULL) return; 
  2584.     //{fprintf(stderr, " NOT FOUND ");fprintf(stdout, " NOT FOUND "); 
  2585.     // return 1;}
  2586.     //fprintf(stdout," ::%08X",pk->c_pos);
  2587.  
  2588.     /*-----------*/pushTrace(2600);
  2589.     eraseUncertain1(pk->c_pos, ph);
  2590.     /*-----------*/popTrace();
  2591. }
  2592.  
  2593. // *******************************************
  2594. // label handling functions
  2595. // *******************************************
  2596.  
  2597. int isLabelCheckable(DWORD r)
  2598. {
  2599.    if (getMap(r  )>0) return 0;
  2600.    if (getMap(r+1)>0) return 0;
  2601.    if (getMap(r+2)>0) return 0;
  2602.    if (getMap(r+3)>0) return 0;
  2603.    return 1;
  2604. }
  2605.  
  2606. void setAddress(DWORD pos)
  2607. {
  2608.     /*-----------*/pushTrace(2650);
  2609.     if(isLabelCheckable(pos))
  2610.     {
  2611.         setMap(pos  , 0x0E);   setMap(pos+1, 0x0E); 
  2612.         setMap(pos+2, 0x0E);   setMap(pos+3, 0x0E);
  2613.     }
  2614.     /*-----------*/popTrace();
  2615. }
  2616.  
  2617. void setAnyAddress(DWORD pos)
  2618. {
  2619.     /*-----------*/pushTrace(2660);
  2620.     orMap1(pos  ,0x30);
  2621.     orMap1(pos+1,0x20);
  2622.     orMap1(pos+2,0x20);
  2623.     orMap1(pos+3,0x20);
  2624.     /*-----------*/popTrace();
  2625. }
  2626.  
  2627. int isItAnyAddress(DWORD pos)
  2628. {
  2629.     if ((getMap1(pos  )&0x30)!=0x30) return 0;
  2630.     if ((getMap1(pos+1)&0x30)!=0x20) return 0;
  2631.     if ((getMap1(pos+2)&0x30)!=0x20) return 0;
  2632.     if ((getMap1(pos+3)&0x30)!=0x20) return 0;
  2633.     return 1;
  2634. }
  2635.  
  2636. int touchAnyAddress(DWORD pos)
  2637. {
  2638.     if ((getMap1(pos)&0x30)==0x20) return 1;
  2639.     return 0;
  2640. }
  2641.  
  2642. int isAddressBlock(DWORD pos)
  2643. {
  2644. DWORD   i, r, rmax;
  2645.  
  2646.     r=pos-3;
  2647.     rmax=pos+128;
  2648.     while(1)
  2649.     {
  2650.         for (;r<rmax;r++) if (isItAnyAddress(r)) break;
  2651.         for (i=r+4;i<rmax;i+=4) if (!isItAnyAddress(i)) break;
  2652.         if (i-r >12) return 1;
  2653.         return 0;
  2654.     }
  2655. }
  2656.  
  2657. void setFirstTime(DWORD pos)
  2658. {                
  2659.     /*--------*/pushTrace(2670);
  2660.     if (nextMode==0) orMap1(pos,0x80); else orMap1(pos,0x40);
  2661.     /*--------*/popTrace();
  2662. }
  2663.  
  2664. int isItFirstTime(DWORD pos)
  2665. {
  2666. BYTE    b;
  2667.  
  2668.     if (nextMode==0) b=0x80; else b=0x40;
  2669.     if ((getMap1(pos)&b)==0x00) return 1;
  2670.     return 0;
  2671. }
  2672.  
  2673. void MyBtreeInsertDual(int class, DWORD ref, DWORD pos)
  2674. {
  2675. _key_    k;
  2676.     
  2677.     k.class = class;
  2678.     k.c_pos = pos;
  2679.     k.c_ref = ref;
  2680.     MyBtreeInsert(&k);
  2681.     k.class = -class;
  2682.     k.c_pos = ref;
  2683.     k.c_ref = pos;
  2684.     MyBtreeInsert(&k);  // we can use this .. for erase uncertain case.    
  2685. }
  2686.  
  2687. void MyBtreeDeleteDual(int class, DWORD ref, DWORD pos)
  2688. {
  2689. _key_    k;
  2690.  
  2691.     k.class = class;
  2692.     k.c_pos = pos;
  2693.     k.c_ref = ref;
  2694.     MyBtreeDelete(&k);
  2695.     k.class = -class;
  2696.     k.c_pos = ref;
  2697.     k.c_ref = pos;
  2698.     MyBtreeDelete(&k);  // we can use this .. for erase uncertain case.    
  2699. }
  2700.  
  2701. int BadEnter(DWORD ref, DWORD pos)
  2702. {
  2703. int    col;
  2704. BYTE   b;
  2705.  
  2706.     b=getMap(ref);
  2707.     if (i_col>0) col=i_col; else col=i_col_save;
  2708.     if (pos<=ref&&ref<pos+col) 
  2709.     {fatalError=998; 
  2710.     //if(nextMode)fprintf(stderr," 998 p=%08X r=%08X ics=%d ",pos,ref,i_col_save);
  2711.     return 1;}
  2712.     if ((b&0x0F)==0x00) return 0;
  2713.     if ((b&0x0F)==0x05) return 0;
  2714.     if ((b&0x0F)==0x07) return 0;
  2715.  
  2716.     //fprintf(stderr,"\n%02X ::pos=%08X:ref=%08X:",b,pos,ref);
  2717.     //fprintf(stdout,"%02X:pos=%08X:ref=%08X:",b,pos,ref);
  2718.     fatalPosition=pos;
  2719.     fatalReference=ref;
  2720.     
  2721.     //for(i=ref-2;i<ref+3;i++)
  2722.     //fprintf(stderr," %02X",getMap(i));
  2723.     fatalError=998;
  2724.     return 1;
  2725. }
  2726.  
  2727. //=======================================================================
  2728. // I need to describe the intended usage of _key_ and its fields.
  2729. // as you can see the _key_ structure consists of three fields
  2730. //  _key_ ::= class,  c_pos, c_ref
  2731. // class tells what kind of reference we are dealing with
  2732. // the table shows:
  2733. //-----------------------------------------------------------------------
  2734. //  class of reference  |unconditional(jump or call)|  conditional jump |
  2735. // ----------------------------------------------------------------------
  2736. // Jmp  Short Rel Disp  |                1          |            2      |
  2737. // Jmp  Near  Rel Disp  |                3          |            4      |
  2738. // Jmp  Near  Abs Indir |                5          |          ***      |
  2739. // Jmp  Far   Absolute  |                7          |          ***      |
  2740. // Jmp  Far   Abs Indir |                9          |          ***      |
  2741. // Call Near  Rel Disp  |               11          |          ***      |
  2742. // Call Near  Abs Indir |               13          |          ***      |
  2743. // Call Far   Absolute  |               15          |          ***      |
  2744. // Call Far   Abs Indir |               17          |          ***      |
  2745. //-----------------------------------------------------------------------
  2746. // Jmp indirect instruction                                    133      |
  2747. // Jmp indirect address holding place                          165      |
  2748. // the reference which is adjacent to above 165                166      |
  2749. // it looks like case 166                                      167      | 
  2750. // the possible reference by   --  push dword                  512      |
  2751. // the possible reference by   --  push [reg or mem]           513      | 
  2752. // the data reference     4 bytes                              514      |
  2753. // the data reference     4 bytes (32 real)                    524      |
  2754. // the data reference 14/24 bytes                              515      |
  2755. // the data reference     2 bytes                              516      |
  2756. // the data reference    10 bytes                              517      |
  2757. // the data reference     8 bytes                              518      |
  2758. // the data reference     8 bytes (64 real)                    528      |
  2759. // the data reference 94/108 bytes                             519      |
  2760. // the data reference     1 byte                               520      |
  2761. // the possible reference by   --  mov [reg or mem], dword    1024      |
  2762. // the definitive reference by export function block          2048      |
  2763. //-----------------------------------------------------------------------
  2764.  
  2765. //=======================================================================
  2766. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  2767. // this one tell what is lpMap and its intended usage...               //
  2768. //---------------------------------------------------------------------//
  2769. // I can use lpMap (code check buffer?)                                //
  2770. //---------------------------------------------------------------------//
  2771. //       0x00: unprocessed                                             //
  2772. //       0x01: starting position of instruction  (masked)              //
  2773. //       0x02: gray mark(suspicious code)        (masked)              //
  2774. //       0x04: processed instructions            (masked)              //
  2775. //       0x08: data(address, byte, CC block)     (no masking)          //
  2776. //             0x09,0x08                         NULL string           //
  2777. //             0x0B,0x0A                         Pascal string         //
  2778. //             0x0C: cc block                      "                   //
  2779. //             0x0E: address                       "                   //
  2780. //             0x0F: byte                          "                   //
  2781. //       0x10: label generated here              (masked)              //
  2782. //       0x20: label or not                      (masked)              //
  2783. //       0x40: entry or not                      (masked)              //
  2784. //       0x80: anchor set                        (masked)              //    
  2785. //---------------------------------------------------------------------//
  2786.  
  2787.  
  2788. // this function tries to record all the possible entries and labels
  2789. // and data references we can find and decipher. 
  2790. void EnterLabel(int class, DWORD ref, DWORD pos)
  2791. {
  2792. DWORD          i, r, rr;
  2793. BYTE           b;
  2794.  
  2795.     //{fprintf(stderr,"EnterLabel::class=%5dX,ref=%08X\n",class,ref);getch();}
  2796.     
  2797.     if (getOffset(ref)<CodeOffset) return;
  2798.     if (!AddressCheck(pos)) return;
  2799.     if (getOffset(ref)<CodeOffset+CodeSize) 
  2800.     {
  2801.         switch(class)
  2802.         {
  2803.             case 1: case 2: case 3: case 4: case 7: 
  2804.                  /*----------*/pushTrace(3000);
  2805.                  MyBtreeInsertDual(class, ref, pos);
  2806.                  /*----------*/popTrace();
  2807.                  if (BadEnter(ref,pos)) break; //need to store something here.
  2808.                  /*----------*/pushTrace(3010);
  2809.                  if (class>2 && isItStartAnyWay(ref)) addLabels(ref, 256);
  2810.                  /*----------*/popTrace();
  2811.                  /*----------*/pushTrace(3020);
  2812.                  orMap(ref, 0x20);
  2813.                  /*----------*/popTrace();
  2814.                  /*----------*/pushTrace(3030);
  2815.                  orMap(pos, 0x10);
  2816.                  /*----------*/popTrace();
  2817.                  break;
  2818.             case 11: case 15: case 2048: 
  2819.                  /*----------*/pushTrace(3040);
  2820.                  MyBtreeInsertDual(class, ref, pos);
  2821.                  /*----------*/popTrace();
  2822.                  if (BadEnter(ref,pos)) break; //need to store something here.
  2823.                  /*----------*/pushTrace(3050);
  2824.                  if (isItStartAnyWay(ref)) addLabels(ref, 512);
  2825.                  /*----------*/popTrace();
  2826.                  /*----------*/pushTrace(3060);
  2827.                  orMap(ref, 0x40);
  2828.                  /*----------*/popTrace();
  2829.                  /*----------*/pushTrace(3070);
  2830.                  orMap(pos, 0x10);
  2831.                  /*----------*/popTrace();
  2832.                  break;
  2833.             case 166: case 167: 
  2834.             // mark that address data
  2835.                  /*----------*/pushTrace(3080);
  2836.                  addLabels(ref,128);
  2837.                  /*----------*/popTrace();
  2838.                  /*----------*/pushTrace(3090);
  2839.                  setAddress(pos);
  2840.                  /*----------*/popTrace();
  2841.                  /*----------*/pushTrace(3100);
  2842.                  MyBtreeInsertDual(class, ref, pos); 
  2843.                  /*----------*/popTrace();
  2844.                  if (BadEnter(ref,pos)) break;
  2845.                  /*----------*/pushTrace(3110);
  2846.                  orMap(ref, 0x20);
  2847.                  /*----------*/popTrace();
  2848.                  break;
  2849.             case 512: case 513: case 514: case 515: case 516: case 517: 
  2850.             case 518: case 519: case 520: case 524: case 528: case 1024:
  2851.                   /*----------*/pushTrace(3120);
  2852.                  MyBtreeInsertDual(class, ref, pos);
  2853.                  /*----------*/popTrace();
  2854.                  /*----------*/pushTrace(3130);
  2855.                  markData(class, ref, pos);
  2856.                  /*----------*/popTrace();
  2857.                  break;
  2858. //-------------------------------------------------------------------//
  2859. // now it is indirect address reference and we need to take some     //
  2860. // serious actions, namely if it is preventable than it is OK        //
  2861. // but if bad deed is already done we need to UNDO it.               //
  2862. // this requires couple of things.                                   //
  2863. // first we need to store indirect references in some convenient way //
  2864. // and every time we need to check whether we touch it or not.       //
  2865. // second we need to store all the anchors and start positions       //
  2866. // so we can easily determine how much we need to UNDO.              //
  2867. //                          october 24, 1997 late night-- sang cho   //
  2868. //-------------------------------------------------------------------//
  2869.             case 5: case 9: case 13: case 17: case 133: 
  2870.             // mark that address data
  2871.                   
  2872.                  //
  2873.                  // the following code is for some special interuptive case:::
  2874.                  // I need to check the validity of this part somehow...
  2875.                  //
  2876.                  if(getMap(ref)!=0x0E&&!isLabelCheckable(ref))
  2877.                  {
  2878.                      if(isGoodAddress(getIntFile(ref))
  2879.                      &&    isGoodAddress(getIntFile(ref+4))
  2880.                      && isGoodAddress(getIntFile(ref+8)))
  2881.                      for(i=ref;i<ref+CodeSize;i+=4)
  2882.                      {
  2883.                          if(getMap(i)==0x0E) break;
  2884.                          if(!isGoodAddress(getIntFile(i))) break;
  2885.                          /*
  2886.                          if(debugAdd-3<=i&&i<=debugAdd)
  2887.                          {
  2888.                              fprintf(stderr,"\nGOD SAVE US");
  2889.                              fprintf(stderr,"getMap(%08X)=%02X",ref,getMap(ref));
  2890.                          }*/
  2891.                          /*----------*/pushTrace(3150);
  2892.                          setMap(i,  0x00);setMap(i+1,0x00);
  2893.                          setMap(i+2,0x00);setMap(i+3,0x00);
  2894.                          /*----------*/popTrace();
  2895.                      }
  2896.                      if ((b=getMap(i))!=0x0E&&(b&0x05)!=0x05) 
  2897.                      {
  2898.                      // emergency erase - I cannot wait until ErrorRecover,
  2899.                      // but is this OK or WHAT?
  2900.                          my_h.m=nextMode;
  2901.                          my_h.f=992;
  2902.                          my_h.r=lastReset;
  2903.                          my_h.c=cur_position;
  2904.                          /*----------*/pushTrace(3160);
  2905.                          eraseUncertain(i, &my_h);
  2906.                          /*----------*/popTrace();
  2907.                      }
  2908.                  }
  2909.  
  2910.                  /*---------*/pushTrace(3170);
  2911.                  setAddress(ref);
  2912.                  /*---------*/popTrace();
  2913.                  /*---------*/pushTrace(3180);
  2914.                  MyBtreeInsertDual(class, ref, pos);
  2915.                  /*---------*/popTrace();
  2916.                  /*---------*/pushTrace(3190);
  2917.                  orMap(pos, 0x10);
  2918.                  /*---------*/popTrace();
  2919.             // I am forming chain of label references.
  2920.             // also new class is defined here.
  2921.                  r = Get32Address(ref);
  2922.                  if (r>0)
  2923.                  {
  2924.                        if (AddressCheck(r))
  2925.                      {
  2926.                          if (BadEnter(r,ref)) break;
  2927.                          /*---------*/pushTrace(3200);
  2928.                          MyBtreeInsertDual(class+32, r, ref);
  2929.                          /*---------*/popTrace();
  2930.  
  2931.                          if (class<13||17<class)
  2932.                          {
  2933.                              if (!(getMap(r)&0x20)) 
  2934.                              { 
  2935.                                  /*---------*/pushTrace(3210);
  2936.                                  if (isGoodAddress(r)) addLabels(r,64); 
  2937.                                  orMap(r, 0x20); 
  2938.                                  /*---------*/popTrace();
  2939.                              }   
  2940.                          }
  2941.                          else
  2942.                          {
  2943.                              /*----------*/pushTrace(3220);
  2944.                              addLabels(r,128);
  2945.                              orMap(r, 0x40); 
  2946.                              /*----------*/popTrace();
  2947.                          }
  2948.                      }
  2949.                  }
  2950.                     break;
  2951.             // I need to UNDO that bad deed, I once did.
  2952.             // but this one is in the middle of printing really something untouchable,
  2953.             // so what should I do, can I preempt it and proceed what I have to do?
  2954.             // well... if I am more careful I think I can do that.
  2955.             // OK this is fixed now, I can progress as I wished.   october 25, 1997
  2956.             // the following code is move to above position....^^^^^.....
  2957.             //if (ref<pos+4) { eraseUncertain(ref); break; }
  2958.  
  2959.             default:
  2960.         }
  2961.     }
  2962.  //
  2963.  // if reference is out of code range what can I do?
  2964.  // I have to think about it a while, meantime I'll just 
  2965.  // do the thing I can do.
  2966.  //
  2967.     else
  2968.     {
  2969.         switch(class)
  2970.         {
  2971.             case 3: case 4:
  2972.                  fatalError=950;
  2973.                  break;
  2974.             case 7: case 11: case 15:      
  2975.                  r = Get32Address(ref);
  2976.                  if (r>0)
  2977.                  {
  2978.                      if (class==7 )
  2979.                      {
  2980.                           /*----------*/pushTrace(3250);
  2981.                          if (isGoodAddress(r))
  2982.                          addLabels(r,32);
  2983.                          /*----------*/popTrace();
  2984.                      }
  2985.                      /*--------------*/pushTrace(3260);
  2986.                      MyBtreeInsertDual(class, r, pos);
  2987.                      /*--------------*/popTrace();
  2988.                  }
  2989.                  break;
  2990.             case 166: case 167:
  2991.             // mark that address data
  2992.                  /*-----------*/pushTrace(3270);
  2993.                  setAddress(pos);
  2994.                  /*-----------*/popTrace();
  2995.                  /*-----------*/pushTrace(3280);
  2996.                  MyBtreeInsertDual(class, ref, pos);
  2997.                  /*-----------*/popTrace();
  2998.                  break;
  2999.             case 512: case 513: case 514: case 515: case 516: case 517: 
  3000.             case 518: case 519: case 520: case 524: case 528: case 1024:
  3001.                  /*-----------*/pushTrace(3290);
  3002.                  MyBtreeInsertDual(class, ref, pos);
  3003.                  /*-----------*/popTrace();
  3004.                  break;
  3005.             case 5: case 9: case 13: case 17: case 133: 
  3006.             // mark that address data
  3007.                  r = Get32Address(ref);
  3008.                  if (r>0)
  3009.                  {
  3010.                      /*-----------*/pushTrace(3300);
  3011.                      MyBtreeInsertDual(class, r, pos);
  3012.                      /*-----------*/popTrace();
  3013.  
  3014.             // I am forming chain of label references.
  3015.             // also new class is defined here.
  3016.                  rr = Get32Address(r);
  3017.                      if (rr>0)
  3018.                      {
  3019.                          if (class<13||class>17)
  3020.                          {
  3021.                              /*------------*/pushTrace(3310);
  3022.                              if(isGoodAddress(rr))
  3023.                              addLabels(rr,16);
  3024.                              /*------------*/popTrace();
  3025.                          }
  3026.                          /*-----------*/pushTrace(3320);
  3027.                          MyBtreeInsertDual(class+32, rr, r);
  3028.                           /*-----------*/popTrace();
  3029.                      }
  3030.                  }
  3031.             default:
  3032.         }
  3033.     }
  3034. }
  3035.  
  3036. void markData(int class, DWORD ref, DWORD pos)
  3037. {
  3038. BYTE    a, b, c, d;
  3039. DWORD   i;
  3040.  
  3041.     /*-----------*/pushTrace(3400);
  3042.     switch(class)
  3043.     {
  3044.         case 512:
  3045.              a=getMap(ref); b=getMap(ref+1); c=getMap(ref+2); d=getMap(ref+3);
  3046.              if ((a==0||(a&0x08))&&(b==0||(b&0x08))
  3047.                &&(c==0||(c&0x08))&&(d==0||(d&0x08))) 
  3048.              {     
  3049.                  if (isItStartAnyWay(ref)) addLabels(ref, 1);
  3050.                  else if(isGoodAddress(getIntFile(ref)))
  3051.                  {     
  3052.                      setMap(ref,0x0E);   setMap(ref+1,0x0E); 
  3053.                      setMap(ref+2,0x0E); setMap(ref+3,0x0E);
  3054.                  }
  3055.              }
  3056.              
  3057.              break;
  3058.         case 513:
  3059.              a=getMap(ref); b=getMap(ref+1); c=getMap(ref+2); d=getMap(ref+3);
  3060.              if ((a==0||(a&0x08))&&(b==0||(b&0x08))
  3061.                &&(c==0||(c&0x08))&&(d==0||(d&0x08)))   
  3062.              {     
  3063.                  if(isGoodAddress(getIntFile(ref)))
  3064.                  {     
  3065.                      setMap(ref,0x0E);   setMap(ref+1,0x0E); 
  3066.                      setMap(ref+2,0x0E); setMap(ref+3,0x0E);
  3067.                  }
  3068.              }
  3069.              break;
  3070.         case 514: 
  3071.              a=getMap(ref); b=getMap(ref+1); c=getMap(ref+2); d=getMap(ref+3);
  3072.              if ((a==0||(a&0x08))&&(b==0||(b&0x08))
  3073.                &&(c==0||(c&0x08))&&(d==0||(d&0x08))) 
  3074.              {     
  3075.                  setMap(ref,0x0E);   setMap(ref+1,0x0E); 
  3076.                  setMap(ref+2,0x0E); setMap(ref+3,0x0E);
  3077.              }
  3078.              else if (a==0x0E && b==0x0E && c==0x0E && d==0x0E);
  3079.              else
  3080.              {
  3081.                  //fprintf(stderr, "\nmarkData error class=%3d ref=%08X pos=%08X ",
  3082.                  //        class, ref, pos);
  3083.                  //fprintf(stderr, "%02X %02X %02X %02X ", a,b,c,d);
  3084.                  fatalError=994;
  3085.                  //getch();
  3086.              }
  3087.              break;
  3088.         case 515:
  3089.              for (i=ref;i<ref+14;i++)
  3090.              {   a=getMap(i); if ((a!=0 && a!=0x0F)) break;   }
  3091.              if (i==ref+14)
  3092.                  for (i=ref;i<ref+14;i++) {setMap(i,0x0F); orMap1(i,0x08);}
  3093.              else 
  3094.              {
  3095.                  //fprintf(stderr, "\nmarkData error class=%3d ref=%08X pos=%08X ",
  3096.                  //        class, ref, pos);
  3097.                  //fprintf(stderr, "%02X ", a);
  3098.                  fatalError=994;
  3099.                  //getch();
  3100.              }
  3101.              break;
  3102.         case 516:
  3103.              
  3104.              a=getMap(ref); b=getMap(ref+1);
  3105.              if ((a==0||a==0x0F)&&(b==0||b==0x0F)) 
  3106.              { setMap(ref,0x0D);   setMap(ref+1,0x0D);}
  3107.              else if(a==0x0D && b==0x0D);
  3108.              else
  3109.              {
  3110.                  //fprintf(stderr, "\nmarkData error class=%3d ref=%08X pos=%08X ",
  3111.                  //        class, ref, pos);
  3112.                  //fprintf(stderr, "%02X %02X ", a, b);
  3113.                  fatalError=994;
  3114.                  //getch();
  3115.              }
  3116.              break;
  3117.         case 517:
  3118.              for (i=ref;i<ref+10;i++)
  3119.              {   a=getMap(i); if ((a!=0x00 && a!=0x0F)) break;   }
  3120.              if (i==ref+10)
  3121.              {
  3122.                  for (i=ref;i<ref+10;i++) {setMap(i,0x0F); orMap1(i,0x08); }
  3123.              }
  3124.              else 
  3125.              {
  3126.                  //fprintf(stderr, "\nmarkData error class=%3d ref=%08X pos=%08X i=%08X ",
  3127.                  //        class, ref, pos, i);
  3128.                  //fprintf(stderr, "%02X ", a);
  3129.                  fatalError=994;
  3130.                  //getch();
  3131.              }
  3132.              break;
  3133.         case 518: case 528:
  3134.              for (i=ref;i<ref+8;i++)
  3135.              {   a=getMap(i); if ((a!=0x00 && a!=0x0F)) break;   }
  3136.              if (i==ref+8)
  3137.                  for (i=ref;i<ref+8;i++) {setMap(i,0x0F); orMap1(i,0x08); }
  3138.              else 
  3139.              {
  3140.                  //fprintf(stderr, "\nmarkData error class=%3d ref=%08X pos=%08X ",
  3141.                  //        class, ref, pos);
  3142.                  //fprintf(stderr, "%02X ", a);
  3143.                  fatalError=994;
  3144.                  //getch();
  3145.              }
  3146.              break;
  3147.         case 519:
  3148.              for (i=ref;i<ref+94;i++)
  3149.              {   a=getMap(i); if ((a!=0x00 && a!=0x0F)) break;   }
  3150.              if (i==ref+94)
  3151.                  for (i=ref;i<ref+94;i++) {setMap(i,0x0F); orMap1(i,0x08); }
  3152.              else 
  3153.              {
  3154.                  //fprintf(stderr, "\nmarkData error class=%3d ref=%08X pos=%08X ",
  3155.                  //        class, ref, pos);
  3156.                  //fprintf(stderr, "%02X ", a);
  3157.                  fatalError=994;
  3158.                  //getch();
  3159.              }
  3160.              break;
  3161.         case 520:
  3162.              a=getMap(ref);
  3163.              if ((a==0||a==0x0F)) {setMap(ref,0x0F); orMap1(ref,0x08); }
  3164.              else
  3165.              {
  3166.                  fatalError=994;
  3167.                  //fprintf(stderr, "\nmarkData error class=%3d ref=%08X pos=%08X ",
  3168.                  //        class, ref, pos);
  3169.                  //fprintf(stderr, "%02X ", a);
  3170.                  fatalError=994;
  3171.                  //getch();
  3172.              }
  3173.              break;
  3174.         case 524:
  3175.              a=getMap(ref); b=getMap(ref+1); c=getMap(ref+2); d=getMap(ref+3);
  3176.              if ((a==0||(a&0x08))&&(b==0||(b&0x08))
  3177.                &&(c==0||(c&0x08))&&(d==0||(d&0x08))) 
  3178.              {     
  3179.                  setMap(ref,0x0F);   setMap(ref+1,0x0F); 
  3180.                  setMap(ref+2,0x0F); setMap(ref+3,0x0F);
  3181.                  orMap1(ref,0x08);   orMap1(ref+1,0x08);
  3182.                  orMap1(ref+2,0x08); orMap1(ref+3,0x08);
  3183.              }
  3184.              else if (a==0x0F && b==0x0F && c==0x0F && d==0x0F);
  3185.              else
  3186.              {
  3187.                  //fprintf(stderr, "\nmarkData error class=%3d ref=%08X pos=%08X ",
  3188.                  //        class, ref, pos);
  3189.                  //fprintf(stderr, "%02X %02X %02X %02X ", a,b,c,d);
  3190.                  fatalError=994;
  3191.                  //getch();
  3192.              }
  3193.              break;
  3194.         case 1024:
  3195.              a=getMap(ref); b=getMap(ref+1); c=getMap(ref+2); d=getMap(ref+3);
  3196.              if ((a==0||(a&0x08))&&(b==0||(b&0x08))
  3197.                &&(c==0||(c&0x08))&&(d==0||(d&0x08))) 
  3198.              {     
  3199.                  if(isGoodAddress(getIntFile(ref)))
  3200.                  {     
  3201.                      setMap(ref,0x0E);   setMap(ref+1,0x0E); 
  3202.                      setMap(ref+2,0x0E); setMap(ref+3,0x0E);
  3203.                  }
  3204.              }
  3205.              break;
  3206.         default:
  3207.     }
  3208.     /*-----------*/popTrace();
  3209. }
  3210.  
  3211. // this is inverse of EnterLabel, but... who knows!
  3212. void DeleteLabels(DWORD pos)
  3213. {
  3214. //int            r;
  3215. BYTE           b;
  3216. _key_          k, k1, k2, k3;
  3217. PKEY           pk;
  3218.  
  3219.     k.c_ref=pos; k.c_pos=-1; k.class=0;
  3220.     pk = searchBtree1(&k);
  3221.     if(pk==NULL) return;    
  3222.     k1=*pk;   
  3223.     k.class=-k1.class; k.c_pos=k1.c_ref; k.c_ref=k1.c_pos;
  3224.     pk = searchBtree1(&k);
  3225.     if(pk==NULL) return; 
  3226.     k2=*pk;
  3227.     if(k2.class==133 || k2.class==5 || k2.class==9)
  3228.     {
  3229.         k.c_ref=k2.c_ref;     k.c_pos=0; k.class=0;
  3230.         pk = searchBtree1(&k);
  3231.         if (pk)
  3232.         {
  3233.             k3=*pk;
  3234.             MyBtreeDeleteDual(-(k3.class), k3.c_pos, k3.c_ref);
  3235.             b=getMap(k3.c_pos);
  3236.             /*---------*/pushTrace(3500);
  3237.             if (b&0x20) exMap(k3.c_pos, 0x20);
  3238.             /*---------*/popTrace();
  3239.         }
  3240.     }
  3241.     
  3242.     // we have to delete k1 and k2
  3243.     MyBtreeDeleteDual(k2.class, k2.c_ref, k2.c_pos);
  3244.     b=getMap(k2.c_ref);
  3245.     /*---------*/pushTrace(3510);
  3246.     if (b&0x20) exMap(k2.c_ref, 0x20);
  3247.     /*---------*/popTrace();
  3248.     //fprintf(stdout,"deleted label==%5d::%08X<<%08X\n",k2.class,k2.c_ref,k2.c_pos);
  3249. }
  3250.  
  3251.  
  3252. // **********************************************
  3253. // address checking or getactual address. etc...
  3254. // **********************************************
  3255.  
  3256. int isGoodAddress(DWORD ref)
  3257. {
  3258. DWORD   r=getOffset(ref);
  3259. _key_  k;
  3260. PKEY   pk;
  3261.  
  3262.     if ((int)r < CodeOffset) 
  3263.     {
  3264.         k.c_ref=ref; k.c_pos=-1; k.class=0; 
  3265.         pk=searchBtreeX(&k);
  3266.         if (pk==NULL) return 0;
  3267.         else return ref;
  3268.     }
  3269.     
  3270.     if ((int)r<CodeOffset+CodeSize) return 1;
  3271.     return 0;
  3272. }
  3273.  
  3274. DWORD AddressCheck(DWORD ref)
  3275. {
  3276. _key_  k;
  3277. PKEY   pk;
  3278.  
  3279.     if (ref < imagebaseRVA) 
  3280.     {
  3281.         k.c_ref=ref; k.c_pos=-1; k.class=0; 
  3282.         pk=searchBtreeX(&k);
  3283.         if (pk==NULL) return 0;
  3284.         else return ref;
  3285.     }
  3286.     
  3287.     //if (ref<imagebaseRVA) return 0;
  3288.     if (ref<imageBase+maxRVA+maxRVAsize) return ref;
  3289.     return 0;
  3290. }
  3291.  
  3292.  
  3293. int getNumExeSec ()
  3294. {
  3295. int        i, c, n=0;
  3296.  
  3297.     /* locate section containing image directory */
  3298.     for(i=0;i<nSections;i++)
  3299.     {
  3300.         c = (int)shdr[i].Characteristics;
  3301.         if ((c&0x60000020)==0x60000020)n++;
  3302.     }
  3303.  
  3304.     return n;
  3305. }
  3306.  
  3307. DWORD getOffset (DWORD ref)
  3308. {
  3309. int        i;
  3310.  
  3311.     if (ref == 0) return 0;
  3312.     
  3313.     /* locate section containing image directory */
  3314.     for(i=0;i<nSections;i++)
  3315.     {
  3316.         if (shdr[i].VirtualAddress <= ref-imageBase &&
  3317.         ref-imageBase < shdr[i].VirtualAddress + shdr[i].SizeOfRawData)
  3318.         break;
  3319.     }
  3320.  
  3321.     if (i >= nSections)
  3322.     return 0;
  3323.  
  3324.     /* return image import directory offset */
  3325.     return ref - imageBase - (int)shdr[i].VirtualAddress + (int)shdr[i].PointerToRawData;
  3326. }
  3327.  
  3328. DWORD getRVA (DWORD off)
  3329. {
  3330. int        i;
  3331.  
  3332.     if (off == 0) return 0;
  3333.  
  3334.     /* locate section containing image directory */
  3335.     for(i=0;i<nSections;i++)
  3336.     {
  3337.         if ((int)shdr[i].PointerToRawData <= off &&
  3338.         off < (int)shdr[i].PointerToRawData + (int)shdr[i].SizeOfRawData)
  3339.         break;
  3340.     }
  3341.  
  3342.     if (i >= nSections)
  3343.     return 0;
  3344.  
  3345.     /* return image import directory offset */
  3346.     return off - (int)shdr[i].PointerToRawData + (int)shdr[i].VirtualAddress;
  3347. }
  3348.  
  3349. DWORD Get32Address(DWORD ref)
  3350. {
  3351. DWORD     r, off;
  3352. _key_  k;
  3353. PKEY   pk;
  3354.  
  3355.     off = getOffset(ref);
  3356.     if (off < CodeOffset) 
  3357.     {
  3358.         k.c_ref=ref; k.c_pos=-1; k.class=0; 
  3359.         pk=searchBtreeX(&k);
  3360.         if (pk==NULL) return 0;
  3361.         else return ref;
  3362.     }
  3363.     
  3364.     if (off<CodeOffset+CodeSize)
  3365.         return AddressCheck(getIntFile(ref));
  3366.     r=(DWORD)GetActualAddress(lpFile, ref-imageBase);
  3367.     if (r) return (*(PDWORD)(r));
  3368.     return 0;
  3369. }
  3370.  
  3371. int isThisSecure(DWORD ref)
  3372. {
  3373. DWORD   r;
  3374.  
  3375.     if ((getMap(ref)&0x05)!=0x05) return 0;
  3376.     for (r=ref;r<ref+256;r++)
  3377.         if(getMap(r)&0x80) return 1;
  3378.     return 0;
  3379. }
  3380.  
  3381.  
  3382. int isNotGoodJump(DWORD ref)
  3383. {
  3384. BYTE    b;
  3385. DWORD   r;
  3386. _key_   k;
  3387. PKEY    pk;
  3388.  
  3389.     b=getByteFile(ref);
  3390.     if (b==0xC3) return 0;
  3391.     if (b==0xC2) return 0;
  3392.     if (b==0xE9||b==0xFF)
  3393.     {
  3394.         k.class=0;k.c_ref=ref;k.c_pos=0;
  3395.         pk=searchBtree1(&k);
  3396.         if(!pk)return 0;
  3397.         r=pk->c_pos;
  3398.         if(!AddressCheck(r))
  3399.         {
  3400.             k.c_ref=r;k.c_pos=0;k.class=0;
  3401.             pk=searchBtree1(&k);
  3402.             if(pk==NULL)return 1;
  3403.             else return 0;
  3404.         }
  3405.         if(getOffset(r)<CodeOffset+CodeSize&&(getMap(r)&0x20))return 0;
  3406.         if(getOffset(r)>CodeOffset+CodeSize&&referCount(r)>0)return 0;
  3407.     }
  3408.     return 1;
  3409. }
  3410.  
  3411. PBYTE toFile(DWORD ref)
  3412. DWORD   r=getOffset(ref);
  3413.  
  3414.     if(r<0) return 0;
  3415.     if(r>fsize) return 0;
  3416.     return (PBYTE)((int)r+(int)lpFile);
  3417. }
  3418.  
  3419. BYTE getByteFile(DWORD ref)
  3420. {
  3421. DWORD   r=getOffset(ref);
  3422.  
  3423.     if(r<0) return 0;
  3424.     if(r>fsize-4) return 0;
  3425.     return *(PBYTE)((int)r+(int)lpFile);
  3426. }
  3427.  
  3428. int  getIntFile(DWORD ref)
  3429. {
  3430. DWORD   r=getOffset(ref);
  3431.  
  3432.     if(r<0) return 0; 
  3433.     if(r>=fsize) return 0;
  3434.     return *(int *)((int)r+(int)lpFile);
  3435. }
  3436.  
  3437. BYTE getMap(DWORD ref)
  3438. {
  3439. DWORD   r=getOffset(ref);
  3440.  
  3441.     if(r<CodeOffset) return 0;
  3442.     if(r>=CodeOffset+CodeSize) return 0;
  3443.     return *(PBYTE)((int)r+(int)lpMap);
  3444. }
  3445.  
  3446. void setMap(DWORD ref, BYTE c)
  3447. {
  3448. DWORD   r=getOffset(ref);
  3449. //int   i;
  3450. /*
  3451. if(ref==debugAdd||ref==debugAdd1)
  3452. {
  3453.     fprintf(stderr,"\nsetMap(%08X) (%02X)to %02X from c_pos=%08X f=%d ",
  3454.                    ref, getMap(ref),c,cur_position,fatalError);
  3455.     for(i=0;i<debugx;i++)fprintf(stderr," dp=%4d",debugTab[i]);
  3456.     getch();
  3457. }*/
  3458.     if(r<CodeOffset) return;
  3459.     if(r>=CodeOffset+CodeSize) return;
  3460.     *(PBYTE)((int)r+(int)lpMap)=c;
  3461. }
  3462.  
  3463. void orMap(DWORD ref, BYTE c)
  3464. {
  3465. DWORD   r=getOffset(ref);
  3466. //int   i;
  3467. /*  
  3468. if(ref==debugAdd||ref==debugAdd1)
  3469. {
  3470.     fprintf(stderr,"\norMap(%08X) to %02X from c_pos=%08X (%02X)",
  3471.                    ref,c,cur_position, getMap(ref));
  3472.     for(i=0;i<debugx;i++)fprintf(stderr," dp=%4d",debugTab[i]);
  3473.     getch();
  3474. }*/
  3475.  
  3476.     if(r<CodeOffset) return;
  3477.     if(r>=CodeOffset+CodeSize) return;
  3478.     *(PBYTE)((int)r+(int)lpMap)|=c;
  3479. }
  3480.  
  3481. void exMap(DWORD ref, BYTE c)
  3482. {
  3483. DWORD   r=getOffset(ref);
  3484.  
  3485.     if(r<CodeOffset) return;
  3486.     if(r>=CodeOffset+CodeSize) return;
  3487.     *(PBYTE)((int)r+(int)lpMap)^=c;
  3488. }
  3489.  
  3490. BYTE getMap1(DWORD ref)
  3491. {
  3492. DWORD   r=getOffset(ref);
  3493.  
  3494.     if(r<CodeOffset) return 0;
  3495.     if(r>=CodeOffset+CodeSize) return 0;
  3496.     return *(PBYTE)((int)r+(int)lpMap1);
  3497. }
  3498.  
  3499. void setMap1(DWORD ref, BYTE c)
  3500. {
  3501. DWORD   r=getOffset(ref);
  3502.  
  3503.     if(r<CodeOffset) return;
  3504.     if(r>=CodeOffset+CodeSize) return;
  3505.     *(PBYTE)((int)r+(int)lpMap1)=c;
  3506. }
  3507.  
  3508. void orMap1(DWORD ref, BYTE c)
  3509. {
  3510. DWORD   r=getOffset(ref);
  3511.  
  3512.     if(r<CodeOffset) return;
  3513.     if(r>=CodeOffset+CodeSize) return;
  3514.     *(PBYTE)((int)r+(int)lpMap1)|=c;
  3515. }
  3516.  
  3517. void exMap1(DWORD ref, BYTE c)
  3518. {
  3519. DWORD   r=getOffset(ref);
  3520. /*
  3521. if(ref==debugAdd||ref==debugAdd1)
  3522. {
  3523.     fprintf(stderr,"\nexMap1(%08X) to %02X from debugPoint=%3d c_pos=%08X",
  3524.                    ref,c,debugPoint,cur_position);
  3525.     getch();
  3526. }*/
  3527.  
  3528.     if(r<CodeOffset) return;
  3529.     if(r>=CodeOffset+CodeSize) return;
  3530.     *(PBYTE)((int)r+(int)lpMap1)^=c;
  3531. }
  3532.  
  3533.  
  3534. //
  3535. // I cannot actually compute m16:m32 far address value
  3536. // so I will only record m32 part of it, hope it actually works.
  3537. //
  3538. DWORD Get16_32Address(DWORD ref)
  3539. {
  3540.     return Get32Address(ref);
  3541. }
  3542.  
  3543. // *************************************
  3544. // miscellaneous functions
  3545. // *************************************
  3546.  
  3547. void Myfinish()
  3548. {
  3549.     free ((void *)piNameBuff);
  3550.     free ((void *)peNameBuff);
  3551.     free ((void *)lpFile);
  3552.     free ((void *)lpMap);
  3553.     free ((void *)lpMap1);
  3554.     deleteHeaders();
  3555.     //fclose(d_fp);
  3556.     exit(0);
  3557. }
  3558.  
  3559.  
  3560. /* =============================================================
  3561. I am using very strange looking data structure to store labels.
  3562. There are two parts of it.
  3563.    1. source part
  3564.    2. destination part
  3565.  
  3566.    we have node 
  3567.    struct
  3568.    {
  3569.          DWORD  pos1
  3570.          DWORD  pos2   // i don't like to use union structure so i will just 
  3571.          WORD   red;
  3572.          WORD   rclass // use type casting  (node *)pos2 ...
  3573.          WORD   rcount
  3574.          node*  left
  3575.          node * right
  3576.     }
  3577.  
  3578.     node1
  3579.     struct
  3580.     {
  3581.          DWORD  pos2
  3582.          short  rclass
  3583.          node1* left
  3584.          node1* right
  3585.     }
  3586.             
  3587.  
  3588. I. source part looks like this:
  3589.     there are fsize/256 + 1 many headers for labels.
  3590.     if the number of headers exceeds 64K then it is adjusted to 64K.
  3591.     each header is a pointer to a node and there are some nodes linked to this header.
  3592.     these nodes are only generated between 256 byte range of code.
  3593.     so the number of nodes cannot be too big.
  3594.     each nodes are linked in binary search tree as first integer as a key
  3595.     usually rcount == 1 and that is it, but 
  3596.     if rcount > 1 then pos2 points to the second level of nodes
  3597.     that are linked as binary search tree fashion.
  3598.     when there are case jump block we can think all the addresses are
  3599.     used by this case jump instruction so there are many source side references.
  3600.     but this is not direct reference, anyway we need to store counter part of
  3601.     this information into destination side too.
  3602.  
  3603. II. destination part looks like this:
  3604.     there are fsize/256 + 1 many headers for labels.
  3605.     each header is a pinter to a node and there are some nodes linked to this header.
  3606.     these nodes are destinations between 256 byte range of code.
  3607.     each node may have children nodes which are linked through down pointer.( pos2)
  3608.     when rcount == 1 then there are no children.
  3609.     if   rcount >  1 then pos2 points to the second level of nodes (children nodes)
  3610.     
  3611. ----------------------------------------------------------------------------
  3612.  */
  3613. int      asize;   
  3614. int      hsize;
  3615. int      width;
  3616. LPVOID   headerS;
  3617. LPVOID   headerD;
  3618.  
  3619. void initHeaders()
  3620. {
  3621.     asize = fsize/8 + 1;
  3622.     hsize = fsize/256;
  3623.     width =    256;
  3624.     while(hsize>64*1024){hsize/=2;width*=2;}
  3625.     hsize+=1;
  3626.     headerS=(LPVOID)calloc(hsize*4,1);
  3627.     if (headerS==NULL) {fprintf(stderr,"Cannot allocate headerS"); exit(1);}
  3628.     headerD=(LPVOID)calloc(hsize*4,1);
  3629.     if (headerD==NULL) {fprintf(stderr,"Cannot allocate headerD"); exit(1);}
  3630.     initHeap();
  3631. }
  3632.  
  3633. void deleteTrees1(PNODE1 pn)
  3634. {
  3635.     if (pn==NULL) return;
  3636.     deleteTrees1(pn->left);
  3637.     deleteTrees1(pn->right);
  3638.     free((void *)pn);
  3639. }
  3640.  
  3641. void deleteTrees(PNODE pn)
  3642. {
  3643.     //fprintf(stderr,"\n pn==%08X",pn);getch();
  3644.     //if (pn>0) fprintf(stderr," pn->left==%08X pn->right==%08X",pn->left, pn->right);
  3645.     if (pn==NULL) return;
  3646.     deleteTrees(pn->left);
  3647.     deleteTrees(pn->right);
  3648.     if (pn->rcount>1) deleteTrees1((PNODE1)(pn->pos2));
  3649.     free((void *)pn);
  3650. }
  3651.  
  3652. extern PNODE rHead;
  3653.  
  3654. void deleteHeaders()
  3655. {
  3656. int   i;
  3657. PNODE *pps, *ppd;
  3658.  
  3659.     for (i=0; i<hsize; i++)
  3660.     {
  3661.         ppd=(PNODE *)(headerD+4*i);
  3662.         deleteTrees(*ppd);
  3663.         pps=(PNODE *)(headerS+4*i);
  3664.         deleteTrees(*pps);
  3665.     }
  3666.     deleteTrees(rHead);
  3667.     free((void *)headerD);
  3668.     free((void *)headerS);
  3669. }
  3670.  
  3671. // rewritten June 23, 1998 sangcho ... i really hope this will work.
  3672.  
  3673. _key_   my_key;
  3674. node    my_node;
  3675.  
  3676. PNODE1 searchTT1(PNODE1 base, DWORD pos)
  3677. {
  3678. PNODE1  s;
  3679.  
  3680.     if (base==NULL) return NULL;
  3681.     s=searchTT1(base->left, pos);
  3682.     if (s != NULL) return s;
  3683.     if (base->pos2 != 0) return base;
  3684.     s=searchTT1(base->right,pos);
  3685.     return s;
  3686. }
  3687.  
  3688.  
  3689. PNODE1 searchTT(PNODE1 base, DWORD pos1, DWORD pos2)
  3690. {
  3691. PNODE1  s;
  3692.     
  3693.     if (pos2==-1) return searchTT1(base, pos2);
  3694.     s = base;
  3695.     while (s != NULL && pos2 != s->pos2)
  3696.     {
  3697.         if (TOINT(pos2)<TOINT(s->pos2)) 
  3698.              s = s->left;
  3699.         else s = s->right;
  3700.     }
  3701.     return s;
  3702. }
  3703.  
  3704. PNODE searchT(PNODE base, DWORD pos1, DWORD pos2)
  3705. {
  3706. PNODE  s;
  3707. PNODE1 r;
  3708.  
  3709.     s = base;
  3710.     
  3711.     while (s != NULL && pos1 != s->pos1)
  3712.     {
  3713.         if (TOINT(pos1)<TOINT(s->pos1)) 
  3714.              s = s->left;
  3715.         else s = s->right;
  3716.     }
  3717.     if (s == NULL) return NULL;
  3718.     if (s->rcount==1 || pos2==0) return s;
  3719.  
  3720.     // this is dangerous place
  3721.     r=searchTT((PNODE1)(s->pos2), pos1, pos2);
  3722.     if (r == NULL) return NULL;
  3723.  
  3724.     my_node.pos1  =pos1;
  3725.     my_node.pos2  =r->pos2;
  3726.     my_node.rclass=r->rclass;
  3727.     my_node.rcount=1;
  3728.     return &my_node;
  3729. }
  3730.  
  3731. PNODE searchTree(LPVOID h, DWORD pos1, DWORD pos2)
  3732. {
  3733. int    pos;
  3734. PNODE *ppn;
  3735.  
  3736.     pos = pos1-imageBase;
  3737.     if (pos<0) pos=0;
  3738.     pos/=width;
  3739.     if (pos>=hsize) pos=hsize-1;
  3740.     ppn=(PNODE *)(h+4*pos);
  3741.     return searchT(*ppn, pos1, pos2);
  3742. }
  3743.  
  3744. PKEY searchBtree1(PKEY k)
  3745. {
  3746. PNODE t;
  3747.  
  3748.     if (k->class>0) t=searchTree(headerD, k->c_ref, k->c_pos);
  3749.     else t=searchTree(headerS, k->c_ref, k->c_pos);
  3750.     if (t==NULL) return NULL;
  3751.     my_key.class=t->rclass;
  3752.     my_key.c_ref=t->pos1;
  3753.     my_key.c_pos=t->pos2;
  3754.     return &my_key;
  3755. }
  3756.  
  3757. PKEY searchBtree3(PKEY k)
  3758. {
  3759. PNODE t;
  3760.  
  3761.     t=searchTree(headerD, k->c_ref, k->c_pos);
  3762.     if (t==NULL) return NULL;
  3763.     my_key.class=t->rclass;
  3764.     my_key.c_ref=t->pos1;
  3765.     my_key.c_pos=t->pos2;
  3766.     return &my_key;
  3767. }
  3768.  
  3769. extern PNODE headerX;
  3770.  
  3771. PKEY searchBtreeX(PKEY k)
  3772. {
  3773. PNODE t;
  3774.  
  3775.     t=searchT(headerX, k->c_ref, k->c_pos);
  3776.     if (t==NULL) return NULL;
  3777.     my_key.class=t->rclass;
  3778.     my_key.c_ref=t->pos1;
  3779.     my_key.c_pos=t->pos2;
  3780.     return &my_key;
  3781. }
  3782.  
  3783. int  referCount(DWORD ref)
  3784. {
  3785. PNODE t;
  3786.  
  3787.     t = searchTree(headerD, ref, 0);
  3788.     if (t==NULL) return 0;
  3789.     return t->rcount;
  3790. }
  3791.  
  3792. int  referCount1(DWORD ref)
  3793. {
  3794. PNODE t;
  3795.  
  3796.     t = searchTree(headerS, ref, 0);
  3797.     if (t==NULL) return 0;
  3798.     return t->rcount;
  3799. }
  3800.  
  3801. int insertTree(LPVOID h, int class, DWORD pos1, DWORD pos2)
  3802. {
  3803. int   pos;
  3804. PNODE *ppn;
  3805.  
  3806.     //fprintf(stderr,"\nHERE 1 c=%3d r=%08X p=%08X",class,pos1,pos2),getch();
  3807.     
  3808.     pos = pos1-imageBase;
  3809.     if (pos<0) pos=0;
  3810.     pos/=width;
  3811.     if (pos>=hsize) pos=hsize-1;
  3812.     ppn=(PNODE *)(h+4*pos);
  3813.     return insertT(ppn, class, pos1, pos2);
  3814. }
  3815.  
  3816. PNODE headerX=NULL;
  3817.  
  3818. int MyBtreeInsertX(PKEY k)
  3819. {
  3820.     return insertT(&headerX, k->class, k->c_ref, k->c_pos);
  3821.     return 1;
  3822. }
  3823.  
  3824.  
  3825. int MyBtreeInsert(PKEY k)
  3826. {
  3827.     //fprintf(stderr,"\nHERE 0 c=%3d r=%08X p=%08X",k->class,k->c_ref,k->c_pos),getch();
  3828.     
  3829.     if (k->class>0) 
  3830.          return insertTree(headerD, k->class, k->c_ref, k->c_pos);
  3831.     else return insertTree(headerS, k->class, k->c_ref, k->c_pos);
  3832.     return 1;
  3833. }
  3834.  
  3835. int  MyBtreeInsertEx(PKEY k)
  3836. {
  3837. //_key_    key;
  3838.  
  3839.     MyBtreeInsert(k);
  3840.     return 1;
  3841. }
  3842.  
  3843.  
  3844. int deleteTree(LPVOID h, DWORD pos1, DWORD pos2)
  3845. {
  3846. int   pos;
  3847. PNODE *ppn;
  3848.  
  3849.     pos = pos1-imageBase;
  3850.     if (pos<0) pos=0;
  3851.     pos/=width;
  3852.     if (pos>=hsize)pos=hsize-1;
  3853.     ppn=(PNODE *)(h+4*pos);
  3854.     return deleteT(ppn, pos1, pos2);
  3855. }
  3856.  
  3857. // i can refuse to be deleted provied that reference count is big enough.
  3858. int  MyBtreeDelete(PKEY k)
  3859. {
  3860.     
  3861.     if (k->class>0)
  3862.          return deleteTree(headerD, k->c_ref, k->c_pos);
  3863.     else return deleteTree(headerS, k->c_ref, k->c_pos);
  3864.     return 1;
  3865. }
  3866.  
  3867. int   sortCol=0;
  3868.  
  3869. int sortT(PNODE1 pn, DWORD pos1)
  3870. {
  3871.     if (pn==NULL) return 0;
  3872.     sortT(pn->left, pos1);
  3873.     printf("%4d:%08X<%08X,", pn->rclass, (int)pos1, (int)(pn->pos2));
  3874.     if(sortCol++ % 4==0)printf("\n");
  3875.     sortT(pn->right, pos1);
  3876.     return 1;
  3877. }
  3878.  
  3879.  
  3880. int sortTree(PNODE pn)
  3881. {
  3882.     if (pn==NULL) return 0;
  3883.     sortTree(pn->left);
  3884.     if (pn->rcount>1) sortT((PNODE1)(pn->pos2), pn->pos1);
  3885.     if (pn->rcount==1){
  3886.     printf("%4d:%08X<%08X,", pn->rclass, (int)(pn->pos1), (int)(pn->pos2));
  3887.     if(sortCol++ % 4==0)printf("\n");}
  3888.     sortTree(pn->right);
  3889.     return 1;
  3890. }
  3891.  
  3892. int sortTrees()
  3893. {
  3894. int   i;
  3895. PNODE *ppd;
  3896.     
  3897.     for (i=0; i<hsize; i++)
  3898.     {
  3899.         ppd=(PNODE *)(headerD+4*i);
  3900.         sortTree(*ppd);
  3901.     }
  3902.     return 1;
  3903. }
  3904.  
  3905. int sortTrees1()
  3906. {
  3907. int   i;
  3908. PNODE *ppd;
  3909.     
  3910.     for (i=0; i<hsize; i++)
  3911.     {
  3912.         ppd=(PNODE *)(headerS+4*i);
  3913.         sortTree(*ppd);
  3914.     }
  3915.     return 1;
  3916. }
  3917.  
  3918. /*                                                           */
  3919. /*  RBTRSRCH.C  :  Red-Black tree Libaray                    */
  3920. /*                                                           */
  3921. /*                  Programmed By Lee,jaekyu                 */
  3922. /*                  modified   by Sang Cho                   */
  3923.  
  3924. node   my_node;
  3925.  
  3926.  
  3927. PNODE1 rotate1(PNODE1 *base, PNODE1 p, DWORD pos1, DWORD pos2)
  3928. {     /* single rotation */
  3929. PNODE1 child, gchild;
  3930.     
  3931.          if (p==NULL)        child=*base;
  3932.     else if (TOINT(pos2) < TOINT(p->pos2)) 
  3933.          child = p->left;
  3934.     else child = p->right;
  3935.     if (TOINT(pos2) < TOINT(child->pos2))
  3936.     {
  3937.         gchild = child->left;
  3938.         child->left = gchild->right;
  3939.         gchild->right = child;
  3940.     }
  3941.     else
  3942.     {
  3943.         gchild = child->right;
  3944.         child->right = gchild->left;
  3945.         gchild->left = child;
  3946.     }
  3947.          if (p==NULL)           *base    = gchild;
  3948.     else if (TOINT(pos2) < TOINT(p->pos2)) 
  3949.          p->left  = gchild;
  3950.     else p->right = gchild;
  3951.     return gchild;
  3952. }
  3953.  
  3954. PNODE rotate(PNODE *base, PNODE p, DWORD pos1, DWORD pos2)
  3955. {     /* single rotation */
  3956. PNODE child, gchild;
  3957.     
  3958.          if (p==NULL)        child=*base;
  3959.     else if (TOINT(pos1) < TOINT(p->pos1)) 
  3960.          child = p->left;
  3961.     else                                      
  3962.          child = p->right;
  3963.     if (TOINT(pos1) < TOINT(child->pos1))
  3964.     {
  3965.         gchild = child->left;
  3966.         child->left = gchild->right;
  3967.         gchild->right = child;
  3968.     }
  3969.     else
  3970.     {
  3971.         gchild = child->right;
  3972.         child->right = gchild->left;
  3973.         gchild->left = child;
  3974.     }
  3975.          if (p==NULL)           *base    = gchild;
  3976.     else if (TOINT(pos1) < TOINT(p->pos1)) 
  3977.          p->left  = gchild;
  3978.     else p->right = gchild;
  3979.     return gchild;
  3980. }
  3981.  
  3982. int  insertTT(PNODE1 *base, int class, DWORD pos1, DWORD pos2)
  3983. {
  3984.     PNODE1 t, p, g, gg;
  3985.     gg = g = p = NULL;
  3986.     t = *base;
  3987.     while (t != NULL)
  3988.     {
  3989.         if (pos2 == t->pos2)  return 0;
  3990.  
  3991.         if (t->left && t->right && t->left->red && t->right->red)
  3992.         {
  3993.             t->red = 1;        /* color flip */
  3994.             t->left->red = t->right->red = 0;
  3995.             if (p && p->red && g)  /* rotation needed */
  3996.             {
  3997.                 g->red = 1;
  3998.                 if (TOINT(pos2) < TOINT(g->pos2) 
  3999.                  != TOINT(pos2) < TOINT(p->pos2))
  4000.                     p = rotate1(base, g, pos1, pos2);  /* double rotation */
  4001.                 t = rotate1(base, gg, pos1, pos2);
  4002.                 t->red = 0;
  4003.             }
  4004.             (*base)->red = 0;
  4005.         }    
  4006.         
  4007.         gg = g;      g = p;      p = t;
  4008.  
  4009.         if (TOINT(pos2) < TOINT(t->pos2))  
  4010.              t = t->left;
  4011.         else t = t->right;
  4012.     }
  4013.     if ((t = (PNODE1)calloc(sizeof(node1),1)) == NULL)
  4014.         return 0;
  4015.     t->pos2 = pos2;
  4016.     t->rclass = class;
  4017.     t->left = NULL;
  4018.     t->right = NULL;
  4019.            if (p==NULL)        *base = t;
  4020.     else if (TOINT(pos2) < TOINT(p->pos2)) 
  4021.          p->left = t;
  4022.     else p->right = t;
  4023.     t->red = 1;        /* paint color */
  4024.     if (p && p->red && g)  /* rotation needed */
  4025.     {
  4026.         g->red = 1;
  4027.         if (TOINT(pos2) < TOINT(g->pos2) != TOINT(pos2) < TOINT(p->pos2))
  4028.             p = rotate1(base, g, pos1, pos2);  /* double rotation */
  4029.         t = rotate1(base, gg, pos1, pos2);
  4030.         t->red = 0;
  4031.     }
  4032.     (*base)->red = 0;
  4033.     return 1;
  4034. }
  4035.  
  4036. int  insertSecond(PNODE t, int class, DWORD pos1, DWORD pos2)
  4037. {
  4038. DWORD   pos;
  4039.  
  4040.     if (t->pos2==pos2) return 0;
  4041.     if (t->rcount==1)
  4042.     {
  4043.         pos=t->pos2;
  4044.         t->pos2=0;
  4045.         insertTT((PNODE1*)&(t->pos2), t->rclass, pos1, pos);
  4046.         insertTT((PNODE1*)&(t->pos2), class, pos1, pos2);
  4047.         t->rcount=2;
  4048.         return 1;
  4049.     }
  4050.     if (insertTT((PNODE1*)&(t->pos2),class,pos1,pos2)) 
  4051.         { 
  4052.             t->rcount += 1; 
  4053.             return 1; 
  4054.         }
  4055.     return 0;
  4056. }
  4057.  
  4058. int  insertT(PNODE *base, int class, DWORD pos1, DWORD pos2)
  4059. {
  4060.     PNODE t, p, g, gg;
  4061.     gg = g = p = NULL;
  4062.     t = *base;
  4063.     while (t != NULL)
  4064.     {
  4065.         if (pos1==t->pos1) 
  4066.             return insertSecond(t, class, pos1, pos2); /* equal key */
  4067.         
  4068.         if (t->left && t->right && t->left->red && t->right->red)
  4069.         {
  4070.             t->red = 1;        /* color flip */
  4071.             t->left->red = t->right->red = 0;
  4072.             if (p && p->red && g)  /* rotation needed */
  4073.             {
  4074.                 g->red = 1;
  4075.                 if (TOINT(pos1) < TOINT(g->pos1) != TOINT(pos1) < TOINT(p->pos1))
  4076.                     p = rotate(base, g, pos1, pos2);  /* double rotation */
  4077.                 t = rotate(base, gg, pos1, pos2);
  4078.                 t->red = 0;
  4079.             }
  4080.             (*base)->red = 0;
  4081.         }    
  4082.         
  4083.         gg = g;      g = p;      p = t;
  4084.  
  4085.         if (TOINT(pos1) < TOINT(t->pos1))  t = t->left;
  4086.         else                               t = t->right;
  4087.     }
  4088.     if ((t = (PNODE)calloc(sizeof(node),1)) == NULL)
  4089.         return 0;
  4090.     t->pos1 = pos1;
  4091.     t->pos2 = pos2;
  4092.     t->rclass = class;
  4093.     t->rcount = 1;
  4094.     t->left = NULL;
  4095.     t->right = NULL;
  4096.          if (p == NULL)      *base = t;
  4097.     else if (TOINT(pos1) < TOINT(p->pos1)) p->left = t;
  4098.     else                                   p->right = t;
  4099.     t->red = 1;        /* paint color */
  4100.     if (p && p->red && g)  /* rotation needed */
  4101.     {
  4102.         g->red = 1;
  4103.         if (TOINT(pos1) < TOINT(g->pos1) != TOINT(pos1) < TOINT(p->pos1))
  4104.             p = rotate(base, g, pos1, pos2);  /* double rotation */
  4105.         t = rotate(base, gg, pos1, pos2);
  4106.         t->red = 0;
  4107.     }
  4108.     (*base)->red = 0;
  4109.     return 1;
  4110. }
  4111.  
  4112. PNODE1 findSeed1(PNODE1 *base, DWORD pos1, DWORD pos2)
  4113. {
  4114. PNODE1    del, seed_parent, parent;
  4115.     seed_parent = NULL;
  4116.     parent = NULL;
  4117.     del = (*base);
  4118.     while (del != NULL)
  4119.     {
  4120.         if (TOINT(pos2) < TOINT(del->pos2))
  4121.         {
  4122.             if (del->red || (del->right && del->right->red))
  4123.                 seed_parent = parent;
  4124.             parent = del;
  4125.             del = del->left;
  4126.         }
  4127.         else
  4128.         {
  4129.             if (del->red || (del->left && del->left->red))
  4130.                 seed_parent = parent;
  4131.             parent = del;
  4132.             del = del->right;
  4133.         }
  4134.     }
  4135.     return seed_parent;
  4136. }
  4137.  
  4138.  
  4139. PNODE findSeed(PNODE *base, DWORD pos1, DWORD pos2)
  4140. {
  4141. PNODE    del, seed_parent, parent;
  4142.     seed_parent = NULL;
  4143.     parent = NULL;
  4144.     del = (*base);
  4145.     while (del != NULL)
  4146.     {
  4147.         if (TOINT(pos1) < TOINT(del->pos1))
  4148.         {
  4149.             if (del->red || (del->right && del->right->red))
  4150.                 seed_parent = parent;
  4151.             parent = del;
  4152.             del = del->left;
  4153.         }
  4154.         else
  4155.         {
  4156.             if (del->red || (del->left && del->left->red))
  4157.                 seed_parent = parent;
  4158.             parent = del;
  4159.             del = del->right;
  4160.         }
  4161.     }
  4162.     return seed_parent;
  4163. }
  4164.  
  4165. void make_leaf_red1(PNODE1 *base, DWORD pos1, DWORD pos2)
  4166. {
  4167.     PNODE1 seed_parent, seed, seed_child;
  4168.     seed_parent = findSeed1(base, pos1, pos2);
  4169.     if (seed_parent == NULL)
  4170.     {
  4171.         seed_parent = NULL;
  4172.         seed = *base;
  4173.         seed->red = 1;
  4174.     }
  4175.     else
  4176.     {
  4177.         if (seed_parent == NULL || TOINT(pos2) < TOINT(seed_parent->pos2))
  4178.             seed = seed_parent->left;
  4179.         else
  4180.             seed = seed_parent->right;
  4181.     }
  4182.     if (!seed->red)   /* sibling is red, reverse rotation */
  4183.     {
  4184.         if (TOINT(pos2) < TOINT(seed->pos2))  seed_child = seed->right;
  4185.         else                                  seed_child = seed->left;
  4186.         seed->red = 1;
  4187.         seed_child->red = 0;
  4188.         seed_parent = rotate1(base, seed_parent, pos1, seed_child->pos2);
  4189.     }
  4190.     while (seed->left && seed->right)
  4191.     {
  4192.         seed->red = 0;
  4193.         seed->right->red = seed->left->red = 1;
  4194.         if (TOINT(pos2) < TOINT(seed->pos2))
  4195.         {
  4196.             if ((seed->right->left  && seed->right->left->red) 
  4197.              || (seed->right->right && seed->right->right->red))
  4198.             {   /* reverse rotation needed! */
  4199.                 if (seed->right->left && seed->right->left->red)
  4200.                 {
  4201.                     seed->right->red = 0;
  4202.                     rotate1(base, seed, pos1, seed->right->left->pos2);
  4203.                 }
  4204.                 else
  4205.                     seed->right->right->red = 0;
  4206.                 rotate1(base, seed_parent, pos1, seed->right->pos2);
  4207.             }
  4208.             seed_parent = seed;
  4209.             seed = seed->left;
  4210.         }
  4211.         else
  4212.         {
  4213.             if ((seed->left->left  && seed->left->left->red) 
  4214.              || (seed->left->right && seed->left->right->red))
  4215.             {
  4216.                 if (seed->left->right && seed->left->right->red)
  4217.                 {
  4218.                     seed->left->red = 0;
  4219.                     rotate1(base, seed, pos1, seed->left->right->pos2);
  4220.                 }
  4221.                 else
  4222.                     seed->left->left->red = 0;
  4223.                 rotate1(base, seed_parent, pos1, seed->left->pos2);
  4224.             }
  4225.             seed_parent = seed;
  4226.             seed = seed->right;
  4227.         }
  4228.     }
  4229. }
  4230.  
  4231.  
  4232. void make_leaf_red(PNODE *base, DWORD pos1, DWORD pos2)
  4233. {
  4234.     PNODE seed_parent, seed, seed_child;
  4235.     seed_parent = findSeed(base, pos1, pos2);
  4236.     if (seed_parent == NULL)
  4237.     {
  4238.         seed_parent = NULL;
  4239.         seed = *base;
  4240.         seed->red = 1;
  4241.     }
  4242.     else
  4243.     {
  4244.         if (TOINT(pos1) < TOINT(seed_parent->pos1))
  4245.             seed = seed_parent->left;
  4246.         else
  4247.             seed = seed_parent->right;
  4248.     }
  4249.     if (!seed->red)   /* sibling is red, reverse rotation */
  4250.     {
  4251.         if (TOINT(pos1) < TOINT(seed->pos1))  seed_child = seed->right;
  4252.         else                                  seed_child = seed->left;
  4253.         seed->red = 1;
  4254.         seed_child->red = 0;
  4255.         seed_parent = rotate(base, seed_parent, seed_child->pos1, pos2);
  4256.     }
  4257.     while (seed->left && seed->right)
  4258.     {
  4259.         seed->red = 0;
  4260.         seed->right->red = seed->left->red = 1;
  4261.         if (TOINT(pos1) < TOINT(seed->pos1))
  4262.         {
  4263.             if ((seed->right->left  && seed->right->left->red) 
  4264.              || (seed->right->right && seed->right->right->red))
  4265.             {   /* reverse rotation needed! */
  4266.                 if (seed->right->left && seed->right->left->red)
  4267.                 {
  4268.                     seed->right->red = 0;
  4269.                     rotate(base, seed, seed->right->left->pos1, pos2);
  4270.                 }
  4271.                 else
  4272.                     seed->right->right->red = 0;
  4273.                 rotate(base, seed_parent, seed->right->pos1, pos2);
  4274.             }
  4275.             seed_parent = seed;
  4276.             seed = seed->left;
  4277.         }
  4278.         else
  4279.         {
  4280.             if ((seed->left->left  && seed->left->left->red) 
  4281.              || (seed->left->right && seed->left->right->red))
  4282.             {
  4283.                 if (seed->left->right && seed->left->right->red)
  4284.                 {
  4285.                     seed->left->red = 0;
  4286.                     rotate(base, seed, seed->left->right->pos1, pos2);
  4287.                 }
  4288.                 else
  4289.                     seed->left->left->red = 0;
  4290.                 rotate(base, seed_parent, seed->left->pos1, pos2);
  4291.             }
  4292.             seed_parent = seed;
  4293.             seed = seed->right;
  4294.         }
  4295.     }
  4296. }
  4297.  
  4298. int  deleteTT(PNODE1 *base, DWORD pos1, DWORD pos2)
  4299. {
  4300. PNODE1  parent, del, center, pcenter, son;
  4301.     parent = NULL;
  4302.     del = (*base);
  4303.     while (del && TOINT(pos2) < TOINT(del->pos2))
  4304.     {
  4305.         parent = del;
  4306.         if (TOINT(pos2) < TOINT(del->pos2))  del = del->left;
  4307.         else                                 del = del->right;
  4308.     }
  4309.     if (del == NULL) return 0;  /* can't find */
  4310.     if (del->pos2!=pos2)return 0;
  4311.  
  4312.     if (del->right && del->left)
  4313.     {
  4314.         pcenter = del;
  4315.         center = del->right;
  4316.         while (center->left != NULL)
  4317.         {
  4318.             pcenter = center;
  4319.             center = center->left;
  4320.         }
  4321.         
  4322.         del->pos2  =center->pos2;
  4323.         del->rclass=center->rclass;
  4324.         del = center;
  4325.         parent = pcenter;
  4326.         pos2   = del->pos2;
  4327.     }
  4328.     if (del->left || del->right)
  4329.     {  /* one child must be red */
  4330.         if (del->left)  son = del->left;
  4331.         else            son = del->right;
  4332.         son->red = 0;
  4333.     }
  4334.     else if (del->left == NULL && del->right == NULL)
  4335.     {  /* leaf node */
  4336.         if (!del->red) make_leaf_red1(base, pos1, del->pos2);
  4337.         son = NULL;
  4338.     }
  4339.     (*base)->red = 0;
  4340.          if (parent == NULL) *base=son;
  4341.     else if (TOINT(pos2) < TOINT(parent->pos2))
  4342.          parent->left = son;
  4343.     else parent->right = son;
  4344.     free(del);
  4345.   
  4346.     return 1;
  4347. }
  4348.  
  4349.  
  4350. int  deleteT(PNODE *base, DWORD pos1, DWORD pos2)
  4351. {
  4352. PNODE  parent, del, center, pcenter, son;
  4353. int    i;
  4354.     parent = NULL;
  4355.     del = (*base);
  4356.     while (del && TOINT(pos1) < TOINT(del->pos1))
  4357.     {
  4358.         parent = del;
  4359.         if ((int)pos1 < (int)(del->pos1))  del = del->left;
  4360.         else                               del = del->right;
  4361.     }
  4362.     if (del == NULL) return 0;  /* can't find */
  4363.     if (del->pos1!=pos1) return 0;
  4364.     // anyway found it
  4365.     
  4366.     if (del->rcount>1) 
  4367.     {
  4368.          i=deleteTT((PNODE1*)&(del->pos2), pos1, pos2);
  4369.          if(i>0) del->rcount-=1;
  4370.          return 1;
  4371.     }
  4372.  
  4373.     if (del->right && del->left)
  4374.     {
  4375.         pcenter = del;
  4376.         center = del->right;
  4377.         while (center->left != NULL)
  4378.         {
  4379.             pcenter = center;
  4380.             center = center->left;
  4381.         }
  4382.         
  4383.         del->pos1   =center->pos1;
  4384.         del->pos2   =center->pos2;
  4385.         del->rclass =center->rclass;
  4386.         del->rcount =center->rcount;
  4387.         del = center;
  4388.         parent = pcenter;
  4389.            pos1   = del->pos1;
  4390.         pos2   = del->pos2;
  4391.     }
  4392.     if (del->left || del->right)
  4393.     {  /* one child must be red */
  4394.         if (del->left)  son = del->left;
  4395.         else            son = del->right;
  4396.         son->red = 0;
  4397.     }
  4398.     else if (del->left == NULL && del->right == NULL)
  4399.     {  /* leaf node */
  4400.         if (!del->red) make_leaf_red(base, del->pos1, pos2);
  4401.         son = NULL;
  4402.     }
  4403.     (*base)->red = 0;
  4404.          if (parent == NULL) *base=son;
  4405.     else if (TOINT(pos1) < TOINT(parent->pos1))
  4406.          parent->left = son;
  4407.     else parent->right = son;
  4408.     free(del);
  4409.   
  4410.     return 1;
  4411. }
  4412.  
  4413. // Priority Queue routines
  4414.  
  4415. int  heapLTE(_labels x, _labels y)
  4416. {
  4417.     if (x.priority < y.priority) return 1;
  4418.     if (x.priority > y.priority) return 0;
  4419.     if (x.ref >= y.ref) return 1;
  4420.     return 0;
  4421. }
  4422.  
  4423. int  heapLT(_labels x, _labels y)
  4424. {
  4425.     if (x.priority < y.priority) return 1;
  4426.     if (x.priority > y.priority) return 0;
  4427.     if (x.ref > y.ref) return 1;
  4428.     return 0;
  4429. }
  4430.  
  4431. void initHeap()
  4432. {
  4433.     pArray[0].priority = INT_MAX;
  4434.     pArray[0].ref      = 0;
  4435.     jLc = 0;  
  4436. }
  4437.  
  4438. int upHeap(_labels a[], int k)
  4439. {
  4440. _labels   v;
  4441.     //fprintf(stderr,"u");
  4442.     v = a[k];
  4443.     while(heapLTE(a[k/2],v))
  4444.     {
  4445.         a[k] = a[k/2];
  4446.         k /= 2;
  4447.     }
  4448.     a[k] = v;
  4449.     return k;
  4450. }
  4451.  
  4452. void downHeap(_labels a[], int n, int k)
  4453. {
  4454. _labels    v;
  4455. int        i;
  4456.  
  4457.     v = a[k];
  4458.     while(k <= n/2)
  4459.     {
  4460.         i = k + k;
  4461.         if (i < n && heapLT(a[i],a[i+1])) i++;
  4462.         if (heapLTE(a[i],v)) break;
  4463.         a[k] = a[i];
  4464.         k=i;
  4465.     }
  4466.     a[k] = v;
  4467. }
  4468.  
  4469.  
  4470.  
  4471. _labels  getHeap(int *n)
  4472. {
  4473.     _labels v = pArray[1];
  4474.     
  4475.     //fprintf(stderr,"g");
  4476.     pArray[1] = pArray[(*n)--];
  4477.     downHeap(pArray, *n, 1);
  4478.     return v;
  4479. }
  4480.  
  4481. int putHeap(int *n, int priority, DWORD ref)
  4482. {
  4483. int     i;
  4484.     //fprintf(stderr,"p");
  4485.     i=++(*n);    
  4486.     pArray[i].priority = priority;
  4487.     pArray[i].ref      = ref;
  4488.     return upHeap(pArray, i);
  4489. }
  4490.  
  4491. int getLabels()
  4492. {
  4493. _labels  v;
  4494. int      r;
  4495.     while(jLc>0)
  4496.     {
  4497.         v = getHeap(&jLc);
  4498.         r = v.ref;
  4499.         if (isGoodAddress(r)) return r;
  4500.     }
  4501.     return 1;
  4502. }
  4503.  
  4504. PNODE rHead=NULL;
  4505.  
  4506. void addRef(int c, DWORD r, DWORD p)
  4507. {
  4508.     insertT(&rHead, c, r, p);
  4509. }
  4510.  
  4511. int  countRef(DWORD r)
  4512. {
  4513. PNODE    t;
  4514.  
  4515.     t=searchT(rHead, r, 0);
  4516.     if (t==NULL) return 0;
  4517.     return t->rcount;
  4518. }
  4519.  
  4520. int addLabelsNum=0;
  4521. int addLabelsHistogram[256]={0,};
  4522. void addLabels(DWORD r, int pri)
  4523. {
  4524.     if (!isItFirstTime(r)) return;
  4525.     if (r<imageBase) return;
  4526.     putHeap(&jLc, pri, r);
  4527.     addLabelsHistogram[getByteFile(r)]+=1;
  4528.     /*
  4529.     if (r==debugAdd) 
  4530.     {    
  4531.         fprintf(stderr,"\nn=%d c=%08X b=%02X r=%08X pri=%4d nj=%d njN=%08X",
  4532.                 nextMode,cur_position,getByteFile(r),r,pri,needJump,needJumpNext);
  4533.         peekTrace();
  4534.         getch();
  4535.     }*/
  4536.     addLabelsNum++;
  4537.     setFirstTime(r);
  4538. }