Ceci est la source d'un crack écrit en Win32ASM (MASM32), possédant la plupart
des fonctionnalités habituelles : recherche du fichier, patch, backup et
restauration.
ATTENTION: je tiens à préciser que ce n'est pas illégal.
En effet, j'ai mis cette source pour que certains comprennent le principe de
fonctionnement d'un crack. Moi-même cela m'a longtemps fasciné (qui n'a jamais
rêvé de faire des cracks comme ceux du mythique SuperGégé ?), et je pense que ça
peut être intéressant.
Un crack est une type de patch un peu particulier, et j'ai aussi prévu cette
source pour faire des patchs (utilisation d'un thread pour les modifications
importantes des fichiers).
De plus cela constitue une bonne initiation à la programmation avec l'API
Windows (gestion des dialogues, des contrôles, écriture dans un fichier,
etc...). En gros les 10 premiers tutoriaux d'Iczelion sont couverts.
J'ai essayé de commenter le code (en anglais, désolé), mais j'espère que ça en
aidera quelques-uns ;-)
Source / Exemple :
;; Pastille ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Author: Dean ;
; Date : 04.25.2003 ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; http://kickme.to/charloweb ;;
.486
.model flat, stdcall
option casemap: none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
include \masm32\include\comdlg32.inc ; For the GetOpenFileName function
include \masm32\include\shell32.inc ; For the ShellExecute function
include \masm32\include\imagehlp.inc ; For the MapFileAndCheckSumA function
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\imagehlp.lib
HyperlinkProc PROTO : DWORD, : DWORD, : DWORD, : DWORD
DlgProc PROTO : DWORD, : DWORD, : DWORD, : DWORD
PatchThread PROTO : DWORD
.const
; The resource IDs
IDI_TARGETFILE equ 100
IDB_AUTHOR equ 200
IDC_NAME equ 300
IDC_CONTACT equ 301
IDC_AUTHOR equ 302
IDC_RELEASEDATE equ 303
IDC_TARGET equ 304
IDC_TARGETFILE equ 305
IDC_BROWSE equ 306
IDC_BACKUP equ 307
IDC_PATCH equ 308
IDC_EXIT equ 309
; Custom messages for the patch thread
WM_BEGINPATCH equ WM_USER + 100h
WM_ENDPATCH equ WM_USER + 101h
; <ReleaseSettings>
; The name and the filename of the target
TargetName equ 'TextFile'
TargetFileName equ 'textfile.txt'
; The size and the new size of the target file (if it is the same, set it to TargetFileSize)
TargetFileSize equ 26
TargetFileNewSize equ 4
; The checksum of the target file
TargetFileCheckSum equ 0CD93h
; The offsets and the new bytes
Offsets equ 0, 1, 2, 3
NewBytes equ 44h, 65h, 61h, 6Eh
; The author and the release date
Author equ 'Dean', 0
ReleaseDate equ 'Apr 23rd 2003'
; </ReleaseSettings>
; <AdvancedSettings>
; The title and the name of the patch
PatchTitle equ 'Charloweb presents:'
PatchName equ TargetName, ' crack'
; The contact URI
ContactURI equ 'http://kickme.to/charloweb'
; The text of the labels
AuthorLabelText equ 'Author: ', Author
ReleaseDateLabelText equ 'Release date: ', ReleaseDate
TargetLabelText equ 'Target file:'
; The text of the buttons (use & to make a shortcut)
BrowseButtonText equ 'Br&owse...'
BackupButtonText equ 'Create &backup file'
PatchButtonText equ 'Apply &patch'
ExitButtonText equ 'E&xit'
; The title and the filter string of the "open" dialog box
OpenTitle equ 'Select the target file:'
OpenFilterString equ TargetName, ' (', TargetFileName, ')', 0, TargetFileName, 0, 'All files (*.*)', 0, '*.*', 0
; The extension of the backup file
BackupFileExt equ '.bak', 0
; The title of the message boxes
WarningTitle equ 'Warning'
ErrorTitle equ 'Error'
InfoTitle equ 'Information'
; The messages of error
BackupErrorMsg equ 'The backup file cannot be created. Continue anyway?'
OpeningErrorMsg equ 'The file does not exists or cannot be opened.'
FileSizeErrorMsg equ 'The file has not got the right size.'
CheckSumErrorMsg equ 'The file has already been modified or the checksum cannot be computed.'
RestoreErrorMsg equ 'The file cannot be restored.'
; Restoration message
RestoreMsg equ 'The file has already been patched. Would you like to restore it?'
; The messages of success
PatchSuccessMsg equ 'The file has been successfully patched!'
RestoreSuccessMsg equ 'The file has been successfully restored!'
; </AdvancedSettings>
.data
; Settings
nOffsets DWORD Offsets
nNewBytes BYTE NewBytes
szTargetFileName CHAR TargetFileName, 0
szPatchTitle CHAR PatchTitle, 0
szPatchName CHAR PatchName, 0
szContactURI CHAR ContactURI, 0
szAuthorLabelText CHAR AuthorLabelText, 0
szReleaseDateLabelText CHAR ReleaseDateLabelText, 0
szTargetLabelText CHAR TargetLabelText, 0
szBrowseButtonText CHAR BrowseButtonText, 0
szBackupButtonText CHAR BackupButtonText, 0
szPatchButtonText CHAR PatchButtonText, 0
szExitButtonText CHAR ExitButtonText, 0
szOpenTitle CHAR OpenTitle, 0
szOpenFilterString CHAR OpenFilterString, 0
szBackupFileExt CHAR BackupFileExt, 0
szWarningTitle CHAR WarningTitle, 0
szErrorTitle CHAR ErrorTitle, 0
szInfoTitle CHAR InfoTitle, 0
szBackupErrorMsg CHAR BackupErrorMsg, 0
szOpeningErrorMsg CHAR OpeningErrorMsg, 0
szFileSizeErrorMsg CHAR FileSizeErrorMsg, 0
szCheckSumErrorMsg CHAR CheckSumErrorMsg, 0
szRestoreErrorMsg CHAR RestoreErrorMsg, 0
szRestoreMsg CHAR RestoreMsg, 0
szPatchSuccessMsg CHAR PatchSuccessMsg, 0
szRestoreSuccessMsg CHAR RestoreSuccessMsg, 0
; Other variables
szDlgName CHAR 'PASTILLE', 0
szOpenCmd CHAR 'open', 0
bPatch BOOL TRUE
bRestore BOOL FALSE
.data?
; Handles
hInstance HINSTANCE ?
hIcon HICON ?
hHandCursor HCURSOR ?
hTargetFile HANDLE ?
hBackupFile HANDLE ?
; The variables of command-line arguments
argc DWORD ?
argv DWORD 16 dup(?)
; Path and filename buffers
szTargetFile CHAR MAX_PATH dup(?)
szBackupFile CHAR MAX_PATH dup(?)
; Checksum values
nHeaderSum DWORD ?
nCheckSum DWORD ?
; Other variables
Ofn OPENFILENAME <?>
BoldFont LOGFONT <?>
nPatchThreadID DWORD ?
nBytesWritten DWORD ?
.code
start:
; Get the handle of the application instance
INVOKE GetModuleHandle, NULL
mov hInstance, eax
; Get the command-line and process it
; It is a code of comrade <comrade2k@hotmail.com>
INVOKE GetCommandLine
mov esi, eax
mov edi, OFFSET argv
xor ecx, ecx
xor ebx, ebx
xor edx, edx
@@cmss:
mov eax, esi
mov dl, 20h
cmp byte ptr [esi], 22h
sete cl
lea edx, [edx + ecx * 2]
add eax, ecx
stosd
@@cm00:
inc esi
cmp byte ptr [esi], 0
je @@cm01
cmp byte ptr [esi], dl
jne @@cm00
mov byte ptr [esi], 0
add esi, ecx
inc esi
cmp byte ptr [esi], 0
je @@cm01
inc [argc]
jmp @@cmss
@@cm01:
inc [argc]
; Load the icon and the cursor resources
INVOKE LoadIcon, hInstance, IDI_TARGETFILE
mov hIcon, eax
INVOKE LoadCursor, NULL, IDC_HAND
mov hHandCursor, eax
; Display the dialog box
INVOKE DialogBoxParam, hInstance, ADDR szDlgName, NULL, ADDR DlgProc, NULL
; When all the operations are done, terminate the process
INVOKE ExitProcess, eax
; The link procedure, used to change the cursor when the link is rolled over
HyperLinkProc PROC hWnd: DWORD, uMsg: DWORD, wParam: DWORD, lParam: DWORD
.IF uMsg == WM_SETCURSOR
INVOKE SetCursor, hHandCursor
.ELSE
INVOKE GetWindowLong, hWnd, GWL_USERDATA
INVOKE CallWindowProc, eax, hWnd, uMsg, wParam, lParam
ret
.ENDIF
xor eax, eax
ret
HyperLinkProc ENDP
; The main procedure
DlgProc PROC hWnd: DWORD, uMsg: DWORD, wParam: DWORD, lParam: DWORD
.IF uMsg == WM_INITDIALOG
; Change the icon of the dialog
INVOKE SendMessage, hWnd, WM_SETICON, ICON_BIG, hIcon
; Attach the HyperLink procedure to the contact label
INVOKE GetDlgItem, hWnd, IDC_CONTACT
push eax
INVOKE SetWindowLong, eax, GWL_WNDPROC, ADDR HyperLinkProc
pop edx
INVOKE SetWindowLong, edx, GWL_USERDATA, eax
; Fill all fields of text with the settings
INVOKE SetWindowText, hWnd, ADDR szPatchTitle
INVOKE SetDlgItemText, hWnd, IDC_NAME, ADDR szPatchName
INVOKE SetDlgItemText, hWnd, IDC_CONTACT, ADDR szContactURI
INVOKE SetDlgItemText, hWnd, IDC_AUTHOR, ADDR szAuthorLabelText
INVOKE SetDlgItemText, hWnd, IDC_RELEASEDATE, ADDR szReleaseDateLabelText
INVOKE SetDlgItemText, hWnd, IDC_TARGET, ADDR szTargetLabelText
INVOKE SetDlgItemText, hWnd, IDC_BROWSE, ADDR szBrowseButtonText
INVOKE SetDlgItemText, hWnd, IDC_BACKUP, ADDR szBackupButtonText
INVOKE SetDlgItemText, hWnd, IDC_PATCH, ADDR szPatchButtonText
INVOKE SetDlgItemText, hWnd, IDC_EXIT, ADDR szExitButtonText
; Set the "target file" edit box with the command-line argument or the
; target filename by default
.IF argc > 1
INVOKE SetDlgItemText, hWnd, IDC_TARGETFILE, argv + 04h
.ELSE
INVOKE SetDlgItemText, hWnd, IDC_TARGETFILE, ADDR szTargetFileName
.ENDIF
; Check the "backup" checkbox
INVOKE CheckDlgButton, hWnd, IDC_BACKUP, BST_CHECKED
.ELSEIF uMsg == WM_CTLCOLORSTATIC
INVOKE GetDlgCtrlID, lParam
.IF eax == IDC_NAME
; Set the font of the title
INVOKE SendMessage, hWnd, WM_GETFONT, 0, 0
INVOKE GetObject, eax, SIZEOF LOGFONT, ADDR BoldFont
mov BoldFont.lfWeight, FW_BOLD
INVOKE CreateFontIndirect, ADDR BoldFont
INVOKE SelectObject, wParam, eax
.ELSEIF eax == IDC_CONTACT
; Change the color of the link
INVOKE SetBkMode, wParam, TRANSPARENT
INVOKE SetTextColor, wParam, 770000h
INVOKE GetSysColor, COLOR_BTNFACE
INVOKE CreateSolidBrush, eax
ret
.ENDIF
.ELSEIF uMsg == WM_COMMAND
mov eax, wParam
mov edx, wParam
shr edx, 16
.IF dx == BN_CLICKED
.IF ax == IDC_CONTACT
; Open the contact URI
INVOKE ShellExecute, hWnd, ADDR szOpenCmd, ADDR szContactURI, NULL, NULL, 0
.ELSEIF ax == IDC_BROWSE
; Fill the "open" dialog structure and display the window
mov Ofn.lStructSize, SIZEOF Ofn
push hWnd
pop Ofn.hwndOwner
mov Ofn.lpstrFilter, OFFSET szOpenFilterString
INVOKE lstrcpy, ADDR szTargetFile, ADDR szTargetFileName
mov Ofn.lpstrFile, OFFSET szTargetFile
mov Ofn.nMaxFile, SIZEOF szTargetFile
mov Ofn.lpstrTitle, OFFSET szOpenTitle
mov Ofn.Flags, OFN_HIDEREADONLY
INVOKE GetOpenFileName, ADDR Ofn
.IF eax == TRUE
; Set the "target file" edit box with the fullpath and the name of the file
INVOKE SetDlgItemText, hWnd, IDC_TARGETFILE, ADDR szTargetFile
.ENDIF
.ELSEIF ax == IDC_PATCH
; Create a new thread which executes the operations
INVOKE CreateThread, NULL, 0, ADDR PatchThread, hWnd, 0, ADDR nPatchThreadID
INVOKE CloseHandle, eax
.ELSEIF ax == IDC_EXIT
INVOKE SendMessage, hWnd, WM_CLOSE, 0, 0
.ENDIF
.ENDIF
.ELSEIF uMsg == WM_BEGINPATCH
; Disable the "patch" button
INVOKE GetDlgItem, hWnd, IDC_PATCH
INVOKE EnableWindow, eax, FALSE
.ELSEIF uMsg == WM_ENDPATCH
; Enable the "patch" button
INVOKE GetDlgItem, hWnd, IDC_PATCH
INVOKE EnableWindow, eax, TRUE
.ELSEIF uMsg == WM_CLOSE
INVOKE EndDialog, hWnd, 0
.ENDIF
xor eax, eax
ret
DlgProc ENDP
; The patch procedure
PatchThread PROC hWnd: DWORD
INVOKE PostMessage, hWnd, WM_BEGINPATCH, 0, 0
INVOKE GetDlgItemText, hWnd, IDC_TARGETFILE, ADDR szTargetFile, SIZEOF szTargetFile
; Obtain the backup file name
INVOKE lstrcpy, ADDR szBackupFile, ADDR szTargetFile
INVOKE lstrcat, ADDR szBackupFile, ADDR szBackupFileExt
; If the backup file already exists, ask the user if he wants to restore
INVOKE CreateFile, ADDR szBackupFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL
.IF eax != INVALID_HANDLE_VALUE
mov hBackupFile, eax
INVOKE GetFileSize, hBackupFile, NULL
push eax
INVOKE CloseHandle, hBackupFile
pop eax
.IF eax == TargetFileSize
INVOKE MapFileAndCheckSumA, ADDR szBackupFile, ADDR nHeaderSum, ADDR nCheckSum
.IF eax == CHECKSUM_SUCCESS
.IF nCheckSum == TargetFileCheckSum
mov bRestore, TRUE
INVOKE MessageBox, hWnd, ADDR szRestoreMsg, ADDR szInfoTitle, MB_ICONINFORMATION OR MB_YESNO
.IF eax == IDYES
INVOKE MoveFileEx, ADDR szBackupFile, ADDR szTargetFile, MOVEFILE_REPLACE_EXISTING
.IF eax != 0
INVOKE MessageBox, hWnd, ADDR szRestoreSuccessMsg, ADDR szInfoTitle, MB_ICONINFORMATION OR MB_OK
.ELSE
INVOKE MessageBox, hWnd, szRestoreErrorMsg, ADDR szErrorTitle, MB_ICONERROR OR MB_OK
.ENDIF
.ENDIF
.ENDIF
.ENDIF
.ENDIF
.ENDIF
; Patch the file
.IF bRestore == FALSE
; Open the file specified in the "target" edit box
INVOKE CreateFile, ADDR szTargetFile, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL
.IF eax != INVALID_HANDLE_VALUE
mov hTargetFile, eax
; Get the target file size
INVOKE GetFileSize, hTargetFile, NULL
.IF eax == TargetFileSize
; Computes the file checksum
INVOKE MapFileAndCheckSumA, ADDR szTargetFile, ADDR nHeaderSum, ADDR nCheckSum
.IF eax == CHECKSUM_SUCCESS
.IF nCheckSum == TargetFileCheckSum
INVOKE IsDlgButtonChecked, hWnd, IDC_BACKUP
.IF eax == BST_CHECKED
; Create the backup file
INVOKE CopyFile, ADDR szTargetFile, ADDR szBackupFile, 0
.IF eax == 0
INVOKE MessageBox, hWnd, ADDR szBackupErrorMsg, ADDR szWarningTitle, MB_ICONWARNING OR MB_OKCANCEL
.IF eax == IDCANCEL
mov bPatch, FALSE
.ENDIF
.ENDIF
.ENDIF
.IF bPatch == TRUE
xor ecx, ecx
lea eax, nOffsets
lea edx, nNewBytes
patch:
; Save the registers
pushad
pushad
; Move to the offset
INVOKE SetFilePointer, hTargetFile, [eax + ecx * 4], NULL, FILE_BEGIN
; Restore the registers
popad
; Write the new byte
add edx, ecx
INVOKE WriteFile, hTargetFile, edx, 1, ADDR nBytesWritten, NULL
; Restore the registers
popad
inc ecx
cmp ecx, SIZEOF nNewBytes
je endpatch
jmp patch
endpatch:
; Truncate the file to the new file size
INVOKE SetFilePointer, hTargetFile, TargetFileNewSize, NULL, FILE_BEGIN
INVOKE SetEndOfFile, hTargetFile
; Display the message of success
INVOKE MessageBox, hWnd, ADDR szPatchSuccessMsg, ADDR szInfoTitle, MB_ICONINFORMATION OR MB_OK
.ENDIF
mov bPatch, TRUE
.ELSE
INVOKE MessageBox, hWnd, ADDR szCheckSumErrorMsg, ADDR szErrorTitle, MB_ICONERROR OR MB_OK
.ENDIF
.ELSE
INVOKE MessageBox, hWnd, ADDR szCheckSumErrorMsg, ADDR szErrorTitle, MB_ICONERROR OR MB_OK
.ENDIF
.ELSE
INVOKE MessageBox, hWnd, ADDR szFileSizeErrorMsg, ADDR szErrorTitle, MB_ICONERROR OR MB_OK
.ENDIF
INVOKE CloseHandle, hTargetFile
.ELSE
INVOKE MessageBox, hWnd, ADDR szOpeningErrorMsg, ADDR szErrorTitle, MB_ICONERROR OR MB_OK
.ENDIF
.ENDIF
mov bRestore, FALSE
INVOKE PostMessage, hWnd, WM_ENDPATCH, 0, 0
INVOKE ExitThread, 0
xor eax, eax
ret
PatchThread ENDP
END start
Conclusion :
Si vous avez des remarques, des questions, des suggestions, n'hésitez pas à
ajouter un commentaire !
Vous pouvez aussi aller sur mon site pour les mises à jour (bien que j'uploade
régulièrement sur AsmFr.Com) :
http://kickme.to/charloweb (voir "Pastille").
UPDATE DU 11.08.2003 :
------------------------------------------------------------
Suite à plusieurs demandes, j'ai ajouté une vieille version du patch, plus simplifiée.
Celle-ci se trouve dans le fichier "old.zip".
Il faudrait que je fasse une grosse update et ajouter la 2.0, mais je n'ai pas le temps. Vous pouvez me contacter par mail si vous voulez que je vous envoie les sources mises à jour !
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.