de4dot-cex/dumpMethodsN/DotNetFile.h
2011-09-22 04:55:30 +02:00

188 lines
4.7 KiB
C++

/*
Copyright (C) 2011 de4dot@gmail.com
This file is part of de4dot.
de4dot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
de4dot 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 de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DOTNETFILE_H
#define DOTNETFILE_H
#include <Windows.h>
#include <WinNT.h>
#include <CorHdr.h>
#include <stdio.h>
#include "strex.h"
enum MetaDataIndex {
iModule = 0,
iTypeRef = 1,
iTypeDef = 2,
iField = 4,
iMethodDef = 6,
iParam = 8,
iInterfaceImpl = 9,
iMemberRef = 10,
iConstant = 11,
iCustomAttribute = 12,
iFieldMarshal = 13,
iDeclSecurity = 14,
iClassLayout = 15,
iFieldLayout = 16,
iStandAloneSig = 17,
iEventMap = 18,
iEvent = 20,
iPropertyMap = 21,
iProperty = 23,
iMethodSemantics = 24,
iMethodImpl = 25,
iModuleRef = 26,
iTypeSpec = 27,
iImplMap = 28,
iFieldRVA = 29,
iAssembly = 32,
iAssemblyProcessor = 33,
iAssemblyOS = 34,
iAssemblyRef = 35,
iAssemblyRefProcessor = 36,
iAssemblyRefOS = 37,
iFile = 38,
iExportedType = 39,
iManifestResource = 40,
iNestedClass = 41,
iGenericParam = 42,
iGenericParamConstraint = 44,
};
struct Stream {
Stream() : addr(0), size(0), name(0) {}
~Stream() {
if (name)
free((void*)name);
}
void init(unsigned char* addr, size_t size, const char* name) {
this->addr = addr;
this->size = size;
this->name = _strdup(name);
}
unsigned char* addr;
size_t size;
const char* name;
};
struct MetaDataTable {
MetaDataTable() : addr(0), rows(0) {}
unsigned char* addr;
size_t rows;
};
struct MetaDataField {
unsigned short offset;
unsigned short size;
};
class MetaDataType {
public:
MetaDataType(const MetaDataField* _fields, size_t _numFields)
: totalSize(0), numFields(_numFields), fields(0) {
fields = new MetaDataField[numFields];
for (size_t i = 0; i < numFields; i++) {
fields[i] = _fields[i];
totalSize += fields[i].size;
}
}
~MetaDataType() {
if (fields)
delete[] fields;
}
size_t size() const { return totalSize; }
size_t read(void* addr, size_t field) const {
if (field >= numFields)
throw strex("Invalid field index");
void* p = (unsigned char*)addr + fields[field].offset;
switch (fields[field].size) {
case 1: return *(unsigned char*)p; break;
case 2: return *(unsigned short*)p; break;
case 4: return *(unsigned int*)p; break;
default: throw strex("Invalid field size");
}
}
private:
MetaDataType(const MetaDataType&);
MetaDataType& operator=(const MetaDataType&);
size_t totalSize;
size_t numFields;
MetaDataField* fields;
};
class DotNetFile {
public:
DotNetFile(const wchar_t* filename);
~DotNetFile();
bool isYourImageBase(void* addr) const;
void* getMethodHeader(unsigned index, void* imageBase = 0) const;
const char* getMethodName(unsigned index, void* imageBase = 0) const;
void* getMethodDef(unsigned index, void* imageBase) const;
size_t getNumMethods() const;
const MetaDataType* getMethodType() const { return metaDataTypes[iMethodDef]; }
const MetaDataType* getType(MetaDataIndex t) const { return metaDataTypes[t]; }
size_t getStandAloneSigBlobIndex(unsigned index, void* imageBase) const;
private:
static const size_t METADATA_TYPES = 64;
DotNetFile(const DotNetFile&);
DotNetFile& operator=(const DotNetFile&);
void fread(long offset, void* buf, size_t size) const;
void fread(void* buf, size_t size) const;
void loadImage(const _IMAGE_FILE_HEADER& fileHeader, DWORD imageSize, DWORD headerSize);
void loadImage(DWORD rva, DWORD fileOffset, DWORD sizeRawData);
void* rvaToPtr(DWORD rva, size_t size) const;
size_t ptrToRva(void* addr) const;
size_t rvaToOffset(DWORD rva) const;
void* metaOffsToAddr(DWORD offs, DWORD size) const;
void initStreams();
Stream* findStream(const char* name) const;
void initMetadataTables();
void* getMetaDataTableElem(MetaDataIndex metaIndex, unsigned index, void* imageBase) const;
FILE* file;
_IMAGE_SECTION_HEADER* sectionHeaders;
size_t numSections;
unsigned char* image;
size_t imageSize;
size_t sizeOfHeaders;
IMAGE_COR20_HEADER* cor20Header;
unsigned char* metadata;
Stream* streams;
size_t numStreams;
Stream* streamTilde;
Stream* streamBlob;
Stream* streamStrings;
MetaDataTable metaDataTables[METADATA_TYPES];
MetaDataType* metaDataTypes[METADATA_TYPES];
};
#endif