title: how to raise event getche() from process.Popen() - does not monitor stdin
body: <p>I am launching a binary in windows using:</p>
  
  <pre><code>process = subprocess.Popen(cmd, stderr = subprocess.PIPE, stdin = subprocess.PIPE, stdout = ch.input)
  
  ch.input comes from:
  
  ch = InputStreamChunker('\n')
  ch.daemon = True
  ch.start()
  </code></pre>
  
  <p>which was a cool non blocking method of reading from stdout.  It was the accepted answer for this SO question:
  <a href="https://stackoverflow.com/questions/3076542/how-can-i-read-all-availably-data-from-subprocess-popen-stdout-non-blocking">How can I read all availably data from subprocess.Popen.stdout (non blocking)?</a></p>
  
  <p>This is the bulk of my script that attempts to launch/monitor the process:</p>
  
  <pre><code>import subprocess
  import time
  from e import *
  import msvcrt
  
  ch = InputStreamChunker('\n')
  ch.daemon = True
  ch.start()
  
  
  cmd = "C:\TEST.EXE"
  process = subprocess.Popen(cmd, stderr = subprocess.PIPE, stdin = subprocess.PIPE, stdout = ch.input)
  i = process.stdin
  answers = []
  waitforresults(ch, answers, expect = 5)
  an = 1
  for i in answers:
      print "ANSWER # " + str(an) + ":" + i.read()
      an= an+1
  
  answers = []    
  time.sleep(5)
  msvcrt.ungetch('s')
  ch.flush()
  waitforresults(ch, answers, expect = 1)
  for a in answers:
      print a.getvalue()
  
  process.terminate()
  ch.stop()
  del process, ch
  print "DONE"
  </code></pre>
  
  <p>Anyway, I can read from the process using this method fine.  When I attempt to write to the process using:</p>
  
  <p>i = process.stdin
  i.write("s\n")
  or
  i.write("s")</p>
  
  <p>The output is printed in the console window but not captured by the binary.  I took a look at the binary in IDA Pro and find that it's using a non standard method of capturing user input while it is running.</p>
  
  <p>The process is an interactive cli tool that waits for S, R, P or Q (Status, Resume, Pause, Quit) ***and it captures the input withput the user hitting ente***r.  This is accomplished using getche().  I threw the binary at IDA Pro to confirm:</p>
  
  <pre><code>v7 = getche();
  if ( (unsigned int)dword_41F060 &gt; 1 )
    sub_4030A0(&amp;unk_41C111, v5);
  WaitForSingleObject((HANDLE)dword_41F040, 0xFFFFFFFFu);
  if ( v7 == 113 )
  {
    if ( dword_41F060 != 1 )
    {
      if ( dword_41F060 )
        dword_41F060 = 6;
    }
  }
  else
  {
    if ( v7 &lt;= 113 )
    {
      if ( v7 == 112 )
      {
        if ( dword_41F060 == 2 )
          QueryPerformanceCounter((LARGE_INTEGER *)&amp;qword_41F128);
        dword_41F060 = 3;
        sub_4030A0("Paused", v5);
      }
    }
    else
    {
      if ( v7 == 114 )
      {
        if ( dword_41F060 == 3 )
        {
          QueryPerformanceFrequency((LARGE_INTEGER *)&amp;v9);
          QueryPerformanceCounter((LARGE_INTEGER *)&amp;v8);
          v3 = (double)(v8 - qword_41F128);
          LODWORD(v4) = sub_413FF0(v9, v10, 1000, 0);
          dbl_41F138 = v3 / (double)v4 + dbl_41F138;
        }
        dword_41F060 = 2;
        sub_4030A0("Resumed", v5);
      }
      else
      {
        if ( v7 == 115 )
          sub_40AFC0();
      }
    }
  }
  </code></pre>
  
  <p>Does anyone know how to trigger this event? This looked promising: <a href="http://docs.python.org/library/msvcrt.html" rel="nofollow noreferrer">http://docs.python.org/library/msvcrt.html</a> and I tried using:</p>
  
  <p>msvcrt.ungetch("s")
  "Cause the character char to be “pushed back” into the console buffer; it will be the next character read by getch() or getche()."</p>
  
  <p>which DID push the letter "s" to the console but did not trigger my breakpoint on getche().  Hitting the letter S manually does work and does cause IDA pro to hit the breakpoint</p>
  
  <p>halp? :)</p>
  
  <p>EDIT:</p>
  
  <p>I created two small windows console apps to demonstrate what works, what doesn't, and ensure my python is sane.</p>
  
  <p>This first one I can NOT get to recognize input by writing to stdin, the second one I can.</p>
  
  <pre><code>#include "stdafx.h"
  #include &lt;conio.h&gt;
  
  
  int _tmain(int argc, _TCHAR* argv[])
  {
      char response;
      printf("Enter \"s\":\n");
      response = _getch();
      printf("You entered %c\n", response);
      return 0;
  }
  </code></pre>
  
  <p>can write to this one:</p>
  
  <pre><code>#include "stdafx.h"
  #include &lt;conio.h&gt;
  
  
  int _tmain(int argc, _TCHAR* argv[])
  {
      char response [2];
      printf("Enter \"s\":\n");
      gets(response);
      printf("You entered %s", response);
      return 0;
  }
  </code></pre>
  
  <p><strong>EDIT 2</strong>
  I've also tried:
      import subprocess
      import time
      from e import *
      import msvcrt</p>
  
  <pre><code>ch = InputStreamChunker('\n')
  ch.daemon = True
  ch.start()
  
  
  cmd = ["test-getch.exe"]
  process = subprocess.Popen(cmd, stderr = subprocess.PIPE, stdin = subprocess.PIPE, stdout = ch.input)
  i = process.stdin
  answers = []
  msvcrt.putch('s')
  ch.flush
  waitforresults(ch, answers, expect = 1)
  for answer in answers:
      print answer.getvalue()
  i.close()
  time.sleep(3)
  #process.terminate()
  ch.stop()
  del process, ch
  print "DONE"
  </code></pre>