2010-07-11 26 views
8
#include <stdio.h> 

int main(int argc, char** argv) 
{ 
    void (*p) (void); 
    /* this obviously won't work, but what string could I put in 
     here (if anything) to make this execute something meaningful? 
     Does any OS allow instructions to be read from 
     the stack rather than text area of the process image? */ 
    char *c = "void f() { printf(\"Hello, world!\"); }"; 
    p = (void (*)())c; 
    p(); 
    return 0; 
} 

Trả lời

2

Chắc chắn điều đó là có thể. Buffer Overflow exploits sử dụng nó.

Xem Shellcode để biết loại chuỗi bạn có thể đặt.

Về cơ bản bạn có thể làm gì để đặt mã máy lên ngăn xếp và chuyển đến địa chỉ. Điều này sẽ gây ra việc thực hiện (nếu hệ điều hành/máy cho phép nó, xem NX bit).

Bạn thậm chí có thể cố gắng thực hiện một memcpy từ một số địa chỉ hàm vào một chuỗi trên ngăn xếp và sau đó thử nhảy đến địa chỉ trên ngăn xếp.

+0

Cảm ơn bạn, bạn có thể giải thích một chút về cách tôi sẽ chuyển đến địa chỉ sau memcpy không? Và tôi sẽ ghi nhớ một đoạn bộ nhớ lớn như thế nào? Tôi có phải biết cách hàm được biểu diễn bằng ngôn ngữ assembly cho điều đó không? – user389094

+0

Lưu ý rằng mặc dù chúng ta đang nói về việc chèn mã thực thi nhị phân ở đây - bạn không chỉ có khả năng tràn bộ đệm C và mong đợi bộ xử lý biết WTF bạn đang nói đến. –

+0

@ rahulkumar42: Bạn có thể thử truyền địa chỉ chuỗi làm con trỏ hàm và thử gọi nó. Bạn không thực sự cần biết cách hàm được biểu diễn, máy sẽ thực hiện việc giải thích cho bạn. Kích thước để sao chép phụ thuộc vào chức năng bạn đang sao chép và có thể khó tìm hiểu. –

8

Sắp xếp, nhưng không thực sự, không có eval() bằng c, như trong nhiều ngôn ngữ kịch bản.

Tuy nhiên, những gì bạn mô tả giống như một Buffer Overflow exploit.

Ở đâu, bạn sử dụng chuỗi để viết "mã" (không phải cú pháp c, nhưng mã máy) vào không gian địa chỉ sau bộ đệm. Đây là một chút đẹp tutorial của chủ đề.

Không sử dụng thông tin này để viết một virus :(

+2

Có một 'eval()' loại: viết trình biên dịch C, biên dịch chuỗi thành mã máy, sau đó chạy nó. –

+0

Cảm ơn, ý định của tôi là viết một chương trình tự sửa đổi trong khi thực hiện, có lẽ thậm chí không thể đoán trước được. Không có gì độc hại, chỉ là một bài tập học tập. – user389094

+0

@ Chris: điểm tốt;) @rahul: Chắc chắn là một trải nghiệm học tập tốt, âm thanh vui nhộn :) – Stephen

5

Bạn có thể sử dụng libtcc để biên dịch và chạy mã nguồn C:

const char *code = "int main(int argc, char**argv) { printf(\"Hello, world!\"); return 0; }"; 
TCCState *tcc = tcc_new(); 

if (tcc_compile_string(tcc, code)) 
{ 
    // an error occurred compiling the string (syntax errors perhaps?) 
} 

int argc = 1; 
char *argv[] = { "test" }; 

int result = tcc_run (tcc, argc, argv); 

// result should be the return value of the compiled "main" function. 
// be sure to delete the memory used by libtcc 

tcc_delete(tcc); 

Một coouple các vấn đề:

  1. Bạn chỉ có thể biên dịch libtcc trên kiến ​​trúc được hỗ trợ.
  2. Bạn cần có một main chức năng.
Các vấn đề liên quan