dimanche 15 septembre 2019

Unable to find/edit field with reflection, when dotPeek & stackoverflow questions decompiler clearly show it

I've been working on threads for a project of mine, and I've started using thread names for logging purposes. The main thread of my application is being renamed to an empty string (not by me), so I need to change it manually. The problem is, the Name property of a Thread is write-once, and since it's already been set, I am unable to change it normally. I looked around a bit and was able to find This question that seemed promising. When ever I run it though, I get null reference exceptions. I examined further, and the GetField() method is returning null. I checked with Jetbrains dotPeek and I can clearly see the m_Name field, along with it's property:

private Context m_Context;
private ExecutionContext m_ExecutionContext;
private string m_Name; //<- This
private Delegate m_Delegate;
private CultureInfo m_CurrentCulture;

My code to get the field is

thread.GetType().GetField("m_Name", BindingFlags.Instance | BindingFlags.NonPublic);

As soon as I run it, it returns null. I tried using typeof(Thread), to no avail.

Finally, I decided to brute force it, and decided to try and try with every single binding flags combination:

Stopwatch stopwatch = Stopwatch.StartNew();
HashSet<FieldInfo> fieldInfos = new HashSet<FieldInfo>();
//Loop over every single bit combination
for (int i = 0; i < 0x01111111; i++)
{
    BindingFlags f = (BindingFlags) i;
    FieldInfo[] infos = thread.GetType().GetFields(f);
    foreach (FieldInfo info in infos) fieldInfos.Add(info);
}
Debug.Log($"Time to search: {stopwatch.Elapsed.TotalMilliseconds:n0}ms");
stopwatch.Restart();
Debug.Log(fieldInfos.Count);
foreach (FieldInfo info in fieldInfos)
{
    Debug.Log(info.Name);
    Thread.Sleep(10);
}
Debug.Log($"Time to log: {stopwatch.Elapsed.TotalMilliseconds:n0}ms");

Output

How do I get it to find the field properly?





Aucun commentaire:

Enregistrer un commentaire