mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 06:05:58 -06:00
123 lines
3.3 KiB
C++
123 lines
3.3 KiB
C++
#include "support.h"
|
|
|
|
bool PeFile::Open(const char *_data) {
|
|
data = _data;
|
|
if(!data || data[0] != 'M' || data[1] != 'Z')
|
|
return false;
|
|
int pe = Peek32le(data + 0x3C);
|
|
if(IsBadReadPtr(data + pe, sizeof(IMAGE_NT_HEADERS)))
|
|
return false;
|
|
if(memcmp(data + pe, "PE\0\0", 4))
|
|
return false;
|
|
headers = (const IMAGE_NT_HEADERS *)(data + pe);
|
|
sections = (const IMAGE_SECTION_HEADER *)(headers + 1);
|
|
exports = (const IMAGE_EXPORT_DIRECTORY *)(data + headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
|
|
|
|
/*
|
|
RLOGHEXDUMP(headers, sizeof(IMAGE_NT_HEADERS));
|
|
RLOG("\n");
|
|
RLOGHEXDUMP(sections, sizeof(IMAGE_SECTION_HEADER));
|
|
RLOG("\n");
|
|
RLOGHEXDUMP(exports, sizeof(IMAGE_EXPORT_DIRECTORY));
|
|
RLOG("\n");
|
|
*/
|
|
|
|
return true;
|
|
}
|
|
|
|
int PeFile::GetSectionIndex(const char *name) const {
|
|
for(int i = 0, n = headers->FileHeader.NumberOfSections; i < n; i++)
|
|
if(!strcmp((const char *)sections[i].Name, name))
|
|
return i;
|
|
return -1;
|
|
}
|
|
|
|
int PeFile::GetExportCount() const {
|
|
return exports ? exports->NumberOfNames : 0;
|
|
}
|
|
|
|
const char *PeFile::GetExport(int index) const {
|
|
if(!exports || index < 0 || index >= (int) exports->NumberOfNames)
|
|
return 0;
|
|
return data + ((const dword *)(data + (dword)exports->AddressOfNames))[index];
|
|
}
|
|
|
|
static bool EqualMem(const char *a, const char *b, int len, bool case_sensitive) {
|
|
if(case_sensitive)
|
|
return !memcmp(a, b, len);
|
|
else
|
|
return !memicmp(a, b, len);
|
|
}
|
|
|
|
const char *PeFile::FindExportRaw(const char *name, bool case_sensitive) const {
|
|
if(!exports || !name || !*name)
|
|
return 0;
|
|
int len = strlen(name);
|
|
const dword *pnames = (const dword *)(data + (dword)exports->AddressOfNames);
|
|
for(int i = 0; i < (int) exports->NumberOfNames; i++) {
|
|
const char *exp = data + pnames[i];
|
|
int elen = strlen(exp);
|
|
if(elen < len)
|
|
continue;
|
|
if(elen == len && EqualMem(exp, name, len, case_sensitive))
|
|
return exp;
|
|
if(EqualMem(exp, name, len, case_sensitive) && exp[len] == '@')
|
|
return exp;
|
|
if(exp[0] == '_' && EqualMem(exp + 1, name, len, case_sensitive)
|
|
&& (exp[len + 1] == '@' || exp[len + 1] == 0))
|
|
return exp;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void PeFile::LoadFuncsName(Vector<String>& names) {
|
|
|
|
if(!exports) return;
|
|
const dword *pnames = (const dword *)(data + (dword)exports->AddressOfNames);
|
|
for(int i = 0; i < (int) exports->NumberOfNames; i++) {
|
|
const char *exp = data + pnames[i];
|
|
names.Add(String(exp));
|
|
}
|
|
return;
|
|
}
|
|
|
|
ExternLib::ExternLib() {
|
|
|
|
hmod = NULL;
|
|
funcsName.Clear();
|
|
|
|
return;
|
|
}
|
|
|
|
HMODULE ExternLib::Load(const char *fn) {
|
|
hmod = LoadLibrary(fn);
|
|
if(!hmod) return 0;
|
|
|
|
PeFile pe;
|
|
if(!pe.Open((const char *)hmod)) {
|
|
FreeLibrary(hmod);
|
|
return 0;
|
|
}
|
|
|
|
funcsName.Clear();
|
|
pe.LoadFuncsName(funcsName);
|
|
|
|
if(funcsName.GetCount()<1) {
|
|
FreeLibrary(hmod);
|
|
return 0;
|
|
}
|
|
return hmod;
|
|
}
|
|
|
|
FARPROC WINAPI ExternLib::GetProc(const String& funcName) {
|
|
for(int i=0; i<funcsName.GetCount(); i++) {
|
|
String fn = funcsName[i];
|
|
//for(int j=0; j<=(fn.GetLength()-funcName.GetLength()); j++) {
|
|
// if(memcmp((char*)~fn.Mid(j, funcName.GetLength()), (char*)~funcName, funcName.GetLength()) == 0) {
|
|
if(memcmp((char*)~fn, (char*)~funcName, funcName.GetLength()) == 0) {
|
|
return GetProcAddress(hmod, (char*)~fn);
|
|
}
|
|
//}
|
|
}
|
|
return 0;
|
|
}
|