[ 截获API遇到的一个奇怪的问题 ] (有收获后加到高分)

sxbyl 2001-12-04 05:29:58
我用的是Jeffery Richter的那个类,目的是截获GetSystemTime、GetLocalTime这几个API,发现有些程序可以被截获,有些却没反应。
记事本调用GetLocalTime可以被截获,Explore的调用都可以被截获,MSDev的调用也可以被截获,但奇怪的是我自己写的一个测试用的最简单的基于对话框的程序(调用GetSystemTime)却截获不到,不管是Release版还是Debug版,不管是动态连接还是静态连接,奇怪啊!对于MessageBoxA(W)的调用也是如此,记事本的可以截获到,我自己程序的却没反应。

另外,SocksCap的所有API也截获不到。

说明:Jeffery Richter使用Windows挂勾来插入DLL,通过模块的输入结来挂接API

不管问题有没有得到解决,只要讨论过程中有收获,我就加高分!
...全文
210 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
sxbyl 2001-12-05
  • 打赏
  • 举报
回复
DETOURS?只听说过,等我找找,谢了

我只是很想搞清楚这个问题的来龙去脉
eEriEs 2001-12-05
  • 打赏
  • 举报
回复
你不如用DETOURS吧,MS的东西在WINDOWS上运行是要可靠些
sxbyl 2001-12-05
  • 打赏
  • 举报
回复
faint~ 怎么制表符又没了:(

另外我发现这个东西和金山词霸有冲突,当金山运行时,如果我按了键盘,CAPIHook的LoadLibraryA就会不停地循环调用金山词霸的一个动态库而导致堆栈溢出,现在我倒是还没仔细分析原因,不知道你们碰到过这类情况没有?
sxbyl 2001-12-05
  • 打赏
  • 举报
回复
因为这个代码只是测试用的,看这可能不很舒服,将就将就吧
sxbyl 2001-12-05
  • 打赏
  • 举报
回复
Jeffery Richter的CAPIHook我是照抄的,就不贴了,现在只贴出我写的那部分
/////////////////////////////////////////////////////////////////
//CHook头文件
/////////////////////////////////////////////////////////////////
#if !defined _HOOH_H_
#define _HOOK_H_

LRESULT CALLBACK GetMsgProc(int code,WPARAM wParam,LPARAM lParam);
void WINAPI Hook_GetSystemTime(LPSYSTEMTIME lpSystemTime);
void WINAPI Hook_GetLocalTime(LPSYSTEMTIME lpSystemTime);
void WINAPI Hook_GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime);
DWORD WINAPI Hook_GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation);
int WINAPI Hook_MessageBoxA(HWND hWnd,PCSTR lpText,LPCSTR lpCaption,UINT uType);
int WINAPI Hook_MessageBoxW(HWND hWnd,PCWSTR lpText,LPCWSTR lpCaption,UINT uType);

class AFX_EXT_CLASS CHook
{
public:
CHook();
virtual ~CHook();
BOOL InitHook(HWND hWnd);
void UnHook();
BOOL IsOK()
{
return m_bIsOK;
}
protected:
BOOL m_bIsOK;
};

#endif //!defined _HOOH_H_


/////////////////////////////////////////////////////////////////
//CHook程序文件
/////////////////////////////////////////////////////////////////
// Hook.cpp: implementation of the CHook class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Hook.h"
#include "APIHook.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#pragma data_seg("Shared")
static HHOOK g_hHook=NULL;
static HWND g_hWnd=NULL;
#pragma data_seg()
#pragma comment(linker,"/Section:Shared,rws")

typedef void (WINAPI *PFNGETSYSTEMTIME)(LPSYSTEMTIME lpSystemTime);
typedef void (WINAPI *PFNGETLOCALTIME)(LPSYSTEMTIME lpSystemTime);
typedef void (WINAPI *PFNGETSYSTEMTIMEASFILETIME)(LPFILETIME lpSystemTimeAsFileTime);
typedef DWORD (WINAPI *PFNGETTIMEZONEINFORMATION)(LPTIME_ZONE_INFORMATION lpTimeZoneInformation );
typedef int (WINAPI *PFNMESSAGEBOXA)(HWND hWnd,PCSTR lpText,LPCSTR lpCaption,UINT uType);
typedef int (WINAPI *PFNMESSAGEBOXW)(HWND hWnd,PCWSTR lpText,LPCWSTR lpCaption,UINT uType);
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CHook::CHook()
{
m_bIsOK=FALSE;
}

CHook::~CHook()
{
UnHook();
}

BOOL CHook::InitHook(HWND hWnd)
{
HMODULE hModule=NULL;
if(g_hHook!= NULL)
return FALSE;
hModule=GetModuleHandle("TimeHook.DLL");
if(hModule==NULL)
{
AfxMessageBox("模块句柄无效!");
return FALSE;
}
g_hHook=SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hModule,0);
if(g_hHook==NULL)
{
AfxMessageBox("钩子加载失败!");
return FALSE;
}
g_hWnd=hWnd;
m_bIsOK=TRUE;
return TRUE;
}

