病毒木馬查殺實戰第019篇:病毒特征碼查殺之編程實現

前言

? ? ? ?上次我們已經簡介過了病毒特征碼提取的基本方法,那么這次我們就通過編程來實現對于病毒的特征碼查殺。

?

定義特征碼存儲結構

? ? ? ?為了簡單起見。這次我們使用的是setup.exe以及unpacked.exe這兩個病毒樣本。經過上次的分析,我們對setup.exe樣本的特征碼提取例如以下:

\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

? ? ? ?為了方便起見,這里同一時候也將該特征碼的文件偏移保存下來。即0x0c040。

然后是unpacked.exe的特征碼:

\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

? ? ? ?它的文件偏移為0x1921。

? ? ? ?有了以上的信息,就能夠開始進行編程了。

首先須要定義一個數據結構。用于保存特征碼和文件偏移。

該結構例如以下:

#define NAMELEN 20
#define SIGNLEN 32
typedef struct SIGN
{char szVirusName[NAMELEN];LONG lFileOffset;BYTE bVirusSign[SIGNLEN + 1];
}_SIGN, *PSIGN;
? ? ? ?利用該數據結構定義一個全局變量,該全局變量保存有上述兩個病毒的特征碼,定義例如以下:
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”
}
};

? ? ? ?至此。病毒特征碼的基礎定義部分就到這里。

上述程序中,我是將病毒特征碼保存在一個全局變量中,大家也能夠另外創建一個文件。相似于PEiD的userdb.txt文件。從而專門保存病毒的特征碼。

現實中的殺毒軟件的特征庫也是以專門的文件的形式,保存在本地計算機中的。

這里我為了簡單起見,選擇以全局變量的形式進行保存。

?

主體程序的編寫

? ? ? ?首先須要編寫一個函數用于對目標程序指定位置處的十六進制代碼進行檢測:
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++){// 將待檢測程序的文件指針指向特征碼的偏移位置SetFilePointer(hFile, Sign[i].lFileOffset, NULL, FILE_BEGIN);// 讀取目標程序指定偏移位置的特征碼ReadFile(hFile, buffer, sizeof(buffer), &dwNum, NULL);// 特征碼的比對if(memcmp(Sign[i].bVirusSign, buffer, SIGNLEN) == 0){printf("發現病毒程序:%s\n", FilePath);CloseHandle(hFile);return TRUE;}}CloseHandle(hFile);return FALSE;
}
? ? ? ?然后就是main函數的編寫:
int main()
{WIN32_FIND_DATA stFindFile;HANDLE hFindFile;char *szFilter = "*.exe";   // 保存搜索的篩選條件(全部exe文件)char szFindFile[MAX_PATH];  // 保存欲檢測的程序的路徑char szSearch[MAX_PATH];    // 保存完整篩選路徑int ret = 0;                // 搜索的返回值lstrcpy(szFindFile, "E:\\");lstrcpy(szSearch, "E:\\");lstrcat(szSearch, szFilter);hFindFile = FindFirstFile(szSearch, &stFindFile);if(hFindFile != INVALID_HANDLE_VALUE){do{// 組成完整的待檢測程序的路徑lstrcat(szFindFile, stFindFile.cFileName);// 利用特征碼檢測目標程序是不是病毒程序if(!CheckSig(szFindFile)){printf("%s不是病毒程序\n",szFindFile);}// 刪除程序名稱,僅僅保留“E:\”szFindFile[3] = '\0';ret = FindNextFile(hFindFile, &stFindFile);}while( ret != 0 );}FindClose(hFindFile);return 0;
}

? ? ? ?上述程序僅僅是檢測E盤根文件夾下全部后綴為exe的程序是否為病毒程序,其實還能夠進行改動。使其能夠全盤搜索,大家能夠參考“熊貓燒香專殺工具”的相關代碼部分。另外為了謹慎起見,僅僅通過后綴進行exe程序的檢測是不嚴謹的。經常使用的檢測一個程序是不是exe程序的方法。就是解析目標程序中的對應位置是否為“MZ”以及“PE”。我這里為了簡單起見。就不採用該方法,有興趣的朋友能夠自行編程實現。

?

程序的測試

