Nghiên cứu phương pháp nhận dạng từ dưới con trỏ chuột trên màn hình Windows sử dụng Hook

MỤC LỤC

TÌM HIEÅU VEÀ HOOKSTÌM HIEÅU VEÀ HOOKS

Hay nói một cách khác hook là một điểm trong kỹ thuật message-handling hệ thống, nơi mà một ứng dụng có thể đặt một thủ tục để quản lý sự lưu thông của các thông điệp trong hệ thống và xử lý một kiểu thông báo nào đó trước khi chúng tới được thủ tục cửa sổ đích. Như vậy qua những lý thuyết về hook trong môi trường Win32 hay trong môi trường Win16 cho chúng ta có nhận xét: dùng kỹ thuật hook cho phép ta đặt một thủ tục để theo dừi, điều khiển và xử lý cỏc thụng điệp của hệ thống Windows theo ý của ta trước lúc thông điệp đó đến được cửa sổ đích.

HÀM APIHÀM API

Đối với các hàm giao tiếp trong môi trường Windows thì khi Windows gọi đến các DLL (Dynamic Link Library – Thư viện liên kết động) tại các điểm nhập của các hàm Kernel, User, GDI… để xử lý các hàm được gọi trong ứng dụng thì chính ở thời điểm này ta có thể chen vào để có thể thực hiện việc hoàn tất bất kỳ thao tác xử lý gì. Như vậy override các hàm thuộc giao tiếp Windows là một kỹ thuật cho phép developer can thiệp vào tiến trình gọi hàm API nhằm thực hiện một thao tác, một công việc gì đó theo mục đích của developer trước khi quá trình thực thi hàm API bắt đầu (theo cách 1) hoặc là ngay sau khi đã kết thúc việc thực thi hàm API (theo cách 2). Như vậy nếu sử dụng kỹ thuật override thì developer có thể lập trình để chen vào tiến trình thực thi các hành vi, thao tác xử lý riêng của mình bằng cách đón đợi thông báo gọi hàm API tương ứng từ chương trình ứng dụng và chuyển hướng điều khiển cho thực thi đoạn chương trình riêng đó mà không cần sửa đổi, biên dịch lại chương trình ứng dụng.

Một vài chương trình xử lý ngắt trong hệ điều hành DOS có thể được override bởi đoạn chương trình xử lý ngắt riêng của user bằng cách gán địa chỉ bộ nhớ nơi mà chương trình xử lý ngắt mới vào bảng vector ngắt tương ứng với số hiệu ngắt đồng thời lưu giữ địa chỉ của chương trình xử lý ngắt để trở về hoặc phục hồi bảng vector ngắt khi cần thiết. Do hạn chế về thời gian cũng như tài liệu tham khảo về các kỹ thuật này rất ít nên việc nghiên cứu để tìm ra cách giải quyết vấn đề sử dụng kỹ thuật override trong Windows 32bits chưa đi đến kết quả nên chúng tôi buộc phải chọn kỹ thuật override trong Windows 16bits để overrride các hàm xuất văn bản có sẵn để áp dụng vào chương trình của mình.

TRONG WINDOWSTRONG WINDOWS

Các driver thiết bị sẽ chận hứng dữ kiện mà ứng dụng muốn cho hiển thị rồi cho dịch các dữ liệu này ra dạng thích hợp của thiết bị mà nó sẽ hiển thị lên như màn hình, máy in… Mỗi thiết bị đều có một driver do nhà sản xuất tạo ra. Trên thực tế là hầu như các dòng văn bản được hiển thị trên màn hình của Windows 3.X đều được xuất bởi 2 hàm TextOut và ExtTextOut, vì các hàm còn lại cũng gọi vào 2 hàm này để vẽ ra, và vì vậy trong chương trình chúng tôi cũng chỉ tiến hành override 2 hàm này và trong phần này chúng tôi xin giới thiệu chi tiết 2 hàm TextOut(), ExtTextOut(). - Mặc định GDI canh dòng văn bản về góc trái-trên ở điểm điều khiển (spx,spy). - Tương tự hàm TextOut hàm này cũng sẽ vẽ một dòng văn bản đơn nhưng thêm một số chức năng tùy chọn sau: điều khiển chiều rộng ký tự, một vùng chữ nhật làm việc cắt xén, một vùng chữ nhật tô đục. Tùy theo yêu cầu mà lựa chọn. Int spx, Int spy,. CONST RECT* lpRect,. CONST INT* lpDxWidths );.

