Trao đổi với tôi

http://www.buidao.com

10/23/09

[Virus] Kỹ thuật nhận dạng virus đơn giản và code minh họa

Author: DungCoi

Bài tập để làm quen với C++ .
Ngôn ngữ : VC++ 2005

Bài này post bên CongDongCViet rồi, do cũng đơn giản nên chưa post lên forum mình. Hôm qua có bạn hỏi nên giờ post luôn bài viết + Source cho các bạn tham khảo

Virus là gì ?
Trong khoa học máy tính, virus máy tính (thường được người sử dụng gọi tắt là virus) là những chương trình hay đoạn mã được thiết kế để tự nhân bản và sao chép chính nó vào các đối tượng lây nhiễm khác (file, ổ đĩa, máy tính ..).
Trong tài liệu này chỉ để cập đến việc nhận dạng một nhánh của virus gọi là : Worm, trojan... các loại mã độc tĩnh (Không tự làm thay đổi cấu trúc của mình) mà thôi.

Nhận dạng
Có nhiều kỹ thuật nhận dạng virus như : Xét string, xét các mã hash, tạo máy ảo xét hành vi, giám sát hành vi... Nhưng kỹ thuật quan trọng nhất của các phần mềm chống virus là kỹ thuật scan theo string tại các địa chỉ (offset) nhất định.

Nguyên tắc cơ bản trong việc nhận dạng này là xác định một chuỗi string riêng biệt có tính đặc trưng của file nhất định (Ở đây được xét là virus) có tồn tại ở một địa chỉ nhất định mà không.

Để minh họa, tôi xin đưa ra các string nhất của 1 virus trước đây được Bkav cập nhật với tên FunnyIM




Như bạn có thể thấy, tại offset thứ 13834 có một đoạn string mà nếu có kinh nghiệm sẽ nhận ra đây là một string rất đặc trưng khó lẫn với các tập tin khác.
Nguyên tắc chọn ra string để nhận dạng đâu là virus thường dựa vào tính đặc thù của từng virus mà string được chọn có thể khác nhau.
Cùng với việc lựa chọn này, việc chúng ta lưu trữ offset string trên hiện diện sẽ đảm bảo khả năng nhận dạng chính xác với mã độc tĩnh (Không tự thay đổi cấu trúc của mình).

Với nguyên tắc này, việc nhận dạng 1 file có phải là virus hay không là việc kiểm tra tại offset nhất định có hay không không chuỗi string của virus tại offset đó.

Cấu trúc dữ liệu

Chúng ta xây dựng cấu trúc dữ liệu để lưu trữ 3 thông tin sau :
Mã nhận dạng virus
Offset
Tên virus

Code
Quote:
struct m_Sign
{
char sign[20];
long lPos;
char name[20];
}
Thao tác liệt kê file
Để thực hiện được thao tác quét, cần phải liệt kê được các file trong một đường dẫn nhất định. Ở đây, tôi sẽ sử dụng đệ quy để làm việc này.
Code
Quote:
private: System::Void listFile(System::String ^strPath)
{
System::String ^strFile;
//Liệt kê file trong thư mục hiện tại
for each (strFile in System::IO:irectory::GetFiles(strPath))
{
//strFile = Đường dẫn file
}

//Liệt kê các thư mục trong thư mục hiện tại
for each (strFile in System::IO:irectory::GetDirectories(strPath))
{
//Đặt bẫy lỗi
try
{
listFile(strFile);
//Tiến hành đệ quy để tiếp tục liệt kê
}
catch(Exception ^e)
{
//e->Message = Thông báo lỗi nếu có
}
}
}
Thao tác quét 1 file




Code
Quote:
System::String ^strFile;
System::String ^tmp;
char strDatFile[50];

//Liệt kê file trong thư mục hiện tại
for each (strFile in System::IO:irectory::GetFiles(strPath))
{
//Mở file cần được quét ra làm việc
FILE *fs;
//Do trong strFile là kiểu string
//cần phải chuyển đổi ra thành kiểu Char để đưa vào hàm
int itmp = strFile->Length;
char *chTmpData = new char[itmp+1];
for(int i = 0; i < itmp;i++)
{
*(chTmpData + i) = strFile[i];
};
*(chTmpData + itmp) = '\0';

fopen_s(&fs,chTmpData,"rb");

FILE *f;
char strPathSign[]="c:\\sign.vir";
fopen_s(&f,strPathSign,"rb");
m_Sign sign;

int i=0;
int posEnd;

//Xác định kích thước file
fseek(f,0,SEEK_END);
posEnd=ftell(f);

//Trả về vị trí ban đầu fseek(f,0,SEEK_SET);

//Tiến hành vòng lặp liệt kê mã nhận dạng
while (ftell(f) < posEnd)
{
//Đọc mẫu tin lưu mã nhận dạng virus
fread(&sign,sizeof(m_Sign),1,f);
//Nhảy trong file muốn quét tới offset muốn xét
fseek(fs,sign.lPos,SEEK_SET);
//Lấy 50 byte tại offset đó
fread(strDatFile,50,1,fs);

if (compareStr(strDatFile,sign.Sign) == true)
{
//Nhận dạng đúng là virus
tmp = gcnew System::String(sign.Name);
lstRe->Items->Add(L"Phát hiện : " + tmp + L" đường dẫn : " + strFile);
detected++;

lblDetected->Text = Convert::ToString(detected);
}
} fclose(f);
fclose(fs);
Giao diện cửa sổ scan




Chức năng :
Scan trong thư mục nhất định, liệt kê virus nếu có.
Khi đang quét có thể dừng, theo dõi quá trình quét...
Kỹ thuật :
Sử dụng 2 kỹ thuật liệt kê file và scan từng file đã nói ở bên trên để thực hiện.


Giao diện cửa sổ Danh sách virus





Chức năng :

Liệt kê những mã virus đã cập nhật.
Kỹ thuật :
Sử dụng 1 phần kỹ thuật scan virus (Chỉ quan tâm phần liệt kê mã nhận dạng).

Giao diện cửa sổ Thêm mã nhận dạng




Nhận xét
Ưu :
Khả năng nhận dạng và quét cơ bản hoàn thành
Quản lý virus list trực quan
Chức năng Thêm mã nhận dạng giúp có thể chủ động về bảng mã nhận dạng virus
Chức năng Thêm mã nhận dạng tự nhận ra virus đã được cập nhật hay chưa...
Khuyết :
Tốc độ quét còn chậm
Bảng mã nhận dạng còn ít
Do giới hạn các hàm cơ bản được học trong C++ nên hiện nay vẫn còn lỗi không scan được tập tin/thư mục có đường dẫn là ký tự Unicode (Kiểu char không thể lưu trữ).

Đính kèm bài viết là Source + Bài viết
Download: http://www.mediafire.com/?ziwmgzmua5n