00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "log.h"
00022 #include "htendian.h"
00023 #include "htnewexe.h"
00024 #include "htpe.h"
00025 #include "htpehead.h"
00026 #include "htpeexp.h"
00027 #include "htpeil.h"
00028 #include "htpeimp.h"
00029 #include "htpedimp.h"
00030 #include "htpeimg.h"
00031 #include "htperes.h"
00032 #include "stream.h"
00033 #include "tools.h"
00034
00035 #include <stdlib.h>
00036 #include <string.h>
00037
00038 static format_viewer_if *htpe_ifs[] = {
00039 &htpeheader_if,
00040 &htpeexports_if,
00041 &htpeimports_if,
00042 &htpedelayimports_if,
00043 &htperesources_if,
00044 &htpeil_if,
00045 &htpeimage_if,
00046 0
00047 };
00048
00049 static ht_view *htpe_init(bounds *b, ht_streamfile *file, ht_format_group *format_group)
00050 {
00051 byte pemagic[4];
00052 FILEOFS h = get_newexe_header_ofs(file);
00053 file->seek(h);
00054 file->read(pemagic, 4);
00055 if ((pemagic[0]!=PE_MAGIC0) || (pemagic[1]!=PE_MAGIC1) ||
00056 (pemagic[2]!=PE_MAGIC2) || (pemagic[3]!=PE_MAGIC3)) return 0;
00057
00058 ht_pe *g = new ht_pe();
00059 g->init(b, file, htpe_ifs, format_group, h);
00060 return g;
00061 }
00062
00063 format_viewer_if htpe_if = {
00064 htpe_init,
00065 0
00066 };
00067
00068
00069
00070
00071 void ht_pe::init(bounds *b, ht_streamfile *file, format_viewer_if **ifs, ht_format_group *format_group, FILEOFS header_ofs)
00072 {
00073 ht_format_group::init(b, VO_BROWSABLE | VO_SELECTABLE | VO_RESIZE, DESC_PE, file, false, true, 0, format_group);
00074 VIEW_DEBUG_NAME("ht_pe");
00075
00076 LOG("%s: PE: found header at %08x", file->get_filename(), header_ofs);
00077
00078 ht_pe_shared_data *pe_shared = (ht_pe_shared_data*)malloc(sizeof (ht_pe_shared_data));
00079 shared_data = pe_shared;
00080 pe_shared->header_ofs = header_ofs;
00081
00082 pe_shared->exports.funcs = new ht_clist();
00083 pe_shared->exports.funcs->init();
00084
00085 pe_shared->dimports.funcs = new ht_clist();
00086 pe_shared->dimports.funcs->init();
00087
00088 pe_shared->dimports.libs = new ht_clist();
00089 pe_shared->dimports.libs->init();
00090
00091 pe_shared->imports.funcs = new ht_clist();
00092 pe_shared->imports.funcs->init();
00093
00094 pe_shared->imports.libs = new ht_clist();
00095 pe_shared->imports.libs->init();
00096
00097 pe_shared->il = NULL;
00098 pe_shared->v_image = NULL;
00099 pe_shared->v_dimports = NULL;
00100 pe_shared->v_imports = NULL;
00101 pe_shared->v_exports = NULL;
00102 pe_shared->v_resources = NULL;
00103 pe_shared->v_header = NULL;
00104
00105
00106 file->seek(header_ofs+4);
00107 file->read(&pe_shared->coffheader, sizeof pe_shared->coffheader);
00108 create_host_struct(&pe_shared->coffheader, COFF_HEADER_struct, little_endian);
00109 file->read(&pe_shared->opt_magic, sizeof pe_shared->opt_magic);
00110 pe_shared->opt_magic = create_host_int(&pe_shared->opt_magic, sizeof pe_shared->opt_magic, little_endian);
00111 file->seek(header_ofs+4+sizeof pe_shared->coffheader);
00112 switch (pe_shared->opt_magic) {
00113 case COFF_OPTMAGIC_PE32: {
00114 file->read(&pe_shared->pe32.header, sizeof pe_shared->pe32.header);
00115 create_host_struct(&pe_shared->pe32.header, COFF_OPTIONAL_HEADER32_struct, little_endian);
00116 file->read(&pe_shared->pe32.header_nt, sizeof pe_shared->pe32.header_nt);
00117 create_host_struct(&pe_shared->pe32.header_nt, PE_OPTIONAL_HEADER32_NT_struct, little_endian);
00118 for (UINT i=0; i<PE_NUMBEROF_DIRECTORY_ENTRIES; i++) {
00119 create_host_struct(&pe_shared->pe32.header_nt.directory[i], PE_DATA_DIRECTORY_struct, little_endian);
00120 }
00121 break;
00122 }
00123 case COFF_OPTMAGIC_PE64: {
00124 file->read(&pe_shared->pe64.header, sizeof pe_shared->pe64.header);
00125 create_host_struct(&pe_shared->pe64.header, COFF_OPTIONAL_HEADER64_struct, little_endian);
00126 file->read(&pe_shared->pe64.header_nt, sizeof pe_shared->pe64.header_nt);
00127 create_host_struct(&pe_shared->pe64.header_nt, PE_OPTIONAL_HEADER64_NT_struct, little_endian);
00128 for (UINT i=0; i<PE_NUMBEROF_DIRECTORY_ENTRIES; i++) {
00129 create_host_struct(&pe_shared->pe64.header_nt.directory[i], PE_DATA_DIRECTORY_struct, little_endian);
00130 }
00131 break;
00132 }
00133 }
00134
00135
00136 int os=pe_shared->coffheader.optional_header_size;
00137 pe_shared->sections.section_count=pe_shared->coffheader.section_count;
00138
00139 file->seek(header_ofs+os+sizeof(COFF_HEADER)+4);
00140 pe_shared->sections.sections=(COFF_SECTION_HEADER*)malloc(pe_shared->sections.section_count * sizeof *pe_shared->sections.sections);
00141 file->read(pe_shared->sections.sections, pe_shared->sections.section_count*sizeof *pe_shared->sections.sections);
00142
00143 for (UINT i=0; i<pe_shared->sections.section_count; i++) {
00144 create_host_struct(&pe_shared->sections.sections[i], COFF_SECTION_HEADER_struct, little_endian);
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 }
00159
00160 shared_data = pe_shared;
00161
00162 ht_format_group::init_ifs(ifs);
00163 }
00164
00165 void ht_pe::done()
00166 {
00167 ht_format_group::done();
00168
00169 ht_pe_shared_data *pe_shared = (ht_pe_shared_data*)shared_data;
00170
00171 if (pe_shared->exports.funcs) {
00172 pe_shared->exports.funcs->destroy();
00173 delete pe_shared->exports.funcs;
00174 }
00175 if (pe_shared->dimports.funcs) {
00176 pe_shared->dimports.funcs->destroy();
00177 delete pe_shared->dimports.funcs;
00178 }
00179 if (pe_shared->dimports.libs) {
00180 pe_shared->dimports.libs->destroy();
00181 delete pe_shared->dimports.libs;
00182 }
00183 if (pe_shared->imports.funcs) {
00184 pe_shared->imports.funcs->destroy();
00185 delete pe_shared->imports.funcs;
00186 }
00187 if (pe_shared->imports.libs) {
00188 pe_shared->imports.libs->destroy();
00189 delete pe_shared->imports.libs;
00190 }
00191 free(pe_shared->sections.sections);
00192
00193 free(shared_data);
00194 }
00195
00196 void ht_pe::loc_enum_start()
00197 {
00198
00199
00200
00201
00202
00203
00204
00205
00206 }
00207
00208 bool ht_pe::loc_enum_next(ht_format_loc *loc)
00209 {
00210 #if 0
00211 ht_pe_shared_data *sh=(ht_pe_shared_data*)shared_data;
00212 if (loc_enum) {
00213 loc->name="pe";
00214 loc->start=sh->header_ofs;
00215
00216 UINT l=sizeof (COFF_HEADER) + sh->coffheader.optional_header_size;
00217
00218 for (UINT i=0; i<16; i++) {
00219 FILEOFS o;
00220 if (pe_rva_to_ofs(&sh->sections, sh->pe32.header_nt.directory[i].address, &o)) {
00221 UINT k=o+sh->pe32.header_nt.directory[i].size-sh->header_ofs;
00222 l=MAX(k, l);
00223 }
00224 }
00225
00226 for (UINT i=0; i<sh->sections.section_count; i++) {
00227 UINT k=sh->sections.sections[i].data_offset+sh->sections.sections[i].data_size-sh->header_ofs;
00228 l=MAX(k, l);
00229 }
00230 loc->length=l;
00231
00232 loc_enum=0;
00233 return true;
00234 }
00235 return false;
00236 #endif
00237 return false;
00238 }
00239
00240
00241
00242
00243
00244 bool pe_rva_to_ofs(pe_section_headers *section_headers, RVA rva, FILEOFS *ofs)
00245 {
00246 COFF_SECTION_HEADER *s=section_headers->sections;
00247 for (UINT i=0; i<section_headers->section_count; i++) {
00248 if ((rva>=s->data_address) &&
00249 (rva<s->data_address+s->data_size)) {
00250 *ofs=rva-s->data_address+s->data_offset;
00251 return true;
00252 }
00253 s++;
00254 }
00255 return false;
00256 }
00257
00258 bool pe_rva_to_section(pe_section_headers *section_headers, RVA rva, int *section)
00259 {
00260 COFF_SECTION_HEADER *s=section_headers->sections;
00261 for (UINT i=0; i<section_headers->section_count; i++) {
00262 if ((rva>=s->data_address) &&
00263 (rva<s->data_address+MAX(s->data_size, s->data_vsize))) {
00264 *section=i;
00265 return true;
00266 }
00267 s++;
00268 }
00269 return false;
00270 }
00271
00272 bool pe_rva_is_valid(pe_section_headers *section_headers, RVA rva)
00273 {
00274 COFF_SECTION_HEADER *s=section_headers->sections;
00275 for (UINT i=0; i<section_headers->section_count; i++) {
00276 if ((rva>=s->data_address) &&
00277 (rva<s->data_address+MAX(s->data_size, s->data_vsize))) {
00278 return true;
00279 }
00280 s++;
00281 }
00282 return false;
00283 }
00284
00285 bool pe_rva_is_physical(pe_section_headers *section_headers, RVA rva)
00286 {
00287 COFF_SECTION_HEADER *s=section_headers->sections;
00288 for (UINT i=0; i<section_headers->section_count; i++) {
00289 if ((rva>=s->data_address) &&
00290 (rva<s->data_address+s->data_size)) {
00291 return true;
00292 }
00293 s++;
00294 }
00295 return false;
00296 }
00297
00298
00299
00300
00301
00302 bool pe_ofs_to_rva(pe_section_headers *section_headers, FILEOFS ofs, RVA *rva)
00303 {
00304 COFF_SECTION_HEADER *s=section_headers->sections;
00305 for (UINT i=0; i<section_headers->section_count; i++) {
00306 if ((ofs>=s->data_offset) &&
00307 (ofs<s->data_offset+s->data_size)) {
00308 *rva=ofs-s->data_offset+s->data_address;
00309 return true;
00310 }
00311 s++;
00312 }
00313 return false;
00314 }
00315
00316 bool pe_ofs_to_section(pe_section_headers *section_headers, FILEOFS ofs, int *section)
00317 {
00318 COFF_SECTION_HEADER *s=section_headers->sections;
00319 for (UINT i=0; i<section_headers->section_count; i++) {
00320 if ((ofs>=s->data_offset) &&
00321 (ofs<s->data_offset+s->data_size)) {
00322 *section=i;
00323 return true;
00324 }
00325 s++;
00326 }
00327 return false;
00328 }
00329
00330 bool pe_ofs_to_rva_and_section(pe_section_headers *section_headers, FILEOFS ofs, RVA *rva, int *section)
00331 {
00332 bool r = pe_ofs_to_rva(section_headers, ofs, rva);
00333 if (r) {
00334 r = pe_ofs_to_section(section_headers, ofs, section);
00335 }
00336 return r;
00337 }
00338
00339 bool pe_ofs_is_valid(pe_section_headers *section_headers, FILEOFS ofs)
00340 {
00341 RVA rva;
00342 return pe_ofs_to_rva(section_headers, ofs, &rva);
00343 }
00344
00345
00346
00347
00348
00349 bool pe_section_name_to_section(pe_section_headers *section_headers, const char *name, int *section)
00350 {
00351 COFF_SECTION_HEADER *s = section_headers->sections;
00352 int slen = strlen(name);
00353 slen = MIN(slen, COFF_SIZEOF_SHORT_NAME);
00354 for (UINT i=0; i < section_headers->section_count; i++) {
00355 if (strncmp(name, (char*)&s->name, slen) == 0) {
00356 *section = i;
00357 return true;
00358 }
00359 s++;
00360 }
00361 return false;
00362 }