Benina’s TutASM # 3: PlayingXMMusicFromMasm’sEXE – Ver 1.0
Author: Benina
Trang 1/8
Benina’s TutASM # 3
PLAYING XMMUSICFROMMASM’SEXE
Author: Benina
Phần này tôi sẽ hướng dẫn các bạn cách add data XMmusic vào resource của file EXE và chơi
nhạc khi chương trình Runing.
Tool : RadASM+MASM32
Dowload source here: http://h1.ripway.com/benina/files/Keygen3.rar
Lý thuyết:
Trước hết các bạn phải có 2 file thư viện : mfmplayer.inc và mfmplayer.lib chứa code để chơi
nhạc. File thư viện mfmplayer.lib chứa một hàm được định nghĩa trong mfmplayer.inc :
mfmPlay PROTO :DWORD
Hàm này có tên là mfmPlay, lấy một tham số DWORD là con trỏ đến dữ liệumusic trong
memory. Hàm này yêu cầu một dword đầu tiên được trỏ đến bởi tham số hàm, nó chính là là kích
thức (size) của data music.
Nếu tham số là con trỏ đến dữ liệumusic thì nó bắt đầu chơi nhạc. Nếu tham số là 0 , thì music
sẽ stop. Thư viện này chỉ đơn giản vậy thôi.
Nhưng trước hết, để ta sử dụng lâu dài hàm thư viện này khi lập trình , ta hảy copy file
mfmplayer.inc vào thư mục C:\masm32\include chứa chương trình MASM32 và file
mfmplayer.lib vào thư mục C:\masm32\lib. Sau khi làm xong, chúng ta có thể sử dụng dịch vụ
của nó được rồi đó.
Tôi xin tóm tắt các bước để chơi music như sau:
1. Lấy handle của resource music, sử dụng hàm FindResource
2. Load resource trong memory, sử dụng hàm LoadResource
3.
Nhưng như đã nói về hàm mfmPlay, nó cần một Dword nằm trong memory đầu tiên (first
Dword) chứa size của resource. Để giải quyết vấn đề này, chúng ta sẽ định ra một vùng
nhớ mới (dùng hàm GlobalAlloc) và write size của resource đến first Dword của vùng
nhớ mới vừa định. Do có thêm 1 dword để lưu size, nên vùng nhớ mới lớn hơn resource
music 1 dword. Kế đến chúng ta copy resource từng byte từng byte một vào memory
chúng ta mới định ra trước đó.
4. Cuối cùng, chúng ta play music với hàm mfmPlay.
5. Khi chương trình kết thúc, chúng ta cho nhạc tắt theo bằng cách gọi hàm mfmPlay với
tham số là 0
Benina’s TutASM # 3: PlayingXMMusicFromMasm’sEXE – Ver 1.0
Author: Benina
Trang 2/8
Thực hành:
Bây giờ chúng ta hảy bật RadASM và Project Keygen1.
(Chúng ta tiếp tục với Project trong TUT “Benina’s tutASM #2” của tui nhé.)
Để MASM biên dịch link với thư viện mfmplare.lib , chúng ta khai báo các dòng sau trong file
Keygen1.Inc:
include mfmplayer.inc
includelib mfmplayer.lib
Bước tiếp theo, ta copy một file .xm (tôi có kèm theo file keygen.xm trong source) vào trong thư
mục /res của project và add nó vào resource như sau:
Vào menu Project/Resource ta add thêm resource IDM_MUSIC như hình sau:
Trong file Keygen1.Inc phần section .const ta khai báo :
IDM_MUSIC equ 200
Và khai báo thêm các biến trong section .data ? (các biến này sử dụng như thế nào tui sẽ giải
thích sau):
Benina’s TutASM # 3: PlayingXMMusicFromMasm’sEXE – Ver 1.0
Author: Benina
Trang 3/8
;
hResource DD ?
hDataOld DD ?
SizeRes DD ?
pData DD ?
tham khảo thêm hình:
Kế đến trong file Keygen1.Asm ta đánh vào các lệnh sau trước hàm DialogBoxParam:
;
;Loading the music
INVOKE FindResource,hInstance,IDM_MUSIC,RT_RCDATA
mov hResource,eax
INVOKE LoadResource,hInstance,hResource
mov hDataOld,eax
INVOKE SizeofResource,hInstance,hResource
mov SizeRes,eax
INVOKE LockResource,hDataOld
mov esi,eax
mov eax,SizeRes
add eax,SIZEOF SizeRes
INVOKE GlobalAlloc,GPTR,eax
mov pData,eax
mov ecx,SizeRes
mov dword ptr[eax],ecx
mov edi,pData
add edi,SIZEOF SizeRes
Benina’s TutASM # 3: PlayingXMMusicFromMasm’sEXE – Ver 1.0
Author: Benina
Trang 4/8
rep movsb
;
Xem hình kèm theo
Cuối cùng trong phần xử lý thông điệp khởi tạo trị đầu của Dialog ta cho nó chơi nhạc bằng hàm:
INVOKE mfmPlay,pData
Hình minh họa
Benina’s TutASM # 3: PlayingXMMusicFromMasm’sEXE – Ver 1.0
Author: Benina
Trang 5/8
Chúng ta cũng đừng quên khi chương trình thóat exit (thông điệp WM_CLOSE được send) ta
cho tắt nhạc bằng hàm:
INVOKE mfmPlay,0
Hình minh họa
Bây giờ bạn hit nút “GO” xem sao. OK chứ?
Phân tích:
Tôi sẽ giải thích ở đây phần code thêm vào trong section .code của file Keygen1.Asm.
Nhu ta thấy trong đọan code “Loading the music” , trước tiên là gọi hàm:
INVOKE FindResource,hInstance,IDM_MUSIC,RT_RCDATA
mov hResource,eax
Hàm FindResource xác định địa chỉ resource với lọai và tên trong module được chỉ định.
Nó cần 3 tham số. Tham số đầu tiên là handle của module, tham số thứ hai là tên resource và
cuối cùng là lọai Resource. Ở đây là RT_RCDATA.
Trong MSDN LIBRARY:
Benina’s TutASM # 3: PlayingXMMusicFromMasm’sEXE – Ver 1.0
Author: Benina
Trang 6/8
The FindResource function determines the location of a resource with the specified type and
name in the specified module.
HRSRC FindResource(
HMODULE hModule, // resource-module handle
LPCTSTR lpName, // pointer to resource name
LPCTSTR lpType // pointer to resource type
);
Nếu hàm này gọi thành công , giá trị trả về là một handle của block thông tin resource được chỉ
định. Thu được handle của resource, ta lưu nó vào biến hResource để sử dụng sau này, và
chuyển handle này cho hàm LoadResource. Và xin nói thêm, nếu hàm FindResource gọi ko
thành công , nó sẽ trả về giá trị NULL.
Dòng lệnh kế tiếp là :
INVOKE LoadResource,hInstance,hResource
mov hDataOld,eax
Tham khảo Win32 API:
The LoadResource function loads the specified resource into global memory.
HGLOBAL LoadResource(
HMODULE hModule, // resource-module handle
HRSRC hResInfo // resource handle
);
Hàm LoadResource sẽ tải resource được chỉ định vào trong memory tòan cục.
Nếu hàm này gọi thành công, giá trị trả về là một handle của block memory tòan cục có dữ liệu
liên đới với resource. Nếu ko thành công, giá trị trả về là NULL.
Sau đó ta lưu handle vào biến hDataOld.
Tiếp tục ta thấy:
INVOKE SizeofResource,hInstance,hResource
mov SizeRes,eax
Hàm SizeOfResource sẽ trả về kích thước (size đơn vị là byte) của resource music, lưu kích
thước này vào biến SizeRes để sử dụng sau này.
Kế tiếp là lệnh:
INVOKE LockResource,hDataOld
Benina’s TutASM # 3: PlayingXMMusicFromMasm’sEXE – Ver 1.0
Author: Benina
Trang 7/8
Hàm LockResource sẽ chỉ định resource trong bộ nhớ. Nếu resource đã load bị lock, giá trị trả về
là con trỏ đến byte đầu tiên của resource, nếu ngược lại là NULL.
Trước khi đi tiếp, chúng ta cần biết qua hàm này:
rep movsb
Hàm này có tác dụng copy lần lượt từng byte từng byte một từ vùng nhớ trỏ bởi thanh ghi esi đến
vùng nhớ trỏ bởi edi. Số byte cần copy chứa trong ecx.
Vì vậy như lý thuyết lúc đầu, chúng ta sẽ định ra một vùng nhớ mới (dùng hàm GlobalAlloc)
và write size của resource đến first Dword của vùng nhớ mới vừa định. Do có thêm 1
dword để lưu size, nên vùng nhớ mới lớn hơn resource music 1 dword. Kế đến chúng ta
copy resource từng byte từng byte một vào memory chúng ta mới định ra trước đó.
Do đó để copy resource bằng cặp lệnh nói trên (rep movsb), chúng ta sẽ cho esi trỏ đến vùng
memory của resource music, và edi trỏ đến vùng memory mới tạo ra, cuối cùng ecx chứa tổng số
byte cần copy.
Vì vậy , sau hàm LockResource, chúng ta sẽ lưu giá trị trả về trong eax vào esi để dùng cho cặp
lệnh copy sau này.
mov esi,eax
Và do vùng memory mới cần 1 first Dword để lưu size của resource nên size vùng nhớ mới phải
hơn vùng nhớ resource music 1 dword. Ta dùng cặp lệnh sau để thực hiện điều này và eax sẽ lưu
size vùng nhớ mới (chú ý SizeRes có kích thước là một Dword):
mov eax,SizeRes
add eax,SIZEOF SizeRes
Kế đến ta có :
INVOKE GlobalAlloc,GPTR,eax
mov pData,eax
Hàm GlobalAlloc được dùng để định ra một vùng memory. Tham số đầu tiên là thuộc tính định
vị. Ở đây là GPTR có nghĩa là giá trị trả về của hàm sẽ là một con trỏ đến vùng memory mới
định vị và tất cả các byte sẽ được khởi trị đầu là zero. Tham số thứ hai là size của memory để
định kích thước vùng nhớ cần tạo . Ở đây Size được tăng lên một dword để chứa size của music
do yêu cầu của hàm mfmPlay.
Sau khi định memory mới, ta lưu con trỏ đến vùng memory này vào biến pData để sử dụng cho
hàm mfmPlay sau này.
Như đã phân tích ở trên lệnh:
Benina’s TutASM # 3: PlayingXMMusicFromMasm’sEXE – Ver 1.0
Author: Benina
Trang 8/8
mov ecx,SizeRes
lưu Size vào ecx để dùng cho việc copy.
Chỉ thị này:
mov dword ptr[eax],ecx
lưu kích thước size vào dword đầu tiên dùng cho hàm mfmPlay.
Cặp chỉ thị sau đây:
mov edi,pData
add edi,SIZEOF SizeRes
dùng định vị con trỏ vùng nhớ mới (edi) để copy các byte. (edi trỏ đến byte sau first dword)
Cuối cùng là thực hiện copy từng byte từng byte một từ resource music vào vùng nhớ mới định.
Hy vọng những dòng phân tích trên rõ ràng. Hẹn gặp lại các bạn trong các tut sau.
Benina 28/12/2005
Update 28/12/2005
Mail: benina@walla.com
(Không đồng ý bất kỳ ai sử dụng tàiliệu này cho mục đích thương mại nếu ko được phép của
người dịch)
. TutASM # 3: Playing XM Music From Masm’s EXE – Ver 1.0
Author: Benina
Trang 1/8
Benina’s TutASM # 3
PLAYING XM MUSIC FROM MASM’S EXE
Author:. cách gọi hàm mfmPlay với
tham số là 0
Benina’s TutASM # 3: Playing XM Music From Masm’s EXE – Ver 1.0
Author: Benina
Trang 2/8
Thực hành: