begin process at 2012 02 17 11:22:06
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Système

 > RÉCUPÉRER LES VARIABLES D'ENVIRONNEMENT DE N'IMPORTE QUEL PROCESSUS

RÉCUPÉRER LES VARIABLES D'ENVIRONNEMENT DE N'IMPORTE QUEL PROCESSUS


 Information sur la source

Note :
9,5 / 10 - par 2 personnes
9,50 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Système Source .NET ( DotNet ) Classé sous :variable environnement, readprocessmemory, peb, environment, processus Niveau :Expert Date de création :14/02/2009 Date de mise à jour :16/02/2009 18:34:45 Vu / téléchargé :5 258 / 394

Auteur : violent_ken

Ecrire un message privé
Site perso
Ce membre participe au partage de revenus publicitaires
Commentaire sur cette source (16)
Ajouter un commentaire et/ou une note


 Description

Bonjour,

voilà (encore) une source orientée système qui permet de récupérer (lecture seule uniquement) les variables d'environnement d'un processus quelconque.

Pour récupérer les variables du processus courant c'est on ne peut plus trivial avec Environment.GetEnvironmentVariables() :-)

Mais pour les autres processus, c'est une autre histoire...



Il existe deux méthodes pour les obtenir :

La première : "Méthode injection"
- Injecter une dll dans le processus dont on veut connaitre les variables d'environnement
- Ouvrir un nouveau thread dans le processus (CreateRemoteThread)
- Appeler GetEnvironmentStrings() qui récupère les variables du processus courant
- Libérer la dll

C'est très très moche et il faut le privilège Debug !




Du coup ici je vous propose une seconde méthode : il s'agit de lire les informations dans le PEB du processus.

Explication : plusieurs informations d'environnement sont stockées dans un espace mémoire de chacun des processus. Ces informations sont stockées dans le "PEB" (process environment block).
Il convient donc de lire dans la mémoire du processus désiré pour récupérer ces précieuses informations (via ReadProcessMemory).

Toute la difficulté est donc de récupérer l'emplacement mémoire à lire, puisqu'il n'est pas le même pour chacun des processus...

Voici donc comment procéder :
a) on récupère l'adresse du PEB, qui, contrairement à ce qu'on peut souvent lire sur Internet, N'EST PAS TOUJOURS la même (non, ce n'est pas toujours 0x7ffdf000 !!!). Du coup on appelle NtQueryInformationProcess pour obtenir cette info.

b) Le PEB possède plein d'informations inutiles pour nous, il faut donc trouver les bonnes. Il faudra donc dans un premier temps récupérer l'adresse mémoire d'un second block, appelé "ProcessParameters block". En effet, les variables d'environnement sont situées physiquement à une adresse variable, qui elle, est fixée à une adresse fixe dans le PEB.
On récupère donc l'adresse du "ProcessParameters block".

c) On récupère les variables d'environnement à proprement parler.
Elle sont situées à l'offset 0x48 (72) dans le "ProcessParameters block" pour tous les systèmes Windows NT. Toute la (nouvelle) difficulté est de récupérer la taille qu'elles occupent en mémoire.

Voilà comment elles sont architecturées en mémoire :
var1=val1@var2=val2@....@varn=valn@@ , avec le signe '@' représentant deux octets 0.
En effet, les informations sont codées au format Unicode, et donc chaque caractère prend 2 octets.

Les variables sont donc séparées par 00 00, et la fin de la liste est marqué par 00 00 00 00 (4 null bytes).

Donc on lit la mémoire jusqu'à trouver 00 00 00 00, on calcule la taille, ensuite on récupère dans un buffer la liste complète des variables, et on parse le tout pour que ce soit lisible par le commun des mortels (un tableau de shorts c'est moyen ^^).


Voilà pour le principe, la réalisation est dans le fichier zip.




Rappels divers :
- ANSI : caractères codés sur un octet (on voit ABCD dans un éditeur hexa)
- UNICODE : caractères codés sur 2 octets (on voit A.B.C.D. dans un éditeur hexa)
- Integer : 4 octets
- Short : 2 octets
- Byte : 1 octet
- Une adresse mémoire est codée sur 4 octets sur un système 32 bits
- Byte = Octet en anglais (rien à voir avec bit).


NB : pour le changement des variables d'environnement, par contre, il faudra forcément passer par de l'injection. Cf : http://www.codeproject.com/KB/threads/DynEnvVar.as px


Voilà !!

@+


 Conclusion

Si j'ai fait quelques erreurs d'explication, n'hésitez pas à me corriger !


J'ai mis tous les commentaires en anglais, mais c'est compréhensible je pense (en plus je viens de détailler la méthode).

@+

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

16 février 2009 18:34:46 :
Suppression des divers bugs

 Sources du même auteur

