00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "pefstruc.h"
00022 #include "log.h"
00023 #include "htpef.h"
00024 #include "htpefhd.h"
00025 #include "htpefimp.h"
00026 #include "htpefimg.h"
00027 #include "htendian.h"
00028 #include "stream.h"
00029 #include "tools.h"
00030
00031 #include <stdlib.h>
00032
00033 format_viewer_if *htpef_ifs[] = {
00034 &htpefheader_if,
00035 &htpefimports_if,
00036 &htpefimage_if,
00037 0
00038 };
00039
00040 static ht_view *htpef_init(bounds *b, ht_streamfile *file, ht_format_group *format_group)
00041 {
00042 byte id[12];
00043 file->seek(0);
00044 file->read(&id, sizeof id);
00045 if (memcmp(id, "Joy!peff", 8)) return NULL;
00046 PEF_ARCH arch;
00047 if (memcmp(id+8, "pwpc", 4) == 0) {
00048 arch = PEFARCH_PowerPC;
00049 } else if (memcmp(id+8, "m68k", 4) == 0) {
00050 arch = PEFARCH_M68K;
00051 } else return NULL;
00052
00053 ht_pef *g = new ht_pef();
00054 g->init(b, file, htpef_ifs, format_group, 0);
00055 return g;
00056 }
00057
00058 format_viewer_if htpef_if = {
00059 htpef_init,
00060 0
00061 };
00062
00063
00064
00065
00066 void ht_pef::init(bounds *b, ht_streamfile *f, format_viewer_if **ifs, ht_format_group *format_group, FILEOFS header_ofs)
00067 {
00068 ht_format_group::init(b, VO_SELECTABLE | VO_BROWSABLE | VO_RESIZE, DESC_PEF, f, false, true, 0, format_group);
00069 VIEW_DEBUG_NAME("ht_pef");
00070
00071 LOG("%s: PEF: found header at %08x", file->get_filename(), header_ofs);
00072
00073 ht_pef_shared_data *pef_shared=(ht_pef_shared_data *)malloc(sizeof(ht_pef_shared_data));
00074 memset(pef_shared, 0, sizeof *pef_shared);
00075
00076 shared_data = pef_shared;
00077
00078 pef_shared->byte_order = big_endian;
00079 pef_shared->header_ofs = 0;
00080
00081 pef_shared->imports.funcs = new ht_clist();
00082 pef_shared->imports.funcs->init();
00083
00084 pef_shared->imports.libs = new ht_clist();
00085 pef_shared->imports.libs->init();
00086
00087 pef_shared->v_imports = NULL;
00088
00089
00090 file->seek(header_ofs);
00091 file->read(&pef_shared->contHeader, sizeof pef_shared->contHeader);
00092 create_host_struct(&pef_shared->contHeader, PEF_CONTAINER_HEADER_struct, pef_shared->byte_order);
00093
00094 if (memcmp(pef_shared->contHeader.architecture, "pwpc", 4) == 0) {
00095 pef_shared->arch = PEFARCH_PowerPC;
00096 } else if (memcmp(pef_shared->contHeader.architecture, "m68k", 4) == 0) {
00097 pef_shared->arch = PEFARCH_M68K;
00098 } else return;
00099
00100
00101 pef_shared->sheaders.count = pef_shared->contHeader.sectionCount;
00102 pef_shared->sheaders.sheaders = (PEF_SECTION_HEADER*)
00103 malloc(pef_shared->sheaders.count*sizeof (PEF_SECTION_HEADER));
00104 for (uint i=0; i<pef_shared->sheaders.count; i++) {
00105 file->read(&pef_shared->sheaders.sheaders[i], sizeof pef_shared->sheaders.sheaders[i]);
00106 create_host_struct(&pef_shared->sheaders.sheaders[i], PEF_SECTION_HEADER_struct, pef_shared->byte_order);
00107
00108 pef_shared->sheaders.sheaders[i].defaultAddress = i*0x100000;
00109 if (!pef_shared->loader_info_header_ofs
00110 && pef_shared->sheaders.sheaders[i].sectionKind == PEF_SK_Loader) {
00111 pef_shared->loader_info_header_ofs = pef_shared->sheaders.sheaders[i].containerOffset;
00112 }
00113 }
00114
00115 if (pef_shared->loader_info_header_ofs) {
00116 file->seek(pef_shared->loader_info_header_ofs);
00117 file->read(&pef_shared->loader_info_header, sizeof pef_shared->loader_info_header);
00118 create_host_struct(&pef_shared->loader_info_header, PEF_LOADER_INFO_HEADER_struct, pef_shared->byte_order);
00119 }
00120
00121
00122 ht_format_group::init_ifs(ifs);
00123 }
00124
00125 void ht_pef::done()
00126 {
00127 ht_format_group::done();
00128
00129 ht_pef_shared_data *pef_shared = (ht_pef_shared_data*)shared_data;
00130 if (pef_shared->imports.funcs) {
00131 pef_shared->imports.funcs->destroy();
00132 delete pef_shared->imports.funcs;
00133 }
00134 if (pef_shared->imports.libs) {
00135 pef_shared->imports.libs->destroy();
00136 delete pef_shared->imports.libs;
00137 }
00138 free(shared_data);
00139 }
00140
00141 #define RELOC_BASE 0x10000000
00142 #define RELOC_STEPPING 0x100000
00143 #define RELOC_LIMIT 0xffffffff
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 bool pef_phys_and_mem_section(PEF_SECTION_HEADER *s)
00168 {
00169 return (s->sectionKind <= 1) || (s->sectionKind == 3) || (s->sectionKind == 6);
00170 }
00171
00172 bool pef_valid_section(PEF_SECTION_HEADER *s)
00173 {
00174 return (s->sectionKind <= 3) || (s->sectionKind == 6);
00175 }
00176
00177 bool pef_addr_to_ofs(pef_section_headers *section_headers, PEFAddress addr, dword *ofs)
00178 {
00179 PEF_SECTION_HEADER *s = section_headers->sheaders;
00180 for (UINT i=0; i < section_headers->count; i++) {
00181 if ((pef_phys_and_mem_section(s)) &&
00182 (addr.a32 >= s->defaultAddress) && (addr.a32 < s->defaultAddress+s->packedSize)) {
00183 *ofs = addr.a32 - s->defaultAddress + s->containerOffset;
00184 return true;
00185 }
00186 s++;
00187 }
00188 return false;
00189 }
00190
00191 bool pef_addr_to_section(pef_section_headers *section_headers, PEFAddress addr, int *section)
00192 {
00193 PEF_SECTION_HEADER *s = section_headers->sheaders;
00194 for (UINT i = 0; i < section_headers->count; i++) {
00195 if ((pef_valid_section(s)) &&
00196 (addr.a32 >= s->defaultAddress) && (addr.a32 < s->defaultAddress + s->totalSize)) {
00197 *section = i;
00198 return true;
00199 }
00200 s++;
00201 }
00202 return false;
00203 }
00204
00205 bool pef_addr_is_valid(pef_section_headers *section_headers, PEFAddress addr)
00206 {
00207 PEF_SECTION_HEADER *s = section_headers->sheaders;
00208 for (UINT i=0; i<section_headers->count; i++) {
00209 if ((pef_valid_section(s)) &&
00210 (addr.a32 >= s->defaultAddress) && (addr.a32 < s->defaultAddress + s->totalSize)) {
00211 return true;
00212 }
00213 s++;
00214 }
00215 return false;
00216 }
00217
00218
00219
00220
00221
00222 bool pef_ofs_to_addr(pef_section_headers *section_headers, dword ofs, PEFAddress *addr)
00223 {
00224 PEF_SECTION_HEADER *s = section_headers->sheaders;
00225 for (UINT i = 0; i < section_headers->count; i++) {
00226 if ((pef_phys_and_mem_section(s)) &&
00227 (ofs>=s->containerOffset) && (ofs<s->containerOffset+s->packedSize)) {
00228 addr->a32 = ofs - s->containerOffset + s->defaultAddress;
00229 return true;
00230 }
00231 s++;
00232 }
00233 return false;
00234 }
00235
00236 bool pef_ofs_to_section(pef_section_headers *section_headers, dword ofs, int *section)
00237 {
00238 PEF_SECTION_HEADER *s=section_headers->sheaders;
00239 for (UINT i=0; i<section_headers->count; i++) {
00240 if ((pef_valid_section(s)) &&
00241 (ofs >= s->containerOffset) && (ofs<s->containerOffset+s->packedSize)) {
00242 *section = i;
00243 return true;
00244 }
00245 s++;
00246 }
00247 return false;
00248 }
00249
00250
00251
00252
00253 #include "relfile.h"
00254 class ht_pef_reloc_entry: public Object {
00255 public:
00256
00257
00258 };
00259
00260
00261
00262
00263
00264 class ht_pef_reloc_file: public ht_reloc_file {
00265 protected:
00266 ht_pef_shared_data *data;
00267
00268 virtual void reloc_apply(Object *reloc, byte *data);
00269 virtual bool reloc_unapply(Object *reloc, byte *data);
00270 public:
00271
00272 void init(ht_streamfile *s, bool own_s, ht_pef_shared_data *d)
00273 {
00274 ht_reloc_file::init(s, own_s);
00275 data = d;
00276 }
00277
00278 };