delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2005/07/23/10:31:11

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
From: "News Reader" <nospam AT aol DOT com>
Newsgroups: comp.os.msdos.djgpp
References: <1121967843 DOT 477491 DOT 69130 AT g49g2000cwa DOT googlegroups DOT com>
Subject: Re: Generating a CRC over a DJGPP programs binary code in memory?
Date: Sat, 23 Jul 2005 16:17:06 +0200
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.2527
X-RFC2646: Format=Flowed; Original
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2527
Lines: 149
Message-ID: <42e2520d$0$26470$91cee783@newsreader02.highway.telekom.at>
NNTP-Posting-Host: M2487P014.adsl.highway.telekom.at
X-Trace: 1122128398 newsreader02.highway.telekom.at 26470 212.183.42.206
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

In the following you can see an example as a reference what
you could do to perform CRC calcs (for whatever reason you
might require this). I have also included an example showing
a possibility to insert strings into the program code.

Programming style is not optimal. But that's all what I can
slice off my weekend.

The program was tested using GCC 4.00.
(Even optimisation level -O3 worked to my surprise.)


"Gundolf" <news1 AT vonbachhaus DOT net> wrote in message 
news:1121967843 DOT 477491 DOT 69130 AT g49g2000cwa DOT googlegroups DOT com...
> Hello all,
>
> Maybe someone can help me, I need to get an application to self-check
> that certain portions of its binary code haven't been altered once it
> has been started.
> To do that, I'd like to generate a CRC over the code between certain
> markers inserted into the binary code via something like "asm DB ..."
> (assuming there is an equivalent for that in DJGPP)
>
> ....................................
>
> Gundolf
>





#include <stdio.h>
#include <stdlib.h>

typedef unsigned char u8;

// ---> functions below are included in crc checking ...

void crcstart() {}

int addit(int a, int b) { return(a+b); }
int mulit(int a, int b) { return(a*b); }


/////////////////////////////////////////////////
// example for data (string) embedded in code
// (function header needs to be skipped)

void str1(void) {
  asm(".ascii \"ABC\"");   // GCC 4.00 bug: don't insert \0 here
  asm(".byte 0");          // ... use this instead
}


/////////////////////////////////////////////////
// displays contents of embedded data (string)

void showemb() {
  char* s=(char *)&str1;  // get function address

  // now we are using a simplified and "dirty" hack
  // to skip the function header:

  s+=3;

  printf("Embedded string: '%s'\n",s);
}


// ... crc is checked until before the following function <---

void nomorecrc() {}




////////////////////////////////////////////////////////////////
// this function checks the funtion addresses and does a
// crc calculation over the range to be checked
// (in this case "crc" is just done by just adding memory bytes)

int crccheck(size_t *crc) {
  size_t n;  u8* p;

  const size_t funu=6;
  u8 *ptarr[funu];

  ptarr[0]=(u8 *)&crcstart;
  ptarr[1]=(u8 *)&addit;
  ptarr[2]=(u8 *)&mulit;
  ptarr[3]=(u8 *)&str1;
  ptarr[4]=(u8 *)&nomorecrc;
  ptarr[5]=(u8 *)&nomorecrc;

  *crc=0xffffffff;  //set to arbitrary value prior to address checks

  for (n=1; n<funu; n++) {  // error if non-ascending addresses found
    if (ptarr[n-1]>ptarr[n]) return(0);
  }

  // calculate CRC
  for (*crc=0, p=ptarr[0]; p<ptarr[funu-1]; p++) *crc+=(*p);
  return(1);
}


int main() {
  int a=2, b=3;
  size_t crc0, crc1;

  puts("");
  if (!crccheck(&crc0)) {
    puts("Unfortunately the addresses of the to-be-checked");
    puts("functions are not ascending.");
    puts("Possible reason: compiler optimisation or");
    puts("unsuitable compiler. (Sorry mate!)");
    return(1);  // sadly exiting main() ...
  }

  printf("The first CRC check revealed a CRC value of");
  printf(" %lu\n\n",crc0);
  puts("First we'll display a string embedded in the source:");
  showemb();
  puts("");
  printf("Now we are ready to do some");
  printf(" high-performance calculations:\n\n");
  printf("The sum of a [%d] and b [%d] appears to be",a,b);
  printf(" %d ...\n",addit(a,b));
  printf("... while multiplying the values gives us");
  printf(" %d, ok?\n\n", mulit(a,b));
  puts("Now paranoia sets in. Did CPU and memory eventually");
  puts("overheat during that number-crunching?");
  puts("");
  printf("We'll check the CRC again -");
  crccheck(&crc1);  // we need crc1 but not the return value
  printf(" and what we are getting is %lu\n\n", crc1);

  if (crc0 == crc1)
    puts("*** The computer is healthy - CRC's are matching!");
  else
    puts("*** Desaster! Something has modified the code!");

  puts("");
  return(0);
}


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019