PeekMessage() throws an unhandled exception (access violation) - c++

Greetings all,
in my application i use the following code:
bool HandleMessages()
{
MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
return FALSE;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return true;
}
This is the standard code for message handling in windows i thought, but now when i try to run the program, i always get an Exception at the PeekMessage() call.
Exception message is
Unhandled exception at 0x57a10eed
(msvcr100d.dll) in testing.exe:
0xC0000005: access violation while
reading at Position 0x6666665c.
Im completely lost here, cant see why it would throw an exception. Anyone got a hint?
Call Stack:
msvcr100d.dll!__local_unwind2() + 0x48 Bytes Asm
msvcr100d.dll!_except_handler3() + 0xed Bytes Asm
Testing.exe!_except_handler4(_EXCEPTION_RECORD * ExceptionRecord, _EXCEPTION_REGISTRATION_RECORD * EstablisherFrame, _CONTEXT * ContextRecord, void * DispatcherContext) + 0x24 Bytes C
Testing.exe!_except_handler4(_EXCEPTION_RECORD * ExceptionRecord, _EXCEPTION_REGISTRATION_RECORD * EstablisherFrame, _CONTEXT * ContextRecord, void * DispatcherContext) + 0x24 Bytes C
Disassembly:
continue:
57CE0EEA lea esi,[esi+esi*2]
57CE0EED mov ecx,dword ptr [ebx+esi*4]
57CE0EF0 mov dword ptr [esp+0Ch],ecx
57CE0EF4 mov dword ptr [eax+0Ch],ecx
57CE0EF7 cmp dword ptr [ebx+esi*4+4],0
57CE0EFC jne _lu_continue (57CE0F15h)
57CE0EFE push 101h
57CE0F03 mov eax,dword ptr [ebx+esi*4+8]
57CE0F07 call _NLG_Notify (57CE0F55h)
57CE0F0C mov eax,dword ptr [ebx+esi*4+8]
57CE0F10 call _NLG_Call (57CE0F74h)

Show us your call stack. If it's crashing in msvcr100d.dll, then it's happening outside of PeekMessage (before or after the call). you should have good debugging info for this.
Take a look at the this pointer if applicable
do a rebuild all
Step into the disassembly

I don't think the callstack you posted is quite sufficient to make anything out from it.
Is there a chance you could be calling HandleMessages() in response to a message? This could result in recursion / stack exhaustion.

Related

Listing all running applications MASM32 Assembly

Good day! I've been trying to list all the currently running applications and write it on a text file using masm. I'm new with assembly but is using MSDN as my reference. So far, I know how to use CreateFile, WriteFile, ReadFile and others but I don't get how Process32First works.
I'm trying to convert the code in this link to MASM, (https://msdn.microsoft.com/en-us/library/windows/desktop/ms686701(v=vs.85).aspx) but with no luck, I can't get any output.
I will really appreciate any help! Thank you! Have a nice day.
include \masm32\include\masm32rt.inc
.data
pe32 PROCESSENTRY32 <>
errorCreateTool db "ERROR: CreateToolhelp32Snapshot", 0
errorPF db "ERROR: Process32First", 0
errorOP db "ERROR: OpenProcess", 0
yesMsg db "proceed", 0
.data?
dwPriorityClass dd ?
hProcessSnap HANDLE ?
hProcess HANDLE ?
.code
_start:
push 0
push TH32CS_SNAPPROCESS
call CreateToolhelp32Snapshot
mov hProcessSnap, eax
cmp hProcessSnap, INVALID_HANDLE_VALUE
je _errorCT
mov pe32.dwSize, sizeof PROCESSENTRY32
push offset pe32
push hProcessSnap
call Process32FirstW
cmp eax, ERROR_NO_MORE_FILES
je _errorPF
push offset pe32.szExeFile
call StdOut
mov dwPriorityClass, 0
push offset pe32.th32ProcessID
push FALSE
push PROCESS_ALL_ACCESS
call OpenProcess
cmp eax, 00H ;if I comment this out, the code will proceed
je _errorOpen
push offset pe32.th32ProcessID ;but this doesn't have any value and doesn't print out
call StdOut
push offset yesMsg ;while this prints out on the console
call StdOut
jmp _done
_errorOpen:
push offset errorOP
call StdOut
jmp _done
_errorPF:
push offset errorPF
call StdOut
jmp _done
_errorCT:
push offset errorCreateTool
call StdOut
_done:
push 0
call ExitProcess
end _start
I have experienced using that function. All I have to do is updata my kernel32.inc and kernel32p.inc as you have suggested. After doing those things, I run the makelibs.bat in the masm32 folder and it works from there.

