搞过API钩子的请进。。。

lzzqqq 2005-01-06 09:42:14
前一段有个朋友让给他做个工具,要实现如下功能:
1.禁止用户用记事本打开一个已有内容的文件,无论什么文件。

很自然地想到用API钩子,钩住notepad.exe的CreateFile函数,如果操作是打开,查看文件长度是否大于0,如果大于0就直接关闭notepad就完了。
钩子做完以后,倒是能钩住notepad.exe的CreateFileW函数(notepad.exe里面用的是CreateFileW)。也能转向我自定义的新函数,可我的函数一执行完毕,notepad.exe进程就非法内存访问,确定后就退出了,严重不对啊。可是我钩其他函数都没问题,象User32.dll里的TextOutA啊之类的都不会有异常,而且在notepad.exe里也能正常运行。
这个CreateFileW是Kernel32.dll里的,为什么钩住它,转向我的新函数MyCreateFileW(函数原型完全一样),我的新函数执行完毕后,就出异常呢?
...全文
217 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
tan34035 2010-06-12
  • 打赏
  • 举报
回复
mark
lzzqqq 2005-01-06
  • 打赏
  • 举报
回复
真高兴啊,结帐喽,看来今天的确是个新气象啊。。。
lzzqqq 2005-01-06
  • 打赏
  • 举报
回复
哈哈!!终于行了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
原来是我的替代函数原型有问题,贴出来给大家共享一下,免得再象我一样犯这种错误!:
这是我老出异常的替代函数=====》
HANDLE MyCreateFileW(unsigned short* lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile)
{
Beep(1000,100);
return CreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}

这是修改以后的=========》
static HANDLE WINAPI MyCreateFileW(unsigned short* lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile)
{
Beep(1000,100);
return CreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}
区别就在
================================================
HANDLE MyCreateFileW(...)//可以替代CreateFileW,但返回后出异常
static HANDLE WINAPI MyCreateFileW(...)//可以替代CreateFileW,一切正常
===============================================
我替换IAT的函数从www.codeproject.com上down的,呵呵,不要笑我懒啊。。,函数如下,大家可以直接使用。
//---------------------------------------------------------------------------
// 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;
}
lzzqqq 2005-01-06
  • 打赏
  • 举报
回复
高手们显显灵啊,为着这个东西我昨天弄到2点多。
CreateFileW函数倒是被钩住了,我的替代函数也执行了,可我的替代函数一返回,notepad.exe进程就异常了。
大家分析一下是哪的原因啊?
lzzqqq 2005-01-06
  • 打赏
  • 举报
回复
用得是SetWindowsHookEx的方法,
DllMain加载的时候看是否为notepad进程,如果是就修改IAT.
DllMain卸载时再把IAT改回来。函数是直接从www.codeproject.com上下载的,
//---------------------------------------------------------------------------
// ReplaceInOneModule
//
// Replace the address of the function in the IAT of a specific module
//---------------------------------------------------------------------------
BOOL CHookedFunction::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);
// Is this Windows 9x
if (!bFound && (*ppfn > sm_pvMaxAppAddr))
{
PBYTE pbInFunc = (PBYTE) *ppfn;
// Is this a wrapper (debug thunk) represented by PUSH instruction?
if (pbInFunc[0] == cPushOpCode)
{
ppfn = (PROC*) &pbInFunc[1];
// Is this the function we're looking for?
bFound = (*ppfn == pfnCurrent);
} // if
} // if

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;
}
zhangqu_980371 2005-01-06
  • 打赏
  • 举报
回复
你完全可以做到,在别人open这notepad.exe的时候就截断用户的操作。
danyueer 2005-01-06
  • 打赏
  • 举报
回复
你是用什么手法Hook的?如果是CreateRemoteThread,考虑一下是不是WriteProcessMemory没写好;如果是用SetWindowsHookEx然后修改IAT,检查一下卸载Hook的时候有没有把IAT原样改回去(注意一定要原样!)。

15,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