? ? ? ?這里我使用的是Code::Blocks13.12這款開源而且免費的開發環境。由于這款軟件能夠自己主動計算程序的執行時間,便于我們之后的對照操作。為了進行測試,我已經在E盤的根文件夾下放置了10個程序。當中4個程序是我們之前講過的病毒樣本。還有6個程序是我們曾經也曾使用過的一些工具軟件:


圖1

? ? ? ?上圖中前方帶有小方塊的就是病毒樣本。然后我們在Code::Blocks中編譯執行程序:


圖2

? ? ? ?可見程序已經非常成功地識別出了setup.exe以及unpacked.exe這兩個病毒樣本。其實,cf.exe以及OSO.exe也是病毒程序,但由于我并沒有把這兩個樣本的特征碼增加我們程序的特征庫。因此并沒能識別出來。最后,Code::Blocks還顯示出了本次程序的執行時間,當然每次的執行時間可能都不一樣,包含在不同的計算機上執行的結果應該也是不同的。可是通過多次執行進行觀察。基本上是0.016秒。也就是16毫秒。

?

與CRC32病毒識別方式的對照

? ? ? ?我們曾經的程序使用的CRC32算法來識別病毒,那么我們這里能夠對照一下。看看這次我們所講的方法和CRC32算法在程序運算時間上的優劣。CRC32病毒特征識別的程序例如以下:
#include "stdio.h"
#include "windows.h"DWORD CRC32(BYTE* ptr,DWORD Size)
{DWORD crcTable[256],crcTmp1;//動態生成CRC-32表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;}//計算CRC32值DWORD crcTmp2= 0xFFFFFFFF;while(Size--){crcTmp2 = ((crcTmp2>>8) & 0x00FFFFFF) ^ crcTable[ (crcTmp2^(*ptr)) & 0xFF ];ptr++;}return (crcTmp2^0xFFFFFFFF);
}
//
// 計算程序的CRC32值。輸入為文件路徑,輸出為DWORD類型的CRC32值
//
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";   // 保存搜索的篩選條件(全部exe文件)char szFindFile[MAX_PATH];  // 保存欲檢測的程序的路徑char szSearch[MAX_PATH];    // 保存完整篩選路徑int ret = 0;                // 搜索的返回值lstrcpy(szFindFile, "E:\\");lstrcpy(szSearch, "E:\\");lstrcat(szSearch, szFilter);DWORD dwTmpCRC32;hFindFile = FindFirstFile(szSearch, &stFindFile);if(hFindFile != INVALID_HANDLE_VALUE){do{// 組成完整的待檢測程序的路徑lstrcat(szFindFile, stFindFile.cFileName);// 利用CRC32算法檢測目標程序是不是病毒程序dwTmpCRC32 = CalcCRC32(szFindFile);// 匹配setup.exe的CRC32值if(dwTmpCRC32 == 0x89240FCD){printf("發現病毒程序:%s\n",szFindFile);}// 匹配unpacked.exe的CRC32值else if(dwTmpCRC32 == 0xC427A090){printf("發現病毒程序:%s\n",szFindFile);}else{printf("%s不是病毒程序\n",szFindFile);}// 刪除程序名稱,僅僅保留“C:\”szFindFile[3] = '\0';ret = FindNextFile(hFindFile, &stFindFile);}while( ret != 0 );}FindClose(hFindFile);return 0;
}

? ? ? ?相比而言,程序的主體部分還是基本一致的,僅僅只是是對于病毒特征的驗證方式稍有不同。由于關于CRC32算法我們已經在前幾次的課程中運用過,所以這里不再贅述。看一下執行結果:


圖3

? ? ? ?可見,利用CRC32算法提取出來的病毒特征碼的檢測方式,在結果上與上一個程序是一樣的,相同是發現了兩個病毒,沒有特征碼的病毒就沒能識別。

然后再看一下用時,我的測試結果是0.063秒,也就是63毫秒,是之前的時間的3.9375倍,那么也就說明了,CRC32算法在效率上是不如傳統的特征碼查殺方式的。

?

小結

? ? ? ?本文討論了病毒特征碼查殺的編程實現。并與CRC32算法在效率上進行了對照。