Stack Overflow C00000FD in MFC application

I am using a Custom tree control derived class. Below is the code.
CCustomTreeCtrl.h
class CCustomTreeCtrl : public CTreeCtrl
{
public:
BOOL Check;
CCustomTreeCtrl();
virtual ~CCustomTreeCtrl();
protected:
//{{AFX_MSG(CCustomTreeCtrl)
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP();
};
CCustomTreeCtrl.cpp
CCustomTreeCtrl::CCustomTreeCtrl()
{
}
CCustomTreeCtrl::~CCustomTreeCtrl()
{
}
BEGIN_MESSAGE_MAP(CCustomTreeCtrl , CTreeCtrl)
//{{AFX_MSG(CCustomTreeCtrl)
ON_WM_LBUTTONDBLCLK()
//}}AFX_MSG
END_MESSAGE_MAP()
void CCustomTreeCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
{
char buf[255];
FILE *stream;
CString FilePath;
TV_HITTESTINFO pHitTestInfo;
pHittestInfo.pt = point;
pHitTestInfo.flags = TVHT_ONITEMLABEL;
HitTest(&pHitTestInfo);
if(pHitTestInfo.hItem != NULL && !ItemHasChildren(pHitTestInfo.hItem))
{
RECT sRect;
GetItemRect(pHitTestInfo.hItem,&sRect,1);
CRect cRect(&sRect);
if(cRect.PtInRect(point))
{
CTestApp* the = (CTestApp*)AfxGetApp();
CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
CString FileName = GetItemtext(pHitTestInfo.hItem);
FilePath = pFrame->Filepath;
strcpy(buf,Filepath);
strcat(buf,Filename);
strcat(buf,".ext");
stream = fopen(buf, "r");
if(stream != NULL)
{
fclose(stream);
if(pFrame->isUpToDate(buf))
{
pFrame->DisplayFile(buf);
}
else
{
pFrame->CreateFile(buf);//-> Error in this line Exception: C00000FD Stack OverFlow
pFrame->DisplayFile(buf);
}
}
}
}
}
The application exits on double click on a tree item.
When debugging, on stepping into the CreateFile function raises ans stack overflow exception.
If the file is up to date the DisplayFile function is executed properly.
The error is only when I call the CreateFile function. The function just writes some data to text file. On debugging, the exception is raised the minute I step into the function.
Call Trace (IDE VC6)
CCustomTreeCtrl::OnLButtonDblClick(unsigned int 1, Cpoint {x=150 y=104}) line 117
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
USER32! xxxxxxxx()
USER32! xxxxxxxx()
USER32! xxxxxxxx()
USER32! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
CTestApp::PreTranslateMessage(tagMSG * 0x00484cd0 {msg = 0x00000203 wp = 0x00000001 lp= 0x00680096}) line 563
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
MFC42D! xxxxxxxx()
WinMain(HINSTANCE__ 0x00400000, HINSTANCE__ 0x00000000, char * 0x00151f2e, int 1) Line 30
WinMainCRTStartup() Line 330 + 54 bytes
KERNEL32! xxxxxxxx()
CreateFunction
void CMainFrame::CreateFile(CString FileName)
{
BeginWaitCursor();
if(FileName.getAt(1) == 'L')
{
CMyDllA myDlla;
myDlla.ConvertDataToFile(MyDataBasePath,FileName);
}
else if(FileName.getAt(1) == 'B')
{
CMyDllB myDllb;
myDllb.ConvertDataToFile(MyDataBasePath,FileName);
}
else if(FileName.getAt(1) == 'D')
{
CMyDllD myDlld;
myDlld.ConvertDataToFile(MyDataBasePath,FileName);
}
else if(FileName.getAt(1) == 'S')
{
CMyDllS myDlls;
myDlls.ConvertDataToFile(MyDataBasePath,FileName);
}
EndWaitCursor();
}
//ConvertDataToFile Function reads data for a database performs calculations and writes report to a text file.
#Michael Walz Yes, the application crashes before hitting the breakpoint.
In Disassembly:
147 pFrame->CreateFile(buf);
00456B74 push ecx
00456B75 mov ecx,esp
00456B77 mov dword ptr [ebp-112A8h],esp
00456B7D lea edx, [buf]
00456B83 push edx
00456B84 call CString::CString (0045da26)
00456B89 mov dword ptr [ebp-11328h],eap
00456B77 mov ecx, dword ptr [pFrame]
00456B95 call #ILT+1300(CMainFrame::CreateFile) (00401519)
As soon as i step into Create File function, in the variable window its showing "this CXX0069: Error variable needs stack frame"
CreateFile Disassembly:
10040: {
0043F813 push ebp
0043F814 mov ebp, esp
0043F816 push 0FFh
0043F818 push offset $L111205 (00465099)
0043F81D mov eax, fs:[00000000]
0043F823 push eax
0043F824 mov dword ptr fs:[0],esp
0043F824 mov eax, 109DC8h
0043F830 call $$$00001 (0045e840) //Breaks here and jumps to CHKSTK.ASM File
0043F835 mov dword ptr [ebp-109DBCh], ecx
0043F83B mov dword ptr [ebp-4], 0
Currently I don't have the source of the CMyDllx. Only the header and lib.
But I am also calling the same function from the application menu, it get carried out without any error. Its only when I call it using tree control, I face the error.
#IInspectable Sorry but this is work PC, and I cannot install any software in this machine.
0043F824 mov eax, 109DC8h
0043F830 call $$$00001 (0045e840) //Breaks here and jumps to CHKSTK.ASM File
109DC8h tells the tale, the argument passed to __chkstk() is the amount of stack space that CreateFile() requires. 0x109dc8 == 1,088,968 bytes. No can do, that's more than the entire space available in the stack (1 megabyte). So __chkstk() correctly slams the emergency stop button before your program hits the wall, CreateFile() will always fail.
Your snippet squarely points the finger at the guilty party, it is one of the CMyDllx objects that is too big. Or more likely, all of them, needing a quarter of a megabyte each. Rewrite the code to allocate them on the free store with the new operator.

Is it possible to transfer thread execution to another thread?

I'm currently experimenting for possibilities transferring a thread execution to another newly created thread from current thread (I hope its a correct word); Here's the illustration:
Thread1 running
Thread1 stop in the middle of the code and create Thread2
Thread2 continue from the middle of the code where Thread1 stop
EDIT: Updated the example.
#include "stdafx.h"
#include <memory>
#include <windows.h>
#include <cassert>
int _eax, _ebx, _ecx, _edx;
int _ebp, _esp, _esi, _edi;
int _eip;
int _flags;
int _jmp_addr;
bool thread_setup = false;
CONTEXT PrevThreadCtx;
HANDLE thread_handle;
int _newt_esp;
int _newt_ret;
DWORD WINAPI RunTheThread(LPVOID lpParam)
{
// 1000 is more than enough, call to CreateThread() should already return by now.
Sleep(1000);
ResumeThread(thread_handle);
return 0;
}
DWORD WINAPI DummyPrologueEpilogue(LPVOID lpParam)
{
return 123;
}
__declspec(naked) void TransferThread(LPVOID lpParam)
{
//longjmp(jmpbuf, 0);=
__asm
{
call get_eip;
cmp[_newt_esp], 0;
mov[_newt_ret], eax;
jz setup_new_thread;
jmp DummyPrologueEpilogue;
get_eip:
mov eax, [esp];
ret;
setup_new_thread:
pushad;
mov[_newt_esp], esp;
mov eax, [_flags];
push eax;
popfd;
mov eax, [_eax];
mov ebx, [_ebx];
mov ecx, [_ecx];
mov edx, [_edx];
mov ebp, [_ebp];
mov esp, [_esp];
mov esi, [_esi];
mov edi, [_edi];
jmp [_eip];
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int x = 100;
char szTest[256];
sprintf_s(szTest, "x = %d", x);
//HideThread();
//setjmp(jmpbuf);
__asm
{
// Save all the register
mov[_eax], eax;
mov[_ebx], ebx;
mov[_ecx], ecx;
mov[_edx], edx;
mov[_ebp], ebp;
mov[_esp], esp;
mov[_esi], esi;
mov[_edi], edi;
push eax;
// Save the flags
pushfd;
pop eax;
mov[_flags], eax;
// If we on *new thread* jmp to end_asm, otherwise continue...
call get_eip;
mov[_eip], eax;
mov al, byte ptr[thread_setup];
test al, al;
jnz end_asm;
mov eax, [jmp_self];
mov[_jmp_addr], eax;
pop eax;
mov[_newt_esp], 0;
mov byte ptr[thread_setup], 1;
push 0;
push CREATE_SUSPENDED;
push 0;
push TransferThread;
push 0;
push 0;
call CreateThread;
mov [thread_handle], eax;
// Create another thread just to resume 'TransferThread()'/*new thread* to give time to
// __stdcall below to return properly, thus restoring the stack.
// So the *new thread* does not accidentally pop the value from stacks or the __stdcall cleanup
// code doesn't accidentally overwrites new pushed value from *new thread*.
push 0;
push 0;
push 0;
push RunTheThread;
push 0;
push 0;
call CreateThread;
// Jump to self, consumes CPU
jmp_self:
jmp jmp_self;
nop;
nop;
jmp end_asm;
get_eip:
mov eax, [esp];
ret;
end_asm:
}
// Test stack-based variable
MessageBoxA(0, szTest, "Hello World!", MB_OK);
assert(x = 100);
x += GetCurrentThreadId();
sprintf_s(szTest, "x = %d", x);
HMODULE hMod = LoadLibrary(TEXT("comctl32"));
FreeLibrary(hMod);
try
{
std::unique_ptr<char[]> pTest(new char[256]);
sprintf_s(pTest.get(), 256, "WinApi call test. Previous loadLibrary() call return %X", hMod);
MessageBoxA(0, pTest.get(), "Hello World!", MB_OK);
} catch (...) {}
char *pszTest = (char*) malloc(256);
if (pszTest)
{
float f = 1.0;
f *= (float) GetCurrentThreadId();
sprintf_s(pszTest, 256, "Current Thread ID = %X, Thread handle = %X, FP Test = %f", GetCurrentThreadId(), GetCurrentThread(), f);
MessageBoxA(0, pszTest, "Hello World!", MB_OK);
free( pszTest );
}
// printf() from *new thread* will fail on stkchk()
//printf("Simple test\n");
// Let's terminate this *new* thread and continue the old thread
if (thread_setup)
{
DWORD OldProtect;
thread_setup = false;
VirtualProtect((PVOID)_jmp_addr, 2, PAGE_EXECUTE_READWRITE, &OldProtect);
*(int*)(_jmp_addr) = 0x90909090; // Prev thread not suspended. Just hope this op is atomic.
// Operation below will change the stack pointer
//VirtualProtect((PVOID)_jmp_addr, 2, OldProtect, &OldProtect);
//FlushInstructionCache(GetCurrentProcess(), (PVOID)_jmp_addr, 2);
__asm {
push eax;
mov eax, jmp_self2;
mov[_jmp_addr], eax;
pop eax;
jmp_self2:
jmp jmp_self2;
nop;
nop;
mov esp, [_newt_esp];
popad;
jmp _newt_ret;
}
}
else
{
DWORD OldProtect;
VirtualProtect((PVOID)_jmp_addr, 2, PAGE_EXECUTE_READWRITE, &OldProtect);
*(int*)(_jmp_addr) = 0x90909090; // Prev thread not suspended. Just hope this op is atomic.
}
// Show both thread can be exited cleanly... with some hacks.
DWORD dwStatus;
while (GetExitCodeThread(thread_handle, &dwStatus) && dwStatus == STILL_ACTIVE) Sleep(10);
printf("*New Thread* exited with status %d (Expected 123), Error=%X\n", dwStatus, GetLastError());
assert(dwStatus == 123);
printf("Test printf from original thread!\n");
printf("printf again!\n");
printf("and again!\n");
Sleep( 1000 );
return 0;
}
The code might be pain to read since it consists mostly asm. So I added a little comment to help. Now that I test, it is quite possible but with some problems. Calling few win api seems fine, but calling printf will certainly crash on stkchk() function (access denied). I will try alternative if there is any suggestion.
It won't be possible. (EDIT: It might be possible to switch successfully with OS APIs like GetThreadContext as JS1 mentionned, but others limitations still apply)
The thing is, the new thread needs the previous thread stack to run. You can do that by either using the old stack directly, or copying the old stack to the new stack. Neither of these are possible : you can't copy the stack because of stack-dependent pointers (frame pointers, for example), and you can't use the old stack, because the OS will detect that the thread went out of its stack, and throw a stack overflow or underflow.
It might be possible if the OS doesn't detect the stack misplacement. If that's the case, then you can load the old ESP and EBP to use the old stack (like you did). You have some problem with your current code (provided it can even work at all), because you push some registers AFTER you saved the stack pointer (ESP). When you reload ESP, it's like you never pushed anything. The ESP pointer really is a special case that need to be handled carefully. Note that you don't even need to care about the new stack in this case, it will just be ignored. That means you don't need any special naked declaration.
Another note, if you are able to do this, neither thread will be able to terminate if you don't restore the threads previous code flows. The old thread should not use the stack while the new is running, so it can't terminate, and the new can't terminate on the old stack. Each stack contains thread-dependent clean-up code at the bottom (or top, for top-down stack).
As an FYI, I have not tried the following, but it's possible that you might be able to get something to work like this with a naked function (AFAIK only Microsoft compilers):
https://msdn.microsoft.com/en-us/library/5ekezyy2.aspx
There are a significant number of limitations: https://msdn.microsoft.com/en-us/library/4d12973a.aspx but starting a thread with a naked function isn't listed as a limitation. A naked function would remove the prolog/epilog and allow you to try and transfer the context from the previous thread.
You can potentially also do this through an interpreter: basically save the interpreted state of the program and start on a separate thread.
As I can think of no actual use case, I'm not sure why you would ever want to do this.

Read eax register

I would like to know if it is possible to read the eax register of another process immediately after an assembly instruction has been executed.
In my case I have the following assembly code:
mov byte ptr ss:[EBP-4]
call dword ptr ds:[<&MSVCR100.??2#YAPAXI#Z>]
add esp, 4
The idea is to get the eax value just after the "call dword ptr ds:[<&MSVCR100.??2#YAPAXI#Z>]" instruction has been executed.
Indeed, I have to retrieve the memory address returned by the instanciation of an object created in another process, in my C++ code.
Dunno if I have been clear enough. And please forgive my bad english.
You could debug the process using a hardware breakpoint.
Example using winapi:
DWORD address = 0x12345678; // address of the instruction after the call
DebugActiveProcess(pid); // PID of target process
CONTEXT ctx = {0};
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS | CONTEXT_INTEGER;
ctx.Dr0 = address;
ctx.Dr7 = 0x00000001;
SetThreadContext(hThread, &ctx); // hThread with enough permissions
DEBUG_EVENT dbgEvent;
while (true)
{
if (WaitForDebugEvent(&dbgEvent, INFINITE) == 0)
break;
if (dbgEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT &&
dbgEvent.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP)
{
if (dbgEvent.u.Exception.ExceptionRecord.ExceptionAddress == (LPVOID)address)
{
GetThreadContext(hThread, &ctx);
DWORD eax = ctx.Eax; // eax get
}
}
ContinueDebugEvent(dbgEvent.dwProcessId, dbgEvent.dwThreadId, DBG_CONTINUE);
}

Why does GetLastError() return 0 or 2 depending on how it is called?

I am using mingw g++ 4.6.1 with -O0, WinXP SP2.
Minimal working example is here.
g++ is configured with --disable-sjlj-exceptions --with-dwarf2.
GetLastError() returns 0 or 2 depeding on how the exception is thrown:
throw runtime_error(error_message());
bogus "error code: 0" is printed, and
const string msg = error_message();
throw runtime_error(msg);
prints "error code: 2" as expected.
First, I thought GetLastError() is invoked twice but debugging shows it is invoked exactly once, as expected.
What is going on?
It's possible that the code that sets up a throw calls a Win32 API function inside itself somewhere, that resets the Last-Error value to 0. This may be happening before your call to error_message().
Calling GetLastError() does not automatically reset the Last-Error value to 0, so it is safe to call twice.
Whether your compiler/runtime generates code that calls a Win32 API function will be up to your specific runtime. In order to be safe and not depend on this, use the two-statement version:
const string msg = error_message();
throw runtime_error(msg);
Better yet, for future readers of your code it would be useful to call GetLastError() outside error_message():
const string msg = error_message(GetLastError());
throw runtime_error(msg);
This way, readers will see the GetLastError() call immediately after the corresponding Win32 API call, where it belongs.
If you look at the assembly code generated, it become clear what's happening. The following C++ code:
hDevice = CreateFileA(path, // drive to open
// etc...
);
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
throw runtime_error(error_message());
}
Generates a stretch of assembly code (at least using default optimization):
call _CreateFileA#28 #
LEHE4:
sub esp, 28 #,
mov DWORD PTR [ebp-12], eax # hDevice, D.51673
cmp DWORD PTR [ebp-12], -1 # hDevice,
jne L5 #,
mov DWORD PTR [esp], 8 #,
call ___cxa_allocate_exception # // <--- this call is made between the
# // CreateFile() call and the
# // error_message() call
mov ebx, eax # D.50764,
lea eax, [ebp-16] # tmp66,
mov DWORD PTR [esp], eax #, tmp66
LEHB5:
call __Z13error_messagev #
You see a call made to ___cxa_allocate_exception to allocate some memory block for the exception being thrown. That function call is changing the GetLastError() state.
When the C++ code looks like:
hDevice = CreateFileA(path, // drive to open
// etc...
);
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
const string msg = error_message();
throw runtime_error(msg);
}
Then you get the following generated assembly:
call _CreateFileA#28 #
sub esp, 28 #,
mov DWORD PTR [ebp-12], eax # hDevice, D.51674
cmp DWORD PTR [ebp-12], -1 # hDevice,
jne L5 #,
lea eax, [ebp-16] # tmp66,
mov DWORD PTR [esp], eax #, tmp66
call __Z13error_messagev #
LEHE4:
sub esp, 4 #,
mov DWORD PTR [esp], 8 #,
call ___cxa_allocate_exception # // <--- now this happens *after*
// error_message() has been called
which does not call an external function between the failed CreateFile() call and the call to error_message().
This kind of problem is one of the main problems with error handling using some global state like GetLastError() or errno.