Coding

 

Coding [koh-ding]: verb, to translate (a program) into language that can be communicated to the computer.

That about covers it. So here are all things relating to general coding & development.

 

Keeping in line with our previous post “How to prevent users from killing your service or process” and continuing down the road of securing our service this post looks at the prevention of debugging. There are a lot of anti-debugging posts out there, most of them written in C++ and assembly and are therefor of little use to the managed world. One of the most complete I’ve seen is from Symantec “Windows Anti-Debug Reference | Symantec Connect Community” and an interesting one on stackoverflow “What is your favourite anti-debugging trick?“. These both fall short on providing any solution that is both easy to implement and built with managed code.

Let’s face it nothing is going to be bullet proof in this arena, and certainly not the solution I’m going to suggest. Yet it is easy and will prevent someone from attaching a debugger after the program is running. I’m really not concerned with trying to prevent a debug-session from startup. Why? Because you can’t. The debugger can jump past any code you have that tries to verify that a debugger is not currently active. Besides this it provides me very little value, I want to protect an actively running process (a service). If the user has the rights to stop it in the first place (i.e. they are an admin) then there isn’t anything I can do to stop them from debugging.

What I want is to prevent someone from attaching a debugger to this service to protect potentially sensitive information. How? Well as it turns out the easiest way to prevent a debug session from starting is with a debug session. So what we need is to debug ourselves! Oh wait you can’t :( but what you can do is easily spawn another process to debug this process while we debug that new process. This reciprocal or circular debug session will prevent either process from being debugged. Further, any attempt to kill either process will immediately terminate the other process thus thwarting an effort to kill one debugger so that you can attach one.

To accomplish this in managed code we have two choices, either using the managed debugger API or the native win32 debugger API. It turns out that the managed debugger is excessively complicated and requires an extraordinary amount of COM code to pull it off (see the mdbg sample) So I chose to go with a raw win32 debug session and see if we could pull that off easily with a few PInvoke calls. Sure enough, this is really easy.

So let’s jump in and take a look at the debugging API calls we are going to need…

const int DBG_CONTINUE = 0x00010002;
const int DBG_EXCEPTION_NOT_HANDLED = unchecked((int)0x80010001);

enum DebugEventType : int
{
    CREATE_PROCESS_DEBUG_EVENT = 3, //Reports a create-process debugging event. The value of u.CreateProcessInfo specifies a CREATE_PROCESS_DEBUG_INFO structure.
    CREATE_THREAD_DEBUG_EVENT = 2, //Reports a create-thread debugging event. The value of u.CreateThread specifies a CREATE_THREAD_DEBUG_INFO structure.
    EXCEPTION_DEBUG_EVENT = 1, //Reports an exception debugging event. The value of u.Exception specifies an EXCEPTION_DEBUG_INFO structure.
    EXIT_PROCESS_DEBUG_EVENT = 5, //Reports an exit-process debugging event. The value of u.ExitProcess specifies an EXIT_PROCESS_DEBUG_INFO structure.
    EXIT_THREAD_DEBUG_EVENT = 4, //Reports an exit-thread debugging event. The value of u.ExitThread specifies an EXIT_THREAD_DEBUG_INFO structure.
    LOAD_DLL_DEBUG_EVENT = 6, //Reports a load-dynamic-link-library (DLL) debugging event. The value of u.LoadDll specifies a LOAD_DLL_DEBUG_INFO structure.
    OUTPUT_DEBUG_STRING_EVENT = 8, //Reports an output-debugging-string debugging event. The value of u.DebugString specifies an OUTPUT_DEBUG_STRING_INFO structure.
    RIP_EVENT = 9, //Reports a RIP-debugging event (system debugging error). The value of u.RipInfo specifies a RIP_INFO structure.
    UNLOAD_DLL_DEBUG_EVENT = 7, //Reports an unload-DLL debugging event. The value of u.UnloadDll specifies an UNLOAD_DLL_DEBUG_INFO structure.
}

[StructLayout(LayoutKind.Sequential)]
struct DEBUG_EVENT
{
    [MarshalAs(UnmanagedType.I4)]
    public DebugEventType dwDebugEventCode;
    public int dwProcessId;
    public int dwThreadId;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
    public byte[] bytes;
}

[DllImport("Kernel32.dll", SetLastError = true)]
static extern bool DebugActiveProcess(int dwProcessId);
[DllImport("Kernel32.dll", SetLastError = true)]
static extern bool WaitForDebugEvent([Out] out DEBUG_EVENT lpDebugEvent, int dwMilliseconds);
[DllImport("Kernel32.dll", SetLastError = true)]
static extern bool ContinueDebugEvent(int dwProcessId, int dwThreadId, int dwContinueStatus);
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern bool IsDebuggerPresent();

The structure DEBUG_EVENT above is actually only 96 bytes in total and the bytes 12 to 96 are actually a union. I did not need any real details about the specifics so I chose to use slam a blob here and not worry about it. The byte array could be reduced in theory to 84 bytes but I really didn’t care since we are only going to create a single one of these. The rest is pretty strait-forward PInvoke junk, nothing fancy.

Using the methods above to debug a process looks something like the following code:

// Start a thread to perform the debug loop
new Thread(DebuggerThread) { IsBackground = true, Name = "DebuggerThread" }
    .Start(processId);
// Debugging thread main loop
static void DebuggerThread(object arg)
{
    DEBUG_EVENT evt = new DEBUG_EVENT();
    evt.bytes = new byte[1024];
    // Attach to the process we provided the thread as an argument
    if (!DebugActiveProcess((int)arg))
        throw new Win32Exception();

    while (true)
    {
        // wait for a debug event
        if (!WaitForDebugEvent(out evt, -1))
            throw new Win32Exception();
        // return DBG_CONTINUE for all events but the exception type
        int continueFlag = DBG_CONTINUE;
        if (evt.dwDebugEventCode == DebugEventType.EXCEPTION_DEBUG_EVENT)
            continueFlag = DBG_EXCEPTION_NOT_HANDLED;
        // continue running the debugee
        ContinueDebugEvent(evt.dwProcessId, evt.dwThreadId, continueFlag);
    }
}

Frankly I had no idea how trivial this was to do. Once I had this working I was able to quickly build a method that takes my program arguments and detects if it is a parent or child process and act appropriately. For the child we need only debug our parent process, for the parent we need to both spawn the child and debug it. Ideally this would be done as a single step since it is possible to start a process as a debugee; however, I didn’t bother to figure out how to do that. If you know and don’t mind sharing please drop a comment. Since I do know how to start a process and I know how to debug an active process I chose that approach. It doesn’t seem like it would be any more or less secure, but I could be wrong on that point. Anyway the following is what my process start-up looks like…

static void Main(string[] args)
{
    NativeDebug.DebugSelf(args);
    ... stuff ...
}
public static void DebugSelf(string[] args)
{
    Process self = Process.GetCurrentProcess();
    // Child process?
    if (args.Length == 2 && args[0] == "--debug-attach")
    {
        int owner = int.Parse(args[1]);
        Process pdbg = Process.GetProcessById(owner);
        new Thread(KillOnExit) { IsBackground = true, Name = "KillOnExit" }.Start(pdbg);
        //Wait for our parent to debug us
        WaitForDebugger();
        //Start debugging our parent process
        DebuggerThread(owner);
        //Now is a good time to die.
        Environment.Exit(1);
    }
    else // else we are the Parent process...
    {
        ProcessStartInfo psi =
            new ProcessStartInfo(Environment.GetCommandLineArgs()[0], "--debug-attach " + self.Id)
                {
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    ErrorDialog = false,
                    WindowStyle = ProcessWindowStyle.Hidden
                };
        // Start the child process
        Process pdbg = Process.Start(psi);
        if (pdbg == null)
            throw new ApplicationException("Unable to debug");
        // Monitor the child process
        new Thread(KillOnExit) {IsBackground = true, Name = "KillOnExit"}.Start(pdbg);
        // Debug the child process
        new Thread(DebuggerThread) {IsBackground = true, Name = "DebuggerThread"}.Start(pdbg.Id);
        // Wait for the child to debug us
        WaitForDebugger();
    }
}
static void WaitForDebugger()
{
    DateTime start = DateTime.Now;
    while (!IsDebuggerPresent())
    {
        if ((DateTime.Now - start).TotalMinutes > 1)
            throw new TimeoutException("Debug operation timeout.");
        Thread.Sleep(1);
    }
}
static void KillOnExit(object process)
{
    ((Process)process).WaitForExit();
    Environment.Exit(1);
}

So we’ve written about 100 lines of code or so and spent almost no time at all getting it up and running, a good ROI for this kind of stuff. It worked quite well even running under the NETWORK SERVICE account as a service. It certainly stops me from debugging it although I’m certainly not what I’d call an accomplished hacker. Given the time and effort to put this together I’d have to call it a win for active debugger prevention. The down side of course is that there are now two processes running and trying to tell them apart is difficult at first launch.

If you’re going to do something like this, I would suggest adding an ‘if (!IsDebuggerPresent())’ to the else clause of our DebugSelf method above. This would allow you to launch with a debugger but not to attach one at a later time. Have fun with it and as with any code on this site, “Don’t blame me”. I didn’t make you use it ;)

