enet-validator/tools/IlDump.cs

72 lines
3.4 KiB
C#
Raw Normal View History

using System;
using System.IO;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;
class IlDump {
static void Main(string[] args) {
string dll = args[0];
string mode = args.Length > 1 ? args[1] : "types";
string pat = args.Length > 2 ? args[2].ToLower() : "";
var rp = new ReaderParameters { ReadSymbols = false };
var asm = AssemblyDefinition.ReadAssembly(dll, rp);
foreach (var mod in asm.Modules) {
foreach (var t in mod.Types) {
DumpType(t, mode, pat, 0);
}
}
}
static void DumpType(TypeDefinition t, string mode, string pat, int depth) {
bool tmatch = pat.Length == 0 || t.FullName.ToLower().Contains(pat);
if (mode == "types") {
bool anyMethod = t.Methods.Any(m => m.Name.ToLower().Contains(pat));
if (tmatch || anyMethod) {
Console.WriteLine("TYPE " + t.FullName);
foreach (var m in t.Methods) {
if (tmatch || m.Name.ToLower().Contains(pat))
Console.WriteLine(" M " + m.FullName);
}
foreach (var f in t.Fields) {
if (tmatch) Console.WriteLine(" F " + f.FieldType.Name + " " + f.Name);
}
}
} else if (mode == "il") {
foreach (var m in t.Methods) {
if (!(t.FullName.ToLower().Contains(pat) || m.Name.ToLower().Contains(pat))) continue;
if (!m.HasBody) continue;
Console.WriteLine("=== " + m.FullName + " ===");
foreach (var v in m.Body.Variables)
Console.WriteLine(" .local " + v.VariableType.Name + " V_" + v.Index);
foreach (var ins in m.Body.Instructions) {
string op = ins.Operand == null ? "" : " " + OpText(ins.Operand);
Console.WriteLine(string.Format(" IL_{0:x4}: {1}{2}", ins.Offset, ins.OpCode.Name, op));
}
}
} else if (mode == "xref") {
// 找所有引用了匹配名称的方法/字段的方法体
foreach (var m in t.Methods) {
if (!m.HasBody) continue;
bool hit = false;
foreach (var ins in m.Body.Instructions) {
string s = ins.Operand == null ? "" : ins.Operand.ToString();
if (s.ToLower().Contains(pat)) { hit = true; break; }
}
if (hit) Console.WriteLine("XREF " + m.FullName);
}
}
foreach (var nt in t.NestedTypes) DumpType(nt, mode, pat, depth + 1);
}
static string OpText(object o) {
var mr = o as MethodReference; if (mr != null) return mr.FullName;
var fr = o as FieldReference; if (fr != null) return fr.FullName;
var s = o as string; if (s != null) return "\"" + s + "\"";
var ins = o as Instruction; if (ins != null) return "IL_" + ins.Offset.ToString("x4");
var arr = o as Instruction[]; if (arr != null) return string.Join(",", arr.Select(i => "IL_" + i.Offset.ToString("x4")).ToArray());
var p = o as ParameterReference; if (p != null) return "arg" + p.Index;
var vr = o as VariableReference; if (vr != null) return "V_" + vr.Index;
var tr = o as TypeReference; if (tr != null) return tr.FullName;
return o == null ? "" : o.ToString();
}
}