采用个hook技术对writefile函数进行拦截

DLL部分:

View Code
#include <windows.h>
#include <ImageHlp.h>
#include <TlHelp32.h>
#pragma comment(lib,"ImageHlp")

#pragma data_seg("Shared")
HHOOK hhk = NULL;
#pragma data_seg()
#pragma comment(linker, "/Section:Shared,rws")

HMODULE hmodThisDll;
#define MyName "DLL.DLL"
LRESULT CALLBACK GetMsgProc( int nCode,WPARAM wParam,LPARAM lParam){
return CallNextHookEx(hhk,nCode,wParam,lParam);
}
BOOL MyWriteFile(
HANDLE hFile, // 文件句柄
LPCVOID lpBuffer,// 数据缓存区指针
DWORD nNumberOfBytesToWrite, // 你要写的字节数
LPDWORD lpNumberOfBytesWritten, // 用于保存实际写入字节数的存储区域的指针
LPOVERLAPPED lpOverlapped // OVERLAPPED结构体指针
){
MessageBoxA(NULL,"HOOK","DLL",MB_OK);
return WriteFile(hFile,lpBuffer,nNumberOfBytesToWrite,lpNumberOfBytesWritten,lpOverlapped);
}
VOID ModifyIAT(HMODULE hmodCaller,LPCSTR szDllName,PROC pfnOrg,PROC pfnNew){
PIMAGE_THUNK_DATA pITD;
ULONG ulSize;
PIMAGE_IMPORT_DESCRIPTOR pIID;
pIID = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hmodCaller,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&ulSize);
if( !pIID )
return;
for( ; pIID->Name; pIID++ ){
if( !lstrcmpiA(szDllName,(LPSTR)((PBYTE)hmodCaller+pIID->Name)) )
break;
}
if( !pIID->Name )
return;
pITD = (PIMAGE_THUNK_DATA)((PBYTE)hmodCaller+pIID->FirstThunk);
for( ; pITD->u1.Function ; pITD++ ){
PROC* ppfn = (PROC*)&pITD->u1.Function;
if(*ppfn == pfnOrg){
WriteProcessMemory(GetCurrentProcess(),ppfn,&pfnNew,sizeof(pfnNew),NULL);
return;
}
}
}
VOID ModifyIATs(LPCSTR szDllName,PROC pfnOrg,PROC pfnNew){
BOOL fOk = FALSE;
MODULEENTRY32 me32;
HANDLE hSnapshot;
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,GetCurrentProcessId());
me32.dwSize = sizeof( me32 );
for( fOk = Module32First( hSnapshot,&me32 ); fOk ; fOk = Module32Next(hSnapshot,&me32)){
if( me32.hModule != hmodThisDll ){
ModifyIAT(me32.hModule,szDllName,pfnOrg,pfnNew);
}
}
CloseHandle( hSnapshot );
}
FARPROC WINAPI MyGetProcAddress( HMODULE hModule,LPCSTR lpProcName ){
if( hModule == GetModuleHandle("kernel32.DLL") &&
!lstrcmpiA(lpProcName,"WriteFile") )
return (PROC)MyWriteFile;
else
return GetProcAddress( hModule,lpProcName );
}
HMODULE WINAPI MyLoadLibraryA( LPCSTR lpLibFileName ){

HMODULE hmod = LoadLibrary( lpLibFileName );
ModifyIAT(hmod,"kernel32.DLL",GetProcAddress(GetModuleHandle("kernel32.DLL"),"WriteFile"),(PROC)MyWriteFile);
ModifyIAT(hmod,"KERNEL32.DLL",GetProcAddress(GetModuleHandle("KERNEL32.DLL"),"GetProcAddress"),(PROC)MyGetProcAddress);
return hmod;
}