My own intentions for this are to make a reasonable effort to secure a service running in a controlled but insecure environment. I would never ship something like this to a customer and hope you would not either. Preventing a consumer from accessing software they purchased is not at all what I’m after. IMHO if information is on their machine it is theirs to debug and view all they want.

One more thing, in case you are wondering this was not my idea. I read about doing this in a security article some years ago but I can’t seem to locate it.

 

Before I say another word, I have read “The arms race between programs and users” and wholeheartedly agree. You can not, and should not, attempt to stop an Administrator from killing your process or stopping your service. That is not what we are trying to do here, we are trying to prevent Joe User from disrupting our process.

So let’s get started, to do this we want to adjust our process’ access control list. The individual rights we can grant and deny are discussed on MSDN in the articled titled “Process Security and Access Rights“. Though most of that article is about creating a process with specific rights, in this case we want to modify the rights of our current process. To do this we are going to PInvoke GetKernelObjectSecurity to obtain the DACL (Discretionary Access Control List), modify it using the RawSecurityDescriptor, and finally write it back using the SetKernelObjectSecurity API. This should be somewhat familiar to those of you that followed that part of building our service.

Step 1 – Obtaining the process DACL

[DllImport("advapi32.dll", SetLastError = true)]
static extern bool GetKernelObjectSecurity(IntPtr Handle, int securityInformation, [Out] byte[] pSecurityDescriptor,
                                           uint nLength, out uint lpnLengthNeeded);

