Created
May 13, 2018 14:50
-
-
Save svick/22d003327c5d002197748af399aecec0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Project Sdk="Microsoft.NET.Sdk"> | |
<PropertyGroup> | |
<OutputType>Exe</OutputType> | |
<TargetFramework>netcoreapp2.1</TargetFramework> | |
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |
</PropertyGroup> | |
<ItemGroup> | |
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.0-rc1" /> | |
</ItemGroup> | |
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.InteropServices; | |
using System.Runtime.CompilerServices; | |
struct MethodDesc | |
{ | |
const ushort enum_flag3_TokenRemainderMask = 0x3FFF; | |
static readonly int ALIGNMENT_SHIFT = 3; | |
static readonly int ALIGNMENT = (1<<ALIGNMENT_SHIFT); | |
ushort m_wFlags3AndTokenRemainder; | |
byte m_chunkIndex; | |
byte m_bFlags2; | |
ushort m_wSlotNumber; | |
ushort m_wFlags; | |
public unsafe int GetMemberDef() | |
{ | |
MethodDescChunk *pChunk = GetMethodDescChunk(); | |
ushort tokrange = pChunk->GetTokRange(); | |
ushort tokremainder = (ushort)(m_wFlags3AndTokenRemainder & enum_flag3_TokenRemainderMask); | |
return MergeToken(tokrange, tokremainder); | |
} | |
unsafe MethodDescChunk* GetMethodDescChunk() | |
{ | |
return | |
(MethodDescChunk*)((IntPtr)Unsafe.AsPointer(ref this) - | |
(sizeof(MethodDescChunk) + (GetMethodDescIndex() * MethodDesc.ALIGNMENT))); | |
} | |
int GetMethodDescIndex() | |
{ | |
return m_chunkIndex; | |
} | |
const int METHOD_TOKEN_REMAINDER_BIT_COUNT = 14; | |
int MergeToken(ushort tokrange, ushort tokremainder) | |
{ | |
return (tokrange << METHOD_TOKEN_REMAINDER_BIT_COUNT) | tokremainder | mdtMethodDef; | |
} | |
const int mdtMethodDef = 0x06000000; | |
} | |
struct MethodDescChunk | |
{ | |
const ushort enum_flag_TokenRangeMask = 0x03FF; | |
IntPtr m_methodTable; | |
IntPtr m_next; | |
byte m_size; | |
byte m_count; | |
ushort m_flagsAndTokenRange; | |
public ushort GetTokRange() | |
{ | |
return (ushort)(m_flagsAndTokenRange & enum_flag_TokenRangeMask); | |
} | |
} | |
class Program | |
{ | |
static unsafe void Main() | |
{ | |
var mi = typeof(Console).GetMethod("WriteLine", Type.EmptyTypes); | |
var methodDesc = (MethodDesc*)mi.MethodHandle.Value; | |
int token = methodDesc->GetMemberDef(); | |
Console.WriteLine("{0:X8}", token); | |
Console.WriteLine(mi.Module.ResolveMethod(token)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment