Consommation de cpu par process sous windows 98

Description

Objectif :

Sous Windows NT ou 2000/XP il est possible de visualiser la consommation de cpu par process grâce au task manager. Par contre cela n'est pas possible sous Windows 98. Le programme ADVcpu a été développé afin de récupérer cette information sous win98 et l'afficher (il fonctionne uniquement sous Windows 98).

Compilation:
Il y 2 parties: l'application cpu1.exe dont le projet est dans le zip et le pilote (.vxd). Il faut le ddk98 pour compiler le pilote. Si vous ne l'avez pas pour le moment, le .vxd est fourni.

Conclusion :


Résolution des points techniques:

La problématique est que l'API Windows livré pour 98 ne permet pas d'utiliser les compteurs, et qu'aucune fonction de l'API standard ne fourni la consommation de CPU par Process. Sous Windows 98, les 2 seules fonctions qui permettent d'obtenir une approche de la cpu utilisée par un process sont _getLastUpdatedExecTime et _getThreadExecTime du Virtual Machine Manager (Attention, ces fonctions ne peuvent être appelées que dans un pilote). La différence entre les deux fonctions est subtile (consulter la documentation du DDK 98), mais l'une ou l'autre peuvent être utilisées dans le cas de l'application à développer. Comme leur nom l'indique, elles retournent le temps cpu utilisé par un thread. Elles prennent en paramètre la handle d'un thread et retourne un temps en millisecondes. Une énumération des threads d'un process, l'appel à ces fonctions et un petit algorithme de calcul permettent donc d'obtenir le pourcentage de cpu utilisé par un process en particulier.

En fait, cela n'est pas terminé. Tout pourrait bien ce passer s'il n'y avait pas une particularité sous Windows 98. En effet, une handle de thread utilisée dans un pilote n'a pas la même adresse que dans une application. Or, l'énumération des threads pour obtenir les handles doit se faire dans l'application (.exe), alors que l'utilisation de la handle pour la fonction _getThreadExecTime doit se faire dans le pilote (.vxd). L'application tourne dans ce que Microsoft appelle l'anneau 3. Le pilote, quant à lui, tourne dans l'anneau 0. Les valeurs de handle utilisées dans l'anneau 3 ne sont pas utilisables dans l'anneau 0, et vis et versa. Alors comment faire ?

En réalité une passerelle non documentée existe. Il est possible de convertir une handle d'anneau 3 en handle d'anneau 0 grâce à un calcul d'obfuscator. Il s'agit d'un algorithme de pseudo cryptage dont voici la solution à coder dans l'application:

// Voici la fameuse méthode qui permet la récupération
// De la valeur magique pour obtenir une handle de thread utilisable
// Sur l'anneau 0.
DWORD getMagic(DWORD tid)
{

DWORD Magic = 0;

GetCurrentProcessId();
__asm {
xor eax,fs:[30h]
mov [Magic], eax};

return Magic;
}

// Encore une ruse:
// Ici on applique un XOR entre la valeur magique et le thread ID d'anneau 3
// Afin d'obtenir un pointeur sur une structure PTHREAD_DATABASE
PTHREAD_DATABASE TIDToTDB( DWORD tid )
{
DWORD dwPthread = (tid ^ getMagic(tid));
return (PTHREAD_DATABASE)(dwPthread);
}

// cerise sur le gateau:
// la donnée membre contenant la handle de thread utilisable
// sur l'anneau 0 n'est pas Ring0Thread comme son nom
// pourrait le laisser croire,
// mais WaitNodeList
DWORD GetThreadHandle ( DWORD dwThreadID )
{
PTHREAD_DATABASE ptdb;

ptdb = TIDToTDB(dwThreadID);

return (((PTHREAD_DATABASE)ptdb)->WaitNodeList);
}

Le dwThreadID est une handle de thread d'anneau 3 qui peut être par exemple " th32ThreadID" récupéré à l'aide des fonctions d'énumération Thread32First et Thread32Next utilisables sous windows 98.

Pour d'autres informations, aller visiter http://www.advsolutions.fr
Contact: Philippe Plassard

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.