⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 assemblyreader.cs

📁 全功能c#编译器
💻 CS
字号:
// Assembly.cs
// Copyright (C) 2003 Mike Krueger
// 
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// 
// This library 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
// Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
using System.IO;
using ICSharpCode.SharpAssembly.Metadata.Rows;
using ICSharpCode.SharpAssembly.Metadata;
using ICSharpCode.SharpAssembly.PE;

namespace ICSharpCode.SharpAssembly.Assembly {
	
	public class AssemblyReader
	{
		PEFileHeader   header;
		CLIHeader      cliHeader;
		SectionTable[] sections;
		MetadataTable  metadataTable = new MetadataTable();
		
		byte[] stringHeap;
		byte[] userStringHeap;
		byte[] guidHeap;
		byte[] blobHeap;
		byte[] rawSectionData;
		
		string filename;
		
		public PEFileHeader PEHeader {
			get {
				return header;
			}
		}
		
		public CLIHeader CliHeader {
			get {
				return cliHeader;
			}
		}
		
		public string FileName {
			get {
				return filename;
			}
		}
		
		public MetadataTable MetadataTable {
			get {
				return metadataTable;
			}
		}
		
		public byte[] StringHeap {
			get {
				return stringHeap;
			}
		}
		
		public byte[] UserStringHeap {
			get {
				return userStringHeap;
			}
		}
		
		public byte[] GuidHeap {
			get {
				return guidHeap;
			}
		}
		
		public byte[] BlobHeap {
			get {
				return blobHeap;
			}
		}
		
		public byte[] RawSectionData {
			get {
				return rawSectionData;
			}
		}
		
		public static int GetCompressedInt(byte[] heap, ref uint index)
		{
			if (index < 0 || index >= heap.Length) {
				return -1;
			}
			int first = heap[index++];
			switch (first & 0xC0) {
				case 0xC0:
					first &= ~0xC0;
					return first << 24 | heap[index++] << 16 | heap[index++] << 8 | heap[index++];
				case 0x80:
					first &= ~0x80;
					return first << 8 | heap[index++];
				default:
					return first;
			}
		}
		
		public int LoadBlob(ref uint index)
		{
			return GetCompressedInt(blobHeap, ref index);
		}
		
		public byte[] GetBlobFromHeap(uint index)
		{
			if (index < 0 || index >= blobHeap.Length) {
				return new byte[0];
			}
			int length = LoadBlob(ref index);
			
			byte[] dest = new byte[length];
			Array.Copy(blobHeap, index, dest, 0, length);
			
			return dest;
		}

		public string GetUserStringFromHeap(uint index)
		{
			if (index < 0 || index >= userStringHeap.Length) {
				return "";
			}
			
			int length = GetCompressedInt(userStringHeap, ref index);

			return System.Text.Encoding.Unicode.GetString(userStringHeap, (int)index, length);
		}
		
		public string GetStringFromHeap(uint index)
		{
			if (index < 0 || index >= stringHeap.Length) {
				return "";
			}
			
			uint endIndex = index;
			while (endIndex < stringHeap.Length && stringHeap[endIndex] != 0) {
				++endIndex;
			}
			
			return System.Text.Encoding.UTF8.GetString(stringHeap, (int)index, (int)(endIndex - index));
		}
		
		public uint LookupRVA(uint address)
		{
			foreach (SectionTable section in sections) {
				if (section.VirtualAddress <= address && address <= section.VirtualAddress + section.VirtualSize) {
					return section.PointerToRawData + address - section.VirtualAddress;
				}
			}
			return 0;
		}
		
		public Stream OpenStream(uint rva)
		{
			uint offset = LookupRVA(rva);
			MemoryStream ms = new MemoryStream(rawSectionData);
			ms.Seek(offset, SeekOrigin.Begin);
			return ms;
		}
		
		public ICSharpCode.SharpAssembly.Metadata.Rows.MethodBody LoadMethodBody(uint rva)
		{
			BinaryReader binaryReader = new BinaryReader(OpenStream(rva));
			ICSharpCode.SharpAssembly.Metadata.Rows.MethodBody body = new ICSharpCode.SharpAssembly.Metadata.Rows.MethodBody();
			body.Load(binaryReader);
			binaryReader.Close();
			return body;
		}
		
