Introduction:
Voici un autre tuto pour la team XTX, ici on ne va pas s'embêter avec la routine de génération, mais plutôt patcher le soft.
Les outils:
OllyDbg v2.01 (http://ollydbg.de/)
PEiD (http://peid.has.it/)
Le soft (https://web.archive.org/web/20210418...AVSVideoConverter.exe)
I: Démarrage:
On scanne l'appli avec PEiD pour regarder si elle est compressée, etc...
Ce n'est pas le cas. ok, impec, comme ça on pourra coder un patch.
On lance l'application pour voir à quoi ça ressemble, et on remarque plusieurs choses:
- Les titres des fenêtres contenant "Version Gratuite"
- Un nouveau processus est lancé "Registration.exe" quand on clique sur le bouton Activer pour ouvrir la boîte de dialogue d'enregistrement.
- Nag-screen quand on ferme l'application.
Vu que l'exécutable principal semble l'appelé seulement pour la boîte d'enregistrement, cela ne semble pas pertinent de s'attaquer à ce processus-là.
Par contre si on souhaitait le keygenner, Registration.exe aurait sans doute toute son importance.
Il doit y avoir un 'serial check' au démarrage, si "ce n'est pas bon" alors on passe en "version gratuite" et on laisse gérer "Registration.exe" pour l'enregistrement.
II: Trouver la routine de vérification:
On charge l'exécutable principal dans notre débogueur, puis on regarde les strings datas référence on cherche à tout hasard "License".
On voit des strings intéressants tels que: "TFormUnregisteredVersion", "License="
On place des breakpoints à tout hasard sur ces lignes, on lance, et la mince.. Ça ne break pas!.
On regarde un coup les imports pour voir s’il n'y aurait pas quelque chose qui pourrait nous aiguiller, mais là encore, rien de spécial.
On regarde les noms des modules pour voir s’il n'y aurait pas quelque chose à se mettre sous la dent, CTRL+N avec olly, ou bien: Clic droit>Search for>Names
On regarde, et la on voit des choses intéressantes: @TLicenceManager@%GetActualLicence, on pose des breakpoints dessus.
On lance l'exécutable et le débogueur break!
On trace avec F8 pour voir ce qu'il se passe dans cette procédure.
Et bien pas grand-chose, on est éjecté de la boucle dès le début, et EAX passe à: FFFFFFFF
Une fois sorti de la routine, EAX est comparé, puis il y a une série de sauts conditionnels.
On continue le traçage tranquillement et après tous ses sauts on arrive plus bas, on passe sur un string IDS_75 et un CALL "Sicomp@TsiCustomLang@TextOrDefault"
On voit le string "version gratuite" apparaitre.
On continue un peu et la on voit notre string être assemblé au titre, dans la fenêtre de la pile.
On est donc déjà trop bas, il serrait intéressant de remplacer dès le début ou on était le contenu de EAX par 1 pour voir ce qu'il se passe.
Allez hop, on recharge l'exécutable dans le débogueur et on recommence en remplaçant cette fois-ci le registre de eax FFFFFFFF par 1.
On trace tranquillement, notre programme ne prend pas la même trajectoire que tout à l'heure, on arrive sur un string IDS_76 et un CALL "Sicomp@TsiCustomLang@TextOrDefault"
qui cette fois-ci fait apparaitre le string "Version Compl\xE8te" (Version Complète)
On à l'air d'être bon, lançon totalement le programme pour voir, le titre de la fenêtre affiche bien version complète, on regarde dans "À propos"
Le débogueur break à un autre endroit sur un des breakpoints "@TLicenceManager@%GetActualLicence", que l'on avait mis précédemment. On appuie sur F9 quand même.
Là on constate que la fenêtre "à propos" contient toujours des informations d'évaluation.
On va donc patcher toutes les procédures @TLicenceManager@%GetActualLicence, pour mettre EAX à 1, et ça devrait être réglé.
Nos modifications:
00479A4:
0047E3C8:
00486DE0:
00489940:
0048EA98:
Une fois ça fait on enregistre, clic droit>Edit>Copy all modifications to executable
La fenêtre 'File' apparait, clic droit dedans: Save File
On enregistre et on test:
C'est tout bon! le nag-screen n'est plus là lui non plus.
III: Faire un patch:
Vous aimez toujours l'asm hein?
Voici un petit exemple avec une listbox.
patch.asm:
.486 .model flat, stdcall option casemap :none ; case sensitive include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\masm32.inc include \masm32\macros\macros.asm includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\masm32.lib include crc32.inc DlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD Patch PROTO :DWORD List PROTO :DWORD,:DWORD patch MACRO offsetAdr,_bytes,_byteSize invoke SetFilePointer,hTarget,offsetAdr,NULL,FILE_BEGIN .if eax==0FFFFFFFFh invoke CloseHandle,hTarget invoke List,hWin,addr szFileBusy ret .endif invoke WriteFile,hTarget,addr _bytes,_byteSize,addr BytesWritten,FALSE ENDM .const IDC_LISTBOX equ 1002 IDB_PATCH equ 1003 IDB_CANCEL equ 1004 IDC_CHECKBOX equ 1005 .data ; Patch texts szTitle db "AVS Video Converter v12.1.5.673 *Patch*",0 sziNFO db "Place in same folder as target and click pATCH!",0 szIDBPatch db "pATCH",0 szIDBExit db "eXIT",0 szIDBBck db "bCK",0 szNotFound db "AVSVideoConverter.exe non trouvé",0 szWrongSize db "Mauvaise taille",0 szSizeOK db "Taille: OK!",0 szOKCRC32 db "CRC32: OK!",0 szBadCRC32 db "CRC32 incorrecte!",0 szFileBusy db "Fichier ouvert?",0 szBckOK db "Backup: OK!",0 szNoBck db "Backup: Pas de backup!",0 szSucess db "PATCHÉ !",0 ; App details TargetName db "AVSVideoConverter.exe",0 BackupName db "AVSVideoConverter.exe.backup",0 TargetCRC32 dd 0E9984D32h ; CRC32 of AVSVideoConverter.exe TargetSize dd 21531440 ; File size of AVSVideoConverter.exe ; Patch positions WBufferALL db 0B8h,001h,000h,000h,000h,0C3h ; MOV EAX,1 RETN PatchOffset1 dd 00073FA4h ; 004749A4 PatchOffset2 dd 0007D9C8h ; 0047E3C8 PatchOffset3 dd 000863E0h ; 00486DE0 PatchOffset4 dd 00088F40h ; 00489940 PatchOffset5 dd 0008E098h ; 0048EA98 .data? hInstance dd ? ;dd can be written as dword hTarget HINSTANCE ? BytesWritten db ? .code start: invoke GetModuleHandle, NULL mov hInstance, eax invoke DialogBoxParam, hInstance, 101, 0, ADDR DlgProc, 0 invoke ExitProcess,eax DlgProc proc hWin :DWORD, uMsg :DWORD, wParam :DWORD, lParam :DWORD LOCAL ff32:WIN32_FIND_DATA LOCAL pFileMem:DWORD .if uMsg == WM_INITDIALOG ; Set the dialog controls texts. Done here in the code instead of resource ; file to reduce the required bytes (strings in the rc file are UNICODE not ANSI) invoke SetWindowText,hWin,ADDR szTitle ; Set the window title text invoke SetDlgItemText,hWin,IDB_PATCH,ADDR szIDBPatch invoke SetDlgItemText,hWin,IDB_CANCEL,ADDR szIDBExit invoke SetDlgItemText,hWin,IDC_CHECKBOX,ADDR szIDBBck ; Display patch info in IDC_LISTBOX invoke List,hWin,addr sziNFO ; Init CRC32 table call InitCRC32Table ; Check IDC_CHECKBOX for file backup invoke SendDlgItemMessage,hWin,IDC_CHECKBOX,BM_SETCHECK,1,0 .elseif uMsg == WM_COMMAND ; Crack button .if wParam == IDB_PATCH invoke FindFirstFile,ADDR TargetName,ADDR ff32 ; File to patch is not in same dir .if eax == INVALID_HANDLE_VALUE invoke List,hWin,addr szNotFound .else mov eax,TargetSize ; File size is incorrect .if ff32.nFileSizeLow != eax invoke List,hWin,addr szWrongSize ; Filesize is correct .else invoke List,hWin,addr szSizeOK mov pFileMem,InputFile(ADDR TargetName) invoke CRC32,pFileMem,ff32.nFileSizeLow mov edx,TargetCRC32 ; Calculated CRC32 does not match .if eax != edx invoke List,hWin,addr szBadCRC32 .else invoke List,hWin,addr szOKCRC32 invoke GetFileAttributes,addr TargetName ; The file is read-only, so let's try to set it to read/write .if eax!=FILE_ATTRIBUTE_NORMAL invoke SetFileAttributes,addr TargetName,FILE_ATTRIBUTE_NORMAL .endif ; Everything's okay, so let's patch the file invoke CreateFile,addr TargetName,GENERIC_READ+GENERIC_WRITE,FILE_SHARE_READ+FILE_SHARE_WRITE,\ NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL .if eax!=INVALID_HANDLE_VALUE mov hTarget,eax ;Before patching check if backup invoke SendDlgItemMessage,hWin,IDC_CHECKBOX,BM_GETCHECK,0,0 .if eax==BST_CHECKED invoke CopyFile, addr TargetName, addr BackupName, TRUE invoke List,hWin,addr szBckOK .else invoke List,hWin,addr szNoBck .endif ; Start patches to the file patch PatchOffset1,WBufferALL,6 patch PatchOffset2,WBufferALL,6 patch PatchOffset3,WBufferALL,6 patch PatchOffset4,WBufferALL,6 patch PatchOffset5,WBufferALL,6 invoke CloseHandle,hTarget invoke List,hWin,addr szSucess invoke GetDlgItem,hWin,IDB_PATCH invoke EnableWindow, eax, FALSE .endif .endif .endif .endif .elseif wParam == IDB_CANCEL ; Exit button, so send a close message invoke EndDialog,hWin,0 .endif .elseif uMsg == WM_CLOSE invoke EndDialog,hWin,0 .endif xor eax,eax ret DlgProc endp List proc hWin:HWND, pMsg:DWORD invoke SendDlgItemMessage,hWin,IDC_LISTBOX,LB_ADDSTRING,0,pMsg invoke SendDlgItemMessage,hWin,IDC_LISTBOX,WM_VSCROLL,SB_BOTTOM,0 Ret List EndP Patch proc hWnd:HWND local status:DWORD Patch EndP end start
crc32.inc:
CRC32 PROTO :DWORD,:DWORD .data? CRCtable dd 256 DUP (?) .code align 4 ; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл ; These are MASM versions of Donkey's GoAsm CRC-32 procedures, ; adapted from routines by Thomas Bleeker (MadWizard),table- ; driven and fast ; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл InitCRC32Table proc uses ebx esi edi mov edi, offset CRCtable - 4 xor ecx, ecx M1: mov eax, ecx mov ebx, 0EDB88320h add edi, 4 mov esi, 8 @@: shr eax, 1 sbb edx, edx and edx, ebx xor eax, edx dec esi jnz @B inc ecx mov [edi], eax cmp ecx, 256 jb M1 mov eax,offset CRCtable ret InitCRC32Table endp align 4 CRC32 proc uses ebx esi edi lpBuffer, cbBuffer mov esi, lpBuffer mov edi, offset CRCtable mov edx, cbBuffer shr edx, 1 or ecx, -1 xor eax, eax @@: mov al, [esi] xor al, cl shr ecx, 8 mov ebx, [edi+4*eax] xor ecx, ebx mov al, [esi+1] xor al, cl shr ecx, 8 mov ebx, [edi+4*eax] add esi,2 xor ecx, ebx dec edx jnz @B test dword ptr[cbBuffer], 1 jz @F mov al, [esi] xor al, cl inc esi shr ecx, 8 mov ebx, [edi+4*eax] xor ecx, ebx @@: mov eax, ecx not eax ret CRC32 endp
base.rc:
;This Resource Script was generated by WinAsm Studio. #define IDB_PATCH 1003 #define IDB_CANCEL 1004 #define IDC_CHECKBOX 1005 101 DIALOGEX 0,0,184,66 CAPTION "" FONT 8,"Tahoma" STYLE 0x80c80880 EXSTYLE 0x00000000 BEGIN CONTROL "",IDB_PATCH,"Button",0x10000001,40,49,50,14,0x00000000 CONTROL "",IDB_CANCEL,"Button",0x10000000,130,49,50,14,0x00000000 CONTROL "",IDC_CHECKBOX,"Button",0x50010003,3,52,27,10,0x00000000 CONTROL "",1002,"ListBox",0x50810140,3,3,177,44,0x00000200 END
make.bat:
@echo off \masm32\bin\rc /v base.rc \masm32\bin\ml.exe /c /coff /Cp /nologo patch.asm \masm32\bin\link.exe /SUBSYSTEM:WINDOWS /RELEASE /VERSION:4.0 /OUT:Patch.exe patch.obj base.res del base.res del base.obj del patch.obj pause
Une fois compilé, ça ressemble à ça:
Xylitol, 19/04/2021
Copyright (C)- xtx Team (2021)