请教下大家,关于HOOK API函数时需要改变页面文件属性的问题!

lifeix1985 2012-01-22 10:03:41
最近在学HOOK,于是在网上COPY了一些代码,但发现很多都不能编译通过的`
今天在看雪上看到 小扫地僧 的代码,COPY下来编译了个DLL,是HOOOK MessageBox函数的,然后注入了自己的测试程序,发现能HOOK成功。
于是把代码改了下,想把它弄成HOOK SEND 函数的。
但是注入程序的时候,能把那个SEDN HOOK ,但是程序会崩溃。下面是代码,请大家指点下!
#include <windows.h>
#define HookModName "wsock32.dll" //HOOK的模块和API
#define HookApiName "send"

//修改API入口为 mov eax, 00400000;jmp eax是程序能跳转到自己的函数
BYTE g_btNewBytes[8] = { 0xB8, 0x0, 0x0, 0x40, 0x0, 0xFF, 0xE0, 0x0 };
//保存原API入口的8个字节
DWORD g_dwOldBytes[8] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
//API地址
void * m_AddrAPI;
//定义自己的API,参数表和原函数一致,MyHookAPI中调用的也一样
int WINAPI MyHookAPI(SOCKET, const char FAR *, int , int);
typedef int(*PFunSend)( SOCKET, const char FAR *, int , int); // send 函数指针
PFunSend pSend;
BOOL APIENTRY DllMain( HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
if(ul_reason_for_call==DLL_PROCESS_ATTACH)
{
//找到API地址
::MessageBox(0,"sdfdsf",0,0);//这句是为了方便的知道,DLL是不是成功的被加载了。。
HMODULE hWsock = LoadLibrary(HookModName);
m_AddrAPI = (void *)GetProcAddress( hWsock,HookApiName);
//保存原始字节

ReadProcessMemory(INVALID_HANDLE_VALUE,m_AddrAPI, ( void * )g_dwOldBytes, sizeof( DWORD )*2, NULL );
//将00400000替换为我们函数的地址
*( DWORD* )( g_btNewBytes + 1 ) = ( DWORD )MyHookAPI;
//改写API跳向MyHookAPI
DWORD dwOldProc;
DWORD dwNewProc;
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,PAGE_READWRITE,&dwOldProc);
WriteProcessMemory( INVALID_HANDLE_VALUE,m_AddrAPI,( void * )g_btNewBytes, sizeof( DWORD )*2, NULL );
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,dwOldProc, &dwNewProc );
}

return TRUE;
}
int _stdcall MyHookAPI(SOCKET s, const char FAR *buf, int len, int flags)
{ int Ret;
DWORD dwOldProc;
DWORD dwNewProc;
//恢复指令
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,PAGE_READWRITE,&dwOldProc);//看到网上的大能说要修改页面属性,于是我把这句代码加了进去。但是被注入的程序还是崩溃。
WriteProcessMemory( INVALID_HANDLE_VALUE,m_AddrAPI,( void * )g_dwOldBytes, sizeof( DWORD )*2, NULL );
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,dwOldProc, &dwNewProc );
//调用
::MessageBox(0,"HOOK了",0,0);//SEND函数入口被修改了,就弹出个窗口。问题在这里,当被注入的程序调用了SEND函数的时候,是弹出了这个窗口。接着程序就马上崩溃了。提示某个指令地址引用的内存地址不能read.
Ret=pSend(s, buf, len, flags );
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,PAGE_READWRITE,&dwOldProc);
//重新改写,为下次调用
WriteProcessMemory( INVALID_HANDLE_VALUE,m_AddrAPI,( void * )g_btNewBytes, sizeof( DWORD )*2, NULL );
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,dwOldProc, &dwNewProc );
return Ret;
}
...全文
138 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
lifeix1985 2012-01-23
  • 打赏
  • 举报
回复
呵呵,看来老是做COPY党不行啊`
还是要认真学才行~
Lactoferrin 2012-01-23
  • 打赏
  • 举报
回复
原因看来是psend没初始化
lifeix1985 2012-01-23
  • 打赏
  • 举报
回复
能啊````游戏里玩了一下,没崩溃哦``!用久就不知道了 呵呵`
Lactoferrin 2012-01-23
  • 打赏
  • 举报
回复
你这样能成功发包么
lifeix1985 2012-01-23
  • 打赏
  • 举报
回复
还有谢谢扫地小僧的代码!
lifeix1985 2012-01-23
  • 打赏
  • 举报
回复
Lactoferrin大能,你的程序接口我都不知道 呵呵``
还有谢谢大家。祝大家龙年健康快乐!
刚刚用OD看了下,说我00000的地址不能读无法调试。于是该了下代码 现在能用了`呵呵``
typedef int(*PFunSend)( SOCKET, const char FAR *, int , int); // send 函数指针
我没用这个函数指针了!
我把#include "winsock.h" 包含了进来!然后Ret=send(s, buf, len, flags );就OK了`
测试了下,用注入器注入游戏,只要一发包, 就MessageBox。

