Trang 1
Xây dng thư vin liên kết động trong MASM
Translated and Written by NhatPhuongLe
www.reaonline.net
Tutorial 17
Building a DLL in MASM32
Reverse Engineering Association
IczelionsWin32AssemblyTutorials
For more updated info, please check
http://nhatphuongle.spaces.live.com
Xây dng thư vin liên kết động trong MASM
Translated and Written by NhatPhuongLe
www.reaonline.net
1. Lý thuyết
Nếu bn lp trình đủ lâu, thì bn nhn thy rng các chương trình mà trước đây bn
viết thường có nhng đon code ging nhau, nó thường là các th hàm (routines). Nó giúp
bn tiết kim thi gian tránh phi viết li mi khi bt đầu viết mt chương trình mi. Tr li
thi lp trình trên nn DOS, nhng hàm thường xuyên được gi s dng, s được lưu tr
trong tp tin đối tượng (.OBJ, .LIB, .RES). Khi bn mun s dng các hàm này, bn ch liên
kết ti tp tin đối tượng này, sau đó trình liên kết s extract các hàm này và nhúng ni dung
ca hàm vào tp tin EXE. Tiến trình này được gi là liên kết tĩnh. Các thư vin lúc biên dch
trong ngôn ng lp trình C là ví d d thy nht.
Liên kết tĩnh không hiu qu bi vì đon mã để thc thi mt hàm thường phi nhúng
nhiu ln vào các tp tin .EXE khác nhau. Không gian đĩa cng ca bn s tn nhiu b
nh để lưu tr các bn sao ca hàm. Tuy nhiên, phương pháp này có th chp nhn được
bi vì thường ch có mt chương trình được gi thc thi trên b nh. Tuy nhiên, dưới nn
tng Windows thì vic tiết kim b nh được quan tâm hơn bi vì có th có nhiu chương
trình chy cùng lúc. Lúc này, b nh được chia nhau s dng bi các chương trình, và nếu
như chương trình bn càng ln thì nó s “ngn” b nh càng nhiu. Windows đã đưa ra
hướng gii quyết cho vn đề này là thư vin liên kết động. Windows s không np các bn
sao ca mt DLL lên b nh vì thế thm chí có nhiu th hin ca chương trình đang chy
cùng 1 lúc, cũng ch có duy nht mt bn sao ca DLL mà chương trình đang s dng được
np lên b nh.
Tôi gii thích rõ hơn cho bn hiu. Thc ra, tt c các tiến trình đều s dng chung
mt DLL, mà DLL này chính là bn sao ca chính nó. Điu này thì tương t như là có nhiu
bn sao ca DLL trong b nh. Nhưng trong thc tế, Windows s “thc hin” điu này bng
cách phân trang b nh và tt c các tiến trình s chia s mã ngun ca cùng 1 DLL. Vì thế
trong b nh vt lý, ch có duy nht mt bn sao ca mã ngun DLL. Tuy nhiên, mi tiến
trình s có mt section d liu ca DLL cho riêng nó.
Chương trình liên kết vi DLL lúc thc thi không ging như kiu liên kết tĩnh cũ. Đó
là lý do ti sao nó được gi là thư vin liên kết động. Bn cũng có th gii phóng DLL ti
thi đim biên dch khi bn không s dng nó na. Nếu như ch có mt chương trình ca
bn s dng DLL, nó s được gii phóng ra khi b nh ngay lp tc. Nhưng nếu như DLL
này vn được s dng bi các chương trình khác, thì DLL vn còn nm trên b nh cho
đến khi chương trình cui cùng s dng nó xong và yêu cu gii phóng nó ra khi b nh.
Tuy nhiên, trình linker s có mt nhim v khó hơn phi làm đó là fix li địa ch cho tp tin
EXE. Bi vì khi nó không th “extract” các hàm và nhúng ni dung ca hàm vào trong tp tin
EXE, bng cách này hay cách khác nó phi lưu tr đầy đủ thông tin v DLL và các hàm
trong tp tin EXE để nó có th định v và np li mt chính xác DLL ti thi đim biên dch.
Quá trình này được gi là base relocation. Đây là nơi mà thư vin nhp được import. Mt
thư vin nhp cha thông tin v DLL. Trình linker có th extract thông tin khi nó cn t thư
vin nhp vào tp tin EXE. Khi Windows Loader np chương trình vào b nh, nó s tìm
xem chương trình có liên kết vi DLL hay không, nó s tìm DLL đó và ánh x nó vào trong
không gian địa ch ca tiến trình và tiến hành fix địa ch ca các hàm call gi ti các hàm
trong DLL.
Bn cũng có th la chn cách np DLL vào b nh bng cách riêng ca bn không cn
nh vào Windows Loader. Phương pháp này có nhng thun li và khó khăn sau:
Trang 2
Reverse Engineering Association
Xây dng thư vin liên kết động trong MASM
Translated and Written by NhatPhuongLe
www.reaonline.net
Nó không cn phi import bt k thư vin nhp nào vì thế bn có th np và s dng
DLL thm chí nó đi kèm vi thư vin nhp. Tuy nhiên, bn vn phi biết thông tin v
các hàm bên trong DLL, có báo nhiêu tham s được truyn vào hàm hay đại loi thế.
Khi bn “nh” loader np DLL cho chương trình ca bn, nếu như loader không tìm
thy DLL nó s thông báo “A required .DLL file, xxx.dll is missing”, và chương
trình ca bn không th run thm chí nếu như DLL không tht s cn thiết cho x
trong chương trình chính đang gi. Nhưng khi bn np DLL theo cách ca bn thì khi
DLL không được tìm thy và nó không cn thiết cho x lýu ca chương trình, thì
chương trình ch thông báo cho bn biết và chương trình vn run tt.
Nếu bn s dng LoadLibrary, bn phi gi hàm GetProcAddress cho mi hàm mà
bn mun gi. GetProAddress s cho bn địa ch entrypoint ca mt hàm trong DLL
có liên quan. Vì thế mã ngun ca bn có th dài hơn mt tí và chm hơn mt chút
khi thc thi. Tuy nhiên, nó không đáng k so vi thun li, bn có th np DLL
không cn nh loader.
Thy được ưu và khuyết đim ca vic gi hàm LoadLibrary, chúng ta s đi vào chi tiết
làm thế nào để to mt DLL.
Đây là cu trúc ca mt DLL chun:
DLLSkeleton.asm
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
DllEntry proc hInstance:HINSTANCE,reason:DWORD, reserved1:DWORD
...
mov eax,TRUE
ret
DllEntry Endp
Function proc
...
ret
Function endp
End DllEntry
DLLSkeleton.DEF
LIBRARY DLLSkelton
EXPORTS Function
Trang 3
Reverse Engineering Association
Xây dng thư vin liên kết động trong MASM
Translated and Written by NhatPhuongLe
www.reaonline.net
Trên đây là cu trúc chung ca mt chương trình DLL. Mi DLL phi có đim vào
(entrypoint) ca hàm. Hàm DllEntry trong DLL s được gi khi thư vin được Windows
np vào b nh và khi Windows yêu cu chm dt.
DllEntry proc hInstance:HINSTANCE,reason:DWORD, reserved1:DWORD
...
mov eax,TRUE
ret
DllEntry Endp
Bn có th đặt tên entrypoint ca DLL tùy ý, min sao là tên này ging vi tên sau
nhãn END
End DllEntry
Hàm này nhn vào 3 tham s, trong đó có 2 tham s quan trng là hInstance
reversed1:
Tham s đầu tiên mà hàm này s dng là mã th hin ca thư vin hay còn gi
là instance handle (tìm hiu sâu vào kiến trúc Windows 32-bits, bn s thy
instacne handle chính là địa ch vùng nh đầu tiên nơi thư vin DLL được np
vào). Nếu thư vin ca bn s dng đến nhng tài nguyên yêu cu cung cp mã
th hin ca chương trình gi (như Dialogbox chng hn) thì bn cn phi lưu
biến hInstance này như mt biến toàn cc.
Tham s th 2 là reason, tham s này có th mang 4 giá tr cho biết nguyên do
và ti sao Dll được Windows np vào b nh. Trong phn tiếp theo đây, bn hãy
hình dung ng cnh trong đó mt chương trình ng dng được cho kích hot và
chy nhiu ln song song vi nhau. Mi ln chương trình được gi, Windows
xem đó như là mt tiến trình (process). Mi tiến trình nm trong mt vùng không
gian địa ch o độc lp vi nhau.
Giá tr tham s reason Ý nghĩa
DLL_PROCESS_ATTACH
Hàm DllEntry vi tham s
DLL_PROCESS_ATTACH được gi khi process
tiến hành load DLL
Thư vin DLL đang được Windows ánh x vào
vùng nh ca tiến trình (thc hin li gi DLL)
Đây là thi đim để DLL khi to các biến, cp
phát vùng nh hay nhng thao tác cn thiết
khác trước khi cho phép tiến trình gi đến các
hàm ca thư vin
DLL_PROCESS_DETACH
Thư vin DLL được gii phóng khi vùng nh
ca tiến trình do 1 trong 3 nguyên nhân: np
DLL không thành công, tiến trình kết thúc, hay
tiến trình gi hàm FreeLibrary.
Đây là thi đim để gii phóng các biến hay tài
nguyên mà DLL đã cp phát
Trang 4
Reverse Engineering Association
Xây dng thư vin liên kết động trong MASM
Translated and Written by NhatPhuongLe
www.reaonline.net
DLL_THREAD_ATTACH
Khi tiến trình to mi mt tiu trình (Thread),
Windows gi hàm DllEntry ca tt c các thư
vin DLL đang được s dng vi tiến trình đó.
Đây là thi đim để khi to các biến dùng cho
tiu trình
Lưu ý rng tình hung này ch xy ra khi tiu
trình được to sau khi thư vin DLL đã load vào
tiến trình, nghĩa là nếu DLL được load bng hàn
LoadLibrary thì tt c các tiu trình hin có
(trong tiến trình) s không gi hàm DllEntry vi
tham s này.
DLL_THREAD_DETACH
Khi 1 tiu trình kết thúc, Windows gi hàm
DllEntry ca tt c các thư vin DLL đang được
s dng vi tiu trình này.
Đây là thi đim để gii phóng các biến dùng
cho tiu trình
Tham s cui cùng truyn cho hàm DllEntry là reversed1 được h thng dành
cho mc đích riêng.
Bn tr v giá tr TRUE cho thanh ghi EAX, nếu như bn mun DLL chy. Ngược li,
nếu EAX cha giá tr FALSE thì DLL s không được np. Ví d, nếu code khi to ch
định mt s vùng nh và nó không th làm điu đó thành công, thì hàm DllEntry s tr
v giá tr FALSE để ch ra rng DLL không th chy được.
Bn có th đặt các hàm ca bn trong DLL trước hoc sau entrypoint đều được.
Nhưng nếu bn mun nó có th được gi t chương trình khác bn phi đặt các hàm
trong export list chính là danh sách các hàm được export ra bên ngoài cho các DLL hoc
chương trình khác s dng trong file định nghĩa (.DEF)
LIBRARY DLLSkelton
EXPORTS Function
Thông thường, bn phi có dòng đầu tiên. Phát biu LIBRARY s định nghĩa tên
module bên trong ca DLL. Bn nên để nó phù hp vi tên file ca DLL (trong ví d này
DLLSkeleton). Phát biu EXPORTS s nói cho trình linker biết nhng hàm nào trong
DLL được export, đó là nhng hàm có th được gi bi các chương trình khác. Trong ví
d này, chúng ta mun các modules khác có th gi hàm Function, vì thế ta đặt tên ca
hàm này (Function) phía sau phát biu EXPORT.
Nếu bn không viết code trên mt IDE dành riêng cho asm, thì bn có th viết mt tp
tin .BAT để biên dch và liên kết các tp tin đối tượng. Tuy nhiên, có mt s thay đổi
trong vic viết lnh trong file .BAT như sau:
Thông thường, bn mun trình linker sau khi liên kết các tp tin đối tượng thành tp tin
.EXE thì bn viết lnh như sau:
\masm32\bin\Link /SUBSYSTEM:WINDOWS /OUT:xxx.exe xxx.obj
Trang 5
Reverse Engineering Association