mirror of https://github.com/icsharpcode/ILSpy.git
4 changed files with 238 additions and 0 deletions
@ -0,0 +1,65 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<Project> |
||||||
|
<Import Sdk="Microsoft.NET.Sdk" Project="Sdk.props" /> |
||||||
|
|
||||||
|
<PropertyGroup> |
||||||
|
<TargetFramework>net472</TargetFramework> |
||||||
|
<AssemblyName>ILSpy.ReadyToRun.Plugin</AssemblyName> |
||||||
|
<LangVersion>7.2</LangVersion> |
||||||
|
|
||||||
|
<GenerateAssemblyInfo>False</GenerateAssemblyInfo> |
||||||
|
|
||||||
|
<EnableDefaultItems>false</EnableDefaultItems> |
||||||
|
|
||||||
|
<BaseAddress>6488064</BaseAddress> |
||||||
|
</PropertyGroup> |
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)' == 'Debug'"> |
||||||
|
<DebugType>full</DebugType> |
||||||
|
<DebugSymbols>true</DebugSymbols> |
||||||
|
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> |
||||||
|
</PropertyGroup> |
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)' == 'Release'"> |
||||||
|
<DebugType>pdbonly</DebugType> |
||||||
|
<DebugSymbols>true</DebugSymbols> |
||||||
|
</PropertyGroup> |
||||||
|
|
||||||
|
<PropertyGroup> |
||||||
|
<OutputPath>..\ILSpy\bin\$(Configuration)\</OutputPath> |
||||||
|
</PropertyGroup> |
||||||
|
|
||||||
|
<ItemGroup> |
||||||
|
<ProjectReference Include="..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj"> |
||||||
|
<Private>False</Private> |
||||||
|
</ProjectReference> |
||||||
|
<ProjectReference Include="..\ILSpy\ILSpy.csproj"> |
||||||
|
<Private>False</Private> |
||||||
|
</ProjectReference> |
||||||
|
<ProjectReference Include="..\SharpTreeView\ICSharpCode.TreeView.csproj"> |
||||||
|
<Private>False</Private> |
||||||
|
</ProjectReference> |
||||||
|
</ItemGroup> |
||||||
|
|
||||||
|
<ItemGroup> |
||||||
|
<Reference Include="Iced"> |
||||||
|
<HintPath>..\..\iced\Iced\bin\Debug\netstandard2.0\Iced.dll</HintPath> |
||||||
|
</Reference> |
||||||
|
<Reference Include="ILCompiler.Reflection.ReadyToRun"> |
||||||
|
<HintPath>..\..\runtime\artifacts\bin\coreclr\Windows_NT.x64.Debug\ILCompiler.Reflection.ReadyToRun.dll</HintPath> |
||||||
|
</Reference> |
||||||
|
</ItemGroup> |
||||||
|
|
||||||
|
<ItemGroup> |
||||||
|
<Compile Include="ReadyToRunLanguage.cs" /> |
||||||
|
</ItemGroup> |
||||||
|
|
||||||
|
<Import Sdk="Microsoft.NET.Sdk" Project="Sdk.targets" /> |
||||||
|
|
||||||
|
<Target Name="RemoveTransitiveProjectReferences" AfterTargets="IncludeTransitiveProjectReferences"> |
||||||
|
<ItemGroup> |
||||||
|
<ProjectReference Remove="@(_TransitiveProjectReferences)" /> |
||||||
|
</ItemGroup> |
||||||
|
</Target> |
||||||
|
|
||||||
|
</Project> |
||||||
@ -0,0 +1,33 @@ |
|||||||
|
#region Using directives
|
||||||
|
|
||||||
|
using System.Reflection; |
||||||
|
using System.Runtime.InteropServices; |
||||||
|
using System.Runtime.CompilerServices; |
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("ILSpy.ReadyToRun.Plugin")] |
||||||
|
[assembly: AssemblyDescription("")] |
||||||
|
[assembly: AssemblyConfiguration("")] |
||||||
|
[assembly: AssemblyCompany("")] |
||||||
|
[assembly: AssemblyProduct("ILSpy.ReadyToRun.Plugin")] |
||||||
|
[assembly: AssemblyCopyright("Copyright 2011")] |
||||||
|
[assembly: AssemblyTrademark("")] |
||||||
|
[assembly: AssemblyCulture("")] |
||||||
|
|
||||||
|
// This sets the default COM visibility of types in the assembly to invisible.
|
||||||
|
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
|
||||||
|
[assembly: ComVisible(false)] |
||||||
|
|
||||||
|
[assembly: InternalsVisibleTo("ILSpy.ReadyToRun.Tests")] |
||||||
|
|
||||||
|
// The assembly version has following format :
|
||||||
|
//
|
||||||
|
// Major.Minor.Build.Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can use the default the Revision and
|
||||||
|
// Build Numbers by using the '*' as shown below:
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")] |
||||||
@ -0,0 +1,134 @@ |
|||||||
|
// Copyright (c) 2018 Siegfried Pammer
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.ComponentModel.Composition; |
||||||
|
using Iced.Intel; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
using ICSharpCode.Decompiler.Solution; |
||||||
|
using ICSharpCode.Decompiler.TypeSystem; |
||||||
|
using ILCompiler.Reflection.ReadyToRun; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy |
||||||
|
{ |
||||||
|
[Export(typeof(Language))] |
||||||
|
class ReadyToRunLanguage : Language |
||||||
|
{ |
||||||
|
public override string Name => "ReadyToRun"; |
||||||
|
|
||||||
|
public override string FileExtension { |
||||||
|
get { return ".asm"; } |
||||||
|
} |
||||||
|
|
||||||
|
public override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
PEFile module = assembly.GetPEFileOrNull(); |
||||||
|
// TODO: avoid eager parsing
|
||||||
|
R2RReader reader = new R2RReader(new R2RAssemblyResolver(), module.Metadata, module.Reader, module.FileName); |
||||||
|
|
||||||
|
output.WriteLine("// TODO - display ready to run information"); |
||||||
|
// TODO: display other header information
|
||||||
|
foreach (var method in reader.R2RMethods) { |
||||||
|
output.WriteLine(method.SignatureString); |
||||||
|
} |
||||||
|
|
||||||
|
return base.DecompileAssembly(assembly, output, options); |
||||||
|
} |
||||||
|
|
||||||
|
public override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
PEFile module = method.ParentModule.PEFile; |
||||||
|
// TODO: avoid eager parsing in R2RReader
|
||||||
|
R2RReader reader = new R2RReader(new R2RAssemblyResolver(), module.Metadata, module.Reader, module.FileName); |
||||||
|
foreach (var m in reader.R2RMethods) { |
||||||
|
if (m.MethodHandle == method.MetadataToken) { |
||||||
|
// TODO: Indexing
|
||||||
|
foreach (RuntimeFunction runtimeFunction in m.RuntimeFunctions) { |
||||||
|
byte[] code = new byte[runtimeFunction.Size]; |
||||||
|
for (int i = 0; i < runtimeFunction.Size; i++) { |
||||||
|
code[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i]; |
||||||
|
} |
||||||
|
// TODO: Bitness
|
||||||
|
// TODO: RIP
|
||||||
|
DecoderFormatterExample(output, code, 64, 0); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
private void DecoderFormatterExample(ITextOutput output, byte[] exampleCode, int exampleCodeBitness, ulong exampleCodeRIP) |
||||||
|
{ |
||||||
|
// TODO: Decorate the disassembly with Unwind, GC and debug info
|
||||||
|
// You can also pass in a hex string, eg. "90 91 929394", or you can use your own CodeReader
|
||||||
|
// reading data from a file or memory etc
|
||||||
|
var codeBytes = exampleCode; |
||||||
|
var codeReader = new ByteArrayCodeReader(codeBytes); |
||||||
|
var decoder = Decoder.Create(exampleCodeBitness, codeReader); |
||||||
|
decoder.IP = exampleCodeRIP; |
||||||
|
ulong endRip = decoder.IP + (uint)codeBytes.Length; |
||||||
|
|
||||||
|
// This list is faster than List<Instruction> since it uses refs to the Instructions
|
||||||
|
// instead of copying them (each Instruction is 32 bytes in size). It has a ref indexer,
|
||||||
|
// and a ref iterator. Add() uses 'in' (ref readonly).
|
||||||
|
var instructions = new InstructionList(); |
||||||
|
while (decoder.IP < endRip) { |
||||||
|
// The method allocates an uninitialized element at the end of the list and
|
||||||
|
// returns a reference to it which is initialized by Decode().
|
||||||
|
decoder.Decode(out instructions.AllocUninitializedElement()); |
||||||
|
} |
||||||
|
|
||||||
|
// Formatters: Masm*, Nasm*, Gas* (AT&T) and Intel* (XED)
|
||||||
|
// TODO: DecompilationOptions?
|
||||||
|
var formatter = new NasmFormatter(); |
||||||
|
formatter.Options.DigitSeparator = "`"; |
||||||
|
formatter.Options.FirstOperandCharIndex = 10; |
||||||
|
var tempOutput = new StringBuilderFormatterOutput(); |
||||||
|
// Use InstructionList's ref iterator (C# 7.3) to prevent copying 32 bytes every iteration
|
||||||
|
foreach (var instr in instructions) { |
||||||
|
// Don't use instr.ToString(), it allocates more, uses masm syntax and default options
|
||||||
|
formatter.Format(instr, tempOutput); |
||||||
|
output.Write(instr.IP.ToString("X16")); |
||||||
|
output.Write(" "); |
||||||
|
int instrLen = instr.ByteLength; |
||||||
|
int byteBaseIndex = (int)(instr.IP - exampleCodeRIP); |
||||||
|
for (int i = 0; i < instrLen; i++) |
||||||
|
output.Write(codeBytes[byteBaseIndex + i].ToString("X2")); |
||||||
|
int missingBytes = 10 - instrLen; |
||||||
|
for (int i = 0; i < missingBytes; i++) |
||||||
|
output.Write(" "); |
||||||
|
output.Write(" "); |
||||||
|
output.WriteLine(tempOutput.ToStringAndReset()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class R2RAssemblyResolver : ILCompiler.Reflection.ReadyToRun.IAssemblyResolver |
||||||
|
{ |
||||||
|
public bool Naked => false; |
||||||
|
|
||||||
|
public bool SignatureBinary => false; |
||||||
|
|
||||||
|
public bool InlineSignatureBinary => false; |
||||||
|
|
||||||
|
public string FindAssembly(string name, string filename) |
||||||
|
{ |
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue