2012-03-06 29 views
6

Trong gcc, công cụ này hoạt động tốt. Mã này đi một cái gì đó như:Thực thi shellcode bằng cách truyền tới con trỏ hàm trong Visual C++

unsigned char b[50] = "\xda\xd1 ... \x0"; //some shellcode with terminating \x0 
((void(*)())b)(); //cast b to function pointer from void to void, then run it 

Nhưng khi điều này được đặt trong Visual C++, nó spits ra thông báo lỗi này:

1>..\test.cpp(132): error C2440: 'type cast' : cannot convert from 'unsigned char [50]' to 'void (__cdecl *)(void)' 
1>   There is no context in which this conversion is possible 

Bất cứ ai biết tại sao điều này là như vậy?

+1

thử '(* (void (*)()) & b [0])()'. –

+0

Ngay cả khi bạn nhận được điều này để làm việc bằng cách nào đó, đó là một ý tưởng rất xấu. –

+0

Hoặc: 'reinterpret_cast (static_cast (b))()'. –

Trả lời

10

Trình sửa lỗi thích hợp sẽ cho bạn biết điều gì đang xảy ra. Tôi chỉ có thể đoán rằng mã của bạn đang gây ra vi phạm quyền truy cập vì bộ đệm bạn muốn chuyển đến không thực thi được.

Có thể bạn đang sử dụng hệ thống được kích hoạt mặc định - DEP như Vista hoặc 7, vì vậy bạn phải đảm bảo rằng shellcode của bạn có thể thực thi được. Để làm điều đó, đầu tiên sử dụng VirtualAlloc để phân bổ một, đệm thực thi mới và sao chép shellcode của bạn vào nó, sau đó thực hiện nó:

void *exec = VirtualAlloc(0, sizeof b, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 
memcpy(exec, b, sizeof b); 
((void(*)())exec)(); 

Bằng cách này, bạn không cần phải null-chấm dứt shellcode (C++ sẽ chấm dứt chuỗi chữ tự động cho bạn, nhưng điều này là không cần thiết). Bạn cũng không cần chỉ định kích thước:

unsigned char b[] = "\xcc"; 
+0

Cảm ơn bạn - điều này hoạt động đúng. Không biết rằng có một chức năng phân bổ đặc biệt để thực hiện các công cụ. – Arcinde

+1

@ user49164: Để tăng độ khó của việc khai thác tràn bộ đệm dựa trên chồng và đống, DEP thực thi sự vâng lời của các quyền thực thi trên các trang bộ nhớ. Điều này ngăn chặn việc thực hiện ngay lập tức dữ liệu trên stack hoặc đống. 'VirtualAlloc' không phải là một chức năng phân bổ đặc biệt để thực hiện các công cụ, đó là chức năng phân bổ chung (mà xảy ra để lấy làm đối số các quyền truy cập mong muốn của bộ nhớ được cấp phát). –

0

Cách điển hình để diễn giải dữ liệu như là một loại khác nhau là bằng cách sao chép các đại diện nhị phân:

void (*fp)(); 
unsigned char buf[50]; 
char const * p = reinterpret_cast<char const *>(&buf); 

std::copy(p, p + sizeof(char const *), reinterpret_cast<char*>(&fp)); 

// now fp contains the same value as &buf 

fp(); // call 

Điều này tránh hành vi undefined do răng cưa và vi phạm liên kết.

+0

OP đang cố gắng diễn giải lại con trỏ tới bộ đệm dưới dạng con trỏ hàm, để thực thi nội dung dưới dạng mã. Phiên bản của bạn sẽ ghi đè con trỏ hàm bằng một số nội dung của bộ đệm - kết quả chắc chắn không phải là một con trỏ hợp lệ. Bạn sẽ cần phải định nghĩa một con trỏ tới 'buf', sau đó sao chép giá trị của nó. Đã xác nhận –

+0

. Điều này bị treo khi chạy. – Arcinde

+0

@ user49164: Có, Mike đã đúng. Xin lỗi vì điều đó. Đã sửa. –

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