2014-07-20 18 views
8
int eax = ((int(*)())("\xc3 <- This returns the value of the EAX register"))(); 

Cách thức hoạt động? Chuỗi được đúc thành con trỏ hàmLập trình C (Hàm con trỏ đúc)

+3

không chắc chắn nó có hoạt động không. Nếu bất cứ điều gì, sau đó có thể 'c3' trong hệ thập lục phân là opcode trả lại thanh ghi EAX hoặc một cái gì đó như thế này. Nhưng thực sự, rất nhiều bối cảnh bị thiếu. –

+1

Đây là ngữ cảnh gốc: http://stackoverflow.com/a/5602143/544557 –

+0

Và đây là phiên bản sau: https://gist.github.com/leegao/910993 –

Trả lời

11

c3 là hướng dẫn RET. Khi một máy x86 nhảy vào chuỗi này được hiểu là mã, nó sẽ thực thi RET và do đó nhảy ngược lại mà không cần phải làm gì (phần còn lại của chuỗi do đó bị bỏ qua). Vì quy ước gọi chuẩn trên x86 là đặt giá trị trả về của bạn trong eax, nhưng mã không làm bất cứ điều gì trước khi trở về, bất kỳ điều gì đã có trong eax sẽ vẫn ở đó và ở vị trí mã C để diễn giải nó "trả lại".

Điều này phụ thuộc nhiều vào máy của bạn là x86 và bạn được phép truyền giữa dữ liệu và con trỏ hàm (và thực hiện kết quả) - một rất hack dành riêng cho hệ thống. Đây không phải là tiêu chuẩn tuân thủ hoặc di động C bằng bất kỳ khoảng thời gian nào!

(\xXX là cú pháp thoát C để chèn ký tự nonreadable duy nhất vào chuỗi thông qua mã ASCII của họ trong hex, nếu bạn không biết rằng một phần.)

5

0xc3ret opcode trong x86. Phần còn lại của chuỗi chỉ có cho hương vị. Tất cả các công việc được thực hiện bởi quy ước gọi điện thoại, và quy ước gọi cdecl (mặc định cho ngôn ngữ C) nói rằng một hàm trả về int trả về nó trong eax.

Chức năng của bạn không thực sự làm bất cứ điều gì, nó chỉ trả về ngay sau khi nó được gọi là, nhưng bất kỳ mã mà các cuộc gọi int foo = eax() vẫn sẽ mong đợi nó đã đưa giá trị trả về của nó vào eax đăng ký, vì vậy nó sẽ để sao chép nội dung của eax đăng ký vào foo.

Các vấn đề liên quan