Trong các giá trị được chứa trong cấu trúc TEXTMETRIC thì chúng tôi chỉ quan tâm tới thông số tmAveCharWidth có kiểu dữ liệu LONG, thông số này là độ rộng trung bình tính bằng pixel của một ký tự của font chữ thường được đại diện bởi độ rộng của ký tự “x”. Chú ý rằng một điểm được coi là thuộc hình chữ nhật khi nó nằm ở trên cạnh trái, nằm ở trên cạnh trên hoặc nằm hoàn toàn trong hình chữ nhật, ngược lại một điểm không thuộc hình chữ nhật khi nó nằm ở bên ngoài, nằm ở trên cạnh phải hoặc nằm ở trên cạnh dưới của hình chữ nhật.

PHÂN TÍCH VÀ THIẾTPHÂN TÍCH VÀ THIẾT

Có nghĩa là tại một vị trí bất kỳ nào đó của cursor mouse trên màn hình Windows nếu có một tác động chuột quy định trước (chẳng hạn như click nút phải của chuột) thì phải lấy được từ ở ngay dưới vị trí cursor (nếu có), hoặc xuất ra thông báo cho biết không có từ nào nằm ngay dưới vị trí cursor đang đứng. - Đối với dạng thể hiện ảnh, văn bản chỉ là tập các điểm ảnh của bức ảnh, chẳng có ý nghĩa gì khác đối với Windows, nên nếu muốn trích văn bản ra chỉ có một cách là xử lý ảnh, điều này thực sự là một vấn đề hay và có nhiều ứng dụng thực tiễn: như nhận dạng một trang giấy được scan vào máy để tạo ra file text tương ứng thay cho việc đánh máy lại trang giấy đó. - Đối với dạng thể hiện văn bản bằng các hàm kết xuất văn bản: Ứng dụng sẽ gởi cho Windows chuỗi văn bản cần thể hiện và các thông số cần thiết, và Windows dùng các hàm kết xuất văn bản để vẽ chuỗi văn bản đó ra màn hình.

Từ cách kết xuất đó đã nảy sinh một ý tưởng về việc nhận dạng các dòng text trên màn hình: là nếu ta có thể khống chế các hàm kết xuất văn bản, lấy về các thông tin của các hàm này, thì vấn đề có thể thực hiện được mà không cần phải xử lý ảnh. * Từ sự phân tích đó chúng tôi đã chọn giải thuật dựa vào sự khống chế các hàm xuất văn bản của Windows, và cũng may mắn là hầu như tất cả dòng văn bản kết xuất ra màn hình đều dùng dạng kết xuất dùng hàm kết xuất văn bản, nên nếu thực hiện hoàn hảo ý tưởng nói trên thì vấn đề được giải quyết gần như hoàn toàn.

WM_QUIT)

Vòng loop bắt thông điệp: Dẫn vào hàm xử lý thoõng ủieọp cuỷa chửụng trỡnh: MenuWndProc.

KEÁT THUÙC

-Lấy bộ chọn phân đọan và địa chỉ offset hàm override -Đổi từ code selector của hàm API sang data selector Hàm PrestoChangoSelector(). -Ghi lên 5 byte đầu của hàm API bằng đoạn code assembler -Đổi trở lại từ data selector sang code selector.

LƯU ĐỒ HÀM GỠ BỎ OVERRIDE (GTDLL.DLL : RemoveOverrideAPI)

