mirror of
https://github.com/radareorg/radare2.git
synced 2024-10-08 02:53:29 +00:00
Initial implementation of the PDB parser
* Contains 78 rebased commits
- add R_PDB struct
- add implementation of init_pdb_parser()
- add stub for init_pdb7_root_stream()
- add init_pdb_stream() function
- add functions for working with stream_file
- do fixes for stream_file_read
- add getting of sizes
- save streams to rlist
- add light implementation of read_root function
- add stubs for parsed_pdb_stream_init
- add parsing of pdb info stream
- start of parsing tpi header
- add stub for tpi stream
- fix stream file read. +stubs for eFIELD_LIST
- add parsing of lf_enumerate
- add parsing of lf_nesttype()
- add parsing of LF_METHOD
- add parsing of lf_member
- add some additional parsing of types
- fix some memory leaks
- add support of LF_METHOD and LF_MEMBER
- add support of LF_NESTTYPE
- add support of LF_ENUM
- add parsing of lf_structure
- add parsing of lf_pointer
- start of lf_array implementation
- back implementation of lf_array
- add implementation of LF_MODIFIER
- add implementaion of lf_arglist
- add implementaion of lf_mfunction
- add useful macros
- add implementation of lf_procedure
- add implementation of lf_union
- add free of sval and printf name of sval
- add implementation of LF_BITFIELD
- add implementation of LF_CLASS
- add implementation of LF_VTSHPAE
- start of refactoring
- finish refactor of the code
- fix memory leak issues
- some refactor of memory managment
- fix memory managment
- add supprot of ushort type
- add function for printing type name and value
- add API for getting leaf types members
- refactor of SType and STypeInfO
- add implementation of get_name/val/... for new types
- fix cast in some function of getting name, val, etc
- add stubs for resolving type
- add pointers to function for getting types
- add connections for types function pointers
- add stub for printing structures
- update memory manadgement and fix some problems in API for working with types
- add process of result from init_pdb function
- print more info about structure
- refactor of printing structure info
- Revert of 9fa8e7083c
refactor structure info printing
more pretty print
refactor code
add parsing of dbi header
add structure stabs for dbi stream
add parsing of dbi_ex_headers
add free for dbi stream
finish parsing of dbg stream
add stubs for streams from dbg stream
add fpo parsing
add free for fpo stream and do some refactor
add parsing of gdata stream
add parsing of pe stream
add parsing of fpo new stream
add fpo new stream
add omap stream parsing
add implementation of printing gvars
add setting parameters for pdb_parser
delete unused comments
delete unused comments
This commit is contained in:
parent
7b65bb16b2
commit
d547b037c9
@ -10,7 +10,7 @@ PFX=$(call rmdblslash,${DESTDIR}/${PREFIX})
|
||||
BFX=$(call rmdblslash,${DESTDIR}/${BINDIR})
|
||||
LFX=$(call rmdblslash,${DESTDIR}/${LIBDIR})
|
||||
|
||||
BINS=rax2 rasm2 rabin2 rahash2 radiff2 radare2 rafind2 rarun2 ragg2 r2agent
|
||||
BINS=pdb-parser rax2 rasm2 rabin2 rahash2 radiff2 radare2 rafind2 rarun2 ragg2 r2agent
|
||||
|
||||
all: preload
|
||||
@for a in ${BINS} ; do (cd $$a && ${MAKE} all) || exit 1; done
|
||||
|
64
binr/pdb-parser/pdb_parser.c
Normal file
64
binr/pdb-parser/pdb_parser.c
Normal file
@ -0,0 +1,64 @@
|
||||
#include <stdio.h>
|
||||
#include <r_pdb.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void print_usage()
|
||||
{
|
||||
printf("pdb_parser -f pdb_file [option]\n");
|
||||
printf("\t -f, --pdb_file : set pdb file to parse\n");
|
||||
printf("[option]:\n");
|
||||
printf("\t -t, --print_types : print all types parsed in pdb file\n");
|
||||
printf("\t -g, --print_globals : print all globals functions/variables parsed in pdb file\n");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int main(int argc, char **argv) {
|
||||
R_PDB pdb;
|
||||
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"pdb_file", required_argument, 0, 'f'},
|
||||
{"print_types", no_argument, 0, 't'},
|
||||
{"print_globals", required_argument, 0, 'g'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int option_index = 0;
|
||||
int c = 0;
|
||||
char *pdb_file = 0;
|
||||
|
||||
while(1) {
|
||||
c = getopt_long (argc, argv, ":f:tg:h",
|
||||
long_options, &option_index);
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'f':
|
||||
pdb_file = optarg;
|
||||
strcpy(&pdb.file_name, optarg);
|
||||
if (!init_pdb_parser(&pdb)) {
|
||||
printf("initialization error of pdb parser\n");
|
||||
return 0;
|
||||
}
|
||||
pdb.pdb_parse(&pdb);
|
||||
break;
|
||||
case 't':
|
||||
pdb.print_types(&pdb);
|
||||
break;
|
||||
case 'g':
|
||||
pdb.print_gvars(&pdb, *(int *)optarg);
|
||||
break;
|
||||
default:
|
||||
print_usage();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -45,6 +45,9 @@ EXTRA +=
|
||||
<include>format
|
||||
;
|
||||
|
||||
# PDB
|
||||
OBJS += pdb/omap.c pdb/pe.c pdb/gdata.c pdb/fpo.c pdb/dbi.c pdb/tpi.c pdb/stream_file.c pdb/pdb.c
|
||||
|
||||
# Java
|
||||
OBJS += p/bin_java.c ;
|
||||
EXTRA +=
|
||||
|
@ -18,6 +18,7 @@ STATIC_OBJS=$(addprefix $(LTOP)/bin/p/, $(STATIC_OBJ))
|
||||
OBJS=bin.o dbginfo.o bin_write.o demangle.o dwarf.o
|
||||
OBJS+=mangling/cxx/cp-demangle.o ${STATIC_OBJS}
|
||||
OBJS+=mangling/objc.o mangling/cxx.o
|
||||
OBJS+=pdb/omap.o pdb/pe.o pdb/gdata.o pdb/fpo.o pdb/dbi.o pdb/tpi.o pdb/stream_file.o pdb/pdb.o
|
||||
LINK+=$(SHLR)/java/libr_java.a
|
||||
|
||||
include $(TOP)/libr/rules.mk
|
||||
|
172
libr/bin/pdb/dbi.c
Normal file
172
libr/bin/pdb/dbi.c
Normal file
@ -0,0 +1,172 @@
|
||||
#include "dbi.h"
|
||||
|
||||
#include "stream_file.h"
|
||||
#include "tpi.h"
|
||||
|
||||
#define _ALIGN 4
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void free_dbi_stream(void *stream)
|
||||
{
|
||||
SDbiStream *t = (SDbiStream *) stream;
|
||||
RListIter *it = 0;
|
||||
SDBIExHeader *dbi_ex_header = 0;
|
||||
|
||||
it = r_list_iterator(t->dbiexhdrs);
|
||||
while (r_list_iter_next(it)) {
|
||||
dbi_ex_header = (SDBIExHeader *) r_list_iter_get(it);
|
||||
free(dbi_ex_header->modName.name);
|
||||
free(dbi_ex_header->objName.name);
|
||||
free(dbi_ex_header);
|
||||
}
|
||||
r_list_free(t->dbiexhdrs);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void parse_dbi_header(SDBIHeader *dbi_header, R_STREAM_FILE *stream_file)
|
||||
{
|
||||
stream_file_read(stream_file, sizeof(unsigned int), (char *)&dbi_header->magic);
|
||||
stream_file_read(stream_file, sizeof(unsigned int), (char *)&dbi_header->version);
|
||||
stream_file_read(stream_file, sizeof(unsigned int), (char *)&dbi_header->age);
|
||||
stream_file_read(stream_file, sizeof(short), (char *)&dbi_header->gssymStream);
|
||||
stream_file_read(stream_file, sizeof(unsigned short), (char *)&dbi_header->vers);
|
||||
stream_file_read(stream_file, sizeof(short), (char *)&dbi_header->pssymStream);
|
||||
stream_file_read(stream_file, sizeof(unsigned short), (char *)&dbi_header->pdbver);
|
||||
stream_file_read(stream_file, sizeof(short), (char *)&dbi_header->symrecStream);
|
||||
stream_file_read(stream_file, sizeof(unsigned short), (char *)&dbi_header->pdbver2);
|
||||
stream_file_read(stream_file, sizeof(unsigned int), (char *)&dbi_header->module_size);
|
||||
stream_file_read(stream_file, sizeof(unsigned int), (char *)&dbi_header->seccon_size);
|
||||
stream_file_read(stream_file, sizeof(unsigned int), (char *)&dbi_header->secmap_size);
|
||||
stream_file_read(stream_file, sizeof(unsigned int), (char *)&dbi_header->filinf_size);
|
||||
stream_file_read(stream_file, sizeof(unsigned int), (char *)&dbi_header->tsmap_size);
|
||||
stream_file_read(stream_file, sizeof(unsigned int), (char *)&dbi_header->mfc_index);
|
||||
stream_file_read(stream_file, sizeof(unsigned int), (char *)&dbi_header->dbghdr_size);
|
||||
stream_file_read(stream_file, sizeof(unsigned int), (char *)&dbi_header->ecinfo_size);
|
||||
stream_file_read(stream_file, sizeof(unsigned short), (char *)&dbi_header->flags);
|
||||
stream_file_read(stream_file, 2, (char *)&dbi_header->machine);
|
||||
stream_file_read(stream_file, sizeof(unsigned int), (char *)&dbi_header->resvd);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static int parse_ssymbol_range(char *data, int max_len, SSymbolRange *symbol_range)
|
||||
{
|
||||
int read_bytes = 0;
|
||||
|
||||
READ(read_bytes, 2, max_len, symbol_range->section, data, short);
|
||||
READ(read_bytes, 2, max_len, symbol_range->padding1, data, short);
|
||||
READ(read_bytes, 4, max_len, symbol_range->offset, data, int);
|
||||
READ(read_bytes, 4, max_len, symbol_range->size, data, int);
|
||||
READ(read_bytes, 4, max_len, symbol_range->flags, data, unsigned int);
|
||||
READ(read_bytes, 4, max_len, symbol_range->module, data, int);
|
||||
|
||||
// TODO: why not need to read this padding?
|
||||
// READ(read_bytes, 2, max_len, symbol_range->padding2, data, short);
|
||||
READ(read_bytes, 4, max_len, symbol_range->data_crc, data, unsigned int);
|
||||
READ(read_bytes, 4, max_len, symbol_range->reloc_crc, data, unsigned int);
|
||||
|
||||
return read_bytes;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static int parse_dbi_ex_header(char *data, int max_len, SDBIExHeader *dbi_ex_header)
|
||||
{
|
||||
unsigned int read_bytes = 0, before_read_bytes = 0;
|
||||
|
||||
READ(read_bytes, 4, max_len, dbi_ex_header->opened, data, unsigned int);
|
||||
|
||||
before_read_bytes = read_bytes;
|
||||
read_bytes += parse_ssymbol_range(data, max_len, &dbi_ex_header->range);
|
||||
data += (read_bytes - before_read_bytes);
|
||||
|
||||
READ(read_bytes, 2, max_len, dbi_ex_header->flags, data, unsigned short);
|
||||
READ(read_bytes, 2, max_len, dbi_ex_header->stream, data, short);
|
||||
READ(read_bytes, 4, max_len, dbi_ex_header->symSize, data, unsigned int);
|
||||
READ(read_bytes, 4, max_len, dbi_ex_header->oldLineSize, data, unsigned int);
|
||||
READ(read_bytes, 4, max_len, dbi_ex_header->lineSize, data, unsigned int);
|
||||
READ(read_bytes, 2, max_len, dbi_ex_header->nSrcFiles, data, short);
|
||||
READ(read_bytes, 2, max_len, dbi_ex_header->padding1, data, short);
|
||||
READ(read_bytes, 4, max_len, dbi_ex_header->offsets, data, unsigned int);
|
||||
READ(read_bytes, 4, max_len, dbi_ex_header->niSource, data, unsigned int);
|
||||
READ(read_bytes, 4, max_len, dbi_ex_header->niCompiler, data, unsigned int);
|
||||
|
||||
before_read_bytes = read_bytes;
|
||||
parse_sctring(&dbi_ex_header->modName, data, &read_bytes, max_len);
|
||||
data += (read_bytes - before_read_bytes);
|
||||
|
||||
before_read_bytes = read_bytes;
|
||||
parse_sctring(&dbi_ex_header->objName, data, &read_bytes, max_len);
|
||||
data += (read_bytes - before_read_bytes);
|
||||
|
||||
return read_bytes;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void parse_dbg_header(SDbiDbgHeader *dbg_header, R_STREAM_FILE *stream_file)
|
||||
{
|
||||
stream_file_read(stream_file, sizeof(short), (char *)&dbg_header->sn_fpo);
|
||||
stream_file_read(stream_file, sizeof(short), (char *)&dbg_header->sn_exception);
|
||||
stream_file_read(stream_file, sizeof(short), (char *)&dbg_header->sn_fixup);
|
||||
stream_file_read(stream_file, sizeof(short), (char *)&dbg_header->sn_omap_to_src);
|
||||
stream_file_read(stream_file, sizeof(short), (char *)&dbg_header->sn_omap_from_src);
|
||||
stream_file_read(stream_file, sizeof(short), (char *)&dbg_header->sn_section_hdr);
|
||||
stream_file_read(stream_file, sizeof(short), (char *)&dbg_header->sn_token_rid_map);
|
||||
stream_file_read(stream_file, sizeof(short), (char *)&dbg_header->sn_xdata);
|
||||
stream_file_read(stream_file, sizeof(short), (char *)&dbg_header->sn_pdata);
|
||||
stream_file_read(stream_file, sizeof(short), (char *)&dbg_header->sn_new_fpo);
|
||||
stream_file_read(stream_file, sizeof(short), (char *)&dbg_header->sn_section_hdr_orig);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void init_dbi_stream(SDbiStream *dbi_stream)
|
||||
{
|
||||
dbi_stream->free_ = free_dbi_stream;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void parse_dbi_stream(void *parsed_pdb_stream, R_STREAM_FILE *stream_file)
|
||||
{
|
||||
SDbiStream *dbi_stream = (SDbiStream *) parsed_pdb_stream;
|
||||
SDBIExHeader *dbi_ex_header = 0;
|
||||
int pos = 0;
|
||||
char *dbiexhdr_data = 0, *p_tmp = 0;
|
||||
int size = 0, sz = 0;
|
||||
int i = 0;
|
||||
|
||||
parse_dbi_header(&dbi_stream->dbi_header, stream_file);
|
||||
pos += sizeof(SDBIHeader) - 2; // 2 because enum in C equal to 4, but
|
||||
// to read just 2;
|
||||
stream_file_seek(stream_file, pos, 0);
|
||||
|
||||
size = dbi_stream->dbi_header.module_size;
|
||||
dbiexhdr_data = (char *) malloc(size);
|
||||
stream_file_read(stream_file, size, dbiexhdr_data);
|
||||
|
||||
dbi_stream->dbiexhdrs = r_list_new();
|
||||
p_tmp = dbiexhdr_data;
|
||||
while (i < size) {
|
||||
dbi_ex_header = (SDBIExHeader *) malloc(sizeof(SDBIExHeader));
|
||||
// TODO: rewrite for signature where can to do chech CAN_READ true?
|
||||
sz = parse_dbi_ex_header(p_tmp, size, dbi_ex_header);
|
||||
if ((sz % _ALIGN)) {
|
||||
sz = sz + (_ALIGN - (sz % _ALIGN));
|
||||
}
|
||||
i += sz;
|
||||
p_tmp += sz;
|
||||
r_list_append(dbi_stream->dbiexhdrs, dbi_ex_header);
|
||||
}
|
||||
|
||||
free(dbiexhdr_data);
|
||||
|
||||
// "Section Contribution"
|
||||
stream_file_seek(stream_file, dbi_stream->dbi_header.seccon_size, 1);
|
||||
// "Section Map"
|
||||
stream_file_seek(stream_file, dbi_stream->dbi_header.secmap_size, 1);
|
||||
// "File Info"
|
||||
stream_file_seek(stream_file, dbi_stream->dbi_header.filinf_size, 1);
|
||||
// "TSM"
|
||||
stream_file_seek(stream_file, dbi_stream->dbi_header.tsmap_size, 1);
|
||||
// "EC"
|
||||
stream_file_seek(stream_file, dbi_stream->dbi_header.ecinfo_size, 1);
|
||||
|
||||
parse_dbg_header(&dbi_stream->dbg_header, stream_file);
|
||||
}
|
9
libr/bin/pdb/dbi.h
Normal file
9
libr/bin/pdb/dbi.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef DBI_H
|
||||
#define DBI_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void init_dbi_stream(SDbiStream *dbi_stream);
|
||||
void parse_dbi_stream(void *parsed_pdb_stream, R_STREAM_FILE *stream_file);
|
||||
|
||||
#endif // DBI_H
|
126
libr/bin/pdb/fpo.c
Normal file
126
libr/bin/pdb/fpo.c
Normal file
@ -0,0 +1,126 @@
|
||||
#include "fpo.h"
|
||||
|
||||
#include "stream_file.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static int parse_fpo_data(char *data, int data_size, int *read_bytes, SFPO_DATA *fpo_data)
|
||||
{
|
||||
int curr_read_bytes = *read_bytes;
|
||||
|
||||
READ(*read_bytes, 4, data_size, fpo_data->ul_off_start, data, unsigned int);
|
||||
READ(*read_bytes, 4, data_size, fpo_data->cb_proc_size, data, unsigned int);
|
||||
READ(*read_bytes, 4, data_size, fpo_data->cdw_locals, data, unsigned int);
|
||||
READ(*read_bytes, 2, data_size, fpo_data->cdw_params, data, unsigned short);
|
||||
READ(*read_bytes, 2, data_size, fpo_data->bit_values.bit_values, data, unsigned short);
|
||||
|
||||
fpo_data->bit_values.bit_values = SWAP_UINT16(fpo_data->bit_values.bit_values);
|
||||
|
||||
return (*read_bytes - curr_read_bytes);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static int parse_fpo_data_v2(char *data, int data_size, int *read_bytes, SFPO_DATA_V2 *fpo_data)
|
||||
{
|
||||
int curr_read_bytes = *read_bytes;
|
||||
|
||||
memcpy(fpo_data, data, sizeof(SFPO_DATA_V2));
|
||||
*read_bytes += sizeof(SFPO_DATA_V2);
|
||||
|
||||
return (*read_bytes - curr_read_bytes);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void parse_fpo_stream(void *stream, R_STREAM_FILE *stream_file)
|
||||
{
|
||||
int data_size;
|
||||
char *data = 0, *ptmp = 0;
|
||||
int curr_read_bytes = 0, read_bytes = 0;
|
||||
SFPO_DATA *fpo_data = 0;
|
||||
SFPOStream *fpo_stream = 0;
|
||||
|
||||
stream_file_get_size(stream_file, &data_size);
|
||||
data = (char *) malloc(data_size);
|
||||
stream_file_get_data(stream_file, data);
|
||||
|
||||
fpo_stream = (SFPOStream *) stream;
|
||||
fpo_stream->fpo_data_list = r_list_new();
|
||||
curr_read_bytes = 0;
|
||||
ptmp = data;
|
||||
while (read_bytes < data_size) {
|
||||
fpo_data = (SFPO_DATA *) malloc(sizeof(SFPO_DATA));
|
||||
curr_read_bytes = parse_fpo_data(ptmp, data_size, &read_bytes, fpo_data);
|
||||
ptmp += curr_read_bytes;
|
||||
|
||||
if (!curr_read_bytes) {
|
||||
free(fpo_data);
|
||||
break;
|
||||
}
|
||||
|
||||
r_list_append(fpo_stream->fpo_data_list, fpo_data);
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void free_fpo_stream(void *stream)
|
||||
{
|
||||
SFPOStream *fpo_stream = (SFPOStream *) stream;
|
||||
RListIter *it = 0;
|
||||
SFPO_DATA *fpo_data = 0;
|
||||
|
||||
it = r_list_iterator(fpo_stream->fpo_data_list);
|
||||
while (r_list_iter_next(it)) {
|
||||
fpo_data = (SFPO_DATA *) r_list_iter_get(it);
|
||||
free(fpo_data);
|
||||
}
|
||||
r_list_free(fpo_stream->fpo_data_list);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void free_fpo_new_stream(void *stream)
|
||||
{
|
||||
SFPONewStream *fpo_stream = (SFPONewStream *) stream;
|
||||
RListIter *it = 0;
|
||||
SFPO_DATA_V2 *fpo_data = 0;
|
||||
|
||||
it = r_list_iterator(fpo_stream->fpo_data_list);
|
||||
while (r_list_iter_next(it)) {
|
||||
fpo_data = (SFPO_DATA_V2 *) r_list_iter_get(it);
|
||||
free(fpo_data);
|
||||
}
|
||||
r_list_free(fpo_stream->fpo_data_list);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void parse_fpo_new_stream(void *stream, R_STREAM_FILE *stream_file)
|
||||
{
|
||||
int data_size;
|
||||
char *data = 0, *ptmp = 0;
|
||||
int curr_read_bytes = 0, read_bytes = 0;
|
||||
SFPO_DATA_V2 *fpo_data = 0;
|
||||
SFPONewStream *fpo_stream = 0;
|
||||
|
||||
stream_file_get_size(stream_file, &data_size);
|
||||
data = (char *) malloc(data_size);
|
||||
stream_file_get_data(stream_file, data);
|
||||
|
||||
fpo_stream = (SFPONewStream *) stream;
|
||||
fpo_stream->fpo_data_list = r_list_new();
|
||||
curr_read_bytes = 0;
|
||||
ptmp = data;
|
||||
while (read_bytes < data_size) {
|
||||
fpo_data = (SFPO_DATA_V2 *) malloc(sizeof(SFPO_DATA_V2));
|
||||
curr_read_bytes = parse_fpo_data_v2(ptmp, data_size, &read_bytes, fpo_data);
|
||||
ptmp += curr_read_bytes;
|
||||
|
||||
if (!curr_read_bytes) {
|
||||
free(fpo_data);
|
||||
break;
|
||||
}
|
||||
|
||||
r_list_append(fpo_stream->fpo_data_list, fpo_data);
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
12
libr/bin/pdb/fpo.h
Normal file
12
libr/bin/pdb/fpo.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef FPO_H
|
||||
#define FPO_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void free_fpo_stream(void *stream);
|
||||
void parse_fpo_stream(void *stream, R_STREAM_FILE *stream_file);
|
||||
|
||||
void free_fpo_new_stream(void *stream);
|
||||
void parse_fpo_new_stream(void *stream, R_STREAM_FILE *stream_file);
|
||||
|
||||
#endif // FPO_H
|
76
libr/bin/pdb/gdata.c
Normal file
76
libr/bin/pdb/gdata.c
Normal file
@ -0,0 +1,76 @@
|
||||
#include "gdata.h"
|
||||
|
||||
#include "stream_file.h"
|
||||
#include "tpi.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void parse_global(char *data, int data_size, SGlobal *global)
|
||||
{
|
||||
unsigned int read_bytes = 2;
|
||||
|
||||
READ(read_bytes, 4, data_size, global->symtype, data, unsigned int);
|
||||
READ(read_bytes, 4, data_size, global->offset, data, unsigned int);
|
||||
READ(read_bytes, 2, data_size, global->segment, data, unsigned short);
|
||||
if (global->leaf_type == 0x110E) {
|
||||
parse_sctring(&global->name, (unsigned char *)data, &read_bytes, data_size);
|
||||
} else {
|
||||
READ(read_bytes, 1, data_size, global->name.size, data, unsigned char);
|
||||
init_scstring(&global->name, global->name.size, data);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void parse_gdata_stream(void *stream, R_STREAM_FILE *stream_file)
|
||||
{
|
||||
unsigned short len = 0;
|
||||
unsigned short leaf_type = 0;
|
||||
char *data = 0;
|
||||
SGDATAStream *data_stream = (SGDATAStream *) stream;
|
||||
SGlobal *global = 0;
|
||||
|
||||
data_stream->globals_list = r_list_new();
|
||||
while (1) {
|
||||
stream_file_read(stream_file, 2, (char *)&len);
|
||||
if (len == 0)
|
||||
break;
|
||||
data = (char *) malloc(len);
|
||||
stream_file_read(stream_file, len, data);
|
||||
|
||||
leaf_type = *(unsigned short *) (data);
|
||||
if ((leaf_type == 0x110E) || (leaf_type == 0x1009)) {
|
||||
global = (SGlobal *) malloc(sizeof(SGlobal));
|
||||
global->leaf_type = leaf_type;
|
||||
parse_global(data + 2, len, global);
|
||||
r_list_append(data_stream->globals_list, global);
|
||||
}
|
||||
free(data);
|
||||
}
|
||||
|
||||
// TODO: for more fast access
|
||||
// for g in self.globals:
|
||||
// if not hasattr(g, 'symtype'): continue
|
||||
// if g.symtype == 0:
|
||||
// if g.name.startswith("_"):
|
||||
// self.vars[g.name[1:]] = g
|
||||
// else:
|
||||
// self.vars[g.name] = g
|
||||
// elif g.symtype == 2:
|
||||
// self.funcs[g.name] = g
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void free_gdata_stream(void *stream)
|
||||
{
|
||||
SGDATAStream *data_stream = (SGDATAStream *) stream;
|
||||
SGlobal *global = 0;
|
||||
RListIter *it = 0;
|
||||
|
||||
it = r_list_iterator(data_stream->globals_list);
|
||||
while (r_list_iter_next(it)) {
|
||||
global = (SGlobal *) r_list_iter_get(it);
|
||||
if (global->name.name)
|
||||
free(global->name.name);
|
||||
free(global);
|
||||
}
|
||||
r_list_free(data_stream->globals_list);
|
||||
}
|
9
libr/bin/pdb/gdata.h
Normal file
9
libr/bin/pdb/gdata.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef GDATA_H
|
||||
#define GDATA_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void parse_gdata_stream(void *stream, R_STREAM_FILE *stream_file);
|
||||
void free_gdata_stream(void *stream);
|
||||
|
||||
#endif // GDATA_H
|
135
libr/bin/pdb/omap.c
Normal file
135
libr/bin/pdb/omap.c
Normal file
@ -0,0 +1,135 @@
|
||||
#include "omap.h"
|
||||
|
||||
#include "types.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static int parse_omap_entry(char *data, int data_size, int *read_bytes, SOmapEntry *omap_entry)
|
||||
{
|
||||
int curr_read_bytes = *read_bytes;
|
||||
|
||||
memcpy(omap_entry, data, sizeof(SOmapEntry));
|
||||
*read_bytes += sizeof(SOmapEntry);
|
||||
|
||||
return (*read_bytes - curr_read_bytes);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void parse_omap_stream(void *stream, R_STREAM_FILE *stream_file)
|
||||
{
|
||||
int data_size;
|
||||
char *data = 0, *ptmp = 0;
|
||||
int curr_read_bytes = 0, read_bytes = 0;
|
||||
SOmapEntry *omap_entry = 0;
|
||||
SOmapStream *omap_stream = 0;
|
||||
|
||||
stream_file_get_size(stream_file, &data_size);
|
||||
data = (char *) malloc(data_size);
|
||||
stream_file_get_data(stream_file, data);
|
||||
|
||||
omap_stream = (SOmapStream *) stream;
|
||||
omap_stream->froms = 0;
|
||||
omap_stream->omap_entries = r_list_new();
|
||||
curr_read_bytes = 0;
|
||||
ptmp = data;
|
||||
while (read_bytes < data_size) {
|
||||
omap_entry = (SOmapEntry *) malloc(sizeof(SOmapEntry));
|
||||
curr_read_bytes = parse_omap_entry(ptmp, data_size, &read_bytes, omap_entry);
|
||||
ptmp += curr_read_bytes;
|
||||
|
||||
if (!curr_read_bytes) {
|
||||
free(omap_entry);
|
||||
break;
|
||||
}
|
||||
|
||||
r_list_append(omap_stream->omap_entries, omap_entry);
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void free_omap_stream(void *stream)
|
||||
{
|
||||
SOmapStream *omap_stream = (SOmapStream *) stream;
|
||||
RListIter *it = 0;
|
||||
SOmapEntry *omap_entry = 0;
|
||||
|
||||
it = r_list_iterator(omap_stream->omap_entries);
|
||||
while (r_list_iter_next(it)) {
|
||||
omap_entry = (SOmapEntry *) r_list_iter_get(it);
|
||||
free(omap_entry);
|
||||
}
|
||||
r_list_free(omap_stream->omap_entries);
|
||||
}
|
||||
|
||||
// inclusive indices
|
||||
// 0 <= imin when using truncate toward zero divide
|
||||
// imid = (imin+imax)/2;
|
||||
// imin unrestricted when using truncate toward minus infinity divide
|
||||
// imid = (imin+imax)>>1; or
|
||||
// imid = (int)floor((imin+imax)/2.0);
|
||||
static int binary_search(unsigned int *A, int key, int imin, int imax)
|
||||
{
|
||||
int imid;
|
||||
|
||||
// continually narrow search until just one element remains
|
||||
while (imin < imax)
|
||||
{
|
||||
imid = (imin + imax) / 2;
|
||||
|
||||
if (A[imid] < key)
|
||||
imin = imid + 1;
|
||||
else
|
||||
imax = imid;
|
||||
}
|
||||
// At exit of while:
|
||||
// if A[] is empty, then imax < imin
|
||||
// otherwise imax == imin
|
||||
|
||||
// deferred test for equality
|
||||
if ((imax == imin) && (A[imin] == key))
|
||||
return imin;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int omap_remap(void *stream, int address)
|
||||
{
|
||||
SOmapStream *omap_stream = (SOmapStream *) stream;
|
||||
SOmapEntry *omap_entry = 0;
|
||||
RListIter *it = 0;
|
||||
int i = 0;
|
||||
int pos = 0;
|
||||
int len = 0;
|
||||
|
||||
if (!omap_stream) {
|
||||
return address;
|
||||
}
|
||||
|
||||
len = r_list_length(omap_stream->omap_entries);
|
||||
|
||||
if (omap_stream->froms == 0) {
|
||||
omap_stream->froms = (unsigned int *) malloc(4 * len);
|
||||
it = r_list_iterator(omap_stream->omap_entries);
|
||||
while (r_list_iter_next(it)) {
|
||||
omap_entry = (SOmapEntry *) r_list_iter_get(it);
|
||||
omap_stream->froms[i] = omap_entry->from;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// mb (len -1) ???
|
||||
pos = binary_search(omap_stream->froms, address, 0, (len));
|
||||
|
||||
if (omap_stream->froms[pos] != address) {
|
||||
pos -= 1;
|
||||
}
|
||||
|
||||
omap_entry = (SOmapEntry *) r_list_get_n(omap_stream->omap_entries, pos);
|
||||
if (omap_entry->to == 0) {
|
||||
return omap_entry->to;
|
||||
} else {
|
||||
return omap_entry->to + (address - omap_entry->from);
|
||||
}
|
||||
}
|
10
libr/bin/pdb/omap.h
Normal file
10
libr/bin/pdb/omap.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef OMAP_H
|
||||
#define OMAP_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void parse_omap_stream(void *stream, R_STREAM_FILE *stream_file);
|
||||
void free_omap_stream(void *stream);
|
||||
int omap_remap(void *stream, int address);
|
||||
|
||||
#endif // OMAP_H
|
742
libr/bin/pdb/pdb.c
Normal file
742
libr/bin/pdb/pdb.c
Normal file
@ -0,0 +1,742 @@
|
||||
|
||||
#include <r_pdb.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "stream_file.h"
|
||||
#include "types.h"
|
||||
#include "tpi.h"
|
||||
#include "dbi.h"
|
||||
#include "fpo.h"
|
||||
#include "gdata.h"
|
||||
#include "pe.h"
|
||||
#include "omap.h"
|
||||
|
||||
#define PDB2_SIGNATURE "Microsoft C/C++ program database 2.00\r\n\032JG\0\0"
|
||||
#define PDB7_SIGNATURE "Microsoft C/C++ MSF 7.00\r\n\x1ADS\0\0\0"
|
||||
#define PDB7_SIGNATURE_LEN 32
|
||||
#define PDB2_SIGNATURE_LEN 51
|
||||
|
||||
typedef void (*parse_stream_)(void *stream, R_STREAM_FILE *stream_file);
|
||||
|
||||
typedef struct {
|
||||
int indx;
|
||||
parse_stream_ parse_stream;
|
||||
void *stream;
|
||||
EStream type;
|
||||
free_func free;
|
||||
} SStreamParseFunc;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void free_pdb_stream(void *stream)
|
||||
{
|
||||
R_PDB_STREAM *pdb_stream = (R_PDB_STREAM *) stream;
|
||||
|
||||
if (pdb_stream) {
|
||||
if (pdb_stream->pages) {
|
||||
// free(pdb_stream->pages);
|
||||
pdb_stream->pages = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//static void pdb_stream_get_data(R_PDB_STREAM *pdb_stream, char *data)
|
||||
//{
|
||||
// int pos = stream_file_tell(&pdb_stream->stream_file);
|
||||
// stream_file_seek(&pdb_stream->stream_file, 0, 0);
|
||||
// stream_file_read(&pdb_stream->stream_file, -1, data);
|
||||
// stream_file_seek(&pdb_stream->stream_file, pos, 0);
|
||||
//}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// size - default value = -1
|
||||
/// page_size - default value = 0x1000
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static int init_r_pdb_stream(R_PDB_STREAM *pdb_stream, FILE *fp, int *pages,
|
||||
int pages_amount, int index, int size, int page_size)
|
||||
{
|
||||
// printf("init_r_pdb_stream()\n");
|
||||
|
||||
pdb_stream->fp = fp;
|
||||
pdb_stream->pages = pages;
|
||||
pdb_stream->indx = index;
|
||||
pdb_stream->page_size = page_size;
|
||||
pdb_stream->pages_amount = pages_amount;
|
||||
|
||||
if (size == -1) {
|
||||
pdb_stream->size = pages_amount * page_size;
|
||||
} else {
|
||||
pdb_stream->size = size;
|
||||
}
|
||||
|
||||
init_r_stream_file(&(pdb_stream->stream_file), fp, pages, pages_amount, size, page_size);
|
||||
|
||||
pdb_stream->free_ = free_pdb_stream;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static int read_int_var(char *var_name, int *var, FILE *fp)
|
||||
{
|
||||
int bytes_read = fread(var, 4, 1, fp);
|
||||
if (bytes_read != 1) {
|
||||
printf("error while reading from file [%s]", var_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static int count_pages(int length, int page_size)
|
||||
{
|
||||
int num_pages = 0;
|
||||
num_pages = length / page_size;
|
||||
if (length % page_size)
|
||||
num_pages++;
|
||||
return num_pages;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static int init_pdb7_root_stream(R_PDB *pdb, int *root_page_list, int pages_amount,
|
||||
EStream indx, int root_size, int page_size)
|
||||
{
|
||||
int num_streams = 0;
|
||||
char *data = 0;
|
||||
char *tmp_data = 0;
|
||||
int *tmp_sizes = 0;
|
||||
int num_pages = 0;
|
||||
int i = 0;
|
||||
int *sizes = 0;
|
||||
int stream_size = 0;
|
||||
int pos = 0;
|
||||
int pn_start, off_start;
|
||||
R_PDB_STREAM *pdb_stream = 0;
|
||||
int data_size = 0;
|
||||
|
||||
char *tmp;
|
||||
|
||||
R_PDB7_ROOT_STREAM *root_stream7;
|
||||
|
||||
pdb->root_stream = (R_PDB7_ROOT_STREAM *) malloc(sizeof(R_PDB7_ROOT_STREAM));
|
||||
init_r_pdb_stream(pdb->root_stream, pdb->fp, root_page_list, pages_amount,
|
||||
indx, root_size, page_size);
|
||||
|
||||
root_stream7 = pdb->root_stream;
|
||||
pdb_stream = &(root_stream7->pdb_stream);
|
||||
|
||||
stream_file_get_size(&pdb_stream->stream_file, &data_size);
|
||||
data = (char *) malloc(data_size);
|
||||
stream_file_get_data(&pdb_stream->stream_file, data);
|
||||
|
||||
num_streams = *(int *)data;
|
||||
tmp_data = data;
|
||||
tmp_data += 4;
|
||||
|
||||
root_stream7->num_streams = num_streams;
|
||||
|
||||
sizes = (int *) malloc(num_streams * 4);
|
||||
|
||||
for (i = 0; i < num_streams; i++) {
|
||||
stream_size = *(int *)(tmp_data);
|
||||
tmp_data += 4;
|
||||
if (stream_size == 0xffffffff) {
|
||||
stream_size = 0;
|
||||
}
|
||||
memcpy(sizes + i, &stream_size, 4);
|
||||
}
|
||||
|
||||
// char *tmp_file_name = (char *) malloc(strlen("/root/test.pdb.000") + 1);
|
||||
// short ii;
|
||||
// FILE *tmp_file;
|
||||
tmp_data = ((char *)data + num_streams * 4 + 4);
|
||||
root_stream7->streams_list = r_list_new();
|
||||
RList *pList = root_stream7->streams_list;
|
||||
SPage *page = 0;
|
||||
for (i = 0; i < num_streams; i++) {
|
||||
num_pages = count_pages(sizes[i], page_size);
|
||||
|
||||
tmp = (char *) malloc(num_pages * 4);
|
||||
memset(tmp, 0, num_pages * 4);
|
||||
page = (SPage *) malloc(sizeof(SPage));
|
||||
if (num_pages != 0) {
|
||||
memcpy(tmp, tmp_data + pos, num_pages * 4);
|
||||
pos += num_pages * 4;
|
||||
// sprintf(tmp_file_name, "%s%d", "/root/test.pdb", i);
|
||||
// tmp_file = fopen(tmp_file_name, "wb");
|
||||
// fwrite(tmp, num_pages * 4, 1, tmp_file);
|
||||
// fclose(tmp_file);
|
||||
page->stream_size = sizes[i];
|
||||
page->stream_pages = tmp;
|
||||
page->num_pages = num_pages;
|
||||
} else {
|
||||
page->stream_size = 0;
|
||||
page->stream_pages = 0;
|
||||
page->num_pages = 0;
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
r_list_append(pList, page);
|
||||
}
|
||||
|
||||
free(sizes);
|
||||
free(data);
|
||||
printf("init_pdb7_root_stream()\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void init_parsed_pdb_stream(SParsedPDBStream *pdb_stream, FILE *fp, int *pages,
|
||||
int pages_amount, int index, int size,
|
||||
int page_size, f_load pLoad)
|
||||
{
|
||||
pdb_stream->pdb_stream = (R_PDB_STREAM *) malloc(sizeof(R_PDB_STREAM));
|
||||
init_r_pdb_stream(pdb_stream->pdb_stream, fp, pages, pages_amount, index, size, page_size);
|
||||
pdb_stream->load = pLoad;
|
||||
if (pLoad != NULL) {
|
||||
pLoad(pdb_stream, &(pdb_stream->pdb_stream->stream_file));
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void parse_pdb_info_stream(void *parsed_pdb_stream, R_STREAM_FILE *stream)
|
||||
{
|
||||
SPDBInfoStream *tmp = (SPDBInfoStream *)parsed_pdb_stream;
|
||||
|
||||
tmp->names = 0;
|
||||
|
||||
stream_file_read(stream, 4, (char *)&tmp->/*data.*/version);
|
||||
stream_file_read(stream, 4, (char *)&tmp->/*data.*/time_date_stamp);
|
||||
stream_file_read(stream, 4, (char *)&tmp->/*data.*/age);
|
||||
stream_file_read(stream, 4, (char *)&tmp->/*data.*/guid.data1);
|
||||
stream_file_read(stream, 2, (char *)&tmp->/*data.*/guid.data2);
|
||||
stream_file_read(stream, 2, (char *)&tmp->/*data.*/guid.data3);
|
||||
stream_file_read(stream, 8, (char *)&tmp->/*data.*/guid.data4);
|
||||
stream_file_read(stream, 4, (char *)&tmp->/*data.*/cb_names);
|
||||
|
||||
tmp->/*data.*/names = (char *) malloc(tmp->/*data.*/cb_names);
|
||||
stream_file_read(stream, tmp->/*data.*/cb_names, tmp->/*data.*/names);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void free_info_stream(void *stream)
|
||||
{
|
||||
SPDBInfoStream *info_stream = (SPDBInfoStream *)stream;
|
||||
|
||||
free(info_stream->names);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define ADD_INDX_TO_LIST(list, index, stream_size, stream_type, free_func, parse_func) { \
|
||||
if (index != -1) { \
|
||||
SStreamParseFunc *stream_parse_func = (SStreamParseFunc *) malloc(sizeof(SStreamParseFunc)); \
|
||||
stream_parse_func->indx = (index); \
|
||||
stream_parse_func->type = (stream_type); \
|
||||
stream_parse_func->parse_stream = (parse_func); \
|
||||
stream_parse_func->free = (free_func); \
|
||||
if (stream_size) { \
|
||||
stream_parse_func->stream = malloc(stream_size); \
|
||||
} else { \
|
||||
stream_parse_func->stream = 0; \
|
||||
} \
|
||||
r_list_append((list), stream_parse_func); \
|
||||
} \
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void fill_list_for_stream_parsing(RList *l, SDbiStream *dbi_stream)
|
||||
{
|
||||
ADD_INDX_TO_LIST(l, dbi_stream->dbi_header.symrecStream, sizeof(SGDATAStream),
|
||||
ePDB_STREAM_GSYM, free_gdata_stream, parse_gdata_stream);
|
||||
ADD_INDX_TO_LIST(l, dbi_stream->dbg_header.sn_section_hdr, sizeof(SPEStream),
|
||||
ePDB_STREAM_SECT_HDR, free_pe_stream, parse_pe_stream);
|
||||
ADD_INDX_TO_LIST(l, dbi_stream->dbg_header.sn_section_hdr_orig, sizeof(SPEStream),
|
||||
ePDB_STREAM_SECT__HDR_ORIG, free_pe_stream, parse_pe_stream);
|
||||
ADD_INDX_TO_LIST(l, dbi_stream->dbg_header.sn_omap_to_src, sizeof(SOmapStream),
|
||||
ePDB_STREAM_OMAP_TO_SRC, free_omap_stream, parse_omap_stream);
|
||||
ADD_INDX_TO_LIST(l, dbi_stream->dbg_header.sn_omap_from_src, sizeof(SOmapStream),
|
||||
ePDB_STREAM_OMAP_FROM_SRC, free_omap_stream, parse_omap_stream);
|
||||
ADD_INDX_TO_LIST(l, dbi_stream->dbg_header.sn_fpo, sizeof(SFPOStream),
|
||||
ePDB_STREAM_FPO, free_fpo_stream, parse_fpo_stream);
|
||||
ADD_INDX_TO_LIST(l, dbi_stream->dbg_header.sn_new_fpo, sizeof(SFPONewStream),
|
||||
ePDB_STREAM_FPO_NEW, free_fpo_stream, parse_fpo_new_stream);
|
||||
|
||||
// unparsed, but know their names
|
||||
ADD_INDX_TO_LIST(l, dbi_stream->dbg_header.sn_xdata, 0, ePDB_STREAM_XDATA, 0, 0);
|
||||
ADD_INDX_TO_LIST(l, dbi_stream->dbg_header.sn_pdata, 0, ePDB_STREAM_PDATA, 0, 0);
|
||||
ADD_INDX_TO_LIST(l, dbi_stream->dbg_header.sn_token_rid_map, 0, ePDB_STREAM_TOKEN_RID_MAP, 0, 0);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void find_indx_in_list(RList *l, int index, SStreamParseFunc **res)
|
||||
{
|
||||
SStreamParseFunc *stream_parse_func = 0;
|
||||
RListIter *it = 0;
|
||||
|
||||
*res = 0;
|
||||
it = r_list_iterator(l);
|
||||
while (r_list_iter_next(it)) {
|
||||
stream_parse_func = (SStreamParseFunc *) r_list_iter_get(it);
|
||||
if (index == stream_parse_func->indx) {
|
||||
*res = stream_parse_func;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static int pdb_read_root(R_PDB *pdb)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
RList *pList = pdb->pdb_streams;
|
||||
R_PDB7_ROOT_STREAM *root_stream = pdb->root_stream;
|
||||
R_PDB_STREAM *pdb_stream = 0;
|
||||
SParsedPDBStream *parsed_pdb_stream = 0;
|
||||
SPDBInfoStream *pdb_info_stream = 0;
|
||||
STpiStream *tpi_stream = 0;
|
||||
R_STREAM_FILE stream_file;
|
||||
RListIter *it;
|
||||
SPage *page = 0;
|
||||
RList *tmp_list = 0;
|
||||
SStreamParseFunc *stream_parse_func = 0;
|
||||
|
||||
it = r_list_iterator(root_stream->streams_list);
|
||||
while (r_list_iter_next(it)) {
|
||||
page = (SPage*) r_list_iter_get(it);
|
||||
init_r_stream_file(&stream_file, pdb->fp, page->stream_pages,
|
||||
page->num_pages/*root_stream->pdb_stream.pages_amount*/,
|
||||
page->stream_size,
|
||||
root_stream->pdb_stream.page_size);
|
||||
switch (i) {
|
||||
//TODO: rewrite for style like for streams from dbg stream
|
||||
// look default
|
||||
case ePDB_STREAM_PDB:
|
||||
pdb_info_stream = (SPDBInfoStream *) malloc(sizeof(SPDBInfoStream));
|
||||
pdb_info_stream->free_ = free_info_stream;
|
||||
parse_pdb_info_stream(pdb_info_stream, &stream_file);
|
||||
r_list_append(pList, pdb_info_stream);
|
||||
break;
|
||||
case ePDB_STREAM_TPI:
|
||||
tpi_stream = (STpiStream *) malloc(sizeof(STpiStream));
|
||||
init_tpi_stream(tpi_stream);
|
||||
parse_tpi_stream(tpi_stream, &stream_file);
|
||||
r_list_append(pList, tpi_stream);
|
||||
break;
|
||||
case ePDB_STREAM_DBI:
|
||||
{
|
||||
SDbiStream *dbi_stream = (SDbiStream *) malloc(sizeof(SDbiStream));
|
||||
init_dbi_stream(dbi_stream);
|
||||
parse_dbi_stream(dbi_stream, &stream_file);
|
||||
r_list_append(pList, dbi_stream);
|
||||
pdb->pdb_streams2 = r_list_new();
|
||||
fill_list_for_stream_parsing(pdb->pdb_streams2, dbi_stream);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
find_indx_in_list(pdb->pdb_streams2, i, &stream_parse_func);
|
||||
if (stream_parse_func) {
|
||||
if (stream_parse_func->parse_stream) {
|
||||
stream_parse_func->parse_stream(stream_parse_func->stream,
|
||||
&stream_file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pdb_stream = (R_PDB_STREAM *) malloc(sizeof(R_PDB_STREAM));
|
||||
init_r_pdb_stream(pdb_stream, pdb->fp, page->stream_pages,
|
||||
root_stream->pdb_stream.pages_amount, i,
|
||||
page->stream_size,
|
||||
root_stream->pdb_stream.page_size);
|
||||
r_list_append(pList, pdb_stream);
|
||||
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static int pdb7_parse(R_PDB *pdb)
|
||||
{
|
||||
printf("pdb7_parse()\n");
|
||||
|
||||
char signature[PDB7_SIGNATURE_LEN + 1];
|
||||
int page_size = 0;
|
||||
int alloc_tbl_ptr = 0;
|
||||
int num_file_pages = 0;
|
||||
int root_size = 0;
|
||||
int reserved = 0;
|
||||
|
||||
int num_root_pages = 0;
|
||||
int num_root_index_pages = 0;
|
||||
int *root_index_pages = 0;
|
||||
void *root_page_data = 0;
|
||||
int *root_page_list = 0;
|
||||
|
||||
int i = 0;
|
||||
void *p_tmp;
|
||||
|
||||
int bytes_read = 0;
|
||||
|
||||
bytes_read = fread(signature, 1, PDB7_SIGNATURE_LEN, pdb->fp);
|
||||
if (bytes_read != PDB7_SIGNATURE_LEN) {
|
||||
printf("error while reading PDB7_SIGNATURE\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (read_int_var("page_size", &page_size, pdb->fp) == 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (read_int_var("alloc_tbl_ptr", &alloc_tbl_ptr, pdb->fp) == 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (read_int_var("num_file_pages", &num_file_pages, pdb->fp) == 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (read_int_var("root_size", &root_size, pdb->fp) == 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (read_int_var("reserved", &reserved, pdb->fp) == 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
// FIXME: why they is not equal ????
|
||||
// if (memcmp(signature, PDB7_SIGNATURE, PDB7_SIGNATURE_LEN) != 0) {
|
||||
// printf("Invalid signature for PDB7 format\n");
|
||||
// //goto error;
|
||||
// }
|
||||
|
||||
num_root_pages = count_pages(root_size, page_size);
|
||||
num_root_index_pages = count_pages((num_root_pages * 4), page_size);
|
||||
|
||||
root_index_pages = (int *)malloc(sizeof(int) * num_root_index_pages);
|
||||
if (!root_index_pages) {
|
||||
printf("error memory allocation\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
bytes_read = fread(root_index_pages, 4, num_root_index_pages, pdb->fp);
|
||||
if (bytes_read != num_root_index_pages) {
|
||||
printf("error while reading root_index_pages\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
root_page_data = (int *)malloc(page_size * num_root_index_pages);
|
||||
if (!root_page_data) {
|
||||
printf("error memory allocation of root_page_data\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
p_tmp = root_page_data;
|
||||
for (i = 0; i < num_root_index_pages; i++) {
|
||||
fseek(pdb->fp, root_index_pages[i] * page_size, SEEK_SET);
|
||||
fread(p_tmp, page_size, 1, pdb->fp);
|
||||
p_tmp = (char *)p_tmp + page_size;
|
||||
}
|
||||
|
||||
root_page_list = (int *)malloc(sizeof(int) * num_root_pages);
|
||||
if (!root_page_list) {
|
||||
printf("error: memory allocation of root page\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
p_tmp = root_page_data;
|
||||
for (i = 0; i < num_root_pages; i++) {
|
||||
root_page_list[i] = *((int *)p_tmp);
|
||||
p_tmp = (int *)p_tmp + 1;
|
||||
}
|
||||
|
||||
pdb->pdb_streams2 = 0;
|
||||
init_pdb7_root_stream(pdb, root_page_list, num_root_pages, ePDB_STREAM_ROOT, root_size, page_size);
|
||||
pdb_read_root(pdb);
|
||||
|
||||
if (root_page_list) {
|
||||
free(root_page_list);
|
||||
root_page_list = 0;
|
||||
}
|
||||
|
||||
if (root_page_data) {
|
||||
free(root_page_data);
|
||||
root_page_data = 0;
|
||||
}
|
||||
|
||||
if (root_index_pages) {
|
||||
free(root_index_pages);
|
||||
root_index_pages = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
error:
|
||||
if (root_page_list) {
|
||||
free(root_page_list);
|
||||
root_page_list = 0;
|
||||
}
|
||||
|
||||
if (root_page_data) {
|
||||
free(root_page_data);
|
||||
root_page_data = 0;
|
||||
}
|
||||
|
||||
if (root_index_pages) {
|
||||
free(root_index_pages);
|
||||
root_index_pages = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void finish_pdb_parse(R_PDB *pdb)
|
||||
{
|
||||
R_PDB7_ROOT_STREAM *p = pdb->root_stream;
|
||||
|
||||
RListIter *it;
|
||||
SPage *page = 0;
|
||||
|
||||
it = r_list_iterator(p->streams_list);
|
||||
while (r_list_iter_next(it)) {
|
||||
page = (SPage *) r_list_iter_get(it);
|
||||
free(page->stream_pages);
|
||||
page->stream_pages = 0;
|
||||
free(page);
|
||||
page = 0;
|
||||
}
|
||||
r_list_free(p->streams_list);
|
||||
p->streams_list = 0;
|
||||
free(p);
|
||||
p = 0;
|
||||
// end of free of R_PDB7_ROOT_STREAM
|
||||
|
||||
// TODO: maybe create some kind of destructor?
|
||||
// free of pdb->pdb_streams
|
||||
// SParsedPDBStream *parsed_pdb_stream = 0;
|
||||
SPDBInfoStream *pdb_info_stream = 0;
|
||||
STpiStream *tpi_stream = 0;
|
||||
SDbiStream *dbi_stream = 0;
|
||||
SStreamParseFunc *stream_parse_func;
|
||||
R_PDB_STREAM *pdb_stream = 0;
|
||||
int i = 0;
|
||||
it = r_list_iterator(pdb->pdb_streams);
|
||||
while (r_list_iter_next(it)) {
|
||||
switch (i) {
|
||||
case 1:
|
||||
pdb_info_stream = (SPDBInfoStream *) r_list_iter_get(it);
|
||||
pdb_info_stream->free_(pdb_info_stream);
|
||||
free(pdb_info_stream);
|
||||
break;
|
||||
case 2:
|
||||
tpi_stream = (STpiStream *) r_list_iter_get(it);
|
||||
tpi_stream->free_(tpi_stream);
|
||||
free(tpi_stream);
|
||||
break;
|
||||
case 3:
|
||||
dbi_stream = (SDbiStream *) r_list_iter_get(it);
|
||||
dbi_stream->free_(dbi_stream);
|
||||
free(dbi_stream);
|
||||
break;
|
||||
default:
|
||||
find_indx_in_list(pdb->pdb_streams2, i, &stream_parse_func);
|
||||
if (stream_parse_func) {
|
||||
break;
|
||||
}
|
||||
|
||||
pdb_stream = (R_PDB_STREAM *) r_list_iter_get(it);
|
||||
pdb_stream->free_(pdb_stream);
|
||||
free(pdb_stream);
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
r_list_free(pdb->pdb_streams);
|
||||
// enf of free of pdb->pdb_streams
|
||||
|
||||
// start of free pdb->pdb_streams2
|
||||
it = r_list_iterator(pdb->pdb_streams2);
|
||||
while (r_list_iter_next(it)) {
|
||||
stream_parse_func = (SStreamParseFunc *) r_list_iter_get(it);
|
||||
if (stream_parse_func->free) {
|
||||
stream_parse_func->free(stream_parse_func->stream);
|
||||
free(stream_parse_func->stream);
|
||||
}
|
||||
free(stream_parse_func);
|
||||
}
|
||||
r_list_free(pdb->pdb_streams2);
|
||||
// end of free pdb->streams2
|
||||
|
||||
if (pdb->stream_map)
|
||||
free(pdb->stream_map);
|
||||
|
||||
fclose(pdb->fp);
|
||||
printf("finish_pdb_parse()\n");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void print_types(R_PDB *pdb)
|
||||
{
|
||||
printf("print_types()\n");
|
||||
char *name;
|
||||
int val = 0;
|
||||
int offset = 0;
|
||||
SType *t = 0;
|
||||
STypeInfo *tf = 0;
|
||||
RListIter *it = 0, *it2 = 0;
|
||||
RList *plist = pdb->pdb_streams, *ptmp;
|
||||
STpiStream *tpi_stream = r_list_get_n(plist, ePDB_STREAM_TPI);
|
||||
|
||||
it = r_list_iterator(tpi_stream->types);
|
||||
while (r_list_iter_next(it)) {
|
||||
t = (SType *) r_list_iter_get(it);
|
||||
tf = &t->type_data;
|
||||
if ((tf->leaf_type == eLF_STRUCTURE) || (tf->leaf_type == eLF_UNION)) {
|
||||
tf->is_fwdref(tf, &val);
|
||||
if (val == 1) {
|
||||
continue;
|
||||
}
|
||||
tf->get_name(tf, &name);
|
||||
// val for STRUCT or UNION mean size
|
||||
tf->get_val(tf, &val);
|
||||
printf("%s: size 0x%x\n", name, val);
|
||||
|
||||
tf->get_members(tf, &ptmp);
|
||||
it2 = r_list_iterator(ptmp);
|
||||
while (r_list_iter_next(it2)) {
|
||||
tf = (STypeInfo *) r_list_iter_get(it2);
|
||||
tf->get_name(tf, &name);
|
||||
if (tf->get_val)
|
||||
tf->get_val(tf, &offset);
|
||||
else
|
||||
offset = 0;
|
||||
printf("\t0x%x: %s type:", offset, name);
|
||||
tf->get_print_type(tf, &name);
|
||||
printf("%s\n", name);
|
||||
free(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void print_gvars(R_PDB *pdb, int img_base)
|
||||
{
|
||||
RList *l = 0;
|
||||
RListIter *it = 0, *it1 = 0;
|
||||
SStreamParseFunc *omap = 0, *sctns = 0, *sctns_orig = 0 ,
|
||||
*gsym = 0, *tmp = 0;
|
||||
SGDATAStream *gsym_data_stream = 0;
|
||||
SGlobal *gdata = 0;
|
||||
SPEStream *pe_stream = 0;
|
||||
SIMAGE_SECTION_HEADER *sctn_header = 0;
|
||||
|
||||
l = pdb->pdb_streams2;
|
||||
it = r_list_iterator(l);
|
||||
while (r_list_iter_next(it)) {
|
||||
tmp = (SStreamParseFunc *) r_list_iter_get(it);
|
||||
switch (tmp->type) {
|
||||
case ePDB_STREAM_SECT__HDR_ORIG:
|
||||
sctns_orig = tmp;
|
||||
break;
|
||||
case ePDB_STREAM_SECT_HDR:
|
||||
sctns = tmp;
|
||||
break;
|
||||
case ePDB_STREAM_OMAP_FROM_SRC:
|
||||
omap = tmp;
|
||||
break;
|
||||
case ePDB_STREAM_GSYM:
|
||||
gsym = tmp;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gsym_data_stream = (SGDATAStream *) gsym->stream;
|
||||
if ((omap != 0) && (sctns_orig != 0)) {
|
||||
pe_stream = (SPEStream *) sctns_orig->stream;
|
||||
} else {
|
||||
pe_stream = (SPEStream *) sctns->stream;
|
||||
}
|
||||
|
||||
it = r_list_iterator(gsym_data_stream->globals_list);
|
||||
while (r_list_iter_next(it)) {
|
||||
gdata = (SGlobal *) r_list_iter_get(it);
|
||||
sctn_header = r_list_get_n(pe_stream->sections_hdrs, (gdata->segment -1));
|
||||
if (sctn_header) {
|
||||
printf("%s, 0x%x, %d, %s\n",
|
||||
gdata->name.name, img_base + omap_remap((omap) ? (omap->stream) : 0,
|
||||
gdata->offset + sctn_header->virtual_address),
|
||||
gdata->symtype, sctn_header->name);
|
||||
} else {
|
||||
printf("Skipping %s, segment %d does not exist\n",
|
||||
gdata->name.name, (gdata->segment -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int init_pdb_parser(R_PDB *pdb)
|
||||
{
|
||||
char *signature = 0;
|
||||
int bytes_read = 0;
|
||||
|
||||
if (!pdb) {
|
||||
printf("struct R_PDB is not correct\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
pdb->fp = fopen(pdb->file_name, "rb");
|
||||
if (!pdb->fp) {
|
||||
printf("file %s can not be open\n", pdb->file_name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
signature = (char *)malloc(sizeof(char) * PDB7_SIGNATURE_LEN);
|
||||
if (!signature) {
|
||||
printf("memory allocation error\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
bytes_read = fread(signature, 1, PDB7_SIGNATURE_LEN, pdb->fp);
|
||||
if (bytes_read != PDB7_SIGNATURE_LEN) {
|
||||
printf("file reading error\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
fseek(pdb->fp, 0, SEEK_SET);
|
||||
|
||||
if (memcmp(signature, PDB7_SIGNATURE, PDB7_SIGNATURE_LEN)) {
|
||||
pdb->pdb_parse =pdb7_parse;
|
||||
} else {
|
||||
printf("unsupported pdb format\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (signature) {
|
||||
free(signature);
|
||||
signature = 0;
|
||||
}
|
||||
|
||||
pdb->pdb_streams = r_list_new();
|
||||
pdb->stream_map = 0;
|
||||
pdb->finish_pdb_parse = finish_pdb_parse;
|
||||
pdb->print_types = print_types;
|
||||
pdb->print_gvars = print_gvars;
|
||||
printf("init_pdb_parser() finish with success\n");
|
||||
return 1;
|
||||
|
||||
error:
|
||||
if (signature) {
|
||||
free(signature);
|
||||
signature = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
46
libr/bin/pdb/pe.c
Normal file
46
libr/bin/pdb/pe.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include "pe.h"
|
||||
|
||||
#include "stream_file.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void parse_pe_stream(void *stream, R_STREAM_FILE *stream_file)
|
||||
{
|
||||
int data_size = 0;
|
||||
char *data = 0, *ptmp = 0;
|
||||
int read_bytes = 0;
|
||||
SIMAGE_SECTION_HEADER *sctn_header = 0;
|
||||
SPEStream *pe_stream = (SPEStream *) stream;
|
||||
int sctn_header_size =0;
|
||||
|
||||
stream_file_get_size(stream_file, &data_size);
|
||||
data = (char *) malloc(data_size);
|
||||
stream_file_get_data(stream_file, data);
|
||||
|
||||
sctn_header_size = sizeof(SIMAGE_SECTION_HEADER);
|
||||
ptmp = data;
|
||||
pe_stream->sections_hdrs = r_list_new();
|
||||
while (read_bytes < data_size) {
|
||||
sctn_header = (SIMAGE_SECTION_HEADER *) malloc (sctn_header_size);
|
||||
memcpy(sctn_header, ptmp, sctn_header_size);
|
||||
ptmp += sctn_header_size;
|
||||
r_list_append(pe_stream->sections_hdrs, sctn_header);
|
||||
read_bytes += sctn_header_size;
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void free_pe_stream(void *stream)
|
||||
{
|
||||
SPEStream *pe_stream = (SPEStream *) stream;
|
||||
SIMAGE_SECTION_HEADER *sctn_header = 0;
|
||||
RListIter *it = 0;
|
||||
|
||||
it = r_list_iterator(pe_stream->sections_hdrs);
|
||||
while (r_list_iter_next(it)) {
|
||||
sctn_header = (SIMAGE_SECTION_HEADER *) r_list_iter_get(it);
|
||||
free(sctn_header);
|
||||
}
|
||||
r_list_free(pe_stream->sections_hdrs);
|
||||
}
|
9
libr/bin/pdb/pe.h
Normal file
9
libr/bin/pdb/pe.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef PE_H
|
||||
#define PE_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void parse_pe_stream(void *stream, R_STREAM_FILE *stream_file);
|
||||
void free_pe_stream(void *stream);
|
||||
|
||||
#endif // PE_H
|
120
libr/bin/pdb/stream_file.c
Normal file
120
libr/bin/pdb/stream_file.c
Normal file
@ -0,0 +1,120 @@
|
||||
#include "stream_file.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// size = -1 (default value)
|
||||
/// pages_size = 0x1000 (default value)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int init_r_stream_file(R_STREAM_FILE *stream_file, FILE *fp, int *pages,
|
||||
int pages_amount, int size, int page_size)
|
||||
{
|
||||
stream_file->fp = fp;
|
||||
stream_file->pages = pages;
|
||||
stream_file->pages_amount = pages_amount;
|
||||
stream_file->page_size = page_size;
|
||||
|
||||
if (size == -1) {
|
||||
stream_file->end = pages_amount * page_size;
|
||||
} else {
|
||||
stream_file->end = size;
|
||||
}
|
||||
|
||||
stream_file->pos = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void stream_file_read_pages(R_STREAM_FILE *stream_file, int start_indx,
|
||||
int end_indx, char *res)
|
||||
{
|
||||
int i;
|
||||
int page_offset;
|
||||
int curr_pos;
|
||||
int tmp;
|
||||
// char buffer[1024];
|
||||
|
||||
for (i = start_indx; i < end_indx; i++) {
|
||||
tmp = stream_file->pages[i];
|
||||
page_offset = stream_file->pages[i] * stream_file->page_size;
|
||||
fseek(stream_file->fp, page_offset, SEEK_SET);
|
||||
// curr_pos = ftell(stream_file->fp);
|
||||
fread(res, stream_file->page_size, 1, stream_file->fp);
|
||||
res += stream_file->page_size;
|
||||
}
|
||||
}
|
||||
|
||||
// size by default = -1
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void stream_file_read(R_STREAM_FILE *stream_file, int size, char *res)
|
||||
{
|
||||
int pn_start, off_start, pn_end, off_end;
|
||||
int i = 0;
|
||||
char *pdata = 0;
|
||||
char *tmp;
|
||||
int len = 0;
|
||||
|
||||
if (size == -1) {
|
||||
pdata = (char *) malloc(stream_file->pages_amount * stream_file->page_size);
|
||||
GET_PAGE(pn_start, off_start, stream_file->pos, stream_file->page_size);
|
||||
tmp = pdata;
|
||||
stream_file_read_pages(stream_file, 0, stream_file->pages_amount, tmp);
|
||||
stream_file->pos = stream_file->end;
|
||||
memcpy(res, pdata + off_start, stream_file->end - off_start);
|
||||
free(pdata);
|
||||
} else {
|
||||
GET_PAGE(pn_start, off_start, stream_file->pos, stream_file->page_size);
|
||||
GET_PAGE(pn_end, off_end, stream_file->pos + size, stream_file->page_size);
|
||||
|
||||
pdata = (char *) malloc(stream_file->page_size * (pn_end + 1 - pn_start));
|
||||
tmp = pdata;
|
||||
stream_file_read_pages(stream_file, pn_start, pn_end + 1, tmp);
|
||||
stream_file->pos += size;
|
||||
memcpy(res, pdata + off_start, size);
|
||||
free(pdata);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void stream_file_seek(R_STREAM_FILE *stream_file, int offset, int whence)
|
||||
{
|
||||
switch (whence) {
|
||||
case 0:
|
||||
stream_file->pos = offset;
|
||||
break;
|
||||
case 1:
|
||||
stream_file->pos += offset;
|
||||
break;
|
||||
case 2:
|
||||
stream_file->pos = stream_file->end + offset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (stream_file->pos < 0) stream_file->pos = 0;
|
||||
if (stream_file->pos > stream_file->end) stream_file->pos = stream_file->end;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int stream_file_tell(R_STREAM_FILE *stream_file)
|
||||
{
|
||||
return stream_file->pos;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void stream_file_get_data(R_STREAM_FILE *stream_file, char *data)
|
||||
{
|
||||
int pos = 0;
|
||||
pos = stream_file_tell(stream_file);
|
||||
stream_file_seek(stream_file, 0, 0);
|
||||
stream_file_read(stream_file, -1, data);
|
||||
stream_file_seek(stream_file, pos, 0);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void stream_file_get_size(R_STREAM_FILE *stream_file, int *data_size)
|
||||
{
|
||||
int pn_start = 0, off_start = 0;
|
||||
GET_PAGE(pn_start, off_start, stream_file->pos, stream_file->page_size);
|
||||
*data_size = stream_file->end - off_start;
|
||||
}
|
30
libr/bin/pdb/stream_file.h
Normal file
30
libr/bin/pdb/stream_file.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef STREAM_FILE_H
|
||||
#define STREAM_FILE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "types.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// size = -1 (default value)
|
||||
/// pages_size = 0x1000 (default value)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int init_r_stream_file(R_STREAM_FILE *stream_file, FILE *fp, int *pages,
|
||||
int pages_amount, int size, int page_size);
|
||||
|
||||
// size by default = -1
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void stream_file_read(R_STREAM_FILE *stream_file, int size, char *res);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void stream_file_seek(R_STREAM_FILE *stream_file, int offset, int whence);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int stream_file_tell(R_STREAM_FILE *stream_file);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void stream_file_get_data(R_STREAM_FILE *stream_file, char *data);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void stream_file_get_size(R_STREAM_FILE *stream_file, int *data_size);
|
||||
|
||||
#endif // STREAM_FILE_H
|
2189
libr/bin/pdb/tpi.c
Normal file
2189
libr/bin/pdb/tpi.c
Normal file
File diff suppressed because it is too large
Load Diff
17
libr/bin/pdb/tpi.h
Normal file
17
libr/bin/pdb/tpi.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef TPI_H
|
||||
#define TPI_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void init_tpi_stream(STpiStream *tpi_stream);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void parse_tpi_stream(void *parsed_pdb_stream, R_STREAM_FILE *stream);
|
||||
|
||||
// TODO: Remove to separate file
|
||||
void parse_sctring(SCString *sctr, unsigned char *leaf_data, unsigned int *read_bytes, unsigned int len);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void init_scstring(SCString *cstr, unsigned int size, char *name);
|
||||
#endif // TPI_H
|
1201
libr/bin/pdb/types.h
Normal file
1201
libr/bin/pdb/types.h
Normal file
File diff suppressed because it is too large
Load Diff
37
libr/include/r_pdb.h
Normal file
37
libr/include/r_pdb.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef R2_PDB_H
|
||||
#define R2_PDB_H
|
||||
|
||||
#define _R_LIST_C
|
||||
#include "r_util.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define FILE_NAME_LEN 256
|
||||
|
||||
struct R_PDB7_ROOT_STREAM;
|
||||
|
||||
typedef struct {
|
||||
int (*pdb_parse)(struct R_PDB *pdb);
|
||||
void (*finish_pdb_parse)(struct R_PDB *pdb);
|
||||
void (*print_types)(struct R_PDB *pdb);
|
||||
|
||||
char file_name[FILE_NAME_LEN];
|
||||
FILE *fp;
|
||||
struct R_PDB7_ROOT_STREAM *root_stream;
|
||||
void *stream_map;
|
||||
RList *pdb_streams;
|
||||
RList *pdb_streams2;
|
||||
|
||||
void (*print_gvars)(struct R_PDB *pdb, int img_base);
|
||||
} R_PDB;
|
||||
|
||||
int init_pdb_parser(R_PDB *pdb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user