-
----- ========= -----
--------- ==================== ---------
-------- =====Cours de _Masta_ sur l'asm Win95 part 2===== ---------
---------- ==================== ----------
 
 
--==INTRO==--

Hi,
Depuis que les parties 0 et 1 ont été un succès, je suis heureux de vous présenter maintenant la partie 2.
En ce moment, je cherche à faire quelque chose sur la GUI (NdT : Graphic User Interface), mais j'étais très occupé dernièrement donc il n'y aura pas de codage GUI pour l'instant. Je pense que ce sera néanmoins intéressant, enfin je l'espère.
Pour commencer ce tutorial, je n'expliquerais pas les choses faciles comme les MessageBox, parcequ'ils ont déja été expliqués entièrement dans les 2 premères parties. Je ne pense pas que ca vous posera de problèmes une fois que vous aurez lus les tuts précédents.

--==QU'EST-IL REQUIS ?==--

1. Un éditeur de texte
2. TASM 5.0 avec les librairies, etc...
3. Une référence aux APIs Windows (WIN32.HLP)
4. Starcraft (UNIQUEMENT pour le test ! ;])
5. Un peu de cellules grises qui trainent ;)
6. Une connaissance de base ASM (voir les leçons précédentes)
7. Numega SoftIce 3.xx (pas vraiment le must)
 

--==DE QUOI PARLERONS NOUS CETTE FOIS ?==--

Y'a t'il un joueur qui n'ai jamais apprécier des petites aides de temps en temps  ...

Plus de vies
Plus d'argent
Plus d'energie
Plus de gaz
Plus de ...

Ce que je parle c'est d'un trainer, très courant au temps du C64-/Amiga-/PC-DOS, de plus en plus rare malheureusement, même si il y'en a de temps en temps. Mais ce n'est plus comme "au bon vieux temps".
Donc ma cible est Starcraft (Oui je sais qu'il y a déja des entraîneurs pour lui!).
Mes raisons sont les suivantes :
- Le jeu est très populaire
- J'y jouait quand j'ai eu l'idée de ce tut ;)

--==ALLONS-Y==--

Quelques reflexions avant de commencer notre session.

Définition d'un trainer : - Un petit programme, qui change une partie de la mémoire utilisée par un jeu pour, par exemple, posseder plus d'argent, etc...

Normalement, cela n'est pas autorisé sous Windows d'acceder à l'adresse mémoire d'un autre programme. Par chance, notre plus vieil ami Billy à implémenté une série de fonctions, qui était à l'origine prévu pour debugger. Nous pouvons utiliser ces fonctions pour notre cause.
Ces fonctions sont OpenProcess, WriteProcessMemory et ReadProcessMemory. Avec leur aide, nous pouvons lire (et écrire) depuis (dans) l'addresse mémoire d'un autre programme.
Fondamentalement, notre programme agit comme un debugger, qui accède à la mémoire d'autres programmes et qui la change.
 
 

 --==STRUCTURE==--
1. Intro (petite introduction qui montre l'utilisation d'un MessageBox)

2. Obtenir l'ID du process du programme qui doit être "trained" ( Trouvez la fenêtre principal de Starcraft, obtenir le process avec l'aide de Windows)

3. Ouvrir le Process

4. Changer les valeurs

5. Fermer l'handle du process, quitter (et nettoyer la mémoire)
 
 

--==LES FONCTIONS API IMPORTANTES==--

L'handle de la fenêtre principale peut être obtenu avec FindWindowA, avec lequel nous obtiendrons le nom de la classe Windows ("SWarrClass") et le nom de la fenêtre ("Starcraft"). Nous pouvons faire ceçi avec l'aide de SoftIce (TASK -> HWND)

Avec l'handle de la fenêtre nous pouvons obtenir  le process correspondant, ou plutôt le PID, en utilisant GetWindowThreadProcessId.

Maintenant, nous prenons l'handle de la zone mémoire du process avec l'aide du PID -> OpenProcess.