		public void Load(string fileName)
		{
			Stream fs = System.IO.File.OpenRead(fileName);
			fs.Seek(128, SeekOrigin.Begin);
			
			filename = fileName;
			
			BinaryReader binaryReader = new BinaryReader(fs);
			
			header = new PEFileHeader();
			header.LoadFrom(binaryReader);
			
			sections = new SectionTable[header.NumberOfSections];
			for (int i = 0; i < header.NumberOfSections; ++i) {
				sections[i] = new SectionTable();
				sections[i].LoadFrom(binaryReader);
			}
			
			uint rawDataSize = 0;
			for (int i = 0; i < header.NumberOfSections; ++i) {
				rawDataSize += sections[i].SizeOfRawData;
			}
			
			// read all sections to a memory buffer and relocate all pointer in the sections
			// to raw data indices in the buffer
			rawSectionData = new byte[rawDataSize];
			int curOffset = 0;
			for (int i = 0; i < header.NumberOfSections; ++i) {
				fs.Seek((int)sections[i].PointerToRawData, SeekOrigin.Begin);
				fs.Read(rawSectionData, curOffset, (int)sections[i].SizeOfRawData);
				sections[i].PointerToRawData = (uint)curOffset;
				curOffset += (int)sections[i].SizeOfRawData;
			}
			binaryReader.Close();
			fs.Close();
			
			fs           = new MemoryStream(rawSectionData);
			binaryReader = new BinaryReader(fs);
			
			uint cliHeaderPos = LookupRVA(header.DataDirectories.CliHeader);
			fs.Seek((int)cliHeaderPos, SeekOrigin.Begin);
			cliHeader = new CLIHeader();
			cliHeader.LoadFrom(binaryReader);
			
			uint metaDataPos = LookupRVA(cliHeader.MetaData);
			fs.Seek((int)metaDataPos, SeekOrigin.Begin);
			AssemblyMetadata met = new AssemblyMetadata();
			met.LoadFrom(binaryReader);
			
			foreach (StreamHeader streamHeader in met.StreamHeaders) {
				uint offset = LookupRVA(cliHeader.MetaData + streamHeader.Offset);
				fs.Seek((int)offset, SeekOrigin.Begin);
				switch (streamHeader.Name) {
					case "#~":
						metadataTable.LoadFrom(binaryReader);
						break;
					case "#Strings":
						stringHeap = new byte[streamHeader.Size];
						fs.Read(stringHeap, 0, stringHeap.Length);
						break;
					case "#US":
						userStringHeap = new byte[streamHeader.Size];
						fs.Read(userStringHeap, 0, userStringHeap.Length);
						break;
					case "#GUID":
						guidHeap = new byte[streamHeader.Size];
						fs.Read(guidHeap, 0, guidHeap.Length);
						break;
					case "#Blob":
						blobHeap = new byte[streamHeader.Size];
						fs.Read(blobHeap, 0, blobHeap.Length);
						break;
				}
			}
			

		}
		
		public int GetCodedIndexTable(CodedIndex index, ref uint val)
		{
			int bits = 0;
			
			switch (index) {
				case CodedIndex.HasConstant:
				case CodedIndex.TypeDefOrRef:
				case CodedIndex.HasDeclSecurity:
				case CodedIndex.Implementation:
				case CodedIndex.ResolutionScope:
					bits = 2;
					break;
				case CodedIndex.HasCustomAttribute:
					bits = 5;
					break;
				case CodedIndex.HasFieldMarshall:
				case CodedIndex.HasSemantics:
				case CodedIndex.MethodDefOrRef:
				case CodedIndex.MemberForwarded:
					bits = 1;
					break;
				case CodedIndex.MemberRefParent:
				case CodedIndex.CustomAttributeType:
					bits = 3;
					break;
			}
			
			uint origval = val;
			val = origval >> bits;
			
			return (int)(origval & ((int)Math.Pow(2, bits) - 1));
		}

	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -