Sometimes I see this in Olly, typically inside HeapFree or HeapRealloc:
0038F8A1 65 61 70 20|62 6C 6F 63|6B 20 61 74|20 30 30 33| eap block at 003
0038F8B1 45 42 30 38|30 20 6D 6F|64 69 66 69|65 64 20 61| EB080 modified a
0038F8C1 74 20 30 30|33 45 43 30|38 38 20 70|61 73 74 20| t 003EC088 past
0038F8D1 72 65 71 75|65 73 74 65|64 20 73 69|7A 65 20 6F| requested size o
0038F8E1 66 20 31 30|30 30 0A 00|00 3E 00 00|00 00 00 DC| f 1000
Apparently, DbgPrint sents it to the VS debugger output window. My question: Can we use this feature in MASM, e.g. by enabling debug mode, redirecting that stream to the console, ...?
Maybe link against debug version of crt as MS VC does?
Quote from: jj2007 on February 22, 2016, 10:04:38 PM
...
redirecting that stream to the console, ...?
Use DbgView instead
Use a combination of OutputDebugString (https://msdn.microsoft.com/en-us/library/windows/desktop/aa363362(v=vs.85).aspx) and DebugView (https://technet.microsoft.com/en-us/sysinternals/debugview)?
Thanks. So far no luck, can't see that output in DebugView. Linking against debug CRT doesn't make sense, as this is not CRT but rather Win32 standard API calls like HeapAlloc etc :(
Quote from: jj2007 on February 23, 2016, 12:38:51 AM
Thanks. So far no luck, can't see that output in DebugView. Linking against debug CRT doesn't make sense, as this is not CRT but rather Win32 standard API calls like HeapAlloc etc :(
Interesting . I'd look which module does that DbgPrint . Could you upload simple example (for Windows XP) reproducing it?
P.S.: In my first reply I mistakenly named SysInternals' DebugView ( really what I meant) as DbgView
Here it is. Uncomment the ; int 3 to see the difference.
include \masm32\include\masm32rt.inc
.code
start:
mov esi, rv(GetProcessHeap)
invoke HeapAlloc, esi, 0, 20
push eax
xchg eax, edi
m2m ecx, 20+1 ; FOUL!!
rep stosb
; int 3
invoke HeapValidate, esi, 0, 0
print LastError$()
pop eax
invoke HeapFree, esi, 0, eax
print LastError$()
exit
end start
Here is the relevant bit when using the int 3:
77CF0B09 Ú$ 8BFF mov edi, edi ; ntdll.77CF0B09(guessed Arg1)
77CF0B0B ³. 55 push ebp
77CF0B0C ³. 8BEC mov ebp, esp
77CF0B0E ³. 64:A1 18000000 mov eax, fs:[18]
77CF0B14 ³. 8B40 30 mov eax, [eax+30]
77CF0B17 ³. 8078 02 00 cmp byte ptr [eax+2], 0
77CF0B1B ³. 74 17 je short 77CF0B34
77CF0B1D ³. 8B45 08 mov eax, [ebp+8]
77CF0B20 ³. C605 8582D277 01 mov byte ptr [77D28285], 1
77CF0B27 ³. A3 8082D277 mov [77D28280], eax
77CF0B2C ³. CC int3
77CF0B2D ³. C605 8582D277 00 mov byte ptr [77D28285], 0
77CF0B34 ³> 5D pop ebp
77CF0B35 À. C2 0400 retn 4
Register edx points to:
0018FC11 65 61 70 20|62 6C 6F 63|6B 20 61 74|20 30 30 35| eap block at 005
0018FC21 30 33 44 35|30 20 6D 6F|64 69 66 69|65 64 20 61| 03D50 modified a
0018FC31 74 20 30 30|35 30 33 44|36 43 20 70|61 73 74 20| t 00503D6C past
0018FC41 72 65 71 75|65 73 74 65|64 20 73 69|7A 65 20 6F| requested size o
0018FC51 66 20 31 34| f 14
Thanks .I'll go and play with it now
After some playing my guess is that we may simulate a debugger in order to intercept debugging messages.
What if create a simple launcher which will create process for your test app with DEBUG flags ?
[EDIT] That is we might write a small debugger like this Writing the Debugger's Main Loop (https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms681675%28v=vs.85%29.aspx) and handle only OUTPUT_DEBUG_STRING_EVENT (https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms679308%28v=vs.85%29.aspx)
Ehm, that looks like a bit of work ::)
Use C++ :biggrin:
Creating Processes (https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms682512%28v=vs.85%29.aspx)
C++? Too simple - try this one :biggrin:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
int 3 ; somewhere down there is a CreateProcess call...
Launch "Notepad.exe"
EndOfCode
I compiled quick and dirty example from mentioned above C++ snippets.
CreateProcess.exe - launcher for DbgPrint.exe ( compiled from your source ).
I get 2 error messages from MS VC++ Debug Library and WER window ( see screenshots in attachment) and some promising output :
QuoteHEAP[DbgPrint.exe]:
[EDIT] Note that when I start CALC.EXE with my launcher I don't get any error message boxes .
Weird problems with my keyboard didn't let me accomplish the task in single evening :(
To be continued
Works for me :biggrin:
BINGO!
run:
CreateProcess DbgPrint.exe
get:
Quote
HEAP[DbgPrint.exe]:
Heap block at 001429B8 modified at 001429D4 past requested size of 14
The operation completed successfully.
HEAP[DbgPrint.exe]:
Heap block at 001429B8 modified at 001429D4 past requested size of 14
HEAP[DbgPrint.exe]:
Invalid Address specified to RtlFreeHeap( 00140000, 001429C0 )
The operation completed successfully.
Enjoy
**** NOTICE: Tested on Windows XP 32 ****
Quote from: GoneFishing on February 23, 2016, 08:09:04 AM
**** NOTICE: Tested on Windows XP 32 ****
**** NOTICE: Tested on Windows 7 64 ****
Thanks :t
(your version choked with side by side error (http://answers.microsoft.com/en-us/windows/forum/windows_7-pictures/error-the-application-has-failed-to-start-because/df019c0d-746e-42d0-ad68-465e18e3f3ef?auth=1); so I recompiled it for Win7-64)
**** NOTICE: Tested on Windows 10 64 ****
With msvcrt.dll, 32bit and 64bit versions.
Quote from: TWell on February 23, 2016, 08:23:16 PM
**** NOTICE: Tested on Windows 10 64 ****
Works fine on Win7-64. The 64-bit version shows some extra non-identified events, though.
Quote from: jj2007 on February 23, 2016, 10:02:47 PM
The 64-bit version shows some extra non-identified events, though.
And what are they?
some other exception 4000001F STATUS_WX86_BREAKPOINT ?
Quote0x4000001F
STATUS_WX86_BREAKPOINT
An exception status code that is used by the Win32 x86 emulation subsystem.
It makes sense.
It's x64 specific:
Using the Windows debugging API on Windows 64 (http://www.howzatt.demon.co.uk/articles/DebuggingInWin64.html) :
Quote
However some of the output produced is a little unexpected! After all, we are debugging exactly the same process that we debugged earlier under "Next step - running the 32-bit code on 64-bit" but we are getting much more output and a very different call stack on program exit. What is going on?
The first change when using the 64-bit debug API is that the debugger is notified about additional DLLs loaded into the process address space. The first DLL loaded, ntdll.dll, is in fact the 64-bit version of the DLL and it is followed by the 32-bit ntdll32.dll. Note that the 32-bit mode debugger doesn't see the 64-bit DLL, only the 32-bit one.
The next few DLLs are the WOW64 implementation - these are 64-bit DLLs loaded into the target process. Again, the 32-bit mode debugger does not receive any notification when these DLLs are loaded into the process. Notice however that, probably through an oversight in the implementation of the 32-bit debug interface, the 32bit debugger sees the UNLOAD DLL messages for the special WOW64 DLLs.
We then receive an unexpected exception - code 0x4000001f - which turns out to be a new value, STATUS_WX86_BREAKPOINT. This exception code is barely documented but it appears to be a 'start up' breakpoint much like the initial breakpoint that the debugger always receives. On older versions of Windows the default processing for this exception code terminates the process, on Windows 7 it is ignored.
The author of the article fixed this problem like this:
case EXCEPTION_DEBUG_EVENT:
if (!attached)
{
// First exception is special
attached = true;
}
#ifdef _M_X64
else if (DebugEvent.u.Exception.ExceptionRecord.ExceptionCode ==
STATUS_WX86_BREAKPOINT)
{
std::cout << "WOW64 initialised" << std::endl;
}
#endif // _M_X64
else
{
OnException(DebugEvent.dwThreadId,
DebugEvent.u.Exception.dwFirstChance,
DebugEvent.u.Exception.ExceptionRecord);
continueFlag = (DWORD)DBG_EXCEPTION_NOT_HANDLED;
}
break;
I'll add it to the code of the Launcher
Should I use
_M_X64 define for Windows 7 64 /Windows 10 64 ?
Does it heart that you have to terminate it by pressing Ctrl-C ?
Quote from: GoneFishing on February 23, 2016, 11:12:37 PM
Does it heart that you have to terminate it by pressing Ctrl-C ?
Yes it hurts, but that is easy to fix:
case EXIT_PROCESS_DEBUG_EVENT:
// Display the process's exit code.
//MessageBox(0, "Bye", "Debugger:", MB_OK);
return;
// dwContinueStatus = OnExitProcessDebugEvent(DebugEv);
break;
Ok , it'll be fixed
Also make change in default case of exception handling switch:
default:
// Handle other exceptions.
printf("-- other exception with code 0x%08X \n", DebugEv->u.Exception.ExceptionRecord.ExceptionCode);
break;
You won't see non-identified events any more
[EDIT] Fixed version attached, STATUS_WX86_BREAKPOINT is not handled - I still don't know how to ifdef it for x64 target
Hi GoneFishing,
Based on your source, I've written a plain assembler version. The exe is 1536 bytes and handles only debug string messages, i.e. if there are no problems, the target exe will behave as if it was not debugged at all.
Test it with this snippet:
include \masm32\include\masm32rt.inc
.code
start:
mov ebx, rv(GetProcessHeap)
invoke HeapAlloc, ebx, 0, 20
xchg eax, esi
mov byte ptr [esi+48], "x" ; <<<<<<<<<<< ILLEGAL!!!
invoke HeapValidate, ebx, 0, 0
print LastError$()
invoke HeapFree, ebx, 0, esi
print LastError$()
exit
end start
EDIT: Attachment removed, an improved version is now at \Masm32\MasmBasic\Res\DebugHeap.exe; see
HeapValidate doesn't find any problems (http://masm32.com/board/index.php?topic=94.msg55745#msg55745)