views:

40

answers:

1

When you create a DLL you can get notifications about new threads / exiting threads in the DllMain function (DLL_THREAD_ATTACH/DLL_THREAD_DETACH).

Is there a way to get these or equivalent notifications from Windows within an (non managed) Executable?

+1  A: 

Yes - include a small stub DLL in your process that simply monitors DLL_THREAD_ATTACH and DLL_THREAD_DETACH in the way you want.

Steve Townsend
I just want to write the same. This way seems me the most easy, well documented and stable.
Oleg
afaik this is the only way to achieve this reliably on Windows
Steve Townsend
That is what I am currently doing, but the library should be a full source solution without any DLL's. Hence the question how to do it WITHOUT the DllMain notifications..
Ritsaert Hornstra
I understand, but I don't know of any other way to do this. Interestingly, this was an interview question I had to answer once, and the company in question had found no alternative either.
Steve Townsend
@Ritsaert Hornstra : The requirements to have a monolithic solution without any DLL seems me utopian. You EXE will need a lot of parts of operation system which implemented as DLLs. If you use and COM components in your solution you will have more dependencies. Because you ask question about monitoring of threads, then you do use some DLLs which create threads: COM, Sockets or other network components and so on. So I'll recommend you to speak one more time with your chef about the requirement to write code "WITHOUT DLLs".
Oleg
@Oleg: Naturally you always use some system DLLs. But currently we have such requirements; no chef but a contract. The other option currently is using TLS, check if a var exists and add to a list if not. Then use a helper thread and WaitForMultipleObjects to check which threads get closed down and free the token from the helper thread.
Ritsaert Hornstra
@Ritsaert Hornstra: Sorry, I don't understand how you want implement notification about creating of a new thread with respect of TLS. One allocate an TLS index in a DLL inside of `DLL_THREAD_ATTACH` or inside of main thread and save the index in a global variable. Then if inside a thread one can use `TlsSetValue` to save in the index thread specific information or get with `TlsGetValue` the information **previously saved inside the thread**, but all this will not help you to monitor creating of new thread. If you will use **in main thread** `TlsGetValue` you will always have the same value.
Oleg
@Ritsaert Hornstra: The only possibility to monitor thread creating I see in using of some API which register some Callback function, use API hooking (in the form of "Patch the API") of some functions used from **every** thread. You can also modify **in memory** the contain under start address of Kernel32.dll and place JMP to your address. To do this one use `VirtualProtect` function to be able to patch the code. But this technique is much complex as a simple creating of a new DLL.
Oleg
@Oleg: What I mean is that from every thread you should be able to access the thread specific data in the least amount of clock cycles and when a thread is destroyed we should destroy the used data within a reasonable time span (up to 100 ms). So using a single TLS slot I can check if it contains a NULL pointer or a reference to the data. If it is NULL, create data, set reference in TLS and in a global structure together with a handle of the thread. One helper thread can wait for the threads to finish and if so, clean out the allocated data. No hooking needed, but if there is a better way...
Ritsaert Hornstra
It seems to me that what you write can not work. Just write a simple test and verify this. If you test an TLS index in main thread you will only test the value which you set in the main thread. If you will test an TLS index in a helper thread you will only test the value which you set in the helper thread. In every thread all works **absolute independent**, so it will you not help to test whether a new thread are created in your process or not. But verify it better in a test. You need just invest 15-30 min to write a test program.
Oleg
I was serious when I said that there is no other way to do this. The interview q I mentioned above was at a very technologically-savvy company, and they had found no other way to do this. I can imagine there is a way to hook directly into the OS to do this - ask Microsoft. I would expect any such a solution to be kernel-based - like for intrusion prevention, behavioural blocking or AV software - hooking process activity at the OS level.
Steve Townsend
@Steve: I accepted the answer as it really looks like there is no other way. @Oleg: The TLS is naturally only accessed from the thread itself, hence the global structure with a list of objects/thread IDs. This only detects threads when the library is used (not a problem) but the helper thread it needs and the limit of the # threads in a single WaitForMultipleObjects call make it a bit tricky..
Ritsaert Hornstra
@Ritsaert - sorry about that, honestly don't think any alternative will work properly for you. Good luck w it.
Steve Townsend