121 lines
3.9 KiB
C
121 lines
3.9 KiB
C
#include "export.h"
|
|
|
|
IMAGE_EXPORT_DIRECTORY *get_loaded_export_hdr(void *image)
|
|
{
|
|
IMAGE_DOS_HEADER *dos;
|
|
IMAGE_NT_HEADERS32 *nt32;
|
|
IMAGE_NT_HEADERS64 *nt64;
|
|
IMAGE_FILE_HEADER *file;
|
|
IMAGE_OPTIONAL_HEADER32 *opt32;
|
|
IMAGE_OPTIONAL_HEADER64 *opt64;
|
|
|
|
dos = (IMAGE_DOS_HEADER *)image;
|
|
if (dos->e_magic != IMAGE_DOS_SIGNATURE) return NULL;
|
|
nt32 = (IMAGE_NT_HEADERS32*)&((char*)image)[dos->e_lfanew];
|
|
if (nt32->Signature != IMAGE_NT_SIGNATURE) return NULL;
|
|
|
|
file = &nt32->FileHeader;
|
|
if (IMAGE_FILE_MACHINE_I386 == file->Machine)
|
|
{
|
|
opt32 = &nt32->OptionalHeader;
|
|
return (IMAGE_EXPORT_DIRECTORY *)&((char *)image)
|
|
[opt32->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
|
|
.VirtualAddress];
|
|
}
|
|
else if (IMAGE_FILE_MACHINE_AMD64 == file->Machine)
|
|
{
|
|
nt64 = (IMAGE_NT_HEADERS64*)nt32;
|
|
opt64 = &nt64->OptionalHeader;
|
|
return (IMAGE_EXPORT_DIRECTORY *)&((char *)image)
|
|
[opt64->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
|
|
.VirtualAddress];
|
|
}
|
|
else return NULL;
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
|
|
void *get_loaded_export_function_by_name(void *image, char *name)
|
|
{
|
|
IMAGE_EXPORT_DIRECTORY *export;
|
|
uint32_t *eft, *ent; //functions, names
|
|
uint16_t *eot; //offsets
|
|
|
|
export = get_loaded_export_hdr(image);
|
|
if (NULL == export) return NULL;
|
|
eft = (uint32_t *)&((char *)image)[export->AddressOfFunctions];
|
|
ent = (uint32_t *)&((char *)image)[export->AddressOfNames];
|
|
eot = (uint16_t *)&((char *)image)[export->AddressOfNameOrdinals];
|
|
|
|
for (int i = 0; i < export->NumberOfNames; i++)
|
|
{
|
|
if (0 == pic_strncmp((char *)&((char *)image)[ent[i]],
|
|
name, pic_strlen(name)))
|
|
return (char *)&((char*)image)[eft[eot[i]]];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
/*kernelMZ is a pointer on the mz signature of the kernel32.dll
|
|
*which is loaded somewhere in the calling processes address space */
|
|
__attribute__((sysv_abi) )void *get_function_from_lib_by_kernelMZ(void *kernelMZ, char *libName,
|
|
char *funcName)
|
|
{
|
|
char loadLibraryName[15];
|
|
char getProcAddrName[15];
|
|
void *dll;
|
|
llib loadLibrary;
|
|
gpa getProcAddr;
|
|
|
|
//i know it looks ugly but we have to endure it
|
|
//sine we mustn't have the string in a seperate .data section
|
|
loadLibraryName[0] = 'L';
|
|
loadLibraryName[1] = 'o';
|
|
loadLibraryName[2] = 'a';
|
|
loadLibraryName[3] = 'd';
|
|
loadLibraryName[4] = 'L';
|
|
loadLibraryName[5] = 'i';
|
|
loadLibraryName[6] = 'b';
|
|
loadLibraryName[7] = 'r';
|
|
loadLibraryName[8] = 'a';
|
|
loadLibraryName[9] = 'r';
|
|
loadLibraryName[10] = 'y';
|
|
loadLibraryName[11] = 'E';
|
|
loadLibraryName[12] = 'x';
|
|
loadLibraryName[13] = 'A';
|
|
loadLibraryName[14] = '\x00';
|
|
|
|
getProcAddrName[0] = 'G';
|
|
getProcAddrName[1] = 'e';
|
|
getProcAddrName[2] = 't';
|
|
getProcAddrName[3] = 'P';
|
|
getProcAddrName[4] = 'r';
|
|
getProcAddrName[5] = 'o';
|
|
getProcAddrName[6] = 'c';
|
|
getProcAddrName[7] = 'A';
|
|
getProcAddrName[8] = 'd';
|
|
getProcAddrName[9] = 'd';
|
|
getProcAddrName[10] = 'r';
|
|
getProcAddrName[11] = 'e';
|
|
getProcAddrName[12] = 's';
|
|
getProcAddrName[13] = 's';
|
|
getProcAddrName[14] = '\x00';
|
|
|
|
loadLibrary = get_loaded_export_function_by_name(kernelMZ,
|
|
loadLibraryName);
|
|
getProcAddr = get_loaded_export_function_by_name(kernelMZ,
|
|
getProcAddrName);
|
|
if (NULL == loadLibrary) return NULL;
|
|
if (NULL == libName) {
|
|
dll = kernelMZ;
|
|
}
|
|
else {
|
|
dll = loadLibrary(libName, 0, 0);
|
|
}
|
|
if (NULL == dll) return NULL;
|
|
if (NULL == getProcAddr) return NULL;
|
|
return getProcAddr(dll, funcName);
|
|
}
|
|
|