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 >
Wrap
C/C++ Source or Header
|
1998-09-26
|
13KB
|
406 lines
/* Get_addr V 1.02
(c) 1997 by Dimitri Junker
Adenauerallee 30
52066 Aachen */
/* Dises Programm versucht, die für den Patch nötigen Adressen aus einer
beliebigen PD Version zu ermitteln. */
/* -------------------------------------------------------------------- */
/* Includes */
/* -------------------------------------------------------------------- */
#include <stdio.h>
#include "patch.h"
#include "easyfsel.h"
/* -------------------------------------------------------------------- */
/* lokale Funktionsprototypen */
/* -------------------------------------------------------------------- */
void suche_rout1(long anz_word,unsigned int p_txt[]);
long suche_dat_bss(unsigned int p_txt[],PH *ph);
void suche_rout2(long anz_word,unsigned int p_txt[]);
void set_namen(void);
void schreiben(long pd_cfg,char *file_n);
/* -------------------------------------------------------------------- */
/* Globale Variablen */
/* -------------------------------------------------------------------- */
long Reset_any,Version_addr;
PD_ROUT Pd_r[ANZ_ROUT],Pd_d[ANZ_DAT];
char Flag[ANZ_ROUT],*Version_txt;
/* -------------------------------------------------------------------- */
/* Funktionen */
/* -------------------------------------------------------------------- */
int main(void)
{ char file_n[250]="*.prg",dat_n[50];
unsigned int *p_txt;
FILE *F_in;
long p_len,pd_cfg;
PH ph;
get_akt_path(file_n);
memset(Flag,0,ANZ_ROUT);
dat_n[0]=0;
{ if(!easy_fsel(file_n,dat_n,"PD aussuchen"))
exit(0);
build_filename(file_n,file_n,dat_n);
}while((F_in=fopen(file_n,"rb"))==NULL);
if(!F_in )
{ form_alert( 2,"[1][Das angegebene File kann nicht|geöffnet werden][Abbruch]");
exit(0);
}
p_len=lof(F_in)-0x1c;
fseek(F_in,0,SEEK_SET);
fread(&ph,sizeof(PH),1,F_in); /* Programmheader von PD.PRG laden */
if((p_txt=malloc(p_len))==NULL)
{ form_alert( 2,"[1][Nicht genug Speicher][Abbruch]");
exit(0);
}
fread(p_txt,1,p_len,F_in); /* PD.PRG laden */
suche_rout1(ph.ph_tlen/2l,p_txt);
pd_cfg=suche_dat_bss(p_txt,&ph);
suche_rout2(ph.ph_tlen/2l,p_txt);
set_namen();
schreiben(pd_cfg,file_n);
return(0);
}
/* Hier werden Routinen Anhand, zumindest bei mir, eindeutiger Sequenzen gesucht
Die Komentare haben folgende Bedeutung:
name offs: Inhalt */
void suche_rout1(long anz_word,unsigned int p_txt[])
{ long i,sys_rout;
for(i=0;i<anz_word;i++)
{ switch(p_txt[i])
{ case 0x14: /*draw_menu 2a: 0014 322a 0016 302a */
if(p_txt[i+1]==0x322a && p_txt[i+2]==0x0016 && p_txt[i+3]==0x302a)
{ Pd_r[DRAW_MENU].addr=i*2l-0x2al;
Flag[DRAW_MENU]++;
}
break;
case 0x1a: /*set_my_exc 10: 001a 3f03 3f3c 0005 */
if(p_txt[i+1]==0x3f03 && p_txt[i+2]==0x3f3c && p_txt[i+3]==0x0005)
{ Pd_r[SETMYEXC].addr=i*2l-0x10l;
Flag[SETMYEXC]++;
}
break;
case 0x3e: /*Fclose c: 003e 4e41 584f 245f */
if(p_txt[i+1]==0x4e41 && p_txt[i+2]==0x584f && p_txt[i+3]==0x245f)
{ Pd_r[FCLOSE].addr=i*2l-0xcl;
Flag[FCLOSE]++;
}
break;
case 0x027c: /* Bomben 8: 027c dfff 4ef9 */
if(p_txt[i+1]==0xdfff && p_txt[i+2]==0x4ef9)
{ Pd_r[BOMBEN].addr=i*2l-8l;
Flag[BOMBEN]++;
}
break;
case 0x223c: /* graf_handel 4: 223C 4D00 0500 */
if(p_txt[i+1]==0x4D00 && p_txt[i+2]==0x0500)
{ Pd_r[GRAF_HANDLE].addr=i*2l-4l;
Flag[GRAF_HANDLE]++;
}
break;
case 0x2f08: /* Set_Gd_trm 1e: 2f08 3f3c 0021*/
if(p_txt[i+1]==0x3f3c && p_txt[i+2]==0x0021)
{ Pd_r[SETGDT].addr=i*2l-0x1el;
Flag[SETGDT]++;
}
break;
case 0x3f3c:
switch(p_txt[i+1])
{ case 0x0044: /* Mxalloc 6: 3F3C 0044 4E41 */
if(p_txt[i+2]==0x4E41)
{ Pd_r[MXALLOC].addr=i*2l-0x6l;
Flag[MXALLOC]++;
}
break;
case 0x0005: /* Setscreen 8: 3F3C 0005 4E4E */
if(p_txt[i+2]==0x4E4E)
{ Pd_r[SETSCREEN].addr=i*2l-0x8l;
Flag[SETSCREEN]++;
}
break;
case 0x0002: /* Physbase 2: 3F3C 0002 4E4E */
if(p_txt[i+2]==0x4E4E)
{ Pd_r[PHYSBASE].addr=i*2l-0x2l;
Flag[PHYSBASE]++;
}
break;
case 0x0003: /* Logbase 2: 3F3C 0003 4E4E */
if(p_txt[i+2]==0x4E4E)
{ Pd_r[LOGBASE].addr=i*2l-0x2l;
Flag[LOGBASE]++;
}
break;
}
break;
case 0x4e68:
if(p_txt[i+1]==0x082f)
{ switch(p_txt[i+6])
{ case 0x000A: /* Gemdos2 16: 4e68 082f und 22: 000A */
Pd_r[GEMDOS2].addr=i*2l-0x16l;
Flag[GEMDOS2]++;
break;
case 0x000C: /* Gemdos2a 16: 4e68 082f und 22: 000C */
Pd_r[GEMDOS2A].addr=i*2l-0x16l;
Flag[GEMDOS2A]++;
break;
}
}
break;
case 0x6606: /* Etv_term 16: 6606 40e7*/
if(p_txt[i+1]==0x40e7)
{ Pd_r[ETVTRM].addr=i*2l-0x16l;
Flag[ETVTRM]++;
}
break;
case 0x701B: /* esc_h_etc 8: 701B 10: 7048*/
if( p_txt[i+4]==0x7048)
{ Pd_r[ESC_H_ETC].addr=i*2l-0x8l;
Flag[ESC_H_ETC]++;
}
break;
case 0x7073: /* v_opnvwk 36: 7073 4E42*/
if(p_txt[i+1]==0x4E42)
{ Pd_r[V_OPNVWK].addr=i*2l-0x36l;
Flag[V_OPNVWK]++;
}
break;
case 0x7265: /* v_clsvwk 0: 7265 7400*/
if(p_txt[i+1]==0x7400)
{ Pd_r[V_CLSVWK].addr=i*2l;
Flag[V_CLSVWK]++;
}
break;
case 0x7266: /* vq_extnd 16: 7266 7401*/
if(p_txt[i+1]==0x7401)
{ Pd_r[VQ_EXTND].addr=i*2l-0x16l;
Flag[VQ_EXTND]++;
}
break;
case 0x726D: /* vro_cpyfm 16: 726D 243C 0004 */
if(p_txt[i+1]==0x243C && p_txt[i+2]==0x0004)
{ Pd_r[VRO_CPYFM].addr=i*2l-0x16l;
Flag[VRO_CPYFM]++;
}
break;
case 0x727A: /* v_show_c 6: 727A 7401*/
if(p_txt[i+1]==0x7401)
{ Pd_r[V_SHOW_C].addr=i*2l-6l;
Flag[V_SHOW_C]++;
}
break;
case 0x727B: /* v_hide_c = 0: 727B 7400*/
if(p_txt[i+1]==0x7400)
{ Pd_r[V_HIDE_C].addr=i*2l;
Flag[V_HIDE_C]++;
}
break;
case 0x727C: /* vq_mouse 4: 727C 7400*/
if(p_txt[i+1]==0x7400)
{ Pd_r[VQ_MOUSE].addr=i*2l-4l;
Flag[VQ_MOUSE]++;
}
break;
}
}
/* Die folgenden Routinen können direkt aus der Adresse von set_my_exc
abgeleitet werden */
sys_rout=Pd_r[SETMYEXC].addr+0x2al; /* ab hier steht Sprungtabelle für setexc */
i=sys_rout/2l;
Pd_r[BOMB4].addr =sys_rout+(long)*((int *)&p_txt[i+ 4l]);
Pd_r[NOPRIV].addr =sys_rout+(long)*((int *)&p_txt[i+ 8l]);
Pd_r[TRACE].addr =sys_rout+(long)*((int *)&p_txt[i+ 9l]);
Pd_r[LINEA].addr =sys_rout+(long)*((int *)&p_txt[i+10l]);
Pd_r[AESVDI].addr =sys_rout+(long)*((int *)&p_txt[i+34l]);
Pd_r[TOS1].addr =sys_rout+(long)*((int *)&p_txt[i+46l])+6l; /* direkt hinter XBIOS */
Flag[BOMB4]=Flag[NOPRIV]=Flag[TRACE]=Flag[LINEA]=Flag[AESVDI]=Flag[TOS1]=1;
}
/* Hier werden die Adressen zu Daten gesucht (DATA +BSS)
DATA dadurch, das der Inhalt gesucht wird,
BSS durch Zugriffe in bereits bekannten Routinen*/
long suche_dat_bss(unsigned int p_txt[],PH *ph)
{ long i,pd_cfg;
char *p_txtc,*p_datc;
p_txtc=(char *)p_txt;
p_datc=&p_txtc[ph->ph_tlen];
/* Datas suchen */
for(i=0;i<ph->ph_dlen;i++)
{ switch(p_datc[i])
{ case 'P':
if(!strcmp(&p_datc[i],"PD.CFG"))
pd_cfg=ph->ph_tlen+i;
break;
case 'U':
if(!strcmp(&p_datc[i],"User program not yet terminated|Reset program anyway?"))
Reset_any=ph->ph_tlen+i;
break;
case 'V':
if(!strncmp(&p_datc[i],"Version",7))
{ Version_addr=ph->ph_tlen+i;
Version_txt=&p_datc[i];
}
break;
}
}
/* BSS bestimmen */
Pd_d[B_2AD06].addr=*((long *)&p_txtc[Pd_r[SETGDT].addr+0x14l]);
Pd_d[B_2BE54].addr=*((long *)&p_txtc[Pd_r[SETGDT].addr+0x4l]);
Pd_d[B_2BE60].addr=*((long *)&p_txtc[Pd_r[SETGDT].addr+0xal]);
Pd_d[PTRGEMD].addr=*((long *)&p_txtc[Pd_r[SETGDT].addr+0x2el]);
Pd_d[PTRTERM].addr=*((long *)&p_txtc[Pd_r[SETGDT].addr+0x44l]);
Pd_d[ANZBOMB].addr=*((long *)&p_txtc[Pd_r[BOMB4].addr+0xcl]);
Pd_d[ORSR46].addr=*((long *)&p_txtc[Pd_r[TOS1].addr-0x4l]);
Pd_d[ORSR45].addr=Pd_d[ORSR46].addr-4l;
Pd_d[ORSR33].addr=Pd_d[ORSR45].addr-48l;
return(pd_cfg);
}
/* wie suche_rout1, allerdings werden bereits vorher bestimmte Adressen benötigt*/
void suche_rout2(long anz_word,unsigned int p_txt[])
{ long i;
for(i=0;i<anz_word;i++)
{ switch(p_txt[i])
{ case 0x2f39: /*J_or_gem 0: 2f39 Ptr_Gemd*/
if( *(long *)&p_txt[i+1] ==Pd_d[PTRGEMD].addr &&p_txt[i+3] ==0x4e75)
{ Pd_r[JMPGEMD].addr=i*2l;
Flag[JMPGEMD]++;
}
break;
case 0x41f9: /*reset 12: 41f9 reset_any*/
if( *(long *)&p_txt[i+1] ==Reset_any )
{ Pd_r[RESET].addr=i*2l-0x12l;
Flag[RESET]++;
Pd_r[RESET_A].addr=Pd_r[RESET].addr+10l;
Flag[RESET_A]++;
Pd_d[B_23E58].addr=*(long *)&p_txt[i-7l];
}
break;
case 0x4eb9: /* jsr*/
switch(p_txt[i+3])
{ case 0x4e75:
if( *(long *)&p_txt[i+1] ==Pd_r[V_SHOW_C].addr) /*Show_curs 10: 4eb9 v_show_c.l 4e75 */
{ Pd_r[SHOW_CURS].addr=i*2l-0x10l;
Flag[SHOW_CURS]++;
}
if( *(long *)&p_txt[i+1] ==Pd_r[V_HIDE_C].addr) /*Hide_curs 16: 4eb9 v_hide_c.l 4e75 */
{ Pd_r[HIDE_CURS].addr=i*2l-0x16l;
Flag[HIDE_CURS]++;
}
break;
/* case 0x2548:
if( *(long *)&p_txt[i+1] ==Pd_r[PHYSBASE].addr && p_txt[i-3] == 0x45f9)
/*Bilds_0 -6: 45f9 Bilds_0.l 4eb9 Physbase.l 2548 */
Pd_d[BILDS_2].addr=(*(long *)&p_txt[i-2])+8;
break;
*/
}
break;
}
}
}
/* Setzen der Namen in den Feldern Pd_r, Pd_d */
void set_namen(void)
{ strcpy(Pd_r[V_OPNVWK].name,"v_opnvwk");
strcpy(Pd_r[GRAF_HANDLE].name,"graf_handle");
strcpy(Pd_r[PHYSBASE].name,"Physbase");
strcpy(Pd_r[LOGBASE].name,"Logbase");
strcpy(Pd_r[VQ_EXTND].name,"vq_extnd");
strcpy(Pd_r[V_CLSVWK].name,"v_clsvwk");
strcpy(Pd_r[SETSCREEN].name,"Setscreen");
strcpy(Pd_r[VQ_MOUSE].name,"vq_mouse");
strcpy(Pd_r[VRO_CPYFM].name,"vro_cpyfm");
strcpy(Pd_r[V_HIDE_C].name,"v_hide_c");
strcpy(Pd_r[HIDE_CURS].name,"hide_curs");
strcpy(Pd_r[V_SHOW_C].name,"v_show_c");
strcpy(Pd_r[SHOW_CURS].name,"show_curs");
strcpy(Pd_r[MXALLOC].name,"Mxalloc");
strcpy(Pd_r[FCLOSE].name,"Fclose");
strcpy(Pd_r[RESET].name,"prg_reset");
strcpy(Pd_r[RESET_A].name,"prg_reset_a");
strcpy(Pd_r[SETGDT].name,"Set_Gd_trm");
strcpy(Pd_r[ETVTRM].name,"Etv_term");
strcpy(Pd_r[JMPGEMD].name,"J_or_gem");
strcpy(Pd_r[BOMB4].name,"Bomb4");
strcpy(Pd_r[TRACE].name,"Trace");
strcpy(Pd_r[LINEA].name,"LineA");
strcpy(Pd_r[AESVDI].name,"AesVdi");
strcpy(Pd_r[NOPRIV].name,"NoPriv");
strcpy(Pd_r[BOMBEN].name,"Bomben");
strcpy(Pd_r[TOS1].name,"Tos1");
strcpy(Pd_r[SETMYEXC].name,"Set_my_exc");
strcpy(Pd_r[GEMDOS2].name,"Gemdos2");
strcpy(Pd_r[GEMDOS2A].name,"Gemdos2a");
strcpy(Pd_r[ESC_H_ETC].name,"esc_h_etc");
strcpy(Pd_r[DRAW_MENU].name,"draw_menu");
strcpy(Pd_d[PTRTERM].name,"Ptr_term");
strcpy(Pd_d[ORSR33].name,"or_srout33");
strcpy(Pd_d[ORSR45].name,"or_srout45");
strcpy(Pd_d[ORSR46].name,"or_srout46");
strcpy(Pd_d[ANZBOMB].name,"AnzBomben");
strcpy(Pd_d[B_2AD06].name,"B_2AD06");
strcpy(Pd_d[B_2BE54].name,"B_2BE54");
strcpy(Pd_d[B_2BE60].name,"B_2BE60");
strcpy(Pd_d[B_23E58].name,"b_23E58");
strcpy(Pd_d[PTRGEMD].name,"Ptr_Gemd");
/* strcpy(Pd_d[BILDS_2].name,"Bilds_2");*/
}
/* Schreiben des H-Files für PATCH.CFG */
void schreiben(long pd_cfg,char *file_n)
{ int i,j=0;
char fehler[100],file_n_c[300];
FILE *fh;
fh=fopen("PD_ADDR.h","w");
fprintf(fh,"PD_ROUT Pd_r[ANZ_ROUT]={");
for(i=0;i<ANZ_ROUT;i++)
{ if(Flag[i]!=1)
{ sprintf(fehler,"[3][Die Routine %s|wurde %i mal gefunden][Weiter|Abbruch]",Pd_r[i].name,(int)Flag[i]);
Pd_r[i].addr=0l;
if(form_alert(1,fehler)==2)
exit(0);
}
if(i<ANZ_ROUT-1)
{ fprintf(fh,"0x%lXl,\"%s\",",Pd_r[i].addr,Pd_r[i].name);
if(i%4==2)
fprintf(fh,"\n\t");
}
else
fprintf(fh,"0x%lXl,\"%s\"};\n",Pd_r[ANZ_ROUT-1].addr,Pd_r[ANZ_ROUT-1].name);
}
fprintf(fh,"PD_ROUT Pd_d[ANZ_DAT]={");
for(i=0;i<ANZ_DAT-1;i++)
{ fprintf(fh,"0x%lXl,\"%s\",",Pd_d[i].addr,Pd_d[i].name);
if(i%4==2)
fprintf(fh,"\n\t");
}
fprintf(fh,"0x%lXl,\"%s\"};\n",Pd_d[ANZ_DAT-1].addr,Pd_d[ANZ_DAT-1].name);
fprintf(fh,"long Pd_cfg=0x%lXl;\n",pd_cfg);
for(i=0;file_n[i];i++)
{ if(file_n[i]=='\\')
file_n_c[j++]='\\';
file_n_c[j++]=file_n[i];
}
file_n_c[j]='\0';
fprintf(fh,"char File_n[%li]=\"%s\";\n",strlen(file_n)+20,file_n_c);
fprintf(fh,"long Version_ptr=0x%lXl;\n",(long)Version_addr);
fprintf(fh,"char Version_txt[]=\"%s\";\n",Version_txt);
fclose(fh);
}