On Wed, 14 Apr 2004 15:26:47 +0400, Victor Nazarov <vv*****@mail.ru>
wrote:
RoSsIaCrIiLoIA wrote: Do you know how to write a self-checking program in standard C?
Do I can think that if I write in a file.c
static g[100]="1234567";
in the file.exe (or file) there is in some place
1234567'\0''\0''\0''\0''\0''\0''\0'...'\0'
I think you can. But it is out of Standard C scope.
But are there any system where this is not true?
This is my first attempt:
/* file.c -> file.exe */
#include <stdio.h>
#include <string.h>
char* estr(char* nome)
{
char *a = nome, *b;
char c;
if(nome == 0)
return 0;
while( 1 )
{b = a;
while( (c = *a) && c != '\\' && c != '/' )
what about c != '\0'
ok (c = *a)!=0
++a;
if(c == 0) break;
++a;
}
return b;
}
int main(int c, char** argv)
{
(void) c;
printf("I'm a self-checking program\n");
if(strncmp("dc.exe", estr(argv[0]), 6) != 0)
{printf("File corrupted\n"); return 0;}
Why do you think this garanties that file is corrupted? Why user
shouldn't rename files? If he shouldn't then you must consider that file
may had more than one name in some environments (hard and symbolic links).
I'm thinking some of this type:
/* my1.c */
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#define UNS unsigned
char* estr(char* nome)
{
char *a = nome, *b;
char c;
if(nome == 0)
return 0;
while( 1 )
{b = a;
while( (c = *a)!=0 && c!='\\' && c!='/' )
++a;
if(c == 0) break;
++a;
}
return b;
}
int info_p(char* );
int main(int c, char** argv)
{
if(c != 2)
{
if( c==0 || !argv[0] )
printf("Use:> this_prog prog\n");
else printf("Use:> %s prog[.exe]\n", estr(argv[0]));
return 0;
}
if( info_p( argv[1] )==0 )
{ printf("Not signed %s\n", estr(argv[1])); return 0;}
printf("Ok signed %s\n", estr(argv[1]));
return 0;
}
void printu(char* a)
{
int i;
for( i = 0; i < sizeof(UNS); ++i)
printf(" %d ", (int) a[i]);
}
int f(const char* a, FILE* fp)
{
int i, j;
for( i= 0, j= EOF + 1 ; i < sizeof(UNS) && j!=EOF; ++i)
j= fputc(a[i], fp);
return j;
}
int info_p(char* as)
{int c, r, k, cp;
FILE *fp;
unsigned count= 0, rox= 0, sum= 0, *p1, buffer= 0;
char acount[ sizeof(UNS) + 8 ] = {0},
arox [ sizeof(UNS) + 8 ] = {0},
asum [ sizeof(UNS) + 8 ] = {0};
char *pc1 = acount, *pc2 = arox, *pc3 = asum;
long ove;
if( (fp = fopen( as, "r+b"))==NULL )
{printf("Problemi di apertura\n");
return 0;
}
r = 0; cp = 0;
label:
while( (c = fgetc(fp))!=EOF && !(cp=='1' && c=='2') )
{
sum += c; ++count;
cp = c;
buffer = (buffer << CHAR_BIT) | ((UNS)(unsigned char) c);
if(count % sizeof(UNS) ==0)
rox = rox ^ buffer;
}
if( c!=EOF && r==0 )
{k = 2;
while( (c = fgetc(fp))!=EOF && c-'0'== ++k )
{sum += c; ++count;
cp = c;
buffer = (buffer << CHAR_BIT) | (UNS)((unsigned char) c);
if(count % sizeof(UNS) == 0)
rox = rox ^ buffer;
} /*34567*/
if( k==8 && c!=EOF )
{
if((ove = ftell( fp ))== -1)
{ printf("Error\n"); exit(0); }
printf("Find\n");
r=1;
}
else if(c != EOF) goto label;
else goto fine;
while( (c = fgetc(fp))!=EOF && k!=512 ) ++k;
if(c !=EOF) goto label;
}
if(c == EOF) goto fine;
goto label;
fine:
*(UNS*) pc1 = count; *(UNS*) pc2 = rox; *(UNS*) pc3 = sum;
if(r == 1)
{
fseek(fp, ove, SEEK_SET);
clearerr(fp);
if(f(acount, fp)==EOF || f(arox, fp)==EOF || f(asum, fp)==EOF)
{r=0; printf("Error in writing\n");}
}
fclose(fp);
printf("count=%u rox=%u sum=%u\n", count, rox, sum );
printf("String=%s%s%s\nIn_num=", acount, arox, asum);
printu(acount); printf("M") ;printu(arox);printf("M");
printu(asum) ; printf("\n");
return r;
}
/*end my1.c*/
____________________
/* ali.c */
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#define UNS unsigned
char* estr(char* nome)
{
char *a = nome, *b;
char c;
if(nome == 0)
return 0;
while( 1 )
{
b = a;
while( (c = *a)!=0 && c!='\\' && c!='/' ) ++a;
if(c == 0) break;
++a;
}
return b;
}
int info_p(char* );
int main(int c, char** argv)
{
printf("Start \n");
if( c==0 || !argv[0] )
return 0;
if( info_p(argv[0]) == 0 )
{ printf("File corrupted\n"); return 0; }
printf("oK continue\n");
return 0;
}
void printu(char* a)
{
int i;
for( i = 0 ; i < sizeof(UNS) ; ++i)
printf(" %d ", (int) a[i]);
}
int f(const char* a, FILE* fp)
{
int i, j;
for( i = 0 ; i < sizeof(UNS) ; ++i)
{
if( (j = fgetc( fp ))==EOF ) return 0;
if( j != (unsigned char) a[i]) return 0;
}
return 1;
}
/* ###### HERE WE HAVE TO WRITE ###### */
char al[512] = "1234567 ";
int info_p(char* as)
{
int l, c, r, k, cp;
FILE *fp;
unsigned count = 0, rox = 0, sum = 0, *p1, buffer = 0;
char acount[ sizeof(UNS) + 8 ] = {0},
arox [ sizeof(UNS) + 8 ] = {0},
asum [ sizeof(UNS) + 8 ] = {0};
char *pc1 = acount, *pc2 = arox, *pc3 = asum;
long ove;
if((fp = fopen( as, "rb"))==NULL)
{
printf("Problemi di apertura\n");
return 0;
}
r = 0; cp = 0;
label:
while((c = fgetc(fp))!=EOF && !(cp=='1' && c=='2'))
{
sum += c; ++count;
cp = c;
buffer = (buffer << CHAR_BIT) | ((UNS)(unsigned char) c);
if(count % sizeof(UNS) ==0)
rox = rox ^ buffer;
}
if(c!=EOF && r==0)
{
k = 2;
while((c = fgetc(fp))!=EOF && c== ++k + '0' )
{
sum += c; ++count;
cp = c;
buffer = (buffer << CHAR_BIT) | (UNS)((unsigned char) c);
if(count % sizeof(UNS) == 0)
rox = rox ^ buffer;
} /*34567*/
if(k==8 && c!=EOF)
{
if( (ove = ftell(fp)) == -1)
{ printf( "Error\n" ); exit( 0 ); }
r = 1;
}
else if(c != EOF) goto label;
else goto fine;
while((c = fgetc(fp))!=EOF && k!=512) ++k;
if(c !=EOF ) goto label;
}
if(c == EOF) goto fine;
goto label;
fine:
*(UNS*) pc1 = count; *(UNS*) pc2 = rox; *(UNS*) pc3 = sum;
if(r == 1){
fseek(fp, ove, SEEK_SET);
clearerr(fp);
if( f(acount, fp)==0 || f(arox, fp)==0 || f(asum, fp)==0 )
r = 0;
}
fclose(fp);
return r;
}
/*end ali.c*/
__________________
C:\b>ali
Start
File corrupted
C:\b>my1 ali.exe
Find
count=59909 rox=3806249208 sum=5559428
String=?Û°+ÌÔäÈT
In_num= 5 -22 0 0 M -8 -64 -34 -30 M -124 -44 84 0
Ok signed ali.exe
C:\b>ali
Start
oK continue
_______________
Are there errors?
Are there system where this doesn't run with success?