public static RawSecurityDescriptor GetProcessSecurityDescriptor(IntPtr processHandle)
{
    const int DACL_SECURITY_INFORMATION = 0x00000004;
    byte[] psd = new byte[0];
    uint bufSizeNeeded;
    // Call with 0 size to obtain the actual size needed in bufSizeNeeded
    GetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION, psd, 0, out bufSizeNeeded);
    if (bufSizeNeeded < 0 || bufSizeNeeded > short.MaxValue)
        throw new Win32Exception();
    // Allocate the required bytes and obtain the DACL
    if (!GetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION,
                                        psd = new byte[bufSizeNeeded], bufSizeNeeded, out bufSizeNeeded))
        throw new Win32Exception();
    // Use the RawSecurityDescriptor class from System.Security.AccessControl to parse the bytes:
    return new RawSecurityDescriptor(psd, 0);
}

And you thought that was going to be hard? Of course we also need to be able to save the DACL. So…

Part 2 – Updating the process DACL

[DllImport("advapi32.dll", SetLastError = true)]
static extern bool SetKernelObjectSecurity(IntPtr Handle, int securityInformation, [In] byte[] pSecurityDescriptor);

public static void SetProcessSecurityDescriptor(IntPtr processHandle, RawSecurityDescriptor dacl)
{
    const int DACL_SECURITY_INFORMATION = 0x00000004;
    byte[] rawsd = new byte[dacl.BinaryLength];
    dacl.GetBinaryForm(rawsd, 0);
    if (!SetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION, rawsd))
        throw new Win32Exception();
}

