some symbol lookup fixes and performance enhancements

This commit is contained in:
Cheat Engine 2023-03-10 22:28:37 +01:00
parent 3d972a4e98
commit 0b9d34f7f4
7 changed files with 184 additions and 69 deletions

View File

@ -4160,6 +4160,7 @@ BOOL Module32Next(HANDLE hSnapshot, PModuleListEntry moduleentry)
moduleentry->moduleName=ml->moduleList[ml->moduleListIterator].moduleName;
moduleentry->moduleSize=ml->moduleList[ml->moduleListIterator].moduleSize;
moduleentry->part=ml->moduleList[ml->moduleListIterator].part;
moduleentry->fileOffset=ml->moduleList[ml->moduleListIterator].fileOffset;
moduleentry->is64bit=ml->moduleList[ml->moduleListIterator].is64bit;
ml->moduleListIterator++;
@ -4354,6 +4355,7 @@ HANDLE CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID)
while (fgets(s, 511, f)) //read a line into s
{
unsigned long long start, stop;
uint32_t fileoffset;
char protectionstring[32],modulepath[511];
unsigned char elfident[8];
@ -4361,10 +4363,10 @@ HANDLE CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID)
memset(modulepath, 0, 255);
sscanf(s, "%llx-%llx %s %*s %*s %*s %[^\t\n]\n", &start, &stop, protectionstring, modulepath);
sscanf(s, "%llx-%llx %s %x %*s %*s %[^\t\n]\n", &start, &stop, protectionstring, &fileoffset, modulepath);
if (ProtectionStringToType(protectionstring)==MEM_MAPPED)
continue;
//if (ProtectionStringToType(protectionstring)==MEM_MAPPED)
// continue;
if (modulepath[0]) //it's something
{
@ -4372,7 +4374,7 @@ HANDLE CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID)
if (strcmp(modulepath, "[heap]")==0) //not static enough to mark as a 'module'
continue;
// debug_log("%s\n", modulepath);
// debug_log("Checking if %s is a module\n", modulepath);
if (strcmp(modulepath, "[vdso]")!=0) //temporary patch as to not rename vdso, because it is treated differently by the ce symbol loader
{
@ -4393,6 +4395,7 @@ HANDLE CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID)
if (i==0)
{
//printf("%s is unreadable(%llx)\n", modulepath, start);
// debug_log("unreadable so no");
continue; //unreadable
}
@ -4410,20 +4413,25 @@ HANDLE CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID)
}
}
if ((part==0) && ((elfident[0]!=ELFMAG0) || (elfident[1]!=ELFMAG1) || (elfident[2]!=ELFMAG2) || (elfident[3]!=ELFMAG3) ) ) // 7f 45 4c 46 , not yet in the list, and not an ELF
if (((elfident[0]!=ELFMAG0) || (elfident[1]!=ELFMAG1) || (elfident[2]!=ELFMAG2) || (elfident[3]!=ELFMAG3) ) ) // 7f 45 4c 46 , not yet in the list, and not an ELF
{
//printf("%s is not an ELF(%llx). tempbuf=%s\n", modulepath, start, tempbuf);
// debug_log("%s is not an ELF (%p = %.2x %.2x %.2x %.2x)\n", modulepath, start, elfident[0], elfident[1], elfident[2], elfident[3] );
continue; //not an ELF
}
//it's either an ELF, or there is another entry with this name in the list that is an ELF
if (dwFlags & TH32CS_SNAPFIRSTMODULE)
debug_log("Adding %s as a module\n", modulepath);
//e.g:
//71e8f0f86000-71e8f0fb5000 r-xp 00001000 08:13 5488717 /data/app/com.unciv.app-8m-YznaBZ84t5VpB6J6Stg==/split_config.x86_64.apk
//if (dwFlags & TH32CS_SNAPFIRSTMODULE)
// debug_log("Adding %s as a module\n", modulepath);
mle=&ml->moduleList[ml->moduleCount];
mle->moduleName=strdup(modulepath);
mle->baseAddress=start;
mle->fileOffset=fileoffset;
mle->moduleSize=stop-start; //GetModuleSize(modulepath, 0); GetModuleSize is not a good idea as some modules have gaps in them, and alloc will use those gaps (e.g ld*.so)
mle->part=part;

View File

