¦Ì¨²22?? 2?¨¨?DLLo¨ª1¨°?¨®API
?¨²Microsoft Wi n d o w s?D¡ê???????3¨¬??¨®D?¨¹¡Á??o¦Ì???¨®D¦Ì??¡¤?????¡ê¦Ì¡À¨º1¨®?????¨¤¡ä¨°y¨®??¨²¡ä?¨º¡À¡ê?????¦Ì??¦Ì??¨°y¨®???¡Á??o??3¨¬¦Ì?¦Ì??¡¤?????D¦Ì?¨°????¨²¡ä?¦Ì??¡¤?¡ê??¦Ì???3¨¬2??¨¹¡ä¡ä?¡§¨°?????¨°y¨®?¨º?¨®¨²¨¢¨ª¨°?????3¨¬¦Ì??¨²¡ä??????¡ê¨°¨°¡ä?¡ê?¨¨?1???¦Ì???3¨¬¡ä??¨²¨°???¡ä¨ª?¨®¡ê???D¡ä¨¢?¨°??????¨²¦Ì??¡¤¨¦?¦Ì??¨²¡ä?¡ê????¡ä?a??¡ä¨ª?¨®2??¨¢¨®¡ã?¨¬¨¢¨ª¨°?????3¨¬¨º1¨®?¦Ì??¨²¡ä??¡ê?¨²Windows 98????DD¦Ì??¡Â????3¨¬12?¨ª2 GB¦Ì?¦Ì??¡¤????¡ê???¦Ì??¡¤????¡ä¨®0 x 8 0 0 0 0 0 0 0?¨¢0 x F F F F F F F F?¡ê??¨®D?¨²¡ä?¨®3?????to¨ª?¦Ì¨ª3¡Á¨¦?t2??¨¹¨®3¨¦?¦Ì??a????¨®¨°?¡ê?¨º???¦Ì?¡Â2???¦Ì¨²1 3?¡é1 4??o¨ª¦Ì¨²1 7??¦Ì??¨²¨¨Y?¡ê
?¨¤¨¢¡é¦Ì?¦Ì??¡¤??????¨®¨²¡À¨¤3¨¬¨¨??¡Ào¨ª¨®??¡ì¨¤¡ä?¦Ì??¨º?¡¤?3¡ê¨®D¨¤?¦Ì??¡ê??¨®¨²¡À¨¤3¨¬¨¨??¡À¨¤¡ä?¦Ì¡ê??¦Ì¨ª3?¨¹¨¨Y¨°¡Á2?????¨°a¦Ì??¨²¡ä??¨¢¨¨?o¨ªD¡ä¨¨?2¨´¡Á¡Â?¡ê??¨®¨²¨®??¡ì¨¤¡ä?¦Ì¡ê?2¨´¡Á¡Â?¦Ì¨ª3??¡À?¦Ì??¨¹?¨®??¡Á3¡ê?¨°¨°?a¨°???¨®|¨®?3¨¬D¨°?T¡¤¡§???¦Ì¨¢¨ª¨°?????3¨¬?¨°2¨´¡Á¡Â?¦Ì¨ª3¦Ì???DD?¡ê¦Ì¡À¨¨?¡ê?2¨´¡Á¡Â?¦Ì¨ª3¦Ì??a????¡Á3¨¬?D?¨º?¨°a??3?¡ä¨²??¦Ì?¡ê?¨°¨°?a¨°a¡À¨¤D¡ä?¨¹1?¨®???????3¨¬??DD¨ª¡§D?¡ê??¨°???¨¹1?????????3¨¬??DD2¨´¡Á¡Â¦Ì?¨®|¨®?3¨¬D¨°??¨°a¨¤¡ì??¦Ì??¨¤?¡ê
¨®DD??¨¦????¡ê?¡À?D?¡ä¨°????3¨¬¦Ì????T¡ê?¡¤??¨º¨¢¨ª¨°?????3¨¬¦Ì?¦Ì??¡¤????¡ê??aD??¨¦??¡ã¨¹¨¤¡§¡êo
• ¦Ì¡À????¨°a?a¨¢¨ª¨°?????3¨¬¡ä¡ä?¡§¦Ì?¡ä¡ã?¨²?¡§¨¢¡é¡Á¨®¨¤¨¤¨º¡À?¡ê
• ¦Ì¡À??D¨¨¨°a¦Ì¡Â¨º?¡ã??¨²¨º¡À¡ê¡§¨¤y¨¨?¡ê?¦Ì¡À??D¨¨¨°a¨¨¡¤?¡§¨¢¨ª¨°?????3¨¬?y?¨²¨º1¨®?????D L L¨º¡À¡ê??¡ê
• ¦Ì¡À????¨°a1¨°?¨®??????3¨¬¨º¡À?¡ê
¡À??????¨¦¨¦¨¹¨¨??¨¦??¡¤?¡¤¡§¡ê??¨¦¨°?¨®?¨¤¡ä??D L L2?¨¨?¦Ì?¨¢¨ª¨°?????3¨¬¦Ì?¦Ì??¡¤?????D?¡ê¨°?¦Ì???¦Ì?D L L??¨¨?¨¢¨ª¨°?????3¨¬¦Ì?¦Ì??¡¤????¡ê??¨ª?¨¦¨°???¨¢¨ª¨°?????3¨¬?a?¨´¨®??a?¡ê?a¨°??¡§?¨¢¨º1??¡¤?3¡êo|??¡ê?¨°¨°¡ä?¡ê????1¨®|?????¨´¡Á?¡ê?¨°a¨¨y????o¨®DD?¡ê
?¨´¨¦¨¨?????a¨®¨¦¨¢¨ª¨°?????3¨¬¡ä¡ä?¡§¦Ì?¡ä¡ã?¨²?¡§¨¢¡é¨°???¡Á¨®¨¤¨¤?¡ê???¨¦?¨¹??¦Ì?¡ê??¡§¨¢¡é¡Á¨®¨¤¨¤?¨ª?¨¹1???¡À?¡ä¡ã?¨²¦Ì?DD?a¨¬?D??¡ê¨¨?¨°a?¡§¨¢¡é¡Á¨®¨¤¨¤¡ê???D¨¨¨°a¦Ì¡Â¨®?S e t Wi n d o w L o n g P t ro¡¥¨ºy¡ê???¡À?¡ä¡ã?¨²¦Ì??¨²¡ä??¨¦?D¦Ì?¡ä¡ã?¨²1y3¨¬¦Ì??¡¤¡ê????¨°¨°???D?¦Ì?¡ê¡§??¡Á??o¦Ì?¡ê? W n d P r o c?¡êPlatform SDK??¦Ì¦Ì?¦Ì¡ê?¨®|¨®?3¨¬D¨°2??¨¹?a¨¢¨ª¨°?????3¨¬¡ä¡ä?¡§¦Ì?¡ä¡ã?¨²?¡§¨¢¡é¡Á¨®¨¤¨¤?¡ê?a2¡é2?¨ª¨º¨¨??y¨¨¡¤?¡ê?a¨¢¨ª¨°?????3¨¬¦Ì?¡ä¡ã?¨²?¡§¨¢¡é¡Á¨®¨¤¨¤¦Ì?1??¨¹?¨º¨¬a¨®???3¨¬¦Ì??¡¤????¦Ì?¡À???¨®D1??¡ê
¦Ì¡À¦Ì¡Â¨®??????¨´¨º?¦Ì?S e t Wi n d o w s L o n g P t ro¡¥¨ºy¡ê??¡§¨¢¡é¨°???¡ä¡ã?¨²¦Ì?¡Á¨®¨¤¨¤¨º¡À¡ê????????¦Ì¨ª3¡ê?¡¤¡é?¨ª¦Ì??¨°????¨º??¨²h w n d¨¦¨¨?¡§¦Ì?¡ä¡ã?¨²?D¦Ì??¨´¨®D???¡é??¨®|???¨ª¨ª¨´M y S u b c l a s s P r o c¡ê???2?¨º??¨ª¨ª¨´¡ä¡ã?¨²¦Ì??y3¡ê¡ä¡ã?¨²1y3¨¬¡êo
SetWindowLongPtr(hwnd, GWLP_WNDPROC, MySubclassProc);
?a¨¢¨ª¨°?????3¨¬¡ä¡ä?¡§¦Ì?¡ä¡ã?¨²?¡§¨¢¡é¡Á¨®¨¤¨¤¨º¡À¨®?¦Ì?¦Ì??¨º¨¬a¨º?¡ê??¡§¨¢¡é¡Á¨®¨¤¨¤¦Ì?1y3¨¬??¨®¨²¨¢¨ª¨°???¦Ì??¡¤?????D?¡ê¨ª?2 2 - 1??¨º?¨¢?¨°????¨°?¡¥¨¢?¦Ì?¨ª?D?¡ê??¦Ì?¡Â¡ä¡ã?¨²1y3¨¬¨º?¨¨?o??¨®¨º¨¹???¡é¦Ì??¡ê??3¨¬A?y?¨²??DD¡ê?2¡é?¨°¨°??-¡ä¡ä?¡§¨¢?¨°???¡ä¡ã?¨²?¡ê???tU s e r 3 2 . d l l¡À?¨®3¨¦?¦Ì???3¨¬A¦Ì?¦Ì??¡¤?????D?¡ê??U s e r 3 2 . d l l???t¦Ì?¨®3¨¦?¨º??a¨¢??¨®¨º?o¨ª¡¤¡é?¨ª?¨²??3¨¬A?D??DD¦Ì?¨¨?o???3¨¬¡ä¡ä?¡§¦Ì?¨¨?o?¡ä¡ã?¨²?D¡¤¡é?¨ªo¨ª??¨º?¦Ì????¡é?¡ê¦Ì¡ÀU s e r 3 2 . d l l¦Ì?¨®3??¡¤¡é??¨°??????¡é¨º¡À¡ê??¨¹¨º¡Á?¨¨¨°a¨¨¡¤?¡§¡ä¡ã?¨²¦Ì?W n d P r o c¦Ì?¦Ì??¡¤¡ê?¨¨?o¨®¦Ì¡Â¨®???¦Ì??¡¤¡ê?¡ä?¦ÌY¡ä¡ã?¨²¦Ì???¡À¨²?¡é???¡éo¨ªw P a r a mo¨ªl P a r a m?¦Ì?¡ê¦Ì¡ÀW n d P r o c¡ä|¨¤¨ª?????¡éo¨®¡ê?U s e r 3 2 . d l l¡À??-?¡¤??DD¡ê?2¡é¦Ì¨¨¡äy¨¢¨ª¨°???¡ä¡ã?¨²???¡é¡À?¡ä|¨¤¨ª?¡ê
¨ª?22-1 ??3¨¬B?D¦Ì???3¨¬¨º?¨ª??a??3¨¬A?D¦Ì???3¨¬¡ä¡ä?¡§¦Ì?¡ä¡ã?¨²?¡§¨¢¡é¡Á¨®¨¤¨¤
???¨²?¨´¨¦¨¨??¦Ì???3¨¬¨º???3¨¬B¡ê??????a??3¨¬A?D¦Ì???3¨¬¡ä¡ä?¡§¦Ì?¡ä¡ã?¨²?¡§¨¢¡é¡Á¨®¨¤¨¤?¡ê???¨²??3¨¬B?D¦Ì?¡ä¨²??¡À?D?¨º¡Á?¨¨¨¨¡¤?¡§????¨°a?¡§¨¢¡é¡Á¨®¨¤¨¤¦Ì?¡ä¡ã?¨²¦Ì???¡À¨²?¡ê?a??2¨´¡Á¡Â¨º1¨®?¦Ì?¡¤?¡¤¡§o¨¹?¨¤?¡ê¨ª?2 2 - 1??¨º?¦Ì?¨¤y¡Á¨®??¨º?¦Ì¡Â¨®?F i n d Wi n d o wo¡¥¨ºy¨¤¡ä??¦Ì?D¨¨¨°a¦Ì?¡ä¡ã?¨²?¡ê?¨®¡Á?¡ê???3¨¬B?D¦Ì???3¨¬¦Ì¡Â¨®?S e t Wi n d o w L o n g P t ro¡¥¨ºy¡ê?¨º?¨ª???¡À?¡ä¡ã?¨²¦Ì?W n d P r o c¦Ì?¦Ì??¡¤?¡ê??¡Á¡é¨°a?¨°?¦Ì¦Ì??¡ã¨º?¨ª??¡À?t¡Á??¡ê?a??o¡¥¨ºy¦Ì¡Â¨®?2¡é2???DD¨º2?¡ä2¨´¡Á¡Â¡ê??¨¹??¨º?¡¤¦Ì??N U L L?¡êS e t Wi n d o w L o n g P t ro¡¥¨ºy?D¦Ì?¡ä¨²??¨°a2¨¦?¡ä¨º?¡¤?¨®D¨°?????3¨¬?y?¨²¨º?¨ª???¡À?¨¢¨ª¨°?????3¨¬¡ä¡ä?¡§¦Ì?¡ä¡ã?¨²¦Ì?W n d P r o c¦Ì??¡¤¡ê?¨¨?o¨®??o????a??o¡¥¨ºy¦Ì?¦Ì¡Â¨®??¡ê
¨¨?1?S e t Wi n d o w L o n g P t ro¡¥¨ºy?¨¹1???¡À?¡ä¡ã?¨²¦Ì?W n d P r o c¡ê?????3???¨º2?¡ä?¨¦????¡ê??¦Ì¨ª3??¡ã?M y S u b c l a s s P r o c¦Ì?¦Ì??¡¤¨®?¨¬??¡§¦Ì?¡ä¡ã?¨²1?¨¢a?e¨¤¡ä?¡ê¨¨?o¨®¡ê?¦Ì¡À¨®D¨°?¨¬????¡é¡À?¡¤¡é?¨ª¦Ì??a??¡ä¡ã?¨²?D¨º¡À¡ê???3¨¬A?D¦Ì?U s e r 3 2¡ä¨²?????¨¬?¡Â?????¡é¡ê???¦Ì?M y S u b c l a s s P r o c¦Ì?¦Ì??¡¤¡ê?2¡é¨º?¨ª?¦Ì¡Â¨®??a??¦Ì??¡¤?¡ê¦Ì?¨º?¡ê??a¨º¡À?¨¦?¨¹¨®?¦Ì?¨°???¡ä¨®?¨º¨¬a?¡êM y S u b c l a s s P r o c????¨®¨²??3¨¬B¦Ì?¦Ì??¡¤?????D¡ê?????3¨¬A¨¨¡ä¨º??????¡¥??3¨¬?¡ê??¨¨?¡ê?¨¨?1?U s e r 3 2??¨°a¦Ì¡Â¨®???¦Ì??¡¤¡ê??¨¹?¨ª¨°a¦Ì¡Â¨®???3¨¬A¦Ì?¦Ì??¡¤?????D¦Ì?¨°???¦Ì??¡¤¡ê??a?¨ª?¨¦?¨¹?¨¬3¨¦?¨²¡ä?¡¤??¨º¦Ì??£¤1??¡ê
?a¨¢?¡À¨¹?a?a???¨º¨¬a¦Ì?2¨²¨¦¨²¡ê?¨®|??¨¨??¦Ì¨ª3?a¦Ì¨¤M y S u b c l a s s P r o c¨º??¨²??3¨¬B¦Ì?¦Ì??¡¤?????D¡ê?¨¨?o¨®¡ê??¨²¦Ì¡Â¨®?¡Á¨®¨¤¨¤¦Ì?1y3¨¬???¡ã¡ê?¨¨??¦Ì¨ª3?¡äDD¨°?¡ä?¨¦?????¡Áa???¡êM i c r o s o f t??¨®D¨º¦Ì???a???¡§?¨²o¡¥¨ºy1|?¨¹¡ê??-¨°¨°¨º?¡êo
• ¨®|¨®?3¨¬D¨°o¨¹¨¦¨´D¨¨¨°a?a??????3¨¬¦Ì???3¨¬¡ä¡ä?¡§¦Ì?¡ä¡ã?¨²?¡§¨¢¡é¡Á¨®¨¤¨¤?¡ê¡ä¨®?¨¤¨ºy¨®|¨®?3¨¬D¨°??¨º??a?¨¹??¡Á??o¡ä¡ä?¡§¦Ì?¡ä¡ã?¨²?¡§¨¢¡é¡Á¨®¨¤¨¤¡ê?Wi n d o w s¦Ì??¨²¡ä??¨¢112¡é2?¡Á¨¨?1?a??¡ä¡ä?¡§2¨´¡Á¡Â?¡ê
• ?D?????¡¥??3¨¬D¨¨¨°a??¨®?D¨ª?¨¤C P U¨º¡À???¡ê
• ??3¨¬B?D¦Ì???3¨¬¡À?D??¡äDDM y S u b c l a s s P r o c?D¦Ì?¡ä¨²???¡ê?¦Ì¨ª3???1¨®|??¨º1¨®???????3¨¬??¡ê?¨º???¨®D¦Ì???3¨¬¡ê??1¨º?D???3¨¬??¡ê?
• U s e r 3 2 . d l l???¨´2??¨¹?¦Ì?¡Â¨®?¡ä¡ã?¨²?¨¤1?¦Ì?¦Ì??¡¤¨º?¨®?¨®¨²¨¢¨ª¨°?????3¨¬?D¦Ì?1y3¨¬¡ê??1¨º?¨®?¨®¨²¨ª?¨°?????3¨¬?D¦Ì?1y3¨¬??¡ê?
¨®¨¦¨®¨²???a???¨º¨¬a¦Ì??a??2¡é??¨®D¨º2?¡ä¨ª¨°¨¨???2?¡ê?¨°¨°¡ä?M i c r o s o f t???¡§2?¨¨?S e t Wi n d o w s L o n g P t r??¡À?¨¢¨ª¨°?????3¨¬¡ä¡ä?¡§¦Ì?¡ä¡ã?¨²1y3¨¬?¡ê
2?1y¨¨?¨¨??¨¦¨°??a¨¢¨ª¨°?????3¨¬¡ä¡ä?¡§¦Ì?¡ä¡ã?¨²?¡§¨¢¡é¡Á¨®¨¤¨¤?a??D¨¨¨°a¨®?¨¢¨ª¨°???¡¤?¡¤¡§¨¤¡ä??DD?a??2¨´¡Á¡Â?¡ê?a2¡é2?¨º??¡§¨¢¡é¡Á¨®¨¤¨¤¦Ì??¨º¨¬a¡ê???¨º???3¨¬¦Ì?¦Ì??¡¤????¡À???¦Ì??¨º¨¬a?¡ê¨¨?1??¨¹????¦Ì?¡Á¨®¨¤¨¤1y3¨¬¦Ì?¡ä¨²??¡¤?¨¨???3¨¬A¦Ì?¦Ì??¡¤????¡ê??¨ª?¨¦¨°?¡¤?¡À?¦Ì?¦Ì¡Â¨®?S e t Wi n d o w L o n g P t ro¡¥¨ºy¡ê?????3¨¬A¦Ì?¦Ì??¡¤¡ä?¦ÌY??M y S u b c l a s s P r o co¡¥¨ºy?¡ê?¨°???a??¡¤?¡¤¡§3??a??D L L?¡ã2?¨¨??¡À??3¨¬¦Ì?¦Ì??¡¤?????¡ê¨®D¨¨??¨¦??¡¤?¡¤¡§?¨¦¨°?¨®?¨¤¡ä??DD?a??2¨´¡Á¡Â?¡ê???????e???¨¦¨¦¨¹?¨¹???¡ê
22.2 ¨º1¨®?¡Á¡é2¨¢¡À¨ª¨¤¡ä2?¨¨?DLL
¨¨?1??????-?¨¤¨¦¨´¨º1¨®?1yWi n d o w s2¨´¡Á¡Â?¦Ì¨ª3¡ê??????¡§¨º¨¬?¡è¡Á¡é2¨¢¡À¨ª¦Ì??¨¦???¡ê?????¦Ì¨ª3¦Ì???????¨º??¨²¡Á¡é2¨¢¡À¨ª?D???¡è¦Ì?¡ê??¨¦¨°?¨ª¡§1y¦Ì¡Â???¨¹¦Ì?¨¦¨¨??¨¤¡ä??¡À??¦Ì¨ª3¦Ì?DD?a¨¬?D??¡ê??¨°a?¨¦¨¦¨¹¦Ì?????¨º??¨²????¦Ì?1??¨¹¡Á??D¡êo
HKEY_LOCAL_MACHINE\Software\Microsoft \Windows NT\CurrentVersion\Windows\AppInit_DLLs
¨ª?2 2 - 2??¨º?¨¢?¨º1¨®?Registry Editor¡ê¡§¡Á¡é2¨¢¡À¨ª¡À¨¤?-?¡Â¡ê?¨º¡À??1??¨¹¡Á??D¦Ì??¡Â??????¦Ì?D?¨º??¡ê??1??¨¹¡Á?¦Ì??¦Ì¡ã¨¹o?¨°???D L L???t???¨°??¨°?¡Á¨¦D L L???t??¡ê¡§¨®??????¨°?oo????a¡ê??¡ê¨®¨¦¨®¨²????¨®?¨¤¡ä?????t?????a¡ê?¨°¨°¡ä?¡À?D?¡À¨¹?a¨º1¨®?¡ã¨¹o?????¦Ì????t???¡ê¨¢D3?¦Ì?¦Ì¨²¨°???D L L???t???¨¦¨°?¡ã¨¹o?¨°????¡¤??¡ê?¦Ì?¨º?¡ã¨¹o??¡¤??¦Ì?????D L L?¨´¡À?o????¡ê¨®¨¦¨®¨²?a???-¨°¨°¡ê?¡Á?o?????¦Ì?D L L¡¤?¨¨?Wi n d o w s¦Ì??¦Ì¨ª3?????D¡ê??a?¨´?¨ª2?¡À?¨¦¨¨?¡§?¡¤???¡ê?¨²¡ä¡ã?¨²?D¡ê??¨°?????¦Ì¨¦¨¨???a¦Ì£¤??D L L?¡¤????C : \ M y L i b . d l l?¡ê
¨ª?22-2 ¡Á¡é2¨¢¡À¨ª¡ä¡ã?¨²
¦Ì¡À??D????¡¥?????¨²?¡ãWi n d o w s??DD3?¨º??¡¥¨º¡À¡ê??¦Ì¨ª3??¡À¡ê¡ä??a??1??¨¹¡Á?¦Ì??¦Ì?¡ê¨¨?o¨®¡ê?¦Ì¡ÀU s e r 3 2 . d l l?a¡À?¨®3¨¦?¦Ì???3¨¬?D¨º¡À¡ê??¨¹???¨®¨º?¦Ì?¨°???D L L _ P R O C E S S _ AT TA C H¨ª¡§?a?¡ê¦Ì¡À?a??¨ª¡§?a¡À?¡ä|¨¤¨ª¨º¡À¡ê?U s e r 3 2 . d l l¡À??¨¬?¡Â¡À¡ê¡ä?¦Ì??a??1??¨¹¡Á??D¦Ì??¦Ì¡ê?2¡é?¨°?a¡Á?¡¤?¡ä??D???¡§¦Ì?????D L L¦Ì¡Â¨®?L o a d L i b r a r yo¡¥¨ºy?¡ê¦Ì¡À?????a¡À??¨®??¨º¡À¡ê?¡À?¦Ì¡Â¨®?¨®????a?¨¤1?¦Ì?D l l M a i no¡¥¨ºy¡ê???f d w R e a s o n¦Ì??¦Ì¨º?D L L _ P R O C E S S _ AT TA C H¡ê??a?¨´¡ê??????a?¨ª?¨¹1???¡Á??o??DD3?¨º??¡¥?¡ê¨®¨¦¨®¨²2?¨¨?¦Ì?D L L?¨²??3¨¬¦Ì?¨º¨´?¨¹?¨²?D????¦Ì??¨ª??DD¨¢??¨®??¡ê?¨°¨°¡ä??¨²¦Ì¡Â¨®?o¡¥¨ºy¨º¡À¨®|????¨ªaD?D??¡ê¦Ì¡Â¨®?k e r n e l 3 2 . d l l?D¦Ì?o¡¥¨ºy¨º¡À¨®|??2??¨¢3???¨º2?¡ä?¨º¨¬a¡ê?2?1y¦Ì¡Â¨®?????D L L?D¦Ì?o¡¥¨ºy¨º¡À?¨ª?¨¦?¨¹2¨²¨¦¨²¨°?D??¨º¨¬a?¡êU s e r 3 2 . d l l2¡é2??¨¬2¨¦?????a¨º?¡¤?¨°??-?¨®??3¨¦1|¡ê??¨°??3?¨º??¡¥¨º?¡¤?¨¨?¦Ì?3¨¦1|?¡ê
?¨²2?¨¨?D L L¨º¡À?¨´¨®?¦Ì??¨´¨®D¡¤?¡¤¡§?D¡ê??a¨º?¡Á?¨¨Y¨°¡Á¦Ì?¨°???¡¤?¡¤¡§?¡ê¨°a¡Á?¦Ì?1¡è¡Á¡Â??¨º???¨°????¦Ì¨¬¨ª?¨®¦Ì?¨°???¨°??-¡ä??¨²¦Ì?¡Á¡é2¨¢¡À¨ª1??¨¹¡Á??D?¡ê2?1y?a??¡¤?¡¤¡§¨°2¨®D?¨¹¦Ì??3D?2?¡Á?¡êo
• ¨®¨¦¨®¨²?¦Ì¨ª3?¨²3?¨º??¡¥¨º¡À¨°a?¨¢¨¨??a??1??¨¹¡Á?¦Ì??¦Ì¡ê?¨°¨°¡ä??¨²DT???a???¦Ìo¨®¡À?D???D????¡¥??¦Ì??????¨²?a?¡ä¨º1¨ª?3?o¨®?¨´¦Ì???¡ê?¨°22?DD?¡ê¦Ì¡À¨¨?¡ê?¨¨?1?¡ä¨®?a??1??¨¹¡Á?¦Ì??¦Ì?D¨¦?3yD L L¡ê????¡ä?¨²?????¨²??D????¡¥???¡ã¡ê??¦Ì¨ª32??¨¢¨ª¡ê?1???a¦Ì?¨®3¨¦?2¨´¡Á¡Â?¡ê
• ??¦Ì?D L L???¨¢¨®3¨¦?¦Ì?¨º1¨®?U s e r 3 2 . d l l¦Ì???3¨¬?D?¡ê?¨´¨®D?¨´¨®¨²G U I¦Ì?¨®|¨®?3¨¬D¨°?¨´¨º1¨®?U s e r 3 2 . d l l¡ê?2?1y¡ä¨®?¨¤¨ºy?¨´¨®¨²C U I¦Ì?¨®|¨®?3¨¬D¨°2¡é2?¨º1¨®??¨¹?¡ê¨°¨°¡ä?¡ê?¨¨?1?D¨¨¨°a??D L L2?¨¨?¡À¨¤¨°??¡Â?¨°¨¢¡ä?¨®3¨¬D¨°¡ê??a??¡¤?¡¤¡§??2??e¡Á¡Â¨®??¡ê
• ??¦Ì?D L L??¡À?¨®3¨¦?¦Ì??????¨´¨®¨²G U I¦Ì?¨®|¨®?3¨¬D¨°?D¡ê?¦Ì?¨º?¡À?D?????¦Ì??a2?¨¨?¨°????¨°??????3¨¬?D?¡ê??¦Ì?D L L¨®3¨¦?¦Ì?¦Ì???3¨¬???¨¤¡ê??¡ã¨¨Y?¡Â?¡À??3¨¬¡À¨¤¨¤¡ê¦Ì??¨¦?¨¹D??¨ª??¡ä¨®?¡ê¡À??1?¨²?aD???3¨¬?D??DD¦Ì???3¨¬¨º??¨²?¡äDD??¦Ì?¡ä¨²???¡ê¨¨?1???¦Ì?¡ä¨²????¨¨?¨°????T?T?-?¡¤¡ê??¨°??¡¤??¨º¦Ì??¨²¡ä?2??y¨¨¡¤¡ê??¨ª?¨¢¨®¡ã?¨¬¡ä¨²????DD¨º¡À?¨´?¨²??3¨¬¦Ì?DD?a¨¬?D?o¨ª??¡Á3D??¡ê¨°¨°¡ä?¡ê?¡Á?o?????¦Ì??a2?¨¨????¨¦?¨¹¨¦¨´¦Ì???3¨¬?D?¡ê
• ??¦Ì?D L L??¡À?¨®3¨¦?¦Ì??????¨´¨®¨²G U I¦Ì?¨®|¨®?3¨¬D¨°?D?¡ê?a¨®?¨¦???¦Ì??¨º¨¬a?¨¤¨¤¨¤???¡ê?¨²¨¤¨ª??¦Ì??¨¦????¡ê???¦Ì?D L L??¨®|??¨®3¨¦?¦Ì?D¨¨¨°a¦Ì???3¨¬?D¡ê?¨ª?¨º¡À¡ê??¨¹¨®|??¨°????¨¦?¨¹¨¦¨´¦Ì?¨º¡À??¨®3¨¦?¦Ì??aD???3¨¬?D?¡ê?¨´¨¦¨¨?¨²¨®??¡ì¦Ì¡Â¨®???¦Ì?¨®|¨®?3¨¬D¨°¨º¡À????¨°a?¡§¨¢¡éWo r d P a d¦Ì??¡Â¡ä¡ã?¨²¦Ì?¡Á¨®¨¤¨¤?¡ê?¨²¨®??¡ì¦Ì¡Â¨®???¦Ì?¨®|¨®?3¨¬D¨°???¡ã¡ê???¦Ì?D L L2?¡À?¨®3¨¦?¦Ì?Wo r d P a d¦Ì?¦Ì??¡¤?????D?¡ê¨¨?1?¨®??¡ìo¨®¨¤¡ä???¡§???1??¦Ì?¨®|¨®?3¨¬D¨°¦Ì???DD¡ê????¡ä??¡À?D?3¡¤??Wo r d P a d¦Ì??¡Â¡ä¡ã?¨²?¡ê?¨²?a???¨¦????¡ê???¦Ì?D L L??2??¨´D¨¨¨°a¡À?2?¨¨?Wo r d P a d¦Ì?¦Ì??¡¤?????¡ê¡Á?o?¨º????¨²¡À?¨°a¨º¡À¡À¡ê3?D L L¦Ì?2?¨¨?¡Á¡ä¨¬??¡ê
22.3 ¨º1¨®?Windows1¨°13¨¤¡ä2?¨¨?DLL
?¨¦¨°?¨º1¨®?1¨°13??D L L2?¨¨???3¨¬¦Ì?¦Ì??¡¤?????¡ê?a¨¢?¨º11¨°13?¨¹1????¨¹???¨²1 6??Wi n d o w s?D???¨´1¡è¡Á¡Â¡ê?M i c r o s o f t2?¦Ì?2?¨¦¨¨??¨¢?¨°???¡¤?¡¤¡§¡ê?¨º1¦Ì?D L L?¨¹1?2?¨¨?¨¢¨ª¨°?????3¨¬¦Ì?¦Ì??¡¤?????D?¡ê
????¨¨??¨°??¨¤¡ä?¡ä¨°???¨¤y¡Á¨®?¡ê??3¨¬A¡ê¡§¨¤¨¤??Microsoft Spy++¦Ì?¨°???¨º¦Ì¨®?3¨¬D¨°¡ê?¡ã2¡Á¡ã¨¢?¨°???1¨°13W N _ G E T M E S S A G E¡ê?¨°?¡À?2¨¦?¡ä?¦Ì¨ª3?D¦Ì??¡Â??¡ä¡ã?¨²¡ä|¨¤¨ª¦Ì????¡é?¡ê??1¨°13¨º?¨ª¡§1y¦Ì¡Â¨®?????¦Ì?S e t Wi n d o w s H o o k E xo¡¥¨ºy¨¤¡ä¡ã2¡Á¡ã¦Ì?¡êo
HHOOK hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, hinstDll, 0);
???¨²¨¨??¨°??¨¤¡ä?¡ä¨°??¡ä???¨¢¡¤¡é¨¦¨²¨º2?¡ä?¨¦??¡êo
1) ??3¨¬B?D¦Ì?¨°?????3¨¬¡Á?¡À???¨°?¨¬????¡é¡¤¡é?¨ª¦Ì?¨°???¡ä¡ã?¨²?¡ê
2) ?¦Ì¨ª32¨¦?¡ä????3¨¬¨¦?¨º?¡¤?¨°??-¡ã2¡Á¡ã¨¢?W H _ G E T M E S S A G E1¨°13?¡ê
3) ?¦Ì¨ª32¨¦?¡ä¡ã¨¹o?G e t M s g P r o co¡¥¨ºy¦Ì?D L L¨º?¡¤?¡À?¨®3¨¦?¦Ì???3¨¬B¦Ì?¦Ì??¡¤?????D?¡ê
4) ¨¨?1???D L L¨¦D?¡ä¡À?¨®3¨¦?¡ê??¦Ì¨ª3????????D L L¨®3¨¦?¦Ì???3¨¬B¦Ì?¦Ì??¡¤????¡ê?2¡é?¨°????3¨¬B?D¦Ì?D L L¨®3??¦Ì?¡Á??¡¥?¨²¡Á¨´??¨ºy¦ÌY??1?¡ê
5) ¦Ì¡ÀD L L¦Ì?h i n s t D l l¨®?¨®¨²??3¨¬B¨º¡À¡ê??¦Ì¨ª32¨¦?¡ä??o¡¥¨ºy¡ê?2¡é?¨¬2¨¦??D L L¦Ì?h i n s t D l l¨º?¡¤?¨®??¨¹¨®?¨®¨²??3¨¬A¨º¡À?¨´¡ä|¦Ì??????¨¤¨ª??¡ê
¨¨?1?¨¢???h i n s t D l l¨º??¨²?¨¤¨ª?¦Ì?????¨¦?¡ê????¡äG e t M s g P r o co¡¥¨ºy¦Ì??¨²¡ä?¦Ì??¡¤?¨²¨¢?????3¨¬¦Ì?¦Ì??¡¤?????D¦Ì?????¨°2¨º??¨¤¨ª?¦Ì??¡ê?¨²?a???¨¦????¡ê??¦Ì¨ª3??D¨¨¨°a¦Ì¡Â¨®???3¨¬A¦Ì?¦Ì??¡¤?????D¦Ì?G e t M s g P r o co¡¥¨ºy?¡ä?¨¦?¡ê
¨¨?1?h i n s t D l l¦Ì?????2?¨ª?¡ê????¡ä?¦Ì¨ª3¡À?D?¨¨¡¤?¡§??3¨¬B¦Ì?¦Ì??¡¤?????DG e t M s g P r o co¡¥¨ºy¦Ì?D¨¦?a?¨²¡ä?¦Ì??¡¤?¡ê?a??¦Ì??¡¤?¨¦¨°?¨º1¨®?????¦Ì?1?¨º?¨¤¡ä¨¨¡¤?¡§¡êo
GetMsgProc B = hinstDll B + (GetMsgProc A - hinstDll A)
6) ?¦Ì¨ª3????3¨¬B?D¦Ì?D L L¨®3??¦Ì?¡Á??¡¥?¨²¡Á¨´??¨ºy¦ÌY??1?¡ê
7) ?¦Ì¨ª3¦Ì¡Â¨®???3¨¬B¦Ì?¦Ì??¡¤?????D¦Ì?G e t M s g P r o co¡¥¨ºy?¡ê
8) ¦Ì¡ÀG e t M s g P r o co¡¥¨ºy¡¤¦Ì??¨º¡À¡ê??¦Ì¨ª3????3¨¬B?D¦Ì?D L L¨®3??¦Ì?¡Á??¡¥?¨²¡Á¨´??¨ºy¦ÌY??1?¡ê
¡Á¡é¨°a¡ê?¦Ì¡À?¦Ì¨ª32?¨¨??¨°??¨®3¨¦?¡ã¨¹o?1¨°131y???¡Âo¡¥¨ºy¦Ì?D L L¨º¡À¡ê?????D L L?¨´¡À?¨®3¨¦?¡ê???2???¨º?1¨°131y???¡Âo¡¥¨ºy¡À?¨®3¨¦??¡ê?a¨°a??¡Á?D L L?D¡ã¨¹o?¦Ì?¨¨?o?¨°???o¡¥¨ºy?¨°?¨´¨®Do¡¥¨ºy???¨²??¡ä??¨²¡ê?2¡é?¨°?¨¦¨°?¡ä¨®??3¨¬B¦Ì??¡¤?3????DD¦Ì???3¨¬?D¦Ì¡Â¨®??¡ê
¨¨?¨°a?a¨¢¨ª¨°?????3¨¬?D¦Ì???3¨¬¡ä¡ä?¡§¦Ì?¡ä¡ã?¨²?¡§¨¢¡é¡Á¨®¨¤¨¤¡ê?¨º¡Á?¨¨?¨¦¨°??¨²¡ä¡ä?¡§??¡ä¡ã?¨²¦Ì?1¨°13¨¦?¨¦¨¨??¨°???W H _ G E T M E S S A G E1¨°13¡ê?¨¨?o¨®¡ê?¦Ì¡ÀG e t M s g P r o co¡¥¨ºy¡À?¦Ì¡Â¨®?¨º¡À¡ê?¦Ì¡Â¨®?S e t Wi n d o w L o n g P t ro¡¥¨ºy¨¤¡ä?¡§¨¢¡é¡ä¡ã?¨²¦Ì?¡Á¨®¨¤¨¤?¡ê¦Ì¡À¨¨?¡ê?¡Á¨®¨¤¨¤¦Ì?1y3¨¬¡À?D?¨®?G e t M s g P r o co¡¥¨ºy??¨®¨²¨ª?¨°???D L L?D?¡ê
¨®?2?¨¨?D L L¦Ì?¡Á¡é2¨¢¡À¨ª¡¤?¡¤¡§2?¨ª?¡ê??a??¡¤?¡¤¡§?¨ºD¨ª???¨²¨¢¨ª¨°?????3¨¬¦Ì?¦Ì??¡¤?????D2??¨´D¨¨¨°aD L L¨º¡À¨¦?3y??D L L¦Ì?¨®3??¡ê?¡¤?¡¤¡§¨º?¦Ì¡Â¨®?????¦Ì?o¡¥¨ºy¡êo
BOOL UnhookWindowsHookEx(HHOOK hhook);
?a¨°??D¨°a??¡Á?2??¨¹3¡¤????¡ä¡ã?¨²¦Ì?¡Á¨®¨¤¨¤2¡é?¨°¨¢¡é?¡ä3¡¤????1¨°13?¡ê??1¨°13¡À?D??¨²??¡Á¨®¨¤¨¤¦Ì?¨º¨´?¨¹?¨²?¨²¡À¡ê3?¨®DD¡ì¡Á¡ä¨¬??¡ê
¡Á¨¤??????????¡À¡ê¡ä??¡Â¨º¦Ì¨®?3¨¬D¨°
??¦Ì£¤2 2 - 2?D¨¢D3?¦Ì?D I P S . e x e¨®|¨®?3¨¬D¨°¨º1¨®?¡ä¡ã?¨²1¨°13??¨°???D L L2?¨¨?E x p l o r e r. e x e¦Ì?¦Ì??¡¤?????¡ê??¨®|¨®?3¨¬D¨°o¨ªD L L¦Ì??¡ä¡ä¨²??o¨ª¡Á¨º?¡ä???t?¨´??¨®¨²¡À?¨º¨¦?¨´??1a?¨¬¦Ì?2 2 - D I P So¨ª2 2 - D I P S l i b???????¡ê
?¨°?¨´¡À?¨¦????¨°¦Ì??????¨²¨®?¨®¨²¨®?¨¦¨¬??¨®D1?¦Ì?2¨´¡Á¡Â¡ê??¨°¡¤¡é??1152 x 864¦Ì??¨¢??¡¤?¡À??¨º¡Á?¨º¨ºo??¨°?¡ê¦Ì?¨º??¨²?????¨²¨¦?¨ª?¨®??¡¤¨º¡À¡ê?¡ä¨®?¨¤¨ºy¨®??¡¤¨¦¨¨??¨º¡À¨º1¨®?¦Ì?¡¤?¡À??¨º¨º?640 x 480?¡ê¨°¨°¡ä?¡ê?¦Ì¡À?¨°??¨°a¨ª?¨®??¡¤¨º¡À¡ê??¨°¡ä¨°?a??????¡ã?¡ê?¨º1¨®?D i s p l a yD?¨®|¨®?3¨¬D¨°¡ê???¡¤?¡À??¨º???a640 x 480?¡ê2?¨ª?¨®??¡¤¨º¡À¡ê??¨°¨®?¨º1¨®?D i s p l a yD?¨®|¨®?3¨¬D¨°??¡¤?¡À??¨º??D????a1152 x 864 ?¡ê
¨º1¨®??a??¡¤?¡¤¡§?¨²??DD1y3¨¬?D??¡À???¨º??¡Â¦Ì?¡¤?¡À??¨º¨º?¡¤?3¡ê?¨¦¡¤3¦Ì?¡ê?¦Ì?¨º??¨¹¨º?Wi n d o w s¦Ì?¨°???¨º¨¹??¨®-¦Ì?¨¬?D??¡ê2?1y?¨°o???¨¢???¡À???¨º??¡Â¡¤?¡À??¨º¨º¡À¦Ì?¨°????¨º¨¬a¡ê????¨ª¨º?¡Á¨¤??¨ª?¡À¨º?T¡¤¡§??¡Á??¨¹?-¨¤¡ä¦Ì??????¡ê?¨°¦Ì?¡Á¨¤??¨¦?¨®D¨¨??¨¦??¨ª?¡À¨º¡ê??¨¦¨°?¨¢¡é?¡ä¡¤??¨º?¡Â??¨®|¨®?3¨¬D¨°¡ê?2¡é?¨¦¡ä¨°?a?-3¡ê¨º1¨®?¦Ì????t?¡ê¦Ì¡À??¡À???¨º??¡Â¦Ì?¡¤?¡À??¨º¨º¡À¡ê?¡Á¨¤??¡ä¡ã?¨²¡À???¡À???¡ä¨®D?¡ê??¨°¦Ì?¨ª?¡À¨º??D?¡ã2????????¡ê?¨º1?¨°?T¡¤¡§?¨°¦Ì??¨°¨°a¦Ì????¡Â?¡ê¨¨?o¨®¡ê?¦Ì¡À?¨°????¨º??¡Â¦Ì?¡¤?¡À??¨º???a?-¨¤¡ä¦Ì??¨´¡Á¨®¨º¡À¡ê??¨°¦Ì??¨´¨®D¨ª?¡À¨º¨®???D?¡ã2????????¡ê?2¨¦¨®?¨°???D?¦Ì??3D¨°?¡ê?a¨¢??a???a???¨º¨¬a¡ê??¨°2?¦Ì?2?¨®?¨º?1¡è??¡Á¨¤??¨¦?¦Ì??¨´¨®D¨ª?¡À¨º??D????a?¨°?2??¦Ì??¨´¡Á¨®?¡ê??¨º?¡¤3?¨¤¨¨?¨¢??¡ê
?¨°¡¤?3¡ê¨¬??¨¢¨®?¨º?1¡è¡¤?¨º???¡À??aD?¨ª?¡À¨º¦Ì?????¡ê?¨°¨°¡ä?¡ä¡ä?¡§¨¢?¡Á¨¤??????????¡À¡ê¡ä??¡Â¨º¦Ì¨®?3¨¬D¨°D I P S?¡êD I P S¡ã¨¹o?¨°???o¨¹D?¦Ì??¨¦?¡äDD???to¨ª¨°???o¨¹D?¦Ì?D L L?¡ê¦Ì¡À??DD?a???¨¦?¡äDD???t¨º¡À¡ê??¨ª?¨¢3???¨ª?2 2 - 3?¨´¨º?¦Ì????¡é?¨°?¡ê
¨ª?22-3 ¡Á¨¤??????????¡À¡ê¡ä??¡Â¨º¦Ì¨®?1¡è??¡ä¡ã?¨²
?a?????¡é?¨°??¨º?¨¢???¨º¦Ì¨®?3¨¬D¨°¨¨?o?¨º1¨®?¦Ì??¨¦???¡ê¦Ì¡À????S¡Á¡Â?a?¨¹¨¢?DD2?¨ºy¡ä?¦ÌY??D I P S¨º¡À¡ê??¨¹?¨ª¡ä¡ä?¡§?????a??¡Á¡é2¨¢¡À¨ª¡Á¨®1??¨¹¡Á?¡ê?2¡é?¨°??¡Á¨¤??¡ä¡ã?¨²¨¦?¦Ì?????????¨¬¨ª?¨®¨°????¦Ì¡êo
HKEY_CURRENT_USER\Software\Richter\Desktop Item Position Saver
¡Á?3????¨¦?¨¹¨¨??a¡ê?D I P S¦Ì?¨º¦Ì??¨º?¡¤?3¡ê¨¨Y¨°¡Á¦Ì?¡ê?¡À??1????D¨¨¨°a??¦Ì?¡Á¨¤??¦Ì?L i s t Vi e w???t¦Ì?¡ä¡ã?¨²??¡À¨²¡ê??a?¨¹¡¤¡é?¨ª???¨´?¡Â??????¦Ì????¡é¡ê???¦Ì??¨¹??¦Ì?????¡ê?¨¨?o¨®???aD?D??¡é¡À¡ê¡ä??¨²¡Á¡é2¨¢¡À¨ª?D?¨ªDD¨¢??¡ê¦Ì?¨º?¡ê?¨¨?1???DD??¨¬?2¨´¡Á¡Â¡ê??¨ª?¨¢¡¤¡é??¨º??¨¦2¡é2????¡ä?¨°¦Ì£¤?¡ê?¨º¨¬a¨º?¡ä¨®?¨¤¨ºy3¡ê¨®?¦Ì????t¡ä¡ã?¨²???¡é¡ê?¡À¨¨¨¨?LV M _ G E T I T E Mo¨ªLV M _ G E T I T E M P O S I T I O N¡ê?2??¨¹??????3¨¬¦Ì?¡À???¨¤¡ä??DD?¡ê
?-¨°¨°¨º?¡ê?LV M _ G E T I T E M???¡é¨°a?¨®???a???¡é¦Ì?L PA R A M2?¨ºy¡ä?¦ÌY¨°???LV _ I T E M¨ºy?Y?¨¢11¦Ì?¦Ì??¡¤?¡ê¨®¨¦¨®¨²?a???¨²¡ä?¦Ì??¡¤????¡¤¡é?¨ª???¡é¦Ì???3¨¬¨®D¨°a¨°?¡ê??¨®¨º????¡é¦Ì???3¨¬?T¡¤¡§¡À¡ê?¡è?¨¹1?¨º1¨®??¨¹?¡ê¨°¨°¡ä?¡ê??a¨¢?¨º1D I P S?¨¹1?¡ã¡ä?-?¡§¦Ì?¨°a?¨®¨¤¡ä1¡è¡Á¡Â¡ê?¡À?D???¡ä¨²??2?¨¨?E x p l o r e r. e x e¡ê?¨°?¡À???LV M _ G E T I T E Mo¨ªLV M _ G E T I T E M P O S I T I O N???¡é3¨¦1|¦Ì?¡¤¡é?¨ª¦Ì?¡Á¨¤??¦Ì?L i s t Vi e w???t?D?¡ê
¡Á¡é¨°a?¨¦¨°???????3¨¬¦Ì?¡À???¡¤¡é?¨ª¡ä¡ã?¨²???¡é¡ê?¨°?¡À?¨®??¨²?????t¡ê¡§¨¨?¡ã¡ä?£¤?¡é¡À¨¤?-?¨°?¡é?2¨¬??¨°?¡é¡Á¨¦o??¨°o¨ª¨¢D¡À¨ª?¨°¦Ì¨¨¡ê???DD???£¤2¨´¡Á¡Â¡ê?¦Ì?¨º?¡ê???¨°?D?D?¦Ì?3¡ê¨®????t2??¨¹?a?¨´¡Á??¡ê¨¤y¨¨?¡ê??¨¦¨°???¨°???L B _ G E T T E X T???¡é¡¤¡é?¨ª??¨¢¨ª¨°?????3¨¬?D¦Ì???3¨¬¡ä¡ä?¡§¦Ì?¨¢D¡À¨ª?¨°???t¡ê????D¦Ì?L PA R A M2?¨ºy???¨°¡¤¡é?¨ª¡¤???3¨¬?D¦Ì?¨°???¡Á?¡¤?¡ä??o3????¡ê?a¨º??¨¦DD¦Ì?¡ê?¨°¨°?aM i c r o s o f t¡Á¡§??2¨¦?¡äL B _ G E T T E X T???¡é¨º?¡¤?¨°??-¡¤¡é?¨ª?¡ê¨¨?1?¨°??-¡¤¡é?¨ª¡ê?2¨´¡Á¡Â?¦Ì¨ª3???¨²?¨²2?¡ä¡ä?¡§?¨²¡ä?¨®3¨¦????t¡ê?2¡é?¨°??????3¨¬¦Ì?¡À???¨¤¡ä??¡À¡ä??¡Á?¡¤?¡ä?¨ºy?Y?¡ê
?a¨º2?¡äM i c r o s o f t???¡§???¨²?????t?a?¨´¡Á???2???D?¦Ì?3¡ê¨®????t?a?¨´¡Á???¡ê?¡äe¡ã?¨º??a¨¢?¨º¦Ì???¨¦¨°??2D??¡ê?¨²1 6??Wi n d o w s?D¡ê??¨´¨®D¨®|¨®?3¨¬D¨°???¨²¦Ì£¤??¦Ì??¡¤?????D??DD¡ê?¨°???¨®|¨®?3¨¬D¨°?¨¦¨°???¨°???L B _ G E T T E X T???¡é¡¤¡é?¨ª??¨¢¨ª¨°???¨®|¨®?3¨¬D¨°¡ä¡ä?¡§¦Ì?¡ä¡ã?¨²?¡ê?a¨¢?¨º1?aD?1 6??¨®|¨®?3¨¬D¨°?¨¹1?¡¤?3¡ê¨¨Y¨°¡Á¦Ì?¨°??2¦Ì?Wi n 3 2?D¡ê?M i c r o s o f t2¨¦¨¨?¨¢?¨°?D??¡§?¨²¡ä?¨º?¨¤¡ä¨¨¡¤¡À¡ê??????3¨¬¦Ì????¡é¡¤¡é?¨ª¨¨?¨¨??¨¹1???DD?¡ê¦Ì?¨º?1 6??Wi n d o w s?D2?¡ä??¨²D?¦Ì?3¡ê¨®????t¡ê?¨°¨°¡ä?2?¡ä??¨²¨°??2?¨º¨¬a¡ê??¨´¨°?M i c r o s o f t??¨®D?a3¡ê¨®????t2¨¦¨¨??¡§?¨²¦Ì?¡ä?¨º??¡ê
¦Ì¡À??DDD I P S . e x e¨º¡À¡ê??¨¹¨º¡Á?¨¨¦Ì?¦Ì?¡Á¨¤??¦Ì?L i s t Vi e w???t¦Ì?¡ä¡ã?¨²??¡À¨²¡êo
// The Desktop ListView window is the
// grandchild of the ProgMan window.
hwndLV = GetFirstChild(
GetFirstChild(FindWindow(__TEXT("ProgMan"), NULL)));¨°?¦Ì?¨®¦Ì¨®DL i s t Vi e w¦Ì?¡ä¡ã?¨²??¡À¨²¡ê?¨ª¡§1y¦Ì¡Â¨®?G e t Wi n d o w T h r e a d P r o c e s s I do¡¥¨ºy¡ê??¨ª?¨¹1?¨¨¡¤?¡§¡ä¡ä?¡§¡ä¡ã?¨²¦Ì???3¨¬¦Ì?I D ?¡ê???a??I D ¡ä?¦ÌY??S e t D I P S H o o k o¡¥¨ºy¡ê¡§?¨²D I P S L i b . c p p ?D¨º¦Ì??¡ê??¡êS e t D I P S H o o k?o?e?¨²????3¨¬¨¦?¡ã2¡Á¡ã¨°???W H _ G E T M E S S A G E1¨°13¡ê?¨¨?o¨®¦Ì¡Â¨®?????¦Ì?o¡¥¨ºy¡ê?¨°?????Windows Explorer¦Ì???3¨¬D?¨¤¡ä¡êo
PostThreadMessage(dwThreadId, WM_NULL, 0, 0);
GetMessage(&msg, NULL, 0, 0);
¡Á¡é¨°a¡ê??¨°????3¨¬¦Ì????¡é?¨®¨¢D¨®?¨®¨²??3¨¬¦Ì?¨ª?2??¡ê?a?¨´¡Á???????¨®D¨º2?¡ä¡ä¨ª?¨®¡ê?2¡é?¨°¨®D¨º¡À?¨¹1?¡À¨¨¨º1¨®??¡Â???¨²o????¨®¡ê¡§¨¨??£¤3a???¨®?¡éD?¡À¨ºo¨ª¨º??t¦Ì¨¨¡ê??¨¹¨¨Y¨°¡Á¨º¦Ì????3¨¬¦Ì?¨ª?2??¡êWi n d o w s¨®¦Ì¨®D¡¤¨¢??¦Ì?A P I¡ê?¨®|??3?¡¤?¨¤?¨®??¨¹???¡ê
¦Ì¡ÀD I P S?¨¦?¡äDD???t?D¦Ì???3¨¬D?¨¤¡ä¨º¡À¡ê??¨¹?a¦Ì¨¤¡¤t???¡Â???¡ã?¨°¨°??-¡ä¡ä?¡§¡ê?2¡é¦Ì¡Â¨®?F i n d Wi n d o wo¡¥¨ºy¨¤¡ä??¦Ì?¡ä¡ã?¨²¦Ì???¡À¨²?¡ê?a¨º¡À?¨¦¨°?¨º1¨®?¡ä¡ã?¨²???¡é?¨²?¨ª?¡ì?¨²¡ê¡§ D I P S¨®|¨®?3¨¬D¨°¡ê?¨®?¡¤t???¡Â¡ê¡§¨°t2?¦Ì????¡ã?¨°¡ê???????DD¨ª¡§D??¡ê¨®¨¦¨®¨²?¨²Windows Explorer¦Ì???3¨¬?¡¤?3?D??DD¦Ì?¨°?????3¨¬¡ä¡ä?¡§¨¢??a?????¡ã?¨°¡ê?¨°¨°¡ä??¨²¨º1¨®?Windows Explorer¨º¡À???¨¢¨®?¦Ì?¨°?D??T???¡ê
¨¨?¨°a¨¨????¡ã?¨°¡À¡ê¡ä??¨°???1?-¡Á¨¤??¨ª?¡À¨º¦Ì?????¡ê???D¨¨¨°a¡¤¡é?¨ª¨°?¨¬????¡é¡êo
// Tell the DIPS window which ListView window to manipulate // and whether the items should be saved or restored. SendMessage(hwndDIPS, WM_APP, (WPARAM) hwndLV, fSave);
¨®¨¦¨®¨²?¨°¨º1¨®?S e n d M e s s a g e??2?¨º?P o s t m e s s a g e¡ê?¨°¨°¡ä???o¡¥¨ºy?¡À¦Ì???DD¨ª¨º3¨¦2?¡¤¦Ì???¡ê¨¨?1???¨°a¦Ì??¡ã¡ê??¨¦¨°??????¡é¨¬¨ª?¨®?????¡ã?¨°¦Ì?1y3¨¬¡ê?¨º1??3¨¬D¨°?¨¹1???¨°?2?????E x p l o r e r¦Ì???3¨¬?¡ê¦Ì¡À¨ª¨º3¨¦¨®????¡ã?¨°¦Ì?¨ª¡§D?¨º¡À¡ê?2¡é?¨°¡ê¡§¨°¨°¡ä?¡ê???¨°a???1¡¤t???¡Â¦Ì???DD¨º¡À¡ê??¨°¡¤¡é?¨ª¨¢?¨°???W M _ C L O S E???¡é¡ê????????¡ã?¨°??¡Á??o1?¡À??¡ê
¡Á?o¨®¡ê??¨ª?¨²D I P S¨®|¨®?3¨¬D¨°???1??DD???¡ã¡ê??¨¹?¨´¡ä?¦Ì¡Â¨®?S e t D I P S H o o ko¡¥¨ºy¡ê?¦Ì?¨º?¡ä?¦ÌY0¡Á¡Â?a??3¨¬¦Ì?I D?¡ê0¨º???¡À¨º???¦Ì¡ê?¨®?¨®¨²????o¡¥¨ºy3¡¤??W N _ G E T M E S S A G E1¨°13?¡ê¦Ì¡À??1¨°13¡À?D???¨º¡À¡ê?2¨´¡Á¡Â?¦Ì¨ª3¡Á??¡¥¡ä¨®E x p l o r e r¦Ì?¦Ì??¡¤?????DD???D I P S L i b . d l l???t?¡ê???¡ã?¨°¨º¡Á?¨¨3¡¤??¡ê?¨¨?o¨®D???1¨°13¡ê??a¨°?¦Ì?o¨¹??¨°a¡ê?¡¤??¨°???¡ã?¨°?¨®¨º?¦Ì?¦Ì???¨°??????¡é???¨¢¦Ì???E x p l o r e r¦Ì???3¨¬¨°y¡¤¡é¨°?¡ä?¡¤??¨º?£¤1??¡ê¨¨?1?¡¤¡é¨¦¨²?a???¨¦??¡ê?2¨´¡Á¡Â?¦Ì¨ª3?¨ª?¨¢???1E x p l o r e r¦Ì???DD?¡ê¦Ì¡À¨º1¨®?D L L¦Ì?2?¨¨?2¨´¡Á¡Â¨º¡À¡ê?¡À?D?¡¤?3¡êD?D??¡ê
??¦Ì£¤22-1 DIPS¨º¦Ì¨®?3¨¬D¨°
/******************************************************************************
Module: DIPS.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/
#include "..\CmnHdr.h" /* See Appendix A. */
#include <WindowsX.h>
#include <tchar.h>
#include "Resource.h"
#include "..\22-DIPSLib\DIPSLib.h"
///////////////////////////////////////////////////////////////////////////////
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) {
chSETDLGICONS(hwnd, IDI_DIPS);
return(TRUE);
}
///////////////////////////////////////////////////////////////////////////////
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) {
switch (id) {
case IDC_SAVE:
case IDC_RESTORE:
case IDCANCEL:
EndDialog(hwnd, id);
break;
}
}
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand);
}
return(FALSE);
}
///////////////////////////////////////////////////////////////////////////////
int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) {
// Convert command-line character to uppercase.
CharUpperBuff(pszCmdLine, 1);
TCHAR cWhatToDo = pszCmdLine[0];
if ((cWhatToDo != TEXT('S')) && (cWhatToDo != TEXT('R'))) {
// An invalid command-line argument; prompt the user.
cWhatToDo = 0;
}
if (cWhatToDo == 0) {
// No command-line argument was used to tell us what to
// do; show usage dialog box and prompt the user.
switch (DialogBox(hinstExe, MAKEINTRESOURCE(IDD_DIPS), NULL, Dlg_Proc)) {
case IDC_SAVE:
cWhatToDo = TEXT('S');
break;
case IDC_RESTORE:
cWhatToDo = TEXT('R');
break;
}
}
if (cWhatToDo == 0) {
// The user doesn't want to do anything.
return(0);
}
// The Desktop ListView window is the grandchild of the ProgMan window.
HWND hwndLV = GetFirstChild(GetFirstChild(
FindWindow(TEXT("ProgMan"), NULL)));
chASSERT(IsWindow(hwndLV));
// Set hook that injects our DLL into the Explorer's address space. After
// setting the hook, the DIPS hidden modeless dialog box is created. We
// send messages to this window to tell it what we want it to do.
chVERIFY(SetDIPSHook(GetWindowThreadProcessId(hwndLV, NULL)));
// Wait for the DIPS server window to be created.
MSG msg;
GetMessage(&msg, NULL, 0, 0);
// Find the handle of the hidden dialog box window.
HWND hwndDIPS = FindWindow(NULL, TEXT("Richter DIPS"));
// Make sure that the window was created.
chASSERT(IsWindow(hwndDIPS));
// Tell the DIPS window which ListView window to manipulate
// and whether the items should be saved or restored.
SendMessage(hwndDIPS, WM_APP, (WPARAM) hwndLV, (cWhatToDo == TEXT('S')));
// Tell the DIPS window to destroy itself. Use SendMessage
// instead of PostMessage so that we know the window is
// destroyed before the hook is removed.
SendMessage(hwndDIPS, WM_CLOSE, 0, 0);
// Make sure that the window was destroyed.
chASSERT(!IsWindow(hwndDIPS));
// Unhook the DLL, removing the DIPS dialog box procedure
// from the Explorer's address space.
SetDIPSHook(0);
return(0);
}
//////////////////////////////// End of File //////////////////////////////////
/******************************************************************************
Module: DIPSLib.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/
#include "..\CmnHdr.h" /* See Appendix A. */
#include <WindowsX.h>
#include <CommCtrl.h>
#define DIPSLIBAPI __declspec(dllexport)
#include "DIPSLib.h"
#include "Resource.h"
///////////////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
// This function forces the debugger to be invoked
void ForceDebugBreak() {
__try { DebugBreak(); }
__except(UnhandledExceptionFilter(GetExceptionInformation())) { }
}
#else
#define ForceDebugBreak()
#endif
///////////////////////////////////////////////////////////////////////////////
// Forward references
LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);
INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
///////////////////////////////////////////////////////////////////////////////
// Instruct the compiler to put the g_hhook data variable in
// its own data section called Shared. We then instruct the
// linker that we want to share the data in this section
// with all instances of this application.
#pragma data_seg("Shared")
HHOOK g_hhook = NULL;
DWORD g_dwThreadIdDIPS = 0;
#pragma data_seg()
// Instruct the linker to make the Shared section
// readable, writable, and shared.
#pragma comment(linker, "/section:Shared,rws")
///////////////////////////////////////////////////////////////////////////////
// Nonshared variables
HINSTANCE g_hinstDll = NULL;
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, PVOID fImpLoad) {
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
// DLL is attaching to the address space of the current process.
g_hinstDll = hinstDll;
break;
case DLL_THREAD_ATTACH:
// A new thread is being created in the current process.
break;
case DLL_THREAD_DETACH:
// A thread is exiting cleanly.
break;
case DLL_PROCESS_DETACH:
// The calling process is detaching the DLL from its address space.
break;
}
return(TRUE);
}
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI SetDIPSHook(DWORD dwThreadId) {
BOOL fOk = FALSE;
if (dwThreadId != 0) {
// Make sure that the hook is not already installed.
chASSERT(g_hhook == NULL);
// Save our thread ID in a shared variable so that our GetMsgProc
// function can post a message back to to thread when the server
// window has been created.
g_dwThreadIdDIPS = GetCurrentThreadId();
// Install the hook on the specified thread
g_hhook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hinstDll,
dwThreadId);
fOk = (g_hhook != NULL);
if (fOk) {
// The hook was installed successfully; force a benign message to
// the thread's queue so that the hook function gets called.
fOk = PostThreadMessage(dwThreadId, WM_NULL, 0, 0);
}
} else {
// Make sure that a hook has been installed.
chASSERT(g_hhook != NULL);
fOk = UnhookWindowsHookEx(g_hhook);
g_hhook = NULL;
}
return(fOk);
}
///////////////////////////////////////////////////////////////////////////////
LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) {
static BOOL fFirstTime = TRUE;
if (fFirstTime) {
// The DLL just got injected.
fFirstTime = FALSE;
// Uncomment the line below to invoke the debugger
// on the process that just got the injected DLL.
// ForceDebugBreak();
// Create the DTIS Server window to handle the client request.
CreateDialog(g_hinstDll, MAKEINTRESOURCE(IDD_DIPS), NULL, Dlg_Proc);
// Tell the DIPS application that the server is up
// and ready to handle requests.
PostThreadMessage(g_dwThreadIdDIPS, WM_NULL, 0, 0);
}
return(CallNextHookEx(g_hhook, nCode, wParam, lParam));
}
///////////////////////////////////////////////////////////////////////////////
void Dlg_OnClose(HWND hwnd) {
DestroyWindow(hwnd);
}
///////////////////////////////////////////////////////////////////////////////
static const TCHAR g_szRegSubKey[] =
TEXT("Software\\Richter\\Desktop Item Position Saver");
///////////////////////////////////////////////////////////////////////////////
void SaveListViewItemPositions(HWND hwndLV) {
int nMaxItems = ListView_GetItemCount(hwndLV);
// When saving new positions, delete the old position
// information that is currently in the registry.
LONG l = RegDeleteKey(HKEY_CURRENT_USER, g_szRegSubKey);
// Create the registry key to hold the info
HKEY hkey;
l = RegCreateKeyEx(HKEY_CURRENT_USER, g_szRegSubKey, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hkey, NULL);
chASSERT(l == ERROR_SUCCESS);
for (int nItem = 0; nItem < nMaxItems; nItem++) {
// Get the name and position of a ListView item.
TCHAR szName[MAX_PATH];
ListView_GetItemText(hwndLV, nItem, 0, szName, chDIMOF(szName));
POINT pt;
ListView_GetItemPosition(hwndLV, nItem, &pt);
// Save the name and position in the registry.
l = RegSetValueEx(hkey, szName, 0, REG_BINARY, (PBYTE) &pt, sizeof(pt));
chASSERT(l == ERROR_SUCCESS);
}
RegCloseKey(hkey);
}
///////////////////////////////////////////////////////////////////////////////
void RestoreListViewItemPositions(HWND hwndLV) {
HKEY hkey;
LONG l = RegOpenKeyEx(HKEY_CURRENT_USER, g_szRegSubKey,
0, KEY_QUERY_VALUE, &hkey);
if (l == ERROR_SUCCESS) {
// If the ListView has AutoArrange on, temporarily turn it off.
DWORD dwStyle = GetWindowStyle(hwndLV);
if (dwStyle & LVS_AUTOARRANGE)
SetWindowLong(hwndLV, GWL_STYLE, dwStyle & ~LVS_AUTOARRANGE);
l = NO_ERROR;
for (int nIndex = 0; l != ERROR_NO_MORE_ITEMS; nIndex++) {
TCHAR szName[MAX_PATH];
DWORD cbValueName = chDIMOF(szName);
POINT pt;
DWORD cbData = sizeof(pt), nItem;
// Read a value name and position from the registry.
DWORD dwType;
l = RegEnumValue(hkey, nIndex, szName, &cbValueName,
NULL, &dwType, (PBYTE) &pt, &cbData);
if (l == ERROR_NO_MORE_ITEMS)
continue;
if ((dwType == REG_BINARY) && (cbData == sizeof(pt))) {
// The value is something that we recognize; try to find
// an item in the ListView control that matches the name.
LV_FINDINFO lvfi;
lvfi.flags = LVFI_STRING;
lvfi.psz = szName;
nItem = ListView_FindItem(hwndLV, -1, &lvfi);
if (nItem != -1) {
// We found a match; change the item's position.
ListView_SetItemPosition(hwndLV, nItem, pt.x, pt.y);
}
}
}
// Turn AutoArrange back on if it was originally on.
SetWindowLong(hwndLV, GWL_STYLE, dwStyle);
RegCloseKey(hkey);
}
}
///////////////////////////////////////////////////////////////////////////////
INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
chHANDLE_DLGMSG(hwnd, WM_CLOSE, Dlg_OnClose);
case WM_APP:
// Uncomment the line below to invoke the debugger
// on the process that just got the injected DLL.
// ForceDebugBreak();
if (lParam)
SaveListViewItemPositions((HWND) wParam);
else
RestoreListViewItemPositions((HWND) wParam);
break;
}
return(FALSE);
}
//////////////////////////////// End of File //////////////////////////////////
/****************************************************************************** Module: DIPSLib.h Notices: Copyright (c) 2000 Jeffrey Richter ******************************************************************************/ #if !defined(DIPSLIBAPI) #define DIPSLIBAPI __declspec(dllimport) #endif /////////////////////////////////////////////////////////////////////////////// // External function prototypes DIPSLIBAPI BOOL WINAPI SetDIPSHook(DWORD dwThreadId); //////////////////////////////// End of File //////////////////////////////////
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DIPS DIALOG DISCARDABLE 0, 0, 132, 13
STYLE WS_CAPTION
CAPTION "Richter DIPS"
FONT 8, "MS Sans Serif"
BEGIN
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
2?¨¨?D L L¦Ì?¦Ì¨²¨¨y??¡¤?¡¤¡§¨º?¨º1¨®???3¨¬??3¨¬?¡ê?a??¡¤?¡¤¡§??¨®D?¨¹¡ä¨®¦Ì?¨¢¨¦??D??¡ê?¨¹¨°a?¨®????¦Ì?¨¨??¨¦??Wi n d o w s¨¬?D??¡é¨¨???3¨¬?¡é??3¨¬?¡é??3¨¬¨ª?2??¡éD¨¦?a?¨²¡ä?1¨¹¨¤¨ª?¡éD L Lo¨ªU n i c o d e¦Ì¨¨¡ê¡§¨¨?1????aD?¨¬?D?2???3t¡ê???2???¡À?¨º¨¦?D¦Ì?¨®D1????¨²¡ê??¡êWi n d o w s¦Ì?¡ä¨®?¨¤¨ºyo¡¥¨ºy?¨ºD¨ª??3¨¬????¡Á??o??DD2¨´¡Á¡Â?¡ê?a¨º?o¨¹o?¦Ì?¨°???¨¬?D?¡ê?¨°¨°?a?¨¹?¨¹1?¡¤¨¤?1¨°?????3¨¬???¦Ì¨¢¨ª¨°?????3¨¬¦Ì???DD?¡ê¦Ì?¨º?¡ê?¨®DD?o¡¥¨ºy¨¨¡ä?¨ºD¨ª¨°?????3¨¬??¨¢¨ª¨°?????3¨¬??DD2¨´¡Á¡Â?¡ê?aD?o¡¥¨ºy¡ä¨®2?¡¤?¡Á?3?¨º??a¦Ì¡Â¨º?3¨¬D¨°o¨ª????1¡è??¨¦¨¨??¦Ì??¡ê2?1y¨¨?o?o¡¥¨ºy???¨¦¨°?¦Ì¡Â¨®??aD?o¡¥¨ºy?¡ê
?a??D L L2?¨¨?¡¤?¡¤¡§?¨´¡À?¨¦?¨°a?¨®??¡À¨º??3¨¬?D¦Ì???3¨¬¦Ì¡Â¨®?L o a d L i b r a r yo¡¥¨ºy¨¤¡ä?¨®??¡À?¨°a¦Ì?D L L?¡ê¨®¨¦¨®¨²3y¨¢?¡Á??o??3¨¬?D¦Ì???3¨¬¨ªa¡ê??¨°???T¡¤¡§¡¤?¡À?¦Ì???????????3¨¬?D¦Ì???3¨¬¡ê?¨°¨°¡ä??a???a??¡¤?¡ã?¨°a?¨®?¨°???¨²??¡À¨º??3¨¬?D¡ä¡ä?¡§¨°???D???3¨¬?¡ê¨®¨¦¨®¨²¨º?¡Á??o¡ä¡ä?¡§?a????3¨¬¡ê?¨°¨°¡ä??¨°???¨¹1??????¨¹?¡äDD¨º2?¡ä¡ä¨²???¡êD¨°o?¡ê?Wi n d o w s¨¬¨¢1?¨¢?¨°???3??aC r e a t e R e m o t e T h r e a d¦Ì?o¡¥¨ºy¡ê?¨º1?¨°???¨¹1?¡¤?3¡ê¨¨Y¨°¡Á¦Ì??¨²¨¢¨ª¨°?????3¨¬?D¡ä¡ä?¡§??3¨¬¡êo
HANDLE CreateRemoteThread( HANDLE hProcess, PSECURITY_ATTRIBUTES psa, DWORD dwStackSize, PTHREAD_START_ROUTINE pfnStartAddr, PVOID pvParam, DWORD fdwCreate, PDWORD pdwThreadId);
¡Á¡é¨°a?¨²Windows 2000?D¡ê??¨¹3¡ê¨®?¦Ì?o¡¥¨ºyCreateThread¨º??¨²?¨²2?¨°?????¦Ì?D?¨º?¨¤¡ä¨º¦Ì??¦Ì?¡êo
HANDLE CreateThread(PSECURITY_ATTRIBUTES psa, DWORD dwStackSize,
PTHREAD_START_ROUTINE pfnStartAddr, PVOID pvParam,
DWORD fdwCreate, PDWORD pdwThreadID)
{
return(CreateRemoteThread(GetCurrentProcess(), psa, dwStackSize,
pfnStartAddr, pvParam, fdwCreate, pdwThreadID));
}o?¨¢?¡ê????¨²??¨°??-?a¦Ì¨¤¨¨?o??¨²¨¢¨ª¨°?????3¨¬?D¡ä¡ä?¡§??3¨¬¨¢?¡ê?¦Ì?¨º?¡ê?¨¨?o?2??¨¹¨¨?????3¨¬?¨®???¨°??¦Ì?D L L??¡ê?¡äe¡ã?o¨¹?¨°¦Ì£¤¡ê????¨ª¨º?D¨¨¨°a????3¨¬¦Ì¡Â¨®?L o a d L i b r a r yo¡¥¨ºy¡êo
HINSTANCE LoadLibrary(PCTSTR pszLibFile);
HINSTANCE WINAPI LoadLibraryA(LPCSTR pszLibFileName); HINSTANCE WINAPI LoadLibraryW(LPCWSTR pszLibFileName); #ifdef UNICODE #define LoadLibrary LoadLibraryW #else #define LoadLibrary LoadLibraryA #endif // !UNICODE
D¨°o?L o a d L i b r a r yo¡¥¨ºy¦Ì??-D¨ª¨®?¨°?????3¨¬o¡¥¨ºy¦Ì??-D¨ª¨º??¨¤¨ª?¦Ì??¡ê????¨º?¨°?????3¨¬o¡¥¨ºy¦Ì??-D¨ª¡êo
DWORD WINAPI ThreadFunc(PVOID pvParam);
HANDLE hThread = CreateRemoteThread(hProcessRemote, NULL, 0, LoadLibraryA, "C:\\MyLib.dll", 0, NULL);
HANDLE hThread = CreateRemoteThread(hProcessRemote, NULL, 0, LoadLibraryW, L"C:\\MyLib.dll", 0, NULL);
¦Ì¨²¨°????¨º¨¬a¨º?¡ê?2??¨¹???¨°?¨²¨¦????1¨º?¦Ì????¨´¡ê???L o a d L i b r a r y A?¨°L o a d L i b r a r y W¡Á¡Â?a¦Ì¨²????2?¨ºy¡ä?¦ÌY??C r e a t e R e m o t e T h r e a d?¡ê?-¨°¨°o¨¹?¨°¦Ì£¤?¡ê¦Ì¡À??¡À¨¤¨°??¨°??¨¢¡ä?¨®¨°???3¨¬D¨°¨º¡À¡ê?2¨²¨¦¨²¦Ì??t????¡ä¨²??¡ã¨¹o?¨°???¨º?¨¨??¨²¡ê¡§¦Ì¨²1 9???D¡Á?¨¢??¨¦¨¦¨¹¡ê??¡ê?a¨°??¨²¨®¨¦¨°??¦Ì¨¢D¨º?¨¨?o¡¥¨ºy¦Ì?D?¨º?¨¬???3¨¬D¨°¡ê¡§t h u n k¡ê?¡Á¨¦3¨¦?¡ê?¨´¨°?¡ê?¦Ì¡À??¦Ì?¡ä¨²??¦Ì¡Â¨®?¨°???o¡¥¨ºy¨¨?L o a d L i b r a r y A¨º¡À¡ê?¨¢¡ä?¨®3¨¬D¨°??¨¦¨²3¨¦¨°????????¡ê?¨¦¦Ì?¨º?¨¨??¨²?D¦Ì?D?¨º¦Ì¨¬???3¨¬D¨°¦Ì?¦Ì¡Â¨®??¡ê?¨®¡Á?¡ê???D?¨º¦Ì¨¬???3¨¬D¨°¡À?¡Áa¨°?¦Ì?¨º¦Ì?¨º¦Ì?o¡¥¨ºy?¡ê
¨¨?1??¨²??C r e a t e R e m o t e T h r e a d¦Ì?¦Ì¡Â¨®??D¨º1¨®?¨°?????L o a d L i b r a r y A¦Ì??¡À?¨®¨°y¨®?¡ê??a???¨²??¦Ì??¡ê?¨¦¦Ì?¨º?¨¨??¨²?D¡Áa??3¨¦L o a d L i b r a r y A¦Ì?D?¨º¦Ì¨¬???3¨¬D¨°¦Ì?¦Ì??¡¤?¡ê??D?¨º¦Ì¨¬???3¨¬D¨°¦Ì?¦Ì??¡¤¡Á¡Â?a??3¨¬??3¨¬¦Ì??e¨º?¦Ì??¡¤¨¤¡ä¡ä?¦ÌY¡ê??¨¢¦Ì?????3¨¬??3¨¬?a¨º??¡äDD¨°?D?¨¢?¨¨??a??????¦Ì????¡Â?¡ê???¨¢1?o¨¹?¨¦?¨¹?¨¬3¨¦¡¤??¨º?£¤1??¡ê¨¨?¨°a?????¡À?¨®¦Ì¡Â¨®?L o a d L i b r a r y Ao¡¥¨ºy¡ê?¡À¨¹?aD?¨º¦Ì¨¬???3¨¬D¨°¡ê?¡À?D?¨ª¡§1y¦Ì¡Â¨®?G e t P r o c A d d r e s so¡¥¨ºy¡ê???¨¨?L o a d L i b r a r y A¦Ì?¡Á?¨¨¡¤?¨²¡ä??????¡ê
??C r e a t e R e m o t e T h r e a d??DD¦Ì¡Â¨®?¦Ì??¡ã¨¬¨¢¨º?¡ê?K e r n e l 3 2 . d l l¨°??-¡À?¨ª?¨º¡À¨®3¨¦?¦Ì?¡À?¦Ì?o¨ª??3¨¬??3¨¬¦Ì?¦Ì??¡¤?????D?¡ê????¨®|¨®?3¨¬D¨°??D¨¨¨°aK e r n e l 3 2 . d l l¡ê??¨´?Y?¨°¦Ì??-?¨¦¡ê??¦Ì¨ª3??K e r n e l 3 2 . d l l¨®3¨¦?¦Ì???????3¨¬¦Ì?¨ª?¨°???¦Ì??¡¤?¡ê¨°¨°¡ä?¡ê?¡À?D?¦Ì¡Â¨®?????¦Ì?C r e a t e R e m o t e T h r e a do¡¥¨ºy¡êo
// Get the real address of LoadLibraryA in Kernel32.dll.
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryA");
HANDLE hThread = CreateRemoteThread(hProcessRemote, NULL, 0,
pfnThreadRtn, "C:\\MyLib.dll", 0, NULL);
// Get the real address of LoadLibraryW in Kernel32.dll.
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
HANDLE hThread = CreateRemoteThread(hProcessRemote, NULL, 0,
pfnThreadRtn, L"C:\\MyLib.dll", 0, NULL);?a¨¢??a???a???¨º¨¬a¡ê?¡À?D???D L L¦Ì??¡¤????¡Á?¡¤?¡ä?¡¤?¨¨???3¨¬??3¨¬¦Ì?¦Ì??¡¤?????D?¡ê¨¨?o¨®¡ê?¦Ì¡ÀC r e a t e R e m o t e T h r e a do¡¥¨ºy¡À?¦Ì¡Â¨®?¨º¡À¡ê??¨°??¡À?D????¨°??¡¤?????¡Á?¡¤?¡ä?¦Ì?¦Ì??¡¤¡ê¡§?¨¤??¨®¨²??3¨¬??3¨¬¦Ì?¦Ì??¡¤¡ê?¡ä?¦ÌY???¨¹?¡ê¨ª??¨´¡ê?Wi n d o w s¨¬¨¢1?¨¢?¨°???o¡¥¨ºy¡ê??¡äVi r t u a l A l l o c E x¡ê?¨º1¦Ì?¨°?????3¨¬?¨¹1?¡¤???¨¢¨ª¨°?????3¨¬¦Ì?¦Ì??¡¤?????D¦Ì??¨²¡ä?¡êo
PVOID VirtualAllocEx( HANDLE hProcess, PVOID pvAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
BOOL VirtualFreeEx( HANDLE hProcess, PVOID pvAddress, SIZE_T dwSize, DWORD dwFreeType);
¨°?¦Ì??a??¡Á?¡¤?¡ä?¡¤???¨¢??¨²¡ä?¡ê??¨°???1D¨¨¨°a¨°???¡¤?¡¤¡§????¡Á?¡¤?¡ä?¡ä¨®?¨°??¦Ì???3¨¬¦Ì?¦Ì??¡¤??????¡À¡ä¦Ì???3¨¬??3¨¬¦Ì?¦Ì??¡¤?????D?¡êWi n d o w s¨¬¨¢1?¨¢?¨°?D?o¡¥¨ºy¡ê?¨º1¦Ì?¨°?????3¨¬?¨¹1?¡ä¨®¨¢¨ª¨°?????3¨¬¦Ì?¦Ì??¡¤?????D?¨¢¨¨?¨ºy?Y¡ê?2¡é??¨ºy?YD¡ä¨¨?¨¢¨ª¨°?????3¨¬¦Ì?¦Ì??¡¤?????¡ê
BOOL ReadProcessMemory( HANDLE hProcess, PVOID pvAddressRemote, PVOID pvBufferLocal, DWORD dwSize, PDWORD pdwNumBytesRead); BOOL WriteProcessMemory( HANDLE hProcess, PVOID pvAddressRemote, PVOID pvBufferLocal, DWORD dwSize, PDWORD pdwNumBytesWritten);
?¨¨¨¨?¨°??-?a¦Ì¨¤¨¢?¨°a??DD2¨´¡Á¡Â¡ê?????¨¨??¨°????¡À?D??¡äDD¦Ì?2¨´¡Á¡Â2??¨¨¡Á?¨°???1¨¦?¨¦¡êo
1) ¨º1¨®?Vi r t u a l A l l o c E xo¡¥¨ºy¡ê?¡¤?????3¨¬??3¨¬¦Ì?¦Ì??¡¤?????D¦Ì??¨²¡ä??¡ê
2) ¨º1¨®?Wr i t e P r o c e s s M e m o r yo¡¥¨ºy¡ê???D L L¦Ì??¡¤??????¡À¡ä¦Ì?¦Ì¨²¨°???2??¨¨?D¨°??-¡¤???¦Ì??¨²¡ä??D?¡ê
3) ¨º1¨®?G e t P r o c A d d r e s so¡¥¨ºy¡ê???¨¨?L o a d L i b r a r y A?¨°L o a d L i b r a t y Wo¡¥¨ºy¦Ì?¨º¦Ì¦Ì??¡¤¡ê¡§?¨²K e r n e l 3 2 . d l l?D¡ê??¡ê
4) ¨º1¨®?C r e a t e R e m o t e T h r e a do¡¥¨ºy¡ê??¨²??3¨¬??3¨¬?D¡ä¡ä?¡§¨°?????3¨¬¡ê??¨¹¦Ì¡Â¨®??y¨¨¡¤¦Ì?L o a d L i b r a r yo¡¥¨ºy¡ê??a?¨¹¡ä?¦ÌY¦Ì¨²¨°???2??¨¨?D¡¤???¦Ì??¨²¡ä?¦Ì?¦Ì??¡¤?¡ê
?a¨º¡À¡ê? D L L¨°??-¡À?2?¨¨???3¨¬??3¨¬¦Ì?¦Ì??¡¤?????D¡ê?¨ª?¨º¡ÀD L L¦Ì?D l l M a i no¡¥¨ºy?¨®¨º?¦Ì?¨°???D L L _ P R O C E S S _ AT TA C H¨ª¡§?a¡ê?2¡é?¨°?¨¹1??¡äDDD¨¨¨°a¦Ì?¡ä¨²???¡ê¦Ì¡ÀD l l M a i no¡¥¨ºy¡¤¦Ì??¨º¡À¡ê???3¨¬??3¨¬¡ä¨®?¨¹??L o a d L i b r a r y¦Ì?¦Ì¡Â¨®?¡¤¦Ì??¦Ì?B a s e T h r e a d S t a r t o¡¥¨ºy¡ê¡§¦Ì¨²6 ???D¨°??-?¨¦¨¦¨¹¡ê??¡ê¨¨?o¨®B a s e T h r e a d S t a r t¦Ì¡Â¨®?E x i t T h r e a d¡ê?¨º1??3¨¬??3¨¬???1??DD?¡ê
???¨²??3¨¬??3¨¬¨®¦Ì¨®D¦Ì¨²¨°???2??¨¨?D¡¤???¦Ì??¨²¡ä??¨¦¡ê???D L L?¨°¨¨?¨¨?¡À¡ê¨¢??¨²?¨¹¦Ì?¦Ì??¡¤?????D?¡ê¨¨?¨°a???¨¹¨¦?3y¡ê?D¨¨¨°a?¨²??3¨¬??3¨¬¨ª?3?o¨®?¡äDD????¦Ì?2??¨¨¡êo
5) ¨º1¨®?Vi r t u a l F r e e E xo¡¥¨ºy¡ê?¨º¨ª¡¤?¦Ì¨²¨°???2??¨¨?D¡¤???¦Ì??¨²¡ä??¡ê
6) ¨º1¨®?G e t P r o c A d d r e s so¡¥¨ºy¡ê???¦Ì?F r e e L i b r a r yo¡¥¨ºy¦Ì?¨º¦Ì¦Ì??¡¤¡ê¡§?¨²K e r n e l 3 2 . d l l?D¡ê??¡ê
7) ¨º1¨®?C r e a t e R e m o t e T h r e a do¡¥¨ºy¡ê??¨²??3¨¬??3¨¬?D¡ä¡ä?¡§¨°?????3¨¬¡ê??¨¹¦Ì¡Â¨®?F r e e L i b r a r yo¡¥¨ºy¡ê?¡ä?¦ÌY??3¨¬D L L¦Ì?H I N S TA N C E?¡ê
?a?¨ª¨º??¨¹¦Ì??¨´¡À?2¨´¡Á¡Â2??¨¨?¡ê?a??2?¨¨?D L L¦Ì?¡¤?¡¤¡§¡ä??¨²¦Ì??¡§¨°?¨°???2?¡Á?¨º?, Windows 982¡é2??¡ì3??a?¨´¦Ì?o¡¥¨ºy?¡ê???¨¹?¨²Windows 2000¨¦?¨º1¨®??a??¡¤?¡¤¡§?¡ê
22.4.1 Inject Library¨º?¨¤y¨®|¨®?3¨¬D¨°
??¦Ì£¤2 2 - 2?D¨¢D3?¦Ì?I n j L i b . e x e¨®|¨®?3¨¬D¨°¨º1¨®?C r e a t e R e m o t e T h r e a do¡¥¨ºy¨¤¡ä2?¨¨?D L L?¡ê??¨®|¨®?3¨¬D¨°o¨ªD L L¦Ì??¡ä¡ä¨²??o¨ª¡Á¨º?¡ä???t??¨®¨²¡À?¨º¨¦?¨´??1a?¨¬¨¦?¦Ì?2 2 -I n j L i bo¨ª2 2 - I m g Wa l k???????¡ê??3¨¬D¨°¨º1¨®?¨ª?2 2 - 4?¨´¨º?¦Ì????¡ã?¨°¨¤¡ä?¨®¨º???DD¦Ì???3¨¬I D?¡ê
¨ª?22-4 Inject Library Te s t e r???¡ã?¨°
?¨¦¨°?¨º1¨®?Windows 2000??¨®D¦Ì?Task Manager¡ê¡§¨¨???1¨¹¨¤¨ª?¡Â¡ê???¨¨???3¨¬¦Ì?I D?¡ê¨º1¨®??a??I D¡ê???3¨¬D¨°??¨¦¨¨¡¤¡§¨ª¡§1y¦Ì¡Â¨®?O p e n P r o c e s so¡¥¨ºy¨¤¡ä¡ä¨°?a?y?¨²??DD¦Ì???3¨¬¦Ì???¡À¨²¡ê?¨¦¨º???¨¤¨®|¦Ì?¡¤??¨º¨¨¡§¡êo
hProcess = OpenProcess( PROCESS_CREATE_THREAD | // For CreateRemoteThread PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx PROCESS_VM_WRITE, // For WriteProcessMemory FALSE, dwProcessId);
¨¨?1?O p e n P r o c e s so¡¥¨ºy??DD3¨¦1|¡ê?¡À?¨º1¨®?¨°a2?¨¨?¦Ì?D L L¦Ì?¨¨??¡¤??????¨°????o¡ä???3¨¬3?¨º??¡¥?¡ê¨¨?o¨®I n j e c t L i b¡À?¦Ì¡Â¨®?¡ê??a?¨¹¡ä?¦ÌYD¨¨¨°a¦Ì???3¨¬??3¨¬¦Ì???¡À¨²o¨ª¨°a2?¨¨?¦Ì?D L L¦Ì??¡¤?????¡ê¡Á?o¨®¡ê?¦Ì¡ÀI n j e c t L i b¡¤¦Ì??¨º¡À¡ê???3¨¬D¨°??¨º?¨°??????¡é?¨°¡ê????¡ÂD L L¨º?¡¤?¨°??-3¨¦1|¦Ì??¨®??¦Ì???3¨¬??3¨¬?D¡ê?¨¨?o¨®?¨¹1?¡À???3¨¬¦Ì???¡À¨²?¡ê?a?¨ª¨º??¨¹¦Ì?¨¨?2???DD1y3¨¬?¡ê
???¨¦?¨¹?¨²¡ä¨²???D¡¤¡é??¡ê??¨°¡Á¡§??2¨¦?¡ä¨¢?¡ä?¦ÌY¦Ì???3¨¬I D¨º?¡¤?¨º?0?¡ê¨¨?1?¨º?0¡ê??¨°?¨ª¦Ì¡Â¨®?G e t C u r r e n tP r o c e s s I do¡¥¨ºy¡ê?????3¨¬¦Ì?I D¨¦¨¨???aI n j e c t L i b . e x e¡Á??o¦Ì???3¨¬I D?¡ê?a?¨´¡ê?¦Ì¡ÀI n j e c t L i b¡À?¦Ì¡Â¨®?¨º¡À¡ê?D L L¡À?2?¨¨?¦Ì???3¨¬¡Á??o¦Ì?¦Ì??¡¤?????D?¡ê?a¨º1¦Ì?3¨¬D¨°¦Ì?¦Ì¡Â¨®?¡À¨¨??¨¨Y¨°¡Á?¡ê?¨¦¨°????¨®¡ê?¦Ì¡À3???¡ä¨ª?¨®¨º¡À¡ê?¨®D¨º¡Ào¨¹??¨¨¡¤?¡§?aD?¡ä¨ª?¨®¨º??¨²¡À?¦Ì???3¨¬?D?1¨º??¨²??3¨¬??3¨¬?D?¡ê?-?¨¨?¨°¨®?¨¢???¦Ì¡Â¨º?3¨¬D¨°¨¤¡ä¦Ì¡Â¨º??¨°¦Ì?¡ä¨²??¡ê?¨°???¦Ì¡Â¨º?3¨¬D¨°?o?e1?2¨¬I n j L i b¡ê?¨¢¨ª¨°???¦Ì¡Â¨º?3¨¬D¨°?o?e1?2¨¬??3¨¬??3¨¬?¡ê?¨¢1?¡À¨ª?¡Â?a?¨´¡Á?¨º?o¨¹2?¡¤?¡À?¦Ì??¡êo¨®¨¤¡ä?¨°2??¡Â¡ã¡Á¡ê? I n j L i b¨°2?¨¹??D L L2?¨¨?¡À?¨¦¨ª¦Ì?3¨¬D¨°?D¡ê?¨°2?¨ª¨º??¦Ì2?¨¨?¨®?¦Ì¡Â¨®?3¨¬D¨°?¨¤¨ª?¦Ì?¦Ì??¡¤?????D?¡ê?a?¨´¦Ì¡Â¨º?¡ä¨²???¨ª¨¨Y¨°¡Á?¨¤¨¢??¡ê
?¨²?¡ä¡ä¨²???¡ê?¨¦¦Ì??£¤2????¨¢¡¤¡é??¡ê?I n j e c t L i b¨º¦Ì?¨º¨¦?¨º???¡¤?o?¡ê??¨´?Y??¡À¨¤¨°??¡ä¡ä¨²???¨´¨®?¦Ì?¡¤?¡¤¡§¡ê??¨¹?¨¦¨°??1?a?aI n j e c t L i b A?¨°I n j e c t L i b W?¡êo¡¥¨ºyI n j e c t L i b W?y¨º?¨°??D?¡ì¨¢|???¨´?¨²?¡ê3¨¬D¨°¦Ì?¡Á¡é¨º¨ª¡À?¨¦¨ª?¨ª?¦Ì?¡Â¨¢??¨º¨¬a¡ê?¦Ì¡À¨¨?¨°2?¨¦¨°???¨°?2?213??¦Ì?¡Â?¡ê2?1y????¡¤¡é??o¡¥¨ºyI n j e c t L i b A¡À¨¨???¨¬?¡ê?¨¹??¨º???ANSI DLL¦Ì??¡¤????¡Áa??3¨¦??¨®|¦Ì?U n i c o d e?¡¤????¡ê?¨¨?o¨®¦Ì¡Â¨®?I n j e c t L i b Wo¡¥¨ºy??DD¨º¦Ì?¨º¦Ì?2¨´¡Á¡Â?¡ê?a??¡¤?¡¤¡§?y¨º??¨°?¨²¦Ì¨²2???D?¡§¨°¨¦??¨º1¨®?¦Ì??¡ê?¨¹¨°2¨°a??¡Á???D¨¨¨°a¨º12?¨¨?¡ä¨²????DD¨°?¡ä??¨ªDD¨¢??¡ê
??¦Ì£¤22-2 InjLib¨º?¨¤y¨®|¨®?3¨¬D¨°
/******************************************************************************
Module: InjLib.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/
#include "..\CmnHdr.h" /* See Appendix A. */
#include <windowsx.h>
#include <stdio.h>
#include <tchar.h>
#include <malloc.h> // For alloca
#include <TlHelp32.h>
#include "Resource.h"
///////////////////////////////////////////////////////////////////////////////
#ifdef UNICODE
#define InjectLib InjectLibW
#define EjectLib EjectLibW
#else
#define InjectLib InjectLibA
#define EjectLib EjectLibA
#endif // !UNICODE
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile) {
BOOL fOk = FALSE; // Assume that the function fails
HANDLE hProcess = NULL, hThread = NULL;
PWSTR pszLibFileRemote = NULL;
__try {
// Get a handle for the target process.
hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | // Required by Alpha
PROCESS_CREATE_THREAD | // For CreateRemoteThread
PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx
PROCESS_VM_WRITE, // For WriteProcessMemory
FALSE, dwProcessId);
if (hProcess == NULL) __leave;
// Calculate the number of bytes needed for the DLL's pathname
int cch = 1 + lstrlenW(pszLibFile);
int cb = cch * sizeof(WCHAR);
// Allocate space in the remote process for the pathname
pszLibFileRemote = (PWSTR)
VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
if (pszLibFileRemote == NULL) __leave;
// Copy the DLL's pathname to the remote process's address space
if (!WriteProcessMemory(hProcess, pszLibFileRemote,
(PVOID) pszLibFile, cb, NULL)) __leave;
// Get the real address of LoadLibraryW in Kernel32.dll
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
if (pfnThreadRtn == NULL) __leave;
// Create a remote thread that calls LoadLibraryW(DLLPathname)
hThread = CreateRemoteThread(hProcess, NULL, 0,
pfnThreadRtn, pszLibFileRemote, 0, NULL);
if (hThread == NULL) __leave;
// Wait for the remote thread to terminate
WaitForSingleObject(hThread, INFINITE);
fOk = TRUE; // Everything executed successfully
}
__finally { // Now, we can clean everthing up
// Free the remote memory that contained the DLL's pathname
if (pszLibFileRemote != NULL)
VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
}
return(fOk);
}
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI InjectLibA(DWORD dwProcessId, PCSTR pszLibFile) {
// Allocate a (stack) buffer for the Unicode version of the pathname
PWSTR pszLibFileW = (PWSTR)
_alloca((lstrlenA(pszLibFile) + 1) * sizeof(WCHAR));
// Convert the ANSI pathname to its Unicode equivalent
wsprintfW(pszLibFileW, L"%S", pszLibFile);
// Call the Unicode version of the function to actually do the work.
return(InjectLibW(dwProcessId, pszLibFileW));
}
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI EjectLibW(DWORD dwProcessId, PCWSTR pszLibFile) {
BOOL fOk = FALSE; // Assume that the function fails
HANDLE hthSnapshot = NULL;
HANDLE hProcess = NULL, hThread = NULL;
__try {
// Grab a new snapshot of the process
hthSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
if (hthSnapshot == NULL) __leave;
// Get the HMODULE of the desired library
MODULEENTRY32W me = { sizeof(me) };
BOOL fFound = FALSE;
BOOL fMoreMods = Module32FirstW(hthSnapshot, &me);
for (; fMoreMods; fMoreMods = Module32NextW(hthSnapshot, &me)) {
fFound = (lstrcmpiW(me.szModule, pszLibFile) == 0) ||
(lstrcmpiW(me.szExePath, pszLibFile) == 0);
if (fFound) break;
}
if (!fFound) __leave;
// Get a handle for the target process.
hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | // Required by Alpha
PROCESS_CREATE_THREAD |
PROCESS_VM_OPERATION, // For CreateRemoteThread
FALSE, dwProcessId);
if (hProcess == NULL) __leave;
// Get the real address of LoadLibraryW in Kernel32.dll
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "FreeLibrary");
if (pfnThreadRtn == NULL) __leave;
// Create a remote thread that calls LoadLibraryW(DLLPathname)
hThread = CreateRemoteThread(hProcess, NULL, 0,
pfnThreadRtn, me.modBaseAddr, 0, NULL);
if (hThread == NULL) __leave;
// Wait for the remote thread to terminate
WaitForSingleObject(hThread, INFINITE);
fOk = TRUE; // Everything executed successfully
}
__finally { // Now we can clean everything up
if (hthSnapshot != NULL)
CloseHandle(hthSnapshot);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
}
return(fOk);
}
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI EjectLibA(DWORD dwProcessId, PCSTR pszLibFile) {
// Allocate a (stack) buffer for the Unicode version of the pathname
PWSTR pszLibFileW = (PWSTR)
_alloca((lstrlenA(pszLibFile) + 1) * sizeof(WCHAR));
// Convert the ANSI pathname to its Unicode equivalent
wsprintfW(pszLibFileW, L"%S", pszLibFile);
// Call the Unicode version of the function to actually do the work.
return(EjectLibW(dwProcessId, pszLibFileW));
}
///////////////////////////////////////////////////////////////////////////////
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) {
chSETDLGICONS(hwnd, IDI_INJLIB);
return(TRUE);
}
///////////////////////////////////////////////////////////////////////////////
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) {
switch (id) {
case IDCANCEL:
EndDialog(hwnd, id);
break;
case IDC_INJECT:
DWORD dwProcessId = GetDlgItemInt(hwnd, IDC_PROCESSID, NULL, FALSE);
if (dwProcessId == 0) {
// A process ID of 0 causes everything to take place in the
// local process; this makes things easier for debugging.
dwProcessId = GetCurrentProcessId();
}
TCHAR szLibFile[MAX_PATH];
GetModuleFileName(NULL, szLibFile, sizeof(szLibFile));
_tcscpy(_tcsrchr(szLibFile, TEXT('\\')) + 1, TEXT("22 ImgWalk.DLL"));
if (InjectLib(dwProcessId, szLibFile)) {
chVERIFY(EjectLib(dwProcessId, szLibFile));
chMB("DLL Injection/Ejection successful.");
} else {
chMB("DLL Injection/Ejection failed.");
}
break;
}
}
///////////////////////////////////////////////////////////////////////////////
INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand);
}
return(FALSE);
}
///////////////////////////////////////////////////////////////////////////////
int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) {
chWindows9xNotAllowed();
DialogBox(hinstExe, MAKEINTRESOURCE(IDD_INJLIB), NULL, Dlg_Proc);
return(0);
}
//////////////////////////////// End of File //////////////////////////////////
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_INJLIB ICON DISCARDABLE "InjLib.ico"
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_INJLIB DIALOG DISCARDABLE 15, 24, 158, 24
STYLE DS_3DLOOK | DS_CENTER | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION |
WS_SYSMENU
CAPTION "Inject Library Tester"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "&Process Id (decimal):",-1,4,6,69,8
EDITTEXT IDC_PROCESSID,78,4,36,12,ES_AUTOHSCROLL
DEFPUSHBUTTON "&Inject",IDC_INJECT,120,4,36,12,WS_GROUP
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_INJLIB, DIALOG
BEGIN
RIGHTMARGIN, 134
BOTTOMMARGIN, 20
END
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
??¦Ì£¤2 2 - 3¨¢D3?¦Ì?I m g Wa l k . d l l¨º???D L L¡ê?¨°?¦Ì??¨¹¡À?2?¨¨???3¨¬¦Ì?¦Ì??¡¤????¡ê??¨ª?¨¹1?¡À¡§??????3¨¬?y?¨²¨º1¨®?¦Ì??¨´¨®DD L L¡ê¡§??D L L¦Ì??¡ä¡ä¨²??o¨ª¡Á¨º?¡ä???t?¨´?¨²¡À?¨º¨¦?¨´??1a?¨¬¨¦?¦Ì?2 2 - I m g Wa l k??????¡ê??¡ê¨¤y¨¨?¡ê?¨¨?1??¨°¨º¡Á?¨¨??DDN o t e p a d¡ê?¨¨?o¨®??DDI n j L i b¡ê??a?¨¹¡ä?¦ÌYN o t e p a d¦Ì???3¨¬I D¡ê?I n j L i b??I m g Wa l k . d l l2?¨¨?N o t e p a d¦Ì?¦Ì??¡¤?????D?¡ê¨°?¦Ì???¨¨???¦Ì??¡¤????¡ê? I m g Wa l k¡À?¨¨¡¤?¡§N o t e p a d?y?¨²¨º1¨®???D????t¨®3??¡ê¡§?¨¦?¡äDD???to¨ªD L L¡ê?¡ê?2¡é?¨°??¨º?¨ª?2 2 - 5?¨´¨º?¦Ì????¡é?¨°¡ê??¨¹??¨º?¨¢?2¨¦?¨°¦Ì??¨¢1??¡ê
¨ª?22-5 2¨¦?¨°?¨¢1????¡ã?¨°
I m g Wa l k¡À¨¦¨¤¨²??3¨¬¦Ì?¦Ì??¡¤????¡ê?2¨¦?¨°¨°??-¨®3¨¦?¦Ì????t¨®3??¡ê?¡¤¡ä?¡ä¦Ì¡Â¨®?Vi r t u a l Q u e r yo¡¥¨ºy¡ê?¨¬?¨¨?¨°???M E M O RY_BASIC_ INFORMAT I O N?¨¢11?D?¡ê??¨®??-?¡¤¦Ì????????¡ä2¨´¡Á¡Â¡ê? I m g Wa l k?¨°3?¨°??????t?¡¤????¡ê?2¡é¨®?¨°???¡Á?¡¤?¡ä??¨¤¨¢??¨®?¡ê??¡Á?¡¤?¡ä???¨º??¨²???¡é?¨°?D?¡ê
char szBuf[MAX_PATH * 100] = { 0 };
PBYTE pb = NULL;
MEMORY_BASIC_INFORMATION mbi;
while(VirtualQuery(pb, &mbi, sizeof(mbi)) == sizeof(mbi))
{
int nLen;
char szModName[MAX_PATH];
if(mbi.State == MEM_FREE)
mbi.AllocationBase = mbi.BaseAddress;
if((mbi.AllocationBase == hinstDll) ||
(mbi.AllocationBase != mbi.BaseAddress) ||
(mbi.AllocationBase == NULL))
{
// Do not add the module name to the list
// if any of the following is true:
// 1. This region contains this DLL.
// 2. This block is NOT the beginning of a region.
// 3. The address is NULL.
nLen = 0;
}
else
{
nLen = GetModuleFileNameA((HINSTANCE) mbi.AllocationBase,
szModName, chDIMOF(szModName));
}
if(nLen > 0)
{
wsprintfA(strchr(szBuf, 0), "\n%08X-%s",
mbi.AllocationBase, szModName);
}
pb += mbi.RegionSize;
}
chMB(&szBuf[1]);??¦Ì£¤2 2 - 3 Im g Wa l k . d l l¦Ì??¡ä¡ä¨²??
/******************************************************************************
Module: ImgWalk.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/
#include "..\CmnHdr.h" /* See Appendix A. */
#include <tchar.h>
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, PVOID fImpLoad) {
if (fdwReason == DLL_PROCESS_ATTACH) {
char szBuf[MAX_PATH * 100] = { 0 };
PBYTE pb = NULL;
MEMORY_BASIC_INFORMATION mbi;
while (VirtualQuery(pb, &mbi, sizeof(mbi)) == sizeof(mbi)) {
int nLen;
char szModName[MAX_PATH];
if (mbi.State == MEM_FREE)
mbi.AllocationBase = mbi.BaseAddress;
if ((mbi.AllocationBase == hinstDll) ||
(mbi.AllocationBase != mbi.BaseAddress) ||
(mbi.AllocationBase == NULL)) {
// Do not add the module name to the list
// if any of the following is true:
// 1. If this region contains this DLL
// 2. If this block is NOT the beginning of a region
// 3. If the address is NULL
nLen = 0;
} else {
nLen = GetModuleFileNameA((HINSTANCE) mbi.AllocationBase,
szModName, chDIMOF(szModName));
}
if (nLen > 0) {
wsprintfA(strchr(szBuf, 0), "\n%p-%s",
mbi.AllocationBase, szModName);
}
pb += mbi.RegionSize;
}
chMB(&szBuf[1]);
}
return(TRUE);
}
//////////////////////////////// End of File //////////////////////////////////
2?¨¨?D L L¦Ì?¨¢¨ª¨°???¡¤?¡¤¡§¨º?¨¨?¡ä¨²???a¦Ì¨¤??3¨¬??¨°a?¨®??¦Ì?D L L?¡ê¨¤y¨¨?¡ê?¨¨?1????a¦Ì¨¤¨°?????3¨¬??¨°a?¨®??X y z . d l l¡ê??¨ª?¨¦¨°?¡ä¡ä?¡§??¡Á??o¦Ì?D L L¡ê??a?¨¹?3¨®¨¨?¨¤¨ª?¦Ì????t???¡ê¦Ì¡À¨¨?¡ê???¡À?D????-¨¤¡ä¦Ì?X y z . d l l???a¡Àe¦Ì?¨º2?¡ä??¡Á??¡ê
?¨²??¦Ì?X y z . d l l?D¡ê?¨º?3?¦Ì?¨¨?2?¡¤?o?¡À?D?¨®??-¨º?¦Ì?X y z . d l l¨º?3?¦Ì?¡¤?o??¨¤¨ª??¡ê¨º1¨®?o¡¥¨ºy¡Áa¡¤¡é?¡Â¡ê¡§¦Ì¨²2 0??¡Á?¨¢??¨¦¨¦¨¹¡ê?¡ê?o¨¹¨¨Y¨°¡Á¡Á?¦Ì??a¨°?¦Ì??¡ê??¨¨?o¡¥¨ºy¡Áa¡¤¡é?¡Â¨º1???¨¹1?¡¤?3¡ê¨¨Y¨°¡Á¦Ì?1¨°?¨®?3D?o¡¥¨ºy¡ê???¨®|??¡À¨¹?a¨º1¨®??a??¡¤?¡¤¡§¡ê?¨°¨°?a?¨¹2???¡À?¡ã?¡À?¨¦y???¨¹¨¢|?¡ê¨¤y¨¨?¡ê?¨¨?1???¨¨?¡ä¨²¨¢?¨°????¦Ì¨ª3D L L¡ê???M i c r o s o f t?¨²??¨¤¡ä???¨®¨¢?¨°?D?D?o¡¥¨ºy¡ê????¡ä??¦Ì?D L L??2???¡À??¨¹??¦Ì?o¡¥¨ºy¡Áa¡¤¡é?¡Â?¡ê¨°y¨®??aD?D?o¡¥¨ºy¦Ì?¨®|¨®?3¨¬D¨°???T¡¤¡§?¨®??o¨ª?¡äDD?¡ê
¨¨?1????????¨²¦Ì£¤??¨®|¨®?3¨¬D¨°?D¨º1¨®??a??¡¤?¡¤¡§¡ê????¡ä?¨¦¨°??a??¦Ì?D L L?3¨®¨¨¨°????¨¤¨°??T?t¦Ì???¡Á?¡ê?2¡é??¡À?¨®|¨®?3¨¬D¨°¦Ì?. e x e?¡ê?¨¦¦Ì?¨º?¨¨??¨²?¡ê?¨¹?a??¨°a¦Ì?¨º?¡ê?¨º?¨¨??¨²??¡ã¨¹o??¡ê?¨¦D¨¨¨°a¦Ì?D L L¦Ì???¡Á??¡ê???¨¦¨°?¡ÁD?????¡Â???t?D¦Ì??a??¨º?¨¨??¨²¡ê?2¡é?¨°???¨¹??¡À?¡ê?¨º1?¨®??3¨¬D¨°?¨®????¡Á??o¦Ì?D L L?¡ê?a??¡¤?¡¤¡§?¨¤¦Ì¡À2?¡ä¨ª¡ê?¦Ì?¨º?¡À?D?¨°a¡¤?3¡ê¨º¨¬?¡è. e x eo¨ªD L L???t¦Ì???¨º??¡ê
22.6 ??DLL¡Á¡Â?a¦Ì¡Â¨º?3¨¬D¨°¨¤¡ä2?¨¨?
¦Ì¡Â¨º?3¨¬D¨°?¨¹1???¡À?¦Ì¡Â¨º?¦Ì???3¨¬?¡äDD¨¬?¨ºa¦Ì?2¨´¡Á¡Â?¡ê¦Ì¡À¡À?¦Ì¡Â¨º???3¨¬?¨®??¨º¡À¡ê??¨²¡À?¦Ì¡Â¨º???3¨¬¦Ì?¦Ì??¡¤????¨°??-¡Á¡Âo?¡Á?¡À?¡ê?¦Ì?¨º?¡À?¦Ì¡Â¨º???3¨¬¦Ì??¡Â??3¨¬¨¦D?¡ä?¡äDD¨¨?o?¡ä¨²?????¡ã¡ê??¦Ì¨ª3??¡Á??¡¥???a???¨¦??¨ª¡§?a¦Ì¡Â¨º?3¨¬D¨°?¡ê?a¨º¡À¡ê?¦Ì¡Â¨º?3¨¬D¨°?¨¦¨°????????3D?¡ä¨²??2?¨¨?¡À?¦Ì¡Â¨º???3¨¬¦Ì?¦Ì??¡¤?????D¡ê¡§¡À¨¨¨¨?¨º1¨®?Wr i t e P r o c e s s M e m o r yo¡¥¨ºy¨¤¡ä2?¨¨?¡ê?¡ê?¨¨?o¨®¨º1¡À?¦Ì¡Â¨º???3¨¬¦Ì??¡Â??3¨¬?¡äDD??¡ä¨²???¡ê
?a??¡¤?¡¤¡§¨°a?¨®????¡À?¦Ì¡Â¨º???3¨¬¦Ì?C O N T E X T?¨¢11??DD2¨´¡Á¡Â¡ê?¨°a??¡Á?¡À?D?¡À¨¤D¡ä¨¬??¡§C P U¦Ì?¡ä¨²???¡ê¡À?D?DT????¦Ì??¡ä¡ä¨²??¡ê?¨º1???¨¹1??¨²2?¨ª?¦Ì?C P U??¨¬¡§¨¦??y¨¨¡¤¦Ì???DD?¡ê¨¢¨ª¨ªa¡ê?¡À?D???????¨¨?¡À?¦Ì¡Â¨º???3¨¬?¡äDD¦Ì??¨²?¡Â¨®?????¨¢???DD¨®2¡À¨¤???¡ê???¨°¦Ì¡Â¨º?3¨¬D¨°¨®??¨¹¦Ì?¡À?¦Ì¡Â¨º?3¨¬D¨°????¡À?D?¡ä??¨²1¨¬?¡§¦Ì?1??¦Ì?¡ê¨¨?1?¦Ì¡Â¨º?3¨¬D¨°???1??DD¡ê?Wi n d o w s??¡Á??¡¥3¡¤??¡À?¦Ì¡Â¨º???3¨¬?¡ê?????¨°?T¡¤¡§¡Á¨¨?1?¨¹?¡ê
22.7 ¨®?Windows 98¨¦?¦Ì??¨²¡ä?¨®3¨¦????t2?¨¨?¡ä¨²??
?¨²Windows 98 ¨¦?2?¨¨???¡Á??o¦Ì?¡ä¨²??¨º?¡¤?3¡ê?¨°¦Ì£¤¦Ì??¡ê?¨²Windows 98 ¨¦???DD¦Ì??¨´¨®D3 2??Wi n d o w s¨®|¨®?3¨¬D¨°?¨´12?¨ª¨ª??¨´¦Ì?¡Á?¨¦???¦Ì?2 GB¦Ì??¡¤?????¡ê¨¨?1???¡¤????a¨¤???¦Ì??3D?¡ä?¡ä¡é?¡Â¡ê????¡ä??¡ä?¡ä¡é?¡Â?¨²??????3¨¬¦Ì?¦Ì??¡¤?????D?¨´?¨¦¨º1¨®??¡ê¨¨?¨°a¡¤???2 GB¨°?¨¦?¦Ì?¡ä?¡ä¡é?¡Â¡ê???¨°a¨º1¨®??¨²¡ä?¨®3¨¦????t¡ê¡§¦Ì¨²1 7??¨°??-?¨¦¨¦¨¹¡ê??¡ê?¨¦¨°?¡ä¡ä?¡§¨°????¨²¡ä?¨®3¨¦????t¡ê?¨¨?o¨®¦Ì¡Â¨®?M a p Vi e w O f F i l eo¡¥¨ºy¡ê?¨º1?¨¹??¨º?3?¨¤¡ä?¡ê¨¨?o¨®??¨ºy?Y¨¬?¨¨???¦Ì?¦Ì??¡¤??????¨®¨°¡ê¡§?a¨º??¨´¨®D??3¨¬¦Ì??¡¤?????D¦Ì??¨¤¨ª???¨®¨°¡ê??¡ê¡À?D?¨º1¨®?¨®2¡À¨¤??¦Ì??¨²?¡Â¨®???¨¤¡ä??DD?a??2¨´¡Á¡Â¡ê????¨¢1?¨º??a???a??¡¤?¡ã?o¨¹??¨°??2¦Ì?¡Àe¦Ì?C P U??¨¬¡§?¡ê2?1y¡ê?¨¨?1???DD?a??2¨´¡Á¡Â¡ê????¡ä2?¡À?????2?¨ª?¦Ì?C P U??¨¬¡§¡ê?¨°¨°?aWindows 98???¨¹?¨²x86 CPU¨¦???DD?¡ê
?a??¡¤?¡¤¡§¦Ì?¨¤¡ì????¡ä|?¨²¨®¨²¨¨?¨¨?¡À?D?¨¨???????3¨¬?D¦Ì???3¨¬¨¤¡ä?¡äDD?¨²¡ä?¨®3¨¦????t?D¦Ì?¡ä¨²???¡ê¨°a¡Á?¦Ì??a¨°?¦Ì?¡ê?D¨¨¨°a?3??¡¤?¡¤¡§¨¤¡ä??????3¨¬??3¨¬?D¦Ì???3¨¬?¡êC r e a t e R e m o t e T h r e a do¡¥¨ºy?¨¹1?o¨¹o?¦Ì??¡äDD?a??¨¨???¡ê??¨¦?¡ìWindows 982??¡ì3???o¡¥¨ºy¦Ì???DD¡ê????¨°¨°2?T¡¤¡§¨¬¨¢1??¨¤¨®|¦Ì??a??¡¤?¡ã??¡ê
22.8 ¨®?CreateProcess2?¨¨?¡ä¨²??
¨¨?1???¦Ì???3¨¬¨¦¨²3¨¦¨¢?????2?¨¨?¡ä¨²??¦Ì?D???3¨¬¡ê????¡ä¨º??¨¦?¨ª?¨¢¡À?¦Ì?¨¦?¨¦?¨¨Y¨°¡Á¨°?D??¡ê?-¨°¨°??¨°?¨º?¡ê???¦Ì???3¨¬¡ê¡§????3¨¬¡ê??¨¹1?¡ä¡ä?¡§?Y¨ª¡ê??DD¦Ì?D???3¨¬?¡ê?a?¨ª¨º1???¨¹1???¡À?¡Á¨®??3¨¬¦Ì?¡Á¡ä¨¬?¡ê???2?¨®¡ã?¨¬?¨¹¦Ì???DD¡ê?¨°¨°?a?¨¹¨¦D?¡ä?a¨º???DD?¡ê¦Ì?¨º?????3¨¬¨°2?¨¹¦Ì?¦Ì?¡Á¨®??3¨¬¦Ì??¡Â??3¨¬¦Ì???¡À¨²?¡ê¨º1¨®?????¡À¨²¡ê??¨¦¨°?DT????3¨¬?¡äDD¦Ì?¡ä¨²???¡ê???¨¦¨°??a??¨¦?¨°??¨²¨¬¨¢¦Ì?¦Ì??¨º¨¬a¡ê?¨°¨°?a?¨¦¨°?¨¦¨¨????3¨¬¦Ì???¨¢?????¡ê?¨°?¡À??¡äDD?¨²¡ä?¨®3¨¦????t?D¦Ì?¡ä¨²???¡ê
?????¨¦¨¦¨¹¨°???¡¤?¡¤¡§¡ê??¨¹¨º1??¦Ì???3¨¬?¨¹1?????¡Á¨®??3¨¬¦Ì??¡Â??3¨¬?¡äDD¨º2?¡ä¡ä¨²??¡êo
1) ¨º1??¦Ì???3¨¬¨¦¨²3¨¦?Y¨ª¡ê??DD¦Ì?¡Á¨®??3¨¬?¡ê
2) ¡ä¨®. e x e?¡ê?¨¦¦Ì?¨ª¡¤???t?D?¨¬?¡Â?¡Â??3¨¬¦Ì??e¨º??¨²¡ä?¦Ì??¡¤?¡ê
3) ???¨²?¡Â??¨¢?¡À¡ê¡ä??¨²???¨²¡ä?¦Ì??¡¤?D?¡ê
4) ???3D?¨®2¡À¨¤??¦Ì??¨²?¡Â??¨¢?????¡¤?¨¨???¦Ì??¡¤?D?¡ê?aD???¨¢?¨®|??¦Ì¡Â¨®?L o a d L i b r a r yo¡¥¨ºy¨¤¡ä?¨®??D L L?¡ê
5) ?¨¬D???DD¡Á¨®??3¨¬¦Ì??¡Â??3¨¬¡ê?¨º1??¡ä¨²??¦Ì?¨°??¡äDD?¡ê
6) ???-¨º???¨¢???D?¡¤?¨¨??e¨º?¦Ì??¡¤?¡ê
7) ¨¨???3¨¬?¨¬D?¡ä¨®?e¨º?¦Ì??¡¤?a¨º??¡äDD¡ê??¨ª????¨®D¡¤¡é¨¦¨²¨¨?o?¨º??¨¦¨°??¨´?¡ê
¨¦???¦Ì?2??¨¨6o¨ª7¨°a?y¨¨¡¤??DD¨º?o¨¹¨¤¡ì??¦Ì?¡ê?¨°¨°?a??¡À?D?DT??¦Ì¡À?¡ã?y?¨²?¡äDD¦Ì?¡ä¨²???¡ê2?1y?a¨º??¨¦?¨¹¦Ì??¡ê
?a??¡¤?¡¤¡§??¨®DD¨ª?¨¤¨®?¦Ì??¡ê¨º¡Á?¨¨¡ê??¨¹?¨²¨®|¨®?3¨¬D¨°?¡äDD???¡ã?¨ª?¨¹¦Ì?¦Ì?¦Ì??¡¤?????¡ê¦Ì¨²?t¡ê??¨¹?¨¨?¨¹?¨²Windows 98¨¦?¨º1¨®?¡ê?¨°2?¨¹?¨²Windows 2000¨¦?¨º1¨®??¡ê¦Ì¨²¨¨y¡ê?¨®¨¦¨®¨²??2?¨º?¦Ì¡Â¨º???¡ê?¨°¨°¡ä??¨¹1?o¨¹¨¨Y¨°¡Á¨º1¨®?2?¨¨?¦Ì?D L L¨¤¡ä¦Ì¡Â¨º?¨®|¨®?3¨¬D¨°?¡ê¡Á?o¨®¡ê??a??¡¤?¡¤¡§?¨¦¨°?¨ª?¨º¡À¨®?¨®¨²????¨¬¡§o¨ªG U I¨®|¨®?3¨¬D¨°?¡ê
¦Ì¡À¨¨?¡ê??a??¡¤?¡¤¡§¨°2¨®D?3D?2?¡Á??¡ê??¨®D¦Ì¡À??¦Ì?¡ä¨²??¨º?????3¨¬¨º¡À¡ê?2??¨¹2?¨¨?D L L?¡ê¨¢¨ª¨ªa¡ê??a??¡¤?¡¤¡§¦Ì¡À¨¨?2??¨¹????2?¨ª?¦Ì?C P U¨¤¡ä??DD¡ê?¡À?D???2?¨ª?¦Ì?C P U??¨¬¡§??DD?¨¤¨®|¦Ì?DT???¡ê
??D L L2?¨¨???3¨¬¦Ì?¦Ì??¡¤????¨º?¨¨¡¤?¡§??3¨¬??DD¡Á¡ä??¦Ì?¨°???o¨¹o?¦Ì?¡¤?¡¤¡§?¡ê¦Ì?¨º?¡ê?????2?¨¨?D L L?T¡¤¡§¨¬¨¢1?¡Á?1?¦Ì?D??¡é¡ê?¨¨???3¡ê3¡êD¨¨¨°a?a¦Ì¨¤?3????3¨¬?D¦Ì???3¨¬???1¨º?¨¨?o?¦Ì¡Â¨®??¡Â??o¡¥¨ºy¦Ì?¡ê?¨°2?¨¦?¨¹D¨¨¨°aDT??Wi n d o w so¡¥¨ºy¦Ì?1|?¨¹?¡ê
¨¤y¨¨?¡ê??¨°?a¦Ì¨¤¨°??¨°1???¨¦¨²2¨²¦Ì?D L L¨º?¨®¨¦¨°???¨ºy?Y?a2¨²?¡¤¨¤¡ä?¨®??¦Ì??¡ê??D L L¦Ì?¡Á¡Â¨®?¨º?????o¨ª¨¤??1¨ºy?Y?a2¨²?¡¤¦Ì?1|?¨¹?¡ê¦Ì¡À¨ºy?Y?a2¨²?¡¤???1??DD¨º¡À¡ê???D L L?¨ª?¨¢¨º?¦Ì?¨°???D L L _ P R O C E S S_ D E TA C H¨ª¡§?a¡ê?2¡é?¨°??¨®D?¨²?a¨º¡À¡ê??¨¹2??¡äDD?¨¹¦Ì??¨´¨®D??3y¡ä¨²???¡ê??D L L??¦Ì¡Â¨®?????D L L?D¦Ì?o¡¥¨ºy¡ê?¨°?¡À?1?¡À?¨¬¡Á?¨®¡Á?¨¢??¨®?¡é???to¨ª????¡Á¨º?¡ä¡ê?¦Ì?¨º?¦Ì¡À?¨¹¨º?¦Ì?D L L _ P R O C E S S _ D E TA C H¨ª¡§?a¨º¡À¡ê???3¨¬¦Ì?¦Ì??¡¤?????D¦Ì?????D L L¨°??-¨º?¦Ì??¨¹??¦Ì?D L L _ P R O C E S S _ D E TA C H¨ª¡§?a?¡ê¨°¨°¡ä?¡ê?¦Ì¡À??1???¦Ì?D L L¨º?¨ª???3y¨º¡À¡ê??¨¹¦Ì¡Â¨®?¦Ì?D¨ª?¨¤o¡¥¨ºy¦Ì???DD???¨¢¨º¡ì¡ã¨¹¡ê?¨°¨°?a????D L L¨°??-3¡¤??¨¢?3?¨º??¡¥D??¡é?¡ê
??1????????¨°¨¨£¤¡ã??¨²?????a???a???¨º¨¬a¡ê??¨°?¡§¨°¨¦1¨°?¨®o¡¥¨ºyE x i t P r o c e s s?¡ê¨¨????¨´?a¡ê?¦Ì¡Â¨®?E x i t P r o c e s s??¦Ì????¦Ì¨ª3?¨°??D L L¡¤¡é?¨ªD L L _ P R O C E S S _ D E TA C H¨ª¡§?a?¡ê¨ª¡§1y1¨°?¨®E x i t P r e c e s so¡¥¨ºy¡ê??¨°???¨ª?¨¹¨¨¡¤¡À¡ê¦Ì¡ÀE x i t P r o c e s so¡¥¨ºy¡À?¦Ì¡Â¨®?¨º¡À¡ê???1???¦Ì?D L L?¨¹1?¦Ì?¦Ì?¨ª¡§?a?¡ê?a??¨ª¡§?a???¨²¨¨?o?D L L¦Ì?¦Ì?D L L _ P R O C E S S _ D E TA C H¨ª¡§?a???¡ã??¨¤¡ä¡ê?¨°¨°¡ä???3¨¬?D¦Ì??¨´¨®DD L L¨¨?¨¨?¡ä|¨®¨²3?¨º??¡¥¡Á¡ä¨¬??D¡ê?2¡é?¨°?¨¹1??y3¡ê??DD?¡ê¡ä?¨º¡À¡ê???1???¦Ì?D L L?a¦Ì¨¤??3¨¬??¨°a???1??DD¡ê?2¡é?¨°?¨¹1?3¨¦1|¦Ì??¡äDD?¨¹¦Ì?¨¨?2???3y2¨´¡Á¡Â?¡ê¨¨?o¨®¡ê?2¨´¡Á¡Â?¦Ì¨ª3¦Ì?E x i t P r o c e s so¡¥¨ºy¡À?¦Ì¡Â¨®?¡ê?¨º1?¨´¨®DD L L¨º?¦Ì??¨¹??¦Ì?D L L _ P R O C E S S _ D E TA C H¨ª¡§?a2¡é??DD??3y2¨´¡Á¡Â?¡ê¦Ì¡À??1???¦Ì?D L L¨º?¦Ì??a??¨ª¡§?a¨º¡À¡ê??¨¹??2??¡äDD¡Á¡§??¦Ì???3y2¨´¡Á¡Â¡ê?¨°¨°?a?¨¹¨°??-¡Á?¨¢??¨¹¡À?D?¡Á?¦Ì?¨º??¨¦?¡ê
?¨²?a??¨¤y¡Á¨®?D¡ê?2?¨¨?D L L¨º??¨¦¨°???¨°a??DD¦Ì?¡ê?¨°¨°?a¨ºy?Y?a¨®|¨®?3¨¬D¨°¦Ì?¨¦¨¨??¨°??-?¨ºD¨ª??DD?a?¨´¦Ì?2?¨¨?¡ê?2¡é?¨°?¨¹?¨®??¨¢?1???¦Ì?D L L?¡ê¦Ì¡À??1???¦Ì?D L L¡À??¨®??¨º¡À¡ê??¨¹¡À?D?¨¦¡§?¨¨?¨´¨®D¨°??-?¨®??¦Ì??¨¦?¡äDD?¡ê?¨¦o¨ªD L L?¡ê?¨¦¡ê?¨°?¡À??¨°3???E x i t P r o c e s s¦Ì?¦Ì¡Â¨®??¡ê¦Ì¡À?¨¹¡¤¡é????E x i t P r o c e s s¦Ì?¦Ì¡Â¨®?o¨®¡ê?D L L¡À?D?DT???aD??¡ê?¨¦¡ê??a?¨´¡ê??aD??¡ê?¨¦?¨ª?¨¹¦Ì¡Â¨®?1???¦Ì?D L L?D¦Ì?o¡¥¨ºy¡ê???2?¨º?¦Ì¡Â¨®?2¨´¡Á¡Â?¦Ì¨ª3¦Ì?E x i t P r o c e s so¡¥¨ºy¡ê¡§?a??1y3¨¬¡À¨¨???¨®¦Ì??¨¦??¨°a?¨°¦Ì£¤¦Ì??¨¤¡ê??¡ê¨°?¦Ì?1???¦Ì?E x i t P r o c e s s¨¬???o¡¥¨ºy¡ê¡§?¡ä¨ª¡§3¡ê?¨´?¦Ì¦Ì?1¨°13o¡¥¨ºy¡ê??¡äDD?¨¹¦Ì???3y¡ä¨²??¡ê?2¨´¡Á¡Â?¦Ì¨ª3¦Ì?E x i t P r o c e s so¡¥¨ºy¡ê¡§?¨²K e r n e l 3 2 . d l l???t?D¡ê??¨ª¡À?¦Ì¡Â¨®??¡ê
?a??¨¤y¡Á¨®??¨º?¨¢?1¨°?¨®A P I¦Ì?¨°???¦Ì?D¨ª¨®?¡¤¡§?¡ê?¨¹¨®?o¨¹¨¦¨´¦Ì?¡ä¨²???a??¨¢?¨°???¡¤?3¡ê¨º¦Ì?¨º¦Ì??¨º¨¬a?¡ê
22.9.1 ¨ª¡§1y??D¡ä¡ä¨²??¨¤¡ä1¨°?¨®API
A P I1¨°?¨®2¡é2?¨º?¨°???D???¨º?¡ê??¨¤?¨º¨¤¡ä¡À¨¤3¨¬¨¨??¡À¨°??¡À?¨²¨º1¨®?A P I1¨°?¨®¡¤?¡¤¡§?¡ê¨¨?1?¨°a?a??¨¦????¨´?¦Ì¦Ì??¨º¨¬a¡ê????¡ä¨¨???¨º¡Á?¨¨?¡ä¦Ì?¦Ì??¡ã?a??¡¤?¡ã??¡À¨º?¨ª¡§1y??D¡ä¡ä¨²??¨¤¡ä??DD1¨°?¨®?¡ê????¨º???¨¬?¦Ì?2¨´¡Á¡Â¡¤?¡¤¡§¡êo
1) ?¨°¦Ì?????1¨°?¨®¦Ì?o¡¥¨ºy?¨²?¨²¡ä??D¦Ì?¦Ì??¡¤¡ê¡§¡À¨¨¨¨??¦ÌK e r n e l 3 2 . d l l?D¦Ì?E x i t P r o c e s s¡ê??¡ê
2) ????o¡¥¨ºy¦Ì?¨ª¡¤????¡Á??¨²¡À¡ê¡ä??¨²??¡Á??o¦Ì??¨²¡ä??D?¡ê
3) ¨®?¨°???JUMP CPU??¨¢???D¡ä??o¡¥¨ºy¦Ì?¨ª¡¤????¡Á??¨²¡ê?????¨¢??¨¢¡Áa¨°?¦Ì???¦Ì?¨¬???o¡¥¨ºy¦Ì??¨²¡ä?¦Ì??¡¤?¡ê¦Ì¡À¨¨?¡ê???¦Ì?¨¬???o¡¥¨ºy¦Ì?¡À¨º??¡À?D?¨®???1¨°?¨®¦Ì?o¡¥¨ºy¦Ì?¡À¨º??¨ª¨º¨¨??¨¤¨ª?¡ê??¡ä?¨´¨®D¦Ì?2?¨ºy¡À?D?¨°??¨´¡ê?¡¤¦Ì???¦Ì¡À?D?¨°??¨´¡ê?¦Ì¡Â¨®?1??¨°¡À?D?¨°??¨´?¡ê
4) ???¨²¡ê?¦Ì¡À¨°?????3¨¬¦Ì¡Â¨®?¨°??-1¨°?¨®¦Ì?o¡¥¨ºy¨º¡À¡ê? J U M P??¨¢?¨º¦Ì?¨º¨¦???¡Áa¨°?¦Ì???¦Ì?¨¬???o¡¥¨ºy?¡ê?a¨º¡À¡ê????¨ª?¨¹1??¡äDD¨¨?o?¡ä¨²???¡ê
5) ¨¨???o¡¥¨ºy¦Ì?1¨°?¨®¡Á¡ä¨¬?¡ê?¡¤?¡¤¡§¨º?¨¨?3?¡ê¡§¦Ì¨²?t2?¡ê?¡À¡ê¡ä?¦Ì?¡Á??¨²¡ê????¨¹??¡¤???1¨°?¨®o¡¥¨ºy¦Ì??a¨ª¡¤?¡ê
6) ¦Ì¡Â¨®?1¨°?¨®¦Ì?o¡¥¨ºy¡ê¡§?¨¹¨°?2??¨´¡À?1¨°?¨®¡ê?¡ê???o¡¥¨ºy???¡äDD??¨ª¡§3¡ê¦Ì?¡ä|¨¤¨ª2¨´¡Á¡Â?¡ê
7) ¦Ì¡À?-¨º?o¡¥¨ºy¡¤¦Ì??¨º¡À¡ê??¨´¡ä??¡äDD¦Ì¨²?to¨ª¦Ì¨²¨¨y2?¡ê??a?¨´??¦Ì?¨¬???o¡¥¨ºy?¨ª?¨¦¨°?¡À?¦Ì¡Â¨®??¡ê
?a??¡¤?¡¤¡§?¨²1 6??Wi n d o w s¡À¨¤3¨¬?¡À?D¨º1¨®?¦Ì?¡¤?3¡ê??¡À¨¦¡ê?2¡é?¨°¨®?¦Ì?o¨¹o??¡ê??¨¬¨¬¡ê??a??¡¤?¡¤¡§¡ä??¨²¡Á?¨¨??¨¦¡¤?3¡ê????¦Ì?2?¡Á?¡ê?¨°¨°¡ä??¡§¨°¨¦??¨¢?¡À¨¹?a¨º1¨®??¨¹?¡ê¨º¡Á?¨¨¡ê??¨¹??C P U¦Ì?¨°¨¤¨¤¦ÌD?o¨¹¡ä¨®¡ê??¨²x 8 6?¡éA l p h ao¨ª????¦Ì?C P U¨¦?¦Ì?J U M P??¨¢?¨º?2?¨ª?¦Ì?¡ê?¡À?D?¨º1¨®?¨º?1¡è¡À¨¤??¦Ì??¨²?¡Â??¨¢?2??¨¹¨º1?a??¡¤?¡¤¡§¨¦¨²D¡ì?¡ê¦Ì¨²?t¡ê??a??¡¤?¡¤¡§?¨²?¨¤??¨º??¨¤??3¨¬?¡¤?3?D?¨´¡À?2??e¡Á¡Â¨®??¡ê??3¨¬D¨¨¨°a??¨®?¨°??¡§¦Ì?¨º¡À??¨¤¡ä??D¡äo¡¥¨ºy?a¨ª¡¤¦Ì?¡ä¨²???¡ê¦Ì¡À¡ä¨²??¡À???D¡ä¨º¡À¡ê?¨¢¨ª¨°?????3¨¬?¨¦?¨¹¨º?¨ª?¦Ì¡Â¨®???¨ª?¨°???o¡¥¨ºy?¡ê?¨¢1???¨º?????D?¦Ì??¡ê¨°¨°¡ä?¡ê???¨®D¦Ì¡À???a¦Ì¨¤?¨²1??¡§¦Ì?¨º¡À????¨®D¨°?????3¨¬¨º?¨ª?¦Ì¡Â¨®??3??o¡¥¨ºy¨º¡À¡ê?2??¨¹¨º1¨®??a??¡¤?¡¤¡§?¡ê
?¨²Windows 98¨¦?¡ê??¡Â¨°a¦Ì?Windows DLL¡ê¡§K e r n e l 3 2?¡éA d v A P I 3 2?¡éU s e r 3 2o¨ªG D I 3 2¡ê?¨º??a?¨´¨º¨¹¦Ì?¡À¡ê?¡è¦Ì?¡ê??¡ä¨®|¨®?3¨¬D¨°2??¨¹??D¡ä?¨¹??¦Ì?¡ä¨²??¨°3???¡ê¨ª¡§1y¡À¨¤D¡äD¨¦?a¨¦¨¨¡À??y?¡¥3¨¬D¨°¡ê¡§V x D¡ê?2??¨¹1???¦Ì??a??¡À¡ê?¡è?¡ê
22.9.2 ¨ª¡§1y2¨´¡Á¡Â?¡ê?¨¦¦Ì?¨º?¨¨??¨²¨¤¡ä1¨°?¨®API
¨¢¨ª¨°???A P I1¨°?¨®¡¤?¡¤¡§?¨¹1??a???¨°?¡ã???2¦Ì?¦Ì?¨¢????¨º¨¬a?¡ê?a??¡¤?¡¤¡§¨º¦Ì???e¨¤¡äo¨¹¨¨Y¨°¡Á¡ê?2¡é?¨°?¨¤¦Ì¡À??¡Á3?¡ê¦Ì?¨º?¡ê?¨°a¨¤¨ª?a?a??¡¤?¡¤¡§¡ê?¡À?D???¦Ì??¡¥¨¬?¨¢??¨®¨º?¨¨?o?1¡è¡Á¡Â¦Ì??¡ê¨®¨¨??¡À?D???¦Ì??¡ê?¨¦¦Ì?¨º?¨¨??¨²?D¡À¡ê?¡è¦Ì?¨º?¨º2?¡äD??¡é?¡ê¦Ì¨²1 9??¨°??-¨®?¨¢????¨¤¦Ì??a¡¤¨´?¨¦¨¦¨¹¨¢?¨º?¨¨??¨²¨º?¨¨?o?¨¦¨²3¨¦¦Ì?¨°??¡ã?¨¹¡ã¨¹o?¦Ì??¨²¨¨Y?¡ê¦Ì¡À???¨¢????¦Ì??¨²¨¨Y¨º¡À¡ê??¨¦¨°???¨ª¡¤2???¦Ì¨²1 9??¦Ì?¨®D1??¦Ì?¡Â?¡ê
¨¨????¨´?a¡ê??¡ê?¨¦¦Ì?¨º?¨¨??¨²¡ã¨¹o?¨°?¡Á¨¦???¡ê?¨¦??DD¨º¡ÀD¨¨¨°a¦Ì?D L L?¡ê¨¢¨ª¨ªa¡ê??¨¹?1¡ã¨¹o????¡ê?¨¦¡ä¨®????D L L¨º?¨¨?¦Ì?¡¤?o?¦Ì?¨¢D¡À¨ª?¡ê¦Ì¡À?¡ê?¨¦¦Ì¡Â¨®?¨°???¨º?¨¨?o¡¥¨ºy¨º¡À¡ê???3¨¬¨º¦Ì?¨º¨¦?¨°a¡ä¨®?¡ê?¨¦¦Ì?¨º?¨¨??¨²?D2???D¨¨¨°a¦Ì?¨º?¨¨?o¡¥¨ºy¦Ì?¦Ì??¡¤¡ê?¨¨?o¨®¡Áa¨°?¦Ì???¦Ì??¡¤?¡ê
¨°a1¨°?¨®¨°???¨¬??¡§¦Ì?o¡¥¨ºy¡ê???D¨¨¨°a??¡À??¡ê?¨¦¦Ì?¨º?¨¨??¨²?D¦Ì?¦Ì??¡¤¡ê??¨ª?a?¡ä?¨°¦Ì£¤?¡ê?¨¹2?¡ä??¨²¨°¨¤¨¤¦ÌC P U¦Ì??¨º¨¬a?¡ê¨ª?¨º¡À¡ê?¨®¨¦¨®¨²DT??¨¢?o¡¥¨ºy¦Ì?¡ä¨²??¡ê?¨°¨°¡ä?2?D¨¨¨°a¦Ì¡êD???3¨¬¦Ì?¨ª?2??¨º¨¬a?¡ê
?????a??o¡¥¨ºy?¨ª?o?e?¡äDD?a????¨°a¦Ì?2¨´¡Á¡Â?¡ê?¨¹?¨®¨º¨¹¨°????¡ê?¨¦¦Ì?¨º?¨¨??¨²¡ê?¨°?¡À?¨°y¨®?¨¬??¡§¦Ì??¡¤¨¦?¦Ì?¨°???¡¤?o??¡ê¨¨?1?¡ä??¨²?a?¨´¦Ì?¨°y¨®?¡ê????¡ä?¨¹?¨ª??¡À???¡¤?o?¦Ì?¦Ì??¡¤?¡ê
void ReplaceIATEntryInOneMod(PCSTR pszCalleeModName,
PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller)
{
ULONG ulSize;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)
ImageDirectoryEntryToData(hmodCaller, TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);
if(pImportDesc == NULL)
return; // This module has no import section.
//Find the import descriptor containing references
//to callee's functions.
for(; pImportDesc->Name; pImportDesc++)
{
PSTR pszModName = (PSTR)
((PBYTE) hmodCaller + pImportDesc->Name);
if(lstrcmpiA(pszModName, pszCalleeModName) == 0)
break;
}
if(pImportDesc->Name == 0)
// This module doesn't import any functions from this callee.
return;
//Get caller's import address table (IAT)
//for the callee's functions.
PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)
((PBYTE) hmodCaller + pImportDesc->FirstThunk);
//Replace current function address with new function address.
for(; pThunk->u1.Function; pThunk++)
{
// Get the address of the function address.
PROC* ppfn = (PROC*) &pThunk->u1.Function;
// Is this the function we're looking for?
BOOL fFound = (*ppfn == pfnCurrent);
// See the sample code for some tricky Windows 98
// stuff that goes here.
if(fFound)
{
//The addresses match; change the import section address.
WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew,
sizeof(pfnNew), NULL);
return; // We did it; get out.
}
}
//If we get to here, the function
//is not in the caller's import section.
}
PROC pfnOrig = GetProcAddress(GetModuleHandle("Kernel32"),
"ExitProcess");
HMODULE hmodCaller = GetModuleHandle("DataBase.exe");
void ReplaceIATEntryInOneMod(
"Kernel32.dll", // Module containing the function (ANSI)
pfnOrig, // Address of function in callee
MyExitProcess, // Address of new function to be called
hmodCaller); // Handle of module that should call the new function¨¨?1?D a t a B a s e . e x e¨®D¨°???¨º?¨¨??¨²¡ê????¡äI m a g e D i r e c t o r y E n t r y To D a t a?¨ª¡¤¦Ì????¨º?¨¨??¨²¦Ì?¦Ì??¡¤¡ê???¦Ì??¡¤¨º?¨°???¨¤¨¤D¨ª?aP I M A G E _ I M P O RT _ D E S C R I P TO R¦Ì??????¡ê???¨²?¨°??¡À?D?2¨¦?¡ä???¡ê?¨¦¦Ì?¨º?¨¨??¨²¡ê??¨°3?¡ã¨¹o??¨°????¨°aDT??¦Ì?¨º?¨¨?o¡¥¨ºy¦Ì?D L L?¡ê?¨²?a??¨¤y¡Á¨®?D¡ê??¨°??2¨¦?¨°¡ä¨®?¡ã K e r n e l 3 2 . d l l?¡À¨º?¨¨?¦Ì?¡¤?o?¡ê¡§?a¨º?¡ä?¦ÌY??R e p l a c e I AT E n t r y I n O n e M o do¡¥¨ºy¦Ì?¦Ì¨²¨°???2?¨ºy¡ê??¡êf o r?-?¡¤?o?e¨¦¡§?¨¨D L L?¡ê?¨¦¦Ì???¡Á??¡ê¡Á¡é¨°a¡ê??¡ê?¨¦¦Ì?¨º?¨¨??¨²?D¦Ì??¨´¨®D¡Á?¡¤?¡ä???¨º?¨®?A N S I¡ê¡§??2??¨¹¨®?U n i c o d e¡ê?¡À¨¤D¡ä?¡ê?a?¨ª¨º??a¨º2?¡ä¨°a??¨º?¦Ì¡Â¨®?l s t r c m p i A??2?¨º?l s t r c m p io¨º¦Ì??-¨°¨°?¡ê
¨¨?1????-?¡¤???1??DD¡ê?¦Ì?¨º???¨®D?¨°¦Ì????¡ã K e r n e l 3 2 . d l l?¡À?D¦Ì?¨¨?o?¡¤?o?¦Ì?¨°y¨®?¡ê????¡ä??o¡¥¨ºy?¨ª¡¤¦Ì??¡ê?2¡é?¨°¨¨?¨¨??T?¨´¨º?¨º??¡ê¨¨?1??¡ê?¨¦¦Ì?¨º?¨¨??¨²¨¨¡¤¨º¦Ì¨°y¨®?¨¢??¡ã K e r n e l 3 2 . d l l?¡À?D¦Ì?¡¤?o?¡ê????¡ä??¦Ì?¦Ì?¡ã¨¹o?¨º?¨¨?¡¤?o?D??¡é¦Ì?I M A G E _ T H U N K _ D ATA?¨¢11¦Ì?¨ºy¡Á¨¦¦Ì?¦Ì??¡¤?¡ê¨¨?o¨®¡ê????¡ä¨°y¨®?¨¤¡ä¡Á??¡ãK e r n e l 3 2 . d l l?¡À¦Ì??¨´¨®D¨º?¨¨?¡¤?o?¡ê??¡ã?¨°¨®?¡¤?o?¦Ì?¦Ì¡À?¡ã¦Ì??¡¤?¨¤?£¤??¦Ì?¦Ì??¡¤?¡ê?¨²?¨°??¦Ì?¨¤y¡Á¨®?D¡ê??¨°???¡ã?¨°¦Ì?¨º?¨®?E x i t P r o c e s so¡¥¨ºy¦Ì?¦Ì??¡¤?¨¤?£¤??¦Ì?¦Ì??¡¤?¡ê
¨¨?1???¨®D¨®??¨°???¡ã?¨°¦Ì?¦Ì??¡¤?¨¤?£¤??¦Ì?¦Ì??¡¤¡ê????¡ä?a??¡¤?¡¤¡§??2??¨¹¨º?¨¨?D¨¨¨°a¦Ì?¦Ì?¡¤?o?¡ê???R e p l a c e I AT E n t r y I n O n e M o d o¡¥¨ºy?¨°¡¤¦Ì???¡ê¨¨?1??¨°¦Ì?¨¢?¨°????£¤??¦Ì?¦Ì??¡¤¡ê?¡À?¦Ì¡Â¨®?Wr i t e P r o c e s s M e m o r yo¡¥¨ºy¡ê?¨°?¡À???¡À?¨¬???o¡¥¨ºy¦Ì?¦Ì??¡¤?¡ê¨º1¨®?Wr i t e P r o c e s s M e m o r yo¡¥¨ºy¡ê???2?¨º?I n t e r l o c k e d E x c h a n g e P o i n t e ro¡¥¨ºy¨º?¨°¨°?aWr i t e P r o c e s s M e m o r y?¨¹1???¡À?¡Á??¨²¡ê???2?1¨¹?aD?¡Á??¨²¨®¦Ì¨®D¨º2?¡ä¨°3??¡À¡ê?¡è¨º?D??¡ê¨¤y¨¨?¡ê?¨¨?1?¨°3??¨®¦Ì¨®DPA G E _ R E A D O N LY¡À¡ê?¡è¨º?D?¡ê????¡äI n t e r l o c k e dE x c h a n g e P o i n t e ro¡¥¨ºy???¨¢¨°y¡¤¡é¡¤??¨º?£¤1?¡ê???Wr i t e P r o c e s s M e m o r yo¡¥¨ºy?¨°?¨¹1?¡ä|¨¤¨ª¨°3??¡À¡ê?¡è¨º?D?¦Ì??¨´¨®D¡À??¨¹¡ê?2¡é?¨°¨¨?¨¨??¨¹1??y3¡ê??DD?¡ê
¡ä¨®???¨²?e¡ê?¦Ì¡À¨¨?o???3¨¬?¡äDDD a t a B a s e . e x e?¡ê?¨¦?D¦Ì¡Â¨®?E x i t P r o c e s s¦Ì?¡ä¨²??¨º¡À¡ê??¨ª?¨¹1?o¨¹¨¨Y¨°¡Á¦Ì?¦Ì?K e r n e l 3 2 . d l l?D¦Ì?E x i t P r o c e s so¡¥¨ºy¦Ì?¨º¦Ì¦Ì??¡¤¡ê?2¡é?¨²?¨°????¨°a??DD¨ª¡§3¡ê¦Ì?E x i t P r o c e s s¡ä|¨¤¨ª¨º¡À¦Ì¡Â¨®??¨¹?¡ê
¡Á¡é¨°a¡ê?R e p l a c e I AT E n t r y I n O n e M o do¡¥¨ºy?¨¹1???¡À?¨®¨¦¦Ì£¤???¡ê?¨¦?D¦Ì?¡ä¨²????DD¦Ì?o¡¥¨ºy¦Ì¡Â¨®??¡ê¦Ì?¨º?¡ê?¨¢¨ª¨°???D L L?¨¦?¨¹??¨®¨²??¦Ì??¡¤?????D¡ê?????D L L¨°2?¨¦?¨¹¦Ì¡Â¨®?E x i t P r o c e s s?¡ê¨¨?1?D a t a B a s e . e x e??¨ªa¦Ì?¨°????¡ê?¨¦¨º?¨ª?¦Ì¡Â¨®?E x i t P r o c e s s¡ê????¡ä?¨²¦Ì¡Â¨®?K e r n e l 3 2 . d l l?D¦Ì?E x i t P r o c e s s¨º¡À¡ê??¨¹¦Ì?¦Ì¡Â¨®????¨¢3¨¦1|?¡ê
¨¨?1???¨°a2???¡ä¨®?¨´¨®D?¡ê?¨¦??E x i t P r o c e s s??DD¦Ì??¨´¨®D¦Ì¡Â¨®?¡ê?¡À?D??a?¨®??¦Ì???3¨¬¦Ì?¦Ì??¡¤?????D¦Ì??????¡ê?¨¦??DD¨°?¡ä???R e p l a c e I AT E n t r y I n O n e M o do¡¥¨ºy¦Ì?¦Ì¡Â¨®??¡ê?a¡ä?¡ê??¨°¡À¨¤D¡ä¨¢?¨¢¨ª¨°???o¡¥¨ºy¡ê?3??aR e p l a c e I AT E n t r y I n A l l M o d s?¡ê??o¡¥¨ºy????¨º1¨®?To o l H e l po¡¥¨ºy¨¤¡ä???¨´?¨®??¦Ì???3¨¬¦Ì?¦Ì??¡¤?????D¦Ì??¨´¨®D?¡ê?¨¦¡ê?¨¨?o¨®?a?????¡ê?¨¦¦Ì¡Â¨®?R e p l a c e I AT E n t r y I n O n e M o d¡ê?2¡é?a¡Á?o¨®¨°???2?¨ºy¡ä?¦ÌY?¨¤¨®|¦Ì??¡ê?¨¦??¡À¨²?¡ê
?¨²¨¦¨´¨ºy????¦Ì?¡¤??¨¦?¨¹¡¤¡é¨¦¨²¨°?D??¨º¨¬a?¡ê¨¤y¨¨?¡ê?¨¨?1??¨²¦Ì¡Â¨®?R e p l a c e I AT E n t r y I n A l l M o d so¨®¡ê???3¨¬¨®?¦Ì¡Â¨®?L o a d L i b r a r yo¡¥¨ºy¨¤¡ä?¨®??D?D L L¡ê????¨¢3???¨º2?¡ä?¨¦????¡ê??¨²?a???¨¦????¡ê?D??¨®??¦Ì?D L L?¨¦?¨¹¦Ì¡Â¨®???¨®D1¨°?¨®¦Ì?E x i t P r o c e s so¡¥¨ºy?¡ê?a¨¢??a???a???¨º¨¬a¡ê?¡À?D?1¨°?¨®L o a d L i b r a r y A?¡éL o a d L i b r a r y W?¡éL o a d L i b r a r y E x Ao¨ªL o a d L i b r a r y E x W¦Ì¨¨o¡¥¨ºy¡ê??a?¨´¡ê??¨ª?¨¹1?2????aD?o¡¥¨ºy¦Ì?¦Ì¡Â¨®?¡ê?2¡é?¨°?aD??¨®??¦Ì??¡ê?¨¦¦Ì¡Â¨®?R e p l a c e I AT E n t r y I n O n e M o d?¡ê
¡Á?o¨®¨°????¨º¨¬a¨®?G e t P r o c A d d r e s s¨®D1??¡ê¡À¨¨¨¨??¦Ì¨®D¨°?????3¨¬?¡äDD????¦Ì?¡ä¨²??¡êo
typedef int (WINAPI *PFNEXITPROCESS)(UINT uExitCode);
PFNEXITPROCESS pfnExitProcess = (PFNEXITPROCESS)GetProcAddress(
GetModuleHandle("Kernel32"), "ExitProcess");
pfnExitProcess(0);??¨°??¨²?D?1¨º?¦Ì?¨º?¨¤y¨®|¨®?3¨¬D¨°??¨º?¨¢?¨¨?o???DDA P I1¨°?¨®¡ê?¨ª?¨º¡À¨°2?a??¨¢??¨´¨®D¦Ì?L o a d L i b r a r yo¨ªG e t P r o c A d d r e s so¡¥¨ºy¦Ì??¨º¨¬a?¡ê
22.9.3 LastMsgBoxInfo¨º?¨¤y¨®|¨®?3¨¬D¨°
??¦Ì£¤2 2 - 4?D¨¢D3?¦Ì?L a s t M s g B o x I n f o¨®|¨®?3¨¬D¨°¡ê¡§?¡ã22 LastMsgBoxInfo.exe?¡À¡ê??1¨º?¨¢?A P I1¨°?¨®¦Ì?¡¤?¡¤¡§?¡ê?¨¹1¨°?¨®¨¢???U s e r 3 2 . d l l?D¡ã¨¹o?¦Ì??¨´¨®DM e s s a g e B o xo¡¥¨ºy¦Ì?¦Ì¡Â¨®??¡ê¨¨?¨°a1¨°?¨®?¨´¨®D??3¨¬?D¦Ì???o¡¥¨ºy¡ê???¨®|¨®?3¨¬D¨°¨º1¨®?Wi n d o w s1¨°?¨®¡¤?¡¤¡§??DDD L L¦Ì?2?¨¨?2¨´¡Á¡Â?¡ê??¨®|¨®?3¨¬D¨°o¨ªD L L¦Ì??¡ä¡ä¨²??o¨ª¡Á¨º?¡ä???t?¨´??¨®¨²¡À?¨º¨¦?¨´??1a?¨¬¨¦?¦Ì?22- LastMsgBoxInfoo¨ª22- LastMsgBoxInfoLib???????¡ê
¦Ì¡À??DD??¨®|¨®?3¨¬D¨°¨º¡À¡ê???3???¨ª?2 2 - 6?¨´¨º?¦Ì????¡ã?¨°?¡ê
¨ª?22-6 ??DDL a s t M s g B o xIn f o¨º¡À3???¦Ì????¡ã?¨°
?a¨º¡À¡ê???¨®|¨®?3¨¬D¨°??¨¨?¦Ì¨¨¡äy¡Á¡ä¨¬??¡ê???¨²??DD¨¨?o?¨°???¨®|¨®?3¨¬D¨°¡ê?¨º1?¨¹??¨º?¨°??????¡é?¨°?¡ê?a¨¢?2a¨º?¦Ì???¦Ì?¡ê??¨°¡Á¨¹¨º???DDN o t e p a d¡ê?¨º?¨¨?¨°?D???¡Á?¡ê?¨¨?o¨®¨¦¨¨¡¤¡§1?¡À?N o t e p a d¡ê?¦Ì?¨º?2?¡À¡ê¡ä?¨º?¨¨?¦Ì???¡Á??¡ê?a¨º1¦Ì?N o t e p a d??¨º?¨ª?2 2 - 7?¨´¨º?¦Ì????¡é?¨°?¡ê
¦Ì¡À1?¡À??a?????¡é?¨°¨º¡À¡ê?L a s t M s g B o x I n f o???¡ã?¨°??¨¨?¨ª?2 2 - 8?¨´¨º??¡ê
¨ª?22-7 ??DDNotepad ¨º¡À??¨º?¦Ì????¡é?¨°
¨ª?22-8 1?¡À?Notepad ¨º¡À??¨º?¦Ì?L a s t M s g B o x I n f o???¡ã?¨°
?¨¦¨°??¡ä¦Ì?¡ê?L a s t M s g B o x I n f o¨®|¨®?3¨¬D¨°?¨¹1??a¦Ì¨¤??????3¨¬¨º?¨¨?o?¦Ì¡Â¨®?M e s s a g e B o xo¡¥¨ºy¦Ì??¡ê
??¨º?o¨ª1¨¹¨¤¨ªLast MessageBox Info???¡ã?¨°¦Ì?¡ä¨²??¨º?¡¤?3¡ê?¨°¦Ì£¤¦Ì??¡êA P I1¨°?¨®¦Ì?¨¦¨¨???y¨º?¨¨?2?1¡è¡Á¡Â¦Ì???¦Ì????¨´?¨²?¡ê?a¨¢?¨º1A P I¦Ì?1¨°?¨®2¨´¡Á¡Â?¨¹?¨®¨¨Y¨°¡Á¨°?D?¡ê??¨°¡ä¡ä?¡§¨¢?¨°???CAPIHook C++¨¤¨¤?¡ê?a??¨¤¨¤¦Ì??¡§¨°?¨º??¨²A P I H o o k . h???t?D¡ê?¨¤¨¤¦Ì?¨º¦Ì??¨º??¨²A P I H o o k . c p p???t?D?¡ê?a??¨¤¨¤¦Ì?¨º1¨®?¨º?o¨¹¡¤?¡À?¦Ì?¡ê?¨°¨°?a?¨¹??¨®Do¨¹¨¦¨´????1?¨®D3¨¦?¡Ào¡¥¨ºy¡êo¨°???11?¨¬o¡¥¨ºy¡ê?¨°?????11o¡¥¨ºy¡ê??1¨®D¨°???¡¤¦Ì???-¨º?o¡¥¨ºy¦Ì?¦Ì??¡¤¦Ì?o¡¥¨ºy?¡ê
¨¨?¨°a1¨°?¨®¨°???o¡¥¨ºy¡ê???¨°a???????a?¨´¡ä¡ä?¡§?a??¨¤¨¤¦Ì?¨°???¨º¦Ì¨¤y¡êo
CAPIHook g_MessageBoxA("User32.dll", "MessageBoxA",
(PROC) Hook_MessageBoxA, TRUE);
CAPIHook g_MessageBoxW("User32.dll", "MessageBoxW",
(PROC) Hook_MessageBoxW, TRUE);
?¨°¦Ì?C A P I H o o k¨¤¨¤¦Ì?11?¨¬o¡¥¨ºy????¡Á??????¡§¨°a1¨°?¨®¦Ì?¨º?¨º2?¡äA P I¡ê?2¡é¦Ì¡Â¨®?R e p l a c e I ATE n t r y I n A l l M o d s¡ê?¨°?¡À???DD¨º¦Ì?¨º¦Ì?1¨°?¨®2¨´¡Á¡Â?¡ê
¨¢¨ª¨°???1?¨®D3¨¦?¡Ào¡¥¨ºy¨º???11o¡¥¨ºy?¡ê¦Ì¡À¨°???C A P I H o o k???¨®3?3?¡Á¡Â¨®?¨®¨°¨º¡À¡ê???11o¡¥¨ºy?¨ª¦Ì¡Â¨®?R e p l a c e I AT E n t r y I n A l l M o d s¡ê???¡¤?o?¦Ì?¦Ì??¡¤???¡ä3¨¦?????¡ê?¨¦?D?¨¹¦Ì??-¨º?¦Ì??¡¤¡ê?o¡¥¨ºy2??¨´1¨°?¨®?¡ê
¦Ì¨²¨¨y??1?¨®D3¨¦?¡Ào¡¥¨ºy¡¤¦Ì???-¨º?o¡¥¨ºy¦Ì?¦Ì??¡¤?¡ê?a??3¨¦?¡Ào¡¥¨ºy¨ª¡§3¡ê¡ä¨®¨¬???o¡¥¨ºy?¨²2???DD¦Ì¡Â¨®?¡ê?¨°?¡À?¦Ì¡Â¨®??-¨º?o¡¥¨ºy?¡ê????¨º?H o o k _ M e s s a g e B o x Ao¡¥¨ºy?D¦Ì?¡ä¨²??¡êo
int WINAPI Hook_MessageBoxA(HWND hWnd, PCSTR pszText,
PCSTR pszCaption, UINT uType)
{
int nResult = ((PFNMESSAGEBOXA)(PROC) g_MessageBoxA)
(hWnd, pszText, pszCaption, uType);
SendLastMsgBoxInfo(FALSE, (PVOID) pszCaption, (PVOID) pszText, nResult);
return(nResult);
}¨¨?1???¨º1¨®??a??C + +¨¤¨¤¡ê????¡ä?a?¨ª¨º?1¨°?¨®o¨ª3¡¤??1¨°?¨®¨º?¨¨?o¡¥¨ºy¦Ì?¨¨?2?¡¤?¡¤¡§?¡ê¨¨?1???1?2¨¬C A P I H o o k . c p p???t?¨¢?2¡ä|¦Ì?¡ä¨²??¡ê????¨¢¡¤¡é??C + +¨¤¨¤?¨¢¡Á??¡¥?¡§¨¢¡éC A P I H o o k???¨®¦Ì?¨º¦Ì¨¤y¡ê?¨°?¡À?2???L o a d L i b r a r y A?¡éL o a d L i b r a r y W?¡éL o a d L i b r a r y E x Ao¨ªL o a d L i b r a r y E x W?¡ê?a?¨´¡ê?C A P I H o o k¨¤¨¤?¨ª?¨¹¡Á??¡¥?a???¡ã???2¦Ì?¦Ì?¨°?D??¨º¨¬a?¡ê
??¦Ì£¤22-4 LastMsgBoxInfo¨º?¨¤y¨®|¨®?3¨¬D¨°
/******************************************************************************
Module: LastMsgBoxInfo.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/
#include "..\CmnHdr.h" /* See Appendix A. */
#include <windowsx.h>
#include <tchar.h>
#include "Resource.h"
#include "..\22-LastMsgBoxInfoLib\LastMsgBoxInfoLib.h"
///////////////////////////////////////////////////////////////////////////////
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) {
chSETDLGICONS(hwnd, IDI_LASTMSGBOXINFO);
SetDlgItemText(hwnd, IDC_INFO,
TEXT("Waiting for a Message Box to be dismissed"));
return(TRUE);
}
///////////////////////////////////////////////////////////////////////////////
void Dlg_OnSize(HWND hwnd, UINT state, int cx, int cy) {
SetWindowPos(GetDlgItem(hwnd, IDC_INFO), NULL,
0, 0, cx, cy, SWP_NOZORDER);
}
///////////////////////////////////////////////////////////////////////////////
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) {
switch (id) {
case IDCANCEL:
EndDialog(hwnd, id);
break;
}
}
///////////////////////////////////////////////////////////////////////////////
BOOL Dlg_OnCopyData(HWND hwnd, HWND hwndFrom, PCOPYDATASTRUCT pcds) {
// Some hooked process sent us some message box info, display it
SetDlgItemTextA(hwnd, IDC_INFO, (PCSTR) pcds->lpData);
return(TRUE);
}
///////////////////////////////////////////////////////////////////////////////
INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
chHANDLE_DLGMSG(hwnd, WM_SIZE, Dlg_OnSize);
chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand);
chHANDLE_DLGMSG(hwnd, WM_COPYDATA, Dlg_OnCopyData);
}
return(FALSE);
}
///////////////////////////////////////////////////////////////////////////////
int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) {
DWORD dwThreadId = 0;
#ifdef _DEBUG
HWND hwnd = FindWindow(NULL, TEXT("Untitled - Paint"));
dwThreadId = GetWindowThreadProcessId(hwnd, NULL);
#endif
LastMsgBoxInfo_HookAllApps(TRUE, dwThreadId);
DialogBox(hinstExe, MAKEINTRESOURCE(IDD_LASTMSGBOXINFO), NULL, Dlg_Proc);
LastMsgBoxInfo_HookAllApps(FALSE, 0);
return(0);
}
//////////////////////////////// End of File //////////////////////////////////
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_LASTMSGBOXINFO DIALOG DISCARDABLE 0, 0, 379, 55
STYLE DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE | WS_CAPTION |
WS_SYSMENU | WS_THICKFRAME
CAPTION "Last MessageBox Info"
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_INFO,0,0,376,52,ES_MULTILINE | ES_AUTOVSCROLL |
ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_LASTMSGBOXINFO, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 372
TOPMARGIN, 7
BOTTOMMARGIN, 48
END
END
#endif // APSTUDIO_INVOKED
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_LASTMSGBOXINFO ICON DISCARDABLE "LastMsgBoxInfo.ico"
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
/******************************************************************************
Module: LastMsgBoxInfoLib.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/
#define WINVER 0x0500
#include "..\CmnHdr.h"
#include <WindowsX.h>
#include <tchar.h>
#include <stdio.h>
#include "APIHook.h"
#define LASTMSGBOXINFOLIBAPI extern "C" __declspec(dllexport)
#include "LastMsgBoxInfoLib.h"
///////////////////////////////////////////////////////////////////////////////
// Prototypes for the hooked functions
typedef int (WINAPI *PFNMESSAGEBOXA)(HWND hWnd, PCSTR pszText,
PCSTR pszCaption, UINT uType);
typedef int (WINAPI *PFNMESSAGEBOXW)(HWND hWnd, PCWSTR pszText,
PCWSTR pszCaption, UINT uType);
// We need to reference these variables before we create them.
extern CAPIHook g_MessageBoxA;
extern CAPIHook g_MessageBoxW;
///////////////////////////////////////////////////////////////////////////////
// This function sends the MessageBox info to our main dialog box
void SendLastMsgBoxInfo(BOOL fUnicode,
PVOID pvCaption, PVOID pvText, int nResult) {
// Get the pathname of the process displaying the message box
char szProcessPathname[MAX_PATH];
GetModuleFileNameA(NULL, szProcessPathname, MAX_PATH);
// Convert the return value into a human-readable string
PCSTR pszResult = "(Unknown)";
switch (nResult) {
case IDOK: pszResult = "Ok"; break;
case IDCANCEL: pszResult = "Cancel"; break;
case IDABORT: pszResult = "Abort"; break;
case IDRETRY: pszResult = "Retry"; break;
case IDIGNORE: pszResult = "Ignore"; break;
case IDYES: pszResult = "Yes"; break;
case IDNO: pszResult = "No"; break;
case IDCLOSE: pszResult = "Close"; break;
case IDHELP: pszResult = "Help"; break;
case IDTRYAGAIN: pszResult = "Try Again"; break;
case IDCONTINUE: pszResult = "Continue"; break;
}
// Construct the string to send to the main dialog box
char sz[2048];
wsprintfA(sz, fUnicode
? "Process: (%d) %s\r\nCaption: %S\r\nMessage: %S\r\nResult: %s"
: "Process: (%d) %s\r\nCaption: %s\r\nMessage: %s\r\nResult: %s",
GetCurrentProcessId(), szProcessPathname,
pvCaption, pvText, pszResult);
// Send the string to the main dialog box
COPYDATASTRUCT cds = { 0, lstrlenA(sz) + 1, sz };
FORWARD_WM_COPYDATA(FindWindow(NULL, TEXT("Last MessageBox Info")),
NULL, &cds, SendMessage);
}
///////////////////////////////////////////////////////////////////////////////
// This is the MessageBoxW replacement function
int WINAPI Hook_MessageBoxW(HWND hWnd, PCWSTR pszText, LPCWSTR pszCaption,
UINT uType) {
// Call the original MessageBoxW function
int nResult = ((PFNMESSAGEBOXW)(PROC) g_MessageBoxW)
(hWnd, pszText, pszCaption, uType);
// Send the information to the main dialog box
SendLastMsgBoxInfo(TRUE, (PVOID) pszCaption, (PVOID) pszText, nResult);
// Return the result back to the caller
return(nResult);
}
///////////////////////////////////////////////////////////////////////////////
// This is the MessageBoxA replacement function
int WINAPI Hook_MessageBoxA(HWND hWnd, PCSTR pszText, PCSTR pszCaption,
UINT uType) {
// Call the original MessageBoxA function
int nResult = ((PFNMESSAGEBOXA)(PROC) g_MessageBoxA)
(hWnd, pszText, pszCaption, uType);
// Send the infomration to the main dialog box
SendLastMsgBoxInfo(FALSE, (PVOID) pszCaption, (PVOID) pszText, nResult);
// Return the result back to the caller
return(nResult);
}
///////////////////////////////////////////////////////////////////////////////
// Hook the MessageBoxA and MessageBoxW functions
CAPIHook g_MessageBoxA("User32.dll", "MessageBoxA",
(PROC) Hook_MessageBoxA, TRUE);
CAPIHook g_MessageBoxW("User32.dll", "MessageBoxW",
(PROC) Hook_MessageBoxW, TRUE);
// Since we do DLL injection with Windows' hooks, we need to save the hook
// handle in a shared memory block (Windows 2000 actually doesn't need this)
#pragma data_seg("Shared")
HHOOK g_hhook = NULL;
#pragma data_seg()
#pragma comment(linker, "/Section:Shared,rws")
///////////////////////////////////////////////////////////////////////////////
static LRESULT WINAPI GetMsgProc(int code, WPARAM wParam, LPARAM lParam) {
// NOTE: On Windows 2000, the 1st parameter to CallNextHookEx can
// be NULL. On Windows 98, it must be the hook handle.
return(CallNextHookEx(g_hhook, code, wParam, lParam));
}
///////////////////////////////////////////////////////////////////////////////
// Returns the HMODULE that contains the specified memory address
static HMODULE ModuleFromAddress(PVOID pv) {
MEMORY_BASIC_INFORMATION mbi;
return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
? (HMODULE) mbi.AllocationBase : NULL);
}
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI LastMsgBoxInfo_HookAllApps(BOOL fInstall, DWORD dwThreadId) {
BOOL fOk;
if (fInstall) {
chASSERT(g_hhook == NULL); // Illegal to install twice in a row
// Install the Windows' hook
g_hhook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc,
ModuleFromAddress(LastMsgBoxInfo_HookAllApps), dwThreadId);
fOk = (g_hhook != NULL);
} else {
chASSERT(g_hhook != NULL); // Can't uninstall if not installed
fOk = UnhookWindowsHookEx(g_hhook);
g_hhook = NULL;
}
return(fOk);
}
//////////////////////////////// End of File //////////////////////////////////
/****************************************************************************** Module: LastMsgBoxInfoLib.h Notices: Copyright (c) 2000 Jeffrey Richter ******************************************************************************/ #ifndef LASTMSGBOXINFOLIBAPI #define LASTMSGBOXINFOLIBAPI extern "C" __declspec(dllimport) #endif /////////////////////////////////////////////////////////////////////////////// LASTMSGBOXINFOLIBAPI BOOL WINAPI LastMsgBoxInfo_HookAllApps(BOOL fInstall, DWORD dwThreadId); //////////////////////////////// End of File //////////////////////////////////
/******************************************************************************
Module: APIHook.cpp
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/
#include "..\CmnHdr.h"
#include <ImageHlp.h>
#pragma comment(lib, "ImageHlp")
#include "APIHook.h"
#include "..\04-ProcessInfo\Toolhelp.h"
///////////////////////////////////////////////////////////////////////////////
// When an application runs on Windows 98 under a debugger, the debugger
// makes the module's import section point to a stub that calls the desired
// function. To account for this, the code in this module must do some crazy
// stuff. These variables are needed to help with the crazy stuff.
// The highest private memory address (used for Windows 98 only)
PVOID CAPIHook::sm_pvMaxAppAddr = NULL;
const BYTE cPushOpCode = 0x68; // The PUSH opcode on x86 platforms
///////////////////////////////////////////////////////////////////////////////
// The head of the linked-list of CAPIHook objects
CAPIHook* CAPIHook::sm_pHead = NULL;
///////////////////////////////////////////////////////////////////////////////
CAPIHook::CAPIHook(PSTR pszCalleeModName, PSTR pszFuncName, PROC pfnHook,
BOOL fExcludeAPIHookMod) {
if (sm_pvMaxAppAddr == NULL) {
// Functions with address above lpMaximumApplicationAddress require
// special processing (Windows 98 only)
SYSTEM_INFO si;
GetSystemInfo(&si);
sm_pvMaxAppAddr = si.lpMaximumApplicationAddress;
}
m_pNext = sm_pHead; // The next node was at the head
sm_pHead = this; // This node is now at the head
// Save information about this hooked function
m_pszCalleeModName = pszCalleeModName;
m_pszFuncName = pszFuncName;
m_pfnHook = pfnHook;
m_fExcludeAPIHookMod = fExcludeAPIHookMod;
m_pfnOrig = GetProcAddressRaw(
GetModuleHandleA(pszCalleeModName), m_pszFuncName);
chASSERT(m_pfnOrig != NULL); // Function doesn't exist
if (m_pfnOrig > sm_pvMaxAppAddr) {
// The address is in a shared DLL; the address needs fixing up
PBYTE pb = (PBYTE) m_pfnOrig;
if (pb[0] == cPushOpCode) {
// Skip over the PUSH op code and grab the real address
PVOID pv = * (PVOID*) &pb[1];
m_pfnOrig = (PROC) pv;
}
}
// Hook this function in all currently loaded modules
ReplaceIATEntryInAllMods(m_pszCalleeModName, m_pfnOrig, m_pfnHook,
m_fExcludeAPIHookMod);
}
///////////////////////////////////////////////////////////////////////////////
CAPIHook::~CAPIHook() {
// Unhook this function from all modules
ReplaceIATEntryInAllMods(m_pszCalleeModName, m_pfnHook, m_pfnOrig,
m_fExcludeAPIHookMod);
// Remove this object from the linked list
CAPIHook* p = sm_pHead;
if (p == this) { // Removing the head node
sm_pHead = p->m_pNext;
} else {
BOOL fFound = FALSE;
// Walk list from head and fix pointers
for (; !fFound && (p->m_pNext != NULL); p = p->m_pNext) {
if (p->m_pNext == this) {
// Make the node that points to us point to the our next node
p->m_pNext = p->m_pNext->m_pNext;
break;
}
}
chASSERT(fFound);
}
}
///////////////////////////////////////////////////////////////////////////////
// NOTE: This function must NOT be inlined
FARPROC CAPIHook::GetProcAddressRaw(HMODULE hmod, PCSTR pszProcName) {
return(::GetProcAddress(hmod, pszProcName));
}
///////////////////////////////////////////////////////////////////////////////
// Returns the HMODULE that contains the specified memory address
static HMODULE ModuleFromAddress(PVOID pv) {
MEMORY_BASIC_INFORMATION mbi;
return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
? (HMODULE) mbi.AllocationBase : NULL);
}
///////////////////////////////////////////////////////////////////////////////
void CAPIHook::ReplaceIATEntryInAllMods(PCSTR pszCalleeModName,
PROC pfnCurrent, PROC pfnNew, BOOL fExcludeAPIHookMod) {
HMODULE hmodThisMod = fExcludeAPIHookMod
? ModuleFromAddress(ReplaceIATEntryInAllMods) : NULL;
// Get the list of modules in this process
CToolhelp th(TH32CS_SNAPMODULE, GetCurrentProcessId());
MODULEENTRY32 me = { sizeof(me) };
for (BOOL fOk = th.ModuleFirst(&me); fOk; fOk = th.ModuleNext(&me)) {
// NOTE: We don't hook functions in our own module
if (me.hModule != hmodThisMod) {
// Hook this function in this module
ReplaceIATEntryInOneMod(
pszCalleeModName, pfnCurrent, pfnNew, me.hModule);
}
}
}
///////////////////////////////////////////////////////////////////////////////
void CAPIHook::ReplaceIATEntryInOneMod(PCSTR pszCalleeModName,
PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller) {
// Get the address of the module's import section
ULONG ulSize;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)
ImageDirectoryEntryToData(hmodCaller, TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);
if (pImportDesc == NULL)
return; // This module has no import section
// Find the import descriptor containing references to callee's functions
for (; pImportDesc->Name; pImportDesc++) {
PSTR pszModName = (PSTR) ((PBYTE) hmodCaller + pImportDesc->Name);
if (lstrcmpiA(pszModName, pszCalleeModName) == 0)
break; // Found
}
if (pImportDesc->Name == 0)
return; // This module doesn't import any functions from this callee
// Get caller's import address table (IAT) for the callee's functions
PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)
((PBYTE) hmodCaller + pImportDesc->FirstThunk);
// Replace current function address with new function address
for (; pThunk->u1.Function; pThunk++) {
// Get the address of the function address
PROC* ppfn = (PROC*) &pThunk->u1.Function;
// Is this the function we're looking for?
BOOL fFound = (*ppfn == pfnCurrent);
if (!fFound && (*ppfn > sm_pvMaxAppAddr)) {
// If this is not the function and the address is in a shared DLL,
// then maybe we're running under a debugger on Windows 98. In this
// case, this address points to an instruction that may have the
// correct address.
PBYTE pbInFunc = (PBYTE) *ppfn;
if (pbInFunc[0] == cPushOpCode) {
// We see the PUSH instruction, the real function address follows
ppfn = (PROC*) &pbInFunc[1];
// Is this the function we're looking for?
fFound = (*ppfn == pfnCurrent);
}
}
if (fFound) {
// The addresses match, change the import section address
WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew,
sizeof(pfnNew), NULL);
return; // We did it, get out
}
}
// If we get to here, the function is not in the caller's import section
}
///////////////////////////////////////////////////////////////////////////////
// Hook LoadLibrary functions and GetProcAddress so that hooked functions
// are handled correctly if these functions are called.
CAPIHook CAPIHook::sm_LoadLibraryA ("Kernel32.dll", "LoadLibraryA",
(PROC) CAPIHook::LoadLibraryA, TRUE);
CAPIHook CAPIHook::sm_LoadLibraryW ("Kernel32.dll", "LoadLibraryW",
(PROC) CAPIHook::LoadLibraryW, TRUE);
CAPIHook CAPIHook::sm_LoadLibraryExA("Kernel32.dll", "LoadLibraryExA",
(PROC) CAPIHook::LoadLibraryExA, TRUE);
CAPIHook CAPIHook::sm_LoadLibraryExW("Kernel32.dll", "LoadLibraryExW",
(PROC) CAPIHook::LoadLibraryExW, TRUE);
CAPIHook CAPIHook::sm_GetProcAddress("Kernel32.dll", "GetProcAddress",
(PROC) CAPIHook::GetProcAddress, TRUE);
///////////////////////////////////////////////////////////////////////////////
void CAPIHook::FixupNewlyLoadedModule(HMODULE hmod, DWORD dwFlags) {
// If a new module is loaded, hook the hooked functions
if ((hmod != NULL) && ((dwFlags & LOAD_LIBRARY_AS_DATAFILE) == 0)) {
for (CAPIHook* p = sm_pHead; p != NULL; p = p->m_pNext) {
ReplaceIATEntryInOneMod(p->m_pszCalleeModName,
p->m_pfnOrig, p->m_pfnHook, hmod);
}
}
}
///////////////////////////////////////////////////////////////////////////////
HMODULE WINAPI CAPIHook::LoadLibraryA(PCSTR pszModulePath) {
HMODULE hmod = ::LoadLibraryA(pszModulePath);
FixupNewlyLoadedModule(hmod, 0);
return(hmod);
}
///////////////////////////////////////////////////////////////////////////////
HMODULE WINAPI CAPIHook::LoadLibraryW(PCWSTR pszModulePath) {
HMODULE hmod = ::LoadLibraryW(pszModulePath);
FixupNewlyLoadedModule(hmod, 0);
return(hmod);
}
///////////////////////////////////////////////////////////////////////////////
HMODULE WINAPI CAPIHook::LoadLibraryExA(PCSTR pszModulePath,
HANDLE hFile, DWORD dwFlags) {
HMODULE hmod = ::LoadLibraryExA(pszModulePath, hFile, dwFlags);
FixupNewlyLoadedModule(hmod, dwFlags);
return(hmod);
}
///////////////////////////////////////////////////////////////////////////////
HMODULE WINAPI CAPIHook::LoadLibraryExW(PCWSTR pszModulePath,
HANDLE hFile, DWORD dwFlags) {
HMODULE hmod = ::LoadLibraryExW(pszModulePath, hFile, dwFlags);
FixupNewlyLoadedModule(hmod, dwFlags);
return(hmod);
}
///////////////////////////////////////////////////////////////////////////////
FARPROC WINAPI CAPIHook::GetProcAddress(HMODULE hmod, PCSTR pszProcName) {
// Get the true address of the function
FARPROC pfn = GetProcAddressRaw(hmod, pszProcName);
// Is it one of the functions that we want hooked?
CAPIHook* p = sm_pHead;
for (; (pfn != NULL) && (p != NULL); p = p->m_pNext) {
if (pfn == p->m_pfnOrig) {
// The address to return matches an address we want to hook
// Return the hook function address instead
pfn = p->m_pfnHook;
break;
}
}
return(pfn);
}
//////////////////////////////// End of File //////////////////////////////////
/******************************************************************************
Module: APIHook.h
Notices: Copyright (c) 2000 Jeffrey Richter
******************************************************************************/
#pragma once
///////////////////////////////////////////////////////////////////////////////
class CAPIHook {
public:
// Hook a function in all modules
CAPIHook(PSTR pszCalleeModName, PSTR pszFuncName, PROC pfnHook,
BOOL fExcludeAPIHookMod);
// Unhook a function from all modules
~CAPIHook();
// Returns the original address of the hooked function
operator PROC() { return(m_pfnOrig); }
public:
// Calls the real GetProcAddress
static FARPROC WINAPI GetProcAddressRaw(HMODULE hmod, PCSTR pszProcName);
private:
static PVOID sm_pvMaxAppAddr; // Maximum private memory address
static CAPIHook* sm_pHead; // Address of first object
CAPIHook* m_pNext; // Address of next object
PCSTR m_pszCalleeModName; // Module containing the function (ANSI)
PCSTR m_pszFuncName; // Function name in callee (ANSI)
PROC m_pfnOrig; // Original function address in callee
PROC m_pfnHook; // Hook function address
BOOL m_fExcludeAPIHookMod; // Hook module w/CAPIHook implementation?
private:
// Replaces a symbol's address in a module's import section
static void WINAPI ReplaceIATEntryInAllMods(PCSTR pszCalleeModName,
PROC pfnOrig, PROC pfnHook, BOOL fExcludeAPIHookMod);
// Replaces a symbol's address in all module's import sections
static void WINAPI ReplaceIATEntryInOneMod(PCSTR pszCalleeModName,
PROC pfnOrig, PROC pfnHook, HMODULE hmodCaller);
private:
// Used when a DLL is newly loaded after hooking a function
static void WINAPI FixupNewlyLoadedModule(HMODULE hmod, DWORD dwFlags);
// Used to trap when DLLs are newly loaded
static HMODULE WINAPI LoadLibraryA(PCSTR pszModulePath);
static HMODULE WINAPI LoadLibraryW(PCWSTR pszModulePath);
static HMODULE WINAPI LoadLibraryExA(PCSTR pszModulePath,
HANDLE hFile, DWORD dwFlags);
static HMODULE WINAPI LoadLibraryExW(PCWSTR pszModulePath,
HANDLE hFile, DWORD dwFlags);
// Returns address of replacement function if hooked function is requested
static FARPROC WINAPI GetProcAddress(HMODULE hmod, PCSTR pszProcName);
private:
// Instantiates hooks on these functions
static CAPIHook sm_LoadLibraryA;
static CAPIHook sm_LoadLibraryW;
static CAPIHook sm_LoadLibraryExA;
static CAPIHook sm_LoadLibraryExW;
static CAPIHook sm_GetProcAddress;
};
//////////////////////////////// End of File //////////////////////////////////
CZVC¡À¨¤3¨¬¨ª?3??¡¤,¨°??¡ê[QQ:28077188]??¨¤¨ª¡À¨¤¨°?,??¨®-¨¢a?¦Ì
MSN:loomman@hotmail.com