Cool, that was easy, so we are ready now right? Not quite, we still need to get the process handle. A simple thing for our own process:

Part 3 – Getting the current process

[DllImport("kernel32.dll")]
public static extern IntPtr GetCurrentProcess();

It just gets easier and easier. Since this is the current process there (AFAIK) is not any reason to duplicate handle and request additional permissions. This handle should have access to do anything. So the only thing left before we can modify the permissions is to define what those permissions are.

Part 4 – Process access rights

[Flags]
public enum ProcessAccessRights
{
    PROCESS_CREATE_PROCESS =0x0080, //	Required to create a process.
    PROCESS_CREATE_THREAD = 0x0002, //	Required to create a thread.
    PROCESS_DUP_HANDLE = 0x0040, //	Required to duplicate a handle using DuplicateHandle.
    PROCESS_QUERY_INFORMATION = 0x0400, //	Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken, GetExitCodeProcess, GetPriorityClass, and IsProcessInJob).
    PROCESS_QUERY_LIMITED_INFORMATION = 0x1000, //	Required to retrieve certain information about a process (see QueryFullProcessImageName). A handle that has the PROCESS_QUERY_INFORMATION access right is automatically granted PROCESS_QUERY_LIMITED_INFORMATION. Windows Server 2003 and Windows XP/2000:  This access right is not supported.
    PROCESS_SET_INFORMATION = 0x0200, //	Required to set certain information about a process, such as its priority class (see SetPriorityClass).
    PROCESS_SET_QUOTA = 0x0100, //	Required to set memory limits using SetProcessWorkingSetSize.
    PROCESS_SUSPEND_RESUME = 0x0800, //	Required to suspend or resume a process.
    PROCESS_TERMINATE = 0x0001, //	Required to terminate a process using TerminateProcess.
    PROCESS_VM_OPERATION = 0x0008, //	Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory).
    PROCESS_VM_READ = 0x0010, //	Required to read memory in a process using ReadProcessMemory.
    PROCESS_VM_WRITE = 0x0020, //	Required to write to memory in a process using WriteProcessMemory.
    DELETE = 0x00010000, //	Required to delete the object.
    READ_CONTROL = 0x00020000, //	Required to read information in the security descriptor for the object, not including the information in the SACL. To read or write the SACL, you must request the ACCESS_SYSTEM_SECURITY access right. For more information, see SACL Access Right.
    SYNCHRONIZE = 0x00100000, //	The right to use the object for synchronization. This enables a thread to wait until the object is in the signaled state.
    WRITE_DAC = 0x00040000, //	Required to modify the DACL in the security descriptor for the object.
    WRITE_OWNER = 0x00080000, //	Required to change the owner in the security descriptor for the object.
    STANDARD_RIGHTS_REQUIRED = 0x000f0000,
    PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF),//	All possible access rights for a process object.
}

Part 5 – Put it all together

// Get the current process handle
IntPtr hProcess = GetCurrentProcess();
// Read the DACL
var dacl = GetProcessSecurityDescriptor(hProcess);
// Insert the new ACE
dacl.DiscretionaryAcl.InsertAce(
    0,
    new CommonAce(
        AceFlags.None,
        AceQualifier.AccessDenied,
        (int)ProcessAccessRights.PROCESS_ALL_ACCESS,
        new SecurityIdentifier(WellKnownSidType.WorldSid, null),
        false,
        null)
);
// Save the DACL
SetProcessSecurityDescriptor(hProcess, dacl);

