home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser 1998 October / STC_CD_10_1998.iso / BASE / PD_PATCH / GET_ADDR.C < prev    next >
C/C++ Source or Header  |  1998-09-26  |  13KB  |  406 lines

  1. /*        Get_addr     V 1.02
  2.         (c) 1997 by Dimitri Junker
  3.             Adenauerallee 30
  4.             52066 Aachen    */
  5.             
  6. /* Dises Programm versucht, die für den Patch nötigen Adressen aus einer
  7. beliebigen PD Version zu ermitteln. */
  8. /* -------------------------------------------------------------------- */
  9. /*        Includes                                                        */
  10. /* -------------------------------------------------------------------- */
  11.  
  12. #include <stdio.h>
  13. #include "patch.h"
  14. #include "easyfsel.h"
  15.  
  16.  
  17.  
  18. /* -------------------------------------------------------------------- */
  19. /*         lokale Funktionsprototypen                                        */
  20. /* -------------------------------------------------------------------- */
  21.  
  22. void suche_rout1(long anz_word,unsigned int p_txt[]);
  23. long suche_dat_bss(unsigned int p_txt[],PH *ph);
  24. void suche_rout2(long anz_word,unsigned int p_txt[]);
  25. void set_namen(void);
  26. void schreiben(long pd_cfg,char *file_n);
  27.  
  28. /* -------------------------------------------------------------------- */
  29. /*        Globale Variablen                                                */
  30. /* -------------------------------------------------------------------- */
  31.  
  32. long Reset_any,Version_addr;
  33. PD_ROUT Pd_r[ANZ_ROUT],Pd_d[ANZ_DAT];
  34. char Flag[ANZ_ROUT],*Version_txt;
  35.  
  36. /* -------------------------------------------------------------------- */
  37. /*        Funktionen                                                        */
  38. /* -------------------------------------------------------------------- */
  39.  
  40.  
  41. int main(void)
  42. {    char file_n[250]="*.prg",dat_n[50];
  43.     unsigned int *p_txt;
  44.     FILE *F_in;
  45.     long p_len,pd_cfg;
  46.     PH ph;
  47.      get_akt_path(file_n);
  48.     memset(Flag,0,ANZ_ROUT);
  49.      dat_n[0]=0;
  50.     {    if(!easy_fsel(file_n,dat_n,"PD aussuchen"))
  51.             exit(0);
  52.         build_filename(file_n,file_n,dat_n);
  53.     }while((F_in=fopen(file_n,"rb"))==NULL);
  54.     if(!F_in )
  55.     {    form_alert( 2,"[1][Das angegebene File kann nicht|geöffnet werden][Abbruch]");
  56.         exit(0);
  57.     }
  58.     p_len=lof(F_in)-0x1c;
  59.     fseek(F_in,0,SEEK_SET);
  60.     fread(&ph,sizeof(PH),1,F_in);        /* Programmheader von PD.PRG laden */
  61.     if((p_txt=malloc(p_len))==NULL)
  62.     {    form_alert( 2,"[1][Nicht genug Speicher][Abbruch]");
  63.         exit(0);
  64.     }
  65.     fread(p_txt,1,p_len,F_in);                /* PD.PRG laden    */
  66.     suche_rout1(ph.ph_tlen/2l,p_txt);
  67.     pd_cfg=suche_dat_bss(p_txt,&ph);
  68.     suche_rout2(ph.ph_tlen/2l,p_txt);
  69.     set_namen();    
  70.     schreiben(pd_cfg,file_n);
  71.     return(0);
  72. }
  73.  
  74. /* Hier werden Routinen Anhand, zumindest bei mir, eindeutiger Sequenzen gesucht
  75.     Die Komentare haben folgende Bedeutung:
  76.         name    offs:    Inhalt        */
  77.  
  78. void suche_rout1(long anz_word,unsigned int p_txt[])
  79. {    long i,sys_rout;
  80.     for(i=0;i<anz_word;i++)
  81.     {    switch(p_txt[i])
  82.         {    case 0x14:            /*draw_menu    2a:    0014 322a 0016 302a    */
  83.                 if(p_txt[i+1]==0x322a && p_txt[i+2]==0x0016 && p_txt[i+3]==0x302a)
  84.                 {    Pd_r[DRAW_MENU].addr=i*2l-0x2al;
  85.                     Flag[DRAW_MENU]++;
  86.                 }
  87.                 break;
  88.             case 0x1a:            /*set_my_exc 10: 001a 3f03 3f3c 0005    */
  89.                 if(p_txt[i+1]==0x3f03 && p_txt[i+2]==0x3f3c && p_txt[i+3]==0x0005)
  90.                 {    Pd_r[SETMYEXC].addr=i*2l-0x10l;
  91.                     Flag[SETMYEXC]++;
  92.                 }
  93.                 break;
  94.             case 0x3e:            /*Fclose    c:    003e 4e41 584f 245f    */
  95.                 if(p_txt[i+1]==0x4e41 && p_txt[i+2]==0x584f && p_txt[i+3]==0x245f)
  96.                 {    Pd_r[FCLOSE].addr=i*2l-0xcl;
  97.                     Flag[FCLOSE]++;
  98.                 }
  99.                 break;
  100.             case 0x027c:        /* Bomben    8:    027c dfff 4ef9    */
  101.                 if(p_txt[i+1]==0xdfff && p_txt[i+2]==0x4ef9)
  102.                 {    Pd_r[BOMBEN].addr=i*2l-8l;
  103.                     Flag[BOMBEN]++;
  104.                 }
  105.                 break;
  106.             case 0x223c:        /* graf_handel    4:    223C 4D00 0500    */
  107.                 if(p_txt[i+1]==0x4D00 && p_txt[i+2]==0x0500)
  108.                 {    Pd_r[GRAF_HANDLE].addr=i*2l-4l;
  109.                     Flag[GRAF_HANDLE]++;
  110.                 }
  111.                 break;
  112.             case 0x2f08:        /* Set_Gd_trm    1e: 2f08 3f3c 0021*/
  113.                 if(p_txt[i+1]==0x3f3c && p_txt[i+2]==0x0021)
  114.                 {    Pd_r[SETGDT].addr=i*2l-0x1el;
  115.                     Flag[SETGDT]++;
  116.                 }
  117.                 break;
  118.             case 0x3f3c:    
  119.                 switch(p_txt[i+1])
  120.                 {    case 0x0044:    /* Mxalloc        6:    3F3C 0044 4E41    */
  121.                         if(p_txt[i+2]==0x4E41)
  122.                         {    Pd_r[MXALLOC].addr=i*2l-0x6l;
  123.                             Flag[MXALLOC]++;
  124.                         }
  125.                         break;
  126.                     case 0x0005:    /* Setscreen    8:    3F3C 0005 4E4E    */
  127.                         if(p_txt[i+2]==0x4E4E)
  128.                         {    Pd_r[SETSCREEN].addr=i*2l-0x8l;
  129.                             Flag[SETSCREEN]++;
  130.                         }
  131.                         break;
  132.                     case 0x0002:    /* Physbase        2:    3F3C 0002 4E4E    */
  133.                         if(p_txt[i+2]==0x4E4E)
  134.                         {    Pd_r[PHYSBASE].addr=i*2l-0x2l;
  135.                             Flag[PHYSBASE]++;
  136.                         }
  137.                         break;
  138.                     case 0x0003:    /* Logbase        2:    3F3C 0003 4E4E        */
  139.                         if(p_txt[i+2]==0x4E4E)
  140.                         {    Pd_r[LOGBASE].addr=i*2l-0x2l;
  141.                             Flag[LOGBASE]++;
  142.                         }
  143.                         break;
  144.                 }
  145.                 break;
  146.             case 0x4e68:    
  147.                 if(p_txt[i+1]==0x082f)
  148.                 {    switch(p_txt[i+6])
  149.                     {    case 0x000A:    /* Gemdos2    16: 4e68 082f und 22: 000A    */
  150.                             Pd_r[GEMDOS2].addr=i*2l-0x16l;
  151.                             Flag[GEMDOS2]++;
  152.                             break;
  153.                         case 0x000C:    /* Gemdos2a    16: 4e68 082f und 22: 000C    */
  154.                             Pd_r[GEMDOS2A].addr=i*2l-0x16l;
  155.                             Flag[GEMDOS2A]++;
  156.                             break;
  157.                     }
  158.                 }
  159.                 break;
  160.             case 0x6606:        /* Etv_term        16:    6606 40e7*/
  161.                 if(p_txt[i+1]==0x40e7)
  162.                 {    Pd_r[ETVTRM].addr=i*2l-0x16l;
  163.                     Flag[ETVTRM]++;
  164.                 }
  165.                 break;
  166.             case 0x701B:        /* esc_h_etc    8: 701B        10: 7048*/
  167.                 if( p_txt[i+4]==0x7048)
  168.                 {    Pd_r[ESC_H_ETC].addr=i*2l-0x8l;
  169.                     Flag[ESC_H_ETC]++;
  170.                 }
  171.                 break;
  172.             case 0x7073:        /* v_opnvwk        36:    7073 4E42*/
  173.                 if(p_txt[i+1]==0x4E42)
  174.                 {    Pd_r[V_OPNVWK].addr=i*2l-0x36l;
  175.                     Flag[V_OPNVWK]++;
  176.                 }
  177.                 break;
  178.             case 0x7265:        /* v_clsvwk        0:    7265 7400*/
  179.                 if(p_txt[i+1]==0x7400)
  180.                 {    Pd_r[V_CLSVWK].addr=i*2l;
  181.                     Flag[V_CLSVWK]++;
  182.                 }
  183.                 break;
  184.             case 0x7266:        /* vq_extnd        16:    7266 7401*/
  185.                 if(p_txt[i+1]==0x7401)
  186.                 {    Pd_r[VQ_EXTND].addr=i*2l-0x16l;
  187.                     Flag[VQ_EXTND]++;
  188.                 }
  189.                 break;
  190.             case 0x726D:        /* vro_cpyfm    16:    726D 243C 0004    */
  191.                 if(p_txt[i+1]==0x243C && p_txt[i+2]==0x0004)
  192.                 {    Pd_r[VRO_CPYFM].addr=i*2l-0x16l;
  193.                     Flag[VRO_CPYFM]++;
  194.                 }
  195.                 break;
  196.             case 0x727A:        /* v_show_c        6:    727A 7401*/
  197.                 if(p_txt[i+1]==0x7401)
  198.                 {    Pd_r[V_SHOW_C].addr=i*2l-6l;
  199.                     Flag[V_SHOW_C]++;
  200.                 }
  201.                 break;
  202.             case 0x727B:        /* v_hide_c    =    0:    727B 7400*/
  203.                 if(p_txt[i+1]==0x7400)
  204.                 {    Pd_r[V_HIDE_C].addr=i*2l;
  205.                     Flag[V_HIDE_C]++;
  206.                 }
  207.                 break;
  208.             case 0x727C:        /* vq_mouse    4:    727C 7400*/
  209.                 if(p_txt[i+1]==0x7400)
  210.                 {    Pd_r[VQ_MOUSE].addr=i*2l-4l;
  211.                     Flag[VQ_MOUSE]++;
  212.                 }
  213.                 break;
  214.         }
  215.     }
  216.     /* Die folgenden Routinen können direkt aus der Adresse von set_my_exc
  217.         abgeleitet werden    */
  218.  
  219.     sys_rout=Pd_r[SETMYEXC].addr+0x2al;    /* ab hier steht Sprungtabelle für setexc    */
  220.     i=sys_rout/2l;
  221.     Pd_r[BOMB4].addr    =sys_rout+(long)*((int *)&p_txt[i+ 4l]);
  222.     Pd_r[NOPRIV].addr    =sys_rout+(long)*((int *)&p_txt[i+ 8l]);
  223.     Pd_r[TRACE].addr    =sys_rout+(long)*((int *)&p_txt[i+ 9l]);
  224.     Pd_r[LINEA].addr    =sys_rout+(long)*((int *)&p_txt[i+10l]);
  225.     Pd_r[AESVDI].addr    =sys_rout+(long)*((int *)&p_txt[i+34l]);
  226.     Pd_r[TOS1].addr    =sys_rout+(long)*((int *)&p_txt[i+46l])+6l;    /* direkt hinter XBIOS    */
  227.     Flag[BOMB4]=Flag[NOPRIV]=Flag[TRACE]=Flag[LINEA]=Flag[AESVDI]=Flag[TOS1]=1;
  228.  
  229. }
  230. /* Hier werden die Adressen zu Daten gesucht (DATA +BSS) 
  231. DATA dadurch, das der Inhalt gesucht wird,
  232. BSS durch Zugriffe in bereits bekannten Routinen*/
  233.  
  234. long suche_dat_bss(unsigned int p_txt[],PH *ph)
  235. {    long i,pd_cfg;
  236.     char *p_txtc,*p_datc;
  237.     p_txtc=(char *)p_txt;
  238.     p_datc=&p_txtc[ph->ph_tlen];
  239.     /* Datas suchen    */
  240.     for(i=0;i<ph->ph_dlen;i++)
  241.     {    switch(p_datc[i])
  242.         {    case 'P':
  243.                 if(!strcmp(&p_datc[i],"PD.CFG"))
  244.                     pd_cfg=ph->ph_tlen+i;
  245.                 break;
  246.             case 'U':        
  247.                 if(!strcmp(&p_datc[i],"User program not yet terminated|Reset program anyway?"))
  248.                     Reset_any=ph->ph_tlen+i;
  249.                 break;
  250.             case 'V':        
  251.                 if(!strncmp(&p_datc[i],"Version",7))
  252.                 {    Version_addr=ph->ph_tlen+i;
  253.                     Version_txt=&p_datc[i];
  254.                 }
  255.                 break;
  256.  
  257.         }
  258.     }
  259.     /* BSS bestimmen    */
  260.     Pd_d[B_2AD06].addr=*((long *)&p_txtc[Pd_r[SETGDT].addr+0x14l]);
  261.     Pd_d[B_2BE54].addr=*((long *)&p_txtc[Pd_r[SETGDT].addr+0x4l]);
  262.     Pd_d[B_2BE60].addr=*((long *)&p_txtc[Pd_r[SETGDT].addr+0xal]);
  263.     Pd_d[PTRGEMD].addr=*((long *)&p_txtc[Pd_r[SETGDT].addr+0x2el]);
  264.     Pd_d[PTRTERM].addr=*((long *)&p_txtc[Pd_r[SETGDT].addr+0x44l]);
  265.     Pd_d[ANZBOMB].addr=*((long *)&p_txtc[Pd_r[BOMB4].addr+0xcl]);
  266.     Pd_d[ORSR46].addr=*((long *)&p_txtc[Pd_r[TOS1].addr-0x4l]);
  267.     Pd_d[ORSR45].addr=Pd_d[ORSR46].addr-4l;
  268.     Pd_d[ORSR33].addr=Pd_d[ORSR45].addr-48l;
  269.     return(pd_cfg);
  270. }
  271. /* wie suche_rout1, allerdings werden bereits vorher bestimmte Adressen benötigt*/
  272.  
  273. void suche_rout2(long anz_word,unsigned int p_txt[])
  274. {    long i;
  275.     for(i=0;i<anz_word;i++)
  276.     {    switch(p_txt[i])
  277.         {    case 0x2f39:        /*J_or_gem    0:    2f39 Ptr_Gemd*/
  278.                 if( *(long *)&p_txt[i+1] ==Pd_d[PTRGEMD].addr &&p_txt[i+3] ==0x4e75)
  279.                 {    Pd_r[JMPGEMD].addr=i*2l;
  280.                     Flag[JMPGEMD]++;
  281.                 }
  282.                 break;
  283.             case 0x41f9:        /*reset        12: 41f9 reset_any*/
  284.                 if( *(long *)&p_txt[i+1] ==Reset_any )
  285.                 {    Pd_r[RESET].addr=i*2l-0x12l;
  286.                     Flag[RESET]++;
  287.                     Pd_r[RESET_A].addr=Pd_r[RESET].addr+10l;
  288.                     Flag[RESET_A]++;
  289.                     Pd_d[B_23E58].addr=*(long *)&p_txt[i-7l];
  290.                 }
  291.                 break;
  292.             case 0x4eb9:        /* jsr*/
  293.                 switch(p_txt[i+3])
  294.                 {    case 0x4e75:
  295.                         if( *(long *)&p_txt[i+1] ==Pd_r[V_SHOW_C].addr)    /*Show_curs    10:    4eb9 v_show_c.l 4e75 */
  296.                         {    Pd_r[SHOW_CURS].addr=i*2l-0x10l;
  297.                             Flag[SHOW_CURS]++;
  298.                         }
  299.                         if( *(long *)&p_txt[i+1] ==Pd_r[V_HIDE_C].addr)    /*Hide_curs    16:    4eb9 v_hide_c.l 4e75 */
  300.                         {    Pd_r[HIDE_CURS].addr=i*2l-0x16l;
  301.                             Flag[HIDE_CURS]++;
  302.                         }
  303.                         break;
  304. /*                    case 0x2548:
  305.                         if( *(long *)&p_txt[i+1] ==Pd_r[PHYSBASE].addr && p_txt[i-3] == 0x45f9)
  306.                             /*Bilds_0    -6:    45f9 Bilds_0.l 4eb9 Physbase.l 2548 */
  307.                             Pd_d[BILDS_2].addr=(*(long *)&p_txt[i-2])+8;
  308.                         break;
  309. */                        
  310.                         
  311.                 }
  312.                 break;
  313.         }
  314.     }
  315. }
  316. /* Setzen der Namen in den Feldern Pd_r, Pd_d    */
  317. void set_namen(void)
  318. {    strcpy(Pd_r[V_OPNVWK].name,"v_opnvwk");
  319.     strcpy(Pd_r[GRAF_HANDLE].name,"graf_handle");
  320.     strcpy(Pd_r[PHYSBASE].name,"Physbase");
  321.     strcpy(Pd_r[LOGBASE].name,"Logbase");
  322.     strcpy(Pd_r[VQ_EXTND].name,"vq_extnd");
  323.     strcpy(Pd_r[V_CLSVWK].name,"v_clsvwk");
  324.     strcpy(Pd_r[SETSCREEN].name,"Setscreen");
  325.     strcpy(Pd_r[VQ_MOUSE].name,"vq_mouse");
  326.     strcpy(Pd_r[VRO_CPYFM].name,"vro_cpyfm");
  327.     strcpy(Pd_r[V_HIDE_C].name,"v_hide_c");
  328.     strcpy(Pd_r[HIDE_CURS].name,"hide_curs");
  329.     strcpy(Pd_r[V_SHOW_C].name,"v_show_c");
  330.     strcpy(Pd_r[SHOW_CURS].name,"show_curs");
  331.     strcpy(Pd_r[MXALLOC].name,"Mxalloc");
  332.     strcpy(Pd_r[FCLOSE].name,"Fclose");
  333.     strcpy(Pd_r[RESET].name,"prg_reset");
  334.     strcpy(Pd_r[RESET_A].name,"prg_reset_a");
  335.     strcpy(Pd_r[SETGDT].name,"Set_Gd_trm");
  336.     strcpy(Pd_r[ETVTRM].name,"Etv_term");
  337.     strcpy(Pd_r[JMPGEMD].name,"J_or_gem");
  338.     strcpy(Pd_r[BOMB4].name,"Bomb4");
  339.     strcpy(Pd_r[TRACE].name,"Trace");
  340.     strcpy(Pd_r[LINEA].name,"LineA");
  341.     strcpy(Pd_r[AESVDI].name,"AesVdi");
  342.     strcpy(Pd_r[NOPRIV].name,"NoPriv");
  343.     strcpy(Pd_r[BOMBEN].name,"Bomben");
  344.     strcpy(Pd_r[TOS1].name,"Tos1");
  345.     strcpy(Pd_r[SETMYEXC].name,"Set_my_exc");
  346.     strcpy(Pd_r[GEMDOS2].name,"Gemdos2");
  347.     strcpy(Pd_r[GEMDOS2A].name,"Gemdos2a");
  348.     strcpy(Pd_r[ESC_H_ETC].name,"esc_h_etc");
  349.     strcpy(Pd_r[DRAW_MENU].name,"draw_menu");
  350.     
  351.     strcpy(Pd_d[PTRTERM].name,"Ptr_term");
  352.     strcpy(Pd_d[ORSR33].name,"or_srout33");
  353.     strcpy(Pd_d[ORSR45].name,"or_srout45");
  354.     strcpy(Pd_d[ORSR46].name,"or_srout46");
  355.     strcpy(Pd_d[ANZBOMB].name,"AnzBomben");
  356.     strcpy(Pd_d[B_2AD06].name,"B_2AD06");
  357.     strcpy(Pd_d[B_2BE54].name,"B_2BE54");
  358.     strcpy(Pd_d[B_2BE60].name,"B_2BE60");
  359.     strcpy(Pd_d[B_23E58].name,"b_23E58");
  360.     strcpy(Pd_d[PTRGEMD].name,"Ptr_Gemd");
  361. /*    strcpy(Pd_d[BILDS_2].name,"Bilds_2");*/
  362. }
  363. /* Schreiben des H-Files für PATCH.CFG    */
  364.  
  365. void schreiben(long pd_cfg,char *file_n)
  366. {    int i,j=0;
  367.     char fehler[100],file_n_c[300];
  368.     FILE *fh;
  369.     fh=fopen("PD_ADDR.h","w");
  370.     fprintf(fh,"PD_ROUT Pd_r[ANZ_ROUT]={");
  371.     for(i=0;i<ANZ_ROUT;i++)
  372.     {    if(Flag[i]!=1)
  373.         {    sprintf(fehler,"[3][Die Routine %s|wurde %i mal gefunden][Weiter|Abbruch]",Pd_r[i].name,(int)Flag[i]);
  374.             Pd_r[i].addr=0l;
  375.             if(form_alert(1,fehler)==2)
  376.                 exit(0);
  377.         }
  378.         if(i<ANZ_ROUT-1)
  379.         {    fprintf(fh,"0x%lXl,\"%s\",",Pd_r[i].addr,Pd_r[i].name);
  380.             if(i%4==2)
  381.                 fprintf(fh,"\n\t");
  382.         }
  383.         else
  384.             fprintf(fh,"0x%lXl,\"%s\"};\n",Pd_r[ANZ_ROUT-1].addr,Pd_r[ANZ_ROUT-1].name);
  385.         
  386.     }
  387.     fprintf(fh,"PD_ROUT Pd_d[ANZ_DAT]={");
  388.     for(i=0;i<ANZ_DAT-1;i++)
  389.     {    fprintf(fh,"0x%lXl,\"%s\",",Pd_d[i].addr,Pd_d[i].name);
  390.         if(i%4==2)
  391.             fprintf(fh,"\n\t");
  392.     }
  393.     fprintf(fh,"0x%lXl,\"%s\"};\n",Pd_d[ANZ_DAT-1].addr,Pd_d[ANZ_DAT-1].name);
  394.     fprintf(fh,"long Pd_cfg=0x%lXl;\n",pd_cfg);
  395.     for(i=0;file_n[i];i++)
  396.     {    if(file_n[i]=='\\')
  397.             file_n_c[j++]='\\';
  398.         file_n_c[j++]=file_n[i];
  399.     }
  400.     file_n_c[j]='\0';
  401.     fprintf(fh,"char File_n[%li]=\"%s\";\n",strlen(file_n)+20,file_n_c);
  402.     fprintf(fh,"long Version_ptr=0x%lXl;\n",(long)Version_addr);
  403.     fprintf(fh,"char Version_txt[]=\"%s\";\n",Version_txt);
  404.     fclose(fh);
  405. }
  406.