最近在学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;
}

解决方案 »

  1.   

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

  2.   

    恢复后调用原来的会有重入问题
    你试一下这个http://download.csdn.net/detail/lactoferrin/3485453
      

  3.   

    #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;
    }编辑了一下这样好看点
      

  4.   

    谢谢啊,我下来看看!
    恩,HOOK的是一游戏的程序~
    想在游戏登陆时发第一个包的时候,不内存的某个值修改下,呵呵
    (貌似很多程序员对弄游戏辅助的很反感!)
      

  5.   


    你就没理解注入的意思。
    实际上你的额做法就是标准的远程线程DLL注入。
      

  6.   

    不是啊```我用WriteProcessMemory的时候是用窗口句柄得到进程ID来改写内存的。
    我现在弄的是写个DLL注入,虽然DLL里也有这个函数。
      

  7.   

    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;
    }
      

  8.   

    呵呵,看来老是做COPY党不行啊`
    还是要认真学才行~