Trao đổi với tôi

http://www.buidao.com

10/15/09

[MASM] Customize MessageBox in ASM (Source Code)

Customize MessageBox in ASM (Source Code)

Link: http://nhatphuongle.spaces.live.com/blog/cns!320FF19317F0C9A2!747.entry
Author: NhatPhuongLe

- Tạo Project mới trong RadASM, chọn

  • Assembler : masm
  • Project Type : Win32 App
  • Project Name : CustomMsgBox
  • Project Description : CustomMsgBox using by Hook

clip_image002

- Chọn kiểu Template: None

- Khai báo Prototype của các hàm và include các header cần thiết cho chương trình trong file CustomMsgBox.Inc:

include        \masm32\include\windows.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

;Khai bao Prototype
ExitProcess PROTO :DWORD
GetCurrentThreadId PROTO
CallNextHookEx PROTO :DWORD,:DWORD,:DWORD,:DWORD
GetDlgItem PROTO :DWORD,:DWORD
UnhookWindowsHookEx PROTO :DWORD

MessageBoxA PROTO :DWORD,:DWORD,:DWORD,:DWORD
MessageBox equ

SetWindowTextA PROTO :DWORD,:DWORD
SetWindowText equ

SetWindowsHookExA PROTO :DWORD,:DWORD,:DWORD,:DWORD
SetWindowsHookEx equ

- Trong file CustomMsgBox.asm, viết code cho:

  • Thủ tục Hook:
HookProcedure PROC nCode:DWORD,wParam:DWORD,lParam:DWORD

cmp nCode,0
jb @f
cmp nCode,HCBT_ACTIVATE
jne @f
invoke GetDlgItem,wParam,IDOK
invoke SetWindowText,eax,hwndButton
xor eax,eax
ret
@@:
invoke CallNextHookEx,hMsgBoxHook,nCode,wParam,lParam
ret

HookProcedure ENDP

Giải thích code:

  • Ban đầu, so sánh Hook code (nCode) có bằng 0 hay không? Nếu như là nhỏ hơn 0 thì nhảy tới nhãn @@ kế tiếp bằng lệnh jb (jump on below/less than, số không dấu), tức có nghĩa là khi truyền giá trị âm cho tham số này thì thủ tục không được xử lý sự kiện mà phải gọi hàm CallNextHookEx với chính những tham số mà HĐH truyền cho nó. Sau đó, nó phải trả về giá trị được trả về bởi hàm CallNextHookEx
  • Dòng lệnh thứ 3, có nghĩa là nCode khac. Chương trình kiểm tra xem MessageBox đã được kích hoạt (active) hay chưa bằng lệnh cmp, nếu chưa kích hoạt thì cũng nhảy tới nhãn @@ kế tiếp, lúc này wParam chứa handle của messagebox, lParam chứa cấu trúc thông tin.
  • Do đó, ta sẽ dùng hàm GetDlgItem để lấy địa chỉ của nút OK trên messagebox:
invoke GetDlgItem,wParam,IDOK

Công dụng tổng quát của hàm GetDlgItem là lấy địa chỉ con trỏ của một cửa sổ trên 1 dialog (cửa sổ này có thể là button, hoặc cửa sổ ứng dụng, ...). Trong trường hợp của chúng ta, đó chính là nút OK, và Dialog chính là message-box.

Sau đó, dùng hàm SetWindowText để đặt nội dung cho một đối tượng cửa sổ, trong ví dụ của chúng ta đối tượng cửa sổ chính là nút OK

invoke SetWindowText,eax,hwndButton

Gán nội dung của biến hwndButton cho thanh ghi EAX.

  • Cuối cùng, là làm sạch thanh ghi EAX để có thể sử dụng về sau. Có thể bỏ qua bước này.
  • Hàm gọi sử dụng Hook:
MsgBoxEx PROC hWnd:DWORD,message:DWORD,
caption:DWORD,buttontext:DWORD

mov eax,buttontext
mov hwndButton,eax
invoke GetCurrentThreadId
invoke SetWindowsHookEx,WH_CBT,ADDR HookCheck,NULL,eax
mov hMsgBoxHook,eax
invoke MessageBox,0,message,caption,MB_OK + MB_ICONQUESTION
invoke UnhookWindowsHookEx,hMsgBoxHook
ret

MsgBoxEx ENDP

Giải thích code:

Thủ tục Hook có tên là HookProcedure, có 3 tham số như mục 3) đã mô tả. Cách làm việc của procedure như sau:

  • Ban đầu, thủ tục này có nhiệm vụ cài đặt Hook thông qua hàm SetWindowsHookEx. Mà muốn gọi được hàm API này thì phải có đủ 4 tham số của nó (hookMsg, hookProc, hIns, threadId)

+ hookMsg = WH_CBT

+ hookProc = địa chỉ của HookProcedure

+ hIns = NULL

+ threadId = EAX (hàm GetCurrentThreadId sẽ lấy ID của thread, giá trị trả về trong thanh ghi EAX)

invoke SetWindowsHookEx,WH_CBT,ADDR HookCheck,NULL,eax

  • Nếu cài đặt Hook thành công, giá trị trả về của hàm này (thường gọi là handle của hook) được lưu giữ trong thanh ghi EAX. Sau đó, copy giá trị này qua biến hMsgBoxHook đã khai báo trong section .data?

mov hMsgBoxHook,eax

  • Sau đó, gọi hàm MessageBox để hiển thị thông báo với nội dung là tham số truyền vào thông qua biến đại diện message và title là biến caption.
invoke MessageBox,0,message,caption,MB_OK + MB_ICONQUESTION

  • Hủy bỏ cài đặt Hook bằng hàm UnhookWindowsHookEx với tham số đầu vào là hMsgBoxHook (handle của hook)
invoke UnhookWindowsHookEx,hMsgBoxHook

- Nhấn CTRL + F5 để chạy chương trình, bạn được kết quả như sau:

clip_image002[7]

Source Code in MASM

.386
.model flat, stdcall
option casemap:none

;Include header file
include CustomMsgBox.inc

;Khai bao Prototype ham goi thu tuc Hook
MsgBoxEx PROTO :DWORD,:DWORD,:DWORD,:DWORD

.data
szContent db 'How to customize a standard message box?',0
szTitle db 'MsgBoxEx',0
btext db 'Bye bye',0

.data?
hMsgBoxHook dd ?
hwndButton dd ?

.code

start:

invoke MsgBoxEx,0,ADDR szContent,ADDR szTitle,ADDR btext
invoke ExitProcess,0

HookProcedure PROC nCode:DWORD,wParam:DWORD,lParam:DWORD

cmp nCode,0
jb @f
cmp nCode,HCBT_ACTIVATE
jne @f
invoke GetDlgItem,wParam,IDOK
invoke SetWindowText,eax,hwndButton
xor eax,eax
ret
@@:
invoke CallNextHookEx,hMsgBoxHook,nCode,wParam,lParam
ret

HookProcedure ENDP

MsgBoxEx PROC hWnd:DWORD,message:DWORD,caption:DWORD,buttontext:DWORD

mov eax,buttontext
mov hwndButton,eax
invoke GetCurrentThreadId
invoke SetWindowsHookEx,WH_CBT,ADDR HookProcedure,NULL,eax
mov hMsgBoxHook,eax
invoke MessageBox,0,message,caption,MB_OK + MB_ICONQUESTION
invoke UnhookWindowsHookEx,hMsgBoxHook
ret

MsgBoxEx ENDP

END start