views:

59

answers:

4

Hey there!

I'd like to query the current threadID without making a windowsAPI call.

According to this http://en.wikipedia.org/wiki/Win32_Thread_Information_Block wikipedia article it should be possible to access the thread ID directly. I tried this code:

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

as i understand it, dereferencing ptrToThreadID should yeld now everytime the current ThreadID.

however, it gives me a different result than the WinAPI function GetCurrentThreadId() and also the value it points to doesn't change.

What am I doing wrong? I'm compiling for Win32, but running Windows Vista 64bit. Do I need to look for the threadID at another location on 64bit systems?

A: 

Something grabbed my attention in your link:

Quote:
It is not common to access the TIB fields by an offset from FS:[0], but rather first getting a linear self-referencing pointer to it stored at FS:[0x18]. That pointer can be used with pointer arithmetics or be cast to a struct pointer.

I'm no assembly expert, but to my understanding, what you're doing at the end is a 0x24 offset from FS:[0x18].
The table in the link says FS:[0x24] is the thread ID, but that's not where you ended up.
If you're going to offset 0x24, then start from 0x00.
Or if you must start from 0x18, then only offset 0x0C, which is the different from 0x18 to land at 0x24.

Am I on the right track here?

Beemer
I think you're mistaken: the contents of FS:[0x18] hold the pointer to the TIB (thread info block). It's **dereferenced** first. Then we take the 0x24 offset from the **result** take an offset. And this is supposed to be the pointer to the ThreadID
valdo
OOPS, I've made a mistake. Nothing is dereferenced. But it also should not IMHO.
valdo
A: 

Your code works for me. You should use DWORD instead of int since GetCurrentThreadId returns a DWORD.

Alex
It's the same (in this case)
valdo
@Alex - on what system are you running the code?
Mat
A: 

I believe the implementation of GetCurrentThreadId may be different in x64, even for Win32 applications. For instance, the TIB may be larger, hence the actual offset into the ThreadID field may be bigger than 0x24.

I suggest you run this under debuffer, call the actual function, and see what it does.

valdo
+1  A: 

If you want to see how Windows does it, simply trace into the function - it's already very fast - doesn't cause a mode switch.

However, if you want to avoid even that, you can read the thread id directly out of the TIB at offset 0x24.

C with asm is not my strong suit, but something like:

int threadId;
__asm {
    mov EAX, FS:[0x24]
    mov [threadId], EAX
    }
500 - Internal Server Error
it actually works like that for me!
Mat