GCC có một tùy chọn công cụ tự động để vào/ra chức năng.
-finstrument-chức năng Tạo các lệnh gọi thiết bị để truy cập và thoát khỏi các hàm. Ngay sau khi nhập hàm và ngay trước khi thoát hàm, các hàm lược tả sau sẽ được gọi với địa chỉ của hàm hiện tại và trang gọi của hàm đó (Trên một số nền tảng, __buildin_return_address. chức năng hiện tại, do đó, thông tin trang web cuộc gọi có thể không có sẵn cho các chức năng định hình.) void __cyg_profile_func_enter (void *this_fn, void *call_site); __cyg_profile_func_exit (void *this_fn, void *call_site);
tôi hy vọng mọi "khối cơ bản" Có cái gì đó như thế này để tôi có thể tự động ghi lại quá trình thực thi của từng nhánh.
我该怎么做?
Có một chương trình tên là Lop mờ Mỹ fuzzer, giải quyết vấn đề tương tự như phát hiện bước nhảy giữa các khối cơ bản để thu thậpđộ bao phủ cạnh:Nếu khối cơ sở là một đỉnh, những bước nhảy (cạnh) nào sẽ gặp phải trong quá trình thực hiện. Có thể đáng để kiểm tra nguồn của nó. Nó có ba phương pháp:
afl-gcc
Là một trình bao bọc cho gcc, thay thế mã lắp ráp bằng cách viết lại nó theo nhãn khối cơ bản và hướng dẫn nhảy. as
- Plugin trình biên dịch Clang
- Bản vá QEMU để phát hiện mã được biên dịch
Một lựa chọn khác, có lẽ là dễ dàng nhất có thể là sử dụng DynamoRIOHệ thống thiết bị đo động. Không giống như QEMU, nó được thiết kế đặc biệt để triển khai công cụ tùy chỉnh (viết lại mã máy theo cách thủ công hoặc chỉ cần chèn lệnh gọi và trong một số trường hợp, thậm chí tự động nội tuyến nếu tôi hiểu đúng tài liệu). Nếu bạn cho rằng thiết bị đo động là khó, hãy xem các ví dụ của họ - chúng chỉ dài khoảng 100-200 dòng (nhưng ít nhất bạn vẫn cần phải đọc tài liệu của họ đây cũng như chức năng được sử dụng vì nó có thể chứa ý chính: ví dụ: DR xây dựng các khối cơ bản động, khác biệt với các khối cơ bản cổ điển của trình biên dịch ). Bằng cách sử dụng thiết bị đo động, bạn thậm chí có thể sử dụng công cụ cho các thư viện hệ thống đã sử dụng. Nếu đây không phải là điều bạn muốn, bạn có thể sử dụng một cái gì đó như
mô-đun_data_t tĩnh *traced_module;
// trong dr_client_main
traced_module = dr_get_main_module();
// trong trình xử lý sự kiện khối cơ bản
void *app_pc = dr_fragment_app_pc(thẻ);
if (!dr_module_contains_addr(traced_module, app_pc)) {
trả về DR_EMIT_DEFAULT;
}
Tôi là một lập trình viên xuất sắc, rất giỏi!