读书人

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

发布时间: 2012-03-18 13:55:38 作者: rapoo

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

读书人网 >VC/MFC

热点推荐