extern "C"_declspec(dllexport) VOID SetHook( ){
if( !hhk ){
HINSTANCE hInst = LoadLibrary(MyName);
if( !hInst )
return;
hhk = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hInst,0);
FreeLibrary( hInst );
}
}
extern"C"_declspec(dllexport) VOID UnHook(){
if( hhk )
UnhookWindowsHookEx( hhk );
}
BOOL WINAPI DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpvReserved){
hmodThisDll = hInstance;
switch( dwReason ){
case DLL_PROCESS_ATTACH:
ModifyIATs(
"kernel32.DLL",
GetProcAddress(GetModuleHandle("kernel32.DLL"),
"WriteFile"),
(PROC)MyWriteFile);
ModifyIATs(
"KERNEL32.DLL",
GetProcAddress(GetModuleHandle("KERNEL32.DLL"),"LoadLibraryA"),
(PROC)MyLoadLibraryA);
ModifyIATs("KERNEL32.DLL",
GetProcAddress(GetModuleHandle("KERNEL32.DLL"),"GetProcAddress"),
(PROC)MyGetProcAddress);
break;
case DLL_PROCESS_DETACH:
ModifyIATs(
"USER32.DLL",
(PROC)MyWriteFile,
GetProcAddress(GetModuleHandle("kernel32.DLL"),
"WriteFile"));
ModifyIATs(
"KERNEL32.DLL",
(PROC)MyLoadLibraryA,
GetProcAddress(GetModuleHandle("KERNEL32.DLL"),"LoadLibraryA"));
ModifyIATs(
"KERNEL32.DLL",
(PROC)MyGetProcAddress,
GetProcAddress(GetModuleHandle("KERNEL32.DLL"),"GetProcAddress"));
break;
}
return TRUE;
}


Main部分:

View Code
#include <windows.h>

#define DLLNAME "DLL.DLL"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HOOKAPI") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;

wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;

if (!RegisterClass (&wndclass)){
MessageBox(NULL,TEXT("DDFD"),TEXT("DDDFAS"),MB_OK);
return 0 ;
}

hwnd = CreateWindow (szAppName, // window class name
TEXT ("HOOKAPI"), // window caption
WS_OVERLAPPEDWINDOW, // window style
462, // initial x position
353, // initial y position
100, // initial x size
62, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters

if( hwnd ){
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
}

while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
PROC SetHook;
HINSTANCE hInst = LoadLibrary(DLLNAME);
if( !hInst ){
DestroyWindow(hwnd);
MessageBox(hwnd,TEXT("Can not load dll!"),TEXT("HOOKAPI"),MB_ICONHAND);
PostQuitMessage(0);
return 0;
}
SetHook = GetProcAddress(hInst,"SetHook");
if( !SetHook ){
DestroyWindow(hwnd);
MessageBox(hwnd,TEXT("Can not find function!"),TEXT("HOOKAPI"),MB_ICONHAND);
PostQuitMessage(0);
return 0;
}
//安装钩子,这样我们的dll就被映射到每一个gui程序的进程空间中
SetHook();
FreeLibrary(hInst);
return 0 ;
}
case WM_DESTROY:
{
PROC UnHook;
HINSTANCE hInst = LoadLibrary(DLLNAME);
if( !hInst ){
MessageBox(hwnd,TEXT("Can not load dll!"),TEXT("HOOKAPI"),MB_ICONHAND);
PostQuitMessage(0);
return 0;
}
UnHook = GetProcAddress(hInst,"UnHook");
if( !UnHook ){
MessageBox(hwnd,TEXT("Can not find function!"),TEXT("HOOKAPI"),MB_ICONHAND);
PostQuitMessage(0);
return 0;
}
//退出之前我们要缷载钩子
UnHook();
PostQuitMessage (0) ;
return 0 ;
}
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}


能够获取路径名的DLL

View Code
#include <windows.h>
#include <ImageHlp.h>
#include <TlHelp32.h>
#include <stdio.h>
#pragma comment(lib,"ImageHlp")

#pragma data_seg("Shared")
HHOOK hhk = NULL;
#pragma data_seg()
#pragma comment(linker, "/Section:Shared,rws")

