GFlags - command lines - debugging

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)

Related

How to launch an external executable on windows in go

I am trying to launch an external executable (msi driver installer) on windows with go. It is referred to with the relative path bin\launchme.msi
As of now, I am using the commander-cli/cmd library and it is working well with other external executable (though only command line ones).
My command is:
c := cmd.NewCommand(`bin\launchme.msi`)
c.Execute()
The executable is launched but displays the following:
An error occurred while writing installation information to disk.
Check to make sure enough disk space is available."
See here:
What is especially confusing to me is that, as you can see on the screenshot, the msi installer created a %SystemDrive% folder in the working directory.
This folder in turn contains a Program Files folder and some more subfolders.
Otherwise, if I simply launch the msi installer by double-clicking it, everything is fine, no error occurs.
Any help with this would be greatly appreciated.
It could be, that your .MSI file is using cmd.exe in the background.
If you type echo %my_env_var% in cmd.exe, there are two cases what can happen:
If the environment variable my_env_var is defined, the built-in echo command of cmd.exe prints it’s value.
If the environment variable my_env_var is not defined, the built-in echo command of cmd.exe prints %my_env_var% literally.
Every process inherits the environment variables of it’s parent process. If a process is started from the (Windows) File Explorer (explorer.exe) or from the (graphical) shell of Windows (also explorer.exe), then it inherits the system settings for environment variables.
It seems like your library is dropping some environment variables like SystemDrive when starting a new process from the executable bin\launchme.msi.
Try to use import("os/exec") from the Go standard library https://pkg.go.dev/os/exec .
For more information about environment variable in Microsoft Windows see for example: https://learn.microsoft.com/en-us/windows/win32/procthread/environment-variables
Tip:
You can use Process Explorer (procexp.exe) to see the environment variables of running processes, by doing this:
Open Process Explorer, to get a list of running processes
Right-click on the process you are intrested in, to open the context menu
In the context menu click on Preferences
In the new window click on the Tab Environment.
one workaround, for testing, would be to launch that Go program in C:\ as working directory:
// caputred is the captured output from all executed source code
// fnResult contains the result of the executed function
captured, fnResult := cmd.CaptureStandardOut(func() interface{} {
c := NewCommand("C:\path\to\bin\launchme.msi", cmd.WithWorkingDir("C:\\")
err := c.Execute()
return err
})
// prints "hello"
fmt.Println(captured)

Unattended WinDbg script for breakpoints and delays

I want to debug an application running on Windows by setting a breakpoint on a certain address, waiting till the breakpoint is hit, keeping the application paused for a certain period of time and then continuing. All of this should be done in an unattended fashion (e.g. a script).
To do this, I chose to use WinDbg since the scripting support seems promising.
Starting WinDbg and attaching to the process by process name can e.g. be done by invoking the following command:
"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe" -pn my-executable.exe
Setting the breakpoint is done with the bu command:
bu 0x1337
Continuing works with the g command.
Delaying can be done with the .sleep command:
.sleep milliseconds
For writing WinDbg scripts this PDF might be helpful.
How can I piece it all together? I didn't figure out how delaying after hitting a breakpoint can be done nor do I know how to perform all of those actions (including attaching) from the command line alone without loading up the WinDbg GUI at all.
what for you need to sleep
you can embed the script commands and pass it to and instance of windbg
with -c switch the command below lists the modules and quits the session
windbg -c "lm;q" calc.exe
you can put it inside a batfile and run the batfile
like
cdb -c "bu %2 \".sleep 5000;g\";g" %1.exe
a gif showing how i broke on winmain slept for 5 seconds before allowing the exe to run below

Difference between calling "start myapp" and "myapp"

In a Windows batch file, or in the Command Prompt, what's the difference between calling start mspaint, for example, and mspaint? They appear to do exactly the same thing.
Another example, where all 4 cases appear to do the same thing. Can you please help me understand what are the subtle differences, if any?
taskmgr
C:\Windows\System32\Taskmgr.exe
start taskmgr
start C:\Windows\System32\Taskmgr.exe
Follow-up: it looks like start opens a separate background command prompt to run the program you write after it (source: https://technet.microsoft.com/en-us/library/cc770297(v=ws.11).aspx). Is this the same as Linux's myApp & format--where you have the & suffix?
Starting a Program
See start /? and call /? for help on all three ways.
Specify a program name
c:\windows\notepad.exe
In a batch file the batch will wait for the program to exit. When
typed the command prompt does not wait for graphical
programs to exit.
If the program is a batch file control is transferred and the rest of the calling batch file is not executed.
Use Start command
start "" c:\windows\notepad.exe
Start starts a program and does not wait. Console programs start in a new window. Using the /b switch forces console programs into the same window, which negates the main purpose of Start.
Start uses the Windows graphical shell - same as typing in WinKey + R (Run dialog). Try
start shell:cache
Also note the first set of quotes, if any, MUST be the window title.
Use Call command
Call is used to start batch files and wait for them to exit and continue the current batch file.
With Reference to Start and just typing a program name.
Help Windows Find Programs and Documents
Programs and documents can be added to the registry so typing their name without their path in the Start - Run dialog box or shortcut enables Windows to find them.
REGEDIT4
;The bolded name below is the name of the document or program, <filename>.<file extension>
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths\IE.txt]
;The # means the path to the file is assigned to the default value for the key.
;The whole path in enclosed in a quotation mark ".
#="\"C:\\Program Files\\Internet Explorer\\IE.txt\""
;Optional Parameters. The semicolon means don't process the line. Remove it if you want to put it in the registry
;Informs the shell that the program accepts URLs.
;"useURL"="1"
;Sets the path that a program will use as its' default directory. This is commented out.
;"Path"="C:\\Program Files\\Microsoft Office\\Office\\"
For a technical discussion.
CMD preprocesses commands and finds the file then calls CreateProcess. Start - Run dialog or the Start command uses ShellExecuteEx which eventually calls CreateProcess.
This is CreateProcess rules - note CMD provides full paths to CreateProcess. https://msdn.microsoft.com/en-us/library/ms682425
1.The directory from which the application loaded.
2.The current directory for the parent process.
3.The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is System.
5.The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
6.The directories that are listed in the PATH environment variable. Note that this function does not search the per-application path specified by the App Paths registry key. To include this per-application path in the search sequence, use the ShellExecute function.
ShellExecuteEx is here https://msdn.microsoft.com/en-us/library/bb759784(v=vs.85).aspx
CMD preprocessing is available on my Skydrive - originally from MS web site but no more. See Windows NT Command Shell Ch 2 https://1drv.ms/f/s!AvqkaKIXzvDieQFjUcKneSZhDjw
you need to call start application when you want the application to launch and return immediately to the command shell for further commands.
(on Linux, closest equivalent of start is the & suffix)
Some commands have the ability to do that without start prefix. That's what you're experiencing.
On the other hand, if you want an application returning immediately to "block" the shell, prefix by cmd /c
Try cmd /c taskmgr for instance, you'll see it blocks the command window until you quit it.
About the question about taskmgr, the 3 possibilities amount to the same result:
taskmgr is in system path: with or without full path the system finds it
taskmgr returns to the command window immediately. In that case, start is redundant.

how do I run an msi with SEE_MASK_NOZONECHECKS without restart

I'm trying to install a driver with a remote framework that lets me run shell commands spawned as children of the remoting/monitoring app on the remote machine, run as cmd /c "command". But the driver refuses to install due to a security feature which thinks the driver may be unsafe.
The driver also has quotes(spaces in path) so its something like
Dim command: command = "\\\\server\\driver\\folder\\Autorun.exe" /passive /norestart";
Set retVal = remote.Shell(command)
which runs
cmd /c " "\\server\driver\folder\Autorun.exe" /passive /norestart"
on the remote machine
I've tried and have had trouble using setx SEE_MASK_NOZONECHECKS 1 /m in a previous statement, I'm guessing that the subprocess don't see new global enviromental variables that weren't around when it's parent started, and won't work without a restart. I'd like to avoid a restart.
I tried running
cmd /c " set SEE_MASK_NOZONECHECKS=1 & "\\server\driver\folder\Autorun.exe" /passive /norestart"
but it doesn't seem to work. Any ideas?
You got a bit lost on the way SEE_MASK_NOZONECHECKS is used. It is not an environment variable and cannot be tinkered with from the command prompt, it is an option for ShellExecuteEx(). A winapi function that you indeed use to start programs. It isn't very clear what programming tools you have access to, using it in a batch file or VBScript isn't going to work. You'd need at least, say, VB.NET and pinvoke the function. You can get the required declarations from the pinvoke.net web site.
Let's talk about what's really going on, you might find a simpler solution. When you download a file from an Internet web site, Windows adds an extra stream to the file that indicates where the file came from. Which basically states "this file did not come from a safe place" and makes the driver installer balky. Which is rather an important feature if you think about it, your user is going to install software that can do a lot, you pretty much have free reign of the machine if you can get a driver installed.
If you right-click the file in Explorer and click Properties then you'll see this at the bottom of the window:
All that's needed is to click that Unblock button. So this is a simple way for your user to solve the problem. You could document the extra step in the install instructions. Also with the advantage that it is now the user that took responsibility of allowing potentially unsafe code to be installed.
Other ways to get the file unblocked is with PowerShell's Unblock-File command and the SysInterals' streams utility, -d option.
And you probably ought to consider the option of writing your own installer. Which will keep the driver packaged in the setup file so it won't be tinkered with by Windows. And the user gets the warning when he starts the installer instead. And it can be signed so the user has some confidence in where the file came from and that it didn't get messed with on its way to his machine. There are many utilities that help you write an installer, like InstallAware, InstallShield, NSIS, etcetera.
I beg to differ to Hans' answer:
Of course, SEE_MASK_NOZONECHECKS is as well a predefined environment variable. Changing it in a process and then starting a child process (e.g. msiexec.exe) which by defaults inherits the environment, has just the same result as using ShellExecuteEx() and providing SEE_MASK_NOZONECHECKS as a parameter to the SHELLEXECUTEINFO structure. The first method is preferred by admins or quick hacks, e.g. if you work with batch or script files which set the environment variable- or when the final call to the .msi file lying on the unsafe network drive is not done by your own code.
For example:
#echo off
set SEE_MASK_NOZONECHECKS=1
call msiexec.exe /i "\\MY_UNC_DRIVE\installs\mysetup.msi /qb /L*v "c:\logs\mysetup.log"
call "\\MY_UNC_DRIVE\installs\Just_another_setup.exe"
If you already use a ShellExecuteEx() in your code, then of course, go with the parameter as Hans mentioned, because this implementation it is more closed. (If you use CreateProcess(), think about using ShellExecuteEx() instead.
Getting back to the environment variable(s). Generally you cannot influence the environment of already started processes. You can set the default environment used by NEW processes by the "setx" command used in the question. But with "setx" you don't change the environment for your current process.This was the problem in question. For this you have to use "set" as shown. So either use both commands after each other or don't use setx at all because for running a setup on foreign machines, it is not clean to make permanent security changes without asking.
For more details on permanent changes/admin point of view, see:
https://superuser.com/questions/595211/removing-the-open-file-security-warning-in-windows-8/934283#934283
Important: As mentioned, there is no general way in Windows to influence processes which already run (only own-defined inter-process-communication maybe), so it is important to set the environment variable before starting the setup to be influenced.
One more thing: Some people think, one must use "SETLOCAL" in a batch file. Normally this is not necessary. Environment changes with "set" are not permanent, and do not incluence "other" processes- they are only inherited to subprocesses and, partly, to superprocesses. But, when the caller on first level ends, the environment is reverted to original state again.
I ended up setting "Launch applications and unsafe files" to enabled for Internet zone in Internet Explorer options under security(custom level) and then exporting the changes from HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3 to a registry file and adding it with regedit /s.
After that I can run the installer of the shared drive.
One of these days I'll pare the registry file down to the minimum I guess.
P.S. I believe this causes IE to default to a warning page on startup.
I believe you need to put everything within the same quotation:
cmd /c "set SEE_MASK_NOZONECHECKS=1 & \\server\driver\folder\Autorun.exe /passive /norestart"
You can try these and see the difference in the output:
cmd /c "echo foo & echo bar"
cmd /c "echo foo" & "echo bar"

How to debug a Windows Search property handler

I'm maintainning a Windows Search property handler project, it is loaded by SearchFilterHost.exe. I don’t know when SearchFilterHost.exe will be launched, don’t know the command line arguments usage, and I find SearchFilterHost.exe will exit one or two minutes after started, so it’s difficult to use the debugger to attach the process then debug the DLL it loaded.
How to debug a Windows Search property handler?
Debugging Protocol Handlers in MSDN talks about how to do this. It involves adding registry entries to make SearchIndexer and SearchFilterHost a little more friendly to debug. You probably will need to take ownership of the registry branch(es) to be able to change the values. Just doing the first set may be enough for you to be able to directly attach to SearchFilterHost.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft
Windows Search
Gathering Manager
DebugFilters = 1
DisableBackOff = 1 may also be helpful
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
Image File Execution Options
SearchIndexer.exe
Debugger = <path to debugger> <debugger options>
Example using the ntsd debugger
Debugger = C:\debuggers\ntsd.exe -odGx -c: "sxe ld mydll.dll;g"
Option Description
-o Tells ntsd.exe to debug child prcoesses.
-d Pipes ntsd.exe through the kernel debugger to ensure the debugger is lauched on the right desktop (system context).
-g Tells ntsd.exe to exit immediately when the child terminates.
-x Disables first-chance break on access violation exceptions. The second occurrence of an access violation will break into the debugger.
-c Sets the order of commands passed ntsd.exe.
Once you have things set up, restart the WSearch service, tweak your searched file, and things should happen.
Also, here's an old thread of others' experiences. Among other things, it talks about using the MSDN tool IFiltTst in your project's debug settings.
In your Project properties window, open ‘configuration properties’, ‘debugging’; and enter the following settings:
Debugger to launch: Local Windows Debugger
Command: C:\<your path here>\IFiltTst.Exe
Command arguments: /i "D:\<your project test folder>\<good file>.<extention to filter>" /v 3 /t 5 /l /d
Working directory: /i "D:\<your project test folder>
Attach: No
Leave all other settings as default.
Both methods require your DLL to be registered so it will be found by Search.

Resources