得到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没完全看明白而已