Những gì bạn đang hỏi là có thể thực hiện được nhưng không dễ dàng.
Một cách để làm điều đó là bù đắp cho việc di chuyển mã trong hướng dẫn của nó. Bạn cần phải tìm tất cả các hướng dẫn sử dụng địa chỉ liên quan đến RIP (chúng có các byte ModRM
là 05h, 0dh, 15h, 1dh, 25h, 2dh, 35h hoặc 3dh) và điều chỉnh trường disp32
của mình bằng số lượng di chuyển (di chuyển do đó bị giới hạn ở +/- 2GB trong không gian địa chỉ ảo, có thể không được đảm bảo do không gian địa chỉ 64 bit lớn hơn 4GB).
Bạn cũng có thể thay thế những hướng dẫn với các khoản tương đương của họ, nhiều khả năng thay thế tất cả các hướng dẫn ban đầu với nhiều hơn một, ví dụ:
; These replace the original instruction and occupy exactly as many bytes as the original instruction:
JMP Equivalent1
NOP
NOP
Equivalent1End:
; This is the code equivalent to the original instruction:
Equivalent1:
Equivalent subinstruction 1
Equivalent subinstruction 2
...
JMP Equivalent1End
Cả hai phương pháp này sẽ cần ít nhất một số thói quen x86 tháo thô sơ.
Trước đây có thể yêu cầu sử dụng VirtualAlloc()
trên Windows (hoặc một số tương đương trên Linux) để đảm bảo bộ nhớ chứa bản vá của mã gốc nằm trong khoảng +/- 2GB của mã ban đầu đó. Và phân bổ tại các địa chỉ cụ thể vẫn có thể thất bại.
Sau này sẽ yêu cầu nhiều hơn là chỉ tháo gỡ nguyên thủy, mà còn giải mã và tạo mã lệnh đầy đủ.
Có thể có các quirks khác để làm việc xung quanh.
Có thể tìm thấy ranh giới hướng dẫn bằng cách đặt cờ TF
trong thanh ghi RFLAGS
để làm cho CPU tạo ra lỗi ngắt single-step
ở cuối mỗi lệnh thực hiện. Một trình xử lý ngoại lệ gỡ lỗi sẽ cần phải nắm bắt và ghi lại giá trị của RIP của lệnh tiếp theo. Tôi tin rằng điều này có thể được thực hiện bằng cách sử dụng Structured Exception Handling (SEH)
trong Windows (không bao giờ thử với các ngắt lỗi), không chắc chắn về Linux. Để làm việc này bạn sẽ phải làm cho tất cả các mã thực thi, mọi lệnh.
Btw, có địa chỉ tuyệt đối ở chế độ 64 bit, xem, ví dụ: MOV đến/từ chỉ lệnh tích lũy với opcodes từ 0A0h đến 0A3h.
-mcmodel = lớn nên là giải pháp. tôi phải điều tra tại sao trình biên dịch gcc osx không hỗ trợ nó – nux
Có thể nó đã cũ. Các mô hình mã nhỏ (tiêu chuẩn) và trung bình đã được bổ sung sớm, mô hình lớn đến sau. – hirschhornsalz
tôi cảm ơn bạn rất nhiều điều này có vẻ rất tốt và dứt khoát giải quyết vấn đề giải quyết vấn đề tuyệt đối – nux