HMODULE hmodThisDll;
#define MyName "DLL.DLL"
typedef struct _IO_STATUS_BLOCK
{
LONG Status;
LONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

typedef struct _FILE_NAME_INFORMATION
{
ULONG FileNameLength;
WCHAR FileName[MAX_PATH];
} FILE_NAME_INFORMATION;

FARPROC ZwQueryInformationFile;
//通过文件句柄,得到文件所在盘符
BOOL GetVolumeNameByHandle(HANDLE hFile, char *szFullPath)
{
//得到所有磁盘卷的卷序号
char szBuf[500];
int i;
DWORD dwVolumeSerialNumber;
memset(szBuf, 0, sizeof(szBuf));
//通过句柄得到文件的卷序号
//得到卷序号 lpFileInformation.dwVolumeSerialNumber
BY_HANDLE_FILE_INFORMATION lpFileInformation;
if(!GetFileInformationByHandle(hFile, &lpFileInformation) || (lpFileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
//通过句柄得到文件信息失败 或者 此句柄为文件夹句柄,并非文件句柄
return FALSE;
}
if(::GetLogicalDriveStringsA(sizeof(szBuf) - 1,szBuf))
{
for(i = 0; szBuf[i]; i += 4)
{
//得到卷信息->卷序号
if(!stricmp(&(szBuf[i]), "A:\\") || !stricmp(&(szBuf[i]), "B:\\"))
{
//忽略软盘 (一般不会使用,并且查询它的速度非常之慢)
continue;
}
if(GetVolumeInformationA(&(szBuf[i]), NULL, NULL,&dwVolumeSerialNumber,NULL, NULL, NULL, NULL))
{
// 与 lpFileInformation.dwVolumeSerialNumber 比较
// 如果相同,则找到该磁盘
if(dwVolumeSerialNumber == lpFileInformation.dwVolumeSerialNumber)
{
//找到
char szVolumeName[4];
memset(szVolumeName, 0, sizeof(szVolumeName));
strcpy(szVolumeName, &(szBuf[i]));
szVolumeName[strlen(szVolumeName)-1] = '\0';
//得到路径
IO_STATUS_BLOCK isb;
FILE_NAME_INFORMATION fni;
HMODULE hNt = LoadLibraryA("ntdll.dll");
if(hNt)
{
ZwQueryInformationFile = ::GetProcAddress(hNt, "ZwQueryInformationFile");
if(ZwQueryInformationFile)
{
DWORD dwfni = sizeof(fni);
DWORD dwRet = 0;
__asm
{
push 9 ;
push dwfni ;
lea eax, fni ;
push eax ;
lea eax, isb ;
push eax ;
push hFile ;
mov eax, ZwQueryInformationFile ;
call eax ;//调用 ZwQueryInformationFile 函数
mov dwRet, eax;//得到返回值
}
if(!dwRet)
{
//获取文件路径成功
fni.FileName[fni.FileNameLength/2] = 0;
//构造成完整路径名
char szFilePath[MAX_PATH+1];
memset(szFilePath, 0, sizeof(szFilePath));
WideCharToMultiByte( CP_ACP, 0, fni.FileName, -1, szFilePath, sizeof(szFilePath) - 1, NULL, NULL);
sprintf(szFullPath, "%s%s", szVolumeName, szFilePath);
return TRUE;
}
}
FreeLibrary(hNt);
}
}
}
}
}
//没有找到
return FALSE;
}

LRESULT CALLBACK GetMsgProc( int nCode,WPARAM wParam,LPARAM lParam){
return CallNextHookEx(hhk,nCode,wParam,lParam);
}
BOOL MyWriteFile(
HANDLE hFile, // 文件句柄
LPCVOID lpBuffer,// 数据缓存区指针
DWORD nNumberOfBytesToWrite, // 你要写的字节数
LPDWORD lpNumberOfBytesWritten, // 用于保存实际写入字节数的存储区域的指针
LPOVERLAPPED lpOverlapped // OVERLAPPED结构体指针
){
char szFullPath[MAX_PATH];
memset(szFullPath, 0, sizeof(szFullPath));
if(GetVolumeNameByHandle(hFile, szFullPath))
{
MessageBoxA(NULL,szFullPath,"DLL",MB_OK);
}
else MessageBoxA(NULL,"HOOK","DLL",MB_OK);
return WriteFile(hFile,lpBuffer,nNumberOfBytesToWrite,lpNumberOfBytesWritten,lpOverlapped);
}
VOID ModifyIAT(HMODULE hmodCaller,LPCSTR szDllName,PROC pfnOrg,PROC pfnNew){
PIMAGE_THUNK_DATA pITD;
ULONG ulSize;
PIMAGE_IMPORT_DESCRIPTOR pIID;
pIID = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hmodCaller,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&ulSize);
if( !pIID )
return;
for( ; pIID->Name; pIID++ ){
if( !lstrcmpiA(szDllName,(LPSTR)((PBYTE)hmodCaller+pIID->Name)) )
break;
}
if( !pIID->Name )
return;
pITD = (PIMAGE_THUNK_DATA)((PBYTE)hmodCaller+pIID->FirstThunk);
for( ; pITD->u1.Function ; pITD++ ){
PROC* ppfn = (PROC*)&pITD->u1.Function;
if(*ppfn == pfnOrg){
WriteProcessMemory(GetCurrentProcess(),ppfn,&pfnNew,sizeof(pfnNew),NULL);
return;
}
}
}
VOID ModifyIATs(LPCSTR szDllName,PROC pfnOrg,PROC pfnNew){
BOOL fOk = FALSE;
MODULEENTRY32 me32;
HANDLE hSnapshot;
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,GetCurrentProcessId());
me32.dwSize = sizeof( me32 );
for( fOk = Module32First( hSnapshot,&me32 ); fOk ; fOk = Module32Next(hSnapshot,&me32)){
if( me32.hModule != hmodThisDll ){
ModifyIAT(me32.hModule,szDllName,pfnOrg,pfnNew);
}
}
CloseHandle( hSnapshot );
}
FARPROC WINAPI MyGetProcAddress( HMODULE hModule,LPCSTR lpProcName ){
if( hModule == GetModuleHandle("kernel32.DLL") &&
!lstrcmpiA(lpProcName,"WriteFile") )
return (PROC)MyWriteFile;
else
return GetProcAddress( hModule,lpProcName );
}
HMODULE WINAPI MyLoadLibraryA( LPCSTR lpLibFileName ){

HMODULE hmod = LoadLibrary( lpLibFileName );
ModifyIAT(hmod,"kernel32.DLL",GetProcAddress(GetModuleHandle("kernel32.DLL"),"WriteFile"),(PROC)MyWriteFile);
ModifyIAT(hmod,"KERNEL32.DLL",GetProcAddress(GetModuleHandle("KERNEL32.DLL"),"GetProcAddress"),(PROC)MyGetProcAddress);
return hmod;
}


