Skip to main content
added a windbg / livekd script to fetch ThreadProc Eip that will be Executed when broken on ResumeThread
Source Link
blabb
  • 16.7k
  • 1
  • 15
  • 30

if the Thread is Created Suspended and Resume thread is called for the first time ollydbg will not show the thread in its thread window nor will the stack trace for the thread be available in stack window (ALT+K)->Right Click->Thread ->Checkmark

in such cases you can set a breakpoint on the following apis

follow through is based on xp sp3 layout (you may need a bit of tweking in newer os )

1) ntdll!NtContinue / ZwContinue  (can be found without symbol )    
2) ntdll!ZwRegisterThreadTerminateport (can find this too without symbol)    
3) CsrNewThread  (needs symbol)   
4) BaseThreadStartThunk ditto    
5) BaseThreadStart  ditto     

Resume thread will break on either of these apis

if it is broken on Zw/Nt Continue follow the context->eip from the stack [[esp+4] + 0xb8] and set a breakpoint on the eip found (this address normally will be BaseThreadStartThunk which is directly identifiable if you have public symbols loaded ) and hit go once you are on BaseThreadStartThunk single step f8 few times until you get to an indirect call call dword ptr ds:[R32 + CONST] this is your ThreadProc

if it is broken on ZwRegisterTerminatePort you need to just single step (you will return to csrNewThread which you can find if symbols are available) and keep f8ing until you get to the indirect call stated above to land on ThreadProc

the other apis are included in the above and can reduce the number of single step

ntdll!ZwRegisterThreadTerminatePort is the closest break prior to ThreadProc

needs one ctrl+f9 (execute until return) and 3 f8 (single step)

if windbg / livekd is an option this script can retrieve the eip when broken on ResumeThread call be it Firsttime Resume or subsequent resumes

.foreach /ps 8 /pS 0n19 (place { !process 0 4 ${$arg1} } ) {.printf "ETHREAD = %x\n", place ; r? $t0 =  (((nt!_ETHREAD *) @@masm( place ))->Tcb) ; r? $t1 = @$t0.StackLimit;r? $t2 = @$t0.InitialStack;.foreach (vlace {s -[1]d @$t1 @$t2 0x23 0x23 } ) {dt nt!_KTRAP_FRAME DbgEip Eip  @@masm(${vlace}-34) }}

if the Thread is Created Suspended and Resume thread is called for the first time ollydbg will not show the thread in its thread window nor will the stack trace for the thread be available in stack window (ALT+K)->Right Click->Thread ->Checkmark

in such cases you can set a breakpoint on the following apis

follow through is based on xp sp3 layout (you may need a bit of tweking in newer os )

1) ntdll!NtContinue / ZwContinue  (can be found without symbol )    
2) ntdll!ZwRegisterThreadTerminateport (can find this too without symbol)    
3) CsrNewThread  (needs symbol)   
4) BaseThreadStartThunk ditto    
5) BaseThreadStart  ditto     

Resume thread will break on either of these apis

if it is broken on Zw/Nt Continue follow the context->eip from the stack [[esp+4] + 0xb8] and set a breakpoint on the eip found (this address normally will be BaseThreadStartThunk which is directly identifiable if you have public symbols loaded ) and hit go once you are on BaseThreadStartThunk single step f8 few times until you get to an indirect call call dword ptr ds:[R32 + CONST] this is your ThreadProc

if it is broken on ZwRegisterTerminatePort you need to just single step (you will return to csrNewThread which you can find if symbols are available) and keep f8ing until you get to the indirect call stated above to land on ThreadProc

the other apis are included in the above and can reduce the number of single step

ntdll!ZwRegisterThreadTerminatePort is the closest break prior to ThreadProc

needs one ctrl+f9 (execute until return) and 3 f8 (single step)

if the Thread is Created Suspended and Resume thread is called for the first time ollydbg will not show the thread in its thread window nor will the stack trace for the thread be available in stack window (ALT+K)->Right Click->Thread ->Checkmark

in such cases you can set a breakpoint on the following apis

follow through is based on xp sp3 layout (you may need a bit of tweking in newer os )

1) ntdll!NtContinue / ZwContinue  (can be found without symbol )    
2) ntdll!ZwRegisterThreadTerminateport (can find this too without symbol)    
3) CsrNewThread  (needs symbol)   
4) BaseThreadStartThunk ditto    
5) BaseThreadStart  ditto     

Resume thread will break on either of these apis

if it is broken on Zw/Nt Continue follow the context->eip from the stack [[esp+4] + 0xb8] and set a breakpoint on the eip found (this address normally will be BaseThreadStartThunk which is directly identifiable if you have public symbols loaded ) and hit go once you are on BaseThreadStartThunk single step f8 few times until you get to an indirect call call dword ptr ds:[R32 + CONST] this is your ThreadProc

if it is broken on ZwRegisterTerminatePort you need to just single step (you will return to csrNewThread which you can find if symbols are available) and keep f8ing until you get to the indirect call stated above to land on ThreadProc

the other apis are included in the above and can reduce the number of single step

ntdll!ZwRegisterThreadTerminatePort is the closest break prior to ThreadProc

needs one ctrl+f9 (execute until return) and 3 f8 (single step)

if windbg / livekd is an option this script can retrieve the eip when broken on ResumeThread call be it Firsttime Resume or subsequent resumes

.foreach /ps 8 /pS 0n19 (place { !process 0 4 ${$arg1} } ) {.printf "ETHREAD = %x\n", place ; r? $t0 =  (((nt!_ETHREAD *) @@masm( place ))->Tcb) ; r? $t1 = @$t0.StackLimit;r? $t2 = @$t0.InitialStack;.foreach (vlace {s -[1]d @$t1 @$t2 0x23 0x23 } ) {dt nt!_KTRAP_FRAME DbgEip Eip  @@masm(${vlace}-34) }}
Source Link
blabb
  • 16.7k
  • 1
  • 15
  • 30

if the Thread is Created Suspended and Resume thread is called for the first time ollydbg will not show the thread in its thread window nor will the stack trace for the thread be available in stack window (ALT+K)->Right Click->Thread ->Checkmark

in such cases you can set a breakpoint on the following apis

follow through is based on xp sp3 layout (you may need a bit of tweking in newer os )

1) ntdll!NtContinue / ZwContinue  (can be found without symbol )    
2) ntdll!ZwRegisterThreadTerminateport (can find this too without symbol)    
3) CsrNewThread  (needs symbol)   
4) BaseThreadStartThunk ditto    
5) BaseThreadStart  ditto     

Resume thread will break on either of these apis

if it is broken on Zw/Nt Continue follow the context->eip from the stack [[esp+4] + 0xb8] and set a breakpoint on the eip found (this address normally will be BaseThreadStartThunk which is directly identifiable if you have public symbols loaded ) and hit go once you are on BaseThreadStartThunk single step f8 few times until you get to an indirect call call dword ptr ds:[R32 + CONST] this is your ThreadProc

if it is broken on ZwRegisterTerminatePort you need to just single step (you will return to csrNewThread which you can find if symbols are available) and keep f8ing until you get to the indirect call stated above to land on ThreadProc

the other apis are included in the above and can reduce the number of single step

ntdll!ZwRegisterThreadTerminatePort is the closest break prior to ThreadProc

needs one ctrl+f9 (execute until return) and 3 f8 (single step)