Tout devient plus facile maintenant. Avec des opérations de fichier  "normales" nous pouvons écrire dans la mémoire d'un programme en cours avec son handle et la fonction WriteProcessMemory.

Last but not least, nous appelerons CloseHandle, pour fermer l'handle du process, ce qui n'est pas vraiment important sous Win95, mais qui a confiance dans les logiciels de Redmont ;-) ?

Et en tout dernier la fonction connue ExitProcess.
 

--==LES ADRESSES MEMOIRES==--

Nous pouvons facilement obtenir l'ajout de minerals, par exemple, en utilisant le debugger et en cherchant les valeurs hexadecimales des valeurs décimales affichées à l'écran.
Sur mon écran, cela ressemble à ceci :

 Minerals = 04EFE08h
 Gas      = 04EFE38h
 

--==LE SOURCE==--

Cette fois-çi ce ne sera pas très long et comme d'habitude pas structuré, mais ca devrait être façile à comprendre en tout cas...
 

;------------------------------==START==----------------------------------
 
     ; Set some params for the
       assembler
.386P
Locals
jumps
 

.Model Flat ,StdCall
PROCESS_VM_WRITE        equ 020h     ; Flags pour l'accès écriture
PROCESS_VM_OPERATION    equ 008h     ; du process
 
 

mb_ok              equ 0
minerals_pos       equ 04efe08h
gas_pos            equ 04efe38h
 
 

; declaration des fonctions APIs utilisées
 

extrn     MessageBoxA      : PROC        ; Affiche un MessageBox
extrn     FindWindowA      : PROC        ; Trouve la fenêtre avec un nom
extrn     GetWindowThreadProcessId :Proc ; Trouve le PID avec le HWND
extrn     OpenProcess      : PROC        ; Procedure pour acceder au process
extrn     WriteProcessMemory: PROC       ; Ecrire dans la mémoire du programme
                                         ; en cours
extrn     CloseHandle      : PROC        ; Ferme l'handle
                                         ; Cleanup, after use ;)
extrn     ExitProcess      : PROC        ; Procedure pour quitter le programme
 
 

; Ici commence nos données
.Data
 

caption  db "_masta_'s essay on Win32-ASM-Coding, part 2",0
                              ;Captionstring, 0-terminiert
 

text     db "Hi, here we are at part 2",13,10
         db "This tut will describe you how to make",13,10
         db "Win32-ASM Trainer",0

                             ; Texte d'introduction , 0-terminated
 

err_cap  db "ERROR",0        ; Titre pour les messages d'erreurs
 

notrun   db "Sorry, Starcraft is not running",0
 

no_write db "Mmmhhhh, a problem, by writing",13,10
         db "to Starcrafts memory",13,10,0
 

readycap db "Ready",0           ; Titre pour "ready"
 

readytxt db "Ok, now you have 1000000 Minerals and Gas",0

                                ; Texte pour "ready"
 

million  dd 1000000             ; Combien voulez-vous ??? ;]
 

wnd_name db "Starcraft",0       ; Nom de la fenêtre Starcraft
cls_name db "SWarClass",0       ; Classe de la fenêtre Starcraft
 

pid_sc   dd ?                   ; Ici nous sauvons le PID ...
 

p_hand   dd ?                   ; Et içi l'handle du process
 

; Et içi, nous commencons notre code

.Code
Main:
        push mb_ok
        push offset caption
        push offset text
        push 0
        call MessageBoxA        ;Message de démarrage
 

is_SC_RUN:
 

    push offset wnd_name
    push offset cls_name
    call FindWindowA    ; Trouve l'handle de la fenêtre avec la classe de la fenêtre et le
                        ; nom
 

    cmp  eax,0          ; si 0, la fenêtre n'existe pas
    jz   SC_isnt_run_end; --> Starcraft n'est pas lancé
 

    push offset pid_sc  ; Sauvegarde du PID
    push eax            ; PUSH handle de la fenêtre
    call GetWindowThreadProcessId ; Determine le PID avec l'handle de la fenêtre

