2010-10-22 4 views
2

Je voudrais interroger l'ID de thread actuel sans effectuer un appel windowsAPI. Selon cet article wikipedia http://en.wikipedia.org/wiki/Win32_Thread_Information_Block, il devrait être possible d'accéder directement à l'ID du fil. J'ai essayé ce code:Windows actuel ThreadID sans appel d'API Windows

void* tibPtr; 
__asm { 
    mov EAX, FS:[0x18] 
    mov [tibPtr], EAX 
    } 
int* ptrToThreadID = (int*)(((char*)tibPtr)+0x24); 

que je comprends, déréférencement ptrToThreadID devrait YELD maintenant chaque fois que le ThreadID actuel.

Cependant, il me donne un résultat différent de la fonction WinAPI GetCurrentThreadId() et aussi la valeur vers laquelle il pointe ne change pas.

Qu'est-ce que je fais mal? Je compile pour Win32, mais exécute Windows Vista 64bit. Ai-je besoin de rechercher le threadID à un autre emplacement sur des systèmes 64 bits?

+3

Cela me semble tellement faux ... – ypnos

+0

Pouvez-vous expliquer pourquoi vous ne voulez pas utiliser les API Win32? – JaredPar

+0

parce que cela est utilisé dans le code critique de performance et exécuté très souvent, en fait à chaque déréférencement de mes smart_pointers. Je sais que cela semble faux - mais c'est pour un projet de recherche, il ne doit pas fonctionner sur un ordinateur - juste doit être rapide – Mat

Répondre

2

Si vous voulez voir comment Windows le fait, il suffit de tracer dans la fonction - c'est déjà très rapide - ne provoque pas de changement de mode. Cependant, si vous voulez éviter cela, vous pouvez lire l'identificateur de thread directement à partir du TIB au décalage 0x24.

C avec asm est pas mon point fort, mais quelque chose comme:

int threadId; 
__asm { 
    mov EAX, FS:[0x24] 
    mov [threadId], EAX 
    } 
+0

ça fonctionne comme ça pour moi! – Mat

0

Quelque chose a attiré mon attention dans votre lien:

Quote:
Il est rare d'accéder aux champs TIB par un décalage par rapport FS: [0], mais plutôt d'abord obtenir un pointeur d'auto-référencement linéaire il est stocké à FS: [0x18]. Ce pointeur peut être utilisé avec un arithmétique de pointeur ou être converti en un pointeur struct.

Je ne suis pas un expert en assemblage, mais à ma connaissance, ce que vous faites à la fin est un décalage 0x24 de FS: [0x18].
La table dans le lien indique FS: [0x24] est l'ID de thread, mais ce n'est pas là que vous avez fini.
Si vous voulez compenser 0x24, commencez par 0x00.
Ou si vous devez commencer à partir de 0x18, alors seulement offset 0x0C, qui est le différent de 0x18 pour atterrir à 0x24.

Suis-je sur la bonne voie ici?

+0

Je pense que vous vous trompez: le contenu de FS: [0x18] maintient le pointeur sur le TIB (bloc d'informations de threads). C'est ** déréférencé ** en premier. Ensuite, nous prenons le décalage 0x24 à partir du ** résultat ** prendre un décalage. Et ceci est supposé être le pointeur vers le OIDD de ThreadID – valdo

+0

, j'ai fait une erreur. Rien n'est déréférencé. Mais il ne devrait pas non plus à mon humble avis. – valdo

0

Votre code fonctionne pour moi. Vous devez utiliser DWORD au lieu de int, car GetCurrentThreadId renvoie un DWORD.

+0

C'est pareil (dans ce cas) – valdo

+0

sur quel système exécutez-vous le code? – Mat

0

Je crois que l'implémentation de GetCurrentThreadI d peut être différente en x64, même pour les applications Win32. Par exemple, le TIB peut être plus grand, d'où le décalage réel dans le champ ThreadID peut être plus grand que 0x24.

Je vous suggère d'exécuter ce sous debuffer, appelez la réelle fonction, et voir ce qu'il fait.

0

C'est ce que la fonction réelle n'exécutant une application 32 bits sur Windows 2003 64 bits:

mov eax, fs:[$00000018] 
mov eax, [eax+$24] 
ret 

Dans EAX, vous pouvez vous attendre votre threadid.

Questions connexes