The ace we’ve added now will try to deny access to the “Everyone” group (aka WorldSid) to do anything with our process. We need not fear that we are interrupting an administrator’s ability to perform any action they desire. They will have any access required that’s why we call them administrators :) As I said in the beginning, we are not trying to stop Administrators, we just want to make sure they are an administrator if they plan to modify or kill this process.

We could of course be more discrete about the rights we are trying to deny, that is entirely up to you.

 

Let’s face it the clever guys at Google have more bandwidth than the rest of the nation combined. What better to do with all that excess pipe ;) There are of course numerous posts about the performances of +1 buttons. If you missed them there is the ever popular Google +1 Button Performance Review, and Why You Should Not Implement the Google +1 Button At This Time. Both of these have since been updated to indicate that the issues have been addressed. While I will admit that they have solved making the buttons asynchronous (If you implement it correctly) they are still far from done IMHO.

As you may or may not be aware I’ve recently added plus-one buttons to all the post titles on my site in the hopes that you will click one for me. Go click one. I mean it. Never-mind. Anyway the +1 button is cool but it currently performs like a dog. For every button you display an iframe is created that internally uses 5 different resources. Then of course there are two scripts on containing page. The worst part for me is waiting to see these ‘magic’ buttons just pop up out of the blue a second or so after the page loads. All-in-all it is not an impressive experience, so I decided to do something about it.

Completely Lazy Loaded +1 Buttons

It turns out it is really easy to get the experience I wanted. I wanted the +1 button images to show up immediately and then if someone desires to interact with them we’ll create the ‘real’ +1 button. The following solution was created to do just that, inline images and no scripts until required.

The first thing we need is a new HTML placeholder to use instead of the “g:plusone” tag. I chose to use an anchor tag, but a div works too:

<a class="plusone"
    title="+1"
    onclick="return false;"
    href="http://csharptest.net/"
    onmouseover="renderPlusOne({parent:this,href:this.href});" >
</a>

If you are using a div tag you can remove the onclick handler, but this gets us… what? a link? … no we some css to turn this anchor into a proper placeholder:

.plusone {
    display: inline-block;
    width: 24px; height: 15px;
    padding: 0px; margin: 0px; overflow: hidden;
    border: none; background-image: url("http://csharptest.net/images/plusone.png");
}

The image I’m using ‘plusone.png’ was extracted from +1′s sprite.png for the size I wanted, small. So at this point we have a nice place-holder that only needs the single image resource to render. Now what do we do with the scripts? Well we need to implement the ‘renderPlusOne’ method from the ‘onmouseover’ event above. Google was nice enough to provide a gapi.plusone.render method that allows us to explicitly render the +1 button. The only problem is before we call that method we need the plusone.js script on our page. So we have two choices, load it even though we may not use it, or defer loading it until the user wants it. Obviously I’m going after the later approach. If you don’t mind the script, just load it and you’ll only need to call render directly in the onmouseover event. Assuming you want to lazy load all scripts you just need to include the following javascript fragment:

var loadgapi=(function(item){
  loadgapi=null;
  var po=document.createElement('script');po.type='text/javascript';po.async=true;
  po.src = 'https://apis.google.com/js/plusone.js';
  po.onload = (function() { renderPlusOne(item); });
  po.onreadystatechange = (function() { renderPlusOne(item); });
  var s=document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
});
function renderPlusOne(item) {
  if(loadgapi != null) { loadgapi(item); }
  else {
    try {
      gapi.plusone.render(item.parent, { href: item.href, size: "small", annotation: "none" });
      item.parent.onmouseover = null;
    } catch (e) { }
  }
}