void CHook::UnHook()
{
if(g_hHook)
{
m_bIsOK=FALSE;
UnhookWindowsHookEx(g_hHook);
g_hHook=NULL;
g_hWnd=NULL;
}
}

LRESULT CALLBACK GetMsgProc(int code,WPARAM wParam,LPARAM lParam)
{
return CallNextHookEx(g_hHook,code,wParam,lParam);
}

CAPIHook g_GetSystemTime("Kernel32.dll","GetSystemTime",(PROC)Hook_GetSystemTime,TRUE);
CAPIHook g_GetLocalTime("Kernel32.dll","GetLocalTime",(PROC)Hook_GetLocalTime,TRUE);
CAPIHook g_GetSystemTimeAsFileTime("Kernel32.dll","GetSystemTimeAsFileTime",(PROC)Hook_GetSystemTimeAsFileTime,TRUE);
CAPIHook g_GetTimeZoneInformation("Kernel32.dll","GetTimeZoneInformation",(PROC)Hook_GetTimeZoneInformation,TRUE);
CAPIHook g_MessageBoxA("User32.dll","MessageBoxA",(PROC)Hook_MessageBoxA,TRUE);
CAPIHook g_MessageBoxW("User32.dll","MessageBoxW",(PROC)Hook_MessageBoxW,TRUE);
void WINAPI Hook_GetSystemTime(LPSYSTEMTIME lpSystemTime)
{
char szFileName[MAX_PATH];
GetModuleFileName(NULL,szFileName,MAX_PATH);
COPYDATASTRUCT cds={0,MAX_PATH,szFileName};
SendMessage(g_hWnd,WM_COPYDATA,NULL,(LPARAM)&cds);
((PFNGETSYSTEMTIME)(PROC)g_GetSystemTime)(lpSystemTime);
}

void WINAPI Hook_GetLocalTime(LPSYSTEMTIME lpSystemTime)
{
char szFileName[MAX_PATH];
GetModuleFileName(NULL,szFileName,MAX_PATH);
COPYDATASTRUCT cds={1,MAX_PATH,szFileName};
SendMessage(g_hWnd,WM_COPYDATA,NULL,(LPARAM)&cds);
((PFNGETLOCALTIME)(PROC)g_GetLocalTime)(lpSystemTime);
}

void WINAPI Hook_GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
{
char szFileName[MAX_PATH];
GetModuleFileName(NULL,szFileName,MAX_PATH);
COPYDATASTRUCT cds={2,MAX_PATH,szFileName};
SendMessage(g_hWnd,WM_COPYDATA,NULL,(LPARAM)&cds);
((PFNGETSYSTEMTIMEASFILETIME)(PROC)g_GetSystemTimeAsFileTime)(lpSystemTimeAsFileTime);
}

DWORD WINAPI Hook_GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
{
char szFileName[MAX_PATH];
GetModuleFileName(NULL,szFileName,MAX_PATH);
COPYDATASTRUCT cds={3,MAX_PATH,szFileName};
SendMessage(g_hWnd,WM_COPYDATA,NULL,(LPARAM)&cds);
return ((PFNGETTIMEZONEINFORMATION)(PROC)g_GetTimeZoneInformation)(lpTimeZoneInformation);
}

int WINAPI Hook_MessageBoxA(HWND hWnd,PCSTR lpText,LPCTSTR lpCaption,UINT uType)
{
char szFileName[MAX_PATH];
GetModuleFileName(NULL,szFileName,MAX_PATH);
COPYDATASTRUCT cds={4,MAX_PATH,szFileName};
SendMessage(g_hWnd,WM_COPYDATA,NULL,(LPARAM)&cds);
return ((PFNMESSAGEBOXA)(PROC)g_MessageBoxA)(hWnd,lpText,lpCaption,uType);
}

int WINAPI Hook_MessageBoxW(HWND hWnd,PCWSTR lpText,LPCWSTR lpCaption,UINT uType)
{
char szFileName[MAX_PATH];
GetModuleFileName(NULL,szFileName,MAX_PATH);
COPYDATASTRUCT cds={4,MAX_PATH,szFileName};
SendMessage(g_hWnd,WM_COPYDATA,NULL,(LPARAM)&cds);
return ((PFNMESSAGEBOXW)(PROC)g_MessageBoxA)(hWnd,lpText,lpCaption,uType);
}
xtky_limi 2001-12-05
  • 打赏
  • 举报
回复
旁听
roy_hu 2001-12-05
  • 打赏
  • 举报
回复
upup
han012 2001-12-05
  • 打赏
  • 举报
回复
我也正在开发"截获API"的工具,其中也使用了Jeffery Richter的一些思想,但没有遇到你所说的问题, 所以想必是你程序自身的错误了. 如果不介意将你的部分源码贴出让大家看看.给你分析一下.
sxbyl 2001-12-05
  • 打赏
  • 举报
