how does the Callbacks work in a dbgeng based debugger

i am trying to hack together a dbgeng based usermode only debugger and
it seems i cant understand something very basic

at the moment all i want is a printf() from CreateProcess event and
return DEBUG_STATUS_BREAK

add a bp on the AddrOfEntryPoint in a simple MessageBox.exe (invoke
msgbox(); invoke ExitProc();
Addr of EntryPoint is 0x401000 and i want to test bp here only (no
complications reqd atm)

the loadmod msgs will be passed to console via OutputCallbacks

when the bp is hit Event callback is called for breakpoint
and i Want to return back DEBUG_STATUS_STEP_OVER

i have added

class EventCallbacks : public DebugBaseEventCallbacks {
addref,release,getinerestmask.bp,except,createproc,LoadMod,SessStat,ChgengStat}
class StdioOutputCallbacks : public IDebugOutputCallbacks
{Queryint,Addref,Release,Output}
class StdioInputCallbacks : public IDebugInputCallbacks
{QI,Ar,Rel,StartIn,Endin}

in
STDMETHODIMP EvtCb::Bp( Bp ) {printf(“EventCallbacks::Breakpoint Id %x
%I64x\n”,Id,dbgbpparm.Offset); GO_HAND}
STDMETHODIMP EvtCb::Cp(…) {printf (“EventCallbacks::CreateProcess
ImageName %s\n”,ImageName);STAT_BREAK}
STDMETHODIMP EvtCb::Lm(…) {NO_CHANGE}
STDMETHODIMP EvtCb::Exce(…) {printf (“…”);GO_HAND}
STDMETHODIMP EvtCb::SessStat(…) {printf (“…”);S_OK}
STDMETHODIMP EvtCb::ChgEngStat(…) {printf (“…”);S_OK}

STDMETHODIMP OutCb::Output(…) {fput();S_OK}

STDMETHODIMP InCb::StartIn(…) {fgets();S_OK}
STDMETHODIMP InCb::EndIn(…) {void;S_OK}

in main() {
create_interfaces( for
IDbgClient,IdbgControl,IdbgdataSapces,IdebugReg,IdebugSym)
SetEvetCb (event)
Createprocess(…,dbg_only_this);
SetOutCb(out)
SetInCb(in)

EvtLoop();
Exit()
}

now i get the createproc printf
but i dont seem to be called in any of the callbacks for DEBUG_STATUS_BREAK

and i land up in unhandled event in my event loop

which looks like this

plese dont nit pick this crap code for dots and crosses i just want
ideas or concept

th sample healer and remmon loops have comments that we shouldnt
normally land here
so wher should i land where do i add my bp and how to handle the break

void
EventLoop(void)
{
HRESULT Status;
ULONG type,pid,tid;
char Desc[0x20];
BYTE extinf[0x30];
ULONG64 endoffset;
ULONG64 bpoffset = 0x401000;
ULONG ExecStatus;

for (;:wink:
{
if ((Status = g_Control->WaitForEvent(DEBUG_WAIT_DEFAULT,
INFINITE)) != S_OK)
{
ULONG ExecStatus;

if (g_Control->GetExecutionStatus(&ExecStatus) == S_OK &&
ExecStatus == DEBUG_STATUS_NO_DEBUGGEE)
{
// The session ended so we can quit.
break;
}

// There was a real error.
Exit(1, “WaitForEvent failed, 0x%X\n”, Status);
}

according to windbg sdk sample i shouldnt be here unless i have an
unhandled event

g_Control->GetLastEventInformation(&type,&pid,&tid,(PVOID)&extinf,0x30,NULL,(PSTR)Desc,0x20,NULL);
printf(“we have broken into the target due to event %x %s\n”,type,Desc);

g_Control->OutputDisassembly(DEBUG_OUTCTL_THIS_CLIENT,dbgbpparm.Offset,DEBUG_DISASM_EFFECTIVE_ADDRESS,&endoffset);

if (( Status =
g_Control->AddBreakpoint(DEBUG_BREAKPOINT_CODE,DEBUG_ANY_ID,&g_Breakpoint))
!= S_OK)
{
printf(“AddBp failed %x\n”,Status);
}
if (( Status = g_Breakpoint->SetOffset(bpoffset)) != S_OK)
{
printf(“Setoffset failed %x\n”,Status);
}
if (( Status = g_Breakpoint->SetFlags(DEBUG_BREAKPOINT_ENABLED)) != S_OK)
{
printf(“SetFlags failed %x\n”,Status);
}
if (( Status = g_Breakpoint->SetCommand(“.echo This is a Bp From Our
Code”)) != S_OK)
{
printf(“SetCommand failed %x\n”,Status);
}

if ((Status = g_Control->
SetExecutionStatus(DEBUG_STATUS_GO_HANDLED)) != S_OK)
{
Exit(1, “SetExecutionStatus failed, 0x%X\n”, Status);
}
}
}

my output from compiled binary as follows

foo:\>dbgengdbg.exe msgbox.exe
wtf2
EventCallbacks::SessionStatus = 0
Symbol search path is: SRV*F:\symbols*http://msdl.microsoft.com/download/symbols

Executable search path is:
ModLoad: 00400000 00404000 msgbox.exe
EventCallbacks::CreateProcess ImageName msgbox.exe
wtf2
we have broken into the target due to event 10 Create process 0:9b0
00000000 ?? ???
wtf2
wtf2
ModLoad: 7c900000 7c9b2000 ntdll.dll
wtf2
ModLoad: 7c800000 7c8f6000 C:\WINDOWS\system32\kernel32.dll
wtf2
ModLoad: 64d00000 64d3c000 C:\Program Files\Alwil Software\Avast5\snxhk.dll
wtf2
ModLoad: 7e410000 7e4a1000 C:\WINDOWS\system32\user32.dll
wtf2
ModLoad: 77f10000 77f59000 C:\WINDOWS\system32\GDI32.dll
wtf2
wtf2
ModLoad: 5cb70000 5cb96000 C:\WINDOWS\system32\ShimEng.dll
wtf2
ModLoad: 76390000 763ad000 C:\WINDOWS\system32\IMM32.DLL
wtf2
ModLoad: 77dd0000 77e6b000 C:\WINDOWS\system32\ADVAPI32.dll
wtf2
ModLoad: 77e70000 77f02000 C:\WINDOWS\system32\RPCRT4.dll
wtf2
ModLoad: 77fe0000 77ff1000 C:\WINDOWS\system32\Secur32.dll
wtf2
This is a Bp From Our Code
EventCallbacks::Breakpoint Id 0 401000
wtf2
wtf2
we have broken into the target due to event 0
00401000 6a00 push 0
Breakpoints 1 and 0 match
wtf2
wtf2
ModLoad: 5ad70000 5ada8000 C:\WINDOWS\system32\uxtheme.dll
wtf2
ModLoad: 77c10000 77c68000 C:\WINDOWS\system32\msvcrt.dll
wtf2
ModLoad: 77c00000 77c08000 C:\WINDOWS\system32\version.dll
wtf2
ModLoad: 77b40000 77b62000 C:\WINDOWS\system32\apphelp.dll
wtf2
ModLoad: 755c0000 755ee000 C:\WINDOWS\system32\msctfime.ime
wtf2
ModLoad: 774e0000 7761d000 C:\WINDOWS\system32\ole32.dll
wtf2
wtf2
EventCallbacks::SessionStatus = 4
wtf2

foo:\>dbgengdbg.exe msgbox.exe
wtf2
EventCallbacks::SessionStatus = 0
Symbol search path is: SRV*F:\symbols*http://msdl.microsoft.com/download/symbols

Executable search path is:
ModLoad: 00400000 00404000 msgbox.exe
EventCallbacks::CreateProcess ImageName msgbox.exe
wtf2
we have broken into the target due to event 10 Create process 0:488
<--------- unhandled ? dont we land in Exception Callback ?
00000000 ?? ???
wtf2
wtf2
ModLoad: 7c900000 7c9b2000 ntdll.dll
wtf2
ModLoad: 7c800000 7c8f6000 C:\WINDOWS\system32\kernel32.dll
wtf2
ModLoad: 64d00000 64d3c000 C:\Program Files\Alwil Software\Avast5\snxhk.dll
wtf2
ModLoad: 7e410000 7e4a1000 C:\WINDOWS\system32\user32.dll
wtf2
ModLoad: 77f10000 77f59000 C:\WINDOWS\system32\GDI32.dll
wtf2
wtf2
ModLoad: 5cb70000 5cb96000 C:\WINDOWS\system32\ShimEng.dll
wtf2
ModLoad: 76390000 763ad000 C:\WINDOWS\system32\IMM32.DLL
wtf2
ModLoad: 77dd0000 77e6b000 C:\WINDOWS\system32\ADVAPI32.dll
wtf2
ModLoad: 77e70000 77f02000 C:\WINDOWS\system32\RPCRT4.dll
wtf2
ModLoad: 77fe0000 77ff1000 C:\WINDOWS\system32\Secur32.dll
wtf2
This is a Bp From Our Code <---------- the bp seems to be hit :slight_smile: from
our unhandled code ???
EventCallbacks::Breakpoint Id 0 401000 <-------------------------
wtf2
wtf2
we have broken into the target due to event 0
00401000 6a00 push 0
Breakpoints 1 and 0 match <---------------------- yes this is crap we
should spin on it but not real concern atm
wtf2
wtf2
ModLoad: 5ad70000 5ada8000 C:\WINDOWS\system32\uxtheme.dll
wtf2
ModLoad: 77c10000 77c68000 C:\WINDOWS\system32\msvcrt.dll
wtf2
ModLoad: 77c00000 77c08000 C:\WINDOWS\system32\version.dll
wtf2
ModLoad: 77b40000 77b62000 C:\WINDOWS\system32\apphelp.dll
wtf2
ModLoad: 755c0000 755ee000 C:\WINDOWS\system32\msctfime.ime
wtf2
ModLoad: 774e0000 7761d000 C:\WINDOWS\system32\ole32.dll

the exe starts running here what happend to the int 3 ?? dont we crash ?
who eats my excpetion ?? how can i eat my own break ???
wtf2
wtf2
EventCallbacks::SessionStatus = 4 DEBUG_END_SESSION PASSIVE How
??? who gave the permission ??
wtf2

foo:\>

no idea why i am almost always unlucky when i ask a question
does anybody have any idea how to either single step or step over in
the callbacks ??

snippets

void __cdecl main(int Argc, char* Argv)
{
if (Argc != 2)
{
Exit(0, “provide path of exe\n”);
}

CreateInterfaces();
HRESULT Status = 0;
if (
((Status = g_Client->SetEventCallbacks (&g_EventCb)) != S_OK) ||
((Status = g_Client->SetOutputCallbacks (&g_OutputCb)) != S_OK) ||
((Status = g_Client->SetInputCallbacks (&g_InputCb)) != S_OK)
)
{
Exit(1, “Setting of Callbacks failed\n”);
}
if ((Status = g_Client->CreateProcess(0, Argv[1],
DEBUG_ONLY_THIS_PROCESS)) != S_OK)
{
Exit(1, “CreateProcess failed, 0x%X\n”, Status);
}
EventLoop();
Exit(0, NULL);
}

the event loop as follows

void EventLoop(void)
{
HRESULT Status;
ULONG ExecStatus;
for (;:wink:
{
if ((Status = g_Control->WaitForEvent(DEBUG_WAIT_DEFAULT,
INFINITE)) != S_OK)
{
ULONG ExecStatus;
if (g_Control->GetExecutionStatus(&ExecStatus) == S_OK &&
ExecStatus == DEBUG_STATUS_NO_DEBUGGEE)
{
printf(“no debugee quitting\n”);
break;
}
Exit(1, “WaitForEvent failed, 0x%X\n”, Status);
}
Exit(1, “Unhandled event we should not land here exiting\n”);
}
}

when i either single step (t) or step over (p)
i land at

Exit(1, “Unhandled event we should not land here exiting\n”);

can someone point out why ?

the classes (event,output and input) are pretty standard

class EventCallbacks : public DebugBaseEventCallbacks
{
public:
STDMETHOD_(ULONG, AddRef) ( THIS );
STDMETHOD_(ULONG, Release) ( THIS );
STDMETHOD(Breakpoint) ( THIS_ IN PDEBUG_BREAKPOINT Bp );
;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;
}

all STDMETHODIMP are standard too

STDMETHODIMP EventCallbacks::Breakpoint( THIS_ IN PDEBUG_BREAKPOINT Bp )
{
return ProcessInput();
};

every callback is redirected to a single ugly function that does if
{retn stat} else if {{retn stat} else {{retn stat}

HRESULT ProcessInput (void)
{
ULONG InputSize = 0;

if (( g_Control->GetLastEventInformation(&type,&pid,&tid,NULL,NULL,NULL,Desc,sizeof(Desc),&descused)
) != S_OK)
{
Exit( 0,“GetLasteventFailed\n”);
}
if (( g_Control->GetExecutionStatus(&ExceStatus)) !=S_OK)
{
Exit( 0,“GetExecStatus Failed\n”);
}
if (type == DEBUG_EVENT_BREAKPOINT)
{
printf(“DEBUG_EVENT_BREAKPOINT EVENT\n”);
if (( g_Control->Input(Buff,(sizeof(Buff)-5),&InputSize) ) != S_OK)
{
Exit( 0,“g_Control->Input Failed\n”);
}
if(_strnicmp(Buff,“g”,1)==0)
{
return DEBUG_STATUS_GO; <------------ this GO seems to work
}

============================XXXXXXXXXXXX==========
else if ( (_strnicmp(Buff,“p”,1) == 0) && (ExceStatus ==
DEBUG_STATUS_BREAK) )
{
return DEBUG_STATUS_BREAK; nothing seems to work here
g_Control->Execute & WaitFor() fails
SetExecStatus & WaitFor() fails
return DEBUG_STATUS_STEP OVER fails
return DEBUG_STATUS_STEP INTO fails
return DEBUG_STATUS_BREAK fails

}

=========================XXXXXXXXXXXXXXXXXXXX===============

else if (_strnicmp(Buff,“bp”,2) == 0)
{
Buff[9] = 0;
HitBp = _strtoui64(&Buff[3],NULL,16);
if ( HitBp == 0)
{
printf(“offset not ok\n”);
}
else
{
g_Control->OutputDisassembly(DEBUG_OUTCTL_THIS_CLIENT,HitBp,DEBUG_DISASM_EFFECTIVE_ADDRESS
| DEBUG_DISASM_MATCHING_SYMBOLS ,&endoffset );
if (( Status =
g_Control->AddBreakpoint(DEBUG_BREAKPOINT_CODE,DEBUG_ANY_ID,&g_Breakpoint))
!= S_OK)
{
printf(“AddBp failed %x\n”,Status);
}
if (( Status = g_Breakpoint->SetOffset(HitBp)) != S_OK)
{
printf(“Setoffset failed %x\n”,Status);
}
if (( Status = g_Breakpoint->SetFlags(DEBUG_BREAKPOINT_ENABLED)) != S_OK)
{
printf(“SetFlags failed %x\n”,Status);
}
if (( Status = g_Breakpoint->SetCommand(“.echo This is a Bp From
Our Code”)) != S_OK)
{
printf(“SetCommand failed %x\n”,Status);
}
}
return ProcessInput(); <------------- adding bp works and gets hit too
}
else
{
printf(“not implemented\n”);
return ProcessInput(); <--------------- recursive and comes back
without problems
}
}
else if (type == DEBUG_EVENT_EXCEPTION)

how to instruct the engine to stepover or step in ???

a sample output

F:\test>dbgengdbg.exe msgbox.exe

Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: msgbox.exe
Symbol search path is: SRV*F:\symbols*http://msdl.microsoft.com/download/symbols

Executable search path is:
ModLoad: 00400000 00404000 msgbox.exe
DEBUG_EVENT_CREATE_PROCESS EVENT

0:000>bp 401000
DEBUG_EVENT_CREATE_PROCESS EVENT
0:000>g
ModLoad: 7c900000 7c9b2000 ntdll.dll

This is a Bp From Our Code
DEBUG_EVENT_BREAKPOINT EVENT
0:000>bp 401007
00401007 6819304000 push offset msgbox!MsgBoxText (00403019)
DEBUG_EVENT_BREAKPOINT EVENT
0:000>bp 401013
00401013 6a00 push 0
DEBUG_EVENT_BREAKPOINT EVENT
0:000>p <---------------- there is one instruction and it is skipped
because i returnd GO_HANDLED
This is a Bp From Our Code
DEBUG_EVENT_BREAKPOINT EVENT
0:000>p <--------------- behaves like GO

but if i return STEP_OVER or STEP_IN the debugger exits due to unhandled event

ModLoad: 5ad70000 5ada8000 C:\WINDOWS\system32\uxtheme.dll
ModLoad: 77c10000 77c68000 C:\WINDOWS\system32\msvcrt.dll
ModLoad: 77c00000 77c08000 C:\WINDOWS\system32\version.dll
ModLoad: 77b40000 77b62000 C:\WINDOWS\system32\apphelp.dll
ModLoad: 755c0000 755ee000 C:\WINDOWS\system32\msctfime.ime
ModLoad: 774e0000 7761d000 C:\WINDOWS\system32\ole32.dll
This is a Bp From Our Code
DEBUG_EVENT_BREAKPOINT EVENT
0:000>t
not implemented
DEBUG_EVENT_BREAKPOINT EVENT
0:000>g
no debugee quitting

F:\test>

On 1/10/13, raj_r wrote:
> i am trying to hack together a dbgeng based usermode only debugger and
> it seems i cant understand something very basic
>
> at the moment all i want is a printf() from CreateProcess event and
> return DEBUG_STATUS_BREAK
>
> add a bp on the AddrOfEntryPoint in a simple MessageBox.exe (invoke
> msgbox(); invoke ExitProc();
> Addr of EntryPoint is 0x401000 and i want to test bp here only (no
> complications reqd atm)
>
> the loadmod msgs will be passed to console via OutputCallbacks
>
> when the bp is hit Event callback is called for breakpoint
> and i Want to return back DEBUG_STATUS_STEP_OVER
>
> i have added
>
> class EventCallbacks : public DebugBaseEventCallbacks {
> addref,release,getinerestmask.bp,except,createproc,LoadMod,SessStat,ChgengStat}
> class StdioOutputCallbacks : public IDebugOutputCallbacks
> {Queryint,Addref,Release,Output}
> class StdioInputCallbacks : public IDebugInputCallbacks
> {QI,Ar,Rel,StartIn,Endin}
>
> in
> STDMETHODIMP EvtCb::Bp( Bp ) {printf(“EventCallbacks::Breakpoint Id %x
> %I64x\n”,Id,dbgbpparm.Offset); GO_HAND}
> STDMETHODIMP EvtCb::Cp(…) {printf (“EventCallbacks::CreateProcess
> ImageName %s\n”,ImageName);STAT_BREAK}
> STDMETHODIMP EvtCb::Lm(…) {NO_CHANGE}
> STDMETHODIMP EvtCb::Exce(…) {printf (“…”);GO_HAND}
> STDMETHODIMP EvtCb::SessStat(…) {printf (“…”);S_OK}
> STDMETHODIMP EvtCb::ChgEngStat(…) {printf (“…”);S_OK}
>
> STDMETHODIMP OutCb::Output(…) {fput();S_OK}
>
> STDMETHODIMP InCb::StartIn(…) {fgets();S_OK}
> STDMETHODIMP InCb::EndIn(…) {void;S_OK}
>
> in main() {
> create_interfaces( for
> IDbgClient,IdbgControl,IdbgdataSapces,IdebugReg,IdebugSym)
> SetEvetCb (event)
> Createprocess(…,dbg_only_this);
> SetOutCb(out)
> SetInCb(in)
>
> EvtLoop();
> Exit()
> }
>
> now i get the createproc printf
> but i dont seem to be called in any of the callbacks for DEBUG_STATUS_BREAK
>
> and i land up in unhandled event in my event loop
>
> which looks like this
>
> plese dont nit pick this crap code for dots and crosses i just want
> ideas or concept
>
> th sample healer and remmon loops have comments that we shouldnt
> normally land here
> so wher should i land where do i add my bp and how to handle the break
>
> void
> EventLoop(void)
> {
> HRESULT Status;
> ULONG type,pid,tid;
> char Desc[0x20];
> BYTE extinf[0x30];
> ULONG64 endoffset;
> ULONG64 bpoffset = 0x401000;
> ULONG ExecStatus;
>
> for (;:wink:
> {
> if ((Status = g_Control->WaitForEvent(DEBUG_WAIT_DEFAULT,
> INFINITE)) != S_OK)
> {
> ULONG ExecStatus;
>
> if (g_Control->GetExecutionStatus(&ExecStatus) == S_OK &&
> ExecStatus == DEBUG_STATUS_NO_DEBUGGEE)
> {
> // The session ended so we can quit.
> break;
> }
>
> // There was a real error.
> Exit(1, “WaitForEvent failed, 0x%X\n”, Status);
> }
>
> according to windbg sdk sample i shouldnt be here unless i have an
> unhandled event
>
> g_Control->GetLastEventInformation(&type,&pid,&tid,(PVOID)&extinf,0x30,NULL,(PSTR)Desc,0x20,NULL);
> printf(“we have broken into the target due to event %x %s\n”,type,Desc);
>
> g_Control->OutputDisassembly(DEBUG_OUTCTL_THIS_CLIENT,dbgbpparm.Offset,DEBUG_DISASM_EFFECTIVE_ADDRESS,&endoffset);
>
> if (( Status =
> g_Control->AddBreakpoint(DEBUG_BREAKPOINT_CODE,DEBUG_ANY_ID,&g_Breakpoint))
> != S_OK)
> {
> printf(“AddBp failed %x\n”,Status);
> }
> if (( Status = g_Breakpoint->SetOffset(bpoffset)) != S_OK)
> {
> printf(“Setoffset failed %x\n”,Status);
> }
> if (( Status = g_Breakpoint->SetFlags(DEBUG_BREAKPOINT_ENABLED)) != S_OK)
> {
> printf(“SetFlags failed %x\n”,Status);
> }
> if (( Status = g_Breakpoint->SetCommand(“.echo This is a Bp From Our
> Code”)) != S_OK)
> {
> printf(“SetCommand failed %x\n”,Status);
> }
>
> if ((Status = g_Control->
> SetExecutionStatus(DEBUG_STATUS_GO_HANDLED)) != S_OK)
> {
> Exit(1, “SetExecutionStatus failed, 0x%X\n”, Status);
> }
> }
> }
>
>
>
> my output from compiled binary as follows
>
>
>
> foo:&gt;dbgengdbg.exe msgbox.exe
> wtf2
> EventCallbacks::SessionStatus = 0
> Symbol search path is:
> SRVF:\symbolshttp://msdl.microsoft.com/download/symbols
>
> Executable search path is:
> ModLoad: 00400000 00404000 msgbox.exe
> EventCallbacks::CreateProcess ImageName msgbox.exe
> wtf2
> we have broken into the target due to event 10 Create process 0:9b0
> 00000000 ?? ???
> wtf2
> wtf2
> ModLoad: 7c900000 7c9b2000 ntdll.dll
> wtf2
> ModLoad: 7c800000 7c8f6000 C:\WINDOWS\system32\kernel32.dll
> wtf2
> ModLoad: 64d00000 64d3c000 C:\Program Files\Alwil
> Software\Avast5\snxhk.dll
> wtf2
> ModLoad: 7e410000 7e4a1000 C:\WINDOWS\system32\user32.dll
> wtf2
> ModLoad: 77f10000 77f59000 C:\WINDOWS\system32\GDI32.dll
> wtf2
> wtf2
> ModLoad: 5cb70000 5cb96000 C:\WINDOWS\system32\ShimEng.dll
> wtf2
> ModLoad: 76390000 763ad000 C:\WINDOWS\system32\IMM32.DLL
> wtf2
> ModLoad: 77dd0000 77e6b000 C:\WINDOWS\system32\ADVAPI32.dll
> wtf2
> ModLoad: 77e70000 77f02000 C:\WINDOWS\system32\RPCRT4.dll
> wtf2
> ModLoad: 77fe0000 77ff1000 C:\WINDOWS\system32\Secur32.dll
> wtf2
> This is a Bp From Our Code
> EventCallbacks::Breakpoint Id 0 401000
> wtf2
> wtf2
> we have broken into the target due to event 0
> 00401000 6a00 push 0
> Breakpoints 1 and 0 match
> wtf2
> wtf2
> ModLoad: 5ad70000 5ada8000 C:\WINDOWS\system32\uxtheme.dll
> wtf2
> ModLoad: 77c10000 77c68000 C:\WINDOWS\system32\msvcrt.dll
> wtf2
> ModLoad: 77c00000 77c08000 C:\WINDOWS\system32\version.dll
> wtf2
> ModLoad: 77b40000 77b62000 C:\WINDOWS\system32\apphelp.dll
> wtf2
> ModLoad: 755c0000 755ee000 C:\WINDOWS\system32\msctfime.ime
> wtf2
> ModLoad: 774e0000 7761d000 C:\WINDOWS\system32\ole32.dll
> wtf2
> wtf2
> EventCallbacks::SessionStatus = 4
> wtf2
>
> foo:&gt;dbgengdbg.exe msgbox.exe
> wtf2
> EventCallbacks::SessionStatus = 0
> Symbol search path is:
> SRVF:\symbolshttp://msdl.microsoft.com/download/symbols
>
> Executable search path is:
> ModLoad: 00400000 00404000 msgbox.exe
> EventCallbacks::CreateProcess ImageName msgbox.exe
> wtf2
> we have broken into the target due to event 10 Create process 0:488
> <--------- unhandled ? dont we land in Exception Callback ?
> 00000000 ?? ???
> wtf2
> wtf2
> ModLoad: 7c900000 7c9b2000 ntdll.dll
> wtf2
> ModLoad: 7c800000 7c8f6000 C:\WINDOWS\system32\kernel32.dll
> wtf2
> ModLoad: 64d00000 64d3c000 C:\Program Files\Alwil
> Software\Avast5\snxhk.dll
> wtf2
> ModLoad: 7e410000 7e4a1000 C:\WINDOWS\system32\user32.dll
> wtf2
> ModLoad: 77f10000 77f59000 C:\WINDOWS\system32\GDI32.dll
> wtf2
> wtf2
> ModLoad: 5cb70000 5cb96000 C:\WINDOWS\system32\ShimEng.dll
> wtf2
> ModLoad: 76390000 763ad000 C:\WINDOWS\system32\IMM32.DLL
> wtf2
> ModLoad: 77dd0000 77e6b000 C:\WINDOWS\system32\ADVAPI32.dll
> wtf2
> ModLoad: 77e70000 77f02000 C:\WINDOWS\system32\RPCRT4.dll
> wtf2
> ModLoad: 77fe0000 77ff1000 C:\WINDOWS\system32\Secur32.dll
> wtf2
> This is a Bp From Our Code <---------- the bp seems to be hit :slight_smile: from
> our unhandled code ???
> EventCallbacks::Breakpoint Id 0 401000 <-------------------------
> wtf2
> wtf2
> we have broken into the target due to event 0
> 00401000 6a00 push 0
> Breakpoints 1 and 0 match <---------------------- yes this is crap we
> should spin on it but not real concern atm
> wtf2
> wtf2
> ModLoad: 5ad70000 5ada8000 C:\WINDOWS\system32\uxtheme.dll
> wtf2
> ModLoad: 77c10000 77c68000 C:\WINDOWS\system32\msvcrt.dll
> wtf2
> ModLoad: 77c00000 77c08000 C:\WINDOWS\system32\version.dll
> wtf2
> ModLoad: 77b40000 77b62000 C:\WINDOWS\system32\apphelp.dll
> wtf2
> ModLoad: 755c0000 755ee000 C:\WINDOWS\system32\msctfime.ime
> wtf2
> ModLoad: 774e0000 7761d000 C:\WINDOWS\system32\ole32.dll
>
> the exe starts running here what happend to the int 3 ?? dont we crash ?
> who eats my excpetion ?? how can i eat my own break ???
> wtf2
> wtf2
> EventCallbacks::SessionStatus = 4 DEBUG_END_SESSION PASSIVE How
> ??? who gave the permission ??
> wtf2
>
> foo:&gt;
>

Doesn’t “sxe” command of WinDbg work for you?

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-523548-
xxxxx@lists.osr.com] On Behalf Of raj_r
Sent: Monday, January 14, 2013 5:45 PM
To: Kernel Debugging Interest List
Subject: Re:[windbg] how does the Callbacks work in a dbgeng based
debugger

no idea why i am almost always unlucky when i ask a question
does anybody have any idea how to either single step or step over in
the callbacks ??

snippets

void __cdecl main(int Argc, char* Argv)
{
if (Argc != 2)
{
Exit(0, “provide path of exe\n”);
}

CreateInterfaces();
HRESULT Status = 0;
if (
((Status = g_Client->SetEventCallbacks (&g_EventCb)) !=
S_OK) ||
((Status = g_Client->SetOutputCallbacks
(&g_OutputCb)) != S_OK) ||
((Status = g_Client->SetInputCallbacks (&g_InputCb)) !=
S_OK)
)
{
Exit(1, “Setting of Callbacks failed\n”);
}
if ((Status = g_Client->CreateProcess(0, Argv[1],
DEBUG_ONLY_THIS_PROCESS)) != S_OK)
{
Exit(1, “CreateProcess failed, 0x%X\n”, Status);
}
EventLoop();
Exit(0, NULL);
}

the event loop as follows

void EventLoop(void)
{
HRESULT Status;
ULONG ExecStatus;
for (;:wink:
{
if ((Status = g_Control-
>WaitForEvent(DEBUG_WAIT_DEFAULT,
INFINITE)) != S_OK)
{
ULONG ExecStatus;
if (g_Control->GetExecutionStatus(&ExecStatus) ==
S_OK &&
ExecStatus ==
DEBUG_STATUS_NO_DEBUGGEE)
{
printf(“no debugee quitting\n”);
break;
}
Exit(1, “WaitForEvent failed, 0x%X\n”, Status);
}
Exit(1, “Unhandled event we should not land here exiting\n”);

}
}

when i either single step (t) or step over (p)
i land at

Exit(1, “Unhandled event we should not land here exiting\n”);

can someone point out why ?

the classes (event,output and input) are pretty standard

class EventCallbacks : public DebugBaseEventCallbacks
{
public:
STDMETHOD_(ULONG, AddRef) ( THIS );
STDMETHOD_(ULONG, Release) ( THIS );
STDMETHOD(Breakpoint) ( THIS_ IN
PDEBUG_BREAKPOINT Bp );
;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;
}

all STDMETHODIMP are standard too

STDMETHODIMP EventCallbacks::Breakpoint( THIS_ IN
PDEBUG_BREAKPOINT Bp )
{
return ProcessInput();
};

every callback is redirected to a single ugly function that does if
{retn stat} else if {{retn stat} else {{retn stat}

HRESULT ProcessInput (void)
{
ULONG InputSize = 0;

if (( g_Control-
>GetLastEventInformation(&type,&pid,&tid,NULL,NULL,NULL,Desc,sizeof(D
esc),&descused)
) != S_OK)
{
Exit( 0,“GetLasteventFailed\n”);
}
if (( g_Control->GetExecutionStatus(&ExceStatus)) !=S_OK)
{
Exit( 0,“GetExecStatus Failed\n”);
}
if (type == DEBUG_EVENT_BREAKPOINT)
{
printf(“DEBUG_EVENT_BREAKPOINT EVENT\n”);
if (( g_Control->Input(Buff,(sizeof(Buff)-5),&InputSize) ) !=
S_OK)
{
Exit( 0,“g_Control->Input Failed\n”);
}
if(_strnicmp(Buff,“g”,1)==0)
{
return DEBUG_STATUS_GO; <------------ this GO
seems to work
}

============================XXXXXXXXXXXX==========
else if ( (_strnicmp(Buff,“p”,1) == 0) && (ExceStatus ==
DEBUG_STATUS_BREAK) )
{
return DEBUG_STATUS_BREAK; nothing seems to
work here
g_Control->Execute & WaitFor() fails
SetExecStatus & WaitFor() fails
return DEBUG_STATUS_STEP OVER fails
return DEBUG_STATUS_STEP INTO fails
return DEBUG_STATUS_BREAK fails

}

=========================XXXXXXXXXXXXXXXXXXXX=============

else if (_strnicmp(Buff,“bp”,2) == 0)
{
Buff[9] = 0;
HitBp = strtoui64(&Buff[3],NULL,16);
if ( HitBp == 0)
{
printf(“offset not ok\n”);
}
else
{
g_Control-
>OutputDisassembly(DEBUG_OUTCTL_THIS_CLIENT,HitBp,DEBUG_DISASM

EFFECTIVE_ADDRESS
| DEBUG_DISASM_MATCHING_SYMBOLS ,&endoffset );
if (( Status =
g_Control-
>AddBreakpoint(DEBUG_BREAKPOINT_CODE,DEBUG_ANY_ID,&g_Breakpoi
nt))
!= S_OK)
{
printf(“AddBp failed %x\n”,Status);
}
if (( Status = g_Breakpoint-
>SetOffset(HitBp)) != S_OK)
{
printf(“Setoffset failed %x\n”,Status);
}
if (( Status = g_Breakpoint-
>SetFlags(DEBUG_BREAKPOINT_ENABLED)) != S_OK)
{
printf(“SetFlags failed %x\n”,Status);
}
if (( Status = g_Breakpoint-
>SetCommand(“.echo This is a Bp From
Our Code”)) != S_OK)
{
printf(“SetCommand
failed %x\n”,Status);
}
}
return ProcessInput(); <------------- adding bp works
and gets hit too
}
else
{
printf(“not implemented\n”);
return ProcessInput(); <--------------- recursive and
comes back
without problems
}
}
else if (type == DEBUG_EVENT_EXCEPTION)

how to instruct the engine to stepover or step in ???

a sample output

F:\test>dbgengdbg.exe msgbox.exe

Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: msgbox.exe
Symbol search path is:
SRV*F:\symbols*http://msdl.microsoft.com/download/symbols

Executable search path is:
ModLoad: 00400000 00404000 msgbox.exe
DEBUG_EVENT_CREATE_PROCESS EVENT

0:000>bp 401000
DEBUG_EVENT_CREATE_PROCESS EVENT
0:000>g
ModLoad: 7c900000 7c9b2000 ntdll.dll

This is a Bp From Our Code
DEBUG_EVENT_BREAKPOINT EVENT
0:000>bp 401007
00401007 6819304000 push offset msgbox!MsgBoxText (00403019)
DEBUG_EVENT_BREAKPOINT EVENT
0:000>bp 401013
00401013 6a00 push 0
DEBUG_EVENT_BREAKPOINT EVENT
0:000>p <---------------- there is one instruction and it is skipped
because i returnd GO_HANDLED
This is a Bp From Our Code
DEBUG_EVENT_BREAKPOINT EVENT
0:000>p <--------------- behaves like GO

but if i return STEP_OVER or STEP_IN the debugger exits due to unhandled
event

ModLoad: 5ad70000 5ada8000 C:\WINDOWS\system32\uxtheme.dll
ModLoad: 77c10000 77c68000 C:\WINDOWS\system32\msvcrt.dll
ModLoad: 77c00000 77c08000 C:\WINDOWS\system32\version.dll
ModLoad: 77b40000 77b62000 C:\WINDOWS\system32\apphelp.dll
ModLoad: 755c0000 755ee000 C:\WINDOWS\system32\msctfime.ime
ModLoad: 774e0000 7761d000 C:\WINDOWS\system32\ole32.dll
This is a Bp From Our Code
DEBUG_EVENT_BREAKPOINT EVENT
0:000>t
not implemented
DEBUG_EVENT_BREAKPOINT EVENT
0:000>g
no debugee quitting

F:\test>

On 1/10/13, raj_r wrote:
> > i am trying to hack together a dbgeng based usermode only debugger and
> > it seems i cant understand something very basic
> >
> > at the moment all i want is a printf() from CreateProcess event and
> > return DEBUG_STATUS_BREAK
> >
> > add a bp on the AddrOfEntryPoint in a simple MessageBox.exe (invoke
> > msgbox(); invoke ExitProc();
> > Addr of EntryPoint is 0x401000 and i want to test bp here only (no
> > complications reqd atm)
> >
> > the loadmod msgs will be passed to console via OutputCallbacks
> >
> > when the bp is hit Event callback is called for breakpoint
> > and i Want to return back DEBUG_STATUS_STEP_OVER
> >
> > i have added
> >
> > class EventCallbacks : public DebugBaseEventCallbacks {
> >
> addref,release,getinerestmask.bp,except,createproc,LoadMod,SessStat,Chg
> engStat}
> > class StdioOutputCallbacks : public IDebugOutputCallbacks
> > {Queryint,Addref,Release,Output}
> > class StdioInputCallbacks : public IDebugInputCallbacks
> > {QI,Ar,Rel,StartIn,Endin}
> >
> > in
> > STDMETHODIMP EvtCb::Bp( Bp ) {printf(“EventCallbacks::Breakpoint Id %x
> > %I64x\n”,Id,dbgbpparm.Offset); GO_HAND}
> > STDMETHODIMP EvtCb::Cp(…) {printf (“EventCallbacks::CreateProcess
> > ImageName %s\n”,ImageName);STAT_BREAK}
> > STDMETHODIMP EvtCb::Lm(…) {NO_CHANGE}
> > STDMETHODIMP EvtCb::Exce(…) {printf (“…”);GO_HAND}
> > STDMETHODIMP EvtCb::SessStat(…) {printf (“…”);S_OK}
> > STDMETHODIMP EvtCb::ChgEngStat(…) {printf (“…”);S_OK}
> >
> > STDMETHODIMP OutCb::Output(…) {fput();S_OK}
> >
> > STDMETHODIMP InCb::StartIn(…) {fgets();S_OK}
> > STDMETHODIMP InCb::EndIn(…) {void;S_OK}
> >
> > in main() {
> > create_interfaces( for
> > IDbgClient,IdbgControl,IdbgdataSapces,IdebugReg,IdebugSym)
> > SetEvetCb (event)
> > Createprocess(…,dbg_only_this);
> > SetOutCb(out)
> > SetInCb(in)
> >
> > EvtLoop();
> > Exit()
> > }
> >
> > now i get the createproc printf
> > but i dont seem to be called in any of the callbacks for
> DEBUG_STATUS_BREAK
> >
> > and i land up in unhandled event in my event loop
> >
> > which looks like this
> >
> > plese dont nit pick this crap code for dots and crosses i just want
> > ideas or concept
> >
> > th sample healer and remmon loops have comments that we shouldnt
> > normally land here
> > so wher should i land where do i add my bp and how to handle the break
> >
> > void
> > EventLoop(void)
> > {
> > HRESULT Status;
> > ULONG type,pid,tid;
> > char Desc[0x20];
> > BYTE extinf[0x30];
> > ULONG64 endoffset;
> > ULONG64 bpoffset = 0x401000;
> > ULONG ExecStatus;
> >
> > for (;:wink:
> > {
> > if ((Status = g_Control-
> >WaitForEvent(DEBUG_WAIT_DEFAULT,
> > INFINITE)) != S_OK)
> > {
> > ULONG ExecStatus;
> >
> > if (g_Control->GetExecutionStatus(&ExecStatus) ==
> S_OK &&
> > ExecStatus ==
> DEBUG_STATUS_NO_DEBUGGEE)
> > {
> > // The session ended so we can quit.
> > break;
> > }
> >
> > // There was a real error.
> > Exit(1, “WaitForEvent failed, 0x%X\n”, Status);
> > }
> >
> > according to windbg sdk sample i shouldnt be here unless i have an
> > unhandled event
> >
> > g_Control-
> >GetLastEventInformation(&type,&pid,&tid,(PVOID)&extinf,0x30,NULL,(PST
> R)Desc,0x20,NULL);
> > printf(“we have broken into the target due to
> event %x %s\n”,type,Desc);
> >
> > g_Control-
> >OutputDisassembly(DEBUG_OUTCTL_THIS_CLIENT,dbgbpparm.Offset,DEB
> UG_DISASM_EFFECTIVE_ADDRESS,&endoffset);
> >
> > if (( Status =
> > g_Control-
> >AddBreakpoint(DEBUG_BREAKPOINT_CODE,DEBUG_ANY_ID,&g_Breakpoi
> nt))
> > != S_OK)
> > {
> > printf(“AddBp failed %x\n”,Status);
> > }
> > if (( Status = g_Breakpoint->SetOffset(bpoffset)) != S_OK)
> > {
> > printf(“Setoffset failed %x\n”,Status);
> > }
> > if (( Status = g_Breakpoint-
> >SetFlags(DEBUG_BREAKPOINT_ENABLED)) != S_OK)
> > {
> > printf(“SetFlags failed %x\n”,Status);
> > }
> > if (( Status = g_Breakpoint->SetCommand(“.echo This is a Bp
> From Our
> > Code”)) != S_OK)
> > {
> > printf(“SetCommand failed %x\n”,Status);
> > }
> >
> > if ((Status = g_Control->
> >
> SetExecutionStatus(DEBUG_STATUS_GO_HANDLED)) != S_OK)
> > {
> > Exit(1, “SetExecutionStatus failed, 0x%X\n”, Status);
> > }
> > }
> > }
> >
> >
> >
> > my output from compiled binary as follows
> >
> >
> >
> > foo:&gt;dbgengdbg.exe msgbox.exe
> > wtf2
> > EventCallbacks::SessionStatus = 0
> > Symbol search path is:
> > SRVF:\symbolshttp://msdl.microsoft.com/download/symbols
> >
> > Executable search path is:
> > ModLoad: 00400000 00404000 msgbox.exe
> > EventCallbacks::CreateProcess ImageName msgbox.exe
> > wtf2
> > we have broken into the target due to event 10 Create process 0:9b0
> > 00000000 ?? ???
> > wtf2
> > wtf2
> > ModLoad: 7c900000 7c9b2000 ntdll.dll
> > wtf2
> > ModLoad: 7c800000 7c8f6000 C:\WINDOWS\system32\kernel32.dll
> > wtf2
> > ModLoad: 64d00000 64d3c000 C:\Program Files\Alwil
> > Software\Avast5\snxhk.dll
> > wtf2
> > ModLoad: 7e410000 7e4a1000 C:\WINDOWS\system32\user32.dll
> > wtf2
> > ModLoad: 77f10000 77f59000 C:\WINDOWS\system32\GDI32.dll
> > wtf2
> > wtf2
> > ModLoad: 5cb70000 5cb96000 C:\WINDOWS\system32\ShimEng.dll
> > wtf2
> > ModLoad: 76390000 763ad000 C:\WINDOWS\system32\IMM32.DLL
> > wtf2
> > ModLoad: 77dd0000 77e6b000 C:\WINDOWS\system32\ADVAPI32.dll
> > wtf2
> > ModLoad: 77e70000 77f02000 C:\WINDOWS\system32\RPCRT4.dll
> > wtf2
> > ModLoad: 77fe0000 77ff1000 C:\WINDOWS\system32\Secur32.dll
> > wtf2
> > This is a Bp From Our Code
> > EventCallbacks::Breakpoint Id 0 401000
> > wtf2
> > wtf2
> > we have broken into the target due to event 0
> > 00401000 6a00 push 0
> > Breakpoints 1 and 0 match
> > wtf2
> > wtf2
> > ModLoad: 5ad70000 5ada8000 C:\WINDOWS\system32\uxtheme.dll
> > wtf2
> > ModLoad: 77c10000 77c68000 C:\WINDOWS\system32\msvcrt.dll
> > wtf2
> > ModLoad: 77c00000 77c08000 C:\WINDOWS\system32\version.dll
> > wtf2
> > ModLoad: 77b40000 77b62000 C:\WINDOWS\system32\apphelp.dll
> > wtf2
> > ModLoad: 755c0000 755ee000 C:\WINDOWS\system32\msctfime.ime
> > wtf2
> > ModLoad: 774e0000 7761d000 C:\WINDOWS\system32\ole32.dll
> > wtf2
> > wtf2
> > EventCallbacks::SessionStatus = 4
> > wtf2
> >
> > foo:&gt;dbgengdbg.exe msgbox.exe
> > wtf2
> > EventCallbacks::SessionStatus = 0
> > Symbol search path is:
> > SRVF:\symbolshttp://msdl.microsoft.com/download/symbols
> >
> > Executable search path is:
> > ModLoad: 00400000 00404000 msgbox.exe
> > EventCallbacks::CreateProcess ImageName msgbox.exe
> > wtf2
> > we have broken into the target due to event 10 Create process 0:488
> > <--------- unhandled ? dont we land in Exception Callback ?
> > 00000000 ?? ???
> > wtf2
> > wtf2
> > ModLoad: 7c900000 7c9b2000 ntdll.dll
> > wtf2
> > ModLoad: 7c800000 7c8f6000 C:\WINDOWS\system32\kernel32.dll
> > wtf2
> > ModLoad: 64d00000 64d3c000 C:\Program Files\Alwil
> > Software\Avast5\snxhk.dll
> > wtf2
> > ModLoad: 7e410000 7e4a1000 C:\WINDOWS\system32\user32.dll
> > wtf2
> > ModLoad: 77f10000 77f59000 C:\WINDOWS\system32\GDI32.dll
> > wtf2
> > wtf2
> > ModLoad: 5cb70000 5cb96000 C:\WINDOWS\system32\ShimEng.dll
> > wtf2
> > ModLoad: 76390000 763ad000 C:\WINDOWS\system32\IMM32.DLL
> > wtf2
> > ModLoad: 77dd0000 77e6b000 C:\WINDOWS\system32\ADVAPI32.dll
> > wtf2
> > ModLoad: 77e70000 77f02000 C:\WINDOWS\system32\RPCRT4.dll
> > wtf2
> > ModLoad: 77fe0000 77ff1000 C:\WINDOWS\system32\Secur32.dll
> > wtf2
> > This is a Bp From Our Code <---------- the bp seems to be hit :slight_smile: from
> > our unhandled code ???
> > EventCallbacks::Breakpoint Id 0 401000 <-------------------------
> > wtf2
> > wtf2
> > we have broken into the target due to event 0
> > 00401000 6a00 push 0
> > Breakpoints 1 and 0 match <---------------------- yes this is crap we
> > should spin on it but not real concern atm
> > wtf2
> > wtf2
> > ModLoad: 5ad70000 5ada8000 C:\WINDOWS\system32\uxtheme.dll
> > wtf2
> > ModLoad: 77c10000 77c68000 C:\WINDOWS\system32\msvcrt.dll
> > wtf2
> > ModLoad: 77c00000 77c08000 C:\WINDOWS\system32\version.dll
> > wtf2
> > ModLoad: 77b40000 77b62000 C:\WINDOWS\system32\apphelp.dll
> > wtf2
> > ModLoad: 755c0000 755ee000 C:\WINDOWS\system32\msctfime.ime
> > wtf2
> > ModLoad: 774e0000 7761d000 C:\WINDOWS\system32\ole32.dll
> >
> > the exe starts running here what happend to the int 3 ?? dont we crash ?
> > who eats my excpetion ?? how can i eat my own break ???
> > wtf2
> > wtf2
> > EventCallbacks::SessionStatus = 4 DEBUG_END_SESSION PASSIVE How
> > ??? who gave the permission ??
> > wtf2
> >
> > foo:&gt;
> >
>
> —
> WINDBG is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer