2

My question may seem as a straight forward one, because it was asked many times before.Anyway I think my case is completely different and I can't find any intuition about it. I have an exe file compiled from a code written in assembly language and I want to run this exe using another code and capture its output. I did this using C# and here is the code for it:

static string runCommand(string command, string args)
    {
        if (File.Exists(command))
        {
            Process p = new Process();
            p.StartInfo.FileName = command;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.Arguments = args;
            p.Start();
            p.WaitForExit();
            string output = p.StandardOutput.ReadToEnd();
            return output; 
        }
        return "";
    }

The code for the target exe file is pretty simple (I'm using Irvine library):

INCLUDE Irvine32.inc


.data

.code
main proc
    call dumpregs
    exit
main ENDP

end main

Where command is the exe file path, args is the arguments passed to the exe file (be noted that no arguments required by this exe)

The output is always equal to "" !. When I run the exe using command prompt, the console output is definitely not empty.Here is what I get:enter image description here

I also tried to capture the console output using python but the returned string is awlays empty.

I have done this several times but the exe file was written in C# instead of assembly language, but I think it shouldn't be any difference exist.

EDIT

Solutions attempted so far and suggested by hatchet:

  1. Capturing console output from a .NET application (C#)
  2. How to spawn a process and capture its STDOUT in .NET? [duplicate]
  3. Process.start: how to get the output?

None of them worked for me

If you need any further information let me know in the comments

Ibrahim Amer
  • 1,147
  • 4
  • 19
  • 46
  • @hatchet thank you sir for your comment. My problem is not how to run an exe file using C#, I already have the code for this. My problem is the output is always an empty string – Ibrahim Amer Jun 15 '17 at 19:29
  • @hatchet none of them worked for me.The output is always empty – Ibrahim Amer Jun 15 '17 at 19:44
  • 1
    Are you sure the output is going to standard output and not standard error? – Ross Ridge Jun 15 '17 at 19:53
  • 1
    Irvine's library works with [`WriteConsole`](https://msdn.microsoft.com/library/windows/desktop/ms687401.aspx) which cannot be redirected. You have to change it in `Irvine32.asm` to [`WriteFile`](https://msdn.microsoft.com/library/windows/desktop/aa365747.aspx), assemble it and build a new library together with `floatio.obj`. – rkhb Jun 15 '17 at 19:55
  • The other comments are correct. The problem is not in your c# code. If that program (that calls dumpregs) had written normally to stdout, your code as is would have captured it. I ran a quick test to verify that. – hatchet - done with SOverflow Jun 15 '17 at 20:08
  • @RossRidge yes sir – Ibrahim Amer Jun 15 '17 at 22:35
  • @rkhb thank you sir for your comment. I think your hypothesis is correct. I think eventually will replace it with read and write to file instead. Thanks again sir! – Ibrahim Amer Jun 15 '17 at 22:37

1 Answers1

1

Your C# code is correct. The standard way of capturing the output of a console process is to redirect the standard output by setting the process object's StartInfo.RedirectStandardOutput property to true, as described here. This is exactly what you have done.

The problem, as correctly diagnosed by rkhb, is that you're using the Irvine32 library in the auxiliary process, and its implementation of dumpregs calls the Win32 WriteConsole function, which cannot be redirected. If you attempt to redirect the standard output (e.g., to a pipe or file), then WriteConsole will fail with ERROR_INVALID_HANDLE, as documented on MSDN:

ReadConsole and WriteConsole can only be used with console handles; ReadFile and WriteFile can be used with other handles (such as files or pipes). ReadConsole and WriteConsole fail if used with a standard handle that has been redirected and is no longer a console handle.

Like rkhb's comment, this except from the documentation also hints at the solution. To support redirection, you need to change the implementation of dumpregs to call WriteFile instead of WriteConsole. This is a more general function that can write to any type of handle, including the standard console output (a la WriteConsole) or any other type of object that you might redirect the output to. Once you've made this change, you will, of course, need to rebuild the Irvine32 library.

The only significant limitation of WriteFile is that it doesn't support Unicode output like WriteConsole does, but that isn't a problem in your case. The output of dumpregs is all ANSI.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • You are absolutely correct!. I used WriteFile procedure to print on console screen. Now I can capture the output using the C# code. Many thanks sir!. @rkhb thank you sir as well ! – Ibrahim Amer Jun 16 '17 at 13:11