Computer - Communication - Control. 3C INC
 
Nhiều người quan tâm
Skip List - đối thủ của cây cân bằng
Trong Java, làm thế nào để lấy processor ID (CPU)?
Visual Foxpro 9.0
Hướng dẫn sử dụng công cụ eclipse lập trình java (Phần 1: download và cài đặt)
Hướng dẫn sử dụng công cụ eclipse lập trình java (Phần 2: Hướng dẫn kéo thả Giao diện)
Java cơ bản đến nâng cao (phần I)

Lập trình


In bài này Gửi bài viết này cho bạn bè
(Thứ Sáu, 25/08/2006-11:21 AM)
Kỹ thuật Override hàm API trong WinXP?
Hỏi: Xin hướng dẫn kỹ thuật Override hàm API trong WinXP, ví dụ Override hàm SetSystemTime hoặc SetLocalTime của Windows bằng Delphi.
 

Đáp:

Kỹ thuật "override" một hàm API Windows là kỹ thuật "lái" các lời gọi hàm đó trong các ứng dụng về 1 hàm mới do mình viết nhằm thực hiện những chức năng theo yêu cầu riêng của mình. Để hiểu rõ ràng chi tiết kỹ thuật này, bạn cần trang bị nhiều kiến thức về hệ thống Windows và lập trình hệ thống, ở đây chúng tôi chỉ trình bày các điểm cơ bản.

Trước hết bạn cần biết rằng mỗi chương trình chạy trên Windows có không gian bộ nhớ riêng dài 4GB được chia làm 2 phần:

• Phần đầu dài 2GB từ địa chỉ 0 tới 2GB, đây là vùng nhớ chứa code và dữ liệu riêng của chương trình, không một chương trình nào khác có thể truy xuất được vùng bộ nhớ này.

• Phần sau dài 2GB từ địa chỉ 2GB tới 4GB, đây là vùng nhớ dùng chung giữa các chương trình, nó chứa các module HĐH Windows, các driver thiết bị I/O và tất cả các hàm trong các thư viện liên kết động *.dll đang được dùng bởi bất kỳ ứng dụng nào.


Như vậy các hàm API Windows và các hàm thư viện *.dll đều nằm trong vùng nhớ dùng chung bởi tất cả chương trình, việc "override" 1 hàm nào đó về nguyên tắc sẽ ảnh hưởng đến mọi chương trình gọi hàm này. Ý tưởng "override" 1 hàm API được minh họa bằng hình sau:

Thí dụ bạn cần override hàm "Func" trong thư viện *.dll nào đó (mỗi hàm API Windows đều nằm trong file *.dll nào đó), các bước cơ bản cần thực hiện là:

• Viết 1 hàm khác có cùng giao tiếp sử dụng như hàm "Func" (prototype, interface), đặt hàm "NewFunc" này trong 1 thư viện *.dll nào đó của bạn để khi được nạp vào bộ nhớ, Windows sẽ nạp nó vào vùng nhớ dùng chung, nhờ đó tất cả ứng dụng đều dùng được.

• Xác định địa chỉ hàm "Func" trong vùng nhớ dùng chung.

• Lưu 5 byte đầu của hàm "Func" để phục vụ cho việc phục hồi lại sau này (nếu cần).

• Ghi 5 byte miêu tả lệnh jump về địa chỉ đầu của hàm "NewFunc" của bạn (lệnh jump là lệnh máy của CPU Intel, gồm 1 byte mã lệnh + 4 byte miêu tả địa chỉ nhảy đến).

Từ đây mỗi khi 1 ứng dụng nào đó gọi hàm "Func", lệnh đầu của hàm này bây giờ là lệnh jump nhảy về hàm "NewFunc", ở đây chứa các lệnh mà bạn viết theo yêu cầu xử lý của mình.

