Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > General Coding
You last visited: Today at 17:11

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



SetThreadContext + CPU EFlags help please

Discussion on SetThreadContext + CPU EFlags help please within the General Coding forum part of the Coders Den category.

Reply
 
Old   #1
 
elite*gold: 20
Join Date: Aug 2007
Posts: 1,749
Received Thanks: 2,199
SetThreadContext + CPU EFlags help please

Hey everyone. I'm having some problems with my homemade debugger, written in VB6, and I was hoping someone here could help me.

See, I'm writing this kind of debugger hack for Conquer Online. I'm using it to read the decrypted packets both incoming and outgoing. I'm using breakpoints at the "SendPacket()" and "ReceivePacket()" function inside the .exe and then I use the GetThreadContext API to read the register values and get the decrypted packets.

It works almost perfectly, although there's a tiny problem, and I was hoping someone here might know how to solve it. Whenever I hit a breakpoint, my tool is supposed to set the Resume Flag inside the CPU to 1 which should prevent exceptions from going into an infinite loop, but it does not work - the Resume Flag just won't change.

However, it works just fine on Windows Vista, which I cannot seem to understand why, I've google'd a million times, and still no luck. Here's the part of my code that's supposed to toggle the Resume Flag:

Code:
Do While bContinue

    ContinueStatus = DBG_CONTINUE

    If WaitForDebugEvent(DebugEvent, 0) Then
    
        ExceptionAddress = DebugEvent.dwUnionData.ExceptionRecord.ExceptionAddress
        ExceptionCode = DebugEvent.dwUnionData.ExceptionRecord.ExceptionCode
    

        Select Case DebugEvent.dwDebugEventCode
        
            Case EXCEPTION_DEBUG_EVENT
                ContinueStatus = DBG_CONTINUE
                
                If Not bSeenInitialBreakpoint And ExceptionCode = EXCEPTION_BREAKPOINT Then
                    ContinueStatus = DBG_CONTINUE
                    SetHardwareBreakpoint DebugEvent.dwProcessId
                    bSeenInitialBreakpoint = True
                End If
                
                If ExceptionCode = EXCEPTION_SINGLE_STEP Then
                    ContinueStatus = DBG_CONTINUE
                    ThreadHandle = OpenThread(THREAD_ALL_ACCESS, False, DebugEvent.dwThreadId)
'                    Debug.Print "Single step exception occured"
                    SuspendThread (ThreadHandle)
                    If DebugEvent.dwUnionData.ExceptionRecord.ExceptionAddress = SendPacketFunction Or DebugEvent.dwUnionData.ExceptionRecord.ExceptionAddress = RecvPacketFunction Then
                        ExceptionHandler ThreadHandle, ExceptionAddress
                    End If
                    ResumeThread (ThreadHandle)
                    CloseHandle (ThreadHandle)
                End If
                    
                If ExceptionCode = EXCEPTION_BREAKPOINT Then
                    ContinueStatus = DBG_CONTINUE
                End If
                                
            Case CREATE_THREAD_DEBUG_EVENT
                'SetHardwareBreakpointInThread DebugEvent.dwThreadId
        
        End Select
        
        ContinueDebugEvent DebugEvent.dwProcessId, DebugEvent.dwThreadId, ContinueStatus
        
    End If
    
        DoEvents
    Loop
    
    End If
And this:

Code:
Public Sub ExceptionHandler(hThread As Long, ExceptionAddress As Long)

Dim cThread As CONTEXT

cThread.ContextFlags = CONTEXT_ALL
GetThreadContext hThread, cThread
cThread.EFlags = cThread.EFlags Or EFLAG_RF ' // EFLAG_RG = Resume Flag = &H10000
SetThreadContext hThread, cThread
Also, another quick question:
I'm using CreateRemoteThread to execute code inside the .exe (e.g. using a skill), but whenever I'm debugging the application (using DebugActiveProcess) it just freezes. Is there a way to prevent a debugged application from freezing when using CreateRemoteThread? At the moment I have to use this whenever I need to call a function:

Code:
DebugActiveProcessStop(ProcessID)
UseSkill SkillID, TargetID ' (Just an example)
DebugActiveProcess(ProcessID)
Thank you for your time .
IAmHawtness is offline  
Old 08/10/2009, 18:53   #2
 
link's Avatar
 
elite*gold: 1
Join Date: Jul 2005
Posts: 553
Received Thanks: 454
Quote:
You last visited: 08-04-2009 at 01:19
Uh, was quite some time not online.

I don't know if you already solved your problem and additional
I'm not familiar with this topic so the only thing I can do is to guess but let's try though:

Others debuggers break on the next instructions when using HW BPs.
Try setting the RF and then get the flags anew.
You'll see it got cleared..
I don't know why but you seem to cannot set this flag.

Here's a newbish workaround which just came to my mind:
Check in STATUS_SINGLE_STEP if your HW BP got toggled, if so do some stuff, clear Dr7, set a variable and on top of that set the TF.

Call ContinueDebugEvent and WaitForDebugEvent (I would pass -1 as second param. Don't know if it changes something at all, as I said this is the first time I was faced with this topic :x), then check in STATUS_SINGLE_STEP if your variable was set to clear it and set Dr7 again.

Also to not open the thread over and over again I would catch CREATE_PROCESS_DEBUG_EVENT and save u.CreateProcessInfo.hThread.

Err, I certainly do not know how to solve your CreateRemoteThread-problem..
I thought it should work due to ContinueDebugEvent although I did not test it.

Btw. I'm curious how your SetHardwareBreakpoint looks like since it wants the PID. Could you please post it? (Does it use CreateToolhelp32Snapshot?)
link is offline  
Thanks
1 User
Old 08/10/2009, 21:49   #3
 
elite*gold: 20
Join Date: Aug 2007
Posts: 1,749
Received Thanks: 2,199
Quote:
Originally Posted by link View Post
Uh, was quite some time not online.

I don't know if you already solved your problem and additional
I'm not familiar with this topic so the only thing I can do is to guess but let's try though:

Others debuggers break on the next instructions when using HW BPs.
Try setting the RF and then get the flags anew.
You'll see it got cleared..
I don't know why but you seem to cannot set this flag.

Here's a newbish workaround which just came to my mind:
Check in STATUS_SINGLE_STEP if your HW BP got toggled, if so do some stuff, clear Dr7, set a variable and on top of that set the TF.

Call ContinueDebugEvent and WaitForDebugEvent (I would pass -1 as second param. Don't know if it changes something at all, as I said this is the first time I was faced with this topic :x), then check in STATUS_SINGLE_STEP if your variable was set to clear it and set Dr7 again.

Also to not open the thread over and over again I would catch CREATE_PROCESS_DEBUG_EVENT and save u.CreateProcessInfo.hThread.

Err, I certainly do not know how to solve your CreateRemoteThread-problem..
I thought it should work due to ContinueDebugEvent although I did not test it.

Btw. I'm curious how your SetHardwareBreakpoint looks like since it wants the PID. Could you please post it? (Does it use CreateToolhelp32Snapshot?)
Thanks for the input, however I'm converting my project to VB.NET now, I'll see if it works later, and yes, it does call CreateToolHelp32Snapshot to get all the threads of the process.

Code:
Public Function SetHardwareBreakpoint(pid As Long)
Dim hSnap As Long
Dim te As THREADENTRY32
Dim bResult As Boolean

hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, pid)
te.Size = Len(te)
bResult = Thread32First(hSnap, te)

Do While bResult

    If te.ProcessID = pid Then

        SetHardwareBreakpointInThread te.ThreadID

    End If

bResult = Thread32Next(hSnap, te)

Loop

CloseHandle hSnap

End Function
Edit: Forgot to add, I was already clearing the DR7 flag after a breakpoint was met and then re-enabling the breakpoint after execution, however the amount of time it takes to call the SetThreadContext to set the DR7 flag back to enable the breakpoint means that I miss a lot of instructions, depending on how fast they're executed of course.
IAmHawtness is offline  
Old 08/13/2009, 01:52   #4
 
link's Avatar
 
elite*gold: 1
Join Date: Jul 2005
Posts: 553
Received Thanks: 454
Quote:
Originally Posted by IAmHawtness View Post
Edit: Forgot to add, I was already clearing the DR7 flag after a breakpoint was met and then re-enabling the breakpoint after execution, however the amount of time it takes to call the SetThreadContext to set the DR7 flag back to enable the breakpoint means that I miss a lot of instructions, depending on how fast they're executed of course.
Just saw your edit:
The amount of instructions you actually miss is equal to 1 ;-)
That's why I mentioned the behaviour of debuggers when dealing with HW BPs.

I should have had commented it better...
I noticed my whole post is messed up (in language and remarks) and this one gets fucked up, too (hope it helps though).
My English-posts are just awful..

Nevertheless:
Quote:
Originally Posted by link
Check in STATUS_SINGLE_STEP if your HW BP got toggled, if so do some stuff, clear Dr7, set a variable and on top of that set the TF.
Remember the single-step mode :-)

A simple snippet to do so:
Code:
local SetBP, HWToggled
assume ebx : ptr DEBUG_EVENT
mov [SetBP], 1
mov [HWToggled], 0
lea ebx, [DebugEvent]
mov edi, [hThread]

;...

mov ecx, [ebx.u.Exception.ExceptionRecord.ExceptionCode]
cmp ecx, STATUS_BREAKPOINT
jne single_step

  mov eax, [SetBP]
  test eax, eax
  jz already_bp

    inv SuspendThread, edi
    mov [cxt.ContextFlags], CONTEXT_DEBUG_REGISTERS
    inv GetThreadContext, edi, offset cxt
    mov [cxt.rDr0], 0DEADBEEFh
    or [cxt.rDr7], 1
    inv SetThreadContext, edi, offset cxt
    inv ResumeThread, edi
    xor eax, eax
    mov [SetBP], eax

  already_bp:
  jmp continue_debugevent

single_step:
cmp ecx, STATUS_SINGLE_STEP
jne continue_debugevent

  mov eax, 1
  cmp [HWToggled], eax
  jz toggled

    mov [HWToggled], eax
    inv SuspendThread, edi
    mov [cxt.ContextFlags], CONTEXT_DEBUG_REGISTERS or CONTEXT_CONTROL
    inv GetThreadContext, edi, offset cxt
    and [cxt.rDr7], not 1
    or [byte high word low cxt.EFlags], 1
    inv SetThreadContext, edi, offset cxt
    inv ResumeThread, edi
    jmp continue_debugevent

  toggled:
    xor eax, eax
    mov [HWToggled], eax
    inv SuspendThread, edi
    mov [cxt.ContextFlags], CONTEXT_DEBUG_REGISTERS
    inv GetThreadContext, edi, offset cxt
    or [cxt.rDr7], 1
    inv SetThreadContext, edi, offset cxt
    inv ResumeThread, edi
    jmp continue_debugevent
;...
inv ContinueDebugEvent...
link is offline  
Thanks
2 Users
Reply




All times are GMT +1. The time now is 17:11.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.