Chương 1: Giới thiệu tổng quan về đề tài của khóa luận tốt nghiệp và những nghiên cứu có liên quan trước đó. e Chương 2: Trình bay cơ sở lý thuyết và những kiến thức nền tang phục vụ cho khóa luận. e Chương 3: Trình bày phương pháp phát hiên sự tương đồng trong mã nhị phân mà chúng tôi da nghiên cứu. e Chương 4: Trình bày các thí nghiệm và đánh giá.
e Chương 5: Kết luận và hướng phát triển của đề tài. CƠ SỞ LÝ THUYET Trong chương này chúng tôi sẽ trình bày các cơ sở lý thuyết liên quan của đề tài: Bao gồm các thành phần liên quan đến tập tin nhị phân, ngôn ngữ biểu điễn trung gian (Intermediate representation) và mô hình học sâu. Các thành phần liên quan đến tập tin nhị phân 2. Chức năng - Function Trong nghiên cứu này, chúng tôi đề cập đến một hàm là một danh sách các câu lệnh (Instructions) được sắp xếp trong các tập tin nhị phân, và chúng được biên dịch từ một hàm mã nguồn.
Do đó, nó có ngữ nghĩa cụ thể. Hơn nữa một chức năng có biểu đồ luồng điều khiển (Control-flow-graph) dùng để biểu thị thông tin luồng thực thi của nó (Tương tự như hình 2. La: ' Li: ¡ mov P8, [rbp] ! mov P8, [rbp] ' emp hai, rax ' cmp [rbp], rax ti; jz L3 | call exaae3te ‘Ta: L3: edd L4 h ee add rax, rdi 1 add rax, rdi ' call 0x4ee3fe eee i; L[_ imp ta jmp L5 ï jmp L5 ' tla: | add rax, 3 La:add rax, 3 ' H mov [rbp-8], rax ,' U5: t add rax, 3 1 ret ' ‘6: TLS: L6: ! sub rax, 3 h add rax, 3 sub rax, 3 ! net h ret ret ~=—~=====—==—==m—===m==-=“a Hành 2.1: Mot vi dụ uề biểu đồ luồng điều khiển của hàm nhị phân. Phần bên trái là ma tập hợp bố cục tuyến tinh uới các địa chỉ bước nhảy va phan bên phải là biểu đồ luồng điều khiển tương ứng.
L1 va LẠ là các nút bắt buộc. Basic block Basic block là một chuỗi các lệnh liên tiếp trong mã máy, có một điểm vào và một điểm ra duy nhất. Trong file nhị phân, basic block là một đoạn mã máy được tạo ra từ một số lệnh máy và thường được xem như là một đơn vị dùng trong việc phân tích mã nhị phân (Hình 2. sample2 proc near 888 cmp [esp+enabled], ø 908 jz short loc_481852 loc_ 481052: 888 or eax, OFFFFFFFFH 888 retn sample2 endp eax, eax short loc_48184D esptcounter], 1 SAN loc_48184D : 888 mov eax, [esptcounter] 888 retn Hình 2.2: Các basic block kế tiếp nhau được trích xuất khi dùng IDA 2.
Biểu dé luồng điều khiển - Control flow graph Control Flow Graph (CFG) là biểu đồ biểu diễn luồng điều khiển của chương trình máy tính hoặc chương trình nguồn dưới dạng đồ thị hướng điều khiển. Mỗi nút trong CFG đại diện cho một basic block, đại diện cho một chuỗi các lệnh liên tiếp không thể ngắt giữa các lệnh. Các cạnh trong CFG biểu thị các chuyển đổi giữa các basic block thông qua các nhánh điều kiện, nhánh vô điều 12 kiện hoặc các lệnh gọi hàm. Trong phát hiện sự tương đồng trong mã nhị phân, CFG được sử dụng để so sánh cấu trúc điều khiển của các chương trình khác nhau và xác định sự tương đồng giữa chúng.
Các phương pháp phát hiện sự tương đồng thường dựa trên việc so sánh các đặc trưng của CFG, quan hệ điều khiển và đường đi thực thi. 1 intadd(inta}{ func —- loc_40143A: 2 return a++; .text:0040143A mov dword ptr [esp+18h], 0 3 } ,text:00401442 mov eax, [ebp+argc] .text:00401445 cmp eax, [esp+18h] 4 intsublinta){ .text:00401449 jle — shortloc 40141E 5 return a--; .text:00401448 mov dword ptr [esp+1Ch], offset _sub 6 } .text:00401453 jmp short lọc 401410 7 int func(int a){ 8 int num = 0; 9 int (*cal)(int); add — lọc_401410 sub -— lọc_40141E 10 if{(a>num)( ,text:00401410 push ebp ,text:0040141E push ebp 11 cal = add; .text:00401411 mov ebp,esp .text:0040141F mov ebp, esp 12 } .text:00401413 mov eax, [ebp+arg_0]} .text:00401421 mov eax, [ebp+arg_0] 13 else{ .text:00401416 lea edx, [eax+1] .text:00401424 lea edx, [eax-1] 14 EesuÙb: .text:00401419 mov [|ebp+arg 0], edx .text:00401427 mov l|ebp+arg 0],edx NI BỌN text:0040141C pop cbp .text:0040142A pop ebp 15 } .text:0040141D retn ,text:0040142B retn 16 return cal(a); 17 } (a). Source code of the example (b). CFG of the example Hình 2.3: Ví du vé một đoạn chương trinh uới CFG tương ứng 2.
Strand Trong ngữ cảnh phát hiện tương đồng mã nhị phân, thuật ngữ "Strand" thường được sử dụng để chỉ một đoạn mã nhị phân hoặc các lệnh cụ thể trong mã nhị phân. Strand là một tập hợp các câu lệnh liên quan nhau mà khi kết hợp lại, chúng sẽ tạo thành một chuỗi hoàn chỉnh thực hiện một nhiệm vụ nào đó trong chương trình. Trong nghiên cứu này, quá trình phát hiện tương đồng mã nhị phân thường bắt đầu bằng việc chia nhỏ các mã nhị phân thành các strand. Sau đó, các thuật toán so sánh có thể được ap dụng để so sánh các strand này với nhau để xác định 13 mức độ tương đồng giữa chúng.
Các kỹ thuật như inlining, constant folding, và các phép tối ưu hóa khác có thể được áp dụng lên các strand để tăng cường hiệu quả của quá trình phân tích và so sánh mã nhị phân. Decompiler Decompiler là một công cụ hoặc chương trình máy tính dùng để chuyển đổi mã máy (machine code) hoặc mã nhị phan (binary code) trở lại thành mã nguồn gốc dưới dạng ngôn ngữ lập trình. Việc sử dụng decompiler có thể giúp phân tích và nằm bắt rõ hơn về chức năng và logic của một chương trình đã được biên dịch. Hiện nay có rất nhìu decompiler khác nhau như: IDA, Ghidra, Radare2, RetDec,.
Thông thường các decompiler có thể có các công dụng như sau: e Phân tích ngược: Giúp nhà phát triển hiểu cấu trúc và logic của một chương trình khi mã nguồn không còn hoặc không có sẵn. e Trích xuất chức năng: Decompiler cho phép chuyển đổi mã máy không cấu trúc thành dạng mã có cấu trúc ( thường là assembly), giúp dễ dàng hiểu và phân tích các chức năng trong mã nhị phân. e Phân tích bảo mật: Hỗ trợ các chuyên gia an ninh mạng phân tích mã độc, phát hiện lỗ hong bảo mật và đánh giá rủi ro từ mã nhị phan. 14 mov lea mov xor call Mov jmp Hình 2.4: Vi dụ vé một đoạn ma được chuyển đổi sang assembly bằng IDA 2.
IDA Pro Ở nghiên cứu nay, chúng tôi cần sử dung decompiler để trích xuất các dia chỉ của các chức năng trong tập tin nhị phân, từ đó trích xuất ra các bytes code của các chức năng đó. Để phục vụ cho yêu cầu này, chúng tôi quyết định chọn IDA Pro để thực hiện, ngoài là công cu decompiler quen thuộc thì IDA Pro còn có các ưu điểm: e Hỗ trợ phân tích mã nhị phân: IDA Pro cho phép người dùng phân tích các file thực thi (executable files), thư viện (libraries), hay các đoạn mã khác từ nhiều nền tảng khác nhau như Windows, Linux, macOS, và nhiều hệ điều hành nhúng. e Phân tích đồ thị luồng điều khiển: Công cụ này giúp người dùng hình dung và phân tích các nhánh thực thi của chương trình, từ đó tìm ra các kết nối logic và điểm nhập nhằng (critical point) của chương trình. e Hỗ trợ nhiều kiến trúc và định dạng file: IDA Pro hỗ trợ nhiều loại kiến trúc vi xử lý và định dang file như ELF, PE, Mach-O, và COFF, giúp người dùng phân tích các loại file khác nhau dé dàng.
IDA Python API IDA Python API là một giao diện lập trình ứng dung (API) được cung cấp bởi IDA Pro để cho phép người dùng tương tác với và điều khiển IDA Pro bằng ngôn ngữ lập trình Python. API này cho phép các nhà phân tích mã nhị phân và bảo mật sử dụng các tính năng của [DA Pro một cách tự động hóa và linh hoạt hơn thông qua việc viết các script và plugin. Một số tính năng nổi bat của IDA Python API: e Doc và phân tích mã nhị phân: API cho phép người dùng mở các file thực thi và thực hiện các thao tác như phân tích đồ thị luồng điều khiển (CFG), đọc các hàm, khối lệnh, và các cấu trúc dữ liệu khác từ chương trình. e Tự động hóa quy trình phân tích: Bằng cách sử dụng IDA Python API, chúng ta có thể viết các script để tự động hóa các quy trình phân tích, như tìm kiếm chuỗi, đặt nhãn, phát hiện các cấu trúc dit liệu và các chuỗi lỗi.
e Tích hợp với các công cụ và workflow khác: IDA Python API có thé tích hợp và tương tác với các công cụ và quy trình làm việc khác, ví dụ như phân tích tĩnh (static analysis) từ các công cụ khác, tự động hóa các bước kiểm thử (testing automation), hoặc tạo ra các báo cáo phân tích. Biểu diễn trung gian - Intermediate Representation VEX Intermediate Representation (VEX-IR) là một biểu diễn trung gian được sử dụng trong phân tích mã nhị phân. Nó được phát triển bởi dự án Valgrind và hiện tại được sử dụng rộng rãi trong nhiều công cụ phân tích mã nhị phân như Angr. VEX-TR chuyển đổi mã máy cụ thể của các kiến trúc phần cứng khác 16 nhau thành một định dạng trung gian phổ quát, giúp dễ dàng phân tích và xử lý mã nhị phân.
Vex Intermediate Representation (Vex-IR) Một trong những biểu diễn trung gian pho 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 này chúng tôi lựa chọn Vex-IR vì các lí do sau: e Kiến trúc trung gian: VEX-IR không phụ thuộc vào kiến trúc cụ thể, nghĩa là nó có thể biểu diễn mã từ nhiều kiến trúc CPU khác nhau (x86, ARM, MIPS, etc.) trong một định dạng nhất quán. Điều này giúp chuẩn hóa việc phân tích mã từ nhiều nguồn khác nhau.
e Ngôn ngữ trung gian cấp thấp: VEX-IR là ngôn ngữ trung gian cấp thấp, gần với mã máy nhưng van dễ hiểu hơn đối với con người. N6 cung cấp một tập hợp các lệnh cơ bản để biểu diễn các thao tác như di chuyển dữ liệu, tính toán, và các lệnh điều khiển luồng. e Hỗ trợ nhiều phép toán và kiểu dữ liệu: VEX-IR hỗ trợ các phép toán số học, logic, so sánh, và các phép toán trên bộ nhớ. Nó cũng hỗ trợ nhiều kiểu dữ liệu như số nguyên, số thực, và các kiểu dữ liệu vector.
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.