热血江湖pr无法定位程序输入点点stophook

开机时蹦出“无法定位程序输入点 Jumphookoff 于动态链接库于 winsock32.dll”_百度知道
开机时蹦出“无法定位程序输入点 Jumphookoff 于动态链接库于 winsock32.dll”
winsock32.dll是不是病毒啊? 怎么解决
dll被修改或者替换。麻烦你把邮箱再发一遍给我这个是重要的系统组件,不小心关了,会出现这个提示,怀疑是正常的系统文件winsock32,建议用SREng进行检查,如果不存在则可能导致无法上网或者上网不正常
其他类似问题
为您推荐:
您可能关注的推广
定位程序输入点的相关知识
其他2条回答
肯定是染毒了 ,杀杀毒再说吧。 建议全盘扫描。
如果在system32目录下,则不是。这是用来进行网络连接的DLL,很多病毒都会用到它。
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁2346人阅读
写了一个注册表的程序,在win7下可正常运行,拿到XP系统下运行,爆出如下错误:
接下来试着把win7下的ADVAPI32.DLL拷贝到目录下,结果还是不行。
拿出IDA看下xp下面的ADVAPI32.DLL的导出函数,发现原来xp下的该dll没有导出该函数。
查看MSDN,发现RegSetKeyValue只支持Vista以上的操作系统。看来是使用了高版本系统才支持的API导致出错。
摸索了一下,改用RegSetValueExA函数,就可以了。
顺便总结一下注册表编程:
①先打开注册表
②操作子项
示例代码:
ST st = GetSystemType();
if (st==WINDOWS_XP)
r = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
&SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows&, //注册表路径
0, KEY_WRITE, &hk);
if (r!=ERROR_SUCCESS)
MessageBoxA(&写注册表失败!&, &Warn&, MB_OK);
r = RegSetValueExA(hk, //注册表句柄
&AppInit_DLLs&, //子项名称
0, REG_SZ, (BYTE*)filename, strlen(filename));
if (r!=ERROR_SUCCESS)
MessageBoxA(&写注册表失败!&, &Warn&, MB_OK);
} 注意不能直接调RegSetValueExA,传入绝对路径,这样操作是不能成功的。

版权声明:本文为博主原创文章,未经博主允许不得转载。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:329495次
积分:3853
积分:3853
排名:第3793名
原创:118篇
转载:165篇
评论:29条
(2)(1)(2)(4)(3)(2)(2)(4)(8)(2)(9)(7)(4)(9)(6)(6)(6)(5)(8)(13)(7)(1)(2)(3)(9)(1)(3)(2)(3)(12)(7)(14)(15)(27)(18)(15)(5)(11)(9)(3)(9)(7)HOOK API(三)
&& HOOK 所有程序的 MessageBox
本实例要实现HOOK MessageBox,包括MessageBoxA和MessageBoxW,其实现细节与HOOK API(二)中介绍的基本类似,唯一不同的是,本实例要实现对所有程序的HOOK MessageBox,即无论系统中哪一个程序调用MessageBox都会被重定向到我们实现的新的API中。
之前说过,在Windows中,每个进程都有自己的地址空间,进程不能调用别的进程中的函数。这里涉及到一个关键,如何让我们实现的新的API调用地址存在于所有进程的地址空间中呢?如果这无法实现的话,其他进程就无法调用到我们所实现的API。这里涉及到的关键就是,如何将我们的代码注入到别的进程中。
这里有一个实现手段,就是将我们实现的代码随着系统钩子注入到目标进程中,我们在HOOK API (一)中讲过鼠标钩子,鼠标钩子一旦启动,就会存在于每个当前运行的进程中,实现对屏幕坐标的定位。还有一个关键就是,这样的钩子需要注入到多个目标进程中,那么这就要在动态链接库(DLL)中实现,然后启动某一主调进程将这样一个DLL注入到目标进程中,从而实现HOOK API。
本实例介绍如何将实现了HOOK MessageBox的DLL注入到所有进程中的过程。
0x01 HOOK DLL的实现
建立一个MFC DLL工程
由于被实例的DLL用于MFC框架,因此创建的是MFC DLL,需要的话,也可以建立其他类型的DLL工程。
鼠标钩子回调函数
我们的DLL要跟随鼠标钩子注入到目标进程中,而鼠标钩子是系统钩子,我们需要实现其钩子回调函数。
&&&& 鼠标钩子子过程,目的是加载本dll到使用鼠标的程序中。
&&&& 鼠标钩子的作用:当鼠标在某程序窗口中时,就会加载我们这个dll。
LRESULT CALLBACK MouseProc(
&&&&&&&&&&&&&&&&&&&&&&&&int nCode,&&&& // hook code
&&&&&&&&&&&&&&&&&&&&&&&&WPARAM wParam,// message identifier
&&&&&&&&&&&&&&&&&&&&&&&&LPARAM lParam // mouse coordinates
&&&&&&&&&&&&&&&&&&&&&&&&)
&&&&return CallNextHookEx(hhk,nCode,wParam,lParam);
安装鼠标钩子
调用SetWindowsHookEx() API可以安装鼠标钩子,其中SetWindowsHookEx() 原型如下:
HHOOK SetWindowsHookEx( int idHook,HOOKPROC lpfn, INSTANCE hMod,DWORD dwThreadId )
idHook表示钩子类型,它是和钩子函数类型一一对应的。比如,WH_KEYBOARD表示安装的是键盘钩子,WH_MOUSE表示是鼠标钩子等等。
  Lpfn是钩子函数的地址。
  HMod是钩子函数所在的实例的句柄。对于线程钩子,该参数为NULL;对于系统钩子,该参数为钩子函数所在的DLL句柄。
