.effmach x86 failed to swtich from 64bits to 32 bits - windows

I use Windbg 64 bits to debug a program (32bits, langage C), this program contains exceptions.
In my program I recolte informations about exception occured, especialy ExceptionRecord and ContextRecord and I call batch file that call cdb.exe (64bits).
The line in batch file where I call cdb.exe is:
cdb.exe -p %PID% -pd -loga %LogFile%.txt -lines -c ".echo ;.echo *** Call stack of module causing abort ***;.effmach x86;.cxr %ContextRecord%;kp; .dump /ma %LogFile%.dmp;q" > nul
Where %PID% : my process Id
So, when I use ;.load wow64exts;!sw; instead .effmach x86, the debuger run and show me exactly what I need (The line and function caused exception), but when I use .effmach x86, the batch file stop runing, or crash, or I don't know, but there is no result and the logfile not created.
My question: Why .effmach x86 crash my batch file?
Thanks
I use Windows 7 64 bits
(sorry for my english)

I have find problem
for simple reason, must add space between x86 and next semicolon ; (x86; architecture doesn' exist)

Related

'.symfix+' is not recognized on cmd terminal

I am trying to follow this WinDBG tutorial, and at some point, it requires the Microsoft public symbol server to be set up. I ran the command:
set _NT_SYMBOL_PATH=srv*DownstreamStore*https://msdl.microsoft.com/download/symbols
followed by
.symfix+ C:\MySymbols
but I get the infamous error message
'.symfix+' is not recognized as an internal or external command, operable program or batch file.
My environment, running the command systeminfo | findstr /B /C:"OS Name" /C:"OS Version" is:
OS Name: Microsoft Windows 10 Home
OS Version: 10.0.19041 N/A Build 19041
I would appreciate it if you could help me know what is the problem and how I can solve it.
The command
set _NT_SYMBOL_PATH=...
sets an environment variable that attempts to tell all debugging programs where to download symbols. This affects WinDbg, Visual Studio, Process Explorer and others.
The command
.symfix
is WinDbg specific and is an equivalent to the above. Setting both is not necessary.
Please note that you should not enter this part
srv*DownstreamStore*https://msdl.microsoft.com/download/symbols
literally. You should replace the part DownstreamStore by a place where you want the downloaded symbols to be stored on your hard disk. So in your case, this should be C:\MySymbols.
The command .symfix just takes DownstreamStore as an argument and puts srv* before and *https://msdl.microsoft.com/download/symbols after that argument. So using
.symfix C:\MySymbols
is equivalent to
.sympath srv*C:\MySymbols*https://msdl.microsoft.com/download/symbols
but much easier to type.
The + in these commands (.sympath+ or .symfix+) will append another symbol path, assuming that you already had one set up before.
Neither set _NT_SYMBOL_PATH nor .symfix nor .sympath will actually download symbols. The symbols will be downloaded on demand. Use ld*; reload /f when being attached to a process for downloading symbols.
Or, as mentioned by yourself, use the command line tool symchk.
As mentioned in the comment above, the .symfix command is a WinDbg one, which needs to be entered at the software's command line, not the Windows terminal cmd!
However, there are certain command-line tools that can do the job, partly! The complete "WinDbg Command-Line Options" documentation can be seen here. Also, there is the symchk tool coming with the "Windows Driver Kit (WDK)". One can download the "Microsoft's public symbol" database using the command:
symchk "path\to\binary" /s srv*DownstreamStore*https://msdl.microsoft.com/download/symbols
P.S. Usefull common WinDbg commands

GFlags - command lines

I want to start a process that takes a commandline. Using gflags I want to enable page heap and allow windbg to attach to the process each time it starts.
How can I add the commandline parameter in the gflags UI?
You don't. And you're mixing up pretty unrelated things.
PageHeap
To enable the heap verification ("PageHeap") you set the configuration you want using the GFlags utility, either using the GUI or passing it the approporiate command-line arguments (See GFlags and PageHeap). Either way, this setting it global for all binaries with the name you define.
Debugging
To run the program under the debugger each and every time it starts you'd probably want to use the Debugger setting under Image File Execution Options. You can set it too using GFlags. Tick the Debugger checkbox in the Image File tab (after specifying the EXE name and hitting tab) and enter the path to the debugger.
The way this mechanism works is that (somewhere) inside CreateProcess there's a test whether or not IFEO\Debugger is set for the program you're trying to run, and if it is set, whatever set in the Debugger value is executed **and it is passed the original command line*.
So if you set
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\foo.exe\Debugger
to be C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe and then try to execute C:\Users\d_blk\Desktop\foo.exe -param 1 -param 2, Windows runs
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe C:\Users\d_blk\Desktop\foo.exe -param 1 -param 2
and WinDbg passes everything after foo.exe to the target program (as noted here).
So you see, there's no need to set the command-line arguments to the program you're debugging anywhere but wherever you're running it.
The only connection between PageHeap and IFEO\Debugger is that you can control both of them through the GFlags utility.
Caveats
Note all the usual caveats for using IFEO\Debugger. For example:
The caller gets from CreateProcess a handle to WinDbg, not the target process (and process ID, etc.).
Any information in a non-default STARTUPINFO argument applies to WinDbg, not the target process. Same for lpEnvironment I guess.
If that doesn't affect you great. If it does, an alternative might be adding an unhandled exception at the beginning of your program, and setting WinDbg as the post-mortem debugger (AeDebug)

why does cmd.exe in CreateProcess behaves different from DOS-prompt?

I use Altar's GetDOSOutput() (variant 1) to this question to call dos-commands by a simple delphi program. However, existing DOS program's such as DiskPart cannot be found when called by by CreateProcess whereas they present no problem when called from the DOS-prompt (Windows server 2003 X64). What could be the cause of this?
commandline: `ListVolumes.bat'
ListVolumes.bat:
path
C:\WINDOWS\SYSTEM32\DiskPart.exe /s ListVolumes.scr
dir C:\WINDOWS\SYSTEM32\DiskPart.exe
output through the program call:
I:\PartScan>path
PATH=C:\WINDOWS;C:\WINDOWS\System32;C:\WINDOWS\System32\wbem;C:\Program Files (x86)\Borland\Delphi7\Bin; C:\Program Files (x86)\Borland\Delphi7\Projects\Bpl\;
I:\PartScan>C:\WINDOWS\SYSTEM32\DiskPart.exe /s ListVolumes.scr
'C:\WINDOWS\SYSTEM32\DiskPart.exe' is not recognized as an internal or external command,
operable program or batch file.
I:\PartScan>dir C:\WINDOWS\SYSTEM32\DiskPart.exe
Volume in drive C is system
Volume Serial Number is 351F-0221
Directory of C:\WINDOWS\SYSTEM32
File Not Found
output when called from the DOS prompt (note the final dir command):
PATH=C:\WINDOWS;C:\WINDOWS\System32;C:\WINDOWS\System32\wbem;C:\Program Files (x86)\Borland\Delphi7\Bin; C:\Program Files (x86)\Borl
and\Delphi7\Projects\Bpl\;
I:\PartScan>C:\WINDOWS\SYSTEM32\DiskPart.exe /s ListVolumes.scr
Microsoft DiskPart version 5.2.3790.3959
Copyright (C) 1999-2001 Microsoft Corporation.
On computer: ISOETES
Volume ### Ltr Label Fs Type Size Status Info
---------- --- ----------- ----- ---------- ------- --------- --------
Volume 0 F DVD-ROM 0 B Healthy
...
Volume 11 G DVD-ROM 0 B Healthy
I:\PartScan>dir C:\WINDOWS\SYSTEM32\DiskPart.exe
Volume in drive C is system
Volume Serial Number is 351F-0221
Directory of C:\WINDOWS\SYSTEM32
17-Feb-2007 08:17 263,680 diskpart.exe
1 File(s) 263,680 bytes
0 Dir(s) 33,111,334,912 bytes free
You've not shown code so we cannot diagnose this with 100% certainty. However, the likely cause is that your process is a 32 bit process running under the WOW64 emulator. When you create a cmd process under the emulator you get a 32 bit cmd process, also running under the emulator. You are comparing that with a 64 bit process. Do note that under the emulator, system32 is redirected to SysWOW64 by the file system redirector.
The way you deal with this is to create a 64 bit process. That's quite tricky to do for cmd when creating from inside the emulator. The easiest way to do so is to call CreateProcess from a 64 bit process.
Since you use Delphi 7 you may need to use a modern compiler to make a small 64 bit executable that will do the work for you. Call the small executable from your Delphi 7 program.
An alternative that may fit your needs is to use the sysnative alias to reach the 64 bit system directory from inside the emulator. That is described in the file system redirector documentation.

Creating a dump file, copying an error (taking a screenshot) and restarting after an application crash

I'm testing an application in a stress test.
That's why I need it to restart if an error occurs (an error window opens) or it hangs or crashes. At the same time I need to collect all the useful information about the problem which lead to a restart: make a dump file and copy the error text from the error window (and/or take its screenshot).
With bash it's easy: Restarting program automatically on crash in OSX (without screenshots or dumps, but the error window stays on MacOS, so they are practically not needed there). However, I need this functionality to run on Win (XP/Vista/7).
I can use special monitoring tools for restart, but that way I would rely on non-standard programs. I can use User Mode Process Dumper on XP, but it doesn't work for Vista.
Is there any elegant and universal way (batch file or perl script would be great) to implement described functionality for all versions of Windows?
Regarding the 1st part of your question, you can test if a process is running using tasklist.
This will run myapp.exe, restarting it if necessary:
#echo off
set MYAPP=myapp.exe
rem # Loop infinitely and restart the application if it's not running
:Start
tasklist /FI "IMAGENAME eq %MYAPP%" 2>NUL | find /I /N "%MYAPP%" >NUL
if errorlevel 1 %MYAPP%
call :Sleep 1
goto Start
rem # A short sleep subroutine to yield system resources
:Sleep
ping 127.0.0.1 -n %1 -w 1000 > nul
Regarding the 2nd part of your question, you can collect a user mode core dump using AutoDumpPlus.
For instance:
adplus -crash -quiet -pn myapp.exe -o C:\temp
This will run ADPlus, monitoring all processes named myapp.exe, and producing a core dump in the output directory C:\temp (of course, this can be changed) if a crash is detected.
I haven't tested this setup as a whole, but I hope it works for you!

Running Batch Stript in Windows 7 causes process to be launched under wrong cmd process

Whenever I run a batch file on my comuter (64 bit architecture running 64 bit windows 7), the console window that is opened is running in 32-bit mode, and checking the task manager confirms I am indeed running everything as a 32-bit process. I want to run the batch file under a 64-bit process, not a 32-bit process. I have changed the comspec environment variable to point to the proper variable, to no avail. Does anyone know how to fix this so that when I click on the batch file, it everything is run in 64-bit mode.
I realize I could simply open the 64 bit command window and run my batch file. However, this is a workaround and doesn't get at the root of the problem, and won't help when I give file to others.
Thanks,
MM
Are the file associations for .cmd associated with the 32bit cmd.exe or the 64bit cmd.exe?
Can you run the scripts with the full path name to the executable?
"C:\Windows\System32\cmd.exe" /c <batch_name> should run 64-bit
"C:\Windows\SysWOW64\cmd.exe" /c <batch_name> would run in 32-bit
Otherwise, you could change the associations to run the extension .cmd with 64-bit (ftype cmdfile=C:\Windows\System32\cmd.exe /c "%1" %*) and .bat with 32-bit (ftype cmdfile=C:\Windows\SysWOW64\cmd.exe /c "%1" %*).

Resources