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.
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)
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 ;)
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.
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)
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.
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
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==----------------------------
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.
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.