Mơ hình trừu tượng

Một phần của tài liệu phân tích và xây dựng mã độc đã sửa đổi (Trang 88 - 93)

Người dùng có thể chạy hệ điều hành Windows trên nhiều loại

phần cứng khác nhau. Khi người viết chương trình mã độc, họ có thể viết bằng nhiều ngơn ngữ khác nhau và sử dụng các trình biên dịch về dịch và chạy mã. Còn đối với người phân tích mã thì họ lại phải làm cơng việc ngược lại đó là đảo lại mã nguồn và làm sao có thể phân tích được mã nguồn đó và hiểu được.

Hình:

Hình trên giúp sinh viên có hiểu tổng quan về vị trí của người viết mã và vị trí của người phân tích mã là như thế nào. Hiện nay có rất cấp độ của ngơn ngữ lập trình, phần dưới đây sẽ mơ tả 6 mức khác nhau đó:

Mức Hardware: đây là mức vật lý, chứa các tín hiệu điện tử thực hiện

các tổ hợp các lệnh logic điện tử như XOR, AND, OR, NOT. Vì đây là phần cứng nên khơng thể dễ dàng có thể can thiệp bằng phần mềm.

Mức Microcode : mức microcode hay còn gọi là firmware. Microcode

hoạt động trên sơ đồ dịng điện. Nó chứa các chỉ dẫn nhỏ được chuyển đổi từ ngôn ngữ bậc cao, cung cấp 1 phương thức để giao tiếp với phần cứng. Khi thực hiện phân tích mã độc, khơng cần lo lắng về các microcode vì nó ln được chỉ rõ bởi máy tính.

Mức Machine code : (mã máy) Mức machine code chưa các Opcodes,

89

máy thông thường được thực hiện với nhiều chỉ dẫn microcode để cho phần cứng bên dưới có thể thực thi được. Mã máy được tạo ra khi chương trình máy tính bậc cao được biên dịch.

Mức Low-level languages: Ngôn ngữ bậc thấp là ngôn ngữ người

phân tích có thể đọc được. Ngơn ngữ bậc thấp mà phổ biến nhất là ngôn ngữ Assembly. Người phân tích mã độc làm việc ở mức ngơn ngữ này vì mã máy khó đọc. Người phân tích sử dụng các cơng cụ dịch ngược mã nguồn về dạng ngôn ngữ bậc thấp assembly.

Mức high-level languges: Ngơn ngữ bậc cao được nhiều lập trình viên

sử dụng như C,C++ và một số ngôn ngữ khác. Ngôn ngữ này sau khi biên dịch sẽ chuyển sang dạng mã máy.

Mức Interpreted languages là ngôn ngữ ở cấp cao nhất, nhiều lập

trình viên sử dụng các ngơn ngữ thông dịch như C#, Perl, .NET và Java. Các mã viết không biên dịch thành mã máy mà thay vì vậy biên dịch sang bytecode.

Đối với người phân tích mã độc, cần phải hiểu rõ ngơn ngữ Assembly để có thể đọc được mã nguồn (ở dạng dịch ngược)để phân tích. Phần tiếp theo đây giáo trình sẽ mơ tả tổng quan ngôn ngữ Assembly 32bit trên kiến trúc CPU x86.

3.1.1 Ngôn ngữ Assembly 32bit

3.1.1.1 Các thanh ghi

- ESP trỏ đến đầu stack

- EBP thường dùng để chứa các địa chỉ stack - EIP trỏ đến lệnh tiếp theo

- EAX chứa các biến số học,logic, thường dùng trong các thao tác nhân chia

- EBX thanh gi địa chỉ

- ECX thanh gi đếm hay dùng trong các vòng lặp - EDX các thao tác vào ra, các phép tính

- ESI EDI thường dùng thao tác với các mảng, chuỗi

Các cờ:

- O cờ tràn, = 1 khi tràn bộ nhớ. - P cờ chẵn lẻ

90 - Z cờ zero - kết quả bằng không z=1 - S cờ dấu s=1 thì kết quả âm

- C cờ nhớ, khi phép tính kết quả có nhớ hoặc mượn thì c=1

cờ điều khiển:

- T = 1 CPU chế độ là chạy từng lệnh (cờ bẫy- trap) - I cờ ngắt.

- D cờ hướng, D =1 thì cpu làm việc với chuỗi từ phải sang trái.

Một số câu lệnh cơ bản:

- MOV gán vế phải cho vế trái

- MOVSX thực hiện khi vế trái có độ dài > hơn phải - MOVZX thực hiện khi vế trái toàn 0

- LEA thanh gi, ô nhớ. Ghi ô nhớ vào thanh gi - XCHG hoán đổi dữ liệu

- INC tăng 1 đơn vị - DEC giảm 1 đơn vị

- ADD x1,x2 | x1 = x1 +x2 - ADC cộng phụ thuộc vào cờ - SUB trừ.

-SBB trừ, phụ thuộc cờ C,(c=1 trừ kết quả di 1) - MUL Nhân số không dấu (mul ecx |edx= eax *ecx)

- IMUL nhân số có dấu

- XADD thực hiện lần lượt xchg và add

- CMP so sánh: sau khi thực hiện tác động đến các cờ C Z S; C Z S

đích=nguồn 0 1 0 đích>Nguồn 0 0 0 đích< nguồn 1 0 1

- Test so sánh (tác động S Z P flag) so sánh bằng phép AND - JMP nhảy không điều kiện

- JE JZ nhảy nếu cờ Z = 1 ,JNE JNZ ngược lại - JS nhảy nếu cờ S =1

- JP/JPE nhảy nếu cờ P=1, JNP JNPE ngược lại - JO nhảy nếu cờ O=1 JNO ngược lại

91 - JB nếu cờ C=1

- JBE nếu cờ C or F=1 - JL nếu cờ S<>O

- LOOP X, ECX >0 thì nhảy lên địa chỉ X, tạo vòng lặp

- MOVS: mov string, sau đó tăng, giảm các thanh gi tùy thuộc vào cờ D, D =0 tăng, D=1 giảm

- REP X thực hiện lặp lại X đến khi ECX =0 - LODS nạp vào EAX

- STDOS X nạp từ EAX vào X, sau đo tăng X - CPMS so sánh 2 chuỗi

- CALL X , đi vào thực hiện ở địa chỉ X và pop địa chỉ trở về vào stack để phục

vụ cho lệnh ret.

- RET (retn) di chuyển đến địa chỉ đang chứa trong đỉnh stack, RET X, sau khi di chuyển sẽ clear X byte trong stack, lùi ESP lại tương ứng

3.1.1.2 ASM trên phần mềm IDA pro

1. Các kiểu:

• Byte_xxxxxx - địa chỉ xxxxx chứa giá trị kích thước 1 byte • Word_xxxxx - địa chỉ xxxxx chứa giá trị kích thước 2 byte • Dword_xxxxx - địa chỉ xxxxx chứa giá trị kích thước 4 byte • Qword_xxxxxx- địa chỉ xxxxx chứa giá trị kích thước 8 byte • Unk_xxxxx- Unknow type

2. Mảng, truy cập các phần tử trong mảng: Với code C:

#include "stdafx.h" int i,mang[10];

int _tmain(int argc, _TCHAR* argv[]) { mang[0]=1; mang[1]=2; mang[2]=3; mang[3]=4; return 0;

92 }

Đoạn code trên hiển thị trong IDA:

Hình 3-3 Mảng hiển thị trong IDA

Với dword_403370 là địa chỉ đầu tiên của mảng, do mảng kiểu int ( 4 byte / biến ) nên các phần tử tiếp theo có địa chỉ ô nhớ tăng lên 4, dword_403374, dword_403378,… Tương ứng với Mov dword_403370 ,1 Mov dword_403370+4,2 Mov dword_403370+8,3 Mov dword_403370 +12,4

Với các biến cục bộ thì sẽ được lưu địa chỉ trong EBP, là các địa chỉ thuộc stack. Với từng vị trí sẽ là ebp +1 +2 +3 +4…

3. Mảng dùng cấp phát bộ nhớ động: int _tmain(int argc, _TCHAR* argv[]) {

int *heap_array = (int*)malloc(3 * sizeof(int)); heap_mang[0] = 10;

heap_mang[1] = 20; heap_mang[2] = 30; heap_mang[2] = 40; }

93

Một phần của tài liệu phân tích và xây dựng mã độc đã sửa đổi (Trang 88 - 93)

Tải bản đầy đủ (PDF)

(200 trang)