#include <windows.h>
#include "winsock.h"
#define HookModName "ws2_32.dll" //HOOK的模块和API
#define HookApiName "send"

//修改API入口为 mov eax, 00400000;jmp eax是程序能跳转到自己的函数
BYTE g_btNewBytes[8] = { 0xB8, 0x0, 0x0, 0x40, 0x0, 0xFF, 0xE0, 0x0 };
//保存原API入口的8个字节
DWORD g_dwOldBytes[8] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
//API地址
void * m_AddrAPI;
//定义自己的API,参数表和原函数一致,MyHookAPI中调用的也一样
int WINAPI MyHookAPI(SOCKET, const char FAR *, int , int);
//typedef int(*PFunSend)( SOCKET, const char FAR *, int , int); // send 函数指针
//PFunSend pSend;
BOOL APIENTRY DllMain( HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
if(ul_reason_for_call==DLL_PROCESS_ATTACH)
{
DWORD dwOldProc;
DWORD dwNewProc;
//找到API地址
::MessageBox(0,"sdfdsf",0,0);
HMODULE hWsock = LoadLibrary(HookModName);
m_AddrAPI = (void *)GetProcAddress( hWsock,HookApiName);
//保存原始字节
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,PAGE_READWRITE,&dwOldProc);
ReadProcessMemory(INVALID_HANDLE_VALUE,m_AddrAPI, ( void * )g_dwOldBytes, sizeof( DWORD )*2, NULL );
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,dwOldProc, &dwNewProc );
//将00400000替换为我们函数的地址
*( DWORD* )( g_btNewBytes + 1 ) = ( DWORD )MyHookAPI;
//改写API跳向MyHookAPI

VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,PAGE_READWRITE,&dwOldProc);
WriteProcessMemory( INVALID_HANDLE_VALUE,m_AddrAPI,( void * )g_btNewBytes, sizeof( DWORD )*2, NULL );
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,dwOldProc, &dwNewProc );
}

return TRUE;
}
int _stdcall MyHookAPI(SOCKET s, const char FAR *buf, int len, int flags)
{ int Ret;
DWORD dwOldProc;
DWORD dwNewProc;
//恢复指令
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,PAGE_READWRITE,&dwOldProc);
WriteProcessMemory( INVALID_HANDLE_VALUE,m_AddrAPI,( void * )g_dwOldBytes, sizeof( DWORD )*2, NULL );
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,dwOldProc, &dwNewProc );
//调用
::MessageBox(0,"efsd",0,0);
Ret=send(s, buf, len, flags);
//Ret=pSend(s, buf, len, flags );
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,PAGE_READWRITE,&dwOldProc);
//重新改写,为下次调用
WriteProcessMemory( INVALID_HANDLE_VALUE,m_AddrAPI,( void * )g_btNewBytes, sizeof( DWORD )*2, NULL );
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,dwOldProc, &dwNewProc );
return Ret;
}
lifeix1985 2012-01-23
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 otishiono 的回复:]
引用 1 楼 lifeix1985 的回复:

顺便请教下,为什么我自己写了个程序,不 用DLL注入,直接用WriteProcessMemory和ReadProcessMemory来写和读远程内存不会崩溃和报错呢?


你就没理解注入的意思。
实际上你的额做法就是标准的远程线程DLL注入。
[/Quote]
不是啊```我用WriteProcessMemory的时候是用窗口句柄得到进程ID来改写内存的。
我现在弄的是写个DLL注入,虽然DLL里也有这个函数。
Lactoferrin 2012-01-22
  • 打赏
  • 举报
回复
你先不看,直接用看行不行,我给的接口还是很简单的
lifeix1985 2012-01-22
  • 打赏
  • 举报
回复
大能啊``,你这代码也太恐怖了吧``
很长的代码啊
没有注释,孙鑫老师的视频我都没看完,这份代码完全看不懂啊 ```还是先留着,等以后再看了!
不知道有没有什么简单点的方法吗?
Tishion 2012-01-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 lifeix1985 的回复:]

