Tracking some function calls
This commit is contained in:
parent
1ed2fb51a1
commit
8cae299570
167
src/format/pe.c
167
src/format/pe.c
@ -29,6 +29,21 @@
|
|||||||
/* private */
|
/* private */
|
||||||
/* types */
|
/* types */
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
struct pe_export_directory
|
||||||
|
{
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t time;
|
||||||
|
uint16_t major;
|
||||||
|
uint16_t minor;
|
||||||
|
uint32_t name;
|
||||||
|
uint32_t base;
|
||||||
|
uint32_t functions_cnt;
|
||||||
|
uint32_t names_cnt;
|
||||||
|
uint32_t functions_addr;
|
||||||
|
uint32_t names_addr;
|
||||||
|
uint32_t ordinals_addr;
|
||||||
|
};
|
||||||
|
|
||||||
struct pe_header
|
struct pe_header
|
||||||
{
|
{
|
||||||
uint16_t machine;
|
uint16_t machine;
|
||||||
@ -228,7 +243,6 @@ FormatPlugin format_plugin =
|
|||||||
static int _pe_init(FormatPlugin * format, char const * arch)
|
static int _pe_init(FormatPlugin * format, char const * arch)
|
||||||
{
|
{
|
||||||
FormatPluginHelper * helper = format->helper;
|
FormatPluginHelper * helper = format->helper;
|
||||||
char const ps[4] = { 'P', 'E', '\0', '\0' };
|
|
||||||
int machine;
|
int machine;
|
||||||
struct pe_msdos pm;
|
struct pe_msdos pm;
|
||||||
struct pe_header ph;
|
struct pe_header ph;
|
||||||
@ -244,7 +258,9 @@ static int _pe_init(FormatPlugin * format, char const * arch)
|
|||||||
if(helper->write(helper->format, &pm, sizeof(pm)) != sizeof(pm))
|
if(helper->write(helper->format, &pm, sizeof(pm)) != sizeof(pm))
|
||||||
return -1;
|
return -1;
|
||||||
/* output the PE signature */
|
/* output the PE signature */
|
||||||
if(helper->write(helper->format, &ps, sizeof(ps)) != sizeof(ps))
|
if(helper->write(helper->format, _pe_header_signature,
|
||||||
|
sizeof(_pe_header_signature))
|
||||||
|
!= sizeof(_pe_header_signature))
|
||||||
return -1;
|
return -1;
|
||||||
/* output the PE header */
|
/* output the PE header */
|
||||||
memset(&ph, 0, sizeof(ph));
|
memset(&ph, 0, sizeof(ph));
|
||||||
@ -279,12 +295,18 @@ static char const * _pe_detect(FormatPlugin * format)
|
|||||||
|
|
||||||
|
|
||||||
/* pe_decode */
|
/* pe_decode */
|
||||||
|
static int _decode_data(FormatPlugin * format, uint32_t vaddr, uint32_t base,
|
||||||
|
struct pe_image_header_data * pid, size_t i);
|
||||||
|
static int _decode_data_export_directory(FormatPlugin * format, uint32_t vaddr,
|
||||||
|
uint32_t base, struct pe_image_header_data * pid);
|
||||||
static int _decode_error(FormatPlugin * format);
|
static int _decode_error(FormatPlugin * format);
|
||||||
|
static char * _decode_string(FormatPlugin * format, off_t offset);
|
||||||
|
|
||||||
static int _pe_decode(FormatPlugin * format, int raw)
|
static int _pe_decode(FormatPlugin * format, int raw)
|
||||||
{
|
{
|
||||||
FormatPluginHelper * helper = format->helper;
|
FormatPluginHelper * helper = format->helper;
|
||||||
struct pe_msdos pm;
|
struct pe_msdos pm;
|
||||||
|
char buf[sizeof(_pe_header_signature)];
|
||||||
struct pe_header ph;
|
struct pe_header ph;
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t cnt;
|
size_t cnt;
|
||||||
@ -304,11 +326,14 @@ static int _pe_decode(FormatPlugin * format, int raw)
|
|||||||
return -1;
|
return -1;
|
||||||
if(helper->read(helper->format, &pm, sizeof(pm)) != sizeof(pm))
|
if(helper->read(helper->format, &pm, sizeof(pm)) != sizeof(pm))
|
||||||
return -1;
|
return -1;
|
||||||
/* FIXME check the PE signature */
|
/* check the PE signature */
|
||||||
/* read the PE header */
|
|
||||||
pm.offset = _htol16(pm.offset) + 4;
|
|
||||||
if(helper->seek(helper->format, pm.offset, SEEK_SET) != pm.offset)
|
if(helper->seek(helper->format, pm.offset, SEEK_SET) != pm.offset)
|
||||||
return -1;
|
return -1;
|
||||||
|
if(helper->read(helper->format, &buf, sizeof(buf)) != sizeof(buf))
|
||||||
|
return -1;
|
||||||
|
if(memcmp(buf, _pe_header_signature, sizeof(buf)) != 0)
|
||||||
|
return -1;
|
||||||
|
/* read the PE header */
|
||||||
if(helper->read(helper->format, &ph, sizeof(ph)) != sizeof(ph))
|
if(helper->read(helper->format, &ph, sizeof(ph)) != sizeof(ph))
|
||||||
return _decode_error(format);
|
return _decode_error(format);
|
||||||
ph.section_cnt = _htol16(ph.section_cnt);
|
ph.section_cnt = _htol16(ph.section_cnt);
|
||||||
@ -326,6 +351,7 @@ static int _pe_decode(FormatPlugin * format, int raw)
|
|||||||
}
|
}
|
||||||
pih = (struct pe_image_header *)p;
|
pih = (struct pe_image_header *)p;
|
||||||
pih->signature = _htol16(pih->signature);
|
pih->signature = _htol16(pih->signature);
|
||||||
|
pih->code_base = _htol32(pih->code_base);
|
||||||
/* read any additional part of the optional header */
|
/* read any additional part of the optional header */
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
if(pih->signature == PE_IMAGE_HEADER_PE32
|
if(pih->signature == PE_IMAGE_HEADER_PE32
|
||||||
@ -355,21 +381,13 @@ static int _pe_decode(FormatPlugin * format, int raw)
|
|||||||
/* read the data directories */
|
/* read the data directories */
|
||||||
for(i = 0; pid != NULL && (char *)(&pid[i + 1]) < p
|
for(i = 0; pid != NULL && (char *)(&pid[i + 1]) < p
|
||||||
+ ph.opthdr_size && i < cnt; i++)
|
+ ph.opthdr_size && i < cnt; i++)
|
||||||
{
|
if(_decode_data(format, base, pih->code_base, &pid[i],
|
||||||
pid[i].vaddr = _htol32(pid[i].vaddr);
|
i) != 0)
|
||||||
pid[i].size = _htol32(pid[i].size);
|
break; /* XXX report error */
|
||||||
/* FIXME really implement */
|
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(stderr, "DEBUG: %s() pid[%lu] 0x%08x, 0x%08x\n",
|
|
||||||
__func__, i, pid[i].vaddr, pid[i].size);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if(ph.opthdr_size != 0 && helper->seek(helper->format,
|
|
||||||
ph.opthdr_size, SEEK_CUR) != ph.opthdr_size)
|
|
||||||
return _decode_error(format);
|
|
||||||
/* read and decode each section */
|
/* read and decode each section */
|
||||||
offset = pm.offset + sizeof(ph) + ph.opthdr_size;
|
offset = pm.offset + sizeof(_pe_header_signature) + sizeof(ph)
|
||||||
|
+ ph.opthdr_size;
|
||||||
if(ph.opthdr_size != 0 && helper->seek(helper->format, offset, SEEK_SET)
|
if(ph.opthdr_size != 0 && helper->seek(helper->format, offset, SEEK_SET)
|
||||||
!= offset)
|
!= offset)
|
||||||
return _decode_error(format);
|
return _decode_error(format);
|
||||||
@ -414,18 +432,127 @@ static int _pe_decode(FormatPlugin * format, int raw)
|
|||||||
/* FIXME implement */
|
/* FIXME implement */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* read symbols */
|
|
||||||
/* FIXME implement */
|
|
||||||
free(p);
|
free(p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _decode_data(FormatPlugin * format, uint32_t vaddr, uint32_t base,
|
||||||
|
struct pe_image_header_data * pid, size_t i)
|
||||||
|
{
|
||||||
|
pid->vaddr = _htol32(pid->vaddr);
|
||||||
|
pid->size = _htol32(pid->size);
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s() pid[%lu] 0x%08x, 0x%08x\n", __func__, i,
|
||||||
|
pid->vaddr, pid->size);
|
||||||
|
#endif
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return _decode_data_export_directory(format, vaddr,
|
||||||
|
base, pid);
|
||||||
|
default:
|
||||||
|
/* FIXME implement the rest */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _decode_data_export_directory(FormatPlugin * format, uint32_t vaddr,
|
||||||
|
uint32_t base, struct pe_image_header_data * pid)
|
||||||
|
{
|
||||||
|
FormatPluginHelper * helper = format->helper;
|
||||||
|
struct pe_export_directory ped;
|
||||||
|
size_t j;
|
||||||
|
uint32_t f;
|
||||||
|
uint32_t n;
|
||||||
|
char * p;
|
||||||
|
|
||||||
|
if(base > pid->vaddr || helper->seek(helper->format, pid->vaddr - base,
|
||||||
|
SEEK_SET) < 0
|
||||||
|
|| helper->read(helper->format, &ped, sizeof(ped))
|
||||||
|
!= sizeof(ped))
|
||||||
|
return -1;
|
||||||
|
ped.major = _htol16(ped.major);
|
||||||
|
ped.minor = _htol16(ped.minor);
|
||||||
|
ped.name = _htol32(ped.name);
|
||||||
|
ped.base = _htol32(ped.base);
|
||||||
|
ped.functions_cnt = _htol32(ped.functions_cnt);
|
||||||
|
ped.names_cnt = _htol32(ped.names_cnt);
|
||||||
|
ped.functions_addr = _htol32(ped.functions_addr);
|
||||||
|
ped.names_addr = _htol32(ped.names_addr);
|
||||||
|
ped.ordinals_addr = _htol32(ped.ordinals_addr);
|
||||||
|
ped.time = _htol32(ped.time);
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s() M:0x%04x m:0x%04x n:0x%08x f:0x%08x@0x%08x"
|
||||||
|
" n:0x%0x8@0x%08x 0x%08x t:0x%08x\n", __func__,
|
||||||
|
ped.major, ped.minor, ped.name, ped.functions_cnt,
|
||||||
|
ped.functions_addr, ped.names_cnt, ped.names_addr,
|
||||||
|
ped.base, ped.time);
|
||||||
|
#endif
|
||||||
|
for(j = 0; j < ped.functions_cnt && j < ped.names_cnt; j++)
|
||||||
|
{
|
||||||
|
if(helper->seek(helper->format, ped.functions_addr - base
|
||||||
|
+ j * sizeof(f), SEEK_SET) < 0)
|
||||||
|
return -1;
|
||||||
|
if(helper->read(helper->format, &f, sizeof(f)) != sizeof(f))
|
||||||
|
return -1;
|
||||||
|
if(helper->seek(helper->format, ped.names_addr - base
|
||||||
|
+ j * sizeof(n), SEEK_SET) < 0)
|
||||||
|
return -1;
|
||||||
|
if(helper->read(helper->format, &n, sizeof(n)) != sizeof(n))
|
||||||
|
return -1;
|
||||||
|
if((p = _decode_string(format, n - base)) == NULL)
|
||||||
|
continue;
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s() 0x%08x@0x%08x \"%s\"\n", __func__,
|
||||||
|
n - base, f + vaddr, p);
|
||||||
|
#endif
|
||||||
|
/* XXX report errors */
|
||||||
|
helper->set_function(helper->format, f + vaddr, p, f, -1);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int _decode_error(FormatPlugin * format)
|
static int _decode_error(FormatPlugin * format)
|
||||||
{
|
{
|
||||||
return -error_set_code(1, "%s: %s", format->helper->get_filename(
|
return -error_set_code(1, "%s: %s", format->helper->get_filename(
|
||||||
format->helper->format), strerror(errno));
|
format->helper->format), strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char * _decode_string(FormatPlugin * format, off_t offset)
|
||||||
|
{
|
||||||
|
FormatPluginHelper * helper = format->helper;
|
||||||
|
char * ret = NULL;
|
||||||
|
char * p;
|
||||||
|
size_t len = 0;
|
||||||
|
ssize_t s;
|
||||||
|
size_t i;
|
||||||
|
const int inc = 32;
|
||||||
|
|
||||||
|
if(helper->seek(helper->format, offset, SEEK_SET) != offset)
|
||||||
|
return NULL;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if((p = realloc(ret, len + inc)) == NULL)
|
||||||
|
{
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret = p;
|
||||||
|
if((s = helper->read(helper->format, &ret[len], inc)) < 0)
|
||||||
|
{
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for(i = len; i < len + inc; i++)
|
||||||
|
if(ret[i] == '\0')
|
||||||
|
return ret;
|
||||||
|
len += s;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* accessors */
|
/* accessors */
|
||||||
/* pe_get_arch */
|
/* pe_get_arch */
|
||||||
|
Loading…
Reference in New Issue
Block a user