I’ve run this in the only browser that matters, Chrome, as well as a few of the others like Safari, Firefox, and IE (8 and 9). Try it for yourself, all the plus one buttons on this page are using this code. Feel free to drop a comment by following the title link.
Sample:

 

If you’ve missed it there is great article entitled Keep it secret, keep it safe by Eric Lippert. Essentially it attempts to dissect the essence of typical crypto issues in plain English (i.e. crypto for dummies). He did a great job of explaining the difficulties in key management, worth a read.

I found it particularly interesting that he brought up this topic since just days ago I released a “SecureTransfer” class. I’ll get more into the details of that later, but it is interesting here because it happens to be very susceptible to the very issue he warns about. To put the problem in simple terms:

The best implementations of cryptography out there are only as secure as their key storage.

This is most certainly true for the SecureTransfer client/server classes. That doesn’t mean that implementing a secure communication channel is easy. Far from it. It just means that *if* you’ve implemented a secure channel it’s most obvious attack vector is to crack the key store.

Key storage for HttpClone

This very problem was one of the first things I had to address with HttpClone (which is now serving this website). To publish content from my local machine over HTTP I needed to know the server’s public key, and the server needs to know my local public key. In addition both client and server also have to store their own private keys.

So I asked myself what kind of assurances do I want regarding key security for HttpClone? It turns out that simply placing the keys in the web server’s /bin directory is probably all that is required. I mean to say if they can modify files on my web server’s bin directory the game is already lost. They can freely change the assemblies, web.config, etc and serve up any malicious content they want.

In the end I chose to allow an added a level of password security to the private key file and then store that password elsewhere. Why? Well you only need to remember back to last year at this time when Microsoft released this annoucement: “Important: ASP.NET Security Vulnerability“. One of the possible gains from this attack was being able to read any file in the web directory (web.config included). Due to this and the potential of a co-hosted site not running ASP.NET being hacked I thought adding the extra layer was worthwhile.

For HttpClone’s purposes it’s still not necessary to further protect the server’s private key. This is due in part to the fact that the data being sent (a copy of a public website) is not private and does not need to be secure. In fact the only reason for involving cryptography at all is for authorization not privacy.

 

Background: I get a lot of traffic looking for details on running a process and collecting the process output. If you haven’t already done so, you should read “How to use System.Diagnostics.Process correctly“. It outlines the major pitfalls of using this class. Another post on “Using the ProcessRunner class” will demonstrate using the helper class I wrote: CSharpTest.Net.Processes.ProcessRunner.

So again I find myself writing about using System.Diagnostics.Process and the Process.Start method. This time it’s not to provide any more information, but rather a simplified example. This example will build upon the previous two posts “How to search the environment’s path for an exe or dll“, and “How to correctly escape command line arguments” to use those methods for solving those needs. Otherwise this example is a relatively stand-alone method for running a process and capturing it’s output.

    /// <summary>
    /// Runs the specified executable with the provided arguments and returns the process' exit code.
    /// </summary>
    /// <param name="output">Recieves the output of either std/err or std/out</param>
    /// <param name="input">Provides the line-by-line input that will be written to std/in, null for empty</param>
    /// <param name="exe">The executable to run, may be unqualified or contain environment variables</param>
    /// <param name="args">The list of unescaped arguments to provide to the executable</param>
    /// <returns>Returns process' exit code after the program exits</returns>
    /// <exception cref="System.IO.FileNotFoundException">Raised when the exe was not found</exception>
    /// <exception cref="System.ArgumentNullException">Raised when one of the arguments is null</exception>
    /// <exception cref="System.ArgumentOutOfRangeException">Raised if an argument contains '\0', '\r', or '\n'
    public static int Run(Action<string> output, TextReader input, string exe, params string[] args)
    {
        if (String.IsNullOrEmpty(exe))
            throw new FileNotFoundException();
        if (output == null)
            throw new ArgumentNullException("output");

        ProcessStartInfo psi = new ProcessStartInfo();
        psi.UseShellExecute = false;
        psi.RedirectStandardError = true;
        psi.RedirectStandardOutput = true;
        psi.RedirectStandardInput = true;
        psi.WindowStyle = ProcessWindowStyle.Hidden;
        psi.CreateNoWindow = true;
        psi.ErrorDialog = false;
        psi.WorkingDirectory = Environment.CurrentDirectory;
        psi.FileName = FindExePath(exe); //see http://csharptest.net/?p=526
        psi.Arguments = EscapeArguments(args); // see http://csharptest.net/?p=529

        using (Process process = Process.Start(psi))
        using (ManualResetEvent mreOut = new ManualResetEvent(false),
             mreErr = new ManualResetEvent(false))
        {
            process.OutputDataReceived += (o, e) => { if (e.Data == null) mreOut.Set(); else output(e.Data); };
            process.BeginOutputReadLine();
            process.ErrorDataReceived += (o, e) => { if (e.Data == null) mreErr.Set(); else output(e.Data); };
            process.BeginErrorReadLine();

            string line;
            while (input != null && null != (line = input.ReadLine()))
                process.StandardInput.WriteLine(line);

            process.StandardInput.Close();
            process.WaitForExit();

            mreOut.WaitOne();
            mreErr.WaitOne();
            return process.ExitCode;
        }
    }

