I have an MFC app running in WinPE (Windows Preinstallation Environment), and I'm trying to make a method call with a 64-bit value in a ULONGLONG as a parameter. I've determined that the value is correct (ie. 0x1b432d6000) before the call, but is corrupt (ie. 0x432d60000000000a) inside the call. The value is initially allocated on the stack immediately before the call, and I've tried passing it by value, reference, and pointer.
The call works correctly in the debugger on my development machine.
What could be causing this?
Check function signatures - sounds like you might be calling the function using an incorrect calling convention.
Related
In Intel Pin you can get the return address of a routine call using IARG_RETURN_IP as one of the arguments of RTN_InsertCall.
I wanted to do the same with a system call, instrumented using PIN_AddSyscallEntryFunction and PIN_AddSyscallExitFunction.
So at first I thought about getting the value of the instruction pointer after the call using
ADDRINT returnIp = PIN_GetContextReg(ctx, REG_INST_PTR);in the function passed as argument to PIN_AddSyscallExitFunction.
However, I noticed that, if I get the value of REG_INST_POINTER in the same way but this time before the system call is executed, I always get the same two values for the instruction pointer.
For example, I would always get 2003266482 before and 2003266484 after.
So I was wondering why is this the case and if I am doing something wrong.
This has to do with the way system calls are executed in libc, there is a single assembly stub that actually does what needs to be done to pass control from and back to the kernel, which all system calls go through.
I used "StartServiceCtrlDispatcher" function to register a callback function (called ServiceMain) in windows, but the callback function I declared got compiled with the wrong calling convention.
The thing is that on some computers, when the application returned from the callback function, the application crashed, but on other computers the application did not crash.
Now, once I found the bug everything worked, but I just don't understand why on some computers it worked correctly without crashing ?
Thanks! :-)
This is all very Windows-specific, we're not talking standard C++ here.
Checking out the documentation of StartServiceDispatcher it has only one argument, and is declared as WINAPI which in turn means __stcall calling convention.
For freestanding functions, __stdcall is one of two main calling conventions. The other one is __cdecl. The machine code level difference is simply who restores the stack pointer: with __stdcall it is the function itself, while with __cdecl it is the calling code.
When the function actually is __stdcall but is invoked as if it was __cdecl, the situation is that there are two attempts to restore the stack pointer: one at the exit from the function, and one in the calling code. The one in the function will succeed. Depending on how the attempt in the calling code is done, it can mess things up thoroughly (e.g. if just adding the required offset, treating the stack pointer as relative), or it may have no harmful effect. But it's very likely to create a mess, since the assumption about the stack pointer value on return from the function, is incorrect.
When the function actually is __cdecl it will not itself restore the stack pointer, since that is the calling code's responsibility. And if the calling code is treating it as __stdcall then the calling code won't restore it either, since from the calling code's view the function is doing that. The result, if you don't get an early crash (because of broken assumptions), should then be that repeated calls, say in a loop, will eat stack space.
It's all very much Undefined Behavior.
And one property of Undefined Behavior is that it can do anything, including apparently working…
Cheers & hth.,
Calling conventions differ in the details, like which registers are preserved. If you happened to not store anything you still needed in those registers, then it didn't matter that they were erased when they didn't have to be. Similarly, if your calling convention differs about how it deals with return values, if you don't return anything, then it doesn't matter.
Fortunately, x64 only has one calling convention and this whole mess will be in the past.
The computers where the application crashed might have been using .NET Framework version 4.
Have a look at the following article:
http://msdn.microsoft.com/en-us/library/ee941656.aspx
It states the following under Interoperability - Platform Invoke:
"To improve performance in interoperability with unmanaged code, incorrect calling conventions in a platform invoke now cause the application to fail. In previous versions, the marshaling layer resolved these errors up the stack."
This is all related to what is current in the memory. Let's assume you have two functions like this:
void stdcall f1(...) { ... }
void cdecl f2(...) { ... }
stdcall is Windows calling convention, while cdecl is used by most compilers. The difference between them is who owns the responsibility to clear the stack after the call. In stdcall, the callee (f1, or f2) does, in cdecl, the caller does.
The stack, after all, is filled with unknown values. Therefore, when it gets cleaned up (wrongly), the next value that you access in the stack is undetermined. It could very well be an acceptable value, or it could be a very bad one. This is, in principle, how stack overflow (the bug, not the site) works.
I have an application that does not use the standard libraries. Instead, it uses stubs to call LoadLibrary/GetProcAddress, then calls functions via the resultant function pointers.
Using the above method my application is calling DoDragDrop in ole32.dll. The call is returning E_UNEXPECTED, which apparently means 'catastophic failure'.
What I want to ask is does anyone know of a way to discover what is happening inside the call to DoDragDrop? Specifically, can I discover what function or variable it is looking for but cannot find? (I am guessing that it wants access to some function or variable that is not loaded at the point I call DoDragDrop, and if I can explicitly load it the call will succeed.) Obviously I can't step into the call - attempting to just runs the function and steps to the line in my code following the DoDragDrop call.
:)
(I'm using VS2005 in XP.)
I recall having something like this occur when I had forgotten to call OleInitialize(Ex) / CoInitialize(Ex) for the thread making the call. Note the apartment must be STA.
I'm debugging a C++ Win32 application and I'd like to call an arbitrary Win32 API from the context of that process, as though the program had run this line of code:
DestroyWindow(0x00021c0e);
But entering that into the Immediate Window gives:
CXX0017: Error: symbol "DestroyWindow" not found
Edit: Using the full name of the function, {,,user32.dll}_NtUserDestroyWindow#4, I can get the Immediate Window to understand which function I mean and display the function's address:
{,,user32.dll}_NtUserDestroyWindow#4
0x76600454 _NtUserDestroyWindow#4
but when I try to call it, this happens:
{,,user32.dll}_NtUserDestroyWindow#4(0x00021c0e);
CXX0004: Error: syntax error
Is it even possible to call a C function from the Immediate Window like this, or am I barking up the wrong tree?
Once you have the function address (as you've done in the updated question), you can try casting it to a function pointer and calling it:
(*(BOOL (*)(HWND))0x76600454)((HWND)0x00021c0e)
The first part of that casts the address to BOOL (*)(HWND), which is a pointer to a function taking an HWND parameter and returning BOOL. Then, the function pointer is dereferenced and called. Make sure to get the parameters correct, otherwise bad things will happen. On 64-bit systems, and HWND might be 64 bits, so you might not be able to get away with passing the parameter as an int.
Edit: See the comments for the full story.
I believe the problem is that the C++ EE is having problems resolving the context of DestroyWindow. Try the following
{,,user32}DestroyWindow(0x00021c0e);
I'm not sure if the method invocation syntax supports this style of qualification (only used it for casting in the past). But it's worth a shot.
EDIT You may or may not need to add a ! after the closing }. It's been awhile since I've used this syntax and I often confuse it with the equivalent windbg one.
I figured out a workaround, but I'd still prefer to get the Immediate Window to work.
The workaround is:
get the address of the function, as shown in the question
use the Disassembly window to go to that address, and put a breakpoint there
do something to the application to make it call DestroyWindow
step back up the call stack to the caller of DestroyWindow, which looks like this:
6D096A9D push ecx
6D096A9E call dword ptr ds:[6D0BB4B8h]
put a breakpoint on the push ecx instruction, and clear the one on DestroyWindow
hit Continue, and again do something to the application to make it call that code
note down the value of ecx
change the value of ecx in the debugger to the desired value and step over the push/call
restore the value of ecx and use Set Next Statement to go back to the push, then Continue
It's longwinded, but it works. It assumes you can make the application call the appropriate API at will.
I just started working with the Android NDK but I keep getting SIGSEGV when I have this call in my C code:
jobjectArray someStringArray;
someStringArray = (*env)->NewObjectArray(env, 10,
(*env)->FindClass(env,"java/lang/String"),(*env)->NewStringUTF(env, ""));
Base on all the example I can find, the above code is correct but I keep getting SIGSERGV and everything is ok if the NewObjectArray line is commented out. Any idea what could cause such a problem?
that looks right, so i'm guessing you've done something else wrong. i assume you're running with checkjni on? you might want to break that up into multiple lines: do the FindClass and check the return value, do the NewStringUTF and check the return value, and then call NewObjectArray.
btw, you might want to pass NULL as the final argument; this pattern of using the empty string as the default value for each element of the array is commonly used (i think it's copy & pasted from some Sun documentation and has spread from there) but it's rarely useful, and it's slightly wasteful. (and it doesn't match the behavior of "new String[10]" in Java.)
I guess one of the possible causes is that in a long-run JNI method, the VM aborts when running out of the per-method-invocation local reference slots (normally 512 slots in Android).
Since FindClass() and NewStringUTF() functions would allocate local references, if you stay in a JNI method for a long time, the VM do not know whether a specific local reference should be recycled or not. So you should explicitly call DeleteLocalRef() to release the acquired local references when not required anymore. If you don't do this, the "zombie" local references will occupy slots in VM, and the VM aborts while running out of all the local reference slots.
In short-run JNI method, this may not be a problem due to all the local references would be recycled when exiting from a JNI method.