For a homemade debugging tool built as a VS add-in, I need to:
break at some arbitrary point in my application
call into another method and break there (without adding code in that spot before runtime)
run some other command from my VS add-in at that second breakpoint
My first instinct on how to do this hit a wall at Hans' excellent answer here.
My second idea would be to set up the call to the other method from the breakpoint and have it execute when the application is allowed to continue (if you can see another way to do what I need, feel free to point it out, though !).
This would be trivial with WinDBG : just use .call and go. Unfortunately, I need to do this in Visual Studio.
Hence my question : is there some way to do this in VS ? I cannot find an equivalent to .call, nor a way to manipulate the registers and stack and emulate .call myself.
After some investigation, I believe the answer to this question is: there is no equivalent to .call in VS.
The only solution is to emulate the behavior of .call yourself by manipulating the stack pointer, instruction pointer, etc. This will obviously have limitations, e.g. mine will only work for the Microsoft x64 calling convention. Conversion to x86 and its myriad of calling conventions is left as an exercise for the reader ;)
Depending on your actual need, I have found two ways to do this. Remember, this is for calling into a function the next time the debuggee runs (so that you can break into it, since nested breakpoints are not supported). If you just need to call a function without breaking again, you are much better off just using the Immediate window to call it directly !
The easy way:
This will trick VS into thinking the current frame is in a DLL and method of your choosing. This is useful is the Expression Evaluator does not want to work in the DLL you are stopped in and needs to be in a different one.
WARNING: You cannot actually execute the method call you are faking without corrupting your stack (unless the method you are calling is very simple and you are very lucky).
Use the following to do this directly in the debugger via the Immediate window:
#rsp=#rsp-8
*((__int64*)$rsp)=#rip
#rip={,,<DLL to jump in.dll>}<method to call>
Now VS sees the DLL and method you specified as your current frame. Once you are done, use the following to return to the previous state:
#rip=*((__int64*)$rsp)
#rsp=#rsp+8
This can also be automated in a VS add-in by running these statements through EnvDTE.Debugger.GetExpression(), as demonstrated with the other method below.
The hard way:
This will work for actually calling the DLL and function you want and later returning from it cleanly. It is more complicated and more dangerous; any mistake will corrupt your stack.
It is also harder to get right for both debug and release mode, since the optimizer might have done complex things you were not expecting with the code of your callee and caller.
The idea is to emulate the Microsoft x64 calling convention (documented here) and break in the function called. We need to do the following things:
push parameters beyond the first 4 to the stack, in right to left order
create the shadow space on the stack(1)
push the return address, i.e. the current value of RIP
set RIP to the address of the function to call, just like above
save all the registers that the callee may change, and the caller might not expect to change. This basically means saving everything marked 'volatile'here.
set a breakpoint in the callee
run the debuggee
when the debuggee breaks again, perform whatever operations we want
step out
restore the saved registers
return RSP to the correct location (i.e. tear down the shadow space)
remove the breakpoint
(1) 32 bytes of scratch space for the callee to spill the first 4 arguments that are passed by registers (usually; the callee can actually use this however it likes).
Here is a simplified chunk of my VS addin to do this for a very basic case (non member function taking one parameter set to 0 and not touching too many registers). Anything beyond this is again left as an exercise for the reader ;)
EnvDTE90a.Debugger4 dbg = (EnvDTE90a.Debugger4)DTE.Debugger;
string method = "{,,dllname.dll}function";
string RAX = null, RCX = null, flags = null;
// get the address of the function to call and the address to break at (function address + a bit, to skip some prolog and help our breakpoint actually hit)
Expression expr = dbg.GetExpression3(method, dbg.CurrentThread.StackFrames.Item(1), false, false, false, 0);
string addr = expr.Value;
string addrToBreak = (UInt64.Parse(addr.Substring(2), NumberStyles.HexNumber) + 2).ToString();
if (!expr.IsValidValue)
return;
// set a breakpoint in the function to jump into
EnvDTE.Breakpoints bpsAdded = dbg.Breakpoints.Add("", "", 0, 0, "", dbgBreakpointConditionType.dbgBreakpointConditionTypeWhenTrue, "c++", "", 0, addrToBreak, 0, dbgHitCountType.dbgHitCountTypeNone);
if (bpsAdded.Count != 1)
return;
// set up the shadow space and parameter space
// NB: for 1 parameter : 4 words of shadow space, no further parameters... BUT, since the stack needs to be 16 BYTES aligned (i.e. 2 words) and the return address takes a single word, we need to offset by 5 !
dbg.GetExpression3("#rsp=#rsp-8*5", dbg.CurrentStackFrame, false, true, false, 0);
// set up the return address
dbg.GetExpression3("#rsp=#rsp-8*1", dbg.CurrentStackFrame, false, true, false, 0);
dbg.GetExpression3("*((__int64*)$rsp)=#rip", dbg.CurrentStackFrame, false, true, false, 0);
// save the registers
RAX = dbg.GetExpression3("#rax", dbg.CurrentStackFrame, false, true, false, 0).Value;
RCX = dbg.GetExpression3("#rcx", dbg.CurrentStackFrame, false, true, false, 0).Value;
// save the flags
flags = dbg.GetExpression3("#efl", dbg.CurrentStackFrame, false, true, false, 0).Value;
// set up the parameter for the call
dbg.GetExpression3("#rcx=0x0", dbg.CurrentStackFrame, false, true, false, 0);
// set the instruction pointer to our target function
dbg.GetExpression3("#rip=" + addr, dbg.CurrentStackFrame, false, true, false, 0);
dbg.Go(true);
// DO SOMETHING USEFUL HERE ! ;)
dbg.StepOut(true);
// restore all registers
dbg.GetExpression3("#rax=" + RAX, dbg.CurrentStackFrame, false, true, false, 0);
dbg.GetExpression3("#rcx=" + RCX, dbg.CurrentStackFrame, false, true, false, 0);
// restore flags
dbg.GetExpression3("#efl=" + flags, dbg.CurrentStackFrame, false, true, false, 0);
// tear down the shadow space
dbg.GetExpression3("#rsp=#rsp+8*5", dbg.CurrentStackFrame, false, true, false, 0);
}
Related
After successfully building a trampoline and learning more about process memory space, I tested the trampoline on MessageBoxA. It worked perfectly so I decided to finally put the code to the use it was supposed to be for in the first place, hiding a process by hooking NtQuerySystemInformation. The redirect function should work fine, but the code I used to write the jmp instruction now causes the task manager to crash every time.
BYTE tmpJMP[5] = {0xE9,0x00,0x00,0x00,0x00}; //jmp,A,D,D,R
memcpy(JMP,tmpJMP,5);
DWORD Addr = ((DWORD)func - ((DWORD)oNtQuerySystemInformation + 0x5));
for (int i=0;i<4;++i)
JMP[i+1] = ((BYTE*)&Addr)[i];
if (VirtualProtect((LPVOID)oNtQuerySystemInformation,5,PAGE_EXECUTE_READWRITE,&oldProtect) == FALSE)
MessageBox(NULL,L"Error unprotecting memory",L"",MB_OK);
memcpy(oldBytes,(LPVOID)oNtQuerySystemInformation,5);
if (!WriteProcessMemory(GetCurrentProcess(),(LPVOID)oNtQuerySystemInformation,(LPCVOID)JMP,5,NULL))
MessageBox(NULL,L"Unable to write to process memory space",L"",MB_OK);
VirtualProtect((LPVOID)oNtQuerySystemInformation,5,oldProtect,NULL);
FlushInstructionCache(GetCurrentProcess(),NULL,NULL);
I'm writing to the memory as such. I can't seem to find a problem with the code. I was thinking that maybe the memory changes from API to API but I was told that's incorrect, making me all out confused. Is there anything wrong that you all see? Please be descriptive. I love to learn o3o
I've got some code to create a new desktop and launch a process into that desktop.
One a few select Windows XP machines, when this code runs, I can see it switch to the new desktop and start the process, but almost immediately, the desktop switches back to the normal desktop.
This code works fine on about 98% of machines, and I can't seem to isolate any reason for this not working on the others.
Should SwitchDesktop be reliable? Can I hook calls to SwitchDesktop that might be called from another application?
My code:
int DLL_EXP_IMP WINAPI Process_Desktop(char *szDesktopName, char *szPath)
{
HDESK hOriginalThread;
HDESK hOriginalInput;
HDESK hNewDesktop;
int procSuccess;
// Save original ...
hOriginalThread = GetThreadDesktop(GetCurrentThreadId());
hOriginalInput = OpenInputDesktop(0, FALSE, DESKTOP_SWITCHDESKTOP);
// Create a new Desktop and switch to it
hNewDesktop = CreateDesktop(szDesktopName, NULL, NULL, DF_ALLOWOTHERACCOUNTHOOK, GENERIC_ALL, NULL);
SetThreadDesktop(hNewDesktop);
SwitchDesktop(hNewDesktop);
// This call blocks until the process exits, and is confirmed to work on the affected machines
procSuccess = StartProcess(szDesktopName, szPath);
// Restore original ...
SwitchDesktop(hOriginalInput);
SetThreadDesktop(hOriginalThread);
// Close the Desktop
CloseDesktop(hNewDesktop);
if (procSuccess != 0)
{
return procSuccess;
}
else
{
return 0;
}
}
My guess is that SetThreadDesktop() fails.
From MSDN:
"The SetThreadDesktop function will fail if the calling thread has any windows or hooks on its current desktop (unless the hDesktop parameter is a handle to the current desktop)."
You mentioned that StartProcess() blocks until the process terminated.
So then there is nobody referencing the new desktop and thus the desktop will go away.
You may want to consider wrapping fallible system calls in C++
-- throwing an exception in case of they fail.
And certainly the pair CreateDesktop/CloseDesktop belongs into a C++ resource wrapper.
This is 2013!
Either SwitchDesktop is failing (most of the time is access denies, or error 170 because of existing handles in another desktop), or there is another program that switches back to the default desktop.
I know for a fact that Yahoo toolbar did this (versions 5-6-7, perhaps they fixed now); KABE4.exe (I don't know what this is), an Acronis program (backup scheduler, AFAIK), and more. All of these are calling SwitchDesktop without any user intervention (a big no-no).
I proved this for Yahoo toolbar; hooking the SwitchDesktop by injecting another dll into yt.dll (loaded by IE) and returning FALSE from the hooked call solved my problem.
The proof of concept sent almost 2 years ago to Yahoo remained unanswered to this day.
In your posted code, there is that part:
// Create a new Desktop and switch to it
hNewDesktop = CreateDesktop(szDesktopName, NULL, NULL, DF_ALLOWOTHERACCOUNTHOOK, GENERIC_ALL, NULL);
SetThreadDesktop(hNewDesktop);
SwitchDesktop(hNewDesktop);
// This call blocks until the process exits, and is confirmed to work on the affected machines
procSuccess = StartProcess(szDesktopName, szPath);
// Restore original ...
SwitchDesktop(hOriginalInput);
SetThreadDesktop(hOriginalThread);
Your call to StartProcess function is between two calls to SwitchDesktop.
No function in this code stop (pause) or delay the running code, thread or process, so as you switch to hNewDesktop, you immediately switch back to hOriginalInput. You should add a while loop with end condition, after the call to StartProcess, and before the second call to SwitchDesktop. I don't know what will be the end condition for the while loop, but you do know, you will choose, after all it is your program.
For example you can use either GetKeyState or GetAsyncKeyState function to check which key is pressed on the keyboard, and make it as the end condition for the while loop, so when you will press that key, you will return immediately to your original desktop!
I've inherited some code that worked on Windows 2000 thats using a small piece of assembly code to locate the base address of the stack, then it uses an offset to grab the parameter value passed to the thread start function.
However this doesnt work in Windows 2008 Server. The offset is obviously different.
#define TEB_OFFSET 4
DWORD * pStackBase;
__asm { mov eax,fs:[TEB_OFFSET]}
__asm { mov pStackBase,eax}
// Read the parameter off the stack
#define PARAM_0_OF_BASE_THEAD_START_OFFSET -3
g_dwCtrlRoutineAddr = pStackBase[PARAM_0_OF_BASE_THEAD_START_OFFSET];
After experimenting, I modified the code to look up the stack till it finds the first non-NULL value. hack
DWORD* pStack = pStackBase;
do
{
pStack--;
}
while (*pStack == NULL);
// Read the parameter off the stack
g_dwCtrlRoutineAddr = *pStack;
Its works! But I want a 'correct' solution.
Does anyone know a safer/better solution for getting the parameter passed to the starting function of a thread on Windows 2008 Server?
The thread start function is ntdll!_RtlUserThreadStart
And the first parameter I'm trying to locate is the address of the function kernel32!CtrlRoutine
Bizarre. Looking with the debugger, the first non-null value on the thread's stack is the value of the argument, the 4th argument to CreateThread. Which gets handed to you on a silver platter when you write the thread procedure like this:
DWORD WINAPI threadProc(void* arg) {
// arg is the value you are looking for
// etc..
}
Not sure how that's related to "kernel32!CtrlRoutine" unless this is a thread used in a service.
To get address of kernel32!CtrlRoutine you can get it by RVA, using a table with all (kernel32 version, CtrlRoutine RVA) pairs. It's the most reliable way.
This is also discussed http://www.latenighthacking.com/projects/2003/sendsignal/
I'm trying to debug a method which among other things, adds items to a list which is local to the method.
However, every so often the list size gets set to zero "midstream". I would like to set the debugger to break when the list size becomes zero, but I don't know how to, and would appreciate any pointers on how to do this.
Thanks.
Why not use conditional breakpoints?
http://blogs.msdn.com/saraford/archive/2008/06/17/did-you-know-you-can-set-conditional-breakpoints-239.aspx
in C#
if(theList.Count == 0){
//do something meaningless here .e.g.
int i = 1; // << set your breakpoint here
}
in VB.NET
If theList.Count = 0 Then
'do something meaningless here .e.g.
Dim i = 1; ' << set your breakpoint here
End If
For completeness sake, here's the C++ version:
if(theList->Count == 0){
//do something meaningless here .e.g.
int i = 1; // << set your breakpoint here
}
I can give a partial answer for Visual Studio 2005. If you open the "Breakpoints" window (Alt + F9) you get a list of breakpoints. Right-click on the breakpoint you want, and choose "Condition." Then put in the condition you want.
You have already got both major options suggested:
1. Conditional breakpoints
2. Code to check for the wrong value, and with a breakpoint if so happens
The first option is the easiest and best, but on large loops it is unfortunately really slow! If you loop 100's of thousands iterations the only real option is #2. In option #1 the cpu break into the debugger on each iteration, then it evaluates the condition and if the condition for breaking is false it just continiues execution of the program. This is slow when it happens thousands of times, it is actually slow if you loop just 1000 times (depending on hardware of course)
As I suspect you really want an "global" breakpoint condition that should break the program if a certain condition is met (array size == 0), unfortunately that does not exist to my knowledge. I have made a debugging function that checks the condition, and if it is true it does something meaningless that I have a breakpoint set to (i.e. option 2), then I call that function frequently where I suspect the original fails. When the system breaks you can use the call stack to identify the faulty location.
I have an OpenGL program that works on all of my computers but one. It's a desktop with Vista 64 and a Radeon HD4850. The problem seems to be in my call to SwapBuffers(hdc).
It compiles fine and then gives me an exception:
Unhandled exception at 0x00000000 in Program.exe: 0xC0000005: Acces violation.
Using VC++ to break before the call to SwapBuffers shows hdc's value to be:
0xfe011734 {unused=???}
CXX0030: Error: expression cannot be evaluated
Anyone have a clue what could be happening? Is there something about SwapBuffers that would change from one PC to the next? I've gotten it to work on XP32, XP64 and a (different) Vista64.
while (!quit)
{
if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
{
if (msg.message == WM_QUIT)
quit = true;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
renderFrame(); //draws the scene
SwapBuffers(hdc);
if (GetAsyncKeyState(VK_ESCAPE))
shutdown();
think(); //calculates object positions, etc.
}
The drivers on the problematic system (HD4850) are up-to-date. I've run, and wrote, the program on another Vista64 system with a Radeon HD4870, also with up-to-date drivers. As far as I know, the drivers for these two cards are nearly identical as both are in the HD48xx series. For that reason it seems odd that the GPU is causing the problem.
Anyway, am I wrong or is this a memory issue? (Access violation)
Also, if I remove the call to SwapBuffers(hdc), the program runs seemingly well, although nothing is drawn, of course, because the framebuffers are never swapped. But it is at least stable.
Call stack (-> is stack ptr):
ATKOGL32.dll!6aef27bc()
opengl32.dll!665edb2d()
opengl32.dll!665f80d1()
gdi32.dll!75e14104()
-> MyProg.exe!WinMain(HINSTANCE__ * hinstance=0x009a0000, HINSTANCE__ * hprevinstance=0x00000000, char * lpcmdline=0x003b4a51, int nshowcmd=1) Line 259 + 0xe bytes
MyProg.exe!__tmainCRTStartup() Line 578 + 0x35 bytes
MyProg.exe!WinMainCRTStartup() Line 400
kernel32.dll!7641e3f3()
ntdll.dll!777dcfed()
ntdll.dll!777dd1ff()
Heres the assembly (-> is the next instruction to be executed):
SwapBuffers(hdc);
009B1B5C mov esi,esp
009B1B5E mov eax,dword ptr [hdc (9BF874h)]
009B1B63 push eax
009B1B64 call dword ptr [__imp__SwapBuffers#4 (0E1040Ch)]
-> 009B1B6A cmp esi,esp
009B1B6C call #ILT+780(__RTC_CheckEsp) (9B1311h)
It looks like you could be accessing the HDC after the window has been destroyed, does the problem disappear if you break out of the loop as soon as you get WM_QUIT ?
This is almost definitely a bug in the drivers. The reason why you can't see the value of hdc is because the top stackframe for the crash is actually inside ATKOGL32.dll but since there are no symbols for that the debugger shows you your code. As far as I can tell ATKOGL32.dll is actually an ASUS wrapper for the ATI driver and that's where the crash happens. You might want to install stock ATI drivers from amd.com and see if the crash still persists.
While the driver should never crash no matter what series of OpenGL calls you make, in my experience usually the crashes are the result of some kind of invalid call that your program makes. Technically this should just be ignored and the error state set but thats not always what happens. You can check for any invalid OpenGL calls easily by using a program like gDebugger.
Whatever hdc is set to, it doesn't look to be a proper value. Is the window created before this call? Is there any multithreading involved with this application that could hurt hdc?
Try creating a watch on the address of hdc itself, and see when the value is changed to be an invalid location, that might give you a hint as to where it changes.
We had the same (or at least very similar) issue. It turns out the Dell Nahimic service and Asus Sonic Suite use some weird injection code.
For us the problem solved itself after disabling these services.
Source: https://github.com/glfw/glfw/issues/1682