VicoTas
Câu hỏi
avatar nhocac191
08/07/2013 13:47

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?



Danh sách câu trả lời (1)
avatar ChoeGa 25/05/2013 20:37
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);
}

Chúc bạn thành công!
Trả lời câu hỏi
Tải lại mã
Câu hỏi lĩnh vực Lập trình
Link Phiên bản VB.Net mới nhất?

Đăng lúc: 20:37 - 25/05/2013 trong Lập trình

nophoto Em đang học lập trình hệ thống bằng hợp ngữ và C. Nhờcác anh/ chị giới thiệu một số tài liệu để tham khảo?

Đăng lúc: 20:37 - 25/05/2013 trong Lập trình

nophoto Sự kiện WM_LBUTTONUP là thả chuột trái, WM_LBUTONDOWN là nhấn chuột trái... Vậy có cách nào để hủy sự kiện nhấn và thả chuột không?

Đăng lúc: 20:37 - 25/05/2013 trong Lập trình

nophoto Trong lập trình VB, khi nhấn phím Enter, focus sẽ tự động nhảy sang control có index kế tiếp?

Đăng lúc: 20:36 - 25/05/2013 trong Lập trình

nophoto Xin giải thích từng toán tử trong ngôn ngữ VB 6.0 bao gồm toán tử số học, toán tử so sánh, toán tử logic?

Đăng lúc: 20:36 - 25/05/2013 trong Lập trình

nophoto Xin hướng dẫn cách tạo form có giao diện WinXP trong VB6?

Đăng lúc: 17:05 - 22/07/2013 trong Lập trình

nophoto Trong VB 6.0, có cách nào làm cho nội dung của textbox có nhiều màu sắc khác nhau?

Đăng lúc: 20:36 - 25/05/2013 trong Lập trình

nophoto Xin hướng dẫn viết chương trình đọc dữ liệu (điện áp, tốc độ động cơ...) từ cổng COM ?

Đăng lúc: 20:36 - 25/05/2013 trong Lập trình

nophoto Xin hướng dẫn lập trình VB 6 lấy dữ liệu trọng lượng từ cân điện tử bên ngoài (cân điện tử có nhiều cổng: COM, USB...)?

Đăng lúc: 20:36 - 25/05/2013 trong Lập trình

Hương Xin hướng dẫn viết chương trình chat cho phép gởi hình mặt cười từ server sang client bằng DHTML control ?

Đăng lúc: 20:36 - 25/05/2013 trong Lập trình

nophoto Để chạy 1 chương trình viết bằng các ngôn ngữ .Net (cụ thể là VB.Net), máy tính bắt buộc phải có cài Net Framework?

Đăng lúc: 20:36 - 25/05/2013 trong Lập trình

nophoto Xin hướng dẫn hiện thực thuật giải Huffman bằng ngôn ngữ Pascal???

Đăng lúc: 23:33 - 26/06/2013 trong Lập trình

nophoto Dùng C# trên Visual Studio.NET hay Java trên JBuilder viết chương trình chỉ có 1 nút lệnh cũng chiếm đến 2 MB?

Đăng lúc: 20:36 - 25/05/2013 trong Lập trình

nophoto Vì sao dùng hàm Pset có sẵn trên VB thì lại chậm hơn so với SetPixel của API?

Đăng lúc: 20:36 - 25/05/2013 trong Lập trình

nophoto Lập trình VB 6.0 dùng hàm Sendkeys {"Tab"} để dời focus trên các đối tượng trên form nhưng có lúc được có lúc không?

Đăng lúc: 20:36 - 25/05/2013 trong Lập trình

nophoto Làm thế nào để có thể lập trình với bộ thư viện của Lạc Việt?

Đăng lúc: 20:36 - 25/05/2013 trong Lập trình

nophoto Xin hỏi cách chuyển 1 ký tự Unicode 2 byte trong C# và VB.NET thành ký tự ASCII?

Đăng lúc: 20:36 - 25/05/2013 trong Lập trình

Thu Trang Phương pháp lập trình lập lịch CPU theo kiểu round-robin?

Đăng lúc: 20:36 - 25/05/2013 trong Lập trình

lê văn nguyên Xin hướng dẫn lập trình C++ xuất file *.bmp ra màn hình?

Đăng lúc: 20:36 - 25/05/2013 trong Lập trình

nophoto Trong VB.Net 2005 làm sao để nắm bắt sự kiện khi nhấn ENTER thì focus nhảy từ textbox1 sang textbox2 và ngược lại?

Đăng lúc: 20:35 - 25/05/2013 trong Lập trình

Rao vặt Siêu Vip