{"id":30173,"date":"2006-08-10T10:00:06","date_gmt":"2006-08-10T10:00:06","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2006\/08\/10\/one-way-people-abused-hooks-in-16-bit-windows\/"},"modified":"2006-08-10T10:00:06","modified_gmt":"2006-08-10T10:00:06","slug":"one-way-people-abused-hooks-in-16-bit-windows","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20060810-06\/?p=30173","title":{"rendered":"One way people abused hooks in 16-bit Windows"},"content":{"rendered":"<p>\nWe saw last time\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2006\/08\/09\/693280.aspx\">\nhow windows hooks were implemented in 16-bit Windows<\/a>.\nEven though the <code>HHOOK<\/code> was an opaque data type that\nshould have been treated like a handle,\nmany programs &#8220;knew enough to be dangerous&#8221;\nand took advantage of the fact that the <code>HHOOK<\/code>\nwas just a pointer to the previous hook procedure.\n<\/p>\n<p>\nThe most common way of abusing this knowledge was\nby unhooking from the windows hook chain the wrong way.\nInstead of calling the <code>UnhookWindowsHook<\/code> function\nto unhook a windows hook, they called <code>SetWindowsHook<\/code> again!\nSpecifically, they removed their hook by simply reinstalling the\nprevious hook at the head of the chain:\n<\/p>\n<pre>\nHHOOK g_hhkPrev;\n\/\/ install the hook\ng_hhkPrev = SetWindowsHook(WH_KEYBOARD, MyHookProc);\n...\n\/\/ crazy! uninstall the hook by setting the previous hook \"back\"\nSetWindowsHook(WH_KEYBOARD, g_hhkPrev);\n<\/pre>\n<p>\nThis code worked in spite of itself;\nit&#8217;s as if two wrongs made a &#8220;sort of right&#8221;.\nIf nobody else messed with the hook chain in between the time\nthe hook was installed and it was subsequently &#8220;uninstalled&#8221;,\nthen reinstalling the hook at the head of the chain\ndid restore the chain variables in the same way they would have\nbeen restored if they had uninstalled the hook correctly.\n<\/p>\n<p>\nBut if somebody else installed their own <code>WH_KEYBOARD<\/code>\nhook in the meantime, then setting the previous hook &#8220;back&#8221;\nwould have the effect of not only &#8220;uninstalling&#8221; the <code>MyHookProc<\/code>\nbut also <strong>all other hooks that were installed in the meantime<\/strong>.\n(This is exactly the same problem you have\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2003\/11\/10\/55647.aspx\">\nif you aren&#8217;t careful in how you remove subclassed window procedures<\/a>.)\n<\/p>\n<p>\nI still have no idea why they used this strange technique instead of\ndoing the right thing, which is just swapping out one line of code\nfor another:\n<\/p>\n<pre>\nUnhookWindowsHook(WH_KEYBOARD, MyHookProc);\n<\/pre>\n<p>\nWindows&nbsp;3.1 introduced the\n<code>SetWindowsHookEx<\/code>\/<code>CallNextHookEx<\/code> model,\nwhich doesn&#8217;t use the external linked list technique but rather manages\nthe hook chain internally.\nThis protected the hook chain from programs that corrupted it by\nmismanaging the external hook chain,\nbut it meant that\nwhen these crazy programs tried to unhook by hooking,\nthey ended up corrupting the <strong>internal<\/strong> hook chain.\nSpecial code had to be written to detect these crazy people and\nturn their bad call into the correct one so that the hook chain\nwouldn&#8217;t get corrupted.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We saw last time how windows hooks were implemented in 16-bit Windows. Even though the HHOOK was an opaque data type that should have been treated like a handle, many programs &#8220;knew enough to be dangerous&#8221; and took advantage of the fact that the HHOOK was just a pointer to the previous hook procedure. The [&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":[2],"class_list":["post-30173","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>We saw last time how windows hooks were implemented in 16-bit Windows. Even though the HHOOK was an opaque data type that should have been treated like a handle, many programs &#8220;knew enough to be dangerous&#8221; and took advantage of the fact that the HHOOK was just a pointer to the previous hook procedure. The [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/30173","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=30173"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/30173\/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=30173"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=30173"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=30173"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}