Các bước cơ bản trên được miêu tả bằng đoạn lệnh C++ sau đây (lưu ý rằng môi trường lập trình Delphi dùng ngôn ngữ Pascal nên khó viết đoạn lệnh dưới đây hơn C++):

//hàm override 1 hàm trong file *.dll
//hàm này nên nằm chung file thư viện *.dll với hàm newfunc
void Ovr_func(char* libname, char *funcname, FARPROC newfunc,
 char *funcbuf, char *f_Installed, BOOL yes)
{
//khai báo các biến cần dùng
FARPROC OldFunction,NewFunction;
HANDLE UserLib, hprocess;
PDWORD phl;
BOOL fOk = FALSE;
DWORD dwOldProtect, dwNewProtect, dwnumbyte;
BYTE buff[20];
MEMORY_BASIC_INFORMATION mbi;
   //tìm handle của process hiện hành
   hprocess = GetCurrentProcess();
   //load thư viện chứa hàm cần override
   UserLib=LoadLibrary(libname);
   //xác định địa chỉ đầu hàm cần override
   OldFunction=GetProcAddress(UserLib,funcname);
   //xác định địa chỉ đầu hàm mới
   NewFunction=MakeProcInstance(newfunc,hModuleDll);
   //tạo lệnh jump từ hàm cũ đến hàm mới
   buff[0]= 0xe9;
   phl = (PDWORD)&buff[1];
   *phl = (DWORD)NewFunction-(DWORD)OldFunction-5;
   // đọc các thuộc tính bảo vệ bộ nhớ hiện hành của trang chứa hàm cũ
   VirtualQuery((LPVOID)(DWORD)OldFunction, &mbi, sizeof(mbi) );
   dwNewProtect = mbi.Protect;
   dwNewProtect &= ~(PAGE_READONLY | PAGE_EXECUTE_READ);
   dwNewProtect |= (PAGE_READWRITE);
   // hiệu chỉnh lại các thuộc tính bảo vệ bộ nhớ hiện hành của trang chứa hàm cũ để có thể ghi nội dung lên
   fOk=VirtualProtect((LPVOID)(DWORD)OldFunction, 5,dwNewProtect, &dwOldProtect);
   // đọc các byte đầu cần lưu giữ của hàm cũ
   fOk=ReadProcessMemory(hprocess, (LPVOID)(DWORD)OldFunction,
   (LPVOID)(DWORD) funcbuf, 5, &dwnumbyte);
   // ghi lệnh jump vào đầu hàm cũ
   fOk=WriteProcessMemory(hprocess, (LPVOID)(DWORD)OldFunction,
   (LPVOID)(DWORD) buff, 5, &dwnumbyte);
   // giải phóng file thư viện
   FreeLibrary(UserLib);
}

Download Portable IDM
PM download file trên mạng cực nhanh, nhỏ gọn, miễn phí

   Download Winrar 3.80
PM nén và giải nén file xuất sắc. Chương trình nhỏ gọn, dễ sử dụng.

    [ Các bài mới ]
    [ Các bài đã đăng ]

    Download BKAV Home
    phiên bản mới nhất

    Bài mới cập nhật
    15 tính năng được mong chờ nhất trên iPhone 4G
    Văn hóa game thủ ngày 8/3
    Kế Toán Bằng Excel
    Viettel không tham dự bình chọn mạng di động của năm
    “Quay phim” desktop với Free Screen Capture
    Điểm báo ngày 11/3/2010
    Khối trường công an: 31/3 hết hạn sơ tuyển
    Cách chọn mua máy điều hòa
    Nhiều người Trung Quốc khiếu nại laptop HP bị lỗi
    Toshiba NB305: Netbook cho dân sành điệu.
     
     
     
    COMPUTER - COMMUNICATION - CONTROL 3C, INC.
    Số 6 - Láng Hạ - Ba Ðình - Hà Nội; Tel: 84.4.38312695; Fax: 84.4.38311925
    Copyright © 2005 3C INC. All rights reserved.