Merge pull request #88 from rofl0r/fixup_imp

improve psp-fixup-imports
This commit is contained in:
Wouter Wijsman
2023-03-08 10:24:29 +01:00
committed by GitHub

View File

@@ -59,6 +59,8 @@ static struct ElfSection *g_modinfo = NULL;
static struct ElfSection *g_libstub = NULL;
static struct ElfSection *g_stubtext = NULL;
static struct ElfSection *g_nid = NULL;
static struct ElfSection *g_symtab = NULL;
static struct ElfSection *g_strtab = NULL;
static struct ImportMap *g_map = NULL;
static int g_reversemap = 0;
@@ -151,6 +153,27 @@ const unsigned char *find_data(unsigned int iAddr)
return NULL;
}
/* find symbol name. addr needs to be in host endianness */
static const char *getsymname(unsigned addr)
{
if(!g_symtab || !g_strtab) return 0;
if(g_symtab->iSize == 0 || g_symtab->pData == 0) return 0;
if(g_strtab->iSize == 0 || g_strtab->pData == 0) return 0;
Elf32_Sym *curr = (void*)g_symtab->pData;
Elf32_Sym *end = curr + (g_symtab->iSize / sizeof(Elf32_Sym));
addr = LW(addr);
while(curr < end) {
if(curr->st_value == addr) {
if(curr->st_name && curr->st_name < g_strtab->iSize)
return (char*)g_strtab->pData + curr->st_name;
else
return 0;
}
++curr;
}
return 0;
}
struct ImportMap *find_map_by_name(const char *name)
{
struct ImportMap *currmap = g_map;
@@ -244,14 +267,14 @@ int validate_header(unsigned char *data)
if(g_verbose)
{
fprintf(stderr, "Magic %08X, Class %02X, Data %02X, Idver %02X\n", g_elfhead.iMagic,
fprintf(stderr, "Magic %08x, Class %02x, Data %02x, Idver %02x\n", g_elfhead.iMagic,
g_elfhead.iClass, g_elfhead.iData, g_elfhead.iIdver);
fprintf(stderr, "Type %04X, Machine %04X, Version %08X, Entry %08X\n", g_elfhead.iType,
fprintf(stderr, "Type %04x, Machine %04x, Version %08x, Entry %08x\n", g_elfhead.iType,
g_elfhead.iMachine, g_elfhead.iVersion, g_elfhead.iEntry);
fprintf(stderr, "Phoff %08X, Shoff %08X, Flags %08X, Ehsize %08X\n", g_elfhead.iPhoff,
fprintf(stderr, "Phoff %08x, Shoff %08x, Flags %08x, Ehsize %08x\n", g_elfhead.iPhoff,
g_elfhead.iShoff, g_elfhead.iFlags, g_elfhead.iEhsize);
fprintf(stderr, "Phentsize %04X, Phnum %04X\n", g_elfhead.iPhentsize, g_elfhead.iPhnum);
fprintf(stderr, "Shentsize %04X, Shnum %08X, Shstrndx %04X\n", g_elfhead.iShentsize,
fprintf(stderr, "Phentsize %04x, Phnum %04x\n", g_elfhead.iPhentsize, g_elfhead.iPhnum);
fprintf(stderr, "Shentsize %04x, Shnum %08x, Shstrndx %04x\n", g_elfhead.iShentsize,
g_elfhead.iShnum, g_elfhead.iShstrndx);
}
@@ -365,6 +388,14 @@ int load_sections(unsigned char *data)
{
g_nid = &g_elfsections[i];
}
else if(strcmp(g_elfsections[i].szName, ".symtab") == 0)
{
g_symtab = &g_elfsections[i];
}
else if(strcmp(g_elfsections[i].szName, ".strtab") == 0)
{
g_strtab = &g_elfsections[i];
}
}
if(g_verbose)
@@ -372,18 +403,18 @@ int load_sections(unsigned char *data)
for(i = 0; i < g_elfhead.iShnum; i++)
{
fprintf(stderr, "\nSection %d: %s\n", i, g_elfsections[i].szName);
fprintf(stderr, "Name %08X, Type %08X, Flags %08X, Addr %08X\n",
fprintf(stderr, "Name %08x, Type %08x, Flags %08x, Addr %08x\n",
g_elfsections[i].iName, g_elfsections[i].iType,
g_elfsections[i].iFlags, g_elfsections[i].iAddr);
fprintf(stderr, "Offset %08X, Size %08X, Link %08X, Info %08X\n",
fprintf(stderr, "Offset %08x, Size %08x, Link %08x, Info %08x\n",
g_elfsections[i].iOffset, g_elfsections[i].iSize,
g_elfsections[i].iLink, g_elfsections[i].iInfo);
fprintf(stderr, "Addralign %08X, Entsize %08X pData %p\n",
fprintf(stderr, "Addralign %08x, Entsize %08x pData %p\n",
g_elfsections[i].iAddralign, g_elfsections[i].iEntsize,
g_elfsections[i].pData);
}
fprintf(stderr, "ELF Load Base address %08X\n", load_addr);
fprintf(stderr, "ELF Load Base address %08x\n", load_addr);
}
if(g_modinfo == NULL)
@@ -504,116 +535,112 @@ int load_mapfile(const char *mapfile)
struct ImportMap *currmap = NULL;
int line = 0;
if(mapfile != NULL)
if(mapfile == NULL) return ret;
do
{
do
FILE *fp;
fp = fopen(mapfile, "r");
if(fp == NULL) return ret;
while(fgets(buf, sizeof(buf), fp))
{
FILE *fp;
fp = fopen(mapfile, "r");
if(fp != NULL)
line++;
strip_wsp(buf);
if((buf[0]) && (buf[0] != '#'))
{
while(fgets(buf, sizeof(buf), fp))
if(buf[0] == '@')
{
line++;
strip_wsp(buf);
if((buf[0]) && (buf[0] != '#'))
struct ImportMap *temp;
temp = (struct ImportMap *) malloc(sizeof(struct ImportMap));
if(temp == NULL)
{
if(buf[0] == '@')
{
struct ImportMap *temp;
printf("Error allocating memory for import map\n");
ret = 0;
break;
}
temp = (struct ImportMap *) malloc(sizeof(struct ImportMap));
if(temp == NULL)
{
printf("Error allocating memory for import map\n");
ret = 0;
break;
}
memset(temp, 0, sizeof(struct ImportMap));
if(currmap == NULL)
{
g_map = temp;
}
else
{
temp->next = currmap;
g_map = temp;
}
memset(temp, 0, sizeof(struct ImportMap));
if(currmap == NULL)
{
g_map = temp;
}
else
{
temp->next = currmap;
g_map = temp;
}
currmap = temp;
if(buf[1])
{
strncpy(currmap->name, &buf[1], 32);
currmap->name[31] = 0;
}
else
{
printf("Invalid library name at line %d\n", line);
break;
}
currmap = temp;
if(buf[1])
{
strncpy(currmap->name, &buf[1], 32);
currmap->name[31] = 0;
}
else
{
printf("Invalid library name at line %d\n", line);
break;
}
if(g_verbose)
{
printf("Mapping library %s\n", currmap->name);
}
}
else
{
unsigned int oldnid;
unsigned int newnid;
char *endp;
if(currmap->count == MAX_MAPNIDS)
{
printf("Error, number of defined nids exceed maximum\n");
break;
}
/* Hex data should be prefixed with 0 */
if(buf[0] == '0')
{
errno = 0;
oldnid = strtoul(buf, &endp, 16);
if((errno != 0) || (*endp != ':'))
{
printf("Invalid NID entry on line %d\n", line);
continue;
}
}
else
{
unsigned char hash[SHA1_DIGEST_SIZE];
endp = strchr(buf, ':');
if(endp == NULL)
{
printf("Invalid NID entry on line %d\n", line);
continue;
}
sha1(hash, (unsigned char *) buf, endp-buf);
oldnid = hash[0] | (hash[1] << 8) | (hash[2] << 16) | (hash[3] << 24);
}
newnid = strtoul(endp+1, &endp, 16);
if(g_verbose)
{
fprintf(stderr, "NID Mapping 0x%08X to 0x%08X\n", oldnid, newnid);
}
currmap->nids[currmap->count].oldnid = oldnid;
currmap->nids[currmap->count].newnid = newnid;
currmap->count++;
}
if(g_verbose)
{
printf("Mapping library %s\n", currmap->name);
}
}
fclose(fp);
else
{
unsigned int oldnid;
unsigned int newnid;
char *endp;
if(currmap->count == MAX_MAPNIDS)
{
printf("Error, number of defined nids exceed maximum\n");
break;
}
/* Hex data should be prefixed with 0 */
if(buf[0] == '0')
{
errno = 0;
oldnid = strtoul(buf, &endp, 16);
if((errno != 0) || (*endp != ':'))
{
printf("Invalid NID entry on line %d\n", line);
continue;
}
}
else
{
unsigned char hash[SHA1_DIGEST_SIZE];
endp = strchr(buf, ':');
if(endp == NULL)
{
printf("Invalid NID entry on line %d\n", line);
continue;
}
sha1(hash, (unsigned char *) buf, endp-buf);
oldnid = hash[0] | (hash[1] << 8) | (hash[2] << 16) | (hash[3] << 24);
}
newnid = strtoul(endp+1, &endp, 16);
if(g_verbose)
{
fprintf(stderr, "NID Mapping 0x%08x to 0x%08x\n", oldnid, newnid);
}
currmap->nids[currmap->count].oldnid = oldnid;
currmap->nids[currmap->count].newnid = newnid;
currmap->count++;
}
}
}
while(0);
fclose(fp);
}
while(0);
return ret;
}
@@ -662,7 +689,8 @@ int fixup_imports(void)
if(g_verbose)
{
fprintf(stderr, "Found import to fixup. pStub %08X, Nid %08X, NidInSect %08X\n", stub_addr, stub_nid, sect_nid);
const char *tmp = getsymname(stub_addr);
fprintf(stderr, "Found import to fixup. pStub %08x (%s), Nid %08x, NidInSect %08x\n", stub_addr, tmp ? tmp : "", stub_nid, sect_nid);
}
if(stub_nid != sect_nid)
@@ -680,8 +708,9 @@ int fixup_imports(void)
pImport = (struct PspModuleImport *) (g_libstub->pData + (stub_addr - g_libstub->iAddr));
if(g_verbose)
{
fprintf(stderr, "Import Stub %p, %08X, %08X, %02X, %02X, %04X, %08X, %08X\n", pImport,
LW(pImport->name), LW(pImport->flags), pImport->entry_size, pImport->var_count,
const char *tmp = getsymname(LW(pImport->name));
fprintf(stderr, "Import Stub %p, %08x (%s), %08x, %02x, %02x, %04x, %08x, %08x\n", pImport,
LW(pImport->name), tmp?tmp:"", LW(pImport->flags), pImport->entry_size, pImport->var_count,
LH(pImport->func_count), LW(pImport->nids), LW(pImport->funcs));
}
@@ -697,9 +726,9 @@ int fixup_imports(void)
{
if((pLastImport) && (pImport != pLastImport))
{
fprintf(stderr, "Error, could not fixup imports, stubs out of order.\n");
fprintf(stderr, "Ensure the SDK libraries are linked in last to correct this error\n");
return 0;
fprintf(stderr, "Warning: could not fixup imports, stubs out of order.\n");
fprintf(stderr, "Ensure the SDK libraries are linked in last to correct this.\n");
fprintf(stderr, "Continuing, your binary may or not work.\n");
}
}
@@ -788,7 +817,7 @@ int fixup_nidmap(void)
{
if(g_verbose)
{
fprintf(stderr, "Mapping 0x%08X to 0x%08X\n", oldnid, newnid);
fprintf(stderr, "Mapping 0x%08x to 0x%08x\n", oldnid, newnid);
}
*pNid = newnid;