{"id":97356,"date":"2017-11-07T07:00:00","date_gmt":"2017-11-07T22:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=97356"},"modified":"2019-03-13T01:34:06","modified_gmt":"2019-03-13T08:34:06","slug":"20171107-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20171107-00\/?p=97356","title":{"rendered":"Was there a problem with Windows 95-era programs relying on undocumented information disclosure stuff?"},"content":{"rendered":"<p><a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20100720-01\/?p=13383#comment-848523\">Tihiy<\/a> noted that back in the Windows 95 days, there was a lot of undocumented stuff lying around in places that are formally undefined. For example, the return value of <code>Is&shy;Window<\/code> is formally zero or nonzero, but it turns out that on Windows 95, the nonzero value actually was a pointer to an internal data structure. I remember another case where a function returned a value in <code>EAX<\/code>, but it so happened that the <code>ECX<\/code> register contained a pointer to some interesting data structure. <\/p>\n<p>These bonus undocumented values were not intentional. In the case of <code>Is&shy;Window<\/code>, it was an optimization: Since the only meaningful values are zero and nonzero, and a null pointer is zero and a non-null pointer is nonzero, it was a clever trick to just return the pointer cast to an integer. In the case of the function that returned a value in <code>ECX<\/code>, that was completely unintentional: It was just a value that the compiler left in the <code>ECX<\/code> register by happenstance. <\/p>\n<p>Did these undocumented but potentially useful values cause trouble? <\/p>\n<p>Surprisingly not. <\/p>\n<p>I&#8217;m not sure why this was not generally a problem. My guess is that software developers kept one eye on that other version of Windows, Windows NT. Relying on undocumented values wouldn&#8217;t work on Windows NT, so the developers had to come up with something that would work on both. <\/p>\n<p>I&#8217;m sure there were plenty of software developers who simply never tested on Windows NT or didn&#8217;t consider Windows NT to be part of their customer base. But the number of those who exploited undocumented return values was small enough that I barely remember them. <\/p>\n<p><b>Bonus chatter<\/b>: I do remember one customer some time around Windows 8 who asked why the contents of the <code>EBX<\/code> register no longer contained a copy of the executable&#8217;s instance handle when the executable entry point as called. We were kind of baffled by this question, because the contents of the <code>EBX<\/code> register at the executable entry point are formally undefined. Indeed, the code never explicitly sets <code>EBX<\/code> to anything. The value in <code>EBX<\/code> is whatever the compiler happened to be using the <code>EBX<\/code> register for. There was no intentional effort to put a particular value into the <code>EBX<\/code> register. It just so happened that the instance handle was something the compiler decided to put into the <code>EBX<\/code> register for 19 years, and then in year 20, it decided to put something else there. <\/p>\n<p><b>Bonus bonus chatter<\/b>: You also shouldn&#8217;t <a HREF=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/#comment-1308415\">sniff the return address to determine how your module was loaded<\/a>. That&#8217;s not part of the API contract either. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Surprisingly not.<\/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":[2],"class_list":["post-97356","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>Surprisingly not.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/97356","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=97356"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/97356\/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=97356"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=97356"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=97356"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}