some symbol lookup fixes and performance enhancements
This commit is contained in:
parent
3d972a4e98
commit
0b9d34f7f4
@ -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;
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
typedef struct
|
||||
{
|
||||
unsigned long long baseAddress;
|
||||
uint32_t fileOffset;
|
||||
int part;
|
||||
int is64bit;
|
||||
int moduleSize;
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -115,6 +115,7 @@ typedef struct {
|
||||
int64_t modulebase;
|
||||
int32_t modulepart;
|
||||
int32_t modulesize;
|
||||
uint32_t modulefileoffset;
|
||||
int32_t modulenamesize;
|
||||
} CeModuleEntry, *PCeModuleEntry;
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user