{"id":26193,"date":"2007-07-02T10:00:00","date_gmt":"2007-07-02T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2007\/07\/02\/image-file-execution-options-just-inserts-the-debugger-in-front-of-the-command-line\/"},"modified":"2007-07-02T10:00:00","modified_gmt":"2007-07-02T10:00:00","slug":"image-file-execution-options-just-inserts-the-debugger-in-front-of-the-command-line","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20070702-00\/?p=26193","title":{"rendered":"Image File Execution Options just inserts the debugger in front of the command line"},"content":{"rendered":"<p>\nIf you use the Image File Execution Options registry key to\nforce a program to run under the debugger,\nall the kernel does is insert the debugger in front of the command line.\nIn other words, the <code>CreateProcess<\/code> function figure out\nwhat program is about to be run and checks the Image File Execution\nOptions.\nIf it finds a debugger, then the debugger is prepended to the command line\nand then <code>CreateProcess<\/code> resumes as if that were the command\nline you had passed originally.\n<\/p>\n<p>\nIn particular, it doesn&#8217;t do anything with the other parameters\nto the <code>CreateProcess<\/code> function.\nIf you passed special parameters via the <code>STARTUPINFO<\/code> structure,\nthose parameters get passed to the debugger.\nAnd the <code>PROCESS_INFO<\/code> that is returned by the\n<code>CreateProcess<\/code> function describes the debugger,\nnot the process being debugged.\n<\/p>\n<p>\nSpecifically, if you specified the\n<code>STARTF_USESHOWWINDOW<\/code> flag and passed,\nsay, <code>SW_HIDE<\/code>, as the <code>wShowWindow<\/code>,\nthen <i>the debugger will be hidden<\/i>.\nThis bites me every so often when I am called upon to\ndebug a program that happens to be launched as hidden.\nI&#8217;ll slap the debugger underneath it with Image File Execution\nOptions,\nrun through the scenario,\nand then&#8230; nothing.\n<\/p>\n<p>\nAnd then eventually I realize,\n&#8220;<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2006\/10\/23\/862750.aspx#868476\">Oh, right, the debugger is hidden<\/a>.&#8221;\n<\/p>\n<p>\nTo unstick myself, I fire up a program like Spy to get the window\nhandle of the hidden debugger and fire up a scratch copy of Notepad so\nI can make it do my bidding and show the window.\n<\/p>\n<pre>\nntsd -Ggx notepad\n&lt;F12&gt;\nBreak instruction exception - code 80000003 (first chance)\neax=7ffdf000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005\neip=7c901230 esp=00a1ffcc ebp=00a1fff4 iopl=0         nv up ei pl zr na po nc\ncs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000246\nntdll!DbgBreakPoint:\n7c901230 cc               int     3\n0:001&gt; r esp=esp-4\n0:001&gt; ed esp 1\n0:001&gt; r esp=esp-4\n0:001&gt; ed esp <font COLOR=\"blue\">0x00010164<\/font>\n0:001&gt; r esp=esp-4\n0:001&gt; ed esp eip\n0:001&gt; r eip=user32!showwindow\n0:001&gt; g\n0:001&gt; q\n<\/pre>\n<p>\nThe first two commands push the value <code>SW_SHOWNORMAL<\/code>\n(numerical value 1) onto the stack.\nThen goes the window handle.\nAnd then the return address.\nMove the instruction pointer to <code>user32!ShowWindow<\/code> and\nwe&#8217;ve simulated the function call\n<code>ShowWindow(0x00010164, SW_SHOWNORMAL);<\/code>.\nOnce I let execution resume, *boom* the debugger window appears\nand I can continue my work.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you use the Image File Execution Options registry key to force a program to run under the debugger, all the kernel does is insert the debugger in front of the command line. In other words, the CreateProcess function figure out what program is about to be run and checks the Image File Execution Options. [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[26],"class_list":["post-26193","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>If you use the Image File Execution Options registry key to force a program to run under the debugger, all the kernel does is insert the debugger in front of the command line. In other words, the CreateProcess function figure out what program is about to be run and checks the Image File Execution Options. [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/26193","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=26193"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/26193\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=26193"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=26193"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=26193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}