ngxhuy
03-03-2010, 01:06 AM
Author: Benina (2009)
Đây là loạt tuts nói về các kiến thức cơ bản cần biết khi lập trình một device driver hay cụ thể hơn là lập trình một rootkit.
1. Khái niệm về driver và device:Driver được phiên dịch là một trình điều khiển. Vậy nó điều khiển cái gì?. Nó điều khiển device (thiết bị). Driver làm việc khác với một chương trình bình thường. Muốn tìm hiểu về driver, đầu tiên chúng ta nói sơ qua về cách làm việc của một chương trình bình thường. Một chương trình bình thường mà chúng ta thường thấy là một file thực thi (exe,...). Khi chúng thực thi chúng có thể có nhiều module được load vào trong memory. Mỗi module là một file ví dụ như file exe, dll,.... Ngoài ra chúng ta còn phải biết trong quá trình thực thi của một chương trình thì chúng có thể tạo ra nhiều processes và threads. Hệ điều hành có cơ chế phân thời gian thực thi cho mỗi thread. Hay còn gọi là lập lịch trình cho thread. Nhưng driver thì ko làm việc như vậy. Chúng được load vào trong memory ko như cách thực thi của một chương trình thông thường. Phải có một chương trình nào đó (hoặc trình loader của Windows) load nó vào trong memory. Khi được load vào memory rồi thì khi khởi động lại máy nó cũng có thể (nếu người viết driver muốn) tự động được HĐH (trình loader của Windows) load lên memory mà ko cần chương trình nào (hay client) load nữa. Muốn vậy OS đăng ký key cho driver trong registry để tự khởi động lần sau cùng OS.
Đồng thời, muốn driver điều khiển một thiết bị (device) nào đó thi chúng ta cũng phải cài đặt một device để nó điều khiển. Khi driver được load vào trong memory cũng như device đã được cài đặt, muốn driver điều khiển thiết bị thì ta phải buộc hệ điều hành truyền lệnh cho nó (driver) thông qua một dạng giống như thông điệp có tên là request I/O (yêu cầu Nhập/Xuất). HĐH sẽ có một I/O Manager gọi là trình quản lý I/O để quản lý các request I/O.
Chú ý rằng driver khi load vào memory chỉ có 1 module chứ ko như program bình thường khi thực thi có thể load nhiều module(file exe, dll,…) vào memory. Thêm nữa như trên có nói, driver ko thể giao tiếp với user bằng cách qua giao diện như một chương trình bình thường. User chỉ có thể giao tiếp với driver thông qua 1 chương trình gọi là client. Chương trình này sẽ cài đặt một request I/O để thực hiện một yêu cầu nào đó của user và trình I/O Manager của OS sẽ xử lý request I/O phù hợp với driver nào.
Một điều quan trọng cần nhắc lại,như trên đã viết driver khi load vào memory thì chỉ có một module thực thi là file sys chứ ko như file exe khi thực thi thì nó còn load các dlls đính kèm.
Khi lập trình Windows, OS quản lý và định thể một driver hay một device bằng một đối tượng Object. Vì vậy OS sẽ có một Trình quản lý đối tượng (Objects Manager) để quản lý các đối tượng của hệ thống.
Ngoài ra chúng ta cần biết là các ứng dụng người dùng (user app) chạy trong chế độ người dùng (user-mode), còn các driver thì chạy trong chế độ nhân hệ thống (kernel-mode). Tương ứng, hệ thống sẽ cấp phát và chia sẽ hai loại vùng nhớ cho hai chế độ này khác nhau. OS sẽ quản lý bộ nhớ thông quaTrình quản lý bộ nhớ (Memory Manager). Các chương trình chạy trong kernel-mode sẽ có chính sách quản lý “khắc khe” và “bảo mật” hơn trong user-mode. Vì OS sẽ tín nhiệm cao các trình chạy trong chế độ kernel-mode. Hai mode này còn được biết đến với cái tên là ring0 (kernel) và ring3 (user).
Tóm lại đến thời điềm này chúng ta thấy OS có rất nhiều trình quản lý, như một số trình quản lý như sau:
-I/O Manager
-Objects Manager
-Memory Manager -. . .v. .v. .
2.Threads và Driver code:
Với những kiến thức ở trên chúng ta thấy hai processes khác nhau có thể request (yêu cầu) 1 dịch vụ (server) của một driver nào đó. Trong user mode, Windows đã ko thể thực thi cùng 1 lúc 2 thread , nó thực thi tuần tự các threads. Tức là tại một thời điểm sẽ có một thread duy nhất đang chạy. Thread này còn gọi là thread hiện hành. Mỗi thread khi thực thi tại một thời để sẽ có một context (ngữ cảnh) của thread, tức là trạng thái dữ liệu của system (như các giá trị các thanh ghi,….) tại thời điểm thread thực thi.
Vậy code driver chỉ thực thi khi OS thông qua I/O Manager phát ra một yêu cầu ngắt (request I/O : còn gọi là yêu cầu Nhập/Xuất) tương ứng để thực thi code driver đó. Khi đó, toàn bộ hoạt động của hệ thống sẽ tạm dừng, và trong ngữ cảnh (context) thread hiện hành, code driver sẽ thực thi các chỉ lệnh của nó. Và như bạn thấy, OS sẽ ko thể thực thi 2 yêu cầu ngắt cùng một lúc (do hai thread yêu cầu ngắt chạy ko cùng lúc).
Từ đó ta thấy, trong Kernel, code driver chạy trong ngữ cảnh (thread context) thread hiện hành bất kỳ khi ngắt gọi code driver xảy ra. Thread hiện hành mà lúc code driver thực thi chứ ko phải là thread chương trình client của bạn gởi request I/O đến driver xử lý. Hệ thống ko tự động tạo thread riêng thực thi code driver.
Còn thread system là một đề tài khác. Muốn cài đặt thread system ta dùng hàm PsCreateSystemThread. Thường là cài đặt loại IRP đồng bộ (synchronous IRP) trong một thread system để send đến một driver khác . I/O Manager sẽ trói buộc synchronous IRP trong thread cài đặt. Cần nhiều giấy mực để thông suốt. Chúng ta tìm hiểu đề tài này ở tut khác.
Benina
Xin phép được chép nguyên văn của chị Benina ko nói thêm ! Nếu ai có thắc mắc gi` thi` pm lại nha ;)) mình sẽ cố gắn giải thích
Đây là loạt tuts nói về các kiến thức cơ bản cần biết khi lập trình một device driver hay cụ thể hơn là lập trình một rootkit.
1. Khái niệm về driver và device:Driver được phiên dịch là một trình điều khiển. Vậy nó điều khiển cái gì?. Nó điều khiển device (thiết bị). Driver làm việc khác với một chương trình bình thường. Muốn tìm hiểu về driver, đầu tiên chúng ta nói sơ qua về cách làm việc của một chương trình bình thường. Một chương trình bình thường mà chúng ta thường thấy là một file thực thi (exe,...). Khi chúng thực thi chúng có thể có nhiều module được load vào trong memory. Mỗi module là một file ví dụ như file exe, dll,.... Ngoài ra chúng ta còn phải biết trong quá trình thực thi của một chương trình thì chúng có thể tạo ra nhiều processes và threads. Hệ điều hành có cơ chế phân thời gian thực thi cho mỗi thread. Hay còn gọi là lập lịch trình cho thread. Nhưng driver thì ko làm việc như vậy. Chúng được load vào trong memory ko như cách thực thi của một chương trình thông thường. Phải có một chương trình nào đó (hoặc trình loader của Windows) load nó vào trong memory. Khi được load vào memory rồi thì khi khởi động lại máy nó cũng có thể (nếu người viết driver muốn) tự động được HĐH (trình loader của Windows) load lên memory mà ko cần chương trình nào (hay client) load nữa. Muốn vậy OS đăng ký key cho driver trong registry để tự khởi động lần sau cùng OS.
Đồng thời, muốn driver điều khiển một thiết bị (device) nào đó thi chúng ta cũng phải cài đặt một device để nó điều khiển. Khi driver được load vào trong memory cũng như device đã được cài đặt, muốn driver điều khiển thiết bị thì ta phải buộc hệ điều hành truyền lệnh cho nó (driver) thông qua một dạng giống như thông điệp có tên là request I/O (yêu cầu Nhập/Xuất). HĐH sẽ có một I/O Manager gọi là trình quản lý I/O để quản lý các request I/O.
Chú ý rằng driver khi load vào memory chỉ có 1 module chứ ko như program bình thường khi thực thi có thể load nhiều module(file exe, dll,…) vào memory. Thêm nữa như trên có nói, driver ko thể giao tiếp với user bằng cách qua giao diện như một chương trình bình thường. User chỉ có thể giao tiếp với driver thông qua 1 chương trình gọi là client. Chương trình này sẽ cài đặt một request I/O để thực hiện một yêu cầu nào đó của user và trình I/O Manager của OS sẽ xử lý request I/O phù hợp với driver nào.
Một điều quan trọng cần nhắc lại,như trên đã viết driver khi load vào memory thì chỉ có một module thực thi là file sys chứ ko như file exe khi thực thi thì nó còn load các dlls đính kèm.
Khi lập trình Windows, OS quản lý và định thể một driver hay một device bằng một đối tượng Object. Vì vậy OS sẽ có một Trình quản lý đối tượng (Objects Manager) để quản lý các đối tượng của hệ thống.
Ngoài ra chúng ta cần biết là các ứng dụng người dùng (user app) chạy trong chế độ người dùng (user-mode), còn các driver thì chạy trong chế độ nhân hệ thống (kernel-mode). Tương ứng, hệ thống sẽ cấp phát và chia sẽ hai loại vùng nhớ cho hai chế độ này khác nhau. OS sẽ quản lý bộ nhớ thông quaTrình quản lý bộ nhớ (Memory Manager). Các chương trình chạy trong kernel-mode sẽ có chính sách quản lý “khắc khe” và “bảo mật” hơn trong user-mode. Vì OS sẽ tín nhiệm cao các trình chạy trong chế độ kernel-mode. Hai mode này còn được biết đến với cái tên là ring0 (kernel) và ring3 (user).
Tóm lại đến thời điềm này chúng ta thấy OS có rất nhiều trình quản lý, như một số trình quản lý như sau:
-I/O Manager
-Objects Manager
-Memory Manager -. . .v. .v. .
2.Threads và Driver code:
Với những kiến thức ở trên chúng ta thấy hai processes khác nhau có thể request (yêu cầu) 1 dịch vụ (server) của một driver nào đó. Trong user mode, Windows đã ko thể thực thi cùng 1 lúc 2 thread , nó thực thi tuần tự các threads. Tức là tại một thời điểm sẽ có một thread duy nhất đang chạy. Thread này còn gọi là thread hiện hành. Mỗi thread khi thực thi tại một thời để sẽ có một context (ngữ cảnh) của thread, tức là trạng thái dữ liệu của system (như các giá trị các thanh ghi,….) tại thời điểm thread thực thi.
Vậy code driver chỉ thực thi khi OS thông qua I/O Manager phát ra một yêu cầu ngắt (request I/O : còn gọi là yêu cầu Nhập/Xuất) tương ứng để thực thi code driver đó. Khi đó, toàn bộ hoạt động của hệ thống sẽ tạm dừng, và trong ngữ cảnh (context) thread hiện hành, code driver sẽ thực thi các chỉ lệnh của nó. Và như bạn thấy, OS sẽ ko thể thực thi 2 yêu cầu ngắt cùng một lúc (do hai thread yêu cầu ngắt chạy ko cùng lúc).
Từ đó ta thấy, trong Kernel, code driver chạy trong ngữ cảnh (thread context) thread hiện hành bất kỳ khi ngắt gọi code driver xảy ra. Thread hiện hành mà lúc code driver thực thi chứ ko phải là thread chương trình client của bạn gởi request I/O đến driver xử lý. Hệ thống ko tự động tạo thread riêng thực thi code driver.
Còn thread system là một đề tài khác. Muốn cài đặt thread system ta dùng hàm PsCreateSystemThread. Thường là cài đặt loại IRP đồng bộ (synchronous IRP) trong một thread system để send đến một driver khác . I/O Manager sẽ trói buộc synchronous IRP trong thread cài đặt. Cần nhiều giấy mực để thông suốt. Chúng ta tìm hiểu đề tài này ở tut khác.
Benina
Xin phép được chép nguyên văn của chị Benina ko nói thêm ! Nếu ai có thắc mắc gi` thi` pm lại nha ;)) mình sẽ cố gắn giải thích