This series of tutorials is copyright "I spring and Autumn" All, reproduced please indicate the source.
for Video tutorials, please visit "I Spring" (www.ichunqiu.com).
Preface
The last time we have introduced the basic method of virus signature extraction, this time we are programmed to implement the virus signature killing.
defining a signature storage structure
For the sake of simplicity, this time we are using two viral samples, Setup.exe and Unpacked.exe. After the last analysis, we extracted the signatures of the Setup.exe samples as follows:
\x2a\x2a\x2a\xce\xe4\x2a\xba\xba\x2a\xc4\xd0\x2a\xc9\xfa\x2a\xb8
\xd0\x2a\xc8\xbe\x2a\xcf\xc2\x2a\xd4\xd8\x2a\xd5\xdf\x2a\x2a\x2a
For the sake of convenience, the file offset of the signature is also preserved, i.e. 0x0c040. Then there is the Unpacked.exe signature:
\x13\x8b\x45\xf0\xe8\x00\x00\x00\x00\x81\x04\x24\xd7\x86\x00\x00
\xff\xd0\xeb\x11\x6a\x10\x68\x30\x80\x40\x00\xff\x75\xfc\x53\xff
It has a file offset of 0x1921.
With the above information, you can start programming. You first need to define a data structure that holds the signatures and file offsets. The structure is as follows:
#define Namelen 20#define signlen 32typedef struct sign{ char Szvirusname[namelen]; LONG Lfileoffset; BYTE Bvirussign[signlen + 1];} _sign, *psign;
Use this data structure to define a global variable that holds the signatures of the two viruses, defined as follows:
Sign Sign[2] = {{ //setup.exe "setup.exe", 0x0c040, "\x2a\x2a\x2a\xce\xe4\x2a\xba\xba\x2a\xc4\xd0 \x2a\xc9\xfa\x2a\xb8 " " \xd0\x2a\xc8\xbe\x2a\xcf\xc2\x2a\xd4\xd8\x2a\xd5\xdf\x2a\x2a\x2a "},{ // Unpacked.exe "Unpacked.exe", 0x1920, "\x13\x8b\x45\xf0\xe8\x00\x00\x00\x00\x81\x04\x24\xd7\x86\ X00\x00 " " \xff\xd0\xeb\x11\x6a\x10\x68\x30\x80\x40\x00\xff\x75\xfc\x53\xff "}};
At this point, the basic definition of the virus signature is here. In the above program, I save the virus signature in a global variable, you can also create a separate file, similar to the Peid userdb.txt file, so that specifically save the virus signatures. In reality, the feature library of anti-virus software is also in the form of special files, saved in the local computer. Here I choose to save as a global variable for the sake of simplicity.
preparation of the principal programYou first need to write a function to detect the hexadecimal code at the location specified by the target program:
BOOL Checksig (char* FilePath) { DWORD dwsignum = 0; DWORD dwnum = 0; BYTE Buffer[signlen+1];int i; HANDLE hfile = NULL; hfile = CreateFile (FilePath, generic_read | Generic_write, file_share_read, null, open_existing, file_attribute_normal, null); for (i=0; I <= 1; i++) { //The file pointer of the program to be instrumented points to the offset position of the signature SetFilePointer (hfile, Sign[i].lfileoffset, NULL, file_begin);// Read the target program to specify the offset location of the signature ReadFile (hfile, buffer, sizeof (buffer), &dwnum, NULL); The comparison of the signature to if (memcmp (sign[i].bvirussign, buffer, signlen) = = 0) {printf ("Discovery Virus Program:%s\n", FilePath); CloseHandle (hfile); return TRUE;} } CloseHandle (hfile); return FALSE;}
Then the main function is written:
int main () { Win32_find_data Stfindfile; HANDLE Hfindfile;char *szfilter = "*.exe"; Save Search filter criteria (all EXE files) char Szfindfile[max_path]; Save the path to the program you want to detect char Szsearch[max_path]; Save full filter path int ret = 0; The return value of the search lstrcpy (szfindfile, "e:\\"); lstrcpy (Szsearch, "e:\\"); Lstrcat (Szsearch, szfilter); hfindfile = FindFirstFile (Szsearch, &stfindfile); if ( hFindFile! = Invalid_handle_value) {do {//the path to the complete program to be detected lstrcat (Szfindfile, stfindfile.cfilename);//Use Special Code detection Target program is not a virus program if (! Checksig (Szfindfile)) {printf ("%s is not a virus program \ n", szfindfile);} Remove the program name and keep only "e:\" szfindfile[3] = ' &stfindfile '; ret = FindNextFile (hFindFile,);} while (ret! = 0);} FindClose (hfindfile); return 0;}
The above procedure is only to detect all the e-packing directory suffix EXE program is a virus program, in fact, can also be modified, so that it can search the whole, we can refer to the "Panda Burn Incense Kill Tool" related code section. In addition, in order to be prudent, only through the suffix EXE program detection is not rigorous, commonly used to detect a program is not an EXE program method, is to resolve the target program in the corresponding location is "MZ" and "PE". I am here for the sake of simplicity, do not use this method, interested friends can be self-programming implementation.
test of the program
Here I am using code::blocks13.12 this open source and free development environment, because this software can automatically calculate the execution time of the program, it is easy for us to compare after the operation. For testing purposes, I have placed 10 programs at the root of the E drive, 4 of which are samples of viruses we have previously told, and 6 programs that we have used before:
Figure 1
A small square in front of it is a virus sample. Then we compile and run the program in Code::Blocks:
Figure 2
Visible programs have successfully identified two virus samples, Setup.exe and Unpacked.exe. In fact, Cf.exe and OSO.exe are also virus programs, but since I did not add the signatures of the two samples to the feature library of our program, we did not recognize them. Finally, the Code::Blocks also shows the running time of this program, of course, each time the running time may be different, including the results of running on different computers should be the same. However, it is observed by running multiple times, which is basically 0.016 seconds, or 16 milliseconds.
comparison with the CRC32 virus identification methodOur previous program used the CRC32 algorithm to identify the virus, then we can compare here to see what we are talking about the method and the CRC32 algorithm in the program time of the pros and cons. The CRC32 virus feature recognition program is as follows:
#include "stdio.h" #include "Windows.h" DWORD CRC32 (byte* Ptr,dword Size) {DWORD Crctable[256],crctmp1; Dynamically generate CRC-32 table for (int i=0; i<256; i++) {crcTmp1 = i; for (int j=8; j>0; j--) {if (crctmp1&1) CrcTmp1 = (crcTmp1 >> 1) ^ 0xedb88320l; else CRCTMP1 >>= 1; } Crctable[i] = CRCTMP1; }//Calculate CRC32 value DWORD crctmp2= 0xFFFFFFFF; while (size--) {crcTmp2 = ((crctmp2>>8) & 0x00ffffff) ^ crctable[(crctmp2^ (*ptr)) & 0xFF]; ptr++; } return (CRCTMP2^0XFFFFFFFF);} Calculates the CRC32 value of the program, enters the file path, and outputs the CRC32 value of the DWORD type//dword CalcCRC32 (char* FilePath) {HANDLE hfile = CreateFile (FilePath, Generic_read,file_share_read,null,open_existing,file_attribute_normal,null); if (hfile = = Invalid_handle_value) {printf ("Create Error"); return FALSE;} DWORD dwsize = GetFileSize (hfile,null); if (dwsize = = 0xFFFFFFFF) {printf ("GetFileSize Error"); Return FAlse;} BYTE *pfile = (byte*) malloc (dwsize); if (PFile = = NULL) {printf ("malloc Error"); return FALSE;} DWORD dwnum = 0; ReadFile (Hfile,pfile,dwsize,&dwnum,null); DWORD DWCRC32 = CRC32 (pfile,dwsize); if (pFile! = NULL) {free (pFile); PFile = NULL;} CloseHandle (hfile); return DWCRC32;} int main () {win32_find_data stfindfile; HANDLE Hfindfile;char *szfilter = "*.exe"; Save Search filter criteria (all EXE files) char Szfindfile[max_path]; Save the path to the program you want to detect char Szsearch[max_path]; Save full filter path int ret = 0; The return value of the search lstrcpy (szfindfile, "e:\\"); lstrcpy (Szsearch, "e:\\"); Lstrcat (Szsearch, Szfilter); DWORD dwtmpcrc32;hfindfile = FindFirstFile (Szsearch, &stfindfile), if (hfindfile! = Invalid_handle_value) {do { The path of the complete program to be detected lstrcat (Szfindfile, stfindfile.cfilename);//using CRC32 algorithm to detect the target program is not a virus program dwTmpCRC32 = CalcCRC32 (szfindf ile);//Match Setup.exe's CRC32 value if (dwTmpCRC32 = = 0X89240FCD) {printf ("Discovery Virus Program:%s\n", szfindfile);} Match UnpacKed.exe CRC32 Value Else if (dwTmpCRC32 = = 0xc427a090) {printf ("Virus program found:%s\n", szfindfile); } else {printf ("%s is not a virus program \ n", szfindfile); }//removes the program name and only retains "C: \" szfindfile[3] = ' &stfindfile '; ret = FindNextFile (hFindFile,);} while (ret! = 0);} FindClose (hfindfile); return 0;}
In contrast, the main body part of the program is still basically the same, but the virus characteristics of the authentication method slightly different. Because we have used the CRC32 algorithm in previous courses, we will not repeat it here. Look at the results of the operation:
Figure 3
Can be seen, using the CRC32 algorithm extraction of the virus signature detection method, in the results with the previous program is the same, the same is found two viruses, no signature virus is not recognized. And then look at the time, my test results are 0.063 seconds, that is, 63 milliseconds, is 3.9375 times times the previous period, then it is also explained that the CRC32 algorithm is less efficient than the traditional signature method.
SummaryThis paper discusses the programming implementation of virus signature detection, and compares the efficiency with the CRC32 algorithm. Since we only have two signatures, for the sake of explaining the course, I use the If...else statement to compare the signatures directly. If the number of signatures of a virus is very large, then it is obviously inefficient to have how many of the IF statements are used by the signatures. Whether the ability to use certain algorithms to optimize a large number of feature code comparison work, is not the focus of our discussion, interested friends can study.
Virus Trojan killing actual combat No. 019: Virus signature Killing program implementation