OutputDebugString / System.Diagnostics.Debug.WriteLine and Debugger.IsAttached - c#

I need to check if OutputDebugString / System.Diagnostics.Debug.WriteLine's output will go to never never land.
Seems like OutputDebugString is a native method while System.Diagnostics.Debug.WriteLine is writing to internal trace listeners.
Is Debugger.IsAttached a sufficient check for this?
Debugger.IsAttached doesn't seem to pick up if something like DebugView is running. I need to be able to check if ANYTHING will see output from OutputDebugString / System.Diagnostics.Debug.WriteLine.

If you are willing to get your hands dirty and use some native stuff you can achieve this. You'll need to use P/Invoke.
OutputDebugString, as you can read here, is based on 4 kernel objects. Mutex named DBWinMutex, a shared memory DBWIN_BUFFER and two events (DBWIN_BUFFER_READY and DBWIN_DATA_READY) as they wrote in the article - we can't relay on the mutex as it exists all the time. But we could check if the shared section is created.
If we import OpenFileMapping to our project from pinvoke.net
static class NativeFunctions
{
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr OpenFileMapping(
uint dwDesiredAccess,
bool bInheritHandle,
string lpName);
}
Then we can check if the section is created or not and based on that decide whether something is listening.
Writing this simple program
public const int FILE_MAP_READ = 0x0004;
static void Main(string[] args)
{
if (NativeFunctions.OpenFileMapping(FILE_MAP_READ, false, "DBWIN_BUFFER") != IntPtr.Zero)
{
Log("Someone is listening");
}
else
{
Log("I am here alone");
}
}
private static void Log(string log)
{
Debug.WriteLine(log);
Console.WriteLine(log);
}
When running without DebugView we get "I'm here alone"
and with the tool
Additionally to clarify the things ".. while System.Diagnostics.Debug.WriteLine is writing to internal trace listeners." Debug.WriteLine will also write to the same place as OutputDebugString but only if VS is not attached - otherwise VS will capture the log and post to its Output window.

Related

How to make Console App listen for keypresses from other processes?

I'm new to C# programming and I'm attempting to write a Console App that will run in the background and perform an action when a key is pressed (ideally I would like to know how to do this for any key but, if that's not possible, then a specific key).
Here's an idea of what I want (please excuse and feel free to correct any bad coding as I'm just starting out).
public static void Main(string[] args)
{
while(true)
{
ConsoleKeyInfo cki = Console.ReadKey();
if( cki.Key == ConsoleKey.R )
{
Console.WriteLine("Run me");
}
}
}
The above seems to work but only if the Console App is in focus. I would like it to happen even if the app isn't in focus.
I've done some research and read about registering 'hotkeys' but also read that this is dangerous in case another application is requiring that key?
I've also read similar questions on here but they seem to deal with Windows Forms and not just Console Apps.
Can anyone help shed any light on this?
You need to use
[DllImport("user32", SetLastError = true)]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32", SetLastError = true)]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
But to make it work from console you'll need to create hidden form that will handle messages for you. Check out this class. It does exactly what you want.

Code stops executing when a user clicks on the console window