由于我們僅僅有兩個特征碼,為了便于課程的解說。我採用的是直接利用if…else語句進行特征碼的對照。

假設病毒的特征碼的數量非常龐大,那么有多少特征碼就須要使用多少個if語句,那么這顯然是非常沒有效率的。能否夠利用一定的算法來優化大量的特征碼的比對工作,不是我們討論的重點。有興趣的朋友能夠研究一下。

轉載于:https://www.cnblogs.com/yangykaifa/p/7258833.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282924.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282924.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282924.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《ASP.NET Core 6框架揭秘》實例演示[22]:如何承載你的后臺服務[補充]

借助 .NET提供的服務承載&#xff08;Hosting&#xff09;系統&#xff0c;我們可以將一個或者多個長時間運行的后臺服務寄宿或者承載我們創建的應用中。任何需要在后臺長時間運行的操作都可以定義成標準化的服務并利用該系統來承載&#xff0c;ASP.NET Core應用最終也體現為這…

命令行打印文件樹列表: tree

Linux & Mac 1.下載tree lib //mac brew install tree //centos yum install tree //ubuntu apt-get install tree 用法 //顯示所有文件 tree //顯示深度2層 tree -L 2 2. 命令find組合 find . -print | sed -e s;[^/]*/;|____;g;s;____|; |;g > structure.txt 移除node…

java 二分法查找數組,Java二分法查找數組元素下標

