?

??1 #include? < windows.h >
??2 #include? < stdio.h >
??3
??4 // ?掛鉤指定模塊hMod對MessageBoxA的調用
??5 BOOL?SetHook(HMODULE?hMod);
??6 // ?定義MessageBoxA函數原型
??7 typedef? int ?(WINAPI? * PFNMESSAGEBOX)(HWND,?LPCSTR,?LPCSTR,?UINT?uType);
??8 // ?保存MessageBoxA函數的真實地址
??9 PROC?g_orgProc? = ?(PROC)MessageBoxA;
?10
?11
?12 BOOL?EnableDebugPrivilege()?
?13 {?
?14 BOOL?fOk? = ?FALSE;?
?15 HANDLE?hToken;?
?16
?17 if ?(OpenProcessToken(GetCurrentProcess(),?
?18 ???????TOKEN_ADJUST_PRIVILEGES,? & hToken))?
?19 {?
?20 ???????TOKEN_PRIVILEGES?tp;
?21 ???????tp.PrivilegeCount? = ? 1 ;?
?22 ???????LookupPrivilegeValue(NULL,?SE_DEBUG_NAME,? & tp.Privileges[ 0 ].Luid);?
?23 ???????tp.Privileges[ 0 ].Attributes? = ?SE_PRIVILEGE_ENABLED;?
?24 ???????AdjustTokenPrivileges(hToken,?FALSE,? & tp,? sizeof (tp),?NULL,?NULL);?
?25 ???????fOk? = ?(GetLastError()? == ?ERROR_SUCCESS);?
?26 ???????CloseHandle(hToken);?
?27 }
?
?28 return ?fOk;? // 提升成功返回TRUE,失敗返回FALSE?
?29 }

?30
?31 void ?main()
?32 {
?33 if (EnableDebugPrivilege())
?34 {
?35 // ?調用原API函數
?36 ::MessageBox(NULL,? " 原函數 " ,? " Hook?Api " ,? 0 );
?37 // ?掛鉤后再調用
?38 SetHook(::GetModuleHandle(NULL));
?39 ::MessageBox(NULL,? " 原函數 " ,? " Hook?Api " ,? 0 );
?40 }

?41
?42 }

?43
?44 // ?用于替換MessageBoxA的自定義函數
?45 int ?WINAPI?MyMessageBoxA(HWND?hWnd,?LPCSTR?lpText,?LPCSTR?lpCaption,?UINT?uType)
?46 {
?47 return ?((PFNMESSAGEBOX)g_orgProc)(hWnd,? " Hook?API?Sucess! " ,? " OK " ,?uType);
?48 return ? 0 ;
?49 }

?50
?51 BOOL?SetHook(HMODULE?hMod)
?52 {
?53 IMAGE_DOS_HEADER * ?pDosHeader? = ?(IMAGE_DOS_HEADER * )hMod;
?54 IMAGE_OPTIONAL_HEADER? * ?pOptHeader? =
?55 (IMAGE_OPTIONAL_HEADER? * )((BYTE * )hMod? + ?pDosHeader -> e_lfanew? + ? 24 );
?56
?57 IMAGE_IMPORT_DESCRIPTOR * ?pImportDesc? = ?(IMAGE_IMPORT_DESCRIPTOR * )
?58 ((BYTE * )hMod? + ?pOptHeader -> DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
?59
?60 // ?在導入表中查找user32.dll模塊。因為MessageBoxA函數從user32.dll模塊導出
?61 while (pImportDesc -> FirstThunk)
?62 {
?63 char * ?pszDllName? = ?( char * )((BYTE * )hMod? + ?pImportDesc -> Name);
?64 if (lstrcmpiA(pszDllName,? " user32.dll " )? == ? 0 )
?65 {
?66 break ;
?67 }

?68 pImportDesc ++ ;
?69 }

?70
?71 if (pImportDesc -> FirstThunk)
?72 {
?73
?74 // ?一個IMAGE_THUNK_DATA就是一個雙字,它指定了一個導入函數
?75 // ?調入地址表其實是IMAGE_THUNK_DATA結構的數組,也就是DWORD數組
?76 IMAGE_THUNK_DATA * ?pThunk? = ?(IMAGE_THUNK_DATA * )
?77 ((BYTE * )hMod? + ?pImportDesc -> FirstThunk);
?78 while (pThunk -> u1.Function)
?79 {
?80 // ?lpAddr指向的內存保存了函數的地址
?81 DWORD * ?lpAddr? = ?(DWORD * ) & (pThunk -> u1.Function);
?82 if ( * lpAddr? == ?(DWORD)g_orgProc)
?83 {?
?84 DWORD?oldProc;
?85 BOOL?VirSu = VirtualProtect(lpAddr, sizeof (DWORD),PAGE_READWRITE, & oldProc);
?86 if (VirSu == TRUE)
?87 {
?88 // ?修改IAT表項,使其指向我們自定義的函數,相當于“*lpAddr?=?(DWORD)MyMessageBoxA;”
?89 DWORD * ?lpNewProc? = ?(DWORD * )MyMessageBoxA;
?90 ::WriteProcessMemory(::GetCurrentProcess(),?
?91 lpAddr,? & lpNewProc,? sizeof (DWORD),?NULL);
?92 }

?93 else
?94 {
?95 MessageBox(NULL, " Error! " , " a " , 0 );
?96 }

?97 return ?TRUE;
?98 }

?99 pThunk ++ ;
100 }

101 }

102 return ?FALSE;
103 }

?

有個郁悶的問題,在2003sp1下,不管是提升進程權限還是修改內存包含屬性都成功!debug版本能成功!release就他娘的死不成功!郁悶死,遍尋高手無著落,暫時等著先。。。