?? pe_analy.cc
字號:
/* * HT Editor * pe_analy.cc * * Copyright (C) 1999-2002 Sebastian Biallas (sb@biallas.net) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "analy.h"#include "analy_alpha.h"#include "analy_ia64.h"#include "analy_il.h"#include "analy_names.h"#include "analy_register.h"#include "analy_ppc.h"#include "analy_x86.h"#include "analy_arm.h"#include "htctrl.h"#include "htdebug.h"#include "htiobox.h"#include "htpe.h"#include "strtools.h"#include "ilopc.h"#include "pe_analy.h"#include "pestruct.h"#include "snprintf.h"#include "x86asm.h"void PEAnalyser::init(ht_pe_shared_data *Pe_shared, File *File){ pe_shared = Pe_shared; file = File; validarea = new Area(); validarea->init(); Analyser::init();}static char *string_func(uint32 ofs, void *context);static char *token_func(uint32 token, void *context);/* * */void PEAnalyser::load(ObjectStream &f){ GET_OBJECT(f, validarea); Analyser::load(f);}/* * */void PEAnalyser::done(){ validarea->done(); delete validarea; Analyser::done();}/* * */void PEAnalyser::reinit(ht_pe_shared_data *Pe_shared, File *f){ pe_shared = Pe_shared; file = f; if (disasm->getObjectID() == ATOM_DISASM_IL) { ((ILDisassembler *)disasm)->initialize(string_func, token_func, pe_shared); }}/* * */void PEAnalyser::beginAnalysis(){ char buffer[1024]; setLocationTreeOptimizeThreshold(100); setSymbolTreeOptimizeThreshold(100); bool pe32 = (pe_shared->opt_magic == COFF_OPTMAGIC_PE32); /* * entrypoint */ Address *entry; if (pe32) { entry = createAddress32(pe_shared->pe32.header.entrypoint_address+pe_shared->pe32.header_nt.image_base); } else { entry = createAddress64(pe_shared->pe64.header.entrypoint_address+pe_shared->pe64.header_nt.image_base); } pushAddress(entry, entry); /* * give all sections a descriptive comment: */ /*struct PE_SECTION_HEADER { byte name[PE_SIZEOF_SHORT_NAME] __attribute__ ((packed)); uint32 data_vsize __attribute__ ((packed)); uint32 data_address __attribute__ ((packed)); uint32 data_size __attribute__ ((packed)); uint32 data_offset __attribute__ ((packed)); uint32 relocation_offset __attribute__ ((packed)); uint32 linenumber_offset __attribute__ ((packed)); uint16 relocation_count __attribute__ ((packed)); uint16 linenumber_count __attribute__ ((packed)); uint32 characteristics __attribute__ ((packed)); };*/ COFF_SECTION_HEADER *s=pe_shared->sections.sections; char blub[100]; for (uint i=0; i<pe_shared->sections.section_count; i++) { Address *secaddr; if (pe32) { secaddr = createAddress32(s->data_address + pe_shared->pe32.header_nt.image_base); } else { secaddr = createAddress64(s->data_address + pe_shared->pe64.header_nt.image_base); } ht_snprintf(blub, sizeof blub, "; section %d <%s>", i+1, getSegmentNameByAddress(secaddr)); addComment(secaddr, 0, ""); addComment(secaddr, 0, ";******************************************************************"); addComment(secaddr, 0, blub); ht_snprintf(blub, sizeof blub, "; virtual address %08x virtual size %08x", s->data_address, s->data_vsize); addComment(secaddr, 0, blub); ht_snprintf(blub, sizeof blub, "; file offset %08x file size %08x", s->data_offset, s->data_size); addComment(secaddr, 0, blub); addComment(secaddr, 0, ";******************************************************************"); // mark end of sections ht_snprintf(blub, sizeof blub, "; end of section <%s>", getSegmentNameByAddress(secaddr)); Address *secend_addr = secaddr->clone(); secend_addr->add(MAX(s->data_size, s->data_vsize)); newLocation(secend_addr)->flags |= AF_FUNCTION_END; addComment(secend_addr, 0, ""); addComment(secend_addr, 0, ";******************************************************************"); addComment(secend_addr, 0, blub); addComment(secend_addr, 0, ";******************************************************************"); validarea->add(secaddr, secend_addr); Address *seciniaddr = secaddr->clone(); seciniaddr->add(MIN(s->data_size, s->data_vsize)); if (validAddress(secaddr, scinitialized) && validAddress(seciniaddr, scinitialized)) { initialized->add(secaddr, seciniaddr); } s++; delete secaddr; delete secend_addr; delete seciniaddr; } // exports int export_count=pe_shared->exports.funcs->count(); int *entropy = random_permutation(export_count); for (int i=0; i<export_count; i++) { ht_pe_export_function *f=(ht_pe_export_function *)(*pe_shared->exports.funcs)[entropy[i]]; Address *faddr; if (pe32) { faddr = createAddress32(f->address + pe_shared->pe32.header_nt.image_base); } else { faddr = createAddress64(f->address + pe_shared->pe64.header_nt.image_base); } if (validAddress(faddr, scvalid)) { char *label; if (f->byname) { ht_snprintf(buffer, sizeof buffer, "; exported function %s, ordinal %04x", f->name, f->ordinal); } else { ht_snprintf(buffer, sizeof buffer, "; unnamed exported function, ordinal %04x", f->ordinal); } label = export_func_name((f->byname) ? f->name : NULL, f->ordinal); addComment(faddr, 0, ""); addComment(faddr, 0, ";********************************************************"); addComment(faddr, 0, buffer); addComment(faddr, 0, ";********************************************************"); pushAddress(faddr, faddr); assignSymbol(faddr, label, label_func); free(label); } delete faddr; } if (entropy) free(entropy); int import_count=pe_shared->imports.funcs->count(); entropy = random_permutation(import_count); for (int i=0; i<import_count; i++) { ht_pe_import_function *f = (ht_pe_import_function *)(*pe_shared->imports.funcs)[entropy[i]]; ht_pe_import_library *d = (ht_pe_import_library *)(*pe_shared->imports.libs)[f->libidx]; char *label; label = import_func_name(d->name, (f->byname) ? f->name.name : NULL, f->ordinal); Address *faddr; if (pe32) { faddr = createAddress32(f->address + pe_shared->pe32.header_nt.image_base); } else { faddr = createAddress64(f->address + pe_shared->pe64.header_nt.image_base); } addComment(faddr, 0, ""); if (!assignSymbol(faddr, label, label_func)) { // multiple import of a function (duplicate labelname) // -> mangle name a bit more addComment(faddr, 0, "; duplicate import"); ht_snprintf(buffer, sizeof buffer, "%s_%x", label, f->address); assignSymbol(faddr, buffer, label_func); } if (pe32) { data->setIntAddressType(faddr, dst_idword, 4); } else { data->setIntAddressType(faddr, dst_iqword, 8); } free(label); delete faddr; } if (entropy) free(entropy); int dimport_count=pe_shared->dimports.funcs->count(); entropy = random_permutation(dimport_count); for (int i=0; i<dimport_count; i++) { // FIXME: delay imports need work (push addr) ht_pe_import_function *f=(ht_pe_import_function *)(*pe_shared->dimports.funcs)[entropy[i]]; ht_pe_import_library *d=(ht_pe_import_library *)(*pe_shared->dimports.libs)[f->libidx]; if (f->byname) { ht_snprintf(buffer, sizeof buffer, "; delay import function loader for %s, ordinal %04x", f->name.name, f->ordinal); } else { ht_snprintf(buffer, sizeof buffer, "; delay import function loader for ordinal %04x", f->ordinal); } char *label; label = import_func_name(d->name, f->byname ? f->name.name : NULL, f->ordinal); Address *faddr; if (pe32) { faddr = createAddress32(f->address); } else { faddr = createAddress64(f->address); } addComment(faddr, 0, ""); addComment(faddr, 0, ";********************************************************"); addComment(faddr, 0, buffer); addComment(faddr, 0, ";********************************************************"); assignSymbol(faddr, label, label_func); free(label); delete faddr; } if (entropy) free(entropy); addComment(entry, 0, ""); addComment(entry, 0, ";****************************"); if (pe_shared->coffheader.characteristics & COFF_DLL) { addComment(entry, 0, "; dll entry point"); } else { addComment(entry, 0, "; program entry point"); } addComment(entry, 0, ";****************************"); assignSymbol(entry, "entrypoint", label_func); setLocationTreeOptimizeThreshold(1000); setSymbolTreeOptimizeThreshold(1000); delete entry; Analyser::beginAnalysis();}/* * */ObjectID PEAnalyser::getObjectID() const{ return ATOM_PE_ANALYSER;}/* * */uint PEAnalyser::bufPtr(Address *Addr, byte *buf, int size){ FileOfs ofs = addressToFileofs(Addr);/* if (ofs == INVALID_FILE_OFS) { int as=0; }*/ assert(ofs != INVALID_FILE_OFS); file->seek(ofs); return file->read(buf, size);}bool PEAnalyser::convertAddressToRVA(Address *addr, RVA *r){ ObjectID oid = addr->getObjectID(); if (oid == ATOM_ADDRESS_FLAT_32) { *r = ((AddressFlat32*)addr)->addr - pe_shared->pe32.header_nt.image_base; return true; } else if (oid == ATOM_ADDRESS_X86_FLAT_32) { *r = ((AddressX86Flat32*)addr)->addr - pe_shared->pe32.header_nt.image_base; return true; } else if (oid == ATOM_ADDRESS_FLAT_64) { uint64 q = ((AddressFlat64*)addr)->addr - pe_shared->pe64.header_nt.image_base; if (q >> 32) return false; *r = q; return true; } return false;}/* * */Address *PEAnalyser::createAddress32(uint32 addr){ switch (pe_shared->coffheader.machine) { case COFF_MACHINE_I386: case COFF_MACHINE_I486: case COFF_MACHINE_I586: return new AddressX86Flat32(addr); } // fallback to standard-addrs return new AddressFlat32(addr);}/* *
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -