{"id":1715,"date":"2022-04-17T23:11:42","date_gmt":"2022-04-17T15:11:42","guid":{"rendered":"https:\/\/0self.mnihyc.com\/blog\/?p=1715"},"modified":"2022-04-29T16:38:44","modified_gmt":"2022-04-29T08:38:44","slug":"win32-%e4%b8%8b-hook-%e5%87%bd%e6%95%b0%e7%9a%84%e5%87%a0%e7%a7%8d%e6%96%b9%e6%b3%95","status":"publish","type":"post","link":"https:\/\/0self.mnihyc.com\/blog\/archives\/1715","title":{"rendered":"Win32 \u4e0b Hook \u51fd\u6570\u7684\u51e0\u79cd\u65b9\u6cd5"},"content":{"rendered":"<p style=\"text-align: left;\">\u9047\u5230\u4e86\u9700\u8981 Hook \u4e00\u4e9b\u51fd\u6570\u7684\u60c5\u51b5\uff0cWinAPI \u7684 <code>__stdcall<\/code> \u6216\u662f IDA \u5206\u6790\u51fa\u6765\u7684 <code>__usercall<\/code>\uff0c\u7559\u6b64\u7eaa\u5f55\u3002\u6d4b\u8bd5\u73af\u5883\u4e3a Win32\uff0c\u7f16\u8bd1\u5668\u4e3a MSVC\u3002<\/p>\n<p>&nbsp;<\/p>\n<p><!--more--><\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>\n<h2><strong>\u76ee\u5f55<\/strong><\/h2>\n<ul>\n<li>\n<h3><a href=\"#n_jmp\">\u666e\u901a <code>JMP<\/code>\uff08\u4e0d\u63a8\u8350\uff09<\/a><\/h3>\n<\/li>\n<li>\n<h3><a href=\"#g_hook\">\u5e26 <code>Gadget<\/code> \u7684 <code>JMP<\/code><\/a><\/h3>\n<\/li>\n<li>\n<h3><a href=\"#rep_iat\">\u66ff\u6362 IAT\uff08\u4ec5\u9002\u7528 PE\uff09<\/a><\/h3>\n<\/li>\n<li>\n<h3><a href=\"#usercall\"><strong><code>__usercall<\/code> \u7684\u8f6c\u6362<\/strong><\/a><\/h3>\n<\/li>\n<li>\n<h3><a href=\"#ref_dll\"><strong>\u9644\uff1aReflective PE Loader<\/strong><\/a><\/h3>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p><a id=\"n_jmp\"><\/a>\u00a0<\/p>\n<hr \/>\n<ul>\n<li>\n<h3>\u666e\u901a <code>JMP<\/code>\uff08\u4e0d\u63a8\u8350\uff09<\/h3>\n<\/li>\n<\/ul>\n<p>Hook \u4e00\u4e2a\u51fd\u6570\uff0c\u6700\u7b80\u5355\u7684\u601d\u8def\u5c31\u662f\u5728\u5b83\u5f00\u5934\u653e\u4e00\u4e2a <code>JMP<\/code> \u6307\u4ee4\u5230\u6211\u4eec\u7684\u5730\u5740\u3002<\/p>\n<p>\u800c\u9700\u8981\u8c03\u7528\u56de\u539f\u51fd\u6570\u65f6\uff08\u6bd4\u5982\u53ea\u662f\u622a\u53d6\u53c2\u6570\u4fe1\u606f\uff09\uff0c\u5fc5\u987b\u5148\u8fd8\u539f\u5b83\u7684\u5f00\u5934\u5b57\u8282\u624d\u80fd\u6b63\u5e38\u8c03\u7528\uff0c\u8fd9\u5728\u591a\u7ebf\u7a0b\u4e2d\u53ef\u80fd\u4f1a\u51fa\u73b0\u77ed\u6682\u7684 Hook \u5931\u6548\uff0c\u751a\u81f3\u6267\u884c\u5230\u975e\u9884\u671f\u7684\u6c47\u7f16\u6307\u4ee4\uff0c\u56e0\u6b64\u4e00\u822c\u4e0d\u91c7\u7528\u6b64\u65b9\u6cd5\u3002<\/p>\n<p>\u9996\u5148\u5b9a\u4e49\u4e00\u4e2a <code>JMPCODE<\/code>\uff0c\u5927\u5c0f\u4e3a 5 \u5b57\u8282\u3002\uff08\u6ce8\u610f\u5bf9\u9f50\u95ee\u9898\uff09<\/p>\n<pre class=\"lang:c++ decode:true \">#pragma pack(push, 1)\r\ntypedef struct _JMPCODE\r\n{\r\n\tBYTE jmp = 0xE9; \/\/ JMP instruction\r\n\tDWORD addr = 0; \/\/ Target address offset\r\n}JMPCODE, *PJMPCODE;\r\n#pragma pack(pop)<\/pre>\n<p>\u6709\u4e00\u4e2a\u51fd\u6570 <code>HOOK::patch<\/code> \u7528\u6765\u5199\u5165\u67d0\u5757\u5185\u5b58\u533a\u57df\u3002\uff08\u6ce8\u610f\u66f4\u6539\u9875\u9762\u4fdd\u62a4\u4fe1\u606f\uff09<\/p>\n<pre class=\"lang:c++ decode:true \">\/*\r\n\tpatch(addr, arr, size) =&gt; bool, whether succeeds\r\n\taddr (DWORD_PTR) address to patch\r\n\tarr (const BYTE*) data\r\n\tsize (DWORD) bytes to patch\r\n*\/\r\nbool HOOK::patch(DWORD_PTR addr, const BYTE* arr, DWORD size)\r\n{\r\n\tDWORD oldProtect = 0;\r\n\t\/\/ make memory page writable\r\n\tif (!VirtualProtect((LPVOID)addr, size, PAGE_READWRITE, &amp;oldProtect))\r\n\t\treturn false;\r\n\t\/\/ overwrite target address\r\n\tBYTE* pad = (BYTE*)addr;\r\n\tfor (unsigned i = 0; i &lt; size; i++)\r\n\t\tpad[i] = arr[i];\r\n\t\/\/ recover page protection\r\n\tif (!VirtualProtect((LPVOID)addr, size, oldProtect, &amp;oldProtect))\r\n\t\treturn false;\r\n\treturn true;\r\n}<\/pre>\n<p>\u4ee5 Hook WinAPI <code>OutputDebugStringA<\/code> \u4e3a\u4f8b\uff0c\u53ea\u9700\u8981\u628a\u5b83\u7684\u524d 5 \u4e2a\u5b57\u8282\u66ff\u6362\u4e3a <code>JMPCODE<\/code> \u5373\u53ef\u3002\uff08\u6ce8\u610f\u5907\u4efd\u524d 5 \u4e2a\u5b57\u8282\uff0c\u53ca <code>JMP<\/code> \u7684\u504f\u79fb\u8ba1\u7b97\uff09<\/p>\n<pre class=\"lang:c++ decode:true \">JMPCODE hookCode, orgCode;\r\n\r\n\/*\r\n\thook(myF, orgF) =&gt; bool\r\n\tmyF (LPVOID) my function address\r\n\torgF (LPVOID) original function address\r\n*\/\r\nbool HOOKJMP::hook(LPVOID myF, LPVOID orgF)\r\n{\r\n\t\/\/ backup original 5 bytes\r\n\tif (!ReadProcessMemory(GetCurrentProcess(), orgF, &amp;orgCode, 5, NULL))\r\n\t\treturn false;\r\n\t\/\/ overwrite original function\r\n\thookCode.addr = (DWORD)myF - (DWORD)orgF - 5; \/\/ calculate offset\r\n\tif (!HOOK::patch((DWORD)orgF, (BYTE*)&amp;hookCode, 5))\r\n\t\treturn false;\r\n\treturn true;\r\n}\r\n\r\nHOOKJMP::hook(myOutputDebugStringA, OutputDebugStringA);<\/pre>\n<p>\u5176\u4e2d Hook \u5230\u7684\u6211\u4eec\u7684 <code>myOutputDebugStringA<\/code> \u51fd\u6570\u5b9e\u73b0\u5982\u4e0b\uff1a\uff08\u6ce8\u610f\u8fd8\u539f\u524d 5 \u4e2a\u5b57\u8282\uff09<\/p>\n<pre class=\"lang:c++ decode:true\">void WINAPI myOutputDebugStringA(LPCSTR lpOutputString)\r\n{\r\n\tMessageBoxA(NULL, lpOutputString, \"DEBUG\", 0);\r\n\t\/\/ recover bytes\r\n\tHOOK::patch(OutputDebugStringA, (BYTE*)&amp;orgCode, 5);\r\n\t\/\/ call original function\r\n\tOutputDebugStringA(lpOutputString);\r\n\t\/\/ re-hook\r\n\tHOOK::patch(OutputDebugStringA, (BYTE*)&amp;hookCode, 5));\r\n}<\/pre>\n<p>\u8fd9\u662f\u7528 <code>JMP<\/code> \u5b9e\u73b0\u7684\u4e00\u4e2a\u6700\u7b80\u5355\u7684 Hook\u3002<\/p>\n<p>&nbsp;<\/p>\n<p><a id=\"g_hook\"><\/a>\u00a0<\/p>\n<hr \/>\n<ul>\n<li>\n<h3><strong>\u5e26 <code>Gadget<\/code> \u7684 <code>JMP<\/code><\/strong><\/h3>\n<\/li>\n<\/ul>\n<p>\u57fa\u4e8e\u4e0a\u8ff0\u666e\u901a <code>JMP<\/code> \u5728\u591a\u7ebf\u7a0b\u73af\u5883\u4e0b\u7684\u95ee\u9898\uff0c\u5982\u679c\u80fd\u907f\u514d\u6bcf\u6b21\u90fd\u91cd\u65b0\u5199\u5165\uff08hook, recover, re-hook, recover, re-hook, &#8230;&#8230;\uff09\u539f\u51fd\u6570\u7684\u524d\u51e0\u4e2a\u5b57\u8282\u5c31\u597d\u4e86\u3002<\/p>\n<p>\u6240\u4ee5\u81ea\u7136\u7684\u4e00\u79cd\u60f3\u6cd5\u5c31\u662f\u5c06\u539f\u51fd\u6570\u7684\u524d\u51e0\u4e2a\u5b57\u8282\u62f7\u5230\u4e00\u4e2a\u5730\u65b9\uff0c\u6bcf\u6b21\u53ea\u9700\u5148\u8f6c\u5230\u8fd9\u4e2a\u5730\u65b9\u6267\u884c\u539f\u51fd\u6570\u7684\u524d\u51e0\u6761\u6307\u4ee4\uff0c\u800c\u540e\u8df3\u56de\u539f\u51fd\u6570\u7ee7\u7eed\u6267\u884c\u540e\u9762\u7684\u6307\u4ee4\u5c31\u597d\u4e86\u3002<\/p>\n<p>\u8fd9\u5c31\u662f\u5e26 <code>Gadget<\/code> \u7684 <code>JMP<\/code> \u601d\u60f3\uff0c\u9996\u5148\u628a\u539f\u51fd\u6570\u7684\u524d\u51e0\u6761\u5b8c\u6574\u7684\u6307\u4ee4\u62f7\u5230 <code>Gadget<\/code> \u4e0a\uff0c<code>Gadget<\/code> \u6700\u540e <code>JMP<\/code> \u56de\u539f\u51fd\u6570\u540e\u9762\u7684\u6307\u4ee4\u7ee7\u7eed\u6267\u884c\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u907f\u514d\u66f4\u6539\u539f\u51fd\u6570\u7684\u524d\u51e0\u4e2a\u5b57\u8282\uff08Hook \u5b8c\u540e\u59cb\u7ec8\u4fdd\u6301\u4e3a <code>JMP<\/code>\uff09\u800c\u8c03\u7528\u56de\u771f\u6b63\u7684\u539f\u51fd\u6570\u4e86\u3002<\/p>\n<p>\u4e3b\u8981\u6d41\u7a0b\u5982\u4e0b\u56fe\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1727 size-full\" src=\"https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-gadget_jmp.png\" alt=\"\" width=\"552\" height=\"876\" srcset=\"https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-gadget_jmp.png 552w, https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-gadget_jmp-189x300.png 189w, https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-gadget_jmp-95x150.png 95w\" sizes=\"auto, (max-width: 552px) 100vw, 552px\" \/><\/p>\n<p>\u9700\u8981\u6ce8\u610f\u7684\u662f\u8fd9\u91cc\u5fc5\u987b patch \u5b8c\u6574\u7684\u6307\u4ee4\u5b57\u8282\uff08\u81f3\u5c11\u662f 5 bytes\uff0c\u591a\u4f59\u7684\u90e8\u5206\u7528 <code>NOP<\/code> \u586b\u5145\uff09\uff0c\u6240\u4ee5\u5bf9\u4e8e\u4e0d\u540c\u51fd\u6570\u9700\u8981 patch \u7684\u5b57\u8282\u6570\u4e5f\u4e0d\u5c3d\u76f8\u540c\u3002<\/p>\n<p>\u4ee5 Hook \u4e0a\u56fe\u4e2d <code>base + 0x75E90<\/code> \u5904\u7684\u51fd\u6570\u4e3a\u4f8b\uff0c\u9700\u8981\u66ff\u6362\u5b83\u7684\u524d 6 \u4e2a\u5b57\u8282\uff08\u5206\u522b\u4e3a\u5b8c\u6574\u7684 <span class=\"lang:asm decode:true  crayon-inline \">sub esp, C<\/span> \u548c <span class=\"lang:asm decode:true  crayon-inline \">push esi<\/span> \u548c <span class=\"lang:asm decode:true  crayon-inline \">push 2C<\/span>\uff09\u4e3a <span class=\"lang:asm decode:true  crayon-inline \">JMP offset<\/span> \u548c <span class=\"lang:asm decode:true  crayon-inline \">NOP<\/span> \u3002<\/p>\n<pre class=\"lang:c++ decode:true   \">LPVOID gadAddress;\r\n\r\n\/*\r\n\thook(myF, orgF, size) =&gt; bool\r\n\tmyF (LPVOID) my function address\r\n\torgF (LPVOID) original function address\r\n\tsize (DWORD) size of complete commands to patch\r\n*\/\r\nbool HOOKJMP::hook(LPVOID myF, LPVOID orgF, DWORD size)\r\n{\r\n\t\/\/ copy size bytes for original command, extra 5 for JMPCODE\r\n\tBYTE* arr = (BYTE*)VirtualAlloc(NULL, size + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);\r\n\tif (!arr)\r\n\t\treturn false;\r\n\tgadAddress = arr; \/\/ gadget address\r\n\tif (!ReadProcessMemory(GetCurrentProcess(), orgF, arr, size, NULL))\r\n\t\treturn false;\r\n\t\/\/ overwrite gadget address\r\n\tJMPCODE code;\r\n\tcode.addr = (DWORD)orgF - (DWORD)arr - 5; \/\/ from gadget to original function\r\n\tif (!WriteProcessMemory(GetCurrentProcess(), &amp;arr[size], &amp;code, 5, NULL))\r\n\t\treturn false;\r\n\t\/\/ overwrite original function\r\n\tcode.addr = (DWORD)myF - (DWORD)orgF - 5; \/\/ from original function to mine\r\n\tif (!HOOK::patch((DWORD)orgF, (BYTE*)&amp;code, 5))\r\n\t\treturn false;\r\n\tBYTE NOPs[1024] = { 0x90 };\r\n\tif (!HOOK::patch((DWORD)orgF + 5, NOPs, this-&gt;size - 5))\r\n\t\treturn false;\r\n\t\/\/ finished\r\n\treturn true;\r\n}\r\n\r\nhook(myFunc, (LPVOID)(base + 0x75E90), 6);<\/pre>\n<p>\u5176\u4e2d Hook \u5230\u7684\u6211\u4eec\u7684 <code>myFunc<\/code> \u51fd\u6570\u5b9e\u73b0\u5982\u4e0b\uff1a\uff08\u5047\u8bbe\u8be5\u51fd\u6570\u4e3a <code>__cdecl<\/code>\uff0c\u63a5\u53d7\u4e00\u4e2a\u53c2\u6570\uff09<\/p>\n<pre class=\"lang:c++ decode:true   \">typedef void (__cdecl* tpOrgFunc)(int);\r\nvoid __cdecl myFunc(int a1)\r\n{\r\n\ttpOrgFunc orgFunc = static_cast&lt;tpOrgFunc&gt;(gadAddress);\r\n\treturn orgFunc(a1);\r\n}<\/pre>\n<p>\u8fd9\u6837\u5c31\u5b8c\u6210\u4e86\u4e00\u4e2a\u5e26 <code>Gadget<\/code> \u7684 <code>JMP<\/code> Hook\u3002<\/p>\n<p>&nbsp;<\/p>\n<p><a id=\"rep_iat\"><\/a>\u00a0<\/p>\n<hr \/>\n<ul>\n<li>\n<h3><strong>\u66ff\u6362 IAT\uff08\u4ec5\u9002\u7528 PE\uff09<\/strong><\/h3>\n<\/li>\n<\/ul>\n<p>\u53ef\u4ee5\u53d1\u73b0\uff0c\u4e0a\u8ff0\u65b9\u6cd5\u4e5f\u5b58\u5728\u4e00\u4e2a\u660e\u663e\u7684\u7f3a\u70b9\uff1a\u88ab\u8c03\u7528\u51fd\u6570\u6700\u597d\u81f3\u5c11\u4e3a 5 \u5b57\u8282\uff0c\u4e14\u524d\u51e0\u6761\u6307\u4ee4\u6700\u597d\u4e0d\u8981\u662f <code>JMP<\/code>\u3002<\/p>\n<p>\u6bd4\u5982 <code>kernel32.dll<\/code> \u4e2d\u7684 <code>OutputDebugStringA<\/code> \u53ea\u662f\u4e00\u4e2a\u7b80\u5355\u7684 <code>JMP<\/code> \u5230 <code>kernelbase.dll<\/code> \u4e2d\u7684 <code>OutputDebugStringA<\/code>\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1729\" src=\"https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-ODSA1.png\" alt=\"\" width=\"681\" height=\"47\" srcset=\"https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-ODSA1.png 681w, https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-ODSA1-300x21.png 300w, https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-ODSA1-150x10.png 150w\" sizes=\"auto, (max-width: 681px) 100vw, 681px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1730\" src=\"https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-ODSA2.png\" alt=\"\" width=\"684\" height=\"67\" srcset=\"https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-ODSA2.png 684w, https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-ODSA2-300x29.png 300w, https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-ODSA2-150x15.png 150w\" sizes=\"auto, (max-width: 684px) 100vw, 684px\" \/><\/p>\n<p>\u800c\u8981 Hook WinAPI \uff08\u6216\u662f\u5176\u5b83\u7531 DLL \u5bfc\u5165\u7684\u51fd\u6570\uff09\uff0c\u8fd8\u53ef\u4ee5\u901a\u8fc7 patch IAT \u4e2d\u5bf9\u5e94\u51fd\u6570\u7684\u4f4d\u7f6e\u3002<\/p>\n<p>IAT ( Import Address Table )\uff0c\u8be6\u89c1 <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/win32\/debug\/pe-format#import-address-table\">https:\/\/docs.microsoft.com\/en-us\/windows\/win32\/debug\/pe-format#import-address-table<\/a><\/p>\n<p>\u5728\u4e00\u4e2a PE \u6587\u4ef6\u91cc\uff0c\u53ef\u4ee5\u5f88\u5bb9\u6613\u5730\u627e\u5230 Import Table \u7684\u4f4d\u7f6e\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1731\" src=\"https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-PET.png\" alt=\"\" width=\"553\" height=\"483\" srcset=\"https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-PET.png 553w, https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-PET-300x262.png 300w, https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-PET-150x131.png 150w\" sizes=\"auto, (max-width: 553px) 100vw, 553px\" \/><\/p>\n<p>\u91cc\u9762\u5305\u542b\u4e86\u5bfc\u5165\u7684\u5404\u79cd DLL \u51fd\u6570\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1732\" src=\"https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-IAT.png\" alt=\"\" width=\"814\" height=\"340\" srcset=\"https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-IAT.png 814w, https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-IAT-300x125.png 300w, https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-IAT-150x63.png 150w, https:\/\/0self.mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-IAT-768x321.png 768w\" sizes=\"auto, (max-width: 814px) 100vw, 814px\" \/><\/p>\n<p>\u5728 PE \u6587\u4ef6\u88ab\u52a0\u8f7d\u7684\u65f6\u5019\uff0c\u7cfb\u7edf\u4f1a\u81ea\u52a8\u586b\u5145\u6b64\u8868\u4e3a\u6b63\u786e\u7684\u5730\u5740\uff0c\u800c\u8981 Hook \u67d0\u4e2a\u5bfc\u5165\u7684\u51fd\u6570\uff0c\u53ea\u9700\u5176\u540e\u5c06 IAT \u4e2d\u5b83\u7684\u5730\u5740\u66ff\u6362\u4e3a\u6211\u4eec\u7684\u5c31\u884c\u4e86\u3002<\/p>\n<p>\u4ee5 Hook WinAPI <code>OutputDebugStringA<\/code> \u4e3a\u4f8b\uff0c\u5b9e\u73b0\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre class=\"lang:c++ decode:true \">LPVOID orgFunc;\r\n\r\n\/*\r\n\thook(myF, orgName) =&gt; bool, whether succeeds\r\n\tmyF (LPVOID) my function address\r\n\torgName (LPCSTR) original function name\r\n*\/\r\nbool HOOKIAT::hook(LPVOID myF, LPCSTR orgName)\r\n{\r\n\tbool suc = false;\r\n\r\n\t\/\/ base address of current process\r\n\tLPVOID imageBase = GetModuleHandleA(NULL);\r\n\tPIMAGE_DOS_HEADER dosHeaders = (PIMAGE_DOS_HEADER)imageBase;\r\n\tPIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)imageBase + dosHeaders-&gt;e_lfanew);\r\n\r\n\t\/\/ jump to imports directory\r\n\tPIMAGE_IMPORT_DESCRIPTOR importDescriptor = NULL;\r\n\tIMAGE_DATA_DIRECTORY importsDirectory = ntHeaders-&gt;OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];\r\n\timportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(importsDirectory.VirtualAddress + (DWORD_PTR)imageBase);\r\n\tLPCSTR libraryName = NULL;\r\n\tHMODULE library = NULL;\r\n\tPIMAGE_IMPORT_BY_NAME functionName = NULL;\r\n\r\n\t\/\/ loop import modules\r\n\twhile (importDescriptor-&gt;Name != NULL)\r\n\t{\r\n\t\t\/\/ get handle of this imported module\r\n\t\tlibraryName = (LPCSTR)((DWORD_PTR)imageBase + importDescriptor-&gt;Name);\r\n\t\tif (library = LoadLibraryA(libraryName))\r\n\t\t{\r\n\t\t\tPIMAGE_THUNK_DATA originalFirstThunk = NULL, firstThunk = NULL;\r\n\t\t\toriginalFirstThunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)imageBase + importDescriptor-&gt;OriginalFirstThunk);\r\n\t\t\tfirstThunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)imageBase + importDescriptor-&gt;FirstThunk);\r\n\r\n\t\t\t\/\/ loop import functions\r\n\t\t\twhile (originalFirstThunk-&gt;u1.AddressOfData != NULL &amp;&amp; !IMAGE_SNAP_BY_ORDINAL(originalFirstThunk-&gt;u1.Ordinal))\r\n\t\t\t{\r\n\t\t\t\tfunctionName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)imageBase + originalFirstThunk-&gt;u1.AddressOfData);\r\n\t\t\t\t\r\n\t\t\t\t\/\/ find function by name\r\n\t\t\t\tif (strcmp(this-&gt;orgName, functionName-&gt;Name) == 0)\r\n\t\t\t\t{\r\n\t\t\t\t\tif (!orgFunc)\r\n\t\t\t\t\t\torgFunc = (LPVOID)(firstThunk-&gt;u1.Function);\r\n\t\t\t\t\t\/\/ patch this\r\n\t\t\t\t\tif (!HOOK::patch((DWORD_PTR)&amp;firstThunk-&gt;u1.Function, (BYTE*)&amp;myF, sizeof(DWORD_PTR)))\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\tsuc = true;\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t++originalFirstThunk;\r\n\t\t\t\t++firstThunk;\r\n\t\t\t}\r\n\t\t}\r\n\t\t++importDescriptor;\r\n\t}\r\n\t\r\n\treturn suc;\r\n}\r\n\r\nHOOKIAT::hook(myOutputDebugStringA, \"OutputDebugStringA\");<\/pre>\n<p>\u5176\u4e2d Hook \u5230\u7684\u6211\u4eec\u7684 <code>myOutputDebugStringA<\/code> \u51fd\u6570\u5b9e\u73b0\u5982\u4e0b\uff1a<\/p>\n<pre class=\"lang:c++ decode:true \">typedef void (WINAPI* tpOutputDebugStringA)(LPCSTR);\r\nvoid WINAPI myOutputDebugStringA(LPCSTR lpOutputString)\r\n{\r\n\tMessageBoxA(NULL, lpOutputString, \"DEBUG\", 0);\r\n\ttpOutputDebugStringA ODA = static_cast&lt;tpOutputDebugStringA&gt;(orgFunc);\r\n\tODA(lpOutputString);\r\n}<\/pre>\n<p>\u8fd9\u6837\u5c31\u5b8c\u6210\u4e86\u4e00\u4e2a\u7b80\u5355\u7684 IAT Hook\u3002<\/p>\n<p>\u53ef\u4ee5\u53d1\u73b0 PE \u4e2d\u7684 IAT \u4e0e ELF \u4e2d\u7684 GOT\/PLT \u5b58\u5728\u76f8\u4f3c\u4e4b\u5904\u3002<\/p>\n<p>&nbsp;<\/p>\n<p><a id=\"usercall\"><\/a>\u00a0<\/p>\n<hr \/>\n<ul>\n<li>\n<h3><strong><code>__usercall<\/code> \u7684\u8f6c\u6362<\/strong><\/h3>\n<\/li>\n<\/ul>\n<p>\u81f3\u6b64\uff0c\u6211\u4eec\u5df2\u7ecf\u53ef\u4ee5\u5f88\u597d\u5730 Hook \u4e00\u4e9b\u5e38\u89c4\u7684\u51fd\u6570\u4e86\u3002<\/p>\n<p>\u800c\u6709\u4e9b\u51fd\u6570\u5728 IDA \u91cc\u4f1a\u88ab\u5206\u6790\u6210\u4e0b\u56fe\u7684 <code>__usercall<\/code> \u8c03\u7528\u65b9\u5f0f\uff1a<\/p>\n<pre class=\"lang:c++ decode:true \">char __usercall sub_475E90@&lt;al&gt;(_DWORD *a1@&lt;eax&gt;, _DWORD *a2@&lt;edi&gt;, int a3)<\/pre>\n<p><code>__usercall<\/code> \u610f\u5473\u7740\u533a\u522b\u4e8e\u5e38\u89c4\u7684 <code>__stdcall<\/code> \uff08\u53c2\u6570\u81ea\u53f3\u5411\u5de6\u4f9d\u6b21\u5165\u6808\uff0c\u7531\u88ab\u8c03\u7528\u51fd\u6570\u6e05\u7406\uff09\u6216\u662f <code>__cdecl<\/code>\uff08\u53c2\u6570\u81ea\u53f3\u5411\u5de6\u4ee5\u6b64\u5165\u6808\uff0c\u7531\u8c03\u7528\u8005\u81ea\u884c\u6e05\u7406\uff09\uff0c\u5b83\u5148\u628a\u4e00\u4e9b\u53c2\u6570\u5b58\u5728\u5bc4\u5b58\u5668\u91cc\uff0c\u4f7f\u7528\u5bc4\u5b58\u5668\u4f20\u53c2\uff0c\u800c\u540e\u624d\u4f1a\u5165\u6808\uff0c\u662f\u4e00\u79cd\u7f16\u8bd1\u5668\u4f18\u5316\u800c\u6210\u7684\u975e\u6807\u51c6\u7684\u8c03\u7528\u65b9\u6cd5\u3002<\/p>\n<p>\u8fd9\u5c31\u610f\u5473\u7740\u6211\u4eec\u65e0\u6cd5\u4f7f\u7528\u7eaf C\/++ \u4ee3\u7801\u6765\u5b9e\u73b0\u6b64\u51fd\u6570\u7684 Hook\uff08\u751a\u81f3\u662f\u8c03\u7528\uff09\uff0c\u4e0d\u8fc7\u5185\u8054\u6c47\u7f16\u4f7f\u8f6c\u6362\u51fd\u6570\uff08<code>__usercall<\/code> &lt;-&gt; <code>__stdcall<\/code>\uff09\u6210\u4e3a\u4e86\u53ef\u80fd\u3002<\/p>\n<p>\u5173\u4e8e\u51fd\u6570\u8c03\u7528\u6808\u64cd\u4f5c\u7684\u7c97\u6d45\u7684\u7406\u89e3\uff0c\u5728\u5148\u524d\u7684\u6587\u7ae0 <a href=\"https:\/\/0self.mnihyc.com\/blog\/archives\/1501\">\u201c\u6808\u6ea2\u51fa \u2014\u2014 \u521d\u7ea7 ROP \u5b66\u4e60\u8bb0\u5f55\u201d<\/a> \u5df2\u6709\u6240\u63d0\u53ca\u3002<\/p>\n<p>\u5728\u8fd9\u91cc Hook \u53ef\u4ee5\u5b8c\u5168\u4eff\u7167\u5148\u524d\u5e26 <code>Gadget<\/code> \u7684 <code>JMP<\/code> \u65b9\u6cd5\uff0c\u5e94\u5f53\u628a\u6ce8\u610f\u529b\u96c6\u4e2d\u5728\u4e24\u79cd\u8c03\u7528\u65b9\u6cd5\u7684\u8f6c\u6362\u4e0a\u3002<\/p>\n<p>\u4ee5 <code>base + 0x75E90<\/code> \u5904\u7684\u51fd\u6570 <code>sub_475E90<\/code> \u4e3a\u4f8b\uff0c\u5b83\u63a5\u53d7\u4e09\u4e2a\u53c2\u6570\uff0c\u5206\u522b\u7531 <code>eax<\/code>\uff0c<code>edi<\/code> \u548c\u6808\u4f20\u9012\uff0c\u6700\u540e\u7528 <code>eax<\/code> \u4f20\u9012\u8fd4\u56de\u503c\u3002<\/p>\n<p>\u5728\u5b9e\u73b0\u4e0a\uff0c<code>__usercall<\/code> \u4f1a\u66f4\u76f8\u4f3c\u4e8e<code> __cdecl<\/code>\uff0c\u56e0\u4e3a\u524d\u8005\u53ef\u4ee5\u88ab\u770b\u505a\u662f\u540e\u8005\u7684\u4e00\u79cd\u4f18\u5316\u3002\u6240\u4ee5\u628a\u539f\u51fd\u6570 Hook \u81f3\u6211\u4eec\u7684 <code>sub_475E90<\/code>\uff0c\u5b9e\u73b0\u5982\u4e0b\uff1a\uff08\u5728\u8fd9\u91cc\u8fdb\u884c <code>enter<\/code>\/<code>leave<\/code> \u64cd\u4f5c\u662f\u4e3a\u4e86\u907f\u514d <code>push<\/code> \u53c2\u6570\u65f6\u53ef\u80fd\u4f1a\u51fa\u73b0\u6ea2\u51fa\uff09<\/p>\n<pre class=\"lang:c++ decode:true \">__declspec(naked) char __cdecl sub_475E90(int a3)\r\n{\r\n\t__asm\r\n\t{\r\n\t\tpush ebp \/\/ save stack frame\r\n\t\tmov ebp, esp \/\/ create new stack frame\r\n\t\tpush a3 \/\/ push arguments\r\n\t\tpush edi \/\/ push arguments\r\n\t\tpush eax \/\/ push arguments\r\n\t\tcall mysub_475E90 \/\/ converted to __stdcall\r\n\t\tleave \/\/ recover stack frame\r\n\t\tret \/\/ finished\r\n\t}\r\n}<\/pre>\n<p>\u800c <code>mysub_475E90<\/code> \u5df2\u7ecf\u53ef\u4ee5\u88ab\u5f53\u505a\u662f\u4e00\u4e2a\u666e\u901a\u7684<code> __stdcall<\/code> \u51fd\u6570\u4e86\u3002\uff08\u8f6c\u6362\u6210\u529f\uff01\uff09<\/p>\n<pre class=\"lang:c++ decode:true \">char __stdcall mysub_475E90(DWORD* a1, DWORD* a2, int a3)\r\n{\r\n\t\/\/ Do whatever wants here\r\n\treturn orgsub_475E90(a1, a2, a3);\r\n}<\/pre>\n<p><code>orgsub_475E90<\/code> \u5b9e\u73b0\u4e86\u4ece <code>__cdecl<\/code> \u5230 <code>__usercall<\/code> \u7684\u8f6c\u6362\u3002\uff08\u6211\u5728\u8fd9\u91cc\u4f7f\u7528\u4e86 <code>HOOKJMP::get<\/code> \u51fd\u6570\uff0c\u529f\u80fd\u662f\u8fd4\u56de\u539f\u51fd\u6570\uff08\u6216\u8005\u662f <code>Gadget<\/code>\uff09\u7684\u5730\u5740\uff0c<code>ecx<\/code> \u4f5c\u4e3a <code>this<\/code> \u6307\u9488\u4f20\u8fdb\u53bb\uff09\uff08\u8c03\u7528\u5b8c\u539f\u51fd\u6570\u540e\u8981\u8bb0\u5f97\u5e73\u8861\u5806\u6808\uff0c<code>orgsub_475E90<\/code> \u9009\u62e9\u4e86 <code>__cdecl<\/code> \u4e5f\u662f\u4e3a\u4e86\u907f\u514d\u9700\u8981\u5728 <code>__declspec(naked)<\/code> \u91cc\u624b\u52a8\u5e73\u8861\u5806\u6808\uff09<\/p>\n<pre class=\"lang:c++ decode:true \">__declspec(naked) char __cdecl orgsub_475E90(DWORD* a1, DWORD* a2, int a3)\r\n{\r\n\t__asm\r\n\t{\r\n\t\tlea ecx, hookJMP \/\/ store class pointer in ecx\r\n\t\tcall HOOKJMP::get \/\/ __thiscall\r\n\t\tmov ecx, eax \/\/ original function address\r\n\t\t\/\/ or just    mov ecx, orgFunc\r\n\t\tpush a3 \/\/ push arguments\r\n\t\tmov edi, a2 \/\/ __usercall\r\n\t\tmov eax, a1 \/\/ __usercall\r\n\t\tcall ecx \/\/ call original function\r\n\t\tadd esp, 0x4 \/\/ recover stack for a3\r\n\t\tret \/\/ finished\r\n\t}\r\n}<\/pre>\n<p>\u8fd9\u6837\u5c31\u53ef\u4ee5 Hook \u4e00\u4e2a <code>__usercall<\/code> \u51fd\u6570\uff0c\u5305\u62ec\u6b63\u5e38\u8c03\u7528\u539f\u51fd\u6570\u4e86\u3002<\/p>\n<p>\uff08\u4e00\u4e2a\u9690\u85cf\u7684\u95ee\u9898\uff0c\u4f7f\u7528\u8fd9\u79cd\u65b9\u6cd5 Hook \u65f6\uff0c<code>va_list<\/code> \u53ef\u80fd\u65e0\u6cd5\u88ab\u6b63\u786e\u5730\u4f20\u9012\u3002\uff09<\/p>\n<p>&nbsp;<\/p>\n<p><a id=\"ref_dll\"><\/a>\u00a0<\/p>\n<hr \/>\n<ul>\n<li>\n<h3><strong>\u9644\uff1aReflective PE Loader<\/strong><\/h3>\n<\/li>\n<\/ul>\n<p>\u4ece\u5185\u5b58\u4e2d\u52a0\u8f7d DLL \u6216\u662f\u8fd0\u884c EXE \u662f\u4e00\u4e2a\u96be\u9898\uff0c\u8fd9\u91cc\u5217\u51fa\u51e0\u6b21\u5c1d\u8bd5\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>\u52a0\u8f7d\u4e00\u4e2a DLL \u65f6\uff0c<code>LoadLibrary<\/code> \u5176\u5b9e\u505a\u4e86\u4e24\u4ef6\u4e8b\uff1a\u4fee\u590d reloc\uff0c\u5bfc\u5165 IAT\u3002<\/p>\n<p>\u5728\u672c\u8fdb\u7a0b\u52a0\u8f7d DLL \u65f6\uff0c\u53ea\u9700\u5728\u5185\u5b58\u4e2d\u624b\u52a8\u89e3\u6790 PE \u5934\u7ed3\u6784\uff0c\u4fee\u590d reloc \u6bb5\uff0c\u6784\u5efa IAT \u8868\uff0c\u7136\u540e\u8f6c\u5230 <code>DllMain<\/code> \u5c31\u53ef\u4ee5\u4e86\u3002<\/p>\n<p>\u672c\u8fdb\u7a0b\u7684 Reflective DLL Loader \u662f\u6210\u529f\u7684\uff0c\u53ea\u662f <code>DllMain<\/code> \u9700\u8981\u4fdd\u6301\u963b\u585e\u5426\u5219\u8c03\u7528 DLL \u7684\u5bfc\u51fa\u51fd\u6570\u65f6\u4f1a\u53d1\u751f\u9519\u8bef\uff08\u6216\u8bb8\u53ef\u4ee5\u7528 <code>GetProcAddress<\/code> \u907f\u514d\uff1f\uff09\u3002<\/p>\n<pre class=\"lang:c++ decode:true \">typedef struct BASE_RELOCATION_BLOCK\r\n{\r\n\tDWORD PageAddress;\r\n\tDWORD BlockSize;\r\n} BASE_RELOCATION_BLOCK, * PBASE_RELOCATION_BLOCK;\r\n\r\ntypedef struct BASE_RELOCATION_ENTRY\r\n{\r\n\tWORD Offset : 12;\r\n\tWORD Type : 4;\r\n} BASE_RELOCATION_ENTRY, * PBASE_RELOCATION_ENTRY;\r\n\r\ntypedef BOOL(WINAPI* tpDllMain)(HMODULE, DWORD, LPVOID);\r\n\r\nvoid PLoadDll(LPVOID imageBase)\r\n{\r\n\t\/\/ pe headers\r\n\tPIMAGE_DOS_HEADER dosHeaders = (PIMAGE_DOS_HEADER)imageBase;\r\n\tPIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)imageBase + dosHeaders-&gt;e_lfanew);\r\n\tDWORD_PTR deltaImageBase = (DWORD_PTR)imageBase - (DWORD_PTR)ntHeaders-&gt;OptionalHeader.ImageBase;\r\n\r\n\t\/\/ perform image base relocation\r\n\tIMAGE_DATA_DIRECTORY relocations = ntHeaders-&gt;OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];\r\n\tDWORD_PTR relocationTable = relocations.VirtualAddress + (DWORD_PTR)imageBase;\r\n\tDWORD relocationsProcessed = 0;\r\n\twhile (relocationsProcessed &lt; relocations.Size)\r\n\t{\r\n\t\tPBASE_RELOCATION_BLOCK relocationBlock = (PBASE_RELOCATION_BLOCK)(relocationTable + relocationsProcessed);\r\n\t\trelocationsProcessed += sizeof(BASE_RELOCATION_BLOCK);\r\n\t\tDWORD relocationsCount = (relocationBlock-&gt;BlockSize - sizeof(BASE_RELOCATION_BLOCK)) \/ sizeof(BASE_RELOCATION_ENTRY);\r\n\t\tPBASE_RELOCATION_ENTRY relocationEntries = (PBASE_RELOCATION_ENTRY)(relocationTable + relocationsProcessed);\r\n\t\tfor (DWORD i = 0; i &lt; relocationsCount; i++)\r\n\t\t{\r\n\t\t\trelocationsProcessed += sizeof(BASE_RELOCATION_ENTRY);\r\n\t\t\tif (relocationEntries[i].Type == 0)\r\n\t\t\t\tcontinue;\r\n\t\t\tDWORD_PTR relocationRVA = relocationBlock-&gt;PageAddress + relocationEntries[i].Offset;\r\n\t\t\tDWORD_PTR writePosition = (DWORD_PTR)imageBase + relocationRVA;\r\n\t\t\tDWORD oldProtect = 0;\r\n\t\t\tVirtualProtect((LPVOID)writePosition, sizeof(DWORD_PTR), PAGE_READWRITE, &amp;oldProtect);\r\n\t\t\tDWORD_PTR *addressToPatch = (DWORD_PTR*)writePosition;\r\n\t\t\t*addressToPatch += deltaImageBase;\r\n\t\t\tVirtualProtect((LPVOID)writePosition, sizeof(DWORD_PTR), oldProtect, &amp;oldProtect);\r\n\t\t}\r\n\t}\r\n\r\n\t\/\/ resolve import address table\r\n\tPIMAGE_IMPORT_DESCRIPTOR importDescriptor = NULL;\r\n\tIMAGE_DATA_DIRECTORY importsDirectory = ntHeaders-&gt;OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];\r\n\timportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(importsDirectory.VirtualAddress + (DWORD_PTR)imageBase);\r\n\tLPCSTR libraryName = NULL;\r\n\tHMODULE library = NULL;\r\n\tPIMAGE_IMPORT_BY_NAME functionName = NULL;\r\n\r\n\twhile (importDescriptor-&gt;Name != NULL)\r\n\t{\r\n\t\tlibraryName = (LPCSTR)(importDescriptor-&gt;Name + (DWORD_PTR)imageBase);\r\n\t\tlibrary = LoadLibraryA(libraryName);\r\n\r\n\t\tif (library)\r\n\t\t{\r\n\t\t\tPIMAGE_THUNK_DATA originalFirstThunk = NULL, firstThunk = NULL;\r\n\t\t\toriginalFirstThunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)imageBase + importDescriptor-&gt;OriginalFirstThunk);\r\n\t\t\tfirstThunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)imageBase + importDescriptor-&gt;FirstThunk);\r\n\t\t\twhile (originalFirstThunk-&gt;u1.AddressOfData != NULL)\r\n\t\t\t{\r\n\t\t\t\tDWORD oldProtect = 0;\r\n\t\t\t\tVirtualProtect((LPVOID)(&amp;firstThunk-&gt;u1.Function), sizeof(DWORD_PTR), PAGE_READWRITE, &amp;oldProtect);\r\n\t\t\t\t\/\/ import by ordinal or name\r\n\t\t\t\tif (IMAGE_SNAP_BY_ORDINAL(originalFirstThunk-&gt;u1.Ordinal))\r\n\t\t\t\t{\r\n\t\t\t\t\tLPCSTR functionOrdinal = (LPCSTR)IMAGE_ORDINAL(originalFirstThunk-&gt;u1.Ordinal);\r\n\t\t\t\t\tfirstThunk-&gt;u1.Function = (DWORD_PTR)GetProcAddress(library, functionOrdinal);\r\n\t\t\t\t}\r\n\t\t\t\telse\r\n\t\t\t\t{\r\n\t\t\t\t\tPIMAGE_IMPORT_BY_NAME functionName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)imageBase + originalFirstThunk-&gt;u1.AddressOfData);\r\n\t\t\t\t\tDWORD_PTR functionAddress = (DWORD_PTR)GetProcAddress(library, functionName-&gt;Name);\r\n\t\t\t\t\tfirstThunk-&gt;u1.Function = functionAddress;\r\n\t\t\t\t}\r\n\t\t\t\tVirtualProtect((LPVOID)(&amp;firstThunk-&gt;u1.Function), sizeof(DWORD_PTR), oldProtect, &amp;oldProtect);\r\n\t\t\t\t++originalFirstThunk;\r\n\t\t\t\t++firstThunk;\r\n\t\t\t}\r\n\t\t}\r\n\t\t++importDescriptor;\r\n\t}\r\n\r\n\t\/\/ entering DllMain\r\n\ttpDllMain DllMain = (tpDllMain)((DWORD_PTR)lp-&gt;imageBase + ntHeaders-&gt;OptionalHeader.AddressOfEntryPoint);\r\n\t(*DllMain)((HMODULE)lp-&gt;imageBase, DLL_PROCESS_ATTACH, NULL);\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>\u800c\u8fdc\u7a0b Reflective DLL Loader \u4e00\u4e2a\u663e\u800c\u6613\u89c1\u7684\u601d\u8def\u5c31\u662f\u628a\u8fd9\u4e2a Loader\uff08\u4fee\u590d reloc\uff0cIAT\uff09\u529f\u80fd\u6ce8\u5165\u5230\u8fdc\u7a0b\u8fdb\u7a0b\u4e2d\u6267\u884c\u3002\uff08\u5982\u4e0b\u4ee3\u7801\uff09<\/p>\n<p>\u7136\u800c\u8fd9\u4e48\u505a\u6709\u4e00\u5b9a\u5931\u8d25\u7684\u673a\u7387\uff0c\u63a8\u6d4b\u539f\u56e0\u4e3a ASLR \u5bfc\u81f4 kernel32.dll \u4e2d API \u7684\u5730\u5740\u53d1\u751f\u4e86\u53d8\u5316\uff0c\u4e00\u79cd\u53ef\u884c\u7684\u6539\u8fdb\u65b9\u6cd5\u4e3a\u4e0d\u501f\u52a9\u5176\u5b83 WinAPI \u800c\u627e\u5230\u8fd9\u4e9b\u51fd\u6570\u7684\u5730\u5740\uff08\u5f85\u5751\uff09\u3002<\/p>\n<pre class=\"lang:c++ decode:true \">typedef HMODULE(WINAPI* tpLoadLibraryA)(LPCSTR);\r\ntypedef FARPROC(WINAPI* tpGetProcAddress)(HMODULE, LPCSTR);\r\ntypedef BOOL(WINAPI* tpVirtualProtect)(LPVOID, SIZE_T, DWORD, PDWORD);\r\ntypedef BOOL(WINAPI* tpDllMain)(HMODULE, DWORD, LPVOID);\r\n\r\nstruct PLoaderParam\r\n{\r\n\tLPVOID imageBase;\r\n\ttpLoadLibraryA fnLoadLibraryA;\r\n\ttpGetProcAddress fnGetProcAddress;\r\n\ttpVirtualProtect fnVirtualProtect;\r\n};\r\n\r\n\/\/ injected thread\r\nDWORD WINAPI PFixDll(LPVOID param)\r\n{\r\n\tPLoaderParam* lp = (PLoaderParam*)param;\r\n\t\/\/ same as above ...\r\n}\r\n\r\n\/\/ used to compute offset\r\nDWORD WINAPI _p2stub()\r\n{\r\n\treturn 0;\r\n}\r\n\r\nbool PLoadDll(HANDLE hProcess, LPVOID lpBuffer, DWORD dwLength)\r\n{\r\n\t\/\/ load dll into remote process\r\n\tPIMAGE_DOS_HEADER dosHeaders = (PIMAGE_DOS_HEADER)lpBuffer;\r\n\tPIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)lpBuffer + dosHeaders-&gt;e_lfanew);\r\n\tSIZE_T imageSize = ntHeaders-&gt;OptionalHeader.SizeOfImage;\r\n\tLPVOID lpRemoteBuffer = VirtualAllocEx(hProcess, NULL, imageSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);\r\n\tif (lpRemoteBuffer == NULL)\r\n\t\treturn false;\r\n\t\r\n\t\/\/ copy header\/section\r\n\tif(!WriteProcessMemory(hProcess, lpRemoteBuffer, lpBuffer, ntHeaders-&gt;OptionalHeader.SizeOfHeaders, NULL))\r\n\t\treturn false;\r\n\tPIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeaders);\r\n\tfor (size_t i = 0; i &lt; ntHeaders-&gt;FileHeader.NumberOfSections; i++)\r\n\t{\r\n\t\tif (!WriteProcessMemory(hProcess, (LPVOID)((DWORD_PTR)lpRemoteBuffer + section-&gt;VirtualAddress),\r\n\t\t\t\t(LPVOID)((DWORD_PTR)lpBuffer + section-&gt;PointerToRawData), section-&gt;SizeOfRawData, NULL))\r\n\t\t\treturn false;\r\n\t\tstatic const ULONG mapping[] = { PAGE_NOACCESS, PAGE_EXECUTE, PAGE_READONLY, PAGE_EXECUTE_READ,\r\n\t\t\t\tPAGE_READWRITE, PAGE_EXECUTE_READWRITE, PAGE_READWRITE, PAGE_EXECUTE_READWRITE };\r\n\t\t\/\/ proper page protection\r\n\t\tDWORD oldProtect = 0;\r\n\t\tVirtualProtectEx(hProcess, (LPVOID)((DWORD_PTR)lpRemoteBuffer + section-&gt;VirtualAddress),\r\n\t\t\t\tsection-&gt;SizeOfRawData, mapping[section-&gt;Characteristics &gt;&gt; 29], &amp;oldProtect);\r\n\t\t++section;\r\n\t}\r\n\r\n\tPLoaderParam lp{};\r\n\tlp.imageBase = lpRemoteBuffer;\r\n\tlp.fnLoadLibraryA = LoadLibraryA;\r\n\tlp.fnGetProcAddress = GetProcAddress;\r\n\tlp.fnVirtualProtect = VirtualProtect;\r\n\r\n\t\/\/ load remote thread\r\n\tDWORD szRLoader = (DWORD_PTR)_p2stub - (DWORD_PTR)PFixDll;\r\n\tLPVOID lpRLoader = VirtualAllocEx(hProcess, NULL, szRLoader, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);\r\n\tLPVOID lpRLoaderParam = VirtualAllocEx(hProcess, NULL, sizeof(lp), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);\r\n\tif (lpRLoader == NULL || lpRLoaderParam == NULL)\r\n\t\treturn false;\r\n\tif (!WriteProcessMemory(hProcess, lpRLoader, PFixDll, szRLoader, NULL))\r\n\t\treturn false;\r\n\tif (!WriteProcessMemory(hProcess, lpRLoaderParam, &amp;lp, sizeof(lp), NULL))\r\n\t\treturn false;\r\n\tHANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpRLoader, lpRLoaderParam, 0, NULL);\r\n\tif (hThread == NULL)\r\n\t\treturn false;\r\n\t\/\/WaitForSingleObject(hThread, INFINITE);\r\n\tCloseHandle(hThread);\r\n\treturn true;\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>\u800c\u672c\u5730\u52a0\u8f7d EXE \u540c\u7406\uff0c\u4fee\u590d reloc\uff0c\u6784\u5efa IAT\uff0c\u7136\u540e\u8f6c\u5230\u5165\u53e3\u70b9\u6267\u884c\u3002\u4ee3\u7801\u57fa\u672c\u540c\u4e0a\u3002<\/p>\n<p>\u7136\u800c\u52a0\u8f7d\u5927\u591a\u6570\u7a0b\u5e8f\u65f6\u5374\u5931\u8d25\u4e86\uff08\u6709\u4e2a\u4f8b\u80fd\u6210\u529f\uff09\uff0c\u539f\u56e0\u672a\u77e5\u3002<\/p>\n<p>\u8fdc\u7a0b\u52a0\u8f7d EXE \u66f4\u4e0d\u7528\u8bf4\uff0c\u6709\u770b\u5230\u4e00\u79cd\u5199\u6cd5\u662f\u5148 <code>ZwUnmapViewOfSection<\/code> \u6389\u539f\u6765\u7684\u533a\u5757\uff0c\u624b\u52a8\u4fee\u590d reloc\u3001IAT \u540e\u7528 <code>SetThreadContext<\/code> \u8986\u76d6\u4e0a\u53bb\uff0c\u52a0\u8f7d\u5927\u591a\u6570\u7a0b\u5e8f\u65f6\u4e5f\u5408\u7406\u5730\u5931\u8d25\u4e86\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>\u4ee5\u4e0a\u4e3a\u4e00\u4e9b\u5c1d\u8bd5\u3002<\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u9047\u5230\u4e86\u9700\u8981 Hook \u4e00\u4e9b\u51fd\u6570\u7684\u60c5\u51b5\uff0cWinAPI \u7684 __stdcall \u6216\u662f IDA \u5206\u6790\u51fa\u6765\u7684 __us &hellip; <a href=\"https:\/\/0self.mnihyc.com\/blog\/archives\/1715\" class=\"more-link\">\u7ee7\u7eed\u9605\u8bfb<span class=\"screen-reader-text\">Win32 \u4e0b Hook \u51fd\u6570\u7684\u51e0\u79cd\u65b9\u6cd5<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,21],"tags":[],"class_list":["post-1715","post","type-post","status-publish","format-standard","hentry","category-other","category-tools"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Win32 \u4e0b Hook \u51fd\u6570\u7684\u51e0\u79cd\u65b9\u6cd5 - mnihyc&#039;s Blog<\/title>\n<meta name=\"description\" content=\"\u9047\u5230\u4e86\u9700\u8981 Hook \u4e00\u4e9b\u51fd\u6570\u7684\u60c5\u51b5\uff0cWinAPI \u7684 __stdcall \u6216\u662f IDA \u5206\u6790\u51fa\u6765\u7684 __usercall\uff0c\u7559\u6b64\u7eaa\u5f55\u3002\u6d4b\u8bd5\u73af\u5883\u4e3a Win32\uff0c\u7f16\u8bd1\u5668\u4e3a MSVC\u3002 &nbsp; &nbsp; \u76ee\u5f55 \u666e\u901a JMP\uff08\u4e0d\u63a8\u8350\uff09 \u5e26 Gadget \u7684 JMP \u66ff\u6362 IAT\uff08\u4ec5\u9002\u7528 PE\uff09\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/mnihyc.com\/blog\/archives\/1715\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Win32 \u4e0b Hook \u51fd\u6570\u7684\u51e0\u79cd\u65b9\u6cd5 - mnihyc&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"\u9047\u5230\u4e86\u9700\u8981 Hook \u4e00\u4e9b\u51fd\u6570\u7684\u60c5\u51b5\uff0cWinAPI \u7684 __stdcall \u6216\u662f IDA \u5206\u6790\u51fa\u6765\u7684 __usercall\uff0c\u7559\u6b64\u7eaa\u5f55\u3002\u6d4b\u8bd5\u73af\u5883\u4e3a Win32\uff0c\u7f16\u8bd1\u5668\u4e3a MSVC\u3002 &nbsp; &nbsp; \u76ee\u5f55 \u666e\u901a JMP\uff08\u4e0d\u63a8\u8350\uff09 \u5e26 Gadget \u7684 JMP \u66ff\u6362 IAT\uff08\u4ec5\u9002\u7528 PE\uff09\" \/>\n<meta property=\"og:url\" content=\"https:\/\/mnihyc.com\/blog\/archives\/1715\" \/>\n<meta property=\"og:site_name\" content=\"mnihyc&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-04-17T15:11:42+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-04-29T08:38:44+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-gadget_jmp.png\" \/>\n<meta name=\"author\" content=\"mnihyc\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@mnihyc\" \/>\n<meta name=\"twitter:site\" content=\"@mnihyc\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"mnihyc\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1715#article\",\"isPartOf\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1715\"},\"author\":{\"name\":\"mnihyc\",\"@id\":\"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751\"},\"headline\":\"Win32 \u4e0b Hook \u51fd\u6570\u7684\u51e0\u79cd\u65b9\u6cd5\",\"datePublished\":\"2022-04-17T15:11:42+00:00\",\"dateModified\":\"2022-04-29T08:38:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1715\"},\"wordCount\":137,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751\"},\"image\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1715#primaryimage\"},\"thumbnailUrl\":\"https:\/\/mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-gadget_jmp.png\",\"articleSection\":[\"\u5176\u5b83\",\"\u5de5\u5177\"],\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/mnihyc.com\/blog\/archives\/1715#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1715\",\"url\":\"https:\/\/mnihyc.com\/blog\/archives\/1715\",\"name\":\"Win32 \u4e0b Hook \u51fd\u6570\u7684\u51e0\u79cd\u65b9\u6cd5 - mnihyc&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1715#primaryimage\"},\"image\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1715#primaryimage\"},\"thumbnailUrl\":\"https:\/\/mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-gadget_jmp.png\",\"datePublished\":\"2022-04-17T15:11:42+00:00\",\"dateModified\":\"2022-04-29T08:38:44+00:00\",\"description\":\"\u9047\u5230\u4e86\u9700\u8981 Hook \u4e00\u4e9b\u51fd\u6570\u7684\u60c5\u51b5\uff0cWinAPI \u7684 __stdcall \u6216\u662f IDA \u5206\u6790\u51fa\u6765\u7684 __usercall\uff0c\u7559\u6b64\u7eaa\u5f55\u3002\u6d4b\u8bd5\u73af\u5883\u4e3a Win32\uff0c\u7f16\u8bd1\u5668\u4e3a MSVC\u3002 &nbsp; &nbsp; \u76ee\u5f55 \u666e\u901a JMP\uff08\u4e0d\u63a8\u8350\uff09 \u5e26 Gadget \u7684 JMP \u66ff\u6362 IAT\uff08\u4ec5\u9002\u7528 PE\uff09\",\"breadcrumb\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1715#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/mnihyc.com\/blog\/archives\/1715\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1715#primaryimage\",\"url\":\"https:\/\/mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-gadget_jmp.png\",\"contentUrl\":\"https:\/\/mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-gadget_jmp.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/mnihyc.com\/blog\/archives\/1715#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/mnihyc.com\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Win32 \u4e0b Hook \u51fd\u6570\u7684\u51e0\u79cd\u65b9\u6cd5\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/mnihyc.com\/blog\/#website\",\"url\":\"https:\/\/mnihyc.com\/blog\/\",\"name\":\"mnihyc&#039;s Blog\",\"description\":\"Welcome!\",\"publisher\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/mnihyc.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"zh-Hans\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751\",\"name\":\"mnihyc\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8d111f863afc3f98816bc96220f97077d470a96f41088de9f19530fc480f8e72?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8d111f863afc3f98816bc96220f97077d470a96f41088de9f19530fc480f8e72?s=96&d=mm&r=g\",\"caption\":\"mnihyc\"},\"logo\":{\"@id\":\"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Win32 \u4e0b Hook \u51fd\u6570\u7684\u51e0\u79cd\u65b9\u6cd5 - mnihyc&#039;s Blog","description":"\u9047\u5230\u4e86\u9700\u8981 Hook \u4e00\u4e9b\u51fd\u6570\u7684\u60c5\u51b5\uff0cWinAPI \u7684 __stdcall \u6216\u662f IDA \u5206\u6790\u51fa\u6765\u7684 __usercall\uff0c\u7559\u6b64\u7eaa\u5f55\u3002\u6d4b\u8bd5\u73af\u5883\u4e3a Win32\uff0c\u7f16\u8bd1\u5668\u4e3a MSVC\u3002 &nbsp; &nbsp; \u76ee\u5f55 \u666e\u901a JMP\uff08\u4e0d\u63a8\u8350\uff09 \u5e26 Gadget \u7684 JMP \u66ff\u6362 IAT\uff08\u4ec5\u9002\u7528 PE\uff09","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/mnihyc.com\/blog\/archives\/1715","og_locale":"zh_CN","og_type":"article","og_title":"Win32 \u4e0b Hook \u51fd\u6570\u7684\u51e0\u79cd\u65b9\u6cd5 - mnihyc&#039;s Blog","og_description":"\u9047\u5230\u4e86\u9700\u8981 Hook \u4e00\u4e9b\u51fd\u6570\u7684\u60c5\u51b5\uff0cWinAPI \u7684 __stdcall \u6216\u662f IDA \u5206\u6790\u51fa\u6765\u7684 __usercall\uff0c\u7559\u6b64\u7eaa\u5f55\u3002\u6d4b\u8bd5\u73af\u5883\u4e3a Win32\uff0c\u7f16\u8bd1\u5668\u4e3a MSVC\u3002 &nbsp; &nbsp; \u76ee\u5f55 \u666e\u901a JMP\uff08\u4e0d\u63a8\u8350\uff09 \u5e26 Gadget \u7684 JMP \u66ff\u6362 IAT\uff08\u4ec5\u9002\u7528 PE\uff09","og_url":"https:\/\/mnihyc.com\/blog\/archives\/1715","og_site_name":"mnihyc&#039;s Blog","article_published_time":"2022-04-17T15:11:42+00:00","article_modified_time":"2022-04-29T08:38:44+00:00","og_image":[{"url":"https:\/\/mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-gadget_jmp.png","type":"","width":"","height":""}],"author":"mnihyc","twitter_card":"summary_large_image","twitter_creator":"@mnihyc","twitter_site":"@mnihyc","twitter_misc":{"\u4f5c\u8005":"mnihyc","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"10 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mnihyc.com\/blog\/archives\/1715#article","isPartOf":{"@id":"https:\/\/mnihyc.com\/blog\/archives\/1715"},"author":{"name":"mnihyc","@id":"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751"},"headline":"Win32 \u4e0b Hook \u51fd\u6570\u7684\u51e0\u79cd\u65b9\u6cd5","datePublished":"2022-04-17T15:11:42+00:00","dateModified":"2022-04-29T08:38:44+00:00","mainEntityOfPage":{"@id":"https:\/\/mnihyc.com\/blog\/archives\/1715"},"wordCount":137,"commentCount":0,"publisher":{"@id":"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751"},"image":{"@id":"https:\/\/mnihyc.com\/blog\/archives\/1715#primaryimage"},"thumbnailUrl":"https:\/\/mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-gadget_jmp.png","articleSection":["\u5176\u5b83","\u5de5\u5177"],"inLanguage":"zh-Hans","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/mnihyc.com\/blog\/archives\/1715#respond"]}]},{"@type":"WebPage","@id":"https:\/\/mnihyc.com\/blog\/archives\/1715","url":"https:\/\/mnihyc.com\/blog\/archives\/1715","name":"Win32 \u4e0b Hook \u51fd\u6570\u7684\u51e0\u79cd\u65b9\u6cd5 - mnihyc&#039;s Blog","isPartOf":{"@id":"https:\/\/mnihyc.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/mnihyc.com\/blog\/archives\/1715#primaryimage"},"image":{"@id":"https:\/\/mnihyc.com\/blog\/archives\/1715#primaryimage"},"thumbnailUrl":"https:\/\/mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-gadget_jmp.png","datePublished":"2022-04-17T15:11:42+00:00","dateModified":"2022-04-29T08:38:44+00:00","description":"\u9047\u5230\u4e86\u9700\u8981 Hook \u4e00\u4e9b\u51fd\u6570\u7684\u60c5\u51b5\uff0cWinAPI \u7684 __stdcall \u6216\u662f IDA \u5206\u6790\u51fa\u6765\u7684 __usercall\uff0c\u7559\u6b64\u7eaa\u5f55\u3002\u6d4b\u8bd5\u73af\u5883\u4e3a Win32\uff0c\u7f16\u8bd1\u5668\u4e3a MSVC\u3002 &nbsp; &nbsp; \u76ee\u5f55 \u666e\u901a JMP\uff08\u4e0d\u63a8\u8350\uff09 \u5e26 Gadget \u7684 JMP \u66ff\u6362 IAT\uff08\u4ec5\u9002\u7528 PE\uff09","breadcrumb":{"@id":"https:\/\/mnihyc.com\/blog\/archives\/1715#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/mnihyc.com\/blog\/archives\/1715"]}]},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/mnihyc.com\/blog\/archives\/1715#primaryimage","url":"https:\/\/mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-gadget_jmp.png","contentUrl":"https:\/\/mnihyc.com\/blog\/wp-content\/uploads\/2022\/04\/1715-gadget_jmp.png"},{"@type":"BreadcrumbList","@id":"https:\/\/mnihyc.com\/blog\/archives\/1715#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/mnihyc.com\/blog"},{"@type":"ListItem","position":2,"name":"Win32 \u4e0b Hook \u51fd\u6570\u7684\u51e0\u79cd\u65b9\u6cd5"}]},{"@type":"WebSite","@id":"https:\/\/mnihyc.com\/blog\/#website","url":"https:\/\/mnihyc.com\/blog\/","name":"mnihyc&#039;s Blog","description":"Welcome!","publisher":{"@id":"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/mnihyc.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"zh-Hans"},{"@type":["Person","Organization"],"@id":"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/61e167d6d591fdd20dcfee2cf848a751","name":"mnihyc","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8d111f863afc3f98816bc96220f97077d470a96f41088de9f19530fc480f8e72?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8d111f863afc3f98816bc96220f97077d470a96f41088de9f19530fc480f8e72?s=96&d=mm&r=g","caption":"mnihyc"},"logo":{"@id":"https:\/\/mnihyc.com\/blog\/#\/schema\/person\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/0self.mnihyc.com\/blog\/wp-json\/wp\/v2\/posts\/1715","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/0self.mnihyc.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/0self.mnihyc.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/0self.mnihyc.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/0self.mnihyc.com\/blog\/wp-json\/wp\/v2\/comments?post=1715"}],"version-history":[{"count":14,"href":"https:\/\/0self.mnihyc.com\/blog\/wp-json\/wp\/v2\/posts\/1715\/revisions"}],"predecessor-version":[{"id":1738,"href":"https:\/\/0self.mnihyc.com\/blog\/wp-json\/wp\/v2\/posts\/1715\/revisions\/1738"}],"wp:attachment":[{"href":"https:\/\/0self.mnihyc.com\/blog\/wp-json\/wp\/v2\/media?parent=1715"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/0self.mnihyc.com\/blog\/wp-json\/wp\/v2\/categories?post=1715"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/0self.mnihyc.com\/blog\/wp-json\/wp\/v2\/tags?post=1715"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}