I've got a console application that executes my code without user interaction. If the user clicks within the console window, on purpose or on accident, all execution stops.
This has something to do with copying text from the console window. The only way for the application to start executing again is if the user selects text and then right-clicks on the console window, copying it to the clipboard.
To see this in action, create a console application and add the following code.
class Program
{
static void Main(string[] args)
{
var task = Task.Run(async () =>
{
int i = 0;
while (true)
{
Console.WriteLine(i++);
await Task.Delay(1000);
}
});
Console.ReadLine();
}
}
When you click on the console window, the Task thread stops executing. This is not desirable behavior at all, and I want to prevent this from happening in my console application.
How can I prevent this? None of the properties/events on the console window have anything to do with controlling this behavior, as far as I can see.
As you can see, when i'm click within window appear cursor. When i press any key - cursor gone and app continue working
This happens if you have Quick Edit Mode enabled on the console window. If you right-click on the title bar and select Properties, then select the Options tab, you can check to see if Quick Edit Mode is enabled. If you disable Quick Edit Mode, then the scrolling doesn't stop when you click in the window.
The reason scrolling stops is because a mouse clicked in the window is used to select text.
You can disable Quick Edit Mode on the console in your program, but doing so requires calling the GetConsoleMode and SetConsoleMode API functions. Here's how you would do it:
[DllImport("kernel32.dll", SetLastError=true)]
public static extern IntPtr GetConsoleWindow();
[DllImport("kernel32.dll", SetLastError=true)]
public static extern bool GetConsoleMode(
IntPtr hConsoleHandle,
out int lpMode);
[DllImport("kernel32.dll", SetLastError=true)]
public static extern bool SetConsoleMode(
IntPtr hConsoleHandle,
int ioMode);
/// <summary>
/// This flag enables the user to use the mouse to select and edit text. To enable
/// this option, you must also set the ExtendedFlags flag.
/// </summary>
const int QuickEditMode = 64;
// ExtendedFlags must be combined with
// InsertMode and QuickEditMode when setting
/// <summary>
/// ExtendedFlags must be enabled in order to enable InsertMode or QuickEditMode.
/// </summary>
const int ExtendedFlags = 128;
void DisableQuickEdit()
{
IntPtr conHandle = GetConsoleWindow();
int mode;
if (!GetConsoleMode(conHandle, out mode))
{
// error getting the console mode. Exit.
return;
}
mode = mode & ~(QuickEditMode | ExtendedFlags);
if (!SetConsoleMode(conHandle, mode))
{
// error setting console mode.
}
}
void EnableQuickEdit()
{
IntPtr conHandle = GetConsoleWindow();
int mode;
if (!GetConsoleMode(conHandle, out mode))
{
// error getting the console mode. Exit.
return;
}
mode = mode | (QuickEditMode | ExtendedFlags);
if (!SetConsoleMode(conHandle, mode))
{
// error setting console mode.
}
}
If you go down this route, it's probably a good idea to save the original console mode setting when your program starts, and restore it when your program exits. So at startup:
GetConsoleMode(GetConsoleWindow(), ref saveConsoleMode);
and when your program terminates:
SetConsoleMode(GetConsoleWindow(), saveConsoleMode);
With appropriate error handling, of course. You wouldn't want to restore the console mode if the call to GetConsoleMode failed.
I just saw that this answer linked in the comments of OP's question contained what I found by myself. I will keep my answer because people might not see it, just like me, and it would spare them a lot of time.
Jim's answer did not work for me, I couldn't figure out why.
I dug around and found a solution that works, so I'll share my findings, hopefully helping someone in the same situation.
The problem was with the handle that I got from GetConsoleWindow(), it gave a Win32 error (0x6) where the handle is invalid when I tried to use it. The call to SetConsoleMode() did nothing.
To get a working handle, I used GetStdHandle() to get the Input handle for the console. Add this to Jim's code :
public const int STD_INPUT_HANDLE = -10;
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern IntPtr GetStdHandle(int nStdHandle);
Then replace GetConsoleWindow() by GetStdHandle(STD_INPUT_HANDLE) in DisableQuickEdit() and EnableQuickEdit() in Jim's code.
After calling DisableQuickEdit(), the selection is disabled in the console.
Thanks Jim !

C# : How to detect if screen reader is running?

