我用建立远程线程的方法将我的dll注入到被hook的进程中,dll的主要作用挂钩 gethostbyname 这个api。我想用自己的MY_gethostbyname来代替原来的函数。现在只成功了30%,当执行到MY_gethostbyname时就出现 “Access violation at address 000003e7,Read of address 000003e7”的错误,幸好没有崩溃。显然是返回值出现了问题。老实说我不会处理这个MY_gethostbyname的返回值,我想他返回一个虚假的ip地址,而不是实际的ip地址。代码基本是安照《windows核心编程》组装的。请各位指点一下!谢谢! 如果能帮我改一下代码就更好了。我的代码如下:#include "stdafx.h"#include <winsock2.h>
#include <windows.h>
#include <ImageHlp.h>
#pragma comment(lib, "ImageHlp")
#pragma comment(lib,"Ws2_32")
extern "C" __declspec(dllexport) struct hostent* FAR MY_gethostbyname(const char* name
);static void WINAPI ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, 
      PROC pfnOrig, PROC pfnHook, HMODULE hmodCaller);
void process();hostent *phostent=new hostent;BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
 )
{
    switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
   process();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
    }
return TRUE;
}struct hostent* FAR MY_gethostbyname(const char* name)
{
  
  //hostent *phostent=malloc(sizeof(hostent));
  //MessageBox(NULL,"I'm in MY_gethostbyname",NULL,NULL);
  
  BYTE ip[5]={0xa,0xc6,0,0xb4,0};
  char *p=(char*)ip;
  phostent->h_addr_list =(char**)&p;
  return phostent;
}///////////////////////////////////////////////////////////////////////////////
//替换IAT入口点
//pszCalleeModName:要寻找dll
//pfnCurrent:要寻找函数
//pfnNew:自己的函数
//hmodCaller:需要调用自己的函数的模块(exe、dll)的句柄static void WINAPI ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, 
   PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller) {   // Get the address of the module's import section
   ULONG ulSize;
   PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)
      ImageDirectoryEntryToData(hmodCaller, TRUE, 
      IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);   if (pImportDesc == NULL)
      return;  // This module has no import section   // Find the import descriptor containing references to callee's functions
   for (; pImportDesc->Name; pImportDesc++) {
      PSTR pszModName = (PSTR) ((PBYTE) hmodCaller + pImportDesc->Name);
      if (lstrcmpiA(pszModName, pszCalleeModName) == 0) 
         break;   // Found
   }   if (pImportDesc->Name == 0)
      return;  // This module doesn't import any functions from this callee   // Get caller's import address table (IAT) for the callee's functions
   PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA) 
      ((PBYTE) hmodCaller + pImportDesc->FirstThunk);   // Replace current function address with new function address
   for (; pThunk->u1.Function; pThunk++) {      // Get the address of the function address
      PROC* ppfn = (PROC*) &pThunk->u1.Function;      // Is this the function we're looking for?
      BOOL fFound = (*ppfn == pfnCurrent);
      
//      if (!fFound && (*ppfn > sm_pvMaxAppAddr)) {         // If this is not the function and the address is in a shared DLL, 
         // then maybe we're running under a debugger on Windows 98. In this 
         // case, this address points to an instruction that may have the 
         // correct address.//         PBYTE pbInFunc = (PBYTE) *ppfn;
//         if (pbInFunc[0] == cPushOpCode) {
//            // We see the PUSH instruction, the real function address follows
//            ppfn = (PROC*) &pbInFunc[1];            // Is this the function we're looking for?
//            fFound = (*ppfn == pfnCurrent);
//        }
//      }      if (fFound) {
         // The addresses match, change the import section address
          MessageBox(NULL,"Changing!",NULL,NULL);
  WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew, 
            sizeof(pfnNew), NULL);
         return;  // We did it, get out
      }
   }   // If we get to here, the function is not in the caller's import section
}void process()
{
PROC oldpfn=GetProcAddress(GetModuleHandle("wsock32.dll"),"gethostbyname");
    PROC newpfn=GetProcAddress(GetModuleHandle("hook.dll"),"MY_gethostbyname");
HMODULE exehandle=GetModuleHandle("COME.exe");
ReplaceIATEntryInOneMod("wsock32.dll",oldpfn,newpfn,exehandle);
}

解决方案 »

  1.   

    if (fFound) {
             // The addresses match, change the import section address
              MessageBox(NULL,"Changing!",NULL,NULL);
      WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew, 
                sizeof(pfnNew), NULL);
             return;  // We did it, get out
          }可能使这里的内存不可写
      

  2.   

    to:rivershan(笨猫)(深入浅出DLL与Hook)ReplaceIATEntryInOneMod非常成功,MY_gethostbyname也执行了!只是MY_gethostbyname写得不正确(我不会写啊)。到现在还不会
      

  3.   

    因为你返回的地址是你私有线程堆栈中的地址空间,当函数返回时,地址被操作系统回收,所以就出现防问内存错误,你可以用new出一个必要的尺寸内存空间来当作返回值
      

  4.   

    TO lianglp() 程序一开始就已经 hostent *phostent=new hostent;在MY_gethostbyname里返回的是 phostent!他是全局变量啊
    我想错误之处应该出在 hostent 结构的填充和处理。搞了几天还是不会.......我快晕了
      

  5.   

    http://community.csdn.net/Expert/topic/3094/3094992.xml?temp=.9350855
    你可以参考一下他的帖子
      

  6.   

    试一试
    static BYTE ip[5]={0xa,0xc6,0,0xb4,0};