/*
* Manipuler le checksum 16 bit et 32 bit d'un fichier executable
* sous windows/dos; peut facilement être adapté à la modification du checksum
*/
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
void Calc16ChkSum(FILE *fp);
void Calc32ChkSum(FILE *fp);
void main(int, char **);
FILE *fp; unsigned long NewHdrOffset, FileSize = 0L;
unsigned int PageCnt;
#define NEWHDROFFSET 0x3C /* Emplacement dans l'ancien header
avec offset du nouveau header dans l'exe */
void main (int argc, char * argv[])
{
if (argc != 2)
{
printf("\n\nUsage: %s \n\n", argv[0]);
exit(-1);
}
if ((fp = fopen(argv[1], "rb")) == NULL)
{
printf("\n\nErreur: impossible d'ouvrir : %s\n\n", argv[1]);
exit(-1);
}
fread(&PageCnt, sizeof(int), 1, fp); /* Lire après la signature */
fread(&PageCnt, sizeof(int), 1, fp); /* Lire la taille de la dèrnière page */
FileSize = PageCnt;
fread(&PageCnt, sizeof(int), 1, fp); /*Lire la page entière du compte */
if (FileSize == 0L)
FileSize = PageCnt * 512;
else
FileSize += (PageCnt - 1) * 512;
fseek(fp, NEWHDROFFSET, SEEK_SET); /* Retrouver le nouveau offsetde l'EXE */
fread(&NewHdrOffset, sizeof(long), 1, fp); /* et le lire */
if (NewHdrOffset == 0L)
Calc16ChkSum(fp);
else
Calc32ChkSum(fp);
fcloseall();
return;
}
void Calc16ChkSum(FILE *fp)
{
unsigned int sum16, NxtInt, x;
unsigned char NxtChar;
sum16 = 0;
fseek(fp, 0, SEEK_SET);
for (x = 0L; x < FileSize / 2L; x++)
{
fread(&NxtInt, sizeof(int), 1, fp);
sum16 += NxtInt;
}
/* Prendre le dernier octet si la taille est bizarre */
if (FileSize % 2)
{
fread(&NxtChar, sizeof(char), 1, fp);
sum16 += (unsigned int)NxtChar;
}
printf("\nLe checksum 16bit devrait etre FFFF, et il est %x\n\n",
sum16);
}
void Calc32ChkSum(FILE *fp)
{
unsigned long sum32, NxtLong, CheckSum32, x;
unsigned char NxtByte, y;
sum32 = 0;
fseek(fp, 0, SEEK_SET);
/* Caculer le nombre de DWords avant le checksum et les ajouter */
x = (NewHdrOffset + 8) / 4;
for ( ; x; x--)
{
fread(&NxtLong, sizeof(long), 1, fp);
sum32 += NxtLong;
}
/* Lire le checksum */
fread(&CheckSum32, sizeof(long), 1, fp);
/* Ensuite, le reste des DWord dans le fichier */
for (x = 0; x < (FileSize - NewHdrOffset - 12) / 4; x++)
{
fread(&NxtLong, sizeof(long), 1, fp);
sum32 += NxtLong;
}
/* On doit compter les octets en plus du fichier. Normalement, ils
forment un long avec les bits de poids fort à zéro
*/
if (0L != (x = FileSize % 4L))
{
NxtLong = 0L;
for (y = 0 ; y < x ; y++)
{
fread(&NxtByte, sizeof(char), 1, fp);
NxtLong += (unsigned long)NxtByte << (8 * y);
}
sum32 += NxtLong;
}
printf("\nLe checksum 32 bits devrait etre %lx, et il est %lx\n\n",
CheckSum32, sum32);
}
| l |