Copy Link
Add to Bookmark
Report
Cris Vol 1 Issue 14
-----BEGIN PGP SIGNED MESSAGE-----
Article Written for Crisnews
By: Michael Stowe
"Self-Protecting Executables" -- by Michael Stowe
Files which protect themselves are probably one of the most
effective weapons against virus spreading. A self-protecting
file is a file which tests itself when starting up and refuses to
run if it has been altered in any way. Often, self-protecting
files will provide the first clue that a virus infection has
occurred.
This article presents simple C source code which may be used in
any program to provide a program with an effective technique for
sensing its own integrity.
There are two components to the protection scheme; a standalone
program which determines an .EXE or .COM file's signature, and
"brands" the file with the signature, and a module to be compiled
into the executable file that verifies this signature.
First, the branding program. It uses a very simple checksum
technique to generate a signature. As you can see from the code,
it simply xor's each byte with its position in the file and
appends the total to the end. The code follows:
#include <stdio.h>
unsigned long int file_brand(char *name)
{
FILE *fin;
register c;
register long accum=0;
register long count=0;
int error=0;
if ((fin=fopen(name, "rb+"))==NULL) {
perror(name);
return ERROR;
}
while ((c=getc(fin))!=EOF) {
accum+=c^count++;
}
fseek(fin, 0, SEEK_END);
fwrite(&accum, sizeof(long), 1, fin);
if (ferror(fin)) {
perror(name);
error = -1;
}
fclose(fin);
return error;
}
void main(int argc, char **argp)
{
register errors = 0;
while( --argc > 0)
errors |= file_brand( *++argp);
exit(errors != 0);
}
The above will generate an executable which takes an .EXE or .COM
file as an argument. The checksum will be appended to the end of
the file, which will make the file a little longer, but do no
damage. If you wish to compress the .EXE or .COM file (e.g.,
with Pklite), do so BEFORE running the branding program.
The companion routines belong in the .C source file which
generated the .EXE or .COM file which was just branded:
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
/* Sanity check for file */
int file_changed(char *filename)
{
FILE *fin;
register c;
register long accum=0;
long compare;
register long count=0;
int error=0;
if ((fin=fopen(name, "rb"))==NULL) {
perror(name);
return -1;
}
length=filelength(fileno(fin))-sizeof(long);
for(count=0; count<length; count++) {
accum+=c^count;
}
fread(&compare, sizeof(long), 1, fin);
if (ferror(fin)) {
perror(name);
error = -1;
}
fclose(fin);
if(compare==accum)
return 0;
else
return 1;
}
int main(int argc, char *argv[])
{
if(file_changed(argv[0]))
{
puts(
" WARNING! The program has failed its internal diagnostic.\n"
" This can be caused by a viral attack, by use of compression\n"
" software or an illegal hack attempt.\n\n
" For your own safety, this program will not execute. Please\n"
" reinstall from the original archive or diskette.");
};
/* Your program follows */
};
The warning text above probably says everything that needs to be
said...
Although the above routine will be effective in 99.9% of all
cases in detecting infections or alterations of an executable
program, you should probably -not- use the routine verbatim.
The reason is simple: if this becomes a common, drop-in program
used in all executables, then new virii will simply contain the
same code to fake their own signatures or disable the routine.
Although this scenario isn't highly likely, it can be avoided
through simple alterations to the checksum calculations, such as
using exclusionary-or between a constant and each byte from the
file, or adding a number to the result, or subtracting, etc.
Just make sure the routines in the brand program and the
executable program match.
The main lesson here is that ALL executable files should contain
some kind of sanity check. It only makes sense for a program to
determine if it is the same version you released -- especially if
you're going to support it. The additional security that it
provides the user is worth some brownie points as well. I've
received several letters from users who were impressed that my
programs (which are not anti-virus programs) alerted them to
problems in their hardware or the presence of virii in their
system.
There is certainly room for improvement. Instead of the checksum
approach, a CRC approach would provide a greater degree of
confidence in the uniqueness of the signature. Also note that
this implementation requires that the entire executable be read
from disk twice; although this is not significant on systems
using a disk cache, it doubles the startup time on systems which
do not. This can be reduced or eliminated using a number of
techniques, including reading only key parts of the file (the
beginning, end, and approximate location of copyright notices,
for example.)
The included C source code is hereby released to the public
domain. I encourage all authors to consider using this or
another sanity-checking technique to ensure the integrity of
their programs.
-----BEGIN PGP SIGNATURE-----
Version: 2.3a
iQBVAgUBLNc4XKM4CDusTF+9AQFwNQH+MzLjYdK+TdUzICtaDxev2I/J+12i+x5I
hZn/hK4MJN5qxdMzos72L+Zcbr+wQchZyOxYo+BsSIl7t9QPBztL3Q==
=bf4z
-----END PGP SIGNATURE-----