open_the_process:
    push pid_sc             ; PUSH PID
    push 0                  ; Uniquement utilisé quand
                            ; on construit des nouveaux
                            ;  process
    push PROCESS_VM_WRITE OR PROCESS_VM_OPERATION ; Active l'acces écriture

    call OpenProcess        ; Obtenir l'handle de Starcraft
    mov  p_hand,eax         ; Sauve l'handle dans p_hand
 

change_Minerals:
 

    push 0                    ; Peut être le plus souvent à 0
    push 4                    ; Ecrire 4 Bytes (1 Dword)
    push offset million       ; Combien ? (1 Million)
    push minerals_pos         ; 1ere adresse mémoire
    push p_hand               ; Handle du process
    call WriteProcessMemory   ; change minerals
    cmp  eax,0
    jz   error_on_write       ; Si il y'a une erreur pendant l'écriture (eax=0) -> fin
 

change_gas:                   ; Code identique pour le gas, mais cette fois-çi
                              ; l'adresse mémoire du gas est poussé (NdT: PUSH)
    push 0
    push 4
    push offset million
    push gas_pos
    push p_hand
    call WriteProcessMemory
    cmp  eax,0
    jz   error_on_write
 
 

Trainer_ready:
 

        push mb_ok
        push offset readycap
        push offset readytxt
        push 0
        call MessageBoxA    ; Tout est OK
 
 

close_the_PID_Handle:
    push p_hand
    Call CloseHandle    ; Ferme l'handle
    jmp  end_           ; Va à la fin
 
 

error_on_write:
 

        push mb_ok
        push offset err_cap
        push offset no_write
        push 0
        call MessageBoxA          ; Mmmhhh, Erreur pendant l'écriture
        jmp  close_the_PID_Handle ; Ferme l'handle avant de quitter
 

SC_isnt_run_end:
 

        push mb_ok
        push offset err_cap
        push offset notrun
        push 0
        call MessageBoxA        ; Rien à modifier içi =(
 
end_:
 

        CALL    ExitProcess     ; Quitte le programme
End Main                        ; Fin de determination du code
        of Jump-point (Main)
 
 

;--------------------------==END OF SOURCE==----------------------------
 
 
 
 

--==LE MOT DE LA FIN==--

OK, comme je vous ai dit auparavant ceçi est un petit travail pratique, mais je pense qu'il est toutefois intéressant. Je devine qu'il n'y a plus grand chose à optimiser (désolé Fungus), peut-être la routine d'écriture en mémoire (utilisation d'une procédure).
J'espère que ma boite aux lettres (masta_t@usa.net) sera bientôt débordée (LES CRITIQUES SONT BIENVENUES) et que vous serez tous là la prochaine fois. Je vous promet que le prochain tut portera sur la GUI, parce que beaucoup de personnes m'ont demandé de le faire.
BTW, j'essaie de construire un channel IRC (EFNET) sur ce sujet (#win32asm) et finalement un projet de page 'HTTP://fungus.home.pages.de' est en cours !
Si quelqu'un est intéressé, toutes contributions sur ce sujet sera bienvenue, nous les attendons ...
J'espère vraiment qu'il y a assez de gens, qui passent du temps sur ce sujet, et qui sont disposés à partager leur connaissance avec d'autres également.

 

--==REMERCIEMENTS==--

VucoeT (Translator and Designer), scut (You are GREAT, why not code in Win32?),
|caligo| (bad news about you :(), fravia (best on the web), +Aescalapius
(i hope to break Brainbreaker), not4you (wir Ossis muessen zusammenhalten ;)),
fungus (something to optimze), CyberBobjr (for translating to frensh), DASavant,
mornings, i_magnus, Quest, Silvio, TheDoctor, everyone on #LAC and
#cracking4newbies and to every cracker around the world.
 
 
 

--==MOTS SAVANTS==--
------===========================================================-------
-----===== Un sérial en clair est aussi commun qu'une vierge de 25 ans =====------
-------===========================================================-------
-----=========-----
-

Traduit par CyberBobJr
CyberBobJr@yahoo.com