2008-11-14 31 views
20

Nếu không tìm hiểu chi tiết về lý do tại sao, tôi đang tìm cách thay thế chức năng hạt nhân và cuộc gọi hệ thống từ mô-đun có thể tải. Ý tưởng ban đầu của tôi là viết một số mã để ghi đè lên một số chức năng, có thể lấy chức năng ban đầu (có thể, nếu có thể, gọi hàm), và sau đó thêm một số mã của riêng tôi. Điều quan trọng là hàm mà tôi viết phải có tên của hàm ban đầu, vì vậy mã khác, khi cố gắng truy cập nó, sẽ truy cập vào hàm của tôi thay vào đó.Chức năng ghi đè với các mô-đun trong hạt nhân Linux

Tôi có thể dễ dàng (tương đối) làm điều này trực tiếp trong hạt nhân bằng cách chỉ cần ném mã của tôi vào các chức năng thích hợp, nhưng tôi đã tự hỏi nếu có ai biết một chút ma thuật C không phải là nhất thiết phải là nhân khủng khiếp (hoặc C) thực hành mã hóa có thể đạt được kết quả tương tự.

Suy nghĩ về #defines và typedefs đến với tâm trí, nhưng tôi không thể hoàn toàn hack nó trong đầu của tôi.

Tóm lại: có ai biết cách ghi đè hiệu quả các chức năng trong hạt nhân Linux (từ mô-đun) không? EDIT: Kể từ khi nó được hỏi, về cơ bản tôi muốn đăng nhập một số chức năng (tạo/xóa thư mục, vv) từ bên trong hạt nhân, nhưng vì lợi ích của sanity, một mô-đun có thể tải có vẻ hợp lý hơn là để viết một bản vá lớn cho mã hạt nhân và biên dịch lại trên mọi thay đổi. Một số lượng tối thiểu của mã được thêm vào hạt nhân là okay, nhưng tôi muốn giảm phần lớn công việc cho một mô-đun.

+0

Bạn có thể làm rõ mà một trong ba bạn đang cố gắng để làm: 1) Ghi đè các cuộc gọi đến kernel chức năng từ mã hạt nhân hiện có 2) Ghi đè các cuộc gọi đến kernel chức năng từ mô-đun hạt nhân của bạn 3) Ghi đè các cuộc gọi hệ thống trong vùng người dùng gọi vào hạt nhân Trừ khi số 1 của nó, tôi khuyên bạn nên sử dụng #defines – bmdhacks

+0

1 và 2? Tôi muốn làm cho các cuộc gọi trong hạt nhân chính nó vẫn còn nguyên vẹn, chỉ các chức năng đang được gọi (trong hạt nhân) được thay thế bởi các hàm được định nghĩa trong mô-đun của tôi. Nếu mà làm cho bất kỳ ý nghĩa. –

+0

Không thực sự, nó có lẽ sẽ giúp nếu bạn giải thích phần "tại sao". –

Trả lời

6

Tôi nhận ra rằng câu hỏi là ba tuổi, nhưng vì lợi ích của những người khác đang cố gắng làm điều này, hạt nhân có một giao diện gọi là kprobes để làm những gì bạn cần.

+0

Tôi đã dành một vài phút nhìn vào điều này, và tôi tự hỏi làm thế nào địa ngục tôi (hoặc bất cứ ai khác) không bao giờ tìm thấy điều này ba năm trước đây. Có vẻ đúng. Tôi đã không đi và sử dụng và thử nghiệm này, nhưng vì nó có vẻ phù hợp với những gì tôi đang tìm kiếm, tôi sẽ đi trước và đánh dấu điều này là chính xác! –

3

Tôi không hoàn toàn chắc chắn rằng tôi hiểu những gì bạn muốn làm, nhưng tôi nghĩ rằng ksplice có thể là một giải pháp tốt. Nó vẫn đang được phát triển, vì vậy tôi không biết liệu nó có ở trong bất kỳ điều kiện nào có thể sử dụng được ngay bây giờ hay không.

+0

Những gì tôi đang xem không thực sự phải làm với việc nạp lại kernel nhiều như mô đun hóa mã của tôi trong nhân, và tránh thực hiện các thay đổi đối với mã hiện tại càng nhiều càng tốt. –

0