顺便请教下,为什么我自己写了个程序,不 用DLL注入,直接用WriteProcessMemory和ReadProcessMemory来写和读远程内存不会崩溃和报错呢?
[/Quote]

你就没理解注入的意思。
实际上你的额做法就是标准的远程线程DLL注入。
Lactoferrin 2012-01-22
  • 打赏
  • 举报
回复
如果游戏有目的地保护那么就没这么简单
lifeix1985 2012-01-22
  • 打赏
  • 举报
回复
谢谢啊,我下来看看!
恩,HOOK的是一游戏的程序~
想在游戏登陆时发第一个包的时候,不内存的某个值修改下,呵呵
(貌似很多程序员对弄游戏辅助的很反感!)
Lactoferrin 2012-01-22
  • 打赏
  • 举报
回复
你hook的什么程序?
lifeix1985 2012-01-22
  • 打赏
  • 举报
回复
#include <windows.h>
#define HookModName "wsock32.dll" //HOOK的模块和API
#define HookApiName "send"

//修改API入口为 mov eax, 00400000;jmp eax是程序能跳转到自己的函数
BYTE g_btNewBytes[8] = { 0xB8, 0x0, 0x0, 0x40, 0x0, 0xFF, 0xE0, 0x0 };
//保存原API入口的8个字节
DWORD g_dwOldBytes[8] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
//API地址
void * m_AddrAPI;
//定义自己的API,参数表和原函数一致,MyHookAPI中调用的也一样
int WINAPI MyHookAPI(SOCKET, const char FAR *, int , int);
typedef int(*PFunSend)( SOCKET, const char FAR *, int , int); // send 函数指针
PFunSend pSend;
BOOL APIENTRY DllMain( HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
if(ul_reason_for_call==DLL_PROCESS_ATTACH)
{
//找到API地址
::MessageBox(0,"sdfdsf",0,0);//这句是为了方便的知道,DLL是不是成功的被加载了。。
HMODULE hWsock = LoadLibrary(HookModName);
m_AddrAPI = (void *)GetProcAddress( hWsock,HookApiName);
//保存原始字节

ReadProcessMemory(INVALID_HANDLE_VALUE,m_AddrAPI, ( void * )g_dwOldBytes, sizeof( DWORD )*2, NULL );
//将00400000替换为我们函数的地址
*( DWORD* )( g_btNewBytes + 1 ) = ( DWORD )MyHookAPI;
//改写API跳向MyHookAPI
DWORD dwOldProc;
DWORD dwNewProc;
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,PAGE_READWRITE,&dwOldProc);
WriteProcessMemory( INVALID_HANDLE_VALUE,m_AddrAPI,( void * )g_btNewBytes, sizeof( DWORD )*2, NULL );
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,dwOldProc, &dwNewProc );
}

return TRUE;
}
int _stdcall MyHookAPI(SOCKET s, const char FAR *buf, int len, int flags)
{ int Ret;
DWORD dwOldProc;
DWORD dwNewProc;
//恢复指令
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,PAGE_READWRITE,&dwOldProc);//看到网上的大能说要修改页面属性,于是我把这句代码加了进去。但是被注入的程序还是崩溃。
WriteProcessMemory( INVALID_HANDLE_VALUE,m_AddrAPI,( void * )g_dwOldBytes, sizeof( DWORD )*2, NULL );
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,dwOldProc, &dwNewProc );
//调用
::MessageBox(0,"HOOK了",0,0);//SEND函数入口被修改了,就弹出个窗口。问题在这里,当被注入的程序调用了SEND函数的时候,是弹出了这个窗口。接着程序就马上崩溃了。提示某个指令地址引用的内存地址不能read.
Ret=pSend(s, buf, len, flags );
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,PAGE_READWRITE,&dwOldProc);
//重新改写,为下次调用
WriteProcessMemory( INVALID_HANDLE_VALUE,m_AddrAPI,( void * )g_btNewBytes, sizeof( DWORD )*2, NULL );
VirtualProtectEx(INVALID_HANDLE_VALUE,m_AddrAPI,sizeof( DWORD )*2,dwOldProc, &dwNewProc );
return Ret;
}

编辑了一下这样好看点
Lactoferrin 2012-01-22
  • 打赏
  • 举报
回复
恢复后调用原来的会有重入问题
你试一下这个http://download.csdn.net/detail/lactoferrin/3485453
lifeix1985 2012-01-22
  • 打赏
  • 举报
回复
顺便请教下,为什么我自己写了个程序,不 用DLL注入,直接用WriteProcessMemory和ReadProcessMemory来写和读远程内存不会崩溃和报错呢?

15,471

社区成员

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

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