@ -47,6 +47,7 @@
typedef struct
{
unsigned long long baseAddress;
uint32_t fileOffset;
int part;
int is64bit;
int moduleSize;

View File

@ -54,10 +54,10 @@ __thread int debugfd;
__thread char* threadname;
#define CESERVERVERSION 5
#define CESERVERVERSION 6 //6 because modulelist got changed
char versionstring[]="CHEATENGINE Network 2.2";
char versionstring[]="CHEATENGINE Network 2.3";
char *CESERVERPATH;
volatile int connections=0;
@ -623,6 +623,7 @@ case CMD_SETTHREADCONTEXT:
m=(PCeModuleEntry)&outputstream[pos];
m->modulebase=me.baseAddress;
m->modulesize=me.moduleSize;
m->modulefileoffset=me.fileOffset;
m->modulenamesize=namelen;
m->modulepart=me.part;
m->result=1;
@ -726,6 +727,7 @@ case CMD_SETTHREADCONTEXT:
r->modulebase=me.baseAddress;
r->modulesize=me.moduleSize;
r->modulenamesize=strlen(me.moduleName);
r->modulefileoffset=me.fileOffset;
r->modulepart=me.part;
@ -1079,37 +1081,45 @@ case CMD_SETTHREADCONTEXT:
{
//get the list and send it to the client
//zip it first
uint32_t symbolpathsize;
struct {
uint32_t fileoffset;
uint32_t symbolpathsize;
} input;
//debug_log("CMD_GETSYMBOLLISTFROMFILE\n");
if (recvall(currentsocket, &symbolpathsize, sizeof(symbolpathsize), MSG_WAITALL)>0)
if (recvall(currentsocket, &input, sizeof(input), MSG_WAITALL)>0)
{
char *symbolpath=(char *)malloc(symbolpathsize+1);
symbolpath[symbolpathsize]='\0';
if (input.fileoffset)
debug_log("CMD_GETSYMBOLLISTFROMFILE with fileoffset=%x\n",input.fileoffset);
if (recvall(currentsocket, symbolpath, symbolpathsize, MSG_WAITALL)>0)
char *symbolpath=(char *)malloc(input.symbolpathsize+1);
symbolpath[input.symbolpathsize]='\0';
if (recvall(currentsocket, symbolpath, input.symbolpathsize, MSG_WAITALL)>0)
{
unsigned char *output=NULL;
//debug_log("symbolpath=%s\n", symbolpath);
if (input.fileoffset)
debug_log("symbolpath=%s\n", symbolpath);
if (memcmp("/dev/", symbolpath, 5)!=0) //don't even bother if it's a /dev/ file
GetSymbolListFromFile(symbolpath, &output);
GetSymbolListFromFile(symbolpath, input.fileoffset, &output);
if (output)
{
//debug_log("output is not NULL (%p)\n", output);
fflush(stdout);
//debug_log("Sending %d bytes\n", *(uint32_t *)&output[4]);
if (input.fileoffset)
{
debug_log("output is not NULL (%p)\n", output);
debug_log("Sending %d bytes\n", *(uint32_t *)&output[4]);
fflush(stdout);
}
sendall(currentsocket, output, *(uint32_t *)&output[4], 0); //the output buffer contains the size itself
free(output);
}
else
{
// debug_log("Sending 8 bytes (fail)\n");
if (input.fileoffset)
debug_log("Sending 8 bytes (fail)\n");
uint64_t fail=0;
sendall(currentsocket, &fail, sizeof(fail), 0); //just write 0
}

View File

@ -115,6 +115,7 @@ typedef struct {
int64_t modulebase;
int32_t modulepart;
int32_t modulesize;
uint32_t modulefileoffset;
int32_t modulenamesize;
} CeModuleEntry, *PCeModuleEntry;

View File

@ -571,8 +571,15 @@ void *CESERVERTEST(int pid )
uint64_t a;
pthread_t pth;
char *output;
debug_log("CESERVERTEST: running (v2)\n");
GetSymbolListFromFile("/home/eric/eclipse-workspace/ceserverbin/libart.so",0, &output);
if (1)
return NULL;
//sleep(2);
debug_log("connecting...\n");

View File

@ -15,6 +15,7 @@
#include <unistd.h>
#include <string.h>
#include <zlib.h>
#include <errno.h>
#include "api.h"
#include "symbols.h"
@ -34,12 +35,12 @@ typedef struct
#define TEMPBUFSIZE 64*1024
void loadStringTable64(int f, Elf64_Shdr *sectionHeaders, unsigned char **stringTable, int index)
void loadStringTable64(int f, unsigned int fileoffset, Elf64_Shdr *sectionHeaders, unsigned char **stringTable, int index)
{
if ((stringTable[index]==NULL) && (sectionHeaders[index].sh_type==SHT_STRTAB))
{
stringTable[index]=malloc(sectionHeaders[index].sh_size);
if (pread(f, stringTable[index], sectionHeaders[index].sh_size, sectionHeaders[index].sh_offset)==-1)
if (pread(f, stringTable[index], sectionHeaders[index].sh_size, sectionHeaders[index].sh_offset+fileoffset)==-1)
{
debug_log("Failure loading the stringtable\n");
free(stringTable[index]);
@ -51,12 +52,12 @@ void loadStringTable64(int f, Elf64_Shdr *sectionHeaders, unsigned char **string
debug_log("Not a string table\n");
}
void loadStringTable32(int f, Elf32_Shdr *sectionHeaders, unsigned char **stringTable, int index)
void loadStringTable32(int f, unsigned int fileoffset, Elf32_Shdr *sectionHeaders, unsigned char **stringTable, int index)
{
if ((stringTable[index]==NULL) && (sectionHeaders[index].sh_type==SHT_STRTAB))
{
stringTable[index]=malloc(sectionHeaders[index].sh_size);
if (pread(f, stringTable[index], sectionHeaders[index].sh_size, sectionHeaders[index].sh_offset)==-1)
if (pread(f, stringTable[index], sectionHeaders[index].sh_size, sectionHeaders[index].sh_offset+fileoffset)==-1)
{
debug_log("Failure loading the stringtable\n");
free(stringTable[index]);
@ -69,7 +70,7 @@ void loadStringTable32(int f, Elf32_Shdr *sectionHeaders, unsigned char **string
}
BOOL ELF32_scan(int f, Elf32_Ehdr *b, char *searchedsymbolname, symcallback cb, void* context)
BOOL ELF32_scan(int f, unsigned int fileoffset, Elf32_Ehdr *b, char *searchedsymbolname, symcallback cb, void* context)
/*
Caller must free output manually
*/
@ -78,7 +79,7 @@ Caller must free output manually
Elf32_Shdr *sectionHeaders=malloc(b->e_shentsize*b->e_shnum);
if (pread(f, sectionHeaders, b->e_shentsize*b->e_shnum, b->e_shoff)==-1)
if (pread(f, sectionHeaders, b->e_shentsize*b->e_shnum, b->e_shoff+fileoffset)==-1)
{
if (sectionHeaders)
free(sectionHeaders);
@ -88,7 +89,7 @@ Caller must free output manually
unsigned char **stringTable=calloc(b->e_shnum, sizeof(unsigned char*) );
loadStringTable32(f, sectionHeaders, stringTable, b->e_shstrndx);
loadStringTable32(f, fileoffset, sectionHeaders, stringTable, b->e_shstrndx);
for (i=0; i<b->e_shnum; i++)
@ -96,7 +97,7 @@ Caller must free output manually
if ((sectionHeaders[i].sh_type==SHT_SYMTAB) || (sectionHeaders[i].sh_type==SHT_DYNSYM))
{
Elf32_Sym *symbolTable=malloc(sectionHeaders[i].sh_size);
if (pread(f, symbolTable, sectionHeaders[i].sh_size, sectionHeaders[i].sh_offset)==-1)
if (pread(f, symbolTable, sectionHeaders[i].sh_size, sectionHeaders[i].sh_offset+fileoffset)==-1)
{
free(symbolTable);
symbolTable=NULL;
@ -106,7 +107,7 @@ Caller must free output manually
{
int maxindex=sectionHeaders[i].sh_size / sizeof(Elf32_Sym);
loadStringTable32(f, sectionHeaders, stringTable, sectionHeaders[i].sh_link);
loadStringTable32(f, fileoffset, sectionHeaders, stringTable, sectionHeaders[i].sh_link);
for (j=0; j<maxindex; j++)
{
@ -141,7 +142,7 @@ Caller must free output manually
}
int ELF64_scan(int f, Elf64_Ehdr *b, char *searchedsymbolname, symcallback cb, void* context)
int ELF64_scan(int f, unsigned int fileoffset, Elf64_Ehdr *b, char *searchedsymbolname, symcallback cb, void* context)
/*
Caller must free output manually
*/
@ -150,7 +151,7 @@ Caller must free output manually
Elf64_Shdr *sectionHeaders=malloc(b->e_shentsize*b->e_shnum);
if (pread(f, sectionHeaders, b->e_shentsize*b->e_shnum, b->e_shoff)==-1)
if (pread(f, sectionHeaders, b->e_shentsize*b->e_shnum, b->e_shoff+fileoffset)==-1)
{
if (sectionHeaders)
free(sectionHeaders);
@ -160,7 +161,7 @@ Caller must free output manually
unsigned char **stringTable=calloc(b->e_shnum, sizeof(unsigned char*) );
loadStringTable64(f, sectionHeaders, stringTable, b->e_shstrndx);
loadStringTable64(f, fileoffset, sectionHeaders, stringTable, b->e_shstrndx);
for (i=0; i<b->e_shnum; i++)
@ -168,7 +169,7 @@ Caller must free output manually
if ((sectionHeaders[i].sh_type==SHT_SYMTAB) || (sectionHeaders[i].sh_type==SHT_DYNSYM))
{
Elf64_Sym *symbolTable=malloc(sectionHeaders[i].sh_size);
if (pread(f, symbolTable, sectionHeaders[i].sh_size, sectionHeaders[i].sh_offset)==-1)
if (pread(f, symbolTable, sectionHeaders[i].sh_size, sectionHeaders[i].sh_offset+fileoffset)==-1)
{
free(symbolTable);
symbolTable=NULL;
@ -178,7 +179,7 @@ Caller must free output manually
{
int maxindex=sectionHeaders[i].sh_size / sizeof(Elf64_Sym);
loadStringTable64(f, sectionHeaders, stringTable, sectionHeaders[i].sh_link);
loadStringTable64(f, fileoffset, sectionHeaders, stringTable, sectionHeaders[i].sh_link);
for (j=0; j<maxindex; j++)
{
@ -214,7 +215,7 @@ Caller must free output manually
}
int ELF32(int f, Elf32_Ehdr *b, unsigned char **output)
int ELF32(int f, unsigned int fileoffset, Elf32_Ehdr *b, unsigned char **output)
/*
Caller must free output manually
*/
@ -225,6 +226,25 @@ Caller must free output manually
int tempbufferpos=0;
int maxoutputsize=TEMPBUFSIZE;
tempbuffer=malloc(TEMPBUFSIZE);
int offset=0;
Elf64_Phdr *programHeaders=malloc(b->e_phentsize*b->e_phnum);
if (pread(f, programHeaders, b->e_phentsize*b->e_phnum, b->e_phoff+fileoffset)==-1)
{
if (programHeaders)
free(programHeaders);
return 0;
}
for (i=0; i<b->e_phnum; i++)
{
if (programHeaders[i].p_type==PT_LOAD)
{
offset=programHeaders[i].p_vaddr;
break;
}
}
//setup zlib
z_stream strm;
@ -243,7 +263,7 @@ Caller must free output manually
Elf32_Shdr *sectionHeaders=malloc(b->e_shentsize*b->e_shnum);
if (pread(f, sectionHeaders, b->e_shentsize*b->e_shnum, b->e_shoff)==-1)
if (pread(f, sectionHeaders, b->e_shentsize*b->e_shnum, b->e_shoff+fileoffset)==-1)
{
//printf("Failure to read sectionHeaders\n");
deflateEnd(&strm);
@ -259,12 +279,15 @@ Caller must free output manually
if (tempbuffer)
free(tempbuffer);
if (programHeaders)
free(programHeaders);
return -1;
}
unsigned char **stringTable=calloc(b->e_shnum, sizeof(unsigned char*) );
loadStringTable32(f, sectionHeaders, stringTable, b->e_shstrndx);
loadStringTable32(f, fileoffset, sectionHeaders, stringTable, b->e_shstrndx);
for (i=0; i<b->e_shnum; i++)
@ -272,7 +295,7 @@ Caller must free output manually
if ((sectionHeaders[i].sh_type==SHT_SYMTAB) || (sectionHeaders[i].sh_type==SHT_DYNSYM))
{
Elf32_Sym *symbolTable=malloc(sectionHeaders[i].sh_size);
if (pread(f, symbolTable, sectionHeaders[i].sh_size, sectionHeaders[i].sh_offset)==-1)
if (pread(f, symbolTable, sectionHeaders[i].sh_size, sectionHeaders[i].sh_offset+fileoffset)==-1)
{
free(symbolTable);
symbolTable=NULL;
@ -282,7 +305,7 @@ Caller must free output manually
{
int maxindex=sectionHeaders[i].sh_size / sizeof(Elf32_Sym);
loadStringTable32(f, sectionHeaders, stringTable, sectionHeaders[i].sh_link);
loadStringTable32(f, fileoffset, sectionHeaders, stringTable, sectionHeaders[i].sh_link);
//printf("maxindex=%d\n", maxindex);
for (j=0; j<maxindex; j++)
@ -305,6 +328,20 @@ Caller must free output manually
if (deflate(&strm, Z_NO_FLUSH)!=Z_OK)
{
//printf("FAILURE TO COMPRESS!\n");
if (sectionHeaders)
free(sectionHeaders);
if (*output)
{
free(*output);
*output=NULL;
}
if (tempbuffer)
free(tempbuffer);
if (programHeaders)
free(programHeaders);
return -1;
}
//printf("strm.avail_out=%d\n", strm.avail_out);
@ -351,6 +388,9 @@ Caller must free output manually
free(sectionHeaders);
if (programHeaders)
free(programHeaders);
// debug_log("end:\n");
strm.avail_in=tempbufferpos;
@ -402,7 +442,7 @@ Caller must free output manually
return 0;
}
int ELF64(int f, Elf64_Ehdr *b, unsigned char **output)
int ELF64(int f, unsigned int fileoffset, Elf64_Ehdr *b, unsigned char **output)
/*
Caller must free output manually
*/
@ -414,6 +454,26 @@ Caller must free output manually
int tempbufferpos=0;
int maxoutputsize=TEMPBUFSIZE;
tempbuffer=malloc(TEMPBUFSIZE);
int offset=0;
Elf64_Phdr *programHeaders=malloc(b->e_phentsize*b->e_phnum);
if (pread(f, programHeaders, b->e_phentsize*b->e_phnum, b->e_phoff+fileoffset)==-1)
{
if (programHeaders)
free(programHeaders);
return 0;
}
for (i=0; i<b->e_phnum; i++)
{
if (programHeaders[i].p_type==PT_LOAD)
{
offset=programHeaders[i].p_vaddr;
break;
}
}
//setup zlib
z_stream strm;
@ -432,7 +492,7 @@ Caller must free output manually
Elf64_Shdr *sectionHeaders=malloc(b->e_shentsize*b->e_shnum);
if (pread(f, sectionHeaders, b->e_shentsize*b->e_shnum, b->e_shoff)==-1)
if (pread(f, sectionHeaders, b->e_shentsize*b->e_shnum, b->e_shoff+fileoffset)==-1)
{
//printf("Failure to read sectionHeaders\n");
deflateEnd(&strm);
@ -448,12 +508,15 @@ Caller must free output manually
if (tempbuffer)
free(tempbuffer);
if (programHeaders)
free(programHeaders);
return -1;
}
unsigned char **stringTable=calloc(b->e_shnum, sizeof(unsigned char*) );
loadStringTable64(f, sectionHeaders, stringTable, b->e_shstrndx);
loadStringTable64(f, fileoffset, sectionHeaders, stringTable, b->e_shstrndx);
for (i=0; i<b->e_shnum; i++)
@ -463,7 +526,7 @@ Caller must free output manually
if ((sectionHeaders[i].sh_type==SHT_SYMTAB) || (sectionHeaders[i].sh_type==SHT_DYNSYM))
{
Elf64_Sym *symbolTable=malloc(sectionHeaders[i].sh_size);
if (pread(f, symbolTable, sectionHeaders[i].sh_size, sectionHeaders[i].sh_offset)==-1)
if (pread(f, symbolTable, sectionHeaders[i].sh_size, sectionHeaders[i].sh_offset+fileoffset)==-1)
{
//printf("Failure reading symbol table\n");
free(symbolTable);
@ -474,7 +537,7 @@ Caller must free output manually
{
int maxindex=sectionHeaders[i].sh_size / sizeof(Elf64_Sym);
loadStringTable64(f, sectionHeaders, stringTable, sectionHeaders[i].sh_link);
loadStringTable64(f, fileoffset, sectionHeaders, stringTable, sectionHeaders[i].sh_link);
for (j=0; j<maxindex; j++)
@ -484,6 +547,7 @@ Caller must free output manually
{
//add it to the tempbuffer
char *symbolname=(char *)&stringTable[sectionHeaders[i].sh_link][symbolTable[j].st_name];
size_t namelength=strlen(symbolname);
int entrysize=sizeof(symbolinfo)+namelength;
if (tempbufferpos+entrysize>=TEMPBUFSIZE)
@ -520,7 +584,7 @@ Caller must free output manually
psymbolinfo si=(psymbolinfo)&tempbuffer[tempbufferpos];
si->address=symbolTable[j].st_value;
si->address=symbolTable[j].st_value-offset;
si->size=symbolTable[j].st_size;
si->type=symbolTable[j].st_info;
si->namelength=namelength;
@ -546,6 +610,8 @@ Caller must free output manually
free(sectionHeaders);
free(programHeaders);
// debug_log("end:\n");
strm.avail_in=tempbufferpos;
@ -627,9 +693,11 @@ int FindSymbol(HANDLE hProcess, char *symbolname, symcallback cb, void* context)
{
int i,f;
unsigned char *b=NULL;
unsigned int fileoffset=mle.fileOffset;
c.modulebase=mle.baseAddress;
f=open(mle.moduleName, O_RDONLY);
if (f==-1)
continue;
@ -637,13 +705,13 @@ int FindSymbol(HANDLE hProcess, char *symbolname, symcallback cb, void* context)
b=malloc(sizeof(Elf64_Ehdr));
if (b)
{
i=pread(f, b, sizeof(Elf64_Ehdr), 0);
i=pread(f, b, sizeof(Elf64_Ehdr), fileoffset);
if (*(uint32_t *)b==0x464c457f)
{
if (b[EI_CLASS]==ELFCLASS32)
i=ELF32_scan(f, (Elf32_Ehdr *)b, symbolname, (symcallback)FindSymbol_internal, (void*)&c);
i=ELF32_scan(f, fileoffset, (Elf32_Ehdr *)b, symbolname, (symcallback)FindSymbol_internal, (void*)&c);
else
i=ELF64_scan(f, (Elf64_Ehdr *)b, symbolname, (symcallback)FindSymbol_internal, (void*)&c);
i=ELF64_scan(f, fileoffset, (Elf64_Ehdr *)b, symbolname, (symcallback)FindSymbol_internal, (void*)&c);
}
free(b);
@ -662,7 +730,7 @@ int FindSymbol(HANDLE hProcess, char *symbolname, symcallback cb, void* context)
return 0;
}
int GetSymbolListFromFile(char *filename, unsigned char **output)
int GetSymbolListFromFile(char *filename, uint32_t fileoffset, unsigned char **output)
/*
* Returns a pointer to a compressed stream. The caller needs to free it
*/
@ -670,28 +738,49 @@ int GetSymbolListFromFile(char *filename, unsigned char **output)
int i, f;
unsigned char *b=NULL;
// debug_log("GetSymbolListFromFile(%s)\n", filename);
if (fileoffset)
debug_log("GetSymbolListFromFile(%s, %x)\n", filename, fileoffset);
*output=NULL;
f=open(filename, O_RDONLY);
if (f==-1)
{
if (fileoffset)
debug_log("open(%s) failed: %s\n", strerror(errno));
return -1;
}
b=malloc(sizeof(Elf64_Ehdr));
if (b)
{
i=pread(f, b, sizeof(Elf64_Ehdr), 0);
i=pread(f, b, sizeof(Elf64_Ehdr), fileoffset);
if (i==-1)
{
debug_log("Failure reading %d bytes from %s at 0x%x\n (%s)", sizeof(Elf64_Ehdr), filename, fileoffset, strerror(errno));
return -1;
}
if (fileoffset)
debug_log("b[0..3]=%.2x %.2x %.2x %.2x\n", b[0],b[1],b[2],b[3]);
if (*(uint32_t *)b!=0x464c457f)
{
if (fileoffset)
debug_log("Not an ELF file\n");
return -1; //not an ELF file
}
if (b[EI_CLASS]==ELFCLASS32)
i=ELF32(f, (Elf32_Ehdr *)b, output);
i=ELF32(f, fileoffset, (Elf32_Ehdr *)b, output);
else
i=ELF64(f, (Elf64_Ehdr *)b, output);
i=ELF64(f, fileoffset, (Elf64_Ehdr *)b, output);
free(b);
}
else
i=-1;
close(f);
@ -699,7 +788,7 @@ int GetSymbolListFromFile(char *filename, unsigned char **output)
}
int GetModuleSize32(int f, Elf32_Ehdr *b)
int GetModuleSize32(int f, uint32_t fileoffset, Elf32_Ehdr *b)
{
/* debug_log("32 bit\n");
debug_log("b->e_ehsize=%d (%d)\n", (int)b->e_ehsize, (int)sizeof(Elf32_Ehdr));*/
@ -715,7 +804,7 @@ int GetModuleSize32(int f, Elf32_Ehdr *b)
debug_log("e_phentsize=%d\n", b->e_phentsize);
debug_log("e_phnum=%d\n", b->e_phnum); */
if (pread(f, programHeaders, b->e_phentsize*b->e_phnum, b->e_phoff)==-1)
if (pread(f, programHeaders, b->e_phentsize*b->e_phnum, b->e_phoff+fileoffset)==-1)
{
if (programHeaders)
free(programHeaders);
@ -755,7 +844,7 @@ int GetModuleSize32(int f, Elf32_Ehdr *b)
return highest-lowest;
}
int GetModuleSize64(int f, Elf64_Ehdr *b)
int GetModuleSize64(int f, uint32_t fileoffset, Elf64_Ehdr *b)
{
/*printf("64 bit\n");
debug_log("b->e_ehsize=%d (%d)\n", (int)b->e_ehsize, (int)sizeof(Elf32_Ehdr));*/
@ -771,7 +860,7 @@ int GetModuleSize64(int f, Elf64_Ehdr *b)
debug_log("e_phnum=%d\n", b->e_phnum);
*/
if (pread(f, programHeaders, b->e_phentsize*b->e_phnum, b->e_phoff)==-1)
if (pread(f, programHeaders, b->e_phentsize*b->e_phnum, b->e_phoff+fileoffset)==-1)
{
if (programHeaders)
free(programHeaders);
@ -812,14 +901,13 @@ int GetModuleSize64(int f, Elf64_Ehdr *b)
}
unsigned long long GetModuleSize(char *filename, unsigned long long defaultsize)
unsigned long long GetModuleSize(char *filename, uint32_t fileoffset, unsigned long long defaultsize)
/*
* Returns size the module will take in memory
*/
{
int i,f;
unsigned char *b=NULL;
int result=defaultsize;
// debug_log("GetModuleSize(\"%s\")=",filename);
@ -834,7 +922,7 @@ unsigned long long GetModuleSize(char *filename, unsigned long long defaultsize)
b=malloc(sizeof(Elf64_Ehdr));
if (b)
{
i=pread(f, b, sizeof(Elf64_Ehdr), 0);
i=pread(f, b, sizeof(Elf64_Ehdr), fileoffset);
if (*(uint32_t *)b!=0x464c457f)
{
@ -845,9 +933,9 @@ unsigned long long GetModuleSize(char *filename, unsigned long long defaultsize)
}
if (b[EI_CLASS]==ELFCLASS32)
i=GetModuleSize32(f, (Elf32_Ehdr *)b);
i=GetModuleSize32(f, fileoffset, (Elf32_Ehdr *)b);
else
i=GetModuleSize64(f, (Elf64_Ehdr *)b);
i=GetModuleSize64(f, fileoffset, (Elf64_Ehdr *)b);
free(b);
close(f);

View File

@ -12,8 +12,8 @@
typedef void (*symcallback)(uintptr_t address, char* symbolname, void *context);
int GetSymbolListFromFile(char *filename, unsigned char **output);
unsigned long long GetModuleSize(char *filename, unsigned long long defaultsize);
int GetSymbolListFromFile(char *filename, uint32_t fileoffset, unsigned char **output);
unsigned long long GetModuleSize(char *filename, uint32_t fileoffset, unsigned long long defaultsize);
int FindSymbol(HANDLE hProcess, char *symbolname, symcallback cb, void* context);