📄 crcset.doc
字号:
| 3 | 2 1 | 0 |
| ------ v --------- -------- v --------- v
+ <-| X0 |<- + <-| X3+X0 |<------| X2+1 |<- + <-| X1+X0 |<- +
^ ------ --------- -------- ---------
|
---- 100
9. Repeat step 8 for all remaining bits:
---------------------1---------------0--------------1---------------1
| 3 | 2 1 | 0 |
| -------------- v --------- -------- v --------- v
+ <-| X3+X2+X1+1 |<- + <-| X3+X0 |<------| X2+1 |<- + <-| X3+X2 |<- +
^ -------------- --------- -------- ---------
|
----
- Page 10 -
We want the CRC in the register to be equal to the unknown CRC we
started inserting at step 4, i.e. we need:
N Value calculated for bit N Bit N
--- -------------------------- -----
3 X3 + X2 + X1 + 1 = X3
2 X3 + X0 = X2
1 X2 + 1 = X1
0 X3 + X2 = X0
If we collect all the variables on the left and all the constants on the
right (keeping in mind that we are dealing with modulo-2 arithmetic):
X2 + X1 = 1
X3 + X2 + X0 = 0
X2 + X1 = 1
X3 + X2 + X0 = 0
The value 1010 is the intermediate CRC mentioned earlier.
Here we have an interesting situation. The first and third equations
are the same and so are the second and fourth. What we come down to is this:
X2 + X1 = 1
X3 + X2 + X0 = 0
We have four variables and only two equations. There is no unique solution;
in fact, there are four (2 to the power of (4 - number of independent
equations)) separate and distinct sets of values that will satisfy these
equations.
Since CRCSET needs a numeric solution, we have to arbitrarily set bits
to get one. For arguments sake, let's set X2 to 1.
1 + X1 = 1
X3 + 1 + X0 = 0
In other words:
X1 = 0
X3 + + X0 = 1
By setting X2 to 1, we have also fixed X1. Now let's set X0 to 0.
X3 + + 0 = 1
In other words:
X3 = 1
We now have a solution for the CRC of the program: 1100. There are three
others: 0101, 0010, and 1011. If we replace the string WXYZ with any of these
values, the CRC calculation process will yield that value at the end, e.g.:
- Page 11 -
------------1-----------0-----------1-----------1
| 3 | 2 1 | 0 |
| ----- v ----- ----- v ----- v
+ <-| 0 |<- + <-| 0 |<------| 1 |<- + <-| 0 |<- +
^ ----- ----- ----- -----
|
---- 101111001100
----
yields
------------1-----------0-----------1-----------1
| 3 | 2 1 | 0 |
| ----- v ----- ----- v ----- v
+ <-| 1 |<- + <-| 1 |<------| 0 |<- + <-| 0 |<- +
^ ----- ----- ----- -----
|
----
If you're not sure about this, try it with pen and paper. Plug in each of the
four values and you should get that same value at the end of the CRC
calculation process. To help you out, here are the intermediate values of the
CRC register for each solution (the first value is the value after step 2 of
the calculation):
CRC
-----
1100: 1001, 0010, 1111, 0101, 1010, 0100, 0011, 0110, 1100
0101: 1001, 1001, 0010, 0100, 0011, 1101, 1010, 1111, 0101
0010: 1001, 1001, 1001, 0010, 0100, 0011, 1101, 0001, 0010
1011: 1001, 0010, 0100, 0011, 1101, 1010, 0100, 1000, 1011
The fact that there is not a unique solution isn't really important;
only about 30% of the time will there be a unique solution. This does not
diminish the effectiveness of the CRC calculation because whichever of the
four values the CRC is set to, any virus installing itself in the program will
still change it. The fact that we did not get a unique solution does mean,
however, that it is possible to get the following situation:
X2 + X1 = 1
X3 + X2 + X0 = 1
X2 + X1 = 1
X3 + X2 + X0 = 0
Here equations 2 and 4 contradict each other. There are no values of X3 to X0
that will satisfy these equations. If the CRCSET program comes across this
situation, it will simply try again.
For illustration, I have used only a 4-bit CRC; the CRCSET algorithm
uses 32 bits. The principle is the same; it just takes more time (and ink,
paper, patience, caffeine, pizza, and chocolate chip cookies).
- Page 12 -
How to Use CRCSET
This is the easy part.
For C programmers, add the files VALIDCRC.C and VIRUSDAT.C to the list
of files required to build the program you are working on (in Turbo C, add
them to the the project file). Add a call to isvalidcrc("PROGNAME.EXE")
somewhere in your program (preferably in main()). The function isvalidcrc()
returns 1 if the CRC is valid or 0 if it is invalid, if the program file is
not found, or if the CRC polynomial has been reset to 0.
For Turbo Pascal programmers, add the unit VirusCRC to your "uses"
clause and call the function IsValidCRC('PROGNAME.EXE'). IsValidCRC returns
TRUE if the CRC is valid or FALSE if it is invalid, if the program file is not
found, or if the CRC polynomial has been reset to 0.
Example programs, TESTCRC.C and TESTCRC.PAS, have been provided.
Once you have compiled your program, you have to calculate its CRC.
The program CRCSET.EXE has been provided for this purpose. The syntax is:
CRCSET [-<string>] file [file [file [...]]]
<string> is an 8-character (0-padded) string in which to store CRC data
(default is DEAN_CRC),
[file] is one or more files for which a CRC is to be calculated.
The string for which CRCSET.EXE searches is stored in the variable _viruscrc
in C and _VirusCRC in Turbo Pascal. The default is DEAN_CRC but you may
change it if there is a conflict (i.e. if there is more than one instance of
DEAN_CRC in the program, CRCSET.EXE will not know which one holds the CRC and
so will not set it). The string is replaced with a randomly-generated
polynomial and the CRC itself.
For example, to set the CRC for either of the test programs, the
command is:
CRCSET TESTCRC.EXE
If you change the string in one of the test programs to something like
"MyName", you would enter:
CRCSET -MyName TESTCRC.EXE
The case of the string on the command line must match exactly the case of the
string in the program. Also, any strings shorter than 8 characters must be
padded with 0's in the program.
If you run TESTCRC before setting the CRC, it will abort with a
warning that it may have been infected. After you set the CRC, run TESTCRC to
assure yourself that its CRC is valid.
If you want to test the reliability of the CRC check, change a few
bytes in TESTCRC.EXE (be careful, changing bytes in the code segment can hang
the program, so try bytes in the data segment, towards the end). Run TESTCRC
again, and it should warn you that it may have been infected.
Despite its complexity, CRCSET.EXE takes only a few seconds to
calculate the CRC of the target file. I have made some optimizations to the
- Page 13 -
algorithm that make the calculation time almost constant regardless of the
size of the file.
Once a CRC has been determined for your program, it takes little time
for the validation function to verify it every time the program is run.
CRCSET will display the name of the file that it is working on and
one or more of the following messages:
CRC search string "<string>" found more than once.
The search string specified occurs more than once in the file.
This is an error, since CRCSET has no way of knowing which occurrence
of the string it is supposed to replace with the polynomial and CRC.
Change the search string in _viruscrc (C version) or _VirusCRC (Turbo
Pascal version), recompile, and try again with the new string as an
argument to CRCSET (e.g. CRCSET -NewStrng PROG.EXE).
CRC search string "<string>" not found.
The search string specified does not occur in the file. Make
sure that the string passed to CRCSET is correct and also that the
validation module is being linked (i.e. that there is a call to the
isvalidcrc() or IsValidCRC somewhere in your program).
Testing polynomial abcdef12 ... no solution.
The matrix generated by CRCSET using the polynomial abcdef12
does not have a solution. CRCSET will try again with another
polynomial.
Testing polynomial abcdef12 ... CRC is 34567890.
It is unique.
The matrix generated by CRCSET using the polynomial abcdef12
has the unique solution 34567890, i.e. 34567890 is the CRC of your
program under the polynomial abcdef12. A unique solution will occur
only about 30% of the time.
Testing polynomial abcdef12 ... CRC is 34567890.
It is not unique (2^N solutions).
The matrix generated by CRCSET using the polynomial abcdef12
has the non-unique solution 34567890, i.e. 34567890 is the CRC of your
program under the polynomial abcdef12. The number of free variables
(the number of bits in the CRC whose value is irrelevant to the
solution) is N; each bit has two possible values, so there are 2^N
possible solutions. It is theoretically possible that all 32 bits
will be free variables, but this is extremely unlikely. The fact that
there is not a unique solution does not diminish the effectiveness of
the CRC validation in any way.
Note: the validation function (both the C and Pascal versions) finds
the name of the running program in _argv[0] (or ParamStr(0)) if the program is
running under DOS versions 3 or greater and searches the DOS PATH for the
program under DOS version 2.
- Page 14 -
Vulnerability
The CRCSET algorithm, like every other anti-virus algorithm, is
vulnerable to attack. Hand-tweaking the code to bypass the virus protection
is always possible. Direct attack to determine the storage location of the
polynomial and the CRC and to change it is also possible, but this can take
upwards of 5-10 minutes on a 386. Any virus that ties up the computer for
that long wins no points for discretion. Any user that doesn't notice a
system lockup lasting over 30 seconds probably has many other doors open for
viruses anyway.
There is no substitute for proper precautions: downloading from a
reputable BBS, avoiding pirated software, scanning programs for viruses before
using them, and so on. This program was developed with the knowledge that
most people don't take these precautions (based on a sample size of at least 1
- me); rather than leave it up to the end user to protect against viruses,
with this we programmers can take on some of the burden by protecting the
programs we write against them.
- Page 15 -
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -