首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

得到DLL在Exe内的地址的有关问题

2012-03-18 
得到DLL在Exe内的地址的问题以下是网上得到的一段代码以下代码是可以正常执行的,我是用来得到某个dll在exe

得到DLL在Exe内的地址的问题
以下是网上得到的一段代码

以下代码是可以正常执行的,我是用来得到某个dll在exe里面的地址的。
但是如果我在main函数里面,想调用两次,得到两次dll在exe里面的地址,第一次OK,第二次就不行了,请问为什么?每次都需要将自己的窗口关闭了之后才能得到正确的地址,是不是哪里没有释放?

include <windows.h>  
#include <TLHELP32.H>  
#include <string>  
#include <tchar.h>  
   
#include "getbaseaddr.h"  
   
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  
   
char exedir[256];  
   
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  
   
typedef int (WINAPI*datMessageBoxA) (HWND, LPCTSTR, LPCTSTR, UINT);  
   
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  
   
struct data {  
   
  char targetDir[256];  
   
  DWORD dllBaseAdrr;  
   
  datMessageBoxA apiMessageBoxA;  
  char message [50];  
  char tilte [50];  
};  
   
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  
   
DWORD GetAPIAdres(char *module, char *function)  
{  
  HMODULE dh = LoadLibrary(module);  
  DWORD pf = (DWORD)GetProcAddress(dh,function);  
  FreeLibrary(dh);  
  return pf;  
}  
   
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  
   
bool EnableDebugPrivilege( bool Enable )  
{  
  bool Success = false;  
   
  HANDLE hToken = NULL;  
   
  DWORD ec = 0;  
   
  do  
  {  
  // Open the process' token  
   
  if( !OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken ) )  
  {  
  ec = GetLastError();  
  _tprintf( _T("OpenProcessToken() failed. Error: %u\n"), ec );  
  break;  
  }  
   
   
  // Lookup the privilege value  
   
  TOKEN_PRIVILEGES tp;  
   
  tp.PrivilegeCount = 1;  
   
  if( !LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid ) )  
  {  
  ec = GetLastError();  
  _tprintf( _T("LookupPrivilegeValue() failed. Error: %u\n"), ec );  
  break;  
  }  
   
   
  // Enable/disable the privilege  


   
  tp.Privileges[0].Attributes = Enable ? SE_PRIVILEGE_ENABLED : 0;  
   
  if( !AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof(tp), NULL, NULL ) )  
  {  
  ec = GetLastError();  
  _tprintf( _T("AdjustTokenPrivileges() failed. Error: %u\n"), ec );  
  break;  
  }  
   
   
  // Success  
   
  Success = true;  
   
  }  
   
  while( 0 );  
   
   
  // Cleanup  
   
  if( hToken != NULL )  
  {  
  if( !CloseHandle( hToken ) )  
  {  
  ec = GetLastError();  
  _tprintf( _T("CloseHandle(hToken) failed. Error: %u\n"), ec );  
  }  
  }  
   
   
  // Complete  
   
  return Success;  
   
}  
   
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  
   
bool ReportLoadDllEvent( DWORD ProcessId, DWORD ThreadId, const LOAD_DLL_DEBUG_INFO& Event, char ModName[MAX_MODULE_NAME32+1] )  
{  
  char message [50];  
  char tilte [50];  
  data dat;  
   
  _tprintf( _T("EVENT: DLL loaded\n") );  
  _tprintf( _T(" ProcessId: %u\n"), ProcessId );  
  _tprintf( _T(" ThreadId: %u\n"), ThreadId );  
   
  //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
   
  char iModName[MAX_MODULE_NAME32+1];  
  GetModuleNameByBase( ProcessId, Event.lpBaseOfDll, iModName );  
   
  if(!_stricmp(iModName, ModName))  
  {  
  dat.dllBaseAdrr = (DWORD)Event.lpBaseOfDll;  
   
  sprintf(message, "WINMM.dll Base Address: 0x%x", dat.dllBaseAdrr);  
  sprintf(tilte, "dbgapi32");  
  MessageBox(0, message, tilte, 0);  
  return true;  
  }  
   
  //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
   
  //char *iModName = (char*)&Event.lpImageName;  
  //if(!_stricmp(iModName, ModName))  
  //{  
  // _tprintf( _T(" WINMM.dll Base Address\n") );  
  // _tprintf( _T(" lpBaseOfDll: %08p\n"), Event.lpBaseOfDll );  
  //}  
   
  return false;  
}  
   
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  
   
