Jump to content
Nytro

[SNIPPET] Improvements to GetProcAddress()

Recommended Posts

Posted

[sNIPPET] Improvements to GetProcAddress()

//      GetProcAddress2 - by Darawk 
// Featured @ www.RealmGX.com & www.Darawk.com
//
// GetProcAddress2 is essentially identical to the
// windows API function GetProcAddress, with one
// key difference. GetProcAddress2 does not check
// to make sure the module handle that's passed to
// it is in the loaded modules list. GetProcAddress2
// is designed to be used in conjunction with ManualMap
// or CloakDll. It allows you to access functions that
// have been exported from a dll loaded by ManualMap or
// cloaked by CloakDll. This functionality is necessary
// for plugin-based applications and late-binding functions.
#include <windows.h></windows.h>

#define IMAGE_DIRECTORY_ENTRY_EXPORT 0

// Pietrek's macro
//
// MakePtr is a macro that allows you to easily add to values (including
// pointers) together without dealing with C's pointer arithmetic. It
// essentially treats the last two parameters as DWORDs. The first
// parameter is used to typecast the result to the appropriate pointer type.
#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD_PTR)(ptr) + (DWORD_PTR)(addValue))

// This one is mine, but obviously..."adapted" from matt's original idea =p
#define MakeDelta(cast, x, y) (cast) ( (DWORD_PTR)(x) - (DWORD_PTR)(y))

// My modified version of pietrek's function, to work with PE files that have
// already been mapped into memory.
LPVOID GetPtrFromRVA( DWORD, IMAGE_NT_HEADERS *, PBYTE, bool);

FARPROC GetProcAddress2(HMODULE hMod, char *func)
{
IMAGE_DOS_HEADER *dosHd;
IMAGE_NT_HEADERS *ntHd;
IMAGE_EXPORT_DIRECTORY *ied;
char **names;
unsigned short *ordinals;
FARPROC *funcs;

// Make sure we got a valid pointer
if(!hMod || hMod == INVALID_HANDLE_VALUE)
return NULL;

dosHd = (IMAGE_DOS_HEADER *)hMod;

// Verify the DOS header
if(dosHd->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;

ntHd = MakePtr(IMAGE_NT_HEADERS *, hMod, dosHd->e_lfanew);

// Verify the NT header
if(ntHd->Signature != IMAGE_NT_SIGNATURE)
return NULL;

ied = (IMAGE_EXPORT_DIRECTORY *)GetPtrFromRVA((DWORD)(ntHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress),
ntHd,
(PBYTE)hMod, true);

names = (char **)GetPtrFromRVA(ied->AddressOfNames, ntHd, (PBYTE)hMod, true);
ordinals = (unsigned short *)GetPtrFromRVA(ied->AddressOfNameOrdinals, ntHd, (PBYTE)hMod, true);
funcs = (FARPROC *)GetPtrFromRVA(ied->AddressOfFunctions, ntHd, (PBYTE)hMod, true);

unsigned int i;
for(i = 0; i < ied->NumberOfNames; i++)
if(!stricmp((char *)GetPtrFromRVA((DWORD)names[i], ntHd, (PBYTE)hMod, true), func))
break;

if(i >= ied->NumberOfNames)
return NULL;

return MakePtr(FARPROC, hMod, funcs[ordinals[i]]);
}

// Matt Pietrek's function
PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(DWORD rva, PIMAGE_NT_HEADERS pNTHeader)
{
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader);
unsigned int i;

for ( i = 0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ )
{
// This 3 line idiocy is because Watcom's linker actually sets the
// Misc.VirtualSize field to 0. (!!! - Retards....!!!)
DWORD size = section->Misc.VirtualSize;
if ( 0 == size )
size = section->SizeOfRawData;

// Is the RVA within this section?
if ( (rva >= section->VirtualAddress) &&
(rva < (section->VirtualAddress + size)))
return section;
}

return 0;
}

unsigned long GetMappedSectionOffset(IMAGE_NT_HEADERS *ntHd, IMAGE_SECTION_HEADER *seHd, void *base)
{
IMAGE_SECTION_HEADER *section = IMAGE_FIRST_SECTION(ntHd);
unsigned int i;
unsigned long offset = MakeDelta(unsigned long, section, base);

for(i = 0; i < ntHd->FileHeader.NumberOfSections; i++, section++)
{
if(section->Name == seHd->Name)
{
offset = MakeDelta(unsigned long, section->VirtualAddress, section->PointerToRawData);
break;
}

//offset += (section->SizeOfRawData > ntHd->OptionalHeader.SectionAlignment ?
// section->SizeOfRawData - ntHd->OptionalHeader.SectionAlignment :
// ntHd->OptionalHeader.SectionAlignment - section->SizeOfRawData);
}

return offset;
}

// This function is also Pietrek's
LPVOID GetPtrFromRVA( DWORD rva, IMAGE_NT_HEADERS *pNTHeader, PBYTE imageBase, bool mapped )
{
PIMAGE_SECTION_HEADER pSectionHdr;
INT delta;
unsigned long offset = 0;

pSectionHdr = GetEnclosingSectionHeader( rva, pNTHeader );

if(mapped)
offset = GetMappedSectionOffset(pNTHeader, pSectionHdr, imageBase);

if ( !pSectionHdr )
return 0;

delta = (INT)(pSectionHdr->VirtualAddress-pSectionHdr->PointerToRawData);
return (PVOID) ( imageBase + rva - delta + offset);
}

Sursa: ic0de.org

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...