Is there a way to go into the thread function, knowing only the thread
handle?
Yes, it's a 2-step process.
Step 1 - Convert the thread handle to a thread ID
In Process Explorer's menu bar, check the following:
- View → Show Lower Pane
- View → Lower Pane View → Handles
- View → Select Columns... → Handle tab → check all checkboxes
Next, select your target process in Process Explorer's list of processes. You'll then see in the lower pane the list of handles for that process, including thread handles. Find the thread ID associated with your target handle. For the example below, thread handle 0x228
is associated with thread ID 3000
:
Though handle values are shown in hexadecimal in Process Explorer, thread IDs are shown in decimal. Thus thread ID 3000
in decimal is equal to thread ID 0xBB8
in hexadecimal.
Step 2 - Find EIP for the thread ID
In OllyDbg's menu bar, select View → Threads. Right-click on the thread whose Ident corresponds to the thread ID you found in Step 1 (0xBB8
in the example below), and select Show registers:
This will show you the current EIP
for that thread, which is the next instruction to be executed once that thread is resumed:
Alternative Step 2 - Find EIP for the thread ID
If the target thread was created in a suspended state and not yet resumed then the thread won't show up in OllyDbg's thread window. In this case, you can use LiveKd to find the thread's starting address by issuing the LiveKd command !thread -t <thread ID in hexadecimal>
kd> !thread -t BB8
Cid handle table at 88e01108 with 944 entries in use
THREAD 86B4E548 Cid 169c.0bb8 Teb: 7ffdb000 Win32Thread: 00000000 WAIT: (Suspended) KernelMode Non-Alertable
SuspendCount 1
FreezeCount 1
86b4ec28 Semaphore Limit 0x2
Not impersonating
DeviceMap 9a70f9e8
Owning Process 86b4cd40 Image: wordpad.exe
Attached Process N/A Image: N/A
Wait Start TickCount 21829348 Ticks: 1299 (0:00:00:20.264)
Context Switch Count 1 IdealProcessor: 0
UserTime 00:00:00.000
KernelTime 00:00:00.000
Win32 Start Address 0x002cb23d
Stack Init 8b777ed0 Current 8b777a40 Base 8b778000 Limit 8b775000 Call 0
Priority 8 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
ChildEBP RetAddr Args to Child
8b777a58 82a88d3d 85807a60 00000000 82b35d20 nt!KiSwapContext+0x26 (FPO: [Uses EBP] [0,0,4])
8b777a90 82a87b9b 85807b20 85807a60 85807c28 nt!KiSwapThread+0x266
8b777ab8 82a8158f 85807a60 85807b20 00000000 nt!KiCommitThreadWait+0x1df
8b777b34 82abbfd9 85807c28 00000005 00000000 nt!KeWaitForSingleObject+0x393
8b777b4c 82abbaf4 00000000 00000000 00000000 nt!KiSuspendThread+0x18 (FPO: [3,0,0])
8b777b90 82e2390f 00000000 00000000 00000000 nt!KiDeliverApc+0x17f
8b777bb0 82e23b29 00000001 00000000 00000000 hal!HalpDispatchSoftwareInterrupt+0x49 (FPO: [Non-Fpo])
8b777bc8 82e23ba9 00000000 00000000 8b777c20 hal!HalpCheckForSoftwareInterrupt+0x83 (FPO: [Non-Fpo])
8b777bd8 82c6450d b553bcc6 00000000 00000000 hal!KfLowerIrql+0x61 (FPO: [Non-Fpo])
8b777c20 82abb559 00000000 778870d8 00000001 nt!PspUserThreadStartup+0x14
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x19
You can see Win32 Start Address 0x002cb23d
in the output above, which is the starting address for the suspended thread.
Also, are there other ways to create suspended threads aside from
CreateThread()
and CreateRemoteThread()
?
Yes, you can call ntdll!NtCreateThread()
or ntdll!NtCreateThreadEx()
.