Hầu hết công việc hệ thống tệp được thực hiện trong mô-đun, giả sử rằng mã hệ thống tệp được xây dựng dưới dạng mô-đun, thay vì được tích hợp vào hạt nhân (nghĩa là câu trả lời 'thực' phụ thuộc vào tùy chọn xây dựng hạt nhân).

Giả sử rằng các bit bạn muốn đăng nhập là tất cả các hệ thống tập tin liên quan, và rằng những thói quen hệ thống tập tin được xây dựng như mô-đun, bạn chỉ có thể thay đổi mô-đun hệ thống tập tin (s) bạn quan tâm, và tải lại chúng .

Nếu những giả định đó không đúng, hoặc không thể thực hiện được, thì mọi thứ rõ ràng trở nên phức tạp hơn, và tôi thực sự không thể chỉ cho bạn nhiều hơn nữa.

+0

Thú vị, mặc dù lý tưởng tôi muốn được đăng nhập ở một mức độ cao hơn so với hệ thống tập tin cụ thể (như sys_write hoặc vfs_write). Tôi làm việc đó ở cấp độ đó sẽ làm cho hệ thống tập tin mã của tôi trở nên bất khả tri. –

4

Bạn có thể muốn hook the system calls (liên kết PDF), điều này có hiệu quả sẽ cho phép bạn ghi nhật ký các chức năng hạt nhân gọi thủ tục của người dùng. Nếu bạn thực sự muốn đăng nhập kernel sử dụng các chức năng hạt nhân, bạn muốn xem xét kernel function trace.

+0

Liên kết PDF nào? :-P –

+0

Người bị tấn công bởi trình phân tích cú pháp đánh dấu. Cảm ơn vì đã chú ý; sửa nó. – geocar

0

Vì bạn chỉ muốn ghi lại các cuộc gọi (nghĩa là bạn sẽ không ghi đè lên chúng), và một số thay đổi nhỏ đối với mã hạt nhân có thể chấp nhận được, cách sạch nhất là thêm một móc vào mỗi hàm bạn quan tâm trong (sử dụng một chuỗi thông báo hoặc thậm chí một con trỏ hàm đơn giản). Mô-đun của bạn sau đó chỉ cần đăng ký chính nó với tất cả các móc bạn đã thêm (và hủy đăng ký chúng khi không tải).

Cũng có khả năng người khác đã thực hiện công việc thêm móc cho bạn.

0

Bạn không muốn sửa đổi các cuộc gọi hệ thống hiện có, bạn muốn thực hiện chúng. Đây là những gì SystemTap là dành cho.Nếu bạn thực sự muốn làm điều đó một cách khó khăn và ngăn chặn các cuộc gọi hệ thống bằng cách mã hóa mô-đun của riêng bạn, tôi khuyên bạn nên đọc một số tài liệu rootkit nhưng tôi không có bất kỳ liên kết nào thuận tiện (mặc dù có ý nghĩ).

1

Đã có nhiều công việc được thực hiện trong hạt nhân để đảm bảo điều này không xảy ra, đặc biệt là làm việc để không hiển thị bảng syscall với mô-đun. Cơ chế duy nhất được hỗ trợ để truy cập tệp nhật ký là LSM, nhưng nó được định hướng theo hướng bảo mật và có một không chắc chắn future. Here là tệp PDF ghi lại API nhưng có thể không cập nhật.

inotify là một cách tốt hơn để theo dõi việc tạo, xóa và sửa đổi tệp hơn cố gắng phá hoại các hàm syscall của hạt nhân, nhưng nó hoạt động từ không gian người dùng.

