【发布时间】:2020-02-28 03:38:29
【问题描述】:
目标: 使用注入器代码,我试图将秒表方法(在秒表 dll 中)注入目标 dll 的所需代码位置,以便计算目标 dll 中每个方法所花费的时间,这可能是也可能不是无效的方法,它可能有多个返回语句。
目标 dll
public class targetDll
{
void func1(){
//Inject Stopwatch_start(); method here
int a = 3;
int b = 4;
int temp;
temp = a;
a = b;
b =temp;
if (a + b > 2)
{
Console.WriteLine("function____1");
}
#Stopwatch_stop() //Inject stop time here
}
String func2(){
//Inject Stopwatch_start(); method here
int a = 3;
int b = 4;
int c = 5;
int temp;
temp = a;
a = b;
b = c;
c = temp;
if (a + b > 5)
{
Console.WriteLine("function____2");
//inject Stopwatch_stop() method here
return ;
}
a = temp;
//inject Stopwatch_stop(); method here
return;
}
}
源 dll(秒表 dll)
public static class stopwatch_class
{
static System.Diagnostics.Stopwatch stopwatch_obj = new System.Diagnostics.Stopwatch();
public static void stopwatch_start()
{
stopwatch_obj.Start();
}
public static void stopwatch_stop()
{
stopwatch_obj.Stop();
Console.WriteLine(stopwatch_obj.ElapsedMilliseconds);
}
}
}
注入器代码
class Trial_injector
{
static void Main(string[] args)
{
var start_method = (dynamic)null;
var stop_method = (dynamic)null;
AssemblyDefinition target_assembly = AssemblyDefinition.ReadAssembly("targetDll.dll",
new ReaderParameters { ReadWrite = true });
var target_modules = target_assembly.MainModule;
TypeDefinition[] target_module = target_modules.Types.ToArray();
AssemblyDefinition source_assembly = AssemblyDefinition.ReadAssembly("stopwatch.dll", new
ReaderParameters { ReadWrite = true });
var source_modules = source_assembly.MainModule;
TypeDefinition[] source_module = source_modules.Types.ToArray();
foreach (var type in source_module)
{
foreach (var method in type.Methods)
{
if (method.Name == "stopwatch_start")
{
start_method = method;
}
if (method.Name == "stopwatch_stop")
{
stop_method = method;
}
}
}
foreach(var module_ in target_module)
{
foreach(var method_ in module_.Methods)
{
String stg="hello_world";
var processor2 = method_.Body.GetILProcessor();
var first_instruction = method_.Body.Instructions.First();
var last_instruction = method_.Body.Instructions.Last();
var ldstr = processor2.Create(OpCodes.Ldstr, stg);
var call = processor2.Create(OpCodes.Call, method_.Module.Import(start_method));
var call2 = processor2.Create(OpCodes.Call, method_.Module.Import(stop_method));
processor2.InsertBefore(first_instruction, ldstr);
processor2.InsertAfter(first_instruction, call);
processor2.InsertBefore(last_instruction, ldstr);
processor2.InsertBefore(last_instruction, call2);
}
}
target_assembly.Write();
}
【问题讨论】:
-
你尝试了什么?
-
我尝试将 stopwatch_start() 和 stopwatch_stop() 分别注入目标 dll 中每个方法的开头和结尾。问题是,在具有 "if body" 的 void 方法中,stopwatch_stop() 方法被插入到 "if body" 本身的末尾,而不是 @Cyril 方法的末尾
-
var processor2 = method_.Body.GetILProcessor(); //这会创建一个新的处理器 var last_instruction = method_.Body.Instructions.Last(); //这移动到代码的最后一行 var call2 = processor2.Create(OpCodes.Call, method_.Module.Import(stop_method)); //这会导入我的 sendstop 方法 processor2.InsertBefore(last_instruction, call2); //在这里,我将转到代码的最后一条指令并使用 call2 调用 stopwatch_Stop();功能
标签: c# dll mono mono.cecil