ultimatepp/uppdev/MySupport/ExternLib.cpp
cxl 2e4b276e07 Merge continued
git-svn-id: svn://ultimatepp.org/upp/trunk@10263 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2016-10-04 08:34:39 +00:00

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;
}