几何尺寸与公差论坛

 找回密码
 注册
查看: 2836|回复: 2

【转帖】利用hook拦截api的问题(附代码),

[复制链接]
发表于 2007-3-27 14:19:31 | 显示全部楼层 |阅读模式
利用hook拦截api的问题
近来想研究一下外挂程序,仅仅学习之用,我尝试着用Hook进入目标进程,然后用替换api入口地址的方法,拦截api调用。部分替换代码如下:   
   
  HMODULE   hModule=LoadLibrary("user32.dll");   
  pfMessageBoxA=GetProcAddress(hModule,"MessageBoxA");   
  if(pfMessageBoxA==NULL)   
        return   false;   
   
  memcpy(OldMessageBoxACode,   pfMessageBoxA,   6);   
  NewMessageBoxACode[0]   =   0xe9;   
  //jmp   MyMessageBoxA的相对地址的指令   
   
  DWORD   jmpaddr   =   (DWORD)MyMessageBoxA   -   (DWORD)pfMessageBoxA   -   5;   
  memcpy(&NewMessageBoxACode[1],   &jmpaddr,   5);   
   
  dwIdOld=dwIdNew;   
  hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld);//得到所属进程的句柄   
  VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld);   
  //修改所属进程中MessageBoxA的前5个字节的属性为可写   
   
  WriteProcessMemory(hProc,pfMessageBoxA,NewMessageBoxACode,5,0);   
  //将所属进程中MessageBoxA的前5个字节改为JMP   到MyMessageBoxA   
   
  VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld);   
  //修改所属进程中MessageBoxA的前5个字节的属性为原来的属性   
   
  以上代码用来拦截user32.dll中的MessageBoxA是成功的,但是同样的方法我想拦截Wsock32.dll中的recv方法,结果拦截时会让目标程序非法操作,感觉是api的入口地址替换不对,请问哪位高人能够指点一下!谢谢!
 楼主| 发表于 2007-3-27 14:20:14 | 显示全部楼层

回复: 【转帖】利用hook拦截api的问题(附代码),

2 楼singlerace(独行者)回复于 2006-01-09 18:32:00 得分 20

VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld);

这句有问题。pfMessageBoxA是MessageBoxA在本地进程的地址,你必须获得API在目标进程的加载地址。user32.dll一般在所有进程的加载基址相同,因此截MessageBoxA没问题,但wsock32.dll就不一定了。
 楼主| 发表于 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;
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|小黑屋|几何尺寸与公差论坛

GMT+8, 2024-5-10 21:25 , Processed in 0.086580 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表