8

I'm working on a mini windows process explorer in C, I have a handle to a thread.
How can I retrieve starting address of that thread? Something like this:
enter image description here

The Pianist
  • 546
  • 2
  • 13
  • 23

3 Answers3

7

Such question was already asked a few days ago. Here is a sample solution:

DWORD WINAPI GetThreadStartAddress(HANDLE hThread)
{
    NTSTATUS ntStatus;
    HANDLE hDupHandle;
    DWORD dwStartAddress;

    pNtQIT NtQueryInformationThread = (pNtQIT)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryInformationThread");

    if(NtQueryInformationThread == NULL) 
        return 0;

    HANDLE hCurrentProcess = GetCurrentProcess();
    if(!DuplicateHandle(hCurrentProcess, hThread, hCurrentProcess, &hDupHandle, THREAD_QUERY_INFORMATION, FALSE, 0)){
        SetLastError(ERROR_ACCESS_DENIED);

        return 0;
    }

    ntStatus = NtQueryInformationThread(hDupHandle, ThreadQuerySetWin32StartAddress, &dwStartAddress, sizeof(DWORD), NULL);
    CloseHandle(hDupHandle);
    if(ntStatus != STATUS_SUCCESS) 
       return 0;

    return dwStartAddress;

}

Source: http://forum.sysinternals.com/how-to-get-the-start-address-and-modu_topic5127_post18072.html#18072

You might have to include this file: http://pastebin.com/ieEqR0eL

Related question: How to add ntdll.dll to project libraries with LoadLibrary() and GetProcAddress() functions?

Community
  • 1
  • 1
Adam Sznajder
  • 9,108
  • 4
  • 39
  • 60
  • Thanks, but this function will return a number. How can I use it as start address? – The Pianist Jun 21 '12 at 23:15
  • This function returns the start address of a thread in target process' address space. You use it in any way you only want (e.g. if you know the function definition you can cast it and call using `CreateRemoteThread` function). – Adam Sznajder Jun 21 '12 at 23:22
  • Can I retrieve something like this: chrome.dll!chromeMain+0x11ded using that number? – The Pianist Jun 21 '12 at 23:31
  • I think that you have to check in which module your start address is located (it doesn't have to be in .text segment of exe file but in e.g. `ntdll.dll` or `chrome.dll`), get the `ImageBaseAddress` of code in it and then calculate the offset (+0x11ded part). Function names can be retrieved by analyzing the DLL files directly (http://msdn.microsoft.com/en-us/library/ms809762.aspx see PE File Exports section). Happy hacking! – Adam Sznajder Jun 21 '12 at 23:39
  • It's the address of function's first byte in target process. You have to remember that it can be cast to a function pointer but the code is located in target process' address space. – Adam Sznajder Jun 22 '12 at 00:07
  • Does this word for x86 and x64? – Ari Seyhun Sep 19 '17 at 05:10
4

NtQueryInformationThread with ThreadQuerySetWin32StartAddress. Another possibility is to walk the thread's stack with StackWalk64.

If you only need the start address, NtQueryInformationProcess is a lot simpler. Even with fairly terse coding, walking the stack takes a couple hundred lines of code or so.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
1

You should be able to get a stack trace with StackWalk64 or a related function, and then parse it with the dbghelp.dll .

This CodeProject article explains it all in detail: http://www.codeproject.com/KB/threads/StackWalker.aspx

Crashworks
  • 40,496
  • 12
  • 101
  • 170