How to detect if screen reader is running (JAWS)?
As I understand in .NET 4 we can use AutomationInteropProvider.ClientsAreListening from System.Windows.Automation.Provider namespace, but what if I have to do it for .NET 2.0?
I tried to inspect ClientsAreListening source code, it calls external RawUiaClientsAreListening method from UIAutomationCore.dll library.
Do you have any ideas how to implement JAWS detection in .NET 2.0?
Use the SystemParametersInfo function passing a uiAction of SPI_GETSCREENREADER.
You will need to use P/Invoke for this, for example:
internal class UnsafeNativeMethods
{
public const uint SPI_GETSCREENREADER = 0x0046;
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref bool pvParam, uint fWinIni);
}
public static class ScreenReader
{
public static bool IsRunning
{
get
{
bool returnValue = false;
if (!UnsafeNativeMethods.SystemParametersInfo(UnsafeNativeMethods.SPI_GETSCREENREADER, 0, ref returnValue, 0))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "error calling SystemParametersInfo");
}
return returnValue;
}
}
}
This is possibly better than using the ClientsAreListening property as this property appears to return true for any automation client, not just screen readers.
Also see:
Using SystemParametersInfo from C# (SPI_GETSCREENREADER SPI_SETSCREENREADER) (Stack Overflow)
INFO: How Clients and Servers Should Use SPI_SETSCREENREADER and SPI_GETSCREENREADER (Microsoft KB)
You should also listen for the WM_SETTINGCHANGE message to detect if a screen reader starts / stops running.
Update (in response to BrendanMcK's comments):
Although this is never explicitly documented in as many words, looking at the description of the flag I think the purpose of this flag is relatively clear:
Determines whether a screen reviewer utility is running. A screen reviewer utility directs textual information to an output device, such as a speech synthesizer or Braille display. When this flag is set, an application should provide textual information in situations where it would otherwise present the information graphically.
What this is saying is that applications set this flag whenever an application wishes the UI to behave as if a screen reader is running, regardless of whether or not that application is actually a screen reader or not.
Suitable things to do in response to this flag is to add text in order to "read" otherwise intuitive UI state to the user. If radical changes are needed to make your UI screen reader accessible then the chances are that your UI also isn't that intuitive to sigted users and could probably do with a re-think.

Windows Mobile 6.5 SndPlayAsync - C# wrapper?

I'm implementing mp3 playback on Windows Mobile 6.5. I need to use SndPlayAsync API function since I don't want to block calling thread until the file is played (SndPlaySync blocks until the audio file is playing). Unfortunately the SndPlayAsync method takes sound handle instead of sound file path as parameter so there's a need to open the handle before and release of it after playback. The problem is that I don't have any information about the playback completion in this API. Did anybody use a C# wrapper for this API? Where can I get one? I've looked up OPENNETCF but they seem not to support this API.
Regards
You have to call SndOpen first to get the handle. Looking at the docs, the declarations would be something along these lines:
[DllImport("coredll", SetLastError=true)]
public static extern int SndOpen(string fileName, out IntPtr handle);
[DllImport("coredll", SetLastError=true)]
public static extern int SndPlayAsync (IntPtr handle, int flags);
[DllImport("coredll", SetLastError=true)]
public static extern int SndClose(IntPtr handle);
So you'd use something like this to call it:
IntPtr handle;
var result = SndOpen("myfile.mp3", out handle);
if(result == 0) SndPlayAsync(handle, 0);
...
SndClose(handle);
If you are using .NET CF there is no reason to create a wrapper, you can just use the System.Media.SoundPlayer class to handle it. There are several options including PlaySync which will play the sound synchronously.
For instance:
string path = "\\Program Files\\SNAP.App.CE\\Content\\5LongLow.wav";
System.Media.SoundPlayer player = new System.Media.SoundPlayer(path);
player.PlaySync();
You can also put it in a separate thread if you don't want to block the UI thread.
You can use SndGetWaitHandle to get a handle to an event which will be signaled when the sound is finished playing. You can use the WaitForSingleObject API to wait or test if the event has been set.

Call a function from an injected DLL

First off I would like to say, that I am not trying to hack a game. I am actually employed by the company whose process I am trying to inject. :)
I would like to know how to call a function from an already injected DLL.
So, I have successfully injected and loaded my DLL in the target using CreateRemoteThread(). Below you can see a snippet of the injection:
private static bool Inject(Process pToBeInjected, string sDllPath,out string sError, out IntPtr hwnd, out IntPtr hLibModule)
{
IntPtr zeroPtr = (IntPtr)0;
hLibModule = zeroPtr;
IntPtr hProcess = NativeUtils.OpenProcess(
(0x2 | 0x8 | 0x10 | 0x20 | 0x400), //create thread, query info, operation ,write, and read
1,
(uint)pToBeInjected.Id);
hwnd = hProcess;
IntPtr loadLibH = NativeUtils.GetProcAddress( NativeUtils.GetModuleHandle("kernel32.dll"),"LoadLibraryA");
IntPtr dllAddress = NativeUtils.VirtualAllocEx(
hProcess,
(IntPtr)null,
(IntPtr)sDllPath.Length, //520 bytes should be enough
(uint)NativeUtils.AllocationType.Commit |
(uint)NativeUtils.AllocationType.Reserve,
(uint)NativeUtils.MemoryProtection.ExecuteReadWrite);
byte[] bytes = CalcBytes(sDllPath);
IntPtr ipTmp = IntPtr.Zero;
NativeUtils.WriteProcessMemory(
hProcess,
dllAddress,
bytes,
(uint)bytes.Length,
out ipTmp);
IntPtr hThread = NativeUtils.CreateRemoteThread(
hProcess,
(IntPtr)null,
(IntPtr)0,
loadLibH, //handle to LoabLibrary function
dllAddress,//Address of the dll in remote process
0,
(IntPtr)null);
uint retV= NativeUtils.WaitForSingleObject(hThread, NativeUtils.INFINITE_WAIT);
bool exitR = NativeUtils.GetExitCodeThread(hThread, out hLibModule);
return true;
}
Note: Error checking and freeing resources were removed for brevity, but rest assured I check all the pointers and free my resources.
After the function above exits, I have a non-zero module handle to my DLL returned by LoadLibrary through hLibModule, meaning that the DLL was loaded correctly.
My DLL is a C# class library meant to show a message box (for testing). I have tried testing the function and the message box pops up. It looks like this:
public class Class1
{
public static void ThreadFunc(IntPtr param )
{
IntPtr libPtr = LoadLibrary("user32.dll");
MessageBox(IntPtr.Zero, "I'm ALIVE!!!!", "InjectedDll", 0);
}
[DllImport("kernel32", SetLastError = true)]
public static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int MessageBox(IntPtr hWnd, String text, String caption, int options);
}
I compile it from Visual Studio and the DLL appears in the Debug folder. I then pass the full path of my DLL to the injector.
After injection into the target process, I don't know how to call my ThreadFunc from the injected DLL, so it never executes.
I cannot use GetProcAddress(hLibModule,"ThreadFunc") since I am out of process, so the answer must lie into calling CreateRemoteThread() somehow. Also, I have read that DllMain is no longer allowed for .NET DLLs, so I cannot get any free execution that way either.
Does anyone have any idea how to call a function from an injected DLL?
Thank you in advance.
Well, you already got a thread running inside that process. You make it do something boring, it only loads a DLL. This works completely by accident, LoadLibrary just happens to have to correct function signature.
It can do much more. That however better be unmanaged code, just like LoadLibrary(), you cannot count on any managed code running properly. That takes a heckofalot more work, you have to load and initialize the CLR and tell it to load and execute the assembly you want to run. And no, you cannot load the CLR in DllMain().
Keywords to look for are CorBindToRuntimeEx() and ICLRRuntimeHost::ExecuteInAppDomain(). This is gritty stuff to get going but I've seen it done. COM and C++ skills and generous helpings of luck required.

Categories

Resources