Source avec Zip Source avec une capture Source .NET (Dotnet) UTILITAIRE DE SANITIZATION DES DISQUES DURS/FICHIERS (SUPPRE...
Source avec Zip Source avec une capture Source .NET (Dotnet) SIMPLE SHUTDOWN SCHEDULER : ARRÊTS PLANIFIÉS (LOCAL OU REMOT...
Source avec Zip Source .NET (Dotnet) COMMENT DÉMARRER UN PROCESSUS SUR PC DISTANT DE MANIÈRE CACH...
Source avec Zip Source avec une capture Source .NET (Dotnet) YET ANOTHER (REMOTE) PROCESS MONITOR
Source avec Zip Source avec une capture Source .NET (Dotnet) COMMENT DÉTECTER LES PROCESSUS CACHÉS (VIRUS, ROOTKITS...) +...

 Sources de la même categorie

Source avec Zip Source avec une capture AUTORISER/REFUSER L'EXECUTION DE PROCESSUS par pierreh51
Source avec Zip Source .NET (Dotnet) CLONE/FORK DES FLUX DE LA CONSOLE : PERMETTRE LA REDIRECTION... par ShareVB
Source avec Zip Source .NET (Dotnet) DÉFRAGMENTER UN FICHIER par ShareVB
Source avec Zip Source .NET (Dotnet) ECRAN DE VEILLE : DÉTECTER LE LANCEMENT/DÉCLENCHER/EMPÊCHER par ShareVB
Source avec Zip Source avec une capture DESACTIVER / ACTIVER LES MISES EN VEILLES PC par Arsena

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture AUTORISER/REFUSER L'EXECUTION DE PROCESSUS par pierreh51
Source avec Zip Source .NET (Dotnet) LA LISTE DES TÂCHES COMME DANS L'ONGLET APPLICATION DU GESTI... par ShareVB
Source avec Zip FERMER UN PROGRAMME OU UN PROCESSUS par 123collargol
Source avec Zip Source avec une capture CLASSE POUR LIRE/MODIFIER LA MEMOIRE DE N'IMPORTE QUEL PROCE... par violent_ken
Source avec Zip DES INFORMATIONS SUR LES PROCESSUS ET LEUR PEB (PARAMÈTRE DE... par ShareVB

Commentaires et avis

Commentaire de violent_ken le 14/02/2009 19:21:37

Bon a priori Process Explorer renvoie les même résultats, donc çà devrait marcher de manière correcte normalement...

@+

Commentaire de Patrice99 le 15/02/2009 10:08:01

Et toi tu vas l'utiliser dans quel but ?

Commentaire de violent_ken le 15/02/2009 11:54:09

Salut !

Bah personnellement, dans l'immédiat, c'est une fonction que je vais ajouter dans cette source : http://www.vbfrance.com/codes/YET-ANOTHER-PROCESS-MONITOR_48860.aspx

J'avais pas trouvé comment faire autrement, ben du coup j'ai proposé çà.


M'enfin, je  viens de voir (juste au dessus, dans la liste des "Source en rapport avec celle ci") que ShareVB est passé bien avant moi :-)
http://www.vbfrance.com/codes/INFORMATIONS-SUR-PROCESSUS-LEUR-PEB-PARAMETRE-LIGNE-COMMANDE_38976.aspx

Mince !



Sinon bah du coup je vais travailler du côté de PEB_LDR_DATA (http://msdn.microsoft.com/en-us/library/aa813708.aspx) afin de proposer de pouvoir récupérer de manière originale (et rapide j'espère ! C'est le but recherché...) la liste des modules chargés par un processus, autrement que par toolhelp.

@+

Commentaire de Patrice99 le 15/02/2009 12:03:40

Moi l'utilité que je voie c'est surtout la ligne de commande des services actifs, par exemple ceux en svchost.exe de façon a détecter des anomalies du type virus ou vers via une liste blanche par exemple. Mais les variables d'environnement, à priori je voie pas comment l'utiliser.

Commentaire de violent_ken le 15/02/2009 12:37:12

Oui la ligne de commande est en effet largement plus utile !

Sinon d'un point de vue "utilité" des variables d'environnement, ben effectivement c'est pas évident :-)

Si on veut trouver une utilité, parmi toutes les variables dispos, je dirais :
- on peut trouver utile de connaitre la valeur TEMP ou TMP des variables d'environnement, dans le cas on le programme les utilise pour stocker ses fichiers temporaires
- peut être aussi USERNAME et USERDOMAIN pour des applications réseau ?
- l'emplacement de stockage des fichiers utilisateur (APPDATA) ?

Bref, je sais pas trop ^^ A part les variables citées, le reste apparait pas franchement intéressant, d'autant que tous les processus ont à peu près les mêmes... :)

@+

Commentaire de bizzard4 le 15/02/2009 18:17:54 9/10

Vraiment super la source ! J'aime beaucoup les sources avec un aspect système. On pense souvent que nous en n'avons jamais besoin mais c'est quand c'est utile qu'on bûche. (expérience personnelle)

Commentaire de PWM63 le 16/02/2009 10:52:57

Je voulais vérifier ce que l'on pouvait voir dans mes applis.
Mais après conversion vers VB .Net 2008 (Framework 3.5), même si aucun erreur n'apparaît et que la compilation se fait sans soucis, je ne vois que la liste des processus à gauche, et à droite, 1 liste plus ou moins longue (en fonction du process) de données vides (et pourtant aucun msgbox n'apparait)...

PS : je suis sur XP SP3

Commentaire de violent_ken le 16/02/2009 11:04:08

Je viens de tester sur une machine virtuelle XP Pro SP3, et effectivement, çà ne marche pas pour certains processus (liste pleine d'éléments vide à droite).

Je vais essayer de voir pourquoi çà bug

Merci
@+

Commentaire de violent_ken le 16/02/2009 11:35:06

J'ai commencé à debugger, en vérifiant les adresses/tailles avec un éditeur hexadécimal.

- l'adresse du PEB est bonne
- l'adresse du ProcessParameter block est bonne
- l'adresse des variables d'environnement est bonne (apparement toujours 65536 sous XP)
- la taille du bloc à lire est bonne.

C'est lors de l'appel à ReadProcessMemory que çà foire (retourne l'erreur ERROR_PARTIAL_COPY, cad seule une partie de la mémoire a pu être lue).

C'est super étrange, la memory region size est largement supérieure à la taille du bloc à lire (region size = 4k, block = 2114 octets).



Tu n'aurais pas un OS 64 bits par hasard ?
@+

Commentaire de violent_ken le 16/02/2009 11:57:10

Bon je peux proposer une correction résolvant le problème, mais je crois qu'il y a un problème de fond sous-jacent : la taille de bloc maximale lisible via ReadProcessMemory sous XP est de 2048, dans mon cas.

Au delà de cette taille, il faut fractionner la lecture en deux fois (et là encore c'est dans l'espoir que la taille totale soit inférieure à 4096 bytes) et fusionner les deux buffers.


Bref çà marche, MAIS :
"pourquoi ne peut t-on pas lire d'un seul bloc 2124 bytes ?"

Je vais regarder sur le net avant de poster la MAJ


(sinon juste remplacer la fonction ReadBytesAS par çà :

    Public Function ReadBytesAS(ByVal offset As Integer, ByVal size As Integer) As Short()

        Dim sBuf() As Short
        Dim _si As Integer = size
        Dim lByte As Integer
        ReDim sBuf(size - 1)

        ' Short array -> size*2 to get bytes count
        Dim ret As Integer = ReadProcessMemory(_handle, offset, sBuf, size * 2, lByte)

        ' If ret = 0 and err = ERROR_PARTIAL_COPY, reduce block size
        Do While ((ret = 0) And (Err.LastDllError = 299))
            size -= 2   ' Short <-> 2 bytes
            ret = ReadProcessMemory(_handle, offset, sBuf, size * 2, lByte)
        Loop

        If size < _si Then
            ' Got an error before, now we have to read part which was unreadable
            Dim sBuf2() As Short
            ReDim sBuf2(_si - size - 1)
            ret = ReadProcessMemory(_handle, offset + size, sBuf2, (_si - size) * 2, lByte)
            ' Copy buf2 to buf
            sBuf2.CopyTo(sBuf, CInt(size / 2 - 1))
        End If

        Return sBuf
    End Function
)

@+

Commentaire de PWM63 le 16/02/2009 16:27:03 10/10

Non, j'ai bien la version 32 bits.

Merci pour la nouvelle fonction, c'est beaucoup mieux !

Il y a  toujours des processus sans données : essaie de découper autant de fois que de tranche de 2048 octets.

Ensuite, quelques bizarreries :
Quand il y a des données, la 1ère ligne est :
=::=::\

Sur quelques processus, j'ai :
=C:=C:\UnChemin
où UnChemin est un chemin complet

Il y a également souvent 2 lignes vides en fin de liste (desfois 1, desfois 0) selon le processus.

En tout cas, j'ai pu tester mes applis : 10/10
(Et ça ne retourne rien de plus que explorer !)

Commentaire de violent_ken le 16/02/2009 16:47:52

Version 32 bits ? Hum, bah de toutes façons même en 64 bits le problème aurait été des plus bizarre. Bref, question ouverte en suspend.
Avec la nouvelle fonction çà marche, mais çà reste franchement étrange que j'ai du apporter la modification du dessus.


Je vais mettre à jour le zip.


Alors sinon pour les lignes vides, effectivement j'ai fait une erreur d'index, il faut lire :
sBuf2.CopyTo(sBuf, CInt(size / 2))    (pas de -1) ^^


Pour =::=::\, ben honnêtement c'est pas de ma faute :-)

En mémoire il y a une chaine de ce type (vérifié avec un editeur hexa) :
==::=::\@ (ou @ est un nullchar). Du coup lors du parsing, je prend ce qui est à gauche du premier '=' (c'est à dire rien) et c'est le nom de la variable.
Sa valeur est à droite du premier '=', c'est donc =::=::\.

Bref, du coup c'est "un bug de Windows" (une variable d'environnement qui n'a pas de nom et qui a une valeur pourrie). Le plus simple est de les filtrer en n'affichant que celles dont NomVariable.Length > 0 (nom de variable non nul).


Pour les processus sans données, tu pourrais s'il te plait juste mettre un point d'arrêt dans le code et me donner la valeur de _size juste avant ReadBytesAS ?
Ainsi que le nom du process, parce qu'un process avec plus de 4K de variables d'environnement... OUCH !!


Merci
@+

Commentaire de PWM63 le 16/02/2009 18:00:50

Alors, pour les lignes vides, la petite correction n'a à priori rien amélioré...
J'ai toujours 1 ou 2 lignes vides à la fin.

Et pour les processus où il n'y a pas de données (sauf 2 lignes vides) :
_size = 2

Commentaire de violent_ken le 16/02/2009 18:33:55

J'ai corrigé tous les bugs (normalement).


Sinon pour le processus ou il n'y a pas de données, _size = 2 indique que le bloc mémoire contenant la liste des variables est vide (du coup c'est normal qu'il retrouve rien).

Plusieurs raisons :
- soit le processus n'a pas de variables (très peu probable)
- soit l'accès est refusé (processus système et droits non suffisants ?)
- soit je sais pas ??

@+

Commentaire de PWM63 le 16/02/2009 19:25:12

Ok merci, je testerai de nouveau ça demain.

Pour info, je suis administrateur de mon propre PC.

@+

Commentaire de violent_ken le 16/02/2009 19:48:39

Ok merci !

Par contre, pour les droits, administrateur ne suffit pas pour accéder à tout : contrairement à ce que j'ai dit dans la description par rapport à l'injection, il faut également le droit DebugPrivilege pour accéder au processus système pour faire un ReadProcessMemory.

@+

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Utilisation de ReadProcessMemory [ par fourne ] Bonjour je souhaiterais pouvoir récupérer des valeurs de variables appartenant à un autre processus, exemple : récupérer les informations d'une fenêtr Finalisation d'un script [ par tetard_is_pa ] bon bah je nage complètement, j'ai beau comprendre la logique du If ... Then avec Else ou Case je n'arrive à rien (vivement les cours et la prog sur t Programme agît sur un processus réduit dans la barre de tâche. [ par anerax ] Bonjour all,Existe-t-il une fonction pour qu'un programme vb6 continue d'agir sur un processus réduit ? Merci.Vb6 is'nt dead ! VB.Net Renommer un fichier utilisé par un autre processus [ par MagDix ] Bonjour Je veux renommer un fichier. J'utilise un listbox et un picturebox. Je sélectionne un fichier dans le listbox et l'image aparrait dans le pic Comment arretez l'utilisation d'un fichier par le processus System [ par cbz ] Bonjour,N'étant pas très vieux en dev, j'ai un petit soucis:Via du VBscript dans un HTA, je lance la ligne de commande suivante. "typeperf -s " &amp Mettre en pause un processus - copier un fichier utilisé par un processus [ par Children ] Bonjours, voilà, je cherche à copier un fichier utilisé par un autre processus. Je connais le nom du processus qui l'utilise. Je suppose qu'il suffit Mettre en pause un processus - copier un fichier utilisé par un processus [ par Children ] Bonjours, voilà, je cherche à copier un fichier utilisé par un autre processus. Je connais le nom du processus qui l'utilise. Je suppose qu'il suffit Minimzer une application [ par DiabloduNord ] Bonjour tout le monde,Je cherche à créer une petit application qui analyse les processus et les tues. Les processus à tués seront supprimé dans un fic Mémoire Framework.net [ par emap ] Hi, Je re-poste (je sais c'est pas bien...) Je fais de la synchro SQLServer&lt;&gt;AS400 via une classe sur un backgroung thread en récupérant 30000 Liste des processus de la barre des tâches [ par pcmanprogrammeur ] Bonjour,J'ai besoin de votre aide car il m'est impossible de trouver comment récupérer la liste des fenêtres qui sont dans la barre des tâches !!!Est-


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,108 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales