-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathBlockParser.cs
65 lines (59 loc) · 2.09 KB
/
BlockParser.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
using dnlib.DotNet;
using dnlib.DotNet.Emit;
using System.Collections.Generic;
namespace IP_Grabber
{
public class Block
{
public Block()
{
Instructions = new List<Instruction>();
}
public List<Instruction> Instructions { get; set; }
public int Number { get; set; }
}
public class BlockParser
{
public static List<Block> ParseMethod(MethodDef method)
{
var blocks = new List<Block>();
var block = new Block();
var Id = 0;
var usage = 0;
block.Number = Id;
block.Instructions.Add(Instruction.Create(OpCodes.Nop));
blocks.Add(block);
block = new Block();
var handlers = new Stack<ExceptionHandler>();
foreach (var instruction in method.Body.Instructions)
{
foreach (var eh in method.Body.ExceptionHandlers)
{
if (eh.HandlerStart == instruction || eh.TryStart == instruction || eh.FilterStart == instruction)
handlers.Push(eh);
}
foreach (var eh in method.Body.ExceptionHandlers)
{
if (eh.HandlerEnd == instruction || eh.TryEnd == instruction)
handlers.Pop();
}
instruction.CalculateStackUsage(out var stacks, out var pops);
block.Instructions.Add(instruction);
usage += stacks - pops;
if (stacks == 0)
{
if (instruction.OpCode != OpCodes.Nop)
{
if ((usage == 0 || instruction.OpCode == OpCodes.Ret) && handlers.Count == 0)
{
block.Number = ++Id;
blocks.Add(block);
block = new Block();
}
}
}
}
return blocks;
}
}
}