dwThreadId 指定钩子所监视的线程的线程号。对于全局钩子,该参数为NULL。
  SetWindowsHookEx返回所安装的钩子句柄。
// 安装钩子
BOOL WINAPI StartHook(HWND hWnd)
&&&&g_hWnd = hW
&&&&hhk = ::SetWindowsHookEx(WH_MOUSE,MouseProc,g_hInstance,0);
&&&&if (hhk == NULL)
&&&&&&&&return FALSE;
&&&&&&&&return TRUE;
卸载鼠标钩子
// 卸载钩子
BOOL WINAPI StopHook()
&&&&&&&&卸载钩子时,一定要记得恢复原API入口。
&&&&&&&&这里恢复的只是主程序的原API入口,其它程序的API入口还没有被恢复。
&&&&&&&&因此我们必须处理dll退出过程,即在函数ExitInstance()中,调用恢复
&&&&&&&&API入口的函数HookOff(),只有这样,其它程序再次调用原API时,才不
&&&&&&&&会发生错误。
&&&&&&&&当我们HOOK所有程序的某个系统API时,千万要注意在ExitInstance()中
&&&&&&&&调用HookOff()!!!!!
&&&&HookOff();
&&&&if (hhk!=NULL)
&&&&&&&&UnhookWindowsHookEx(hhk);
&&&&&&&&FreeLibrary(g_hInstance);
&&&&return TRUE;
导出我们的安装和卸载函数
.def内容如下:
将StarHook和StopHook函数导出,一遍主程序安装和卸载HOOK程序。
; HookDll.def : 声明 DLL 的模块参数。
LIBRARY "HookMessageBox"
; 此处可以是显式导出
&&&&StartHook
&&&&StopHook
MFC DLL的InitInstance()函数
&&&&dll程序入口,当程序加载dll时,会执行InitInstance()
BOOL CHookDllApp::InitInstance()
&&&&CWinApp::InitInstance();
&&&&g_hInstance = AfxGetInstanceHandle();//&&&&获取当前DLL实例句柄
&&&&AdjustPrivileges();&&&&//&&&&提高权限
&&&&DWORD dwPid = ::GetCurrentProcessId();
&&&&hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,0,dwPid);
&&&&if (hProcess == NULL)
&&&&&&&&CS
&&&&&&&&str.Format(_T("OpenProcess fail, and error code = %d"),GetLastError());
&&&&&&&&AfxMessageBox(str);
&&&&&&&&return FALSE;
&&&&Inject();&&&&// 开始注入
&&&&return TRUE;
MFC DLL的ExitInstance()函数
int CHookDllApp::ExitInstance()
&&&&&&&&dll退出时,一定要记得恢复原API的入口!!!
&&&&&&&&我们编写的dll会被注入到所有目标进程中,若dll退出时,没有恢复原API入口,
&&&&&&&&那么被挂钩的程序再次调用该API时,会发生错误。
&&&&&&&&因为我们的dll程序已经退出,但原API的入口仍为我们所定义的API的入口,这
&&&&&&&&时被挂钩的程序无法找到我们实现的API,然而原API的地址又没有被恢复,也就
&&&&&&&&调用不到原API,这时程序自然会发生崩溃了。
&&&&HookOff();
&&&&return CWinApp::ExitInstance();
HOOK API实现
注入函数,保存新的,原来的API的入口
该函数的主要功能是保存新的和原来的API入口,并且在最后启动HOOK。需要注意的是,这个函数只能被调用一次,即只能进行一次注入操作。
void Inject()
&&&&if ( TRUE == bIsInJected)
&&&&&&&&return;
&&&&bIsInJected = TRUE;&&&&// 保证只调用一次
&&&&// 获取函数
&&&&HMODULE hmodle = ::LoadLibrary(_T("User32.dll"));
&&&&oldMsgBoxA = (TypeMsgBoxA) ::GetProcAddress(hmodle,"MessageBoxA");
&&&&pfMsgBoxA = (FARPROC)oldMsgBoxA;
&&&&oldMsgBoxW = (TypeMsgBoxW) ::GetProcAddress(hmodle,"MessageBoxW");
&&&&pfMsgBoxW = (FARPROC)oldMsgBoxW;
&&&&if (pfMsgBoxA == NULL)
&&&&&&&&AfxMessageBox(_T("获取 MessageBoxA 函数失败"));
&&&&&&&&return;
&&&&if ( pfMsgBoxW == NULL)
&&&&&&&&AfxMessageBox(_T("获取 MessageBoxW 函数失败"));
&&&&&&&&return;
&&&&// 保存原API地址
&&&&&&&&lea edi,oldCodeA&&&&// 取数组基地址
&&&&&&&&mov esi,pfMsgBoxA&&&&// API地址
&&&&&&&&cld&&&&&&&&&&&&&&&&&&&&// 设置方向
&&&&&&&&mov ecx,CODE_LENGTH
&&&&&&&&rep movsb
&&&&&&&&lea edi,oldCodeW
&&&&&&&&mov esi,pfMsgBoxW
&&&&&&&&cld
&&&&&&&&mov ecx,CODE_LENGTH
&&&&&&&&rep movsb
&&&&// 将新地址复制到入口
&&&&newCodeA[0] = newCodeW [0] = 0xe9;&&&&// jmp 指定代码
&&&&&&&&lea eax,MyMessageBoxA&&&&&&&&// 新API地址
&&&&&&&&mov ebx,pfMsgBoxA&&&&&&&&&&&&// 原API地址
&&&&&&&&sub eax,ebx&&&&&&&&&&&&&&&&
&&&&&&&&sub eax,CODE_LENGTH&&&&&&&&&&&&// 跳转地址 = 新API地址 - 原API地址 - 指令长度
&&&&&&&&mov dword ptr [newCodeA+1],eax // eax 32bit = 4 BYTE
&&&&&&&&lea eax,MyMessageBoxW
&&&&&&&&mov ebx,pfMsgBoxW
&&&&&&&&sub eax,ebx
&&&&&&&&sub eax,CODE_LENGTH
&&&&&&&&mov dword ptr [newCodeW + 1],eax
&&&&HookOn();&&&&//&&&&开始HOOK
写内存函数
该函数主要完成向进程控制块写写指令的任务。供HookOn()和HookOff()调用,用来将原API入口,或新的API入口写入到进程的地址空间中。
&&&&将长度为length的pcode写入到地址lpAddress中。
void WriteMemory(LPVOID lpAddress,BYTE* pcode,int length)
&&&&//&&&&保证本进程句柄不为NULL
&&&&ASSERT(hProcess != NULL);
&&&&DWORD dwTemp,dwOldProtect,dwRet,dwW
&&&&// 修改API入口前length个字节为 jmp xxxx
&&&&VirtualProtectEx(hProcess,lpAddress,length,PAGE_READWRITE,&dwOldProtect);
&&&&dwRet = WriteProcessMemory(hProcess,lpAddress,pcode,length,&dwWrited);
&&&&if ( 0 == dwRet || 0 == dwWrited)
&&&&&&&&AfxMessageBox(_T("哭!!写入失败"));
&&&&VirtualProtectEx(hProcess,lpAddress,length,dwOldProtect,&dwTemp);
用新API地址替换原API地址
&&&&用新API地址替换原API地址
void HookOn()
&&&&ASSERT(hProcess != NULL);
&&&&DWORD dwTemp,dwOldProtect,dwRet,dwW
&&&&WriteMemory(pfMsgBoxA,newCodeA,CODE_LENGTH);
&&&&WriteMemory(pfMsgBoxW,newCodeW,CODE_LENGTH);
恢复原API地址
&&&&恢复原API地址
void HookOff()
&&&&ASSERT(hProcess != NULL);
&&&&DWORD dwTemp,dwOldProtect,dwRet,dwW
&&&&WriteMemory(pfMsgBoxA,oldCodeA,CODE_LENGTH);
&&&&WriteMemory(pfMsgBoxW,oldCodeW,CODE_LENGTH);
&&&&自己用于替换的API
int WINAPI MyMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCation,UINT uType)
&&&&int nRet = 0;
&&&&HookOff();
&&&&nRet = ::MessageBoxA(hWnd,"哈哈 ^_^,MessageBoxA 被 HOOK 咯",lpCation,uType);
&&&&nRet = ::MessageBoxA(hWnd,lpText,lpCation,uType);
&&&&HookOn();
&&&&return nR
int WINAPI MyMessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCation,UINT uType)
&&&&int nRet = 0;
&&&&HookOff();
&&&&nRet = ::MessageBoxW(hWnd,_T("O(&_&)O哈哈~,MMessageBoxW 被 HOOK 咯"),lpCation,uType);
&&&&nRet = ::MessageBoxW(hWnd,lpText,lpCation,uType);
&&&&HookOn();
&&&&return nR
提升权限函数
这段代码并不是必须的,但有些时候会出现程序权限不足以获取进程句柄的情况,这个时候需要在代码执行前调用该函数来提高程序的权限。
&&&& 提升权限
bool AdjustPrivileges() {
&&&&HANDLE hT
&&&&TOKEN_PRIVILEGES
&&&&TOKEN_PRIVILEGES
&&&&DWORD dwSize=sizeof(TOKEN_PRIVILEGES);
&&&&if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
&&&&&&&&if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED) return true;
&&&&&&&&else return false;
&&&&if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
&&&&&&&&CloseHandle(hToken);
&&&&&&&&return false;
&&&&ZeroMemory(&tp, sizeof(tp));
&&&&tp.PrivilegeCount=1;
&&&&tp.Privileges[0].Luid=
&&&&tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
&&&&/* Adjust Token Privileges */
&&&&if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize)) {
&&&&&&&&CloseHandle(hToken);
&&&&&&&&return false;
&&&&// close handles
&&&&CloseHandle(hToken);
&&&&return true;
0x02 HOOK 窗体实现
HINSTANCE g_hinstDll = NULL;
// 开始 HOOK
void CHookWindowDlg::OnBnClickedButtonStart()
&&&&// TODO: 在此添加控件通知处理程序代码
&&&&g_hinstDll = LoadLibrary(_T("HookDll.dll"));
&&&&if ( NULL == g_hinstDll)
&&&&&&&&AfxMessageBox(_T("加载 HookDll.dll 失败"));
&&&&typedef BOOL (CALLBACK *HookStart)(HWND hwnd);
&&&&HookStart hookStart = NULL;
&&&&hookStart = (HookStart)::GetProcAddress(g_hinstDll,"StartHook");
&&&&if ( NULL == hookStart)
&&&&&&&&AfxMessageBox(_T("获取 StartHook 函数失败"));
&&&&&&&&return;
&&&&bool ret = hookStart(m_hWnd);
&&&&if (ret)
&&&&&&&&m_list.InsertItem(m_list.GetItemCount(),_T("启动钩子成功"));
&&&&&&&&m_list.EnsureVisible(m_list.GetItemCount()-1,FALSE);
&&&&&&&&m_list.InsertItem(m_list.GetItemCount(),_T("启动钩子失败"));
&&&&&&&&m_list.EnsureVisible(m_list.GetItemCount()-1,FALSE);
// 终止 HOOK
void CHookWindowDlg::OnBnClickedButtonStop()
&&&&// TODO: 在此添加控件通知处理程序代码
&&&&typedef BOOL (CALLBACK* HookStop)();
&&&&HookStop hookStop = NULL;
&&&&if (NULL == g_hinstDll) // 一定要加这个判断,若不为空的话就不需要在重新加载,否则会是不同的实例
&&&&&&&&g_hinstDll = LoadLibrary(_T("HookDll.dll"));
&&&&&&&&if (g_hinstDll == NULL)
&&&&&&&&&&&&AfxMessageBox(_T("加载 HookDll.dll 失败"));
&&&&&&&&&&&&return;
&&&&hookStop = ::GetProcAddress(g_hinstDll,"StopHook");
&&&&if (hookStop == NULL)
&&&&&&&&AfxMessageBox(_T("获取 StopHook 失败"));
&&&&&&&&FreeLibrary(g_hinstDll);
&&&&&&&&g_hinstDll=NULL;
&&&&&&&&return;
&&&&hookStop();
&&&&if (g_hinstDll!= NULL)
&&&&&&&&::FreeLibrary(g_hinstDll);
&&&&m_list.InsertItem(m_list.GetItemCount(),_T("终止HOOK成功"));
MessageBoxA
// MessageBoxA
void CHookWindowDlg::OnBnClickedButtonMsga()
&&&&// TODO: 在此添加控件通知处理程序代码
&&&&MessageBoxA(m_hWnd,"这是正常的MessageBoxA...","哈哈",0);
MessageBoxW
// MessageBoxW
void CHookWindowDlg::OnBnClickedButtonMsgw()
&&&&// TODO: 在此添加控件通知处理程序代码
&&&&MessageBoxW(_T("这是正常的MessageBoxW..."),_T("呵呵"),0);
本实例在自己实现的API中打印一句自己的话,然后再弹出原本的对话框。测试结果如下:
单击"MessageBoxA"按钮,调用MessageBoxA函数
可以看到,先弹出了我们自己的对话框,然后才弹出真正的对话框。
单击"MessageBoxW"按钮,调用MessageBoxW函数。
可以看到,先弹出我们的对话框,然后才弹出真正的对话框。
记事本的对话框也被HOOK了。
打开技术本,打开查找对话框,然后输入一个字符串,"查找一下",这个时候同样先弹出我们的对话框,然后才弹出原来的,找不到对话框。
0x04 附录&&HOOK DLL关键源码
// HookDll.cpp : 定义 DLL 的初始化例程。
#include "stdafx.h"
#include "HookDll.h"
#include &Windows.h&
#ifdef _DEBUG
#define new DEBUG_NEW
&&&& 全局共享变量
#pragma data_seg("Share")
HWND g_hWnd = NULL ;&&&&&&&&&&&&// 主窗口句柄
HINSTANCE g_hInstance = NULL;&&&&// 本dll实例句柄
HHOOK hhk = NULL;&&&&&&&&&&&&&&&&// 鼠标钩子句柄
#pragma data_seg()
#pragma comment(linker,"/section:Share,rws")
HANDLE hProcess = NULL;&&&&&&&&&&&&&&&&//&&&&当前进程
BOOL bIsInJected = FALSE;&&&&&&&&&&&&//&&&&是否已注入标记
TCHAR* msgToMain = new TCHAR[200];&&&&//&&&&发给主调程序的信息
&&&&原函数定义
typedef int (WINAPI *TypeMsgBoxA)(HWND hWnd,LPCSTR lpText, LPCSTR lpCaption,UINT uType);
typedef int (WINAPI *TypeMsgBoxW)(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType);
TypeMsgBoxA oldMsgBoxA = NULL;&&&&// 用于保存原函数地址
TypeMsgBoxW oldMsgBoxW = NULL;&&&&// 用于保存原楷书地址
FARPROC pfMsgBoxA = NULL;&&&&&&&&// 指向原函数地址的远指针
FARPROC pfMsgBoxW = NULL;&&&&&&&&// 指向原函数地址的远指针
#define CODE_LENGTH 5
BYTE oldCodeA[CODE_LENGTH];&&&&// 保存原来API入口代码
BYTE oldCodeW[CODE_LENGTH];&&&&// 保存原来API入口代码
BYTE newCodeA[CODE_LENGTH];&&&&// 保存新API入口代码,jmp xxxx
BYTE newCodeW[CODE_LENGTH];&&&&// 保存新API入口代码,jmp xxxx
&&&&自己编写的API
int WINAPI MyMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCation,UINT uType);
int WINAPI MyMessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCation,UINT uType);
&&&&其它函数原型声明
void HookOn();&&&&&&&&&&&&//&&&&开始HOOK
void HookOff();&&&&&&&&&&&&//&&&&关闭HOOK
void Inject();&&&&&&&&&&&&//&&&&注入
BOOL WINAPI StartHook(HWND hWnd);&&&&// 加载钩子
BOOL WINAPI StopHook();&&&&&&&&&&&&&&&&// 卸载钩子
bool AdjustPrivileges();&&&&&&&&&&&&// 提升权限
//TODO: 如果此 DLL 相对于 MFC DLL 是动态链接的,
//&&&&&&&&则从此 DLL 导出的任何调入
//&&&&&&&&MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到
//&&&&&&&&该函数的最前面。
//&&&&&&&&例如:
//&&&&&&&&extern "C" BOOL PASCAL EXPORT ExportedFunction()
//&&&&&&&&{
//&&&&&&&&&&&&AFX_MANAGE_STATE(AfxGetStaticModuleState());
//&&&&&&&&&&&&// 此处为普通函数体
//&&&&&&&&}
//&&&&&&&&此宏先于任何 MFC 调用
//&&&&&&&&出现在每个函数中十分重要。这意味着
//&&&&&&&&它必须作为函数中的第一个语句
//&&&&&&&&出现,甚至先于所有对象变量声明,
//&&&&&&&&这是因为它们的构造函数可能生成 MFC
//&&&&&&&&DLL 调用。
//&&&&&&&&有关其他详细信息,
//&&&&&&&&请参阅 MFC 技术说明 33 和 58。
// CHookDllApp
BEGIN_MESSAGE_MAP(CHookDllApp, CWinApp)
END_MESSAGE_MAP()
// CHookDllApp 构造
CHookDllApp::CHookDllApp()
&&&&// TODO: 在此处添加构造代码,
&&&&// 将所有重要的初始化放置在 InitInstance 中
// 唯一的一个 CHookDllApp 对象
CHookDllApp theA
// CHookDllApp 初始化
&&&&dll程序入口,当程序加载dll时,会执行InitInstance()
BOOL CHookDllApp::InitInstance()
&&&&CWinApp::InitInstance();
&&&&g_hInstance = AfxGetInstanceHandle();//&&&&获取当前DLL实例句柄
&&&&AdjustPrivileges();&&&&//&&&&提高权限
&&&&DWORD dwPid = ::GetCurrentProcessId();
&&&&hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,0,dwPid);
&&&&if (hProcess == NULL)
&&&&&&&&CS
&&&&&&&&str.Format(_T("OpenProcess fail, and error code = %d"),GetLastError());
&&&&&&&&AfxMessageBox(str);
&&&&&&&&return FALSE;
&&&&Inject();&&&&// 开始注入
&&&&return TRUE;
int CHookDllApp::ExitInstance()
&&&&&&&&dll退出时,一定要记得恢复原API的入口!!!
&&&&&&&&我们编写的dll会被注入到所有目标进程中,若dll退出时,没有恢复原API入口,
&&&&&&&&那么被挂钩的程序再次调用该API时,会发生错误。
&&&&&&&&因为我们的dll程序已经退出,但原API的入口仍为我们所定义的API的入口,这
&&&&&&&&时被挂钩的程序无法找到我们实现的API,然而原API的地址又没有被恢复,也就
&&&&&&&&调用不到原API,这时程序自然会发生崩溃了。
&&&&HookOff();
&&&&return CWinApp::ExitInstance();
&&&& 提升权限
bool AdjustPrivileges() {
&&&&HANDLE hT
&&&&TOKEN_PRIVILEGES
&&&&TOKEN_PRIVILEGES
&&&&DWORD dwSize=sizeof(TOKEN_PRIVILEGES);
&&&&if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
&&&&&&&&if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED) return true;
&&&&&&&&else return false;
&&&&if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
&&&&&&&&CloseHandle(hToken);
&&&&&&&&return false;
&&&&ZeroMemory(&tp, sizeof(tp));
&&&&tp.PrivilegeCount=1;
&&&&tp.Privileges[0].Luid=
&&&&tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
&&&&/* Adjust Token Privileges */
&&&&if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize)) {
&&&&&&&&CloseHandle(hToken);
&&&&&&&&return false;
&&&&// close handles
&&&&CloseHandle(hToken);
&&&&return true;
&&&& 鼠标钩子子过程,目的是加载本dll到使用鼠标的程序中。
&&&& 鼠标钩子的作用:当鼠标在某程序窗口中时,就会加载我们这个dll。
LRESULT CALLBACK MouseProc(
&&&&&&&&&&&&&&&&&&&&&&&&int nCode,&&&& // hook code
&&&&&&&&&&&&&&&&&&&&&&&&WPARAM wParam,// message identifier
&&&&&&&&&&&&&&&&&&&&&&&&LPARAM lParam // mouse coordinates
&&&&&&&&&&&&&&&&&&&&&&&&)
&&&&return CallNextHookEx(hhk,nCode,wParam,lParam);
&&&&将长度为length的pcode写入到地址lpAddress中。
void WriteMemory(LPVOID lpAddress,BYTE* pcode,int length)
&&&&//&&&&保证本进程句柄不为NULL
&&&&ASSERT(hProcess != NULL);
&&&&DWORD dwTemp,dwOldProtect,dwRet,dwW
&&&&// 修改API入口前length个字节为 jmp xxxx
&&&&VirtualProtectEx(hProcess,lpAddress,length,PAGE_READWRITE,&dwOldProtect);
&&&&dwRet = WriteProcessMemory(hProcess,lpAddress,pcode,length,&dwWrited);
&&&&if ( 0 == dwRet || 0 == dwWrited)
&&&&&&&&AfxMessageBox(_T("哭!!写入失败"));
&&&&VirtualProtectEx(hProcess,lpAddress,length,dwOldProtect,&dwTemp);
&&&&用新API地址替换原API地址
void HookOn()
&&&&ASSERT(hProcess != NULL);
&&&&DWORD dwTemp,dwOldProtect,dwRet,dwW
&&&&WriteMemory(pfMsgBoxA,newCodeA,CODE_LENGTH);
&&&&WriteMemory(pfMsgBoxW,newCodeW,CODE_LENGTH);
&&&&恢复原API地址
void HookOff()
&&&&ASSERT(hProcess != NULL);
&&&&DWORD dwTemp,dwOldProtect,dwRet,dwW
&&&&WriteMemory(pfMsgBoxA,oldCodeA,CODE_LENGTH);
&&&&WriteMemory(pfMsgBoxW,oldCodeW,CODE_LENGTH);
void Inject()
&&&&if ( TRUE == bIsInJected)
&&&&&&&&return;
&&&&bIsInJected = TRUE;&&&&// 保证只调用一次
&&&&// 获取函数
&&&&HMODULE hmodle = ::LoadLibrary(_T("User32.dll"));
&&&&oldMsgBoxA = (TypeMsgBoxA) ::GetProcAddress(hmodle,"MessageBoxA");
&&&&pfMsgBoxA = (FARPROC)oldMsgBoxA;
&&&&oldMsgBoxW = (TypeMsgBoxW) ::GetProcAddress(hmodle,"MessageBoxW");
&&&&pfMsgBoxW = (FARPROC)oldMsgBoxW;
&&&&if (pfMsgBoxA == NULL)
&&&&&&&&AfxMessageBox(_T("获取 MessageBoxA 函数失败"));
&&&&&&&&return;
&&&&if ( pfMsgBoxW == NULL)
&&&&&&&&AfxMessageBox(_T("获取 MessageBoxW 函数失败"));
&&&&&&&&return;
&&&&// 保存原API地址
&&&&&&&&lea edi,oldCodeA&&&&// 取数组基地址
&&&&&&&&mov esi,pfMsgBoxA&&&&// API地址
&&&&&&&&cld&&&&&&&&&&&&&&&&&&&&// 设置方向
&&&&&&&&mov ecx,CODE_LENGTH
&&&&&&&&rep movsb
&&&&&&&&lea edi,oldCodeW
&&&&&&&&mov esi,pfMsgBoxW
&&&&&&&&cld
&&&&&&&&mov ecx,CODE_LENGTH
&&&&&&&&rep movsb
&&&&// 将新地址复制到入口
&&&&newCodeA[0] = newCodeW [0] = 0xe9;&&&&// jmp 指定代码
&&&&&&&&lea eax,MyMessageBoxA&&&&&&&&// 新API地址
&&&&&&&&mov ebx,pfMsgBoxA&&&&&&&&&&&&// 原API地址
&&&&&&&&sub eax,ebx&&&&&&&&&&&&&&&&
&&&&&&&&sub eax,CODE_LENGTH&&&&&&&&&&&&// 跳转地址 = 新API地址 - 原API地址 - 指令长度
&&&&&&&&mov dword ptr [newCodeA+1],eax // eax 32bit = 4 BYTE
&&&&&&&&lea eax,MyMessageBoxW
&&&&&&&&mov ebx,pfMsgBoxW
&&&&&&&&sub eax,ebx
&&&&&&&&sub eax,CODE_LENGTH
&&&&&&&&mov dword ptr [newCodeW + 1],eax
&&&&HookOn();&&&&//&&&&开始HOOK
// 安装钩子
BOOL WINAPI StartHook(HWND hWnd)
&&&&g_hWnd = hW
&&&&hhk = ::SetWindowsHookEx(WH_MOUSE,MouseProc,g_hInstance,0);
&&&&if (hhk == NULL)
&&&&&&&&return FALSE;
&&&&&&&&return TRUE;
// 卸载钩子
BOOL WINAPI StopHook()
&&&&&&&&卸载钩子时,一定要记得恢复原API入口。
&&&&&&&&这里恢复的只是主程序的原API入口,其它程序的API入口还没有被恢复。
&&&&&&&&因此我们必须处理dll退出过程,即在函数ExitInstance()中,调用恢复
&&&&&&&&API入口的函数HookOff(),只有这样,其它程序再次调用原API时,才不
&&&&&&&&会发生错误。
&&&&&&&&当我们HOOK所有程序的某个系统API时,千万要注意在ExitInstance()中
&&&&&&&&调用HookOff()!!!!!
&&&&HookOff();
&&&&if (hhk!=NULL)
&&&&&&&&UnhookWindowsHookEx(hhk);
&&&&&&&&FreeLibrary(g_hInstance);
&&&&return TRUE;
&&&&自己用于替换的API
int WINAPI MyMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCation,UINT uType)
&&&&int nRet = 0;
&&&&HookOff();
&&&&nRet = ::MessageBoxA(hWnd,"哈哈 ^_^,MessageBoxA 被 HOOK 咯",lpCation,uType);
&&&&nRet = ::MessageBoxA(hWnd,lpText,lpCation,uType);
&&&&HookOn();
&&&&return nR
int WINAPI MyMessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCation,UINT uType)
&&&&int nRet = 0;
&&&&HookOff();
&&&&nRet = ::MessageBoxW(hWnd,_T("O(&_&)O哈哈~,MMessageBoxW 被 HOOK 咯"),lpCation,uType);
&&&&nRet = ::MessageBoxW(hWnd,lpText,lpCation,uType);
&&&&HookOn();
&&&&return nR
阅读(...) 评论()

我要回帖

更多关于 无法定位程序输入 的文章

 

随机推荐