void ReportTimeout( DWORD Timeout )  


{  
  _tprintf( _T("TIMEOUT: %u milliseconds\n"), Timeout );  
}  
   
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  
   
DWORD Injected_Function (data *dat)  
{  
  dat->apiMessageBoxA (0, dat->message, dat->tilte, 0);  
   
  return 0;  
}  
   
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  
   
bool dbgLoop( DWORD Timeout = INFINITE );  
   
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  
   
void Inyector_Function() // E0N  
{  
  int processID;  
  HANDLE hProcess;  
  data dat;  
  DWORD myFunSize;  
  void* FunAlloc;  
   
  //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
   
  // get process ID  
  HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);  
  PROCESSENTRY32 processINFO = { sizeof(PROCESSENTRY32) };  
   
  while(Process32Next(handle, &processINFO))  
  {  
  if(!strcmp(processINFO.szExeFile, "notepad.exe"))  
  {  
  CloseHandle(handle);  
  processID = processINFO.th32ProcessID;  
  }  
  }  
   
  CloseHandle(handle);  
   
  //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
  // Enable debug privilege  
   
  EnableDebugPrivilege( true );  
   
  //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
   
  // open the process  
  hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, false, processID);  
   
  //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
  // debug the process to find the desired dll, and get its base address  
   
  static bool attach = true;  
   
  if(DebugActiveProcess(processID) && attach) // attach the debugger  
  {  
  if(dbgLoop())  


  {  
  attach = false;  
  }  
  }  
   
  // WHY THE PROGRAM CLOSES HERE! ------------------------------  
   
  //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
  // set the api address in the struct  
   
  dat.apiMessageBoxA = (datMessageBoxA) GetAPIAdres ("USER32.DLL", "MessageBoxA");  
   
  //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
  // start variables  
   
  GetModuleFileName(GetModuleHandle(processINFO.szExeFile), dat.targetDir, 255);  
   
  sprintf(dat.message, "debugger attached!!!");  
  sprintf(dat.tilte, "dbgapi32");  
   
  //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
   
  // commit space for the struct and then write it in the process  
  data *datAlloc = (data*) VirtualAllocEx(hProcess, 0, sizeof(data), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);  
  WriteProcessMemory(hProcess, datAlloc, &dat, sizeof(data), NULL);  
   
  //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
   
  // get funcsize to inject  
  myFunSize = (long unsigned int)Inyector_Function - (long unsigned int)Injected_Function;  
   
  //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
   
  // commit space for the function, write in, and create a thread  
  FunAlloc = VirtualAllocEx(hProcess, 0, myFunSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);  
  WriteProcessMemory(hProcess, FunAlloc, (void*)Injected_Function, myFunSize, NULL);  
  CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE) FunAlloc, datAlloc, 0, NULL);  
}  
   
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  
   


[解决办法]
得到DLL的加载地址用GetModuleHandle()就行了.
[解决办法]
windbg + VRA地址查看工具
[解决办法]
main 中调用的 Inyector_Function 函数里有如下内容:


当 dbgLoop 首次被调用并成功调用一次 ReportLoadDllEvent 后,dbgLoop 返回 true,使得 attach 被赋值为 false,此后 if(DebugActiveProcess(processID) && attach) 判断永为假,意味着 dbgLoop 不会再被调用,ReportLoadDllEvent 自然也就不会再被调用了


[解决办法]
昏,用了 code 标签把代码括了起来,居然被过滤掉了。。。上贴中说的“如下内容”如下:

static bool attach = true;

if(DebugActiveProcess(processID) && attach) // attach the debugger
{
if(dbgLoop())
{
attach = false;
}
}
[解决办法]
GetModuleFileNameEx
GetModuleHandleEx
[解决办法]
GetModuleHandle,参数用DLL名字就可以了
[解决办法]
lz的意思是要取其它进程空间内的信息,用GetModuleXXXX 的话,还是得远程线程,然后准备好数据,再 LoadLibrary,再...

lz贴的代码原本就是来干这个的,只不过代码中的逻辑lz没完全看明白而已

热点排行