Hàm GetDiskFreeSpace có nhiệm vụ tìm thông tin về specified disk, kể cả dung lượng trống trên đĩa Code: BOOL GetDiskFreeSpace LPCTSTR lpRootPathName,_____________// address of root path
Trang 1Crack vài soft của www.zealot-soft.com
Quote:
Overview
Amor SWF to Video Converter is a powerful utility that supports to convert Macromedia Flash SWF files to AVI or VCD / SVCD / DVD compatible MPEG files including movie clips, action scripts and audio in the Flash movies Also join many Swf files in one large AVI or VCD / SVCD / DVD compatible MPEG file.Allow the human interaction on Flash content during conversion, no skip frames and support 32bits RGBA alpha channel video that can be directed imported by video authoring tool for composition
Soft: Amor SWF to Video Converter
Homepage: http://www.zealot-soft.com/
Protection: ASPack 2.12 -> Alexey Solodovnikov
Language: Borland Delphi 6.0 - 7.0
Tools: Peid 0.94; OllyDbg 1.10 ; ImpREC 1.6
Cracker: backstrix
Giờ phong trào làm nhạc flash phát triển rộng rãi nhiều cái nhìn trông hay hay burn CD tặng bạn bè cũng good lắm Muốn vậy lại phải convert swf > video Search được cái Amor hay hay nhưng mà kiếm hoài hổng thấy crack của version mới toàn ver cũ không
hà mà ver cũ thì biết kím đâu giờ chứ Nếu không đăng ký ta chỉ được dùng trong 7 ngày thôi Hơn nữa, nó thêm vào dòng chữ báo đây là bản dùng thử to đùng giữa file video sau khi convert Thôi thì giở olly ra xem xét tí vậy Bắt đầu nào
PEiD đâu, ra nhờ tí nào Úy giựt cả mình ASPack 2.12 -> Alexey Solodovnikov Thấy
AS lại tưởng aspr hehe may mà không phải Thằng này thì nhanh gọn thôi Load vô olly
Nó hiện ra cái bảng hỏi xem các pác có thích nó analysis nó tiếp không -> click Yes Các pác sẽ ở đây
Trang 2nhấn chuột fải chọn Breakpoint -> Hardware, On Access -> Dword
Nhấn F9 cho run 1 fát ta break tại
Khà khà ta đang ở OEP rồi, việc ta cần làm là dump nó ra 1 file trên đĩa cứng thui, chọn Plugins -> Ollydump -> Dump Debugged Process bỏ chọn Rebuild import & ghi nhớ giá trị ở ô Modify Okie bấm dump lưu lại với tên pác thích em chọn là dump.exe cho dễ nhớ Giữ nguyên olly, run ImpREC mở bảng liệt kê process chọn file swf2video.exe Nhập địa chỉ OEP vào ô OEP Sau đó nhấn "IAT AutoSearch" Nhấn "Get Imports" Có duy nhất
1 chú mà lại là invalid Chuột phải Advanced command > Get API calls Hix một lô valid:NO hiện ra nhức cả mắt Nhấn Show invalid, chờ chút xíu Okie giờ chuột phải chọn Cut thunk(s) Xong roài, nhấn Fix dump và chọn lấy file dump hồi nãy Run thử file mới này, wow không crash vậy là unpack thành công Scan lại bằng PEiD nó báo liền Borland Delphi 6.0 - 7.0 Xong unpack giờ xử nó được gòi
Run thử soft xem nào một nag văng luôn ra This software can only tray 7 day Please registration! Convert thử 1 file Chài, một dòng chữ to oành ngay giữa file vừa convert Thế thì chán chết Thử reg xem nào Nhập N\S úm ba la chíu bùm Trời đất ơi Thank you for registering Amor SWF to Video Converter,Please restart the program! Thế này thì không mon men theo string được rồi phải dựa vào các hàm API thôi
Dựa vào cái câu Thank you for registering đểu giả này em đoán là nó lưu thông tin vào registry hoặc một file nào đó rồi check khi restart chương trình Ta thấy FU & FS được nó lưu trong file ini trong install dir Hề, vậy là nó check file Biết thế đã, giờ load
nó vào olly Chuột phải -> Search for -> All intermodular calls Chuột phải típ > Sort by > Destination để nhìn cho dễ Giờ chạy đi kiếm hàm GetPrivateProfileStringA Sau khi kiếm được rồi, pác hãy RightClick tại 1 hàm bất kì và chọn Set breakpoint on every call to GetPrivateProfileStringA ta có tất cả 3 hàm thôi không nhiều nhặn gì Xong nhấn F9 run soft nó break tại hàm đầu tiên, ngó nghiêng chả thấy gì quan trọng cả, F9 típ, cũng thía Pác cứ F9 đến khi nào thấy mí cái này bên cửa sổ Register thì dừng lại
ECX 004D8BC8 ASCII "Pass"
hehe cái này hay đây F8 trace over nào, chắc cái hàm kiểm tra serial của ta nó nằm quanh đây thôi F8 một hồi, ta đến đoạn code sau
Code:
Trang 3004D905C | A1 E4CA4D00 MOV EAX,DWORD PTR DS:[4DCAE4]
004D9061 | 8338 00 CMP DWORD PTR DS:[EAX],0
004D9064 0F84 EE000000 JE dump_.004D9158
Hà, có vẻ khả nghi Ta sẽ dừng lại tại đây xem xét một chút Ta thử patch je > jne để xem nó thế nào nhé Save lại thành file mới với tên 1.exe Run thử file này oh nag không còn nữa form register đã bị disable Và cái dòng chữ đáng ghét ở giữa file video cũng không còn We have successfully patched the registration check! :d
Creating an Inline Patch:
Inline Patch được s/d khi ta muốn Patch một chương trình bị Pack mà không muốn
Unpack nó Chúng ta thay đổi program sao cho tại đoạn cuối của quá trình unpacking thay vào việc nhảy tới OEP thì nó nhảy tới đọan code chúng ta tạo ra Ta đưa đoạn code này vào một "code cave" Đoạn code mà ta thêm vào ở thời điểm này sẽ Patch những chỗ cần thiết khi mà program đạng được unpack Sau khi program đã được Patch ta sẽ nhảy tới OEP và run như chưa có chuyện gì xảy ra cả :d Cái cần làm bây giờ là tìm được một
"nơi" trong program đã bị Pack để thêm đoạn code của ta vào Nơi đó gọi là "code cave",
nó là một vùng của bộ nhớ(memory) trong chương trình đang còn trống(empty) Việc tìm Code cave tưởng chừng có vẻ khó nhưng thực ra lại rất chi là izì Trong các files exe thường thường đoạn mã bên trong một section không dùng hết toàn bộ section Vậy thì điều đó cũng có nghĩa ta sẽ s/d những khoảng trống này để viết code của ta Chúng ta sẽ
đi lùng một code cave bên trong program này.(Nguyên văn của bác haule_nth trong loạt tut trans của ARTeam)
Bắt đầu nào, load file swftovideo.exe vào olly Hãy di chuyển scrollbar cho tới khi không nhìn thấy dòng chỉ thị nào nữa thì lúc đó dừng lại Khi các pác tiếp tục nhìn thấy những dòng ADD BYTE PTR DS:[EAX],AL có nghĩa là các pác đang tiến tới gần cuối của section Lúc này tôi đã tìm thấy code cave của mình:
Code:
00563564 CB RETF ; Far return
00563565 15 E8770000 ADC EAX,77E8
0056356A 0000 ADD BYTE PTR DS:[EAX],AL
0056356C 0000 ADD BYTE PTR DS:[EAX],AL
0056356E 0000 ADD BYTE PTR DS:[EAX],AL
00563570 0000 ADD BYTE PTR DS:[EAX],AL
00563572 0000 ADD BYTE PTR DS:[EAX],AL
Các pác có thấy những dòng có 4 số 0000 dưới dòng chỉ thị cuối cùng ko? đó là nơi lý tưởng để tạo code cave của chúng ta Hãy scroll xuống chút nữa wow "bạt ngàn" những dòng code như trên Tôi bắt đầu viết code của tôi tại địa chỉ 0056359C Nhưng trước khi viết code ta phải biết ta sẽ chèn đoạn code vào chỗ nào trong quá trình unpack chứ nhỉ Xem xét chút đã
Trang 4Các pác có nhớ sau khi set hardware bp và nhấn F9 chương trình dừng lại tại đâu không
Code:
0056359C C605 65904D00 8>MOV BYTE PTR DS:[4D9065],85
005635A3 ^ E9 12FEFFFF JMP swftovid.005633BA
Bây giờ bôi đen cả 2 dòng và ấn Right-Click rồi chọn Copy to Executable -> Selection Một cửa sổ mới hiện ra tại cửa sổ này ấn Right-Click và chon Save File -> Save file với tên bất kỳ Lệnh cuối cùng phải thay đổi đó là lệnh Jump ở giai đoạn cuối của quá trình unpack để jump tới code cave vừa tạo Đóng file hiện thời lại và mở file vừa tạo ra Bây giờ ta cần tới đoạn code gần cuối của quá trình unpack chính là đoạn JNZ mà ta phân tích bên trên đó Ta sẽ change lệnh jump này để nó để nó nhảy tới code cave Để change ta bấm SPACE -> trong Assemble box đánh JMP 0056359C rồi ấn Assemble Right-Click
và chọn Copy to Executable -> trong cửa sổ đang mở hãy Right-Click lần nữa và chọn Save File Tôi save với tên là swftovideo_patch_inline.exe Đóng Olly run thử, khà khà phê quá, nó run ầm ầm
Site này còn mấy soft khác cách patch cũng tương tự
Em là super newbie vì vậy kiến thức của em vẫn còn rất hạn chế nên không tránh khỏi nhầm nhọt chỗ này sai xót chỗ kia Mong các bác chỉ giáo để em có thể khá hơn
Mrangelx (http://www.reaonline.net) Windows Cracking Tutorial (complete)
Trang 5
Chào các bác, em chỉ là 1 newbie nhưng hôm rồi đọc được bài viết này về SoftICE nên hôm nay mạn phép translate ra cho các newbie đọc và nếu được cao thủ góp ý cho thì hay quá :) Em mong bài này sẽ giúp ích được cho các bác vì em thấy bài viết này viết kĩ lắm Mong nhận được sự quan tâm của các bác để cùng nhau tiến bộ
Bài viết : Windows Cracking Tutorial
1 Giới thiệu về cracking
2 Giới thiệu về SoftICE/Win 2.00
3 Tìm đoạn code registration
3.1 Phần mềm thực hành : Task Lock 3.00
3.2 Phần mềm thực hành : Command Line 95
4 Tạo keymaker cho phần mềm Command Line 95
5 Làm thế nào mà lệnh PUSH và lệnh CALL và những lệnh khác thật sự làm việc khi mà chương trình gọi 1 funtion
6 Đôi điều về chương trình viết bằng Visual Basic
2 Giới thiệu về SoftICE/Win 2.00
=====================
* How to install SoftICE :
Mặc dù điều này đã được rất, rất… nhìu tut nói rùi nhưng em cũng xin được nói lại (để có
ai chưa biết thì bây giờ biết :) )
Các bác tiến hành install SoftICE như bình thường ( bằng cách nhấn vào file Setup ), khi được hỏi số serial thì bác gõ số serial vào ( thường kèm theo sẵn ) nhưng nếu ko có thì các bác có thể tham khảo số serial ở đây :
+ SoftICE 3.24 : 1900-0000DD-9B
Trang 6+ SoftICE 4.0 : 5419-00009D-DF
+ SoftICE 4.05 : 5109-0122DF-FF
Sau đó các bác típ tục cài đặt cho đến khi hiện bảng thông báo các bác có muốn restart lại máy không , các bác khoan hãy ấn Yes mà hãy dùng Notepad ( hay chương trình soạn thảo nào cũng được ) để mở file winice.dat trong thư mục vừa cài đặt SoftICE Các bác tìm dòng INIT=”WR;X;” ( hoặc có thể là INIT=”X;” ) ở gần đầu file và sửa thành
INIT=”WD;WR; WL;CODE ON;X;” Sau đó các bác kéo xuống gần cuối file tìm các dòng sau :
; ***** Examples of export symbols that can be inluded for Windows 9x *****
; Change the path to the appropriate drive and directory
Trang 7F8 : “bước” vào functions
F10 : “bước” qua functions
F11 : “bước” ra khỏi functions
3 Tìm đoạn code registration
Trước khi bước vào crack chương trình , các bác hãy trả lời 3 câu hỏi này nha :
1 - Đó là chương trình 16 hay 32 bit ?
2 - Làm thế nào để nhập số đăng kí ?
3 - Phần help có thể giúp gì chúng ta để tìm ra cách làm việc của registration không ? Các bác hãy tự tìm câu trả lời cho các câu hỏi trên trước khi chúng ta típ tục nha Em chờ các bác đấy…
Xong chưa các bác ? OK, và sau đây là câu trả lời, các bác xem thử coi có đúng với câu trả lời của các bác không nha ;)
1 – Đây là 1 chương trình 32 bit
2 – Các bác có thể nhập số đăng kí bằng cách gõ vào khung dialog khi các bác chọn menu “Register!Register…”
3 – Và qua phần Help, các bác có thể biết được chương trình có 2 cách đăng kí :
Individual (đăng kí cá nhân) và Site License (đăng kí tại site)
Thế nào, câu trả lời của các bác có đúng không ;) Nếu bác nào trả lời đúng hết thì em xin chúc mừng vì “ các bác có mùi cracker rùi đấy “ ( sorry bác benina nha vì sử dụng câu của bác mà chưa xin phép ;) Đọc đến đây em nghĩ chắc sẽ có bác thắc mắc rằng tại sao phải trả lời câu hỏi 1 làm gì Đúng là em thấy các tuts về SoftICE khác đều không nói về vấn đề này Vì sao ? Vì các tác giả viết sai? Không đâu Thực ra việc trả lời câu hỏi 1 sẽ giúp cho việc crack của các bác đơn giản hơn nhiều Lý do ư , xin mời các bác đọc típ sẽ
- Đối với chương trình 16 bit : GetWindowText , GetDlgItemText
Trang 8- Đối với chương trình 32 bit : GetWindowTextA , GetWIndowTextW ,
GetDlgItemTextA , GetDlgItemTextW
Giờ thì chắc các bác đã hiểu vì sao em bảo các bác trả lời câu hỏi 1 ở trên Okie, giờ chúng ta típ tục nha À quên, em còn điều này chưa nói, các bác có thấy cái chữ cái A và
W trong các function của chương trình 32 bit không, no’ cho chung’ ta biết nếu function
sử dụng one-byte hay double-byte Double-byte code là RARE Đến đây chắc các bác đã hỉu ý em: “If i only could break on GetWindowText” (cái này em xin để nguyên văn câu của tác giả vì em chả bít dịch thế nào cả ;)
Để đặt breakpoint trong SoftICE , các bác vào SoftICE bằng cách ấn Ctrl-D, sau đó dùng lệnh BPX cộng với tên của function hoặc memory address Vì TaskLock là chương trình 32-bit nên sẽ đặt breakpoint ở hàm GetWindowTextA Nếu nó không làm việc, chúng ta
bl
Nó sẽ hiện ra như thế này : 00) BPX USER32!GetWindowTextA C=01
Để ra khỏi SoftICE, các bác ấn Ctrl-D hoặc F5 hoặc dùng lệnh X
Okey, các bác đã bẫy bất kì lệnh gọi GetWindowTextA Bây giờ các bác hãy nhập số nào
đó (ta gọi là FS nha) và ấn OK… chuyện gì sẽ xảy ra? Còn gì nữa, 1 cái nag văng ra nói rằng bác nhập sai registration number Nhưng như dzậy có nghĩa là sao, nghĩa là nó không gọi hàm GetWindowTextA, vậy thì chúng ta sẽ thử với GetDlgItemTextA Nhưng trước hết chúng ta phải xóa cái breakpoint đã đặt đi đã Vào SoftICE đánh : bc 0 , xong chúng ta set breakpoint mới :
BPX GetDlgItemTextA
Chúng ta hãy thử lại nha
3.1.3 Làm việc với SoftICE
-
Oh, nó đã làm việc! Bây giờ chúng ta… uống ly nước đã, em khát nước quá rùi ;))
OK, bây giờ chúng ta đang ở trong SoftICE , tại cái nơi mà function GetDlgItemTextA bắt đầu Để “nhảy” đến nơi mà nó được gọi, các bác hãy nhấn F11 Rùi, chúng ta đang ở trong SGLSET.EXE , nếu các bác không biết thì các bác hãy nhìn vào dòng nằm giữa khung code window và comand window, các bác sẽ thấy như thế này:
-SGLSET!.text+1B13 -
Bây giờ các bác có thể disable breakpoint bằng lệnh : bd 0
Nếu các bác muốn enable nó lại thì các bác dùng lệnh : be 0
Các bác nhìn vào dòng đầu tiên trong code window :
CALL [USER32!GetDlgItemTextA]
Để thấy những lệnh ở trên, các bác nhấn Ctrl-Up Nếu các bác không bít gì về Assembler
Trang 9thì các bác hãy nhìn xuống đây :
PUSH 32 _Lưu chiều dài của FS
PUSH EAX _ Lưu địa chỉ của text buffer
PUSH 000003F4 _Lưu Identifier của control
PUSH DWORD PTR [ESI+1C] Lưu handle của dialog
CALL [USER32!GetDlgItemTextA] _Chúng ta đang ở đây
Em xin giải thích chút xíu : lệnh PUSH có nhiệm vụ lưu lại giá trị cho lần sử dụng sau Các bác chú ý vào 2 dòng màu đỏ Nhìn vào đoạn lệnh trên chúng ta bít được địa chỉ của text buffer đã được cất giữ trong EAX, và EAX đó là EBP-34 Bây giờ chúng ta hãy nhìn vào EBP-34, nó sẽ như thế này : d ebp-3
Chúng ta nhấn F10 đến khi thấy cái gì liên quan đến EBP-34, và nó đây (không bít có giống của các bác không) :
LEA EAX, [EBP+FFFFFF64] _EAX=EBP-9C
LEA ECX, [EBP-34] _ECX=EBP-34
PUSH EAX Lưu EAX
PUSH ECX _Lưu ECX
CALL 00403DD0 Gọi function
ADD ESP, 08 Xóa thông tin đã lưu
TEST EAX, EAX _Kiểm tra function lần nữa
JNZ 00402BC0 Nhảy nếu không bằng 0
Theo em thì đây là 1 đoạn code so sánh, nó làm việc như thế này : Nhập vào 2 giá trị , trở
về 0 nếu 2 giá trị bằng nhau, còn không bằng nhau thì khác 0
Okey, cái gì nằm phía sau [EBP+FFFFFF64], do SoftICE không thể tự negative number, nên để tìm giá trị thật của nó các bác làm phép tính như thế này:
100000000 bằng 0 thì nó cũng cho kết quả như vậy
Và bây giờ là lúc xem cái gì nằm phía sau EBP-9C ( hồi hộp quá ) , các bác làm như sau :
d ebp-9c
Ah, data window hiện ra cho chúng ta 1 dãy số - registration number đây ư ? không đâu (
Trang 10mà sao cái số này giống cái số mà hồi nãy ta nhập vào quá hen ) Các bác có nhớ đoạn code ở trên không, nó so sánh 2 số : 1 là số ta nhập vào , còn số thứ 2 chính là registration number Do vậy chúng ta tiếp tục “nhảy” với F10 nha ;) ( cố lên các bác , thằng
TaskLock sắp là của các bác rùi đấy) Và chúng ta sẽ đến đoạn code này đây ( nó giống đoạn code ở trên đấy các bác ạ ) :
LEA EAX, [EBP-68] EAX=EBP-68
LEA ECX, [EBP-34] _ECX=EBP-34
PUSH EAX Lưu EAX
PUSH ECX Lưu ECX
CALL 00403DD0 Gọi function
ADD ESP, 08 _Xóa thông tin đã lưu
TEST EAX, EAX Kiểm tra function lần nữa
JNZ 00402BFF _Nhảy nếu không bằng 0
Và các bác hãy chú ý đến dòng LEA EAX, [EBP-68] , nó dấu cái gì vậy ? Thui thắc mắc làm cái gì, ta dùng lệnh d là biết nó dấu gì thui mà Nào, các bác đánh cùng em nha : d ebp-68
Hehehe, đây rùi, cuối cùng thì cái registration number nó cũng vác mặt ra !!!
Giống như với TaskLock “xấu số”, chúng ta sẽ đặt breakpoint Chúng ta có thể set
breakpoint cho cả 2 function : GetWindowTextA và GetDlgItemTextA Vào SoftICE (đừng nói là các bác không bít vào nha, đọc đến đây rùi mà nỡ nói 2 chữ không bít là buồn em lắm đó), rùi đánh :
BPX GetWindowTextA
BPX GetDlgItemTextA
Bây giờ chúng ta mở hộp thoại đăng ký ra, nhập tên ( gọi là FN – Fake Name ) và nhập
số nào đó ( em nhập là 12345 và ta hãy gọi số này là FS – Fake Serial ), sau đó nhấn OK…
Và… BÙM, SoftICE nhảy ra giữa màn hình tại function GetDlgItemTextA Cũng như
Trang 11với TaskLock, chúng ta nhấn F11 để trở về đoạn lệnh gọi function Chúng ta nhấn
Ctrl-Up để kéo màn hình lên trên và sẽ thấy đoạn code sau :
MOV ESI,[ESP+0C]
PUSH 1E _Lưu chiều dài lớn nhất của FN
PUSH 0040A680 _Địa chỉ đến buffer
PUSH 000003ED _Control handle
PUSH ESI _Dialog handle
PUSH 000003F6 _Control handle
MOV EDI, 00401680 _Lưu địa chỉ đến buffer
PUSH EDI Dialog handle
CALL [USER32!GetDlgItemInt]
Chắc các bác đang thắc mắc GetDlgItemInt là cái quái gì phải không ? Ở đây em xin nói ngoài lề 1 chút : GetDlgItemInt là 1 function giống với GetDlgItemText, nó trả về giá trị integer từ hộp thoại text Nó được trả về trong EAX, vì vậy chúng ta “nhảy” qua đoạn lệnh này, và nhìn vào register window … Của em là nó như thế này : EAX=00003039
MOV [0040A548], EAX _Lưu FS
MOV EDX, EAX _”đặt” FS vào EDX
3.1.3 Đoạn code tính số serial
-
Và đây chính là đoạn code tính số serial :
MOV ECX, FFFFFFFF Tính chiều dài FN
Trang 12SUB EAX, EAX
REPNZ SCASB
NOT ECX
DEC ECX _EAX chứa chiều dài FN
MOVSX EAX, BYTE PTR [0040A680] Nhận byte tại 40A680
IMUL ECX, EAX _ECX = ECX * EAX
SHL ECX, 0A Đổi chỗ 0A
ADD ECX, 0002F8CC Thêm 2F8CC vào kết quả
MOV [0040A664], ECX
Và đây mới là đoạn code mà ta mong đợi nhất ( cố lên các bác, sắp xong rùi :) :
CMP ECX, EDX _So sánh EAX và EDX
Chúng ta nhìn vào đoạn code tính số serial ở trên, và dịch nó sang C Em làm ví dụ này
để thấy làm thế nào để tính được real serial :
Real serial= [( kí tự viết hoa đầu tiên * chiều dài của chuỗi)<< 0x0A ]+0x2F8CC
unsigned long code;
unsigned char buffer[0*1e];
printf(“CommandLine 95 Keymaker by the_lighthouse\n”);
printf(“Enter your name: “);
gets(buffer);
Trang 13PUSH 32 _Lưu chiều dài của FS
PUSH EAX _Lưu địa chỉ của text buffer
PUSH 000003F4 _Lưu Identifier của control
PUSH DWORD PTR [ESI+1C] Lưu handle của dialog
6 Đôi điều về chương trình viết bằng Visual Basic
===================================
File Visual Basic.exe không thực sự được biên dịch ra file exe Nó chỉ chứa đoạn code để gọi file VBRUNxxx.DLL , file này có nhiệm vụ đọc dữ liệu từ file exe và chạy chương trình Đó là lí do vì sao chương trình viết bằng Visual Basic lại chạy chậm như vậy Và khi file exe không có thực, các bác không thể disassemble nó, các bác chỉ tìm thấy đoạn lệnh gọi DLL và rất nhiều “rác”, và khi các bác dubeg, các bác sẽ kết thúc tại DLL
Và cách giải quyết là decompiler (dịch ngược) Có rất nhìu chương trình decompile cho Visual Basic, được viết bởi DoDi Đây là chương trình shareware và có thể tìm được trên mạng
Trang 14Tuy nhiên các bác cũng chớ lo vì các programmer giỏi thường không bao giờ viết chương trình bằng Basic (phù, may quá ;))
Phụ lục :
A Làm thế nào để kiểm tra SoftICE đã load symbols ?
++++++++++++++++++++++++++++++++++++++
Để kiểm tra xem SoftICE đã load symbols cho GetWindowText chưa, các bác vào
SoftICE và đánh : exp getwindowtext
B Cú pháp cho function
+++++++++++++++++
int GetWindowText(int windowhandle, char *buffer, int maxlen);
int GetDlgItemText(int dialoghandle, int controlid, char *buffer, int maxlen);
int GetDlgIemInt(int dialoghandle, int controlid, int *flag, int type);
the_lighthouse (http://www.reaonline.net) cRACKER's nOTES
Quote:
Bài viết được chia thành 10 phần chính :
00 Giới thiệu
01 Assembly for Crackers
02 SoftICE ( Boot Menu, Setup, Commands)
Trang 15+ 06.5 Key File Protections
+ 06.6 Nag Screens
+ 06.7 Runtime Limits
+ 06.8 Serials
+ 06.9 Time Limits
+ 06.10 Visual Basic Programs
07 Window Messages for Crackers
08 Nhận biết Functions, Arguments, và Variables
+A Những ý kiến chung về Cracking
+B Những câu hỏi thường gặp
01 Assembly for Crackers
Trang 16CMP
Cú pháp : CMP <left>,<right>
Left: là thanh ghi hay bộ nhớ
Right : là thanh ghi hay bộ nhớ hay trực hằng
Tác dụng : dùng để so sánh giữa toán hạng left và toán hạng right Lệnh này Assemble sẽ lấy toán hạng left trừ toán hạng right, kết quả được lưu trong các cờ mà không thay đổi nội dung của 2 toán hạng trên
+Đối với số có dấu :
Left > Right=>ZF=0/1, OF=0, SF=0/1
Left = Right=>ZF=1, OF=0, SF=0
Left < Right=>ZF=0, OF=0/1, SF=1/0
Và ta thấy lệnh này thường được đặt trước lệnh jump
Quote:
Flags
Về cơ bản , Flags giống registers ngoại trừ việc Flags chỉ có thể tồn tại true (đúng) hoặc false (sai) Nó được set bởi những lệnh như CMP, và được dùng để kiểm tra kết quả lệnh call Ví dụ :
CMP AX, BX So sánh AX và BX, nếu bằng thì cờ Zero được set là 0
JZ 00124531 _Nếu cờ zero đã được set thì nhảy đến địa chỉ 00124531
Ví dụ : INT 21h ( gọi ngắt 21 của DOS )
Trang 17mềm xảy ra khi chương trình gọi phục vụ ngắt bằng lệnh INT <interupt>
Bạn sẽ không thấy lệnh này khi debug chương trình window, nhưng nó “gây náo loạn” khắp mọi nơi trong DOS Thường các thông số vượt qua default registers( như AX, BX, CX…)
JMP là lệnh nhảy không điều kiện nhảy đến section của code
Có rất nhiều sự khác nhau trong lệnh này, và quan trọng nhất là :
JZ nhảy nếu cờ zero được set ( giống như JE )
JNZ _nhảy nếu cờ zero không được set ( giống như JNE )
Và nó thường được đi theo sau lệnh CMP :
CMP RealSerial,FakeSerial _so sánh real serial với fake serial do ta nhập vào
JNE nhảy nếu không bằng
Quote:
LODSB / LODSW
Cú pháp : LODSB / LODSW
Tác dụng : load 1 byte hoặc 1 word từ DS:SI và đặt nó vào AL (đối với LODSB) hay vào
AX (đối với LODSW)
Ví dụ : LODSW
Hãy chuyển DS:SI points đến word mà đang giữ giá trị Ebh
LODSW
AX bây giờ sẽ chứa giá trị EBh
Lệnh này thương được sử dụng cùng với lệnh REP
Quote:
MOV
Cú pháp : MOV <đích>,<nguồn>
<đích>: chỉ có thể là 1 thanh ghi hay bộ nhớ
<nguồn>: có thể là thanh ghi, bộ nhớ hay hằng
Tác dụng : chuyển nội dung toán hạng nguồn vào toán hạng đích
MOVSB / MOVSW
Trang 18Cú pháp : MOVSB / MOVSW
Tác dụng : chuyển byte (đối với MOVSB) hoặc word (đối với MOVSW) từ DS:SI đến ES:DI
Ví dụ : MOVSB
Hãy chuyển DS:SI points đến byte mà giữ giá trị 5h
MOVSB lấy byte của DS:SI points và đặt nó trong ES:DI
Byte của ES:DI bây giờ có giá trị là 5h
Lệnh này thường được dùng với lệnh REP
Quote:
Registers
Registers là nơi mà chứa dữ liệu Một điều duy nhất chúng ta lo lắng là: (E)AX, (E)BX, E(CX), E(DX) (chữ E chỉ có ý nghĩa khi chúng ta debug 32bit-code
Như vậy cặp registers là :
DS:SI có thể được dùng như nguồn của chuỗi hoạt động
ES:DI sử dụng như mục tiêu của chuỗi hoạt động
Việc hiểu registers không phải là quá quan trọng trong việc crack, các bác chỉ cầ bít nó là những biến số để lưu trữ dữ liệu là được
Trang 19STOSB copy giá trị trong AX và đặt nó vào word của DS:SI Lúc này DS:SI points
to word chứa Ebh
Lệnh này thường được dùng với lệnh REP
Quote:
The STACK & PUSH / POP
Trước khi gọi bất kì function nào, chương trình phải “push” những thông số mà function đang “chờ đợi” trên stack Chúng ta giả sử nó như là 1 chồng bát, cái bát đặt vào đầu tiên
sẽ là cái bát lấy ra cuối cùng - ở đây stack cũng vậy Chúng ta hãy cứ nhớ “vào đầu / ra cuối” khi nhìn vào lệnh call, có nghĩa là thông số đó sẽ đảo ngược
Nếu như các bác không hỉu những giều trên thì hãy nhìn vào ví dụ sau :
Windows API function GetDlgItemText yêu cầu các thông số sau:
(1) Handle of dialog box
(2) Identifier of control
(3) Địa chỉ của text buffer
(4) Chiều dài tối đa của chuỗi
Bởi vậy nên đoạn code có thể như sau :
MOV EDI,[ESP+00000220] _get handle of dialog box trong EDI
PUSH 00000100 PUSH (4)
PUSH 00406130 PUSH (3)
PUSH 00000405 PUSH (2)
PUSH EDI _PUSH (1)
CALL GetWindowText Gọi function
Có dễ không các bác? Đây là 1 trong những ví dụ đơn giản nhất trong lĩnh vực crack đi tìm số serial, nếu các bác biết được địa chỉ buffer của serial, trong trường hợp này là ở địa chỉ 00406130 , các bác hãy set breakpoint nó và thường các bác sẽ kết thúc tại chuỗi tạo real serial ;)
Để chạy, SoftICE cần vài KB trong RAM của mỗi chương trình Do đó, nếu máy bạn bị
“hạn chế” về RAM hoặc bạn không muốn SoftICE tự động load mỗi khi khởi động máy ( chả lẽ cứ vào msconfig tắt nó rồi khi nào cân dùng lại chỉnh lại rồi phải khởi động lại máy nữa >rất phiền) mà phải “hỏi ý kiến” rồi mới dám “vào chơi với em windows” thì bạn cần phải chỉnh sửa đôi chút trong AUTOEXEC.BAT và CONFIG.SYS Các bác hãy coi 2 file đó trong máy em rồi tìm cách sửa theo máy các bác nha :
AUTOEXEC.BAT:
Trang 20menuitem SICE,Load Soft-Ice
menuitem NORM,khong load SoftICE
menudefault NORM,5(5s là thời gian ngồi chờ các bác “cho phép”, nếu quá 5s mà không thấy các bác trả lời thì windows sẽ típ tục load mà không load SoftICE, các bác có thể thay đổi thời gian chờ đợi 5s này)
Trang 21BPM, BPMB, BPMW, BPMD Breakpoint on memory access BPR Breakpoint on memory range
BPIO _Breakpoint on I/O port access
DATA _Change data window
E, EB, EW, ED, EL, ET Edit memory
EXIT EXIT
F _Fill memory with data
FORMAT _Change format of data window G _Go to address
H _Help on specific function
HBOOT System boot (total reset)
HERE _Go to current cursor line
HWND _Display window handle information M _Move Data
MOD Display windows module list
P _Step skipping calls, Int, etc
R _Display/Change Register contents S _Search for data
T _Single Step one instruction
TASK Display windows task list
THREAD Display thread information
HEAP Display windows global heap
LHEAP _Display windows local heap
IDT _Display interrupt descriptor table
I, IB, IW, ID Input data from I/O Port
O OB, OW, OD Output data form I/O Port
Trang 22LDT _Display local descriptor table
MAP32 _Display 32Bit section map
MAPV86 Display v86 memory map
PAGE Display page table information
PCI Display PCI device information
PEEK Read from physical address
PHYS Display all virtual addresses for physical address POKE Write to physical address
PROC Display process information
QUERY Display process virtual address space map TSS _Display task state segment
STACK _Display call stack
I3HERE Direct INT3 to SoftICE
SET _Change an internal variable
ZAP _Zap embedded INT1 or INT3
Những lệnh chỉnh sửa :
ALTKEY _Set key sequence to invoke window ANSWER Auto-answer and redirect console to modem CODE _Display insctruction bytes in code window COLOR Display/Set screen colors
DEX Display/Assign window data expression DIAL Redirect console to modem
FKEY Display/Set function keys
LINES _Set/Display number of lines on screen MACRO Define a named macro command
PAUSE _Control display scroll mode
PRN _Set printer output port
SERIAL Redirect console
TABS Set/Display tab setting
Window Commands :
. _ Locate current instruction
EC Enable/Disable code window
WC _Toggle code window
Trang 23WD _Toggle data window
WF _Toggle float point stack window
WL _ Toggle locals window
WR _Toggle register window
WW _Toggle watch window
Window Control :
ALTSCR Change to alternate display
CLS _Clear window
FLASH _Restore screen during P and T
RS Restore program screen
Symbole / Source Commands :
EXP _Display export symbols
FILE Change/Display current source file
LOCALS Display locals currently in scope
SRC _Toggle between source, mixed & code
SS Search source module for string
SYMLOC _Relocate symbol base
TAB _Select/Remove symbol table
TYPES _List all types, or display type defination
Back Trace Commands :
SHOW _Display from backtrace buffer
TRACE Enter backtrace simulation mode
XT Step in trace simulation mode
XP Program step in trace simulation mode
XG Go to address in trace simulation mode
XRSET _Reset backtrace history buffer
Special Operators :
. _Preceding a decimal number specifies a line number
$ Preceding an address specifies SEGMENT addressing
# Preceding an address specifies SELECTOR
Trang 24BOOL EnableMenuItem(
HMENU hMenu, _// handle of menu
UINT uIDEnableItem, // menu item to enable, disable, or gray
UINT uEnable // menu item flags
);
Returns
Giá trị trả về sẽ chỉ rõ trạng thái trước đó của menu item (đó là MF_DISABLED,
MF_ENABLED hay MF_GRAYED) Nếu menu item không tồn tại, giá trị trả về sẽ là 0xFFFFFFFF
EnableWindow
Hàm EnableWindow có nhiệm vụ enable hoặc disable chuột và bàn phím input vào specified window hoặc control Khi input bị disable, window không thể nhận input như click chuột và gõ phím Khi input enable, window nhận tất cả input
HWND CreateDialogIndirectParam(
HINSTANCE hInstance, // handle of application instance
LPCDLGTEMPLATE lpTemplate, // address of dialog box template
HWND hWndParent, // handle of owner window
DLGPROC lpDialogFunc, _// address of dialog box procedure
LPARAM lParamInit _// initialization value
);
Returns
Nếu function succeed (tạm dịch là hoàn thành), giá trị trả về là handle của dialog box
Trang 25Còn nếu function fail (không hoàn thành), giá trị trả về là NULL, giá trị là 0xFFFFFFFF
CreateDialogParamA / CreateDialogParamW
Hàm CreateDialogParamA có nhiệm vụ tạo ra modeless dialog box từ dialog box
template resource Trước khi display dialog box, function sẽ pass program-defined value vào dialog box procedure giống như thông số Iparam của WM_INITDIALOG message Chương trình có thể sử dụng giá trị này để initialize dialog box controls
Code:
HWND CreateDialogParam(
HINSTANCE hInstance, // handle of application instance
LPCTSTR lpTemplateName, _// identifies dialog box template
HWND hWndParent, _ // handle of owner window
DLGPROC lpDialogFunc, _// address of dialog box procedure
LPARAM dwInitParam // initialization value
Code:
int DialogBox(
HANDLE hInstance, // handle of application instance
LPCTSTR lpTemplate, _// identifies dialog box template
HWND hWndParent, _// handle of owner window
DLGPROC lpDialogFunc // address of dialog box procedure );
HANDLE hInstance, _// handle of application instance
LPDLGTEMPLATE lpTemplate, // identifies dialog box template
Trang 26HWND hWndParent, // handle of owner window
DLGPROC lpDialogFunc _// address of dialog box procedure );
Returns
Giá trị trả về là giá trị của thông số nResult trong lệnh EndDialog được dùng để kết thúc dialog box Giá trị trả về là -1 nếu function không tạo được dialog box
DialogBoxParam / DialogBoxParamA / DialogBoxParamW
Hàm DialogBoxParam có nhiệm vụ tạo ra modal box từ dialog box template resource Trước khi display dialog box, function sẽ pass program-defined value vào dialog box procedure giống như thông số Iparam của WM_INITDIALOG message Chương trình có thể sử dụng giá trị này để initialize dialog box controls
Code:
int DialogBoxParam(
HINSTANCE hInstance, _// handle of application instance
LPCTSTR lpTemplateName, // identifies dialog box template
HWND hWndParent, // handle of owner window
DLGPROC lpDialogFunc, _// address of dialog box procedure
LPARAM dwInitParam // initialization value
HWND hDlg, _// handle of dialog box
int nResult _// value to return
Trang 27Hàm này có nhiệm vụ tạo ra, display, và operate(làm cho hoạt động) message box
Message box gồm có program-defined message và title cộng thêm 1 vài sự kết hợp của predefined icon và push button
Code:
int MessageBox(
HWND hWnd, _// handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box
);
Returns
Giá trị trả về là 0 nếu không có đủ memory để tạo message box Nếu function hoàn thành, giá trị trả về là một trong những giá trị đã returned bởi dialog box :
IDABORT, IDCANCEL, IDIGNORE, IDNO, IDOK, IDRETRY, IDYES
Nếu message box có nút Cancel, giá trị trả về là IDCANCEL nếu nhấn phím Esc hoặc chọn Cancel button Nếu message box không có nút Cancel, nút Esc sẽ không có tác dụng
MessageBoxExA / MessageBoxExW
Hàm này có nhiệm vụ tạo ra, display, và operate(làm hoạt động) message box Message box gồm có program-defined message và title cộng thêm 1 vài sự kết hợp của predefined icon và push button Thông số wLanguageId set language resource được dùng để
predefined push button
Code:
int MessageBoxEx(
HWND hWnd, // handle of owner window
LPCTSTR lpText, _// address of text in message box
LPCTSTR lpCaption, _// address of title of message box
UINT uType, _// style of message box
WORD wLanguageId _// language identifier
);
Returns
Nếu function hoàn thành, giá trị trả về là giá trị menu-item khác 0 đã returned bởi dialog
Trang 28box
MessageBoxIndirect / MessageBoxIndirectA / MessageBoxIndirectW
Hàm MessageBoxIndirect có nhiệm vụ tạo ra, display, và làm hoạt động message box Message box gồm có program-defined message text và title, icons, và 1 vài sự kết hợp của predifined push button
Code:
BOOL API MessageBoxIndirect(
LPMSGBOXPARAMS lpMsgBoxParams // address of structure for msg box parameters
);
03.3 Drive Type Checks
==============
CreateFileA / CreateFileW
Hàm CreateFile có nhiệm vụ tạo ra, mở, hoặc truncate file, pipe(đường dẫn),
communication resource, disk device hoặc console Nó return handle mà có thể được dùng để access (truy cập) object (đối tượng) Nó cũng có thể mở và return handle to directory
Code:
HANDLE CreateFile(
LPCTSTR lpFileName, _// address of name of the file DWORD dwDesiredAccess, _// access (read-write) mode DWORD dwShareMode, _// share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, _// address of security descriptor
DWORD dwCreationDistribution, // how to create
DWORD dwFlagsAndAttributes, _// file attributes
HANDLE hTemplateFile _// handle of file with attributes
CREATE_ALWAYS hoặc OPEN_ALWAYS, lệnh gọi GetLastError trở về
ERROR_ALREADY_EXISTS (ngay cả khi function đã hoàn thành) Còn nếu file tồn tại trước khi gọi, GetLastError trả về 0
Nếu function không hoàn thành , giá trị trả về là INVALID_HANDLE_VALUE Để có thông tin về lỗi, chúng ta dùng lệnh GetLastError
GetDiskFreeSpaceA / GetDiskFreeSpaceW
Trang 29Hàm GetDiskFreeSpace có nhiệm vụ tìm thông tin về specified disk, kể cả dung lượng trống trên đĩa
Code:
BOOL GetDiskFreeSpace(
LPCTSTR lpRootPathName, _// address of root path
LPDWORD lpSectorsPerCluster, _// address of sectors per cluster
LPDWORD lpBytesPerSector, _// address of bytes per sector
LPDWORD lpNumberOfFreeClusters, _// address of number of free clusters LPDWORD lpTotalNumberOfClusters _// address of total number of clusters );
0 Drive không thể xác định được
1 Drive không thể xác định được
2 Root Directory không tồn tại
3 Fixed Drive (hardware)
4 Remote Drive (network)
LPTSTR lpBuffer, // address of path buffer
LPTSTR *lpFilePart _// address of filename in path
);
Returns
Nếu function được hoàn thành, giá trị trả về là độ dài (chỉ tính kí tự chữ) của chuỗi được
Trang 30copy vào IpBuffer, không bao gồm kí tự terminating null Nếu IpBuffer buffer qua nhỏ, giá trị trả về là độ lớn mà buffer(cũng chỉ tính kí tự chữ) cần có để hold path Nếu
function không hoàn thành , giá trị trả về là 0 Để có thông tin về lỗi, chúng ta dùng lệnh GetLastError
Nếu function hoàn thành , giá trị trả về là bitmask mô tả disk drive hiện đang available
Vị trí bit 0 là đĩa A, vị trí bit 1 là đĩa B, vị trí bit 2 là đĩa C, và cứ như thế… Nếu function không hoàn thành , giá trị trả về là 0
DWORD nBufferLength, // size of buffer
LPTSTR lpBuffer // address of buffer for drive strings
);
Returns
Nếu function hoàn thành, giá trị trả về là chiều dài (chỉ tính kí tự chữ) của chuỗi được copy vào buffer, không bao gồm kí tự terminating null Các bác nên nhớ 1 kí tự ANSI-ASCII null sử dụng 1 byte, trong khi 1 kí tự Unicode null lại sử dụng 2 byte
Nếu buffer không đủ lớn, giá trị trả về sẽ lớn hơn nBufferLength Nó là độ lớn mà buffer cần có để hold drive string Nếu function không hoàn thành , giá trị trả về là 0 Để có thông tin về lỗi, chúng ta dùng lệnh GetLastError
Trang 31LPDWORD lpMaximumComponentLength, _// address of system's maximum filename length
LPDWORD lpFileSystemFlags, // address of file system flags
LPTSTR lpFileSystemNameBuffer, _// address of name of file system DWORD nFileSystemNameSize // length of lpFileSystemNameBuffer );
Returns
Nếu tất cả thông tin yêu cầu được tìm thấy, giá trị trả về là TRUE, ngược lại giá trị trả về
là FALSE Để có thông tin về lỗi, chúng ta dùng lệnh GetLastError
HFILE hFile, // handle of file
LPVOID lpBuffer, // address of buffer for read data
UINT uBytes // length, in bytes, of data buffer
HFILE hFile, // handle of file
LPCSTR lpBuffer, // address of buffer for data to be written
UINT uBytes // number of bytes to write
);
Returns
Nếu function hoàn thành , giá trị trả về cho biết số byte đã viết được vào file
Nếu function không hoàn thành , giá trị trả về là HFILE_ERROR Để có thông tin về lỗi, chúng ta sử dụng hàm GetLastError
CreateFileA / CreateFileW
Trang 32Hàm CreateFile có nhiệm vụ tạo ra, mở, hoặc truncate file, pipe(đường dẫn),
communication resource, disk device hoặc console Nó return handle mà có thể được dùng để truy cập đối tượng Nó cũng có thể mở và return handle to directory
Code:
HANDLE CreateFile(
LPCTSTR lpFileName, // address of name of the file
DWORD dwDesiredAccess, // access (read-write) mode
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // address of security
descriptor
DWORD dwCreationDistribution, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle of file with attributes to copy );
Returns
Nếu function hoàn thành, giá trị trả về là open handle của specified file Nếu specified file không tồn tại trước khi function gọi và dwCreationDistribution là
CREATE_ALWAYS hoặc OPEN_ALWAYS, lệnh gọi GetLastError trở về
ERROR_ALREADY_EXISTS (ngay cả khi function đã hoàn thành) Còn nếu file tồn tại trước khi gọi, GetLastError trả về 0
Nếu function không hoàn thành , giá trị trả về là INVALID_HANDLE_VALUE Để có thông tin về lỗi, chúng ta dùng lệnh GetLastError
LPCTSTR lpAppName, // address of section name
LPCTSTR lpKeyName, // address of key name
INT nDefault, // return value if key name is not found
LPCTSTR lpFileName // address of initialization filename
);
Returns
Nếu function hoàn thành , giá trị trả về là số tương đương của chuỗi phía sau tên key chỉ định trong file khởi tạo đã quy định Nếu không tìm thấy key, giá trị trả về là giá trị mặc định Nếu giá trị của key nhỏ hơn 0, giá trị trả về là 0
GetPrivateProfileStringA / GetPrivateProfileStringW
Hàm GetPrivateProfileString có nhiệm vụ tìm string từ section đã chỉ định trong file khởi
Trang 33tạo Hàm này tương thích với phiên bản 16-bit Window Còn đối với Win32 thì nên “cất” thông tin khởi tạo vào trong Registry
Code:
DWORD GetPrivateProfileString(
LPCTSTR lpAppName, // points to section name
LPCTSTR lpKeyName, // points to key name
LPCTSTR lpDefault, // points to default string
LPTSTR lpReturnedString, // points to destination buffer
DWORD nSize, // size of destination buffer
LPCTSTR lpFileName // points to initialization filename
ReadFileA
Hàm ReadFile có nhiệm vụ đọc dữ liệu từ file, bắt đầu tại vị trí được cho biết bởi file pointer Sau khi đọc xong, file pointer sửa lại cho đúng bằng số byte đã được đọc, trừ khi file handle được tạo với thuộc tính overlapped (chồng lên) Nếu file handle được tạo để overlapped input (cho vào) và output (lấy ra) (I / O) , sau khi đọc xong application phải chỉnh lại cho đúng vị trí của file pointer
Code:
BOOL ReadFile(
HANDLE hFile, // handle of file to read
LPVOID lpBuffer, // address of buffer that receives data
DWORD nNumberOfBytesToRead, // number of bytes to read
LPDWORD lpNumberOfBytesRead, // address of number of bytes read
LPOVERLAPPED lpOverlapped // address of structure for data
);
Returns
Nếu function hoàn thành , giá trị trả về là TRUE Nếu giá trị trả về là TRUE và số byte được đọc là 0 thì file pointer ở xa điểm cuối của file tại thời điểm xảy ra quá trình đọc Nếu function không hoàn thành , giá trị trả về là FALSE Để có thông tin về lỗi, chúng ta dùng hàm GetLastError
Trang 34HANDLE hFile, // handle of file to read
LPVOID lpBuffer, // address of buffer
DWORD nNumberOfBytesToRead, // number of bytes to read
LPOVERLAPPED lpOverlapped, // address of offset
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine // address of completion routine
);
Returns
Nếu function hoàn thành , giá trị trả về là TRUE
Nếu function không hoàn thành , giá trị trả về là FALSE Để có thông tin về lỗi, chúng ta dùng hàm GetLastError
Nếu function hoàn thành , calling thread có quá trình I/O không đồng bộ trong khoảng thời gian : overlapped đọc thao tác từ file Khi quá trình I/O này kết thúc, và lệnh gọi thread bị khóa trong alertable wait state, hệ thống gọi hàm IpCompletionRoutine, và alertable wait state hoàn thành với đoạn code trở lại WAIT_IO_COMPLETION
Nếu function hoàn thành , và quá trình đọc file hoàn thành, nhưng lệnh gọi thread không
có trong alertable wait state, hệ thống queue lệnh call completion thông thường, típ tục lệnh call cho đến khi lệnh gọi thread “gia nhập” alertable wait state Để biết thông tin về alertable wait và overlapped input / output, các bác hãy đọc Synchronization and
Overlapped Input and Output
Nếu hàm ReadFileEx cố gắng đọc qua đoạn cuối của file, giá trị trả về là FALSE, và GetLastError trở về ERROR_HANDLE_EOF
SetFilePointer
Hàm SetFilePointer có nhiệm vụ di chuyển pointer của open file
Code:
DWORD SetFilePointer(
HANDLE hFile, // handle of file
LONG lDistanceToMove, // number of bytes to move file pointer
PLONG lpDistanceToMoveHigh, // address of high-order word of dist to move DWORD dwMoveMethod // how to move
);
Trang 35Returns
Nếu function hoàn thành , giá trị trả về là low-order doubleword của new file pointer, và nếu IpDistanceToMoveHigh không phải là NULL, function đặt high-order doubleword của new file pointer vào trong LONG pointer bằng các thông số đó
WriteFile
Hàm WriteFile có nhiệm vụ viết dữ liệu vào file và được design cho cả 2 quá trình đồng
bộ và không đồng bộ Hàm này bắt đầu viết dữ liệu vào file tại vị trí được cho biết bởi file pointer Sau khi viết xong, file pointer sửa lại cho đúng bằng số byte đã được viết, trừ khi file được mở với FILE_FLAG_OVERLAPPED ) Nếu file handle được tạo để
overlapped input (cho vào) và output (lấy ra) (I / O) , sau khi viết xong application phải chỉnh lại cho đúng vị trí của file pointer
Code:
BOOL WriteFile(
HANDLE hFile, // handle of file to write to
LPCVOID lpBuffer, // address of data to write to file
DWORD nNumberOfBytesToWrite, // number of bytes to write
LPDWORD lpNumberOfBytesWritten, // address of number of bytes written LPOVERLAPPED lpOverlapped // addr of structure needed for
overlapped I/O
);
Returns
Nếu function hoàn thành , giá trị trả về là TRUE
Nếu function không hoàn thành , giá trị trả về là FALSE Để có thêm thông tin về lỗi, chúng ta dùng hàm GetLastError
WriteFileEx
Hàm WriteFileEx có nhiệm vụ viết dữ liệu vào file Nó chỉ được design cho quá trình không đồng bộ, khác với hàm WriteFile được design cho cả 2 quá trình đồng bộ và không đồng bộ
Hàm WriteFileEx “báo cáo” tình trạng không đồng bộ của nó, gọi completion routine chỉ định khi quá trình viết hoàn thành và lệnh gọi thread là alertable wait state
Code:
BOOL WriteFileEx(
HANDLE hFile; // handle to output file
LPCVOID lpBuffer; // pointer to input buffer
DWORD nNumberOfBytesToWrite; // number of bytes to write
LPOVERLAPPED lpOverlapped; // pointer to async i/o data
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine; // ptr to completion routine
);
Trang 36Returns
Nếu function hoàn thành , giá trị trả về là TRUE
Nếu function không hoàn thành , giá trị trả về là FALSE Để có thêm thông tin về lỗi, chúng ta dùng hàm GetLastError
Nếu hàm WriteFileEx hoàn thành , calling thread có quá trình I/O không đồng bộ trong khoảng thời gian : overlapped viết thao tác vào file Khi quá trình I/O này kết thúc, và lệnh gọi thread bị khóa trong alertable wait state, hệ thống gọi hàm
IpCompletionRoutine, và sự chờ đợi hoàn thành với đoạn code trở lại
WAIT_IO_COMPLETION
Nếu function hoàn thành và quá trình viết dữ liệu vào file hoàn thành, nhưng lệnh call thread không nằm trong alertable wait state, hệ thống queue lệnh call *IpCompletion, típ tục lệnh call cho đến khi lệnh gọi thread “gia nhập” alertable wait state Đọc
Synchronization để biết thêm thông tin về alertable wait state và quá trình overlapped input / output
WritePrivateProfileStringA / WritePrivateProfileStringW
Code:
BOOL WritePrivateProfileString(
LPCTSTR lpszSection, // address of section name
LPCTSTR lpszKey, // address of key name
LPCTSTR lpszString, // address of string to add
LPCTSTR lpszFile // address of initialization filename
);
Returns
Nếu function copy string vào file khởi tạo thành công, giá trị trả về là TRUE
Nếu function không hoàn thành , hoặc nếu nó flush cached version của hầu hết file khởi tạo truy cập gần đây, giá trị trả về là FALSE Để có thông tin về lỗi, chúng ta dùng hàm GetLastError
Code:
LONG RegCreateKey(
HKEY hKey, // handle of an open key
LPCTSTR lpszSubKey, // address of name of subkey to open
PHKEY phkResult // address of buffer for opened handle
);
Trang 37Returns
Nếu function hoàn thành , giá trị trả về là ERROR_SUCCESS
Nếu function không hoàn thành , giá trị trả về là 1 giá trị lỗi
HKEY hKey, // handle of an open key
LPCTSTR lpszSubKey, // address of subkey name
DWORD dwReserved, // reserved
LPTSTR lpszClass, // address of class string
DWORD fdwOptions, // special options flag
REGSAM samDesired, // desired security access
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // address of key security structure
PHKEY phkResult, // address of buffer for opened handle LPDWORD lpdwDisposition // address of disposition value buffer );
Returns
Nếu function hoàn thành , giá trị trả về là ERROR_SUCCESS
Nếu function không hoàn thành , giá trị trả về là 1 giá trị lỗi
RegDeleteKeyA / RegDeleteKeyW
Hàm RegDeleteKey có nhiệm vụ xóa key và tất cả các key khác nằm trong nó
Code:
LONG RegDeleteKey(
HKEY hKey, // handle of open key
LPCTSTR lpszSubKey // address of name of subkey to delete );
Returns
Nếu function hoàn thành , giá trị trả về là ERROR_SUCCESS
Nếu function không hoàn thành , giá trị trả về là 1 giá trị lỗi
RegDeleteValueA / RegDeleteValueW
Hàm RegDeleteValue có nhiệm vụ di chuyển named value từ specified registry key Code:
LONG RegDeleteValue(
Trang 38HKEY hKey, // handle of key
LPTSTR lpszValue // address of value name
);
Returns
Nếu function hoàn thành , giá trị trả về là ERROR_SUCCESS
Nếu function không hoàn thành , giá trị trả về là 1 giá trị lỗi
HKEY hKey, // handle of open key
LPCTSTR lpszSubKey, // address of name of subkey to open
PHKEY phkResult // address of handle of open key
);
Returns
Nếu function hoàn thành , giá trị trả về là ERROR_SUCCESS
Nếu function không hoàn thành , giá trị trả về là 1 giá trị lỗi
RegOpenKeyExA / RegOpenKeyExW
Hàm RegOpenKeyEx có nhiệm vụ mở specified key
Code:
LONG RegOpenKeyEx(
HKEY hKey, // handle of open key
LPCTSTR lpszSubKey, // address of name of subkey to open
DWORD dwReserved, // reserved
REGSAM samDesired, // security access mask
PHKEY phkResult // address of handle of open key
);
Returns
Nếu function hoàn thành , giá trị trả về là ERROR_SUCCESS
Nếu function không hoàn thành , giá trị trả về là 1 giá trị lỗi
RegQueryValueA / RegQueryValueW
Hàm RegQueryValue có nhiệm vụ tìm giá trị kết hợp với giá trị không tên cho specified key trong registry Những giá trị trong registry có tên, type (loại) và thành phần dữ liệu Hàm này tìm dữ liệu cho giá trị đầu tiên của key có NULL name Hàm này tương thích với Windows 3.1 Còn đối với Win32 thì chúng ta nên dùng hàm RegQueryValueEx Code:
Trang 39LONG RegQueryValue(
HKEY hKey, // handle of key to query
LPCTSTR lpszSubKey, // address of name of subkey to query
LPTSTR lpszValue, // address of buffer for ret string
PLONG pcbValue // address of buffer for size of ret string
);
Returns
Nếu function hoàn thành , giá trị trả về là ERROR_SUCCESS
Nếu function không hoàn thành , giá trị trả về là 1 giá trị lỗi
HKEY hKey, // handle of key to query
LPTSTR lpszValueName, // address of name of value to query
LPDWORD lpdwReserved, // reserved
LPDWORD lpdwType, // address of buffer for value type
LPBYTE lpbData, // address of data buffer
LPDWORD lpcbData // address of data buffer size
);
Returns
Nếu function hoàn thành , giá trị trả về là ERROR_SUCCESS
Nếu function không hoàn thành , giá trị trả về là 1 giá trị lỗi
HWND hDlg, // handle to dialog box
int nIDDlgItem, // control identifier
BOOL* lpTranslated, // points to var to rec suc/failr indicator
BOOL bSigned // specifies whether value is un/-signed
);
Returns
Nếu function hoàn thành , biến số pointed to bởi IpTranslated được set TRUE, và giá trị trả về là giá trị đã dịch từ control text
Trang 40Nếu function không hoàn thành , biến số pointed to bởi IpTranslated được set FALSE, và giá trị trả về là 0 Nếu như 0 là giá trị translated thì giá trị trả về của 0 không tự indicate failure
Nếu IpTranslated là NULL, function return không có thông tin về hoàn thành hay không hoàn thành
Nếu thông số bSigned là TRUE, ghi rõ giá trị được tìm thấy là giá trị integer signed,
“quăng” giá trị trả về vào int type
GetDlgItemText / GetDlgItemTextA / GetDlgItemTextW
Hàm GetDlgItemText có nhiệm vụ tìm title hoặc text kết hợp với control trong dialog box
Code:
UINT GetDlgItemText(
HWND hDlg, // handle of dialog box
int nIDDlgItem, // identifier of control
LPTSTR lpString, // address of buffer for text
int nMaxCount // maximum size of string
);
Returns
Nếu function hoàn thành , giá trị trả về ghi rõ số kí tự được copy vào buffer, không bao gồm kí tự null
Nếu function không hoàn thành , giá trị trả về là 0
GetWindowLong / GetWindowLongA / GetWindowLongW
Hàm GetWindowLong có nhiệm vụ tìm thông tin về specified window Hàm này còn tìm giá trị 32bit tại specified offset và đưa nó vào extra window memory của window
Nếu function hoàn thành , giá trị trả về là giá trị 32bit
Nếu function không hoàn thành , giá trị trả về là 0 Để biết thêm thông tin về lỗi, chúng ta dùng hàm GetLastError
GetWindowText / GetWindowTextA
Hàm GetWindowText có nhiệm vụ copy text của title bar(nếu nó chỉ có 1) của specified window vào buffer Nếu specified window là 1 control thì text của control sẽ được copy Code:
int GetWindowText(
HWND hWnd, // handle of window or control with text
LPTSTR lpString, // address of buffer for text