Nytro Posted June 19, 2011 Report Posted June 19, 2011 [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 Quote