回复
请大家继续讨论
HWLee 2001-12-05
  • 打赏
  • 举报
回复
呵呵!恭喜恭喜!
sxbyl 2001-12-05
  • 打赏
  • 举报
回复
我知道是怎么回事了,现在才发现,真有够笨的,呵呵~~
开始我观察我的动态库是否注入到别的进程是通过GetMsgProc向主进程发送消息看到的,在这里我看到我的Test已经加载了我的那个Hook动态库
刚才又换了种方法查看,就是在VC环境中运行Test然后查看Debug框中动态库的加载信息,发现我的Hook动态库是在InitDialog之后才加载的,而我的GetSystemTime是在InitDialog中执行的,所以才出现了上面的问题

等会儿加分结帖,顺便请大家帮我看看这个帖子:
http://www.csdn.net/expert/topic/388/388744.shtm
sxbyl 2001-12-05
  • 打赏
  • 举报
回复
我的对话框程序就是MFC向导生成的程序InitDialog中又加了下面两行:
SYSTEMTIME st;
GetSystemTime(&st);
而且我由调试信息可以肯定地说,对话框程序绝对已经注入到了我的那个对话框程序中
HWLee 2001-12-05
  • 打赏
  • 举报
回复
将动态连接库注入到其他进程中有很多种方法。
最常见的方法是使用钩子函数(Hook),但是这种方法主要有两个缺点:第一如果某个进程没有加载User32.dll,那么Hook DLL将永远也不会被加载。第二Hook DLL加载的时机问题,只有在进程发出User32调用的时候, Hook DLL才有可能被加载。也就是说假设进程正在进行复杂的数值计算而没有时间进行消息调用的时候,Hook DLL是不会被加载。理论上我们没有精确的办法来确定我们的Hook DLL是否已经注入到我们想要的进程中。
另外一种最常见的方法是使用函数CreateRemoteThread,在其他进程中开启一个线程来装载DLL。应该说这是一种比较完美的解决放案,这种方法避免了上述使用钩子函数的所有缺点,但是遗憾的是这个函数只能使用在WinNT/2000下。
我觉得你的程序能hook到notepad,说明是正常的,你检查一下你测试用的对话框程序。
sxbyl 2001-12-04
  • 打赏
  • 举报
回复
等等我再试试
不过我觉得问题还不在这里
Win2000带的记事本是VC写的,但是记事本API的调用还可以被截获
han012 2001-12-04
  • 打赏
  • 举报
回复
通常情况下,IAT表通常位于模块 .idata节, 但用VC++编译出来的程序中可能没有单独的.idata节(.idata与其他节进行了合并) 所以IAT表可能位于其他某个"不可写"的节中,例如位于 ".rdata"节中.
而Jeffery Richter程序(如下),在没有判断Memory是否可写的情况下,贸然进行Memory写操作,而又没有判断WriteProcessMemory是否写成功(判断返回值). 所以我想这也许就是你不能HOOK自己(用VC++)写的程序的原因.

if (fFound) {
// The addresses match, change the import section address
WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew,
sizeof(pfnNew), NULL);
return; // We did it, get out
}

进行如下修改:
BOOL bRtn;
DWORD dwOldProtect;

// changed property of page contained IAT table to writeable
// for calling WriteProcessMemory()
bRtn = VirtualProtect(
ppfn, // region of committed pages
sizeof(DWORD), // size of the region
PAGE_READWRITE, // desired access protection
&dwOldProtect // old protection
);

// The addresses match, change the import section address
WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew,
sizeof(pfnNew), NULL);sizeof(DWORD), &cBytesMoved );

// restore old page property
VirtualProtect(
ppfn, // region of committed pages
sizeof(DWORD), // size of the region
dwOldProtect, // desired access protection
&dwOldProtect // old protection
);
black_fox 2001-12-04
  • 打赏
  • 举报
回复
学习学习
sxbyl 2001-12-04
  • 打赏
  • 举报
回复
问题也不在这里,MFC的AfxMessageBox也要调用User32的MessageBox
我用静态连接也不行
而且GetSystemTime也不涉及MFC的问题
qinzm 2001-12-04
  • 打赏
  • 举报
回复
因为你的程序是mfc动态连接的
调用mfc类里面MessageBox时
程序实际上是去mfc42.dll里面去执行了
加上那个类是来改导入表的方式
有可能只截了主程序的调用
你在程序里面用::MessageBox试试可不可以成功
qinzm 2001-12-04
  • 打赏
  • 举报
回复
跟踪一下
sxbyl 2001-12-04
  • 打赏
  • 举报
回复
当然有调用,我的测试程序是基于对话框的MFC程序,而且注入DLL的方法是用消息钩子,而且调试过程中也看到我的DLL也确实注入到测试进程中了
加载更多回复(3)

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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