extern "C"_declspec(dllexport) VOID SetHook( ){
if( !hhk ){
HINSTANCE hInst = LoadLibrary(MyName);
if( !hInst )
return;
hhk = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hInst,0);
FreeLibrary( hInst );
}
}
extern"C"_declspec(dllexport) VOID UnHook(){
if( hhk )
UnhookWindowsHookEx( hhk );
}
BOOL WINAPI DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpvReserved){
hmodThisDll = hInstance;
switch( dwReason ){
case DLL_PROCESS_ATTACH:
ModifyIATs(
"kernel32.DLL",
GetProcAddress(GetModuleHandle("kernel32.DLL"),
"WriteFile"),
(PROC)MyWriteFile);
ModifyIATs(
"KERNEL32.DLL",
GetProcAddress(GetModuleHandle("KERNEL32.DLL"),"LoadLibraryA"),
(PROC)MyLoadLibraryA);
ModifyIATs("KERNEL32.DLL",
GetProcAddress(GetModuleHandle("KERNEL32.DLL"),"GetProcAddress"),
(PROC)MyGetProcAddress);
break;
case DLL_PROCESS_DETACH:
ModifyIATs(
"USER32.DLL",
(PROC)MyWriteFile,
GetProcAddress(GetModuleHandle("kernel32.DLL"),
"WriteFile"));
ModifyIATs(
"KERNEL32.DLL",
(PROC)MyLoadLibraryA,
GetProcAddress(GetModuleHandle("KERNEL32.DLL"),"LoadLibraryA"));
ModifyIATs(
"KERNEL32.DLL",
(PROC)MyGetProcAddress,
GetProcAddress(GetModuleHandle("KERNEL32.DLL"),"GetProcAddress"));
break;
}
return TRUE;
}



posted on 2011-11-03 01:47  zhxfl  阅读(1174)  评论(0编辑  收藏  举报

导航