package pers.ly.javase.algorithm;import java.util.Arrays;/*** 二分法查找* author: Lu Yang* date: 2019-01-23 10:50:37**/public class BinarySearch {public static void main(String[] args) {Integer[] arr {10,50,30,40,10,80,90,70,60,40,100,10};// 數組排序 ->…

ASP.NET Core MVC壓縮樣式、腳本及總是復制文件到輸出目錄

前言 在.NET Core之前對于壓縮樣式文件和腳本我們可能需要借助第三方工具來進行壓縮&#xff0c;但在ASP.NET MVC Core中則無需借助第三方工具來完成&#xff0c;本節我們來看看ASP.NET Core MVC為我們提供了哪些方便。 自動壓縮樣式和腳本 當我們在測試環境中肯定不需要壓縮腳…

京東訂單自動評價方法

剛剛完成的一個京東自動訂單腳本, 以后還要加入其它京東自動的腳本項目地址: https://github.com/mm333444/aox_jd_auto_script 京東自動完成腳本 目前只完成京東訂單自動評價, 評價時會自動上傳商品圖片 一、安裝 1. 程序依賴 python3.52. 安裝配置 安裝pipenv安裝模塊 pipenv…

matlab空間散點擬合曲線,matlab離散點擬合曲線

matlab曲線擬合與數值點標注實例_工程科技_專業資料。實例 1: 現已知兩組...Matlab教程 曲線擬合工具箱 數學科學與技術學院 胡金燕 lionfr 曲線擬合定義 在實際工程應用和科學實踐中,經常需要尋求 兩個(或多個)變量間的關系,而......(p,x); %獲得x點處對相應的y值 plot(x,y,r*…

redis下并發問題解決方案

http://effective.blog.51cto.com/8296150/1671743 現在的計算機大都是多核的cpu,意味著可以并行執行多個進程.如果這多個運行的進程對同一份數據進行讀寫操作,那么就有可能出現兩個或者多個進程讀到的都是老的數據,這種情況下,再進行寫入操作之后就會有一些進程寫入的數據被覆…

宜建立自主可控的車用芯片和操作系統技術體系

萬物互聯時代&#xff0c;操作系統的邊界在不斷突破&#xff0c;面向“人機物”融合的泛在計算場景&#xff0c;能夠支撐分布式人機物協同應用的操作系統將是產業未來之光。操作系統在經過主機時代、PC互聯時代、移動互聯時代之后&#xff0c;來到萬物互聯時代&#xff0c;這恰…

Java 9進入第一輪問題修復階段

Java 9功能特性正式完成&#xff0c;這意味著第一個問題修復階段已經開始。HTTP/2客戶端沒有在截止日期前完成&#xff0c;現已降級為孵化器功能。由于現在的目標是在7月準備好可發布的Java 9&#xff0c;所以目前不太可能添加任何新的JEP。\\InfoQ此前的報道中提到&#xff0c…

django 用戶管理(1)

編輯了前端的頁面展示&#xff0c;用的bootstrap 用戶登錄 用戶信息 用戶編輯 創建用戶 修改密碼 轉載于:https://blog.51cto.com/jacksoner/2133129

qiaoye.php,全自動無限生成關鍵詞頁面(黑帽SEO優化終極方法)

如果你是做黑帽SEO的&#xff0c;如果你還停留在用欄目、租域名、劫持等手段來做黑帽SEO優化&#xff0c;我可以肯定的告訴你&#xff0c;你做的再好&#xff0c;也賺不了多少。那么今天咱們要說的就是無限生成關鍵詞頁面用內容頁來做黑帽SEO優化。這是我在演示的時候做的一個站…

AR Software

... 轉載于:https://www.cnblogs.com/2008nmj/p/7264769.html

v1.0.25 新版發布及Smart Meetup重新開啟丨SmartIDE

作者&#xff1a;徐磊文章首發地址&#xff1a;https://smartide.cn/zh/blog/2022-0892-sprint25/關于SmartIDESmartIDE是一群開發者為所有開發者開發的開源云原生IDE&#xff0c;我們的使命是“為開發者賦予云原生的超能力”&#xff01;使用SmartIDE你只需要學會一個簡單的指…

線程安全的單例模式

面試的時候&#xff0c;常常會被問到這樣一個問題&#xff1a;請您寫出一個單例模式&#xff08;Singleton Pattern&#xff09;吧。好吧&#xff0c;寫就寫&#xff0c;這還不容易。順手寫一個&#xff1a; public final class EagerSingleton { private static EagerSi…

vue實現首屏加載等待動畫 避免首次加載白屏尷尬

為什么80%的碼農都做不了架構師&#xff1f;>>> 0 直接上效果圖 1背景&#xff0c;用戶體驗良好一直是個重要的問題。 2怎么加到自己項目里面&#xff1f; 復制css html代碼到自己的index.html即可 代碼鏈接 源碼地址 Vue學習前端群493671066&#xff0c;美女多多。…

java-回調機制詳解

轉&#xff1a;http://blog.csdn.net/llayjun/article/details/50454148 閱讀目錄 一、前言二、回調的含義和用途三、Java實現接口回調 四、Android中的接口回調五、參考資料一、前言 最近在看android fragment與Activity進行數據傳遞的部分&#xff0c;看到了接口回調的內容&a…

lfi讀取php,php LFI讀php文件源碼以及直接post webshell

php LFI讀php文件源碼以及間接post 網站shell假如如下一個場景(&#xff11;) http://vulnerable/fileincl/example&#xff11;.php?pageintro.php(該php文件包孕LFI漏洞)(&#xff12;) 然而你不有中央能夠upload你的網站shell代碼(三) LFI只能讀取到非php文件的源碼(由于無…

根據請求上下文動態設置靜態文件存儲目錄

前言上次&#xff0c;我們實現了根據 subpath 特定格式《動態設置靜態文件存儲目錄》。例如&#xff1a;subpath靜態文件路徑/userAId/1.jpgc:\abc\userAId\1.jpg/userBId/1.jpgd:\xyz\123\userBId\1.jpg但是&#xff0c;如果 subpath 不能有這種特定格式&#xff0c;只能用通用…

BZOJ3019 : [Balkan2012]handsome

首先預處理出$f[i][j][k]$表示長度為$i$的序列&#xff0c;第一個位置是$j$&#xff0c;最后一個位置是$k$時合法的方案數。 從后往前枚舉LCP以及那個位置應該改成什么。 用線段樹維護區間內最左最右的已經確定的位置&#xff0c;以及區間內的合法方案數。 合并的時候只需要將左…

php smarty入門,smarty 快速入門

smarty 快速入門smarty定義:一個開源的模板引擎模板引擎是為了使用戶界面與業務數據分離而產生的&#xff0c;它可以生成特定格式的文檔&#xff0c;用于網站的模板引擎就會生成一個標準的HTML文檔。功能將網站的數據和網站的界面實現分離(php和html代碼)緩存頁面下載www.smart…