Trích dẫn từ Wikipedia (http://en.wikipedia.org/wiki/Inotify): Một số sự kiện có thể được theo dõi cho là:

* IN_ACCESS - read of the file 
* IN_MODIFY - last modification 
* IN_ATTRIB - attributes of file change 
* IN_OPEN and IN_CLOSE - open or close of file 
* IN_MOVED_FROM and IN_MOVED_TO - when the file is moved or renamed 
* IN_DELETE - a file/directory deleted 
* IN_CREATE - a file/directory created 
* IN_DELETE_SELF - file monitored is deleted 

inotify tồn tại trong hạt nhân kể từ 2.6.13, predecesor của nó là dnotify (http://en.wikipedia.org/wiki/Dnotify).

1

Tôi nghĩ rằng bạn có thể sử dụng audit cho rằng

+0

+1, hệ thống kiểm toán sẽ cho phép OP thực hiện những gì họ dự định ... hoàn toàn từ không gian người dùng. – MarkR

3

Bạn đã nhìn triển khai chức năng của bạn sử dụng LD_PRELOAD?

Chức năng của bạn sẽ được triển khai thông qua một lib được chia sẻ sẽ nằm trong thư mục được chỉ định bởi biến môi trường LD_PRELOAD.

Quy ước là bạn chặn các cuộc gọi hệ thống và sau đó, sau khi thực hiện phép thuật của bạn, hãy chuyển cuộc gọi vào hệ thống shlib thực tế. Nhưng bạn không phải làm vậy.

Có thể xem bài viết "Building library interposers for fun and profit". Trong khi đó là Solaris cụ thể, nó cũng được áp dụng cho Linux.

BTW Đây là cách hầu hết các công cụ phân tích bộ nhớ, ví dụ: Làm sạch, làm việc.

0

Theo KernelTrap.org you can do a simple patch và biên dịch lại kernel để xuất khẩu biến sys_call_table:

// add the following in the file arch/i386/kernel/i386_ksyms.c 
extern void* sys_call_table[]; 
EXPORT_SYMBOL(sys_call_table); 

Sau đó, chỉ cần làm theo this procedure for replacing system calls từ Hướng dẫn lập trình Linux Kernel Module:

Các mã nguồn ở đây là ví dụ về mô-đun hạt nhân . Chúng tôi muốn 'gián điệp' trên một người dùng nhất định và đến printk() một thông báo bất cứ khi nào người dùng đó mở tệp . Hướng tới mục đích này, chúng tôi thay thế cuộc gọi hệ thống để mở tệp với chức năng riêng của chúng tôi, được gọi là our_sys_open. Chức năng này kiểm tra uid (của người dùng id) của quy trình hiện tại và nếu bằng với số mà chúng tôi theo dõi, số gọi printk() để hiển thị tên của tệp sẽ được mở. Sau đó, cách , nó gọi hàm open() gốc với cùng các thông số, để thực sự mở tệp.

Chức năng init_module thay thế vị trí thích hợp trong sys_call_table và giữ con trỏ gốc trong một biến . Hàm cleanup_module sử dụng biến đó để khôi phục mọi thứ trở lại bình thường. Cách tiếp cận này rất nguy hiểm, vì khả năng khả năng của hai mô-đun hạt nhân thay đổi cùng một cuộc gọi hệ thống. Hãy tưởng tượng chúng tôi có hai mô-đun hạt nhân, A và B. Cuộc gọi hệ thống của 01 sẽ là A_open và B sẽ là B_open. Bây giờ, khi A được gắn vào hạt nhân, hệ thống được thay thế bằng A_open, trong đó sẽ gọi số sys_open gốc khi hoàn thành. Tiếp theo, B được chèn vào hạt nhân, thay thế hệ thống cuộc gọi với B_open, gọi số nó nghĩ là cuộc gọi hệ thống ban đầu, A_open, khi hoàn thành.

1

This có thể chứng minh một cách hữu ích cho bạn.

Về cơ bản, vì bảng gọi hệ thống không được xuất trực tiếp trong các hạt nhân mới hơn, bạn phải tự tìm kiếm để xác định vị trí của nó. Sau đó, bạn có thể chặn các cuộc gọi hệ thống của bạn lựa chọn và thao tác chúng. Thay vào đó các chức năng hạt nhân khác sẽ khó khăn hơn nhiều, trừ khi một vài trong số chúng được tổ chức theo cùng một cách gọi hệ thống (chúng xuất hiện trên một số bảng công văn, vv) - điều này không hề phổ biến.

0

Nếu các thư viện được chia sẻ gọi một cuộc gọi hệ thống, bạn sẽ thực hiện một mô-đun để thay đổi cuộc gọi sysltem đó. Để biết thêm thông tin về thay đổi cuộc gọi hệ thống, bạn có thể muốn xem tại đây http://www.xml.com/ldd/chapter/book/ có điều gì đó trong đó về cách chúng thay đổi những gì hệ thống mở() gọi. Một ví dụ là ở đây http://tldp.org/LDP/lkmpg/x931.html

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