2012-11-24 26 views
7

Tôi đã nhìn vào một chương trình trong IDA như tôi đã cố gắng tìm hiểu làm thế nào một chức năng nhất định làm việc, khi tôi đi qua một cái gì đó như thế này:Hiệu quả của việc sử dụng JMP trên một địa chỉ hàm là gì?

; C_TestClass::Foo(void) 
__text:00000000 __ZN14C_TestClass7FooEv proc near 
__text:00000000     jmp  __ZN14C_TestClass20Barr ; C_TestClass::Barr(void) 
__text:00000000 __ZN14C_TestClass7FooEv endp 
__text:00000000 

bất cứ ai có thể giải thích cho tôi chính xác những gì nhảy đến một chức năng sẽ làm trong một trường hợp như thế này? Tôi đoán rằng nó hoạt động như một trình bao bọc cho các chức năng khác?

Trả lời

5

Bạn đúng là nhảy thường là cách xử lý hiệu quả các hàm bao bọc không được gạch chân.

Thông thường, bạn phải đọc tất cả các tham số chức năng và đẩy chúng trở lại ngăn xếp trước khi bạn có thể gọi hàm phụ.

Nhưng khi hàm wrapper có cùng một nguyên mẫu chính xác:

  1. Cùng gọi điện thoại ước
  2. thông số tương tự (và theo thứ tự)
  3. Cùng kiểu trả

không có cần cho tất cả các chức năng gọi điện thoại thông thường trên cao. Bạn chỉ có thể nhảy trực tiếp đến mục tiêu. (Các danh mục này có thể không hoàn toàn cần thiết, vì nó vẫn có thể xảy ra trong một số trường hợp khác.)

Tất cả các tham số (trên ngăn xếp hoặc đăng ký) được thiết lập khi gọi chức năng trình bao bọc sẽ được đặt sẵn (và tương thích) cho chức năng phụ.

3

Đây được gọi là số gọi đuôi. Trình biên dịch có thể gọi trực tiếp hàm và để quay lại trình gọi ban đầu mà không gây ra bất kỳ sự cố nào. Ví dụ:

int f(int x) 
{ 
    ... 
    return g(y); 
} 

Trình biên dịch có thể chỉ đơn giản là jmp g ở cuối vì có chỗ cho các đối số trong cùng một vị trí như f 's đối số và giá trị trả về không được sửa đổi trước khi trở về f' s gọi.

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