Code cave
Code cave hay hang mã là dãy các byte không được sử dụng trong bộ nhớ của tiến trình. Code cave cũng là vùng không được sử dụng trong file thực thi và sẽ được ánh xạ lên không gian bộ nhớ của tiến trình khi thực thi file. Vùng code cave đấy có thể được dùng để inject thêm lệnh chỉ thị tùy chỉnh vào tiến trình. Ví dụVí dụ sau đây nói về use case đơn giản nhất của code cave: chèn lệnh vào đó và làm sao để nó thực thi trước khi phần lệnh chính của chương trình được thực thi. Giả sử cho một file thực thi được thể hiện bằng mã x86, cùng với một vùng "code cave", đơn giản như sau: ; Giả định chương trình sử dụng thư viện C và chạy 64 bit
global main
extern puts
section .text
main:
; fastcall
mov rdi, message ; đưa địa chỉ của chuỗi văn bản vào tham số thứ nhất
call puts ; puts(message)
ret
; Giả sử ở đây có một vùng code cave khá lớn sau khi biên dịch chương trình
message:
db "Hello world", 0
Biên dịch ra file thực thi và chạy nó, trên màn hình dòng lệnh sẽ hiển thị dòng chữ "Hello world". Người ta có thể chỉnh sửa trực tiếp vào file thực thi này, thông qua các công cụ disassembly, theo cách như sau:
Có thể sử dụng các lệnh chỉ thị CALL và RET để đơn giản bớt công việc này. Chẳng hạn như sau: global main
extern puts
section .text
main:
call payload ; chuyển hướng xuống code cave (ghi đè lệnh chỉ thị có sẵn)
call puts
ret
; Bắt đầu code cave
inject_message:
db "Injected", 0
payload:
mov rdi, inject_message
call puts
mov rdi, message ; khôi phục lại lệnh chỉ thị bị ghi đè ở bên trên
ret ; quay trở lại code chính
; Kết thúc code cave
message:
db "Hello world", 0
Sau khi làm thế xong, khi chạy chương trình thì màn hình dòng lệnh sẽ hiện ra dòng chữ "Injected" trước, sau đó mới là "Hello world". Sử dụng thường thấyKhái niệm về code cave này thường hay được giới hacker và giới reverse engineering vận dụng để thực thị mã tùy ý trong chương trình đã biên dịch. Đây có thể là phương pháp có lợi để chỉnh sửa 'chương trình đã biên dịch' ví dụ như để gắn thêm hộp thoại, chỉnh sửa biến số hay thậm chí là vô hiệu hóa phần kiểm tra bản quyền phần mềm. Thường là bằng cách sử dụng 'chỉ thị gọi' (CALL) thường thấy trong nhiều kiến trúc CPU, luồng chương trình sẽ nhảy vào subroutine mới nằm trong code cave. Sau khi thực thi subroutine xong thì có thể sử dụng 'chỉ thị trả về' (RET) để nhảy ra khỏi code cave và quay trở lại phần code ban đầu. Như vậy cho phép chương trình hiện tồn nhảy vào phần code mới thêm mà không gây ra thay đổi đáng kể lên luồng chương trình vốn có. Ưu điểm
Khuyết điểm
Công cụ
Liên kết ngoài |