+ Naốm treõn vuứng client: Leọnh RedrawWindow vuứng client + Nằm trên thanh tiêu đề: Lệnh RedrawWindow vùng nonclient. * Khi cửa sổ vẽ lại các dòng text thì các hàm override sẽ phát huy tác dụng.

LƯU ĐỒ HÀM XỬ LÝ MOUSEHOOK (GTDLL - MouseFunc)

- Từ vị trí mIndex, đặt vòng loop quét dò qua trái - Xét xem vị trí đang dò có phải là space hoặc tab - Vòng loop kết thúc khi dò được vị trí space hoặc tab, hoặc dò đến vị trí đầu chuỗi (vị trí 1). - Từ vị trí mIndex, đặt vòng loop quét dò qua phải - Xét xem vị trí đang dò có phải là space hoặc tab - Vòng loop kết thúc khi dò được vị trí space hoặc tab, hoặc dò đến vị trí cuối chuỗi (chiều dài chuỗi). - Cập nhật CP: Gán lại toạ độ TextOut là CP - Trái/giữa/phải: Chỉnh toạ độ trái/phải - Đỉnh/đáy/baseline: Chỉnh toạ độ trên/dưới.

- Tính khung bao chuỗi text từ 1 đến mIndex để suy ra toạ độ của ký tự mIndex trên màn hình - Xét xem pt nằm bên trái hay bên phải mIndex - Nếu pt bên phải thì tăng mIndex rồi loop lại cho đến khi pt qua trái. - Từ vị trí mIndex, đặt vòng loop quét dò qua trái - Xét xem vị trí đang dò có phải là space hoặc tab - Vòng loop kết thúc khi dò được vị trí space hoặc tab, hoặc dò đến vị trí đầu chuỗi (vị trí 1).

LƯU ĐỒ GIẢI THUẬT TRÍCH TỪ TRONG DềNG TEXT TẠI VỊ TRÍ mIndex (mở rộng lưu đồ GetWordUnderPoint)

- Giá trị trả về: Là handle của cửa sổ con chứa điểm contains the point ngay cả trong trường hợp cửa sổ con bị che hay không thể hoạt động hidden or disabled. - Ghi chú: Nếu cửa sổ đích thuộc sở hữu bởi quá trình hiện hành, hàm GetWindowText tạo nên thông điệp WM_GETTEXT để gởi tới điều khiển hay cửa sổ được đặc tả. - Nếu nCode nhỏ hơn 0 thì thủ tục hook phải chuyển thông điệp tới hàm CallNextHookEx không cần xử lý thêm và nên trả về giá trị được trả về bởi CallNextHookEx.

- Giá trị trả về: Nếu nCode < 0 thì trả về giá trị do CallNextHookEx trả về còn nếu nCode >= 0 và thủ tục hook không xử lý thông điệp nó đề nghị bạn gọi CallNextHookEx và trả về giá trị nó trả về ngược lại những ừng dụng khác đã đặt hook WM_MOUSE sẽ không nhận thông báo hook và có thể đối xử chính xác như là một kết quả. RDW_ERASENOW làm cho các cửa sổ bị tác dụng (như là được xác định bởi cờ RDW_ALLCHILDREN và. RDW_NOCHILDREN) nhận thông điệp WM_NCPAINT và WM_ERASEBKGND ,Nếu cần. RDW_UPDATENOW làm cho các cửa sổ bị tác dụng (như là được xác định bởi cờ RDW_ALLCHILDREN và RDW_NOCHILDREN) nhận thông điệp WM_NCPAINT, WM_ERASEBKGND và WM_PAINT.

Mặt bằng cửa sổ bị thay đổi liên tục (bởi các lệnh resize, đóng mở các dialog box…) vì thế nếu không cập nhật thì sẽ bị biến dạng nên Windows dùng thông điệp WM_PAINT để tô vẽ lại màn hình.