Jump to content
Tuts 4 You

GetThreadContext without debug attributes


ToMKoL

Recommended Posts

Posted

Hi

I'm looking for example on creatingprocess and then acquiring it's context via GetThreadContext without using DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS. If I use CreateProcess with only CREATE_SUSPENDED flag I end up with ERROR_NOACCESS as my thread have no THREAD_GET_CONTEXT attribute. I've tried to use SetSecurityInfo but without luck.

If someone have other ideas I'll be glad to test them.

Posted

Use SuspendThread to pause a thread before you attempt to get its context. Be sure that the thread is opened with proper permissions as well. If you created the process, the PROCESS_INFORMATION structure will contain a handle the process and its main thread you can use for these purposes if the main thread is what you need to suspend. If you need a sub-thread, you can use iteration API such as CreateToolhelp32Snapshot with Thread32First/Thread32Next to loop and find the specific thread you need. Open the thread handle via  OpenThread with the needed permissions then do the other steps like its the other thread handle.

After you have done what you need, you can use ResumeThread to unpause the thread.

Posted

Thanks for reply but you misunderstood me. What I'm doing is CreateProcess with CREATE_SUSPENDED flag only. Then I try to get thread context via GetThreadContext API and fail miserably. I've tried to use OpenThread API with those flags THREAD_GET_CONTEXT or THREAD_SET_CONTEXT or THREAD_SUSPEND_RESUME but ended with ERROR_ACCESS_DENIED. I may use ResumeThread and SuspendThread API but I'll get the same result. Tested already.

Posted

Can you post the code that you are using?  When you call CreateProcess(), you receive in return a handle to the process and its main thread.  You can pass the thread handle (not the process handle) to GetThreadContext() to receive context, but don't forget to set the ContextFlags field in the context structure first.

 

Posted

As Peter mentioned above you will need to fill ContextFlags before calling GetThreadContext as described on MSDN. You may also want to check if your process is 64-bit opening a 32-bit process or vice-versa, refer to remarks in Wow64GetThreadContext.

ProcessInfo.PROCESS_INFORMATION
StartupInfo.STARTUPINFO
Context.CONTEXT

If CreateProcess_("C:\upx32.exe", #Null, #Null, #Null, #False, #CREATE_SUSPENDED, #Null, #Null, @StartupInfo, @ProcessInfo)

  ; Set the context flag for integer values
  
  Context\ContextFlags = #CONTEXT_CONTROL
  
  ; Retrieve the threads context
  
  If GetThreadContext_(ProcessInfo\hThread, @Context)
    ResumeThread_(ProcessInfo\hThread)
  Else
    TerminateProcess_(ProcessInfo\hProcess, #Null)
    Debug "Terminated"
  EndIf
  
  CloseHandle_(ProcessInfo\hProcess)
EndIf

Ted.

Posted

My code is almost identical as Ted. The only difference is that I'm using CONTEXT_i386 as ContextFlags. Did try also CONTEXT_FULL but without luck. My process is 32 bit. Tested my code on win7 x64 SP1 and VM win XP SP3.

Posted

whats the error code from the GetThreadContext call ? debug and see where its failing, are you perhaps using the right handle returned from CreateProcess ? (the thread handle, NOT the process handle for example), post your code perhaps ?

Posted

Here is my code:

	sub eax,eax
	push offset pinfo
	push offset sinfo
	push eax
	push eax
	push CREATE_SUSPENDED
	push eax
	push eax
	push eax
	push eax
	push offset calc
	call CreateProcessA
	mov dword ptr [ctx.ContextFlags],CONTEXT_FULL
	push offset ctx
	push dword ptr [pinfo.hThread]
	call GetThreadContext

My test program is old "32-bit calculator by cybult". I end up with  ERROR_NOACCES (3E6) as last error.

Posted

InitializeContext didn't change anything. Still the same ERROR_NOACCES.

Posted

Hi,

do you wanna write your code directly into any loaded file in Olly with MultiASM etc like you did post?First just check whether the structs you are use are filled with zero bytes and set the size of STARTUPINFO struct into before calling GetStartupInfo and then CreateProcess.

00401088   MOV DWORD PTR DS:[0x406814],0x44          ; size
00401092   PUSH 0x406814
00401097   CALL 0040312A                             ; <JMP.&kernel32.GetStartupInfoA>
0040109C   PUSH 0x406858
004010A1   PUSH 0x406814
004010A6   PUSH 0x0
004010A8   PUSH 0x0
004010AA   PUSH 0x4
004010AC   PUSH 0x0
004010AE   PUSH 0x0
004010B0   PUSH 0x0
004010B2   PUSH 0x0
004010B4   PUSH 0x405064                             ; ASCII "C:\bones.exe"
004010B9   CALL 00403106                             ; <JMP.&kernel32.CreateProcessA>
004010BE   OR EAX,EAX
004010C0   JNZ SHORT 004010D6                        
004010C2   PUSH 0x30
004010C4   PUSH 0x40508C                             ; ASCII "Problem!"
004010C9   PUSH 0x405074                             ; ASCII "CreateProcess Error!"
004010CE   PUSH 0x0
004010D0   CALL 004031A2                             ; <JMP.&user32.MessageBoxA>
004010D5   RETN
004010D6   PUSH 0x10007
004010DB   POP DWORD PTR DS:[0x406868]              
004010E1   PUSH 0x406868
004010E6   PUSH DWORD PTR DS:[0x40685C]
004010EC   CALL 00403136                             ; <JMP.&kernel32.GetThreadContext>
004010F1   OR EAX,EAX
004010F3   JNZ SHORT 00401109                        
004010F5   PUSH 0x30
004010F7   PUSH 0x4050B0                             ; ASCII "Problem!"
004010FC   PUSH 0x405098                             ; ASCII "GetThreadContext Error!"
00401101   PUSH 0x0
00401103   CALL 004031A2                             ; <JMP.&user32.MessageBoxA>
00401108   RETN
00401109   PUSH DWORD PTR DS:[0x40685C]
0040110F   CALL 0040315A                             ; <JMP.&kernel32.ResumeThread>
00401114   PUSH 0x0
00401116   PUSH DWORD PTR DS:[0x406858]
0040111C   CALL 00403166                             ; <JMP.&kernel32.TerminateProcess>

greetz

Posted

@ToMKoL: your code works just fine for me in 64bit Win7 SP1. Full source and sample EXE attached.

If my compiled EXE doesn't work in your 64bit Win7 SP1, check all your antiviruses, sandboxes, exploit mitigation software, user settings and other crap. 
If my compiled EXE works, then start changing things, compiling and testing each step. Most likely it will be some initialization or alignment issue.

 

tomkol_test.zip

Posted

Thanks kao. Works fine. The problem was alignment. I used 4 and it didn't work. With 8 I get empty context and with 16 everything works.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...