123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776 |
- /*
- * PERWAPI - An API for Reading and Writing PE Files
- *
- * Copyright (c) Diane Corney, Queensland University of Technology, 2004.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the PERWAPI Copyright as included with this
- * distribution in the file PERWAPIcopyright.rtf.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY as is explained in the copyright notice.
- *
- * The author may be contacted at d.corney@qut.edu.au
- *
- * Version Date: 26/01/07
- */
- using System;
- using System.IO;
- namespace QUT.PERWAPI
- {
- /**************************************************************************/
- // Classes used to describe constant values
- /**************************************************************************/
- /// <summary>
- /// Descriptor for a constant value, to be written in the blob heap
- /// </summary>
- public abstract class Constant
- {
- protected uint size = 0;
- internal ElementType type;
- protected uint blobIndex;
- internal MetaDataOut addedToBlobHeap;
- /*-------------------- Constructors ---------------------------------*/
- internal Constant() { }
- internal virtual uint GetBlobIndex(MetaDataOut md) { return 0; }
- internal uint GetSize() { return size; }
- internal byte GetTypeIndex() { return (byte)type; }
- internal virtual void Write(BinaryWriter bw) { }
- internal virtual void Write(CILWriter output)
- {
- throw new NotYetImplementedException("Constant values for CIL");
- }
- }
- /**************************************************************************/
- public abstract class BlobConstant : Constant { }
- /**************************************************************************/
- /// <summary>
- /// Boolean constant
- /// </summary>
- public class BoolConst : BlobConstant
- {
- bool val;
- /*-------------------- Constructors ---------------------------------*/
- /// <summary>
- /// Create a new boolean constant with the value "val"
- /// </summary>
- /// <param name="val">value of this boolean constant</param>
- public BoolConst(bool val)
- {
- this.val = val;
- size = 1;
- type = ElementType.Boolean;
- }
- public bool GetBool()
- {
- return val;
- }
- internal sealed override uint GetBlobIndex(MetaDataOut md)
- {
- if (addedToBlobHeap != md)
- {
- if (val) blobIndex = md.AddToBlobHeap(1, 1);
- else blobIndex = md.AddToBlobHeap(0, 1);
- addedToBlobHeap = md;
- }
- return blobIndex;
- }
- internal sealed override void Write(BinaryWriter bw)
- {
- if (val) bw.Write((sbyte)1);
- else bw.Write((sbyte)0);
- }
- }
- /**************************************************************************/
- public class CharConst : BlobConstant
- {
- char val;
- /*-------------------- Constructors ---------------------------------*/
- public CharConst(char val)
- {
- this.val = val;
- size = 2;
- type = ElementType.Char;
- }
- internal CharConst(PEReader buff)
- {
- val = buff.ReadChar();
- size = 2;
- type = ElementType.Char;
- }
- public char GetChar()
- { // KJG addition 2005-Mar-01
- return val;
- }
- internal sealed override uint GetBlobIndex(MetaDataOut md)
- {
- if (addedToBlobHeap != md)
- {
- blobIndex = md.AddToBlobHeap(val);
- addedToBlobHeap = md;
- }
- return blobIndex;
- }
- internal sealed override void Write(BinaryWriter bw)
- {
- bw.Write(val);
- }
- }
- /**************************************************************************/
- public class NullRefConst : BlobConstant
- {
- /*-------------------- Constructors ---------------------------------*/
- public NullRefConst()
- {
- size = 4;
- type = ElementType.Class;
- }
- internal NullRefConst(PEReader buff)
- {
- uint junk = buff.ReadUInt32();
- size = 4;
- type = ElementType.Class;
- }
- internal sealed override uint GetBlobIndex(MetaDataOut md)
- {
- if (addedToBlobHeap != md)
- {
- blobIndex = md.AddToBlobHeap(0, 4);
- addedToBlobHeap = md;
- }
- return blobIndex;
- }
- internal sealed override void Write(BinaryWriter bw)
- {
- bw.Write((int)0);
- }
- }
- /**************************************************************************/
- /// <summary>
- /// Constant array
- /// </summary>
- public class ArrayConst : BlobConstant
- {
- Constant[] elements;
- /*-------------------- Constructors ---------------------------------*/
- public ArrayConst(Constant[] elems)
- {
- type = ElementType.SZArray;
- size = 5; // one byte for SZARRAY, 4 bytes for length
- elements = elems;
- for (int i = 0; i < elements.Length; i++)
- {
- size += elements[i].GetSize();
- }
- }
- public Constant[] GetArray()
- {
- return elements;
- }
- internal sealed override uint GetBlobIndex(MetaDataOut md)
- {
- if (addedToBlobHeap != md)
- {
- MemoryStream str = new MemoryStream();
- BinaryWriter bw = new BinaryWriter(str);
- Write(bw);
- blobIndex = md.AddToBlobHeap(str.ToArray());
- addedToBlobHeap = md;
- }
- return blobIndex;
- }
- internal sealed override void Write(BinaryWriter bw)
- {
- bw.Write((byte)type);
- bw.Write(elements.Length);
- for (int i = 0; i < elements.Length; i++)
- {
- elements[i].Write(bw);
- }
- }
- }
- /**************************************************************************/
- public class ClassTypeConst : BlobConstant
- {
- string name;
- Class desc;
- /*-------------------- Constructors ---------------------------------*/
- public ClassTypeConst(string className)
- {
- name = className;
- type = ElementType.ClassType;
- }
- public ClassTypeConst(Class classDesc)
- {
- desc = classDesc;
- type = ElementType.ClassType;
- }
- public Class GetClass()
- {
- return desc;
- }
- public String GetClassName()
- {
- if (name == null) name = desc.TypeName();
- // CHECK - ClassName or TypeName
- // if (name == null) return desc.ClassName();
- return name;
- }
- internal override void Write(BinaryWriter bw)
- {
- if (name == null) name = desc.TypeName();
- // CHECK - ClassName or TypeName
- // if (name == null) name = desc.ClassName();
- bw.Write(name);
- }
- }
- /**************************************************************************/
- public class BoxedSimpleConst : BlobConstant
- {
- SimpleConstant sConst;
- /*-------------------- Constructors ---------------------------------*/
- public BoxedSimpleConst(SimpleConstant con)
- {
- sConst = con;
- type = (ElementType)sConst.GetTypeIndex();
- }
- public SimpleConstant GetConst()
- {
- return sConst;
- }
- internal override void Write(BinaryWriter bw)
- {
- bw.Write((byte)type);
- sConst.Write(bw);
- }
- }
- /**************************************************************************/
- /// <summary>
- /// Descriptor for a constant value
- /// </summary>
- public abstract class DataConstant : Constant
- {
- private uint dataOffset = 0;
- /*-------------------- Constructors ---------------------------------*/
- internal DataConstant() { }
- public uint DataOffset
- {
- get { return dataOffset; }
- set { dataOffset = value; }
- }
- }
- /**************************************************************************/
- /// <summary>
- /// Constant for a memory address
- /// </summary>
- public class AddressConstant : DataConstant
- {
- DataConstant data;
- /*-------------------- Constructors ---------------------------------*/
- public AddressConstant(DataConstant dConst)
- {
- data = dConst;
- size = 4;
- type = ElementType.TypedByRef;
- }
- internal AddressConstant(PEReader buff)
- {
- }
- public DataConstant GetConst()
- {
- return data;
- }
- internal sealed override void Write(BinaryWriter bw)
- {
- ((PEWriter)bw).WriteDataRVA(data.DataOffset);
- }
- }
- /**************************************************************************/
- public class ByteArrConst : DataConstant
- {
- byte[] val;
- /*-------------------- Constructors ---------------------------------*/
- public ByteArrConst(byte[] val)
- {
- this.val = val;
- size = (uint)val.Length;
- }
- public byte[] GetArray()
- {
- return val;
- }
- internal sealed override uint GetBlobIndex(MetaDataOut md)
- {
- if (addedToBlobHeap != md)
- {
- blobIndex = md.AddToBlobHeap(val);
- addedToBlobHeap = md;
- }
- return blobIndex;
- }
- internal sealed override void Write(BinaryWriter bw)
- {
- bw.Write(val);
- }
- }
- /**************************************************************************/
- public class RepeatedConstant : DataConstant
- {
- DataConstant data;
- uint repCount;
- /*-------------------- Constructors ---------------------------------*/
- public RepeatedConstant(DataConstant dConst, int repeatCount)
- {
- data = dConst;
- repCount = (uint)repeatCount;
- type = ElementType.SZArray;
- size = data.GetSize() * repCount;
- }
- public DataConstant GetConst()
- {
- return data;
- }
- public uint GetCount()
- {
- return repCount;
- }
- internal sealed override void Write(BinaryWriter bw)
- {
- for (int i = 0; i < repCount; i++)
- {
- data.Write(bw);
- }
- }
- }
- /**************************************************************************/
- public class StringConst : DataConstant
- {
- string val;
- byte[] strBytes;
- /*-------------------- Constructors ---------------------------------*/
- public StringConst(string val)
- {
- this.val = val;
- size = (uint)val.Length; // need to add null ??
- type = ElementType.String;
- }
- internal StringConst(byte[] sBytes)
- {
- strBytes = sBytes;
- size = (uint)strBytes.Length;
- type = ElementType.String;
- }
- public string GetString()
- {
- return val;
- }
- public byte[] GetStringBytes()
- {
- return strBytes;
- }
- internal sealed override uint GetBlobIndex(MetaDataOut md)
- {
- if (addedToBlobHeap != md)
- {
- if (val == null)
- blobIndex = md.AddToBlobHeap(strBytes);
- else
- blobIndex = md.AddToBlobHeap(val);
- addedToBlobHeap = md;
- }
- return blobIndex;
- }
- internal sealed override void Write(BinaryWriter bw)
- {
- if ((val == null) && (strBytes != null))
- {
- bw.Write(strBytes);
- }
- else
- bw.Write(val);
- }
- }
- /**************************************************************************/
- public abstract class SimpleConstant : DataConstant { }
- /**************************************************************************/
- public class IntConst : SimpleConstant
- {
- long val;
- /*-------------------- Constructors ---------------------------------*/
- public IntConst(sbyte val)
- {
- this.val = val;
- size = 1; //8;
- type = ElementType.I8;
- }
- public IntConst(short val)
- {
- this.val = val;
- size = 2; //16;
- type = ElementType.I2;
- }
- public IntConst(int val)
- {
- this.val = val;
- size = 4; //32;
- type = ElementType.I4;
- }
- public IntConst(long val)
- {
- this.val = val;
- size = 8; //64;
- type = ElementType.I8;
- }
- internal IntConst(PEReader buff, int numBytes)
- {
- switch (numBytes)
- {
- case (1): val = buff.ReadSByte();
- type = ElementType.I8;
- break;
- case (2): val = buff.ReadInt16();
- type = ElementType.I2;
- break;
- case (4): val = buff.ReadInt32();
- type = ElementType.I4;
- break;
- case (8): val = buff.ReadInt64();
- type = ElementType.I8;
- break;
- default: val = 0;
- break;
- }
- size = (uint)numBytes; // * 4;
- }
- public int GetIntSize()
- {
- return (int)size;
- }
- public ElementType GetIntType()
- {
- return type;
- }
- public int GetInt()
- {
- if (size < 8)
- return (int)val;
- else
- throw new Exception("Constant is long");
- }
- public long GetLong()
- {
- return val;
- }
- internal sealed override uint GetBlobIndex(MetaDataOut md)
- {
- if (addedToBlobHeap != md)
- {
- blobIndex = md.AddToBlobHeap(val, size);
- //switch (size) {
- // case (1) : md.AddToBlobHeap((sbyte)val); break;
- // case (2) : md.AddToBlobHeap((short)val); break;
- // case (4) : md.AddToBlobHeap((int)val); break;
- // default : md.AddToBlobHeap(val); break;
- //}
- addedToBlobHeap = md;
- }
- return blobIndex;
- }
- internal sealed override void Write(BinaryWriter bw)
- {
- switch (size)
- {
- case (1): bw.Write((sbyte)val); break;
- case (2): bw.Write((short)val); break;
- case (4): bw.Write((int)val); break;
- default: bw.Write(val); break;
- }
- }
- }
- /**************************************************************************/
- public class UIntConst : SimpleConstant
- {
- ulong val;
- /*-------------------- Constructors ---------------------------------*/
- public UIntConst(byte val)
- {
- this.val = val;
- size = 1;
- type = ElementType.U8;
- }
- public UIntConst(ushort val)
- {
- this.val = val;
- size = 2;
- type = ElementType.U2;
- }
- public UIntConst(uint val)
- {
- this.val = val;
- size = 4;
- type = ElementType.U4;
- }
- public UIntConst(ulong val)
- {
- this.val = val;
- size = 8;
- type = ElementType.U8;
- }
- public int GetIntSize()
- {
- return (int)size;
- }
- public ElementType GetUIntType()
- {
- return type;
- }
- public uint GetUInt()
- {
- return (uint)val;
- }
- public ulong GetULong()
- {
- return val;
- }
- public long GetLong()
- { // KJG addition
- if (val <= (ulong)(System.Int64.MaxValue))
- return (long)val;
- else
- throw new Exception("UInt Constant too large");
- }
- public long GetULongAsLong()
- { // KJG addition
- return (long)val;
- }
- internal sealed override uint GetBlobIndex(MetaDataOut md)
- {
- if (addedToBlobHeap != md)
- {
- blobIndex = md.AddToBlobHeap(val, size);
- //switch (size) {
- // case (1) : blobIndex = md.AddToBlobHeap((byte)val); break;
- // case (2) : blobIndex = md.AddToBlobHeap((ushort)val); break;
- // case (4) : blobIndex = md.AddToBlobHeap((uint)val); break;
- // default : blobIndex = md.AddToBlobHeap(val); break;
- //}
- addedToBlobHeap = md;
- }
- return blobIndex;
- }
- internal sealed override void Write(BinaryWriter bw)
- {
- switch (size)
- {
- case (1): bw.Write((byte)val); break;
- case (2): bw.Write((ushort)val); break;
- case (4): bw.Write((uint)val); break;
- default: bw.Write(val); break;
- }
- }
- }
- /**************************************************************************/
- public class FloatConst : SimpleConstant
- {
- float val;
- /*-------------------- Constructors ---------------------------------*/
- public FloatConst(float val)
- {
- this.val = val;
- size = 4;
- type = ElementType.R4;
- }
- internal FloatConst(PEReader buff)
- {
- val = buff.ReadSingle();
- size = 4;
- type = ElementType.R4;
- }
- public float GetFloat()
- {
- return val;
- }
- public double GetDouble()
- { // KJG addition 2005-Mar-01
- return (double)val;
- }
- internal sealed override uint GetBlobIndex(MetaDataOut md)
- {
- if (addedToBlobHeap != md)
- {
- blobIndex = md.AddToBlobHeap(val);
- addedToBlobHeap = md;
- }
- return blobIndex;
- }
- internal sealed override void Write(BinaryWriter bw)
- {
- bw.Write(val);
- }
- }
- /**************************************************************************/
- public class DoubleConst : SimpleConstant
- {
- double val;
- /*-------------------- Constructors ---------------------------------*/
- public DoubleConst(double val)
- {
- this.val = val;
- size = 8;
- type = ElementType.R8;
- }
- internal DoubleConst(PEReader buff)
- {
- val = buff.ReadDouble();
- size = 8;
- type = ElementType.R8;
- }
- public double GetDouble()
- { // KJG addition 2005-Mar-01
- return val;
- }
- internal sealed override uint GetBlobIndex(MetaDataOut md)
- {
- if (addedToBlobHeap != md)
- {
- blobIndex = md.AddToBlobHeap(val);
- addedToBlobHeap = md;
- }
- return blobIndex;
- }
- internal sealed override void Write(BinaryWriter bw)
- {
- bw.Write(val);
- }
- }
- }
|