CHƯƠNG 2. CƠ SỞ LÝ THUYET
2.2. Biểu diễn trung gian - Intermediate Representation
Intermediate representation (IR) là một cấu trúc dữ liệu được sử dụng bởi trình biên dich để biểu diễn mã nguồn. Biểu diễn trung gian được thiết kế để
dé dàng quan sát đoạn mã thay vì dang bytes code không có ngữ nghĩa. Đồng thời trong phân tích phần mềm, việc chuyển đổi sang dạng biểu diễn trung gian
có lợi cho quá trình xử lý tiếp theo, chẳng hạn như tối wu hóa mã và trích xuất ngữ nghĩa. Một ngôn ngữ biểu dién trung gian tốt phải có khả năng biểu diễn
chính xác ngữ nghĩa cho mã nguồn ban đầu mà không làm mat thông tin.
2.2.1. Vex Intermediate Representation (Vex-IR)
Một trong những biểu diễn trung gian phổ biến được sử dung là Vex Inter-
mediate Representation (Vex-IR). Vex-IR là một ngôn ngữ trung gian dựa trên
mã máy, được sử dụng để biểu diễn mã nhị phân dưới dạng các biểu thức và
lệnh có cấu trúc.
Hiện nay có rất nhiều ngôn ngữ biểu diễn trung gian như LLVM-IR, BIL,
nhưng trong nghiên cứu nay chúng tôi lựa chọn Vex-IR vì các lí do sau:
e Tính nhất quán với phân tích mã nhị phân: Vex-IR được thiết kế đặc
biệt cho phân tích mã nhị phân, cho phép biểu diễn hành vi và ngữ
nghĩa của mã nhị phân một cách chính xác. Các IR khác như LLVM
IR hoặc BIL thường được phát triển cho mục đích biên dịch hoặc tối
ưu hóa mã nguồn, không phan ánh đầy đủ các đặc điểm cần thiết cho
phân tích mã nhị phân.
e Hỗ trợ đa nền tảng: Vex-IR được thiết kế để hỗ trợ nhiều kiến trúc máy tính khác nhau. Điều này cho phép chúng ta ấp dụng phân tích
và phát hiện sự tương đồng trên các nền tảng khác nhau mà không
cần thay đổi cấu trúc của mã nhị phân.
e Có các đặc trưng phân tích mạnh mẽ: Vex-IR cung cấp một tập hợp
các đặc trưng phân tích mạnh mẽ để thể hiện cấu trúc và hành vi của
ma nhị phan. Ví dụ, nó cho phép chúng ta xác định các basic block
trong mã nhị phân, các nhánh điều kiện, các phép gán giá trị, các lệnh nhảy và các khối lệnh liên quan. Các đặc trưng cung cấp thông tin quan trọng để tìm hiểu sự tương đồng giữa các mã nhị phân.
e Ngoài ra Vex-IR còn có framework hỗ trợ rất mạnh mẽ là angr với
pyvex được tích hop.
2.2.2. Đặc điểm va cấu trúc của Vex-IR
Dé xử lý các kiến trúc rất đa dạng, việc thực hiện các phân tích trên Vex-IR
là rất hữu ích. Vex-IR. trừu tượng hóa các khác biệt về kiến trúc khi xứ lý các kiến trúc khác nhau, cho phép chạy một phân tích duy nhất trên tất cả chúng.
Với Vex-IR, ta có thể trừu tượng hóa nhiều khía cạnh khác nhau:
e Thanh ghi (Register): Các kiến trúc máy tính khác nhau có số
lượng và tên các thanh ghi khác nhau. Tuy nhiên, Vex-IR trừu tượng hóa các thanh ghi này thành một không gian bộ nhớ riêng biệt, cho
phép truy cập thông qua các offset số nguyên. Diều này giúp ta xứ lý các đăng ký trên các nền tảng khác nhau một cách nhất quán.
e Truy cập bộ nhớ (Memory access): Các kiến trúc khác nhau có
cách truy cập bộ nhớ khác nhau, vi dụ như chế độ little-endian và
big-endian của ARM. Vex-IR giúp trừu tượng đi những khác biệt nay
để ta có thể xử lý truy cập bộ nhớ một cách đồng nhất.
e Phân đoạn bộ nhớ (Memory segmentation): Một số kiến trúc như x86 hỗ trợ phân đoạn bộ nhớ thông qua việc sử dụng các đăng
ký phân đoạn đặc biệt. Vex-IR hiểu các cơ chế truy cập bộ nhớ như
này.
e Tác động phụ của các câu lệnh (Instruction side-effects): Hầu
hết các câu lệnh có tác động phụ, ví dụ như cập nhật cờ điều kiện trong chế độ Thumb trên ARM, hoặc cập nhật con trỏ ngăn xếp trong các chỉ thị day (push) ngăn xếp (stack). Dé theo doi những tác động phụ này một cách hệ thống trong phân tích sẽ rất khó khăn. Vì vậy, Vex-IR làm cho những tác động phụ này rõ ràng và dễ xử lý.
Vex-IR là một biểu diễn không phụ thuộc vào kiến trúc, không có tác động phụ, và có thể đại diện cho nhiều ngôn ngữ máy mục tiêu. Nó trừu tượng hóa
mã máy thành một biểu điễn được thiết kế để đễ dàng phân tích chương trình. Biểu diễn này bao gồm năm loại đối tượng chính:
e Biểu thức (Expressions): Biểu diễn IR đại diện cho giá trị được
tính toán hoặc hằng số. Điều này bao gồm việc tải dữ liệu từ bộ nhớ, đọc từ thanh ghi và kết quả của các phép toán số học. Một số loại
biểu thức Vex-IR được thể hiện ở bảng 2.1
Bảng 2.1: Vi dụ một số loại biểu thức Vex-IR
Biểu thức | Giá trị đã tính Ví dụ
Vex-IR
Constant Một giá trị hằng số 0x4:132
Read Temp Giá trị được lưu trữ trong biến tạm | RdTmp(t10)
của VEX Get Register Giá trị được lưu trữ trong một thanh | GET:132(16)
ghi Load Memory | Giá tri được lưu trữ tại một dia chi | LDle:132 /
bộ nhớ, với địa chỉ được xác định bởi | LDbe : 164
biểu thức Vex-IR khác Operation Kết quả của một phép toán Vex-IR | Add32
cụ thể, áp dụng cho các đối số Biểu
thức Vex-IR khác
If-Then-Else Nếu một Biểu thức Vex-IR đã cho | ITE
cho kết quả trả về bằng 0, trả về một biểu thức Vex-TR. Ngược lai, trả về biểu thức Vex-TR khác
Helper Func- | VEX sử dụng các hàm trợ giúp của | function_name ()
tion € cho một số phép toán, ví dụ như
tính toán các thanh ghi cờ điều kiện
. ác hàm này trả về biểu thức Vex-
IR
¢ Thao tác (Operations): Thao tác IR mô tả việc thay đổi Biểu
diễn IR. Điều này bao gồm phép toán số nguyên, phép toán số dấu
chấm động, phép toán bit,... Áp dụng một thao tác IR vào Biểu thức
IR cho kết quả là một Biểu thức IR.
e Biến tạm thời (Temporary variables): Vex-IR sử dụng biến tạm thời như các thanh ghi nội bộ: Biểu thức IR được lưu trữ trong các biến tạm thời trước khi sử dụng. Ta có thể truy xuất nội dung của biến tạm thời bằng cách sử dụng Biểu thức IR. Các biến tạm thời này
được đánh số từ t0.
e Câu lệnh (Statements): Câu lệnh IR mô hình các thay đổi trạng
thái của kiến trúc ban đầu, chẳng hạn như việc lưu trữ dữ liệu vào bộ nhớ và ghi vào thanh ghi. Câu lệnh IR sử dụng Biểu diễn IR cho các giá trị mà chúng cần. Ví dụ, một câu lệnh IR lưu trữ dữ liệu vào bộ nhớ sử dụng biểu thức IR. cho địa chỉ và một biểu thức IR khác cho nội dung. Một số loại câu lệnh Vex-IR được thể hiện ở bảng 2.2.
Bang 2.2: Vi dụ một số loại cau lệnh Vea-IR
Câu lệnh | Ý nghĩa Ví dụ
Vex-IR
Write Temp Dat biến tam thời Vex thành giá tri WrTmp(t1)
của biểu thức IR đã cho. = (IR
Expression)
Put Register Cap nhật một thanh ghi với giá trị | PUT(16) = (IR
của biểu thức IR đã cho. Expression)
Store Memory | Cập nhật một vị trí trong bộ nhớ, | ST1e(0x1000)
được cung cấp dưới dạng biểu thức | = (IR
IR, với một giá trị, cũng được cung | Expression))
cấp dưới dạng biểu thức IR Exit Thoát có điều kiện khỏi một basic | if (condition)
block, với mục tiêu nhảy được chỉ | goto (Boring)
định bởi biểu thức IR và điều kiện | 0x4000A00: 132 cũng được chỉ định bởi biểu thức IR
e Khối (Blocks): Một Khối IR là một tap hợp các câu lệnh IR, đại
điện cho một basic block trong kiến trúc ban đầu (gọi là "IR Super Block" hoặc "IRSB").
Để dé hình dung hơn về các biểu diễn trong Vex-IR, chúng tôi để một đoạn
mã Vex-IR đã được chuyển từ một đoạn bytes code ở bên dưới.
1 PUT(offset=184) = 0x00000000004010e4
2 t2 = LDle:18(0x0000000000404010)
s PUT(offset=144) = 0x0000000000000005
+ 913 = 8Uto64(t2)
t4 = t13
s PUT(offset=152) = t4
PUT (offset=160) = 0x0000000000000000
s PUT(offset=184) = 0x00000000004010eb
s t16 64to8 (0x0000000000000000)
wo ti7 = 64to8(t4)
u t15 = CmpEQ8(t17,t16)
ứ E14 = 1Uto64(t15)
ứ tit = t14
u E18 = 64to1(t11)
ứ E6 = t18
w if (t6) { PUT(offset=184) = 0x4010ed; Ijk_Boring }
7 return 0;