Note that there are some explanatory texts on larger screens.

plurals
  1. POGet StartAddress of win32 thread from another process
    text
    copied!<h2>Background:</h2> <p>I've written a multi-threaded application in Win32, which I start from C# code using <code>Process</code> class from <code>System.Diagnostics</code> namespace.</p> <p>Now, in the C# code, I want to get the name/symbol of the start address of each thread created in the Win32 application so that I could log thread related information, such as CPU usage, to database. Basically, C# code starts multiple instances of the Win32 Application, monitors them, kills if needed, and then logs info/error/exceptions/reason/etc to database.</p> <p>For this purpose, I've wrapped two Win32 API viz. <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms681351%28v=vs.85%29.aspx"><code>SymInitialize</code></a> and <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms681323%28v=vs.85%29.aspx"><code>SymFromAddr</code></a> in programmer-friendly API written by myself, as listed below:</p> <pre><code>extern "C" { //wraps SymInitialize DllExport bool initialize_handler(HANDLE hModue); //wraps SymFromAddr DllExport bool get_function_symbol(HANDLE hModule, //in void *address, //in char *name); //out } </code></pre> <p>And then call these API from C# code, using pinvoke. But it does not work and <code>GetLastError</code> gives <code>126</code> <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382%28v=vs.85%29.aspx">error code</a> which means:</p> <blockquote> <p>The specified module could not be found</p> </blockquote> <p>I'm passing <code>Process.Handle</code> as <code>hModule</code> to both functions; <code>initialize_handler</code> seems to work, but <code>get_function_symbol</code> does not; it gives the above error. I'm not sure if I'm passing the correct handle. I tried passing the following handles:</p> <pre><code>Process.MainWindowHandle Process.MainModule.BaseAddress </code></pre> <p>Both fail at the first step itself (i.e when calling <code>initialize_handler</code>). I'm passing <code>Process.Threads[i].StartAddress</code> as second argument, and that seems to be cause of the failure as <code>ProcessThread.StartAddress</code> seems to be the address of <code>RtlUserThreadStart</code> function, <strong>not</strong> the address of the start function specific to the application. The <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.processthread.startaddress.aspx">MSDN says about it</a>:</p> <blockquote> <p>Every Windows thread actually begins execution in a system-supplied function, not the application-supplied function. The starting address for the primary thread is, therefore, the same (as it represents the address of the system-supplied function) for every Windows process in the system. <strong>However, the StartAddress property allows you to get the starting function address that is specific to your application.</strong></p> </blockquote> <p>But it doesn't say how to get the startinbg function address specific to the application, using ProcessThread.StartAddress.</p> <h2>Question:</h2> <p>My problem boils to getting the start address of win32 thread from another application (written in C#), as once I get it, I will get the name as well, using the above mentioned APIs. So how to get the start address?</p> <hr> <p>I tested my symbol lookup API from C++ code. It works fine to resolve the address to a symbol, if given the correct address to start with.</p> <p>Here is my p/invoke declarations:</p> <pre><code>[DllImport("UnmanagedSymbols.dll", SetLastError = true, CallingConvention= CallingConvention.Cdecl)] static extern bool initialize_handler(IntPtr hModule); [DllImport("UnmanagedSymbols.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] static extern bool get_function_symbol(IntPtr hModule, IntPtr address, StringBuilder name); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload