Retour
MEMORY PATCH (Partie 1)
MEMORY REVERSE ENGENEERING
(Décompressez le ZIP)
Pour ce qui est du cracking et de la programmation, tout est possible. Suffit seulement de penser à d'autres
nouvelles choses qui n'ont pas encore été faites ou dont on parle peu, pour se rendre compte qu'il n'y a pas
de limite. Une fois je suis tombé sur un programme qui avait une protection CRC, le hic c'est que je ne savais
pas la contourer (à l'heure où vous lisez ça, ça a peut-être changé). Mon crack fonctionnait bien sous W32Dasm
mais une fois concrétisé avec un éditeur hexadécimal le CRC foutait sa merde.
Alors l'idée, c'était, au lieu
de Hard-Patcher comme 99% des cas j'allais Memory-Patcher comme le font temporairement SoftIce et W32Dasm. (Ce
qui resterait invisible pour la protection CRC)
La base, c'est évidemment les Tuts d'Aczelion.
Et même si il est très bien fait, j'ai pris le parti de vous réexpliquer son Tut29 en détail, en traduisant
toutes les API, instructions et Flags. J'ai tout retrouvé dans la doc de Microsoft 'api32wh.zip'(4.xx Mo).
Très franchement même si la doc 'api.zip' de +Sync est une référence (elle reste incomplète), même si vous
n'aimez pas Microsoft, sur ce point là...faites une exception.
Au travail: (cliquez sur chaque mot pour une explication détaillée)
Intoduction à ce qu'on va faire
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\user32.lib
.data
AppName db "Memory Patch: DebugActiveProcess",0 ;EXPLICATION 0
ClassName db "SimpleWinClass",0 ;EXPL1
SearchFail db "Cannot find the target process",0 ;EXPL2
TargetPatched db "Target patched!",0 ;EXPL2
buffer dw 9090h ;EXPL3
.data?
DBEvent DEBUG_EVENT <> ;EXPL4
ProcessId dd ? ;EXPL5
ThreadId dd ? ;EXPL6
align dword ;EXPL7
context CONTEXT <> ;EXPL7
.code
start:
invoke FindWindow, addr ClassName, NULL ;EXPL8
.if eax!=NULL ;EXPL9
invoke GetWindowThreadProcessId, eax, addr ProcessId ;EXPL10
mov ThreadId, eax ;EXPL10
invoke DebugActiveProcess, ProcessId ;EXPL11
.while TRUE ;EXPL12
invoke WaitForDebugEvent, addr DBEvent, INFINITE ;EXPL13
.break .if DBEvent.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT ;EXPL14 OUPS
.if DBEvent.dwDebugEventCode==CREATE_PROCESS_DEBUG_EVENT ;EXPL15
mov context.ContextFlags, CONTEXT_CONTROL ;EXPL16
invoke GetThreadContext,DBEvent.u.CreateProcessInfo.hThread, addr context ;EXPL17
invoke WriteProcessMemory, DBEvent.u.CreateProcessInfo.hProcess, context.regEip, \
addr buffer, 2, NULL ;EXPL18
invoke MessageBox, 0, addr TargetPatched, addr AppName, MB_OK+MB_ICONINFORMATION
.elseif DBEvent.dwDebugEventCode==EXCEPTION_DEBUG_EVENT ;EXPL19
.if DBEvent.u.Exception.pExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT
invoke ContinueDebugEvent, DBEvent.dwProcessId,DBEvent.dwThreadId, DBG_CONTINUE
.continue
.endif
.endif
invoke ContinueDebugEvent, DBEvent.dwProcessId, DBEvent.dwThreadId, \ ;EXPL20
DBG_EXCEPTION_NOT_HANDLED
.endw
.else
invoke MessageBox, 0, addr SearchFail, addr AppName,MB_OK+MB_ICONERROR
.endif
invoke ExitProcess, 0
end start
;--------------------------------------------------------------------
; Le code source de win.asm est en réalité une simple fenêtre comme
; celle de l'exemple du tutorial 3 avec une boucle infinie insérée
; juste avant qu'on ne puisse arriver jusqu'à elle (la fenêtre).
;----------------------------------------------------------------------
......
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,
\ WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,
\ CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,
\ hInst,NULL
mov hwnd,eax
jmp $ ;<---- Voici notre boucle infinie. Elle boucle sur elle-même.
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.while TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.break .if (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.endw
mov eax,msg.wParam
ret
WinMain endp
J'espère seulement que tout s'est éclaircit maintenant.
Notre Memory-Patch s'attache à un programme cible alors que celui-ci est déjà lancé. Mais il y a une
autre façon de debugger une cible, c'est de lancer le debugger (ici notre Memory-Patch) en premier, et
faire en sorte que ce soit lui-même qui lance la cible pour la debugguer.
Retour
(Par Morgatte)