Though most people won’t require writing to std::in, it is demonstrated here. If you do decide to remove this be careful that you still set psi.RedirectStandardInput to true, and call process.StandardInput.Close() before you call process.WaitForExit().

If you want to read a single character at a time (so as not to wait for a new line) that can also be done. Unfortunately it does require more work. The following sample class reads one character at a time and writes it to the console:

    //In the above example you would remove the event subscription and the call to
    //process.BeginOutputReadLine() and replace it with the following:
    new ReadOutput(process.StandardInput, mreOut);

    private class ReadOutput
    {
        private StreamReader _reader;
        private ManualResetEvent _complete;

        public ReadOutput(StreamReader reader, ManualResetEvent complete)
        {
            _reader = reader;
            _complete = complete;
            Thread t = new Thread(ReadAll);
            t.Start();
        }

        void ReadAll()
        {
            int ch;
            while(-1 != (ch = _reader.Read()))
            {
                Console.Write((char) ch);
            }
            _complete.Set();
        }
    }

Always remember you need two threads reading both std::out and std::err or you run into the possibility of hanging the process.

 

Most people believe escaping arguments to a process is easy. Surround it with quotes, right? Nope. Escape the quotes and surround it with quotes? Nope. Escape the quotes and backslashes and then surround it with quotes? Nope. It’s actually a lot more strange than that. When do you need to escape and quote an argument? [...]

 

I’d love it if there was a nice clean way to do this; however, there isn’t. When running a process via the Process.Start(…) call one must provide a fully qualified path to an executable. The problem is that hard-coding the full path to the exe isn’t always the best option. This is why there is [...]

 

Last year I ran across this 2009 post by Bruce Schneier entitled “Another New AES Attack“. It got me thinking about and dissecting the Rijndael algorithm which most of you know as AES (Advanced Encryption Standard). This research surprised me, I found that AES has only three variants. These variants are best known by their key [...]

 

Put simply: “YOU DON’T” so quit trying. Just today: http://stackoverflow.com/questions/5806520/parse-email-header-with-regex-in-c http://thedailywtf.com/Articles/Email-Validation-Validity.aspx Why people insist on attempting this is beyond me. I’ve grown to really like Regex, I’ve even built a light-weight xml parser on regular expressions but you can not parse email addresses with a regex. Just look at some of these crazy attempts in [...]

 

Cont’d from Building a database in C# – Part 2 Caching and persistence seem to go hand-in-hand for this adventure. With the cost of serialization and IO it’s just not possible to get anything to perform well without a little caching. The questions I had around caching is really more along the lines of “how” [...]