C# 代码插桩

bigbaldy 2016-05-05 06:28:33
想监测代码执行的过程,目前是通过修改IL的方式进行代码静态注入,例如使用如下方式获取所有Console.WriteLine函数的输入值


一个参数的情况,没有任何问题

如果是多个参数:


C#的函数是自己平栈的,所以必须构造出如上图所示的堆栈才行,但是IL指令里只有dup,不能复制多个栈中的内容,现在的问题是,有什么办法让我的函数调用完毕后堆栈恢复到调用之前

我想过使用局部变量暂时存储堆栈内容,但是我并不知道哪些局部变量可以用,例如使用stloc_1指令,但这样就会覆盖掉索引1中存储的值, 那么只能在stloc_1之前存储1,但是存哪呢?栈是不行了,只能存堆里,但感觉不太通用,需要插入很多IL才能实现

C#现在是否有这种库已经实现了类似功能,肯求各位大牛们帮帮忙!


...全文
663 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
bigbaldy 2016-05-06
  • 打赏
  • 举报
回复
引用 10 楼 u012758945 的回复:
楼主目前应该还处于测试可行性的阶段,按照楼主的方式应该是想在目标方法里的“调用方法之前”拦截,那就要获取所有的IL指令来分析每个调用的方法。 假设可以取到调用的方法,那拿到参数的信息就没问题了。 在假设成立的前提下,如果要通过程序来执行动态注入,我目前想到的只有两种方法, 1是固定Hook方法,在Hook方法里再进行动态调用,但是Hook方法要把传入参数原封不动地返回来。 2是在目标方法里“调用的方法”上绑定特性,在注入之前再反射一下获取信息,但是对于系统类的方法就无力。
有些还需要方法调用后才能拿到参数信息,例如System.IO.BinaryReader(byte[],int,int),但不管在哪获取信息,只要这个函数自己不平栈都好说,例如C里面的cdecl调用约定,可惜C#都是自己平栈,真愁人啊,看来要写大量代码才能实现这个看似很简单就能实现的功能
bigbaldy 2016-05-06
  • 打赏
  • 举报
回复
引用 8 楼 u012758945 的回复:
既然都玩到这个份上了,何不再动态一点,根据Hook方法的参数类型动态插入IL代码
说的也是,我现在只是想找找看是否有成熟的东西可以解决这个问题,或者有什么好的思路,如果真没有这种库,就准备自己写一个了,目前还是想确定下技术方向,听听大家的建议
bigbaldy 2016-05-06
  • 打赏
  • 举报
回复
引用 9 楼 shingoscar 的回复:
我很好奇,既然你不打算转换类型,说明你已经明确知道堆栈上的数据类型,否则即便你用dup,要怎么调用MyHook(string)呢?
首先我知道我要hook的目标方法,所以我的hook函数的参数类型和目标方法是一样的,这样如果堆栈可以复制,我直接在目标方法调用的前一条指令处调用我的hook函数即可
Lee_Y_K 2016-05-06
  • 打赏
  • 举报
回复
至于你的"插桩"技术我不是很理解,如果是在C#代码里操作的话, 能不能在“插桩”之前获取 MethodInfo.GetMethodBody().MaxStackSize 属性,然后偏移 Stloc 的索引来存储变量?
Lee_Y_K 2016-05-06
  • 打赏
  • 举报
回复
引用 9 楼 shingoscar 的回复:
[quote=引用 5 楼 bigbaldy 的回复:] [quote=引用 3 楼 u012758945 的回复:] 至于你的"插桩"技术我不是很理解,如果是在C#代码里操作的话, 能不能在“插桩”之前获取 MethodInfo.GetMethodBody().MaxStackSize 属性,然后偏移 Stloc 的索引来存储变量?
maxstacksize属性可以拿到,但用stloc保存有个问题,就是类型,局部变量是有类型的,就算用object那也得加转换指令,我想的最简单的办法就是复制堆栈,可惜,IL没有这样的指令[/quote] 我很好奇,既然你不打算转换类型,说明你已经明确知道堆栈上的数据类型,否则即便你用dup,要怎么调用MyHook(string)呢?[/quote] 楼主目前应该还处于测试可行性的阶段,按照楼主的方式应该是想在目标方法里的“调用方法之前”拦截,那就要获取所有的IL指令来分析每个调用的方法。 假设可以取到调用的方法,那拿到参数的信息就没问题了。 在假设成立的前提下,如果要通过程序来执行动态注入,我目前想到的只有两种方法, 1是固定Hook方法,在Hook方法里再进行动态调用,但是Hook方法要把传入参数原封不动地返回来。 2是在目标方法里“调用的方法”上绑定特性,在注入之前再反射一下获取信息,但是对于系统类的方法就无力。
Poopaye 2016-05-06
  • 打赏
  • 举报
回复
引用 5 楼 bigbaldy 的回复:
[quote=引用 3 楼 u012758945 的回复:] 至于你的"插桩"技术我不是很理解,如果是在C#代码里操作的话, 能不能在“插桩”之前获取 MethodInfo.GetMethodBody().MaxStackSize 属性,然后偏移 Stloc 的索引来存储变量?
maxstacksize属性可以拿到,但用stloc保存有个问题,就是类型,局部变量是有类型的,就算用object那也得加转换指令,我想的最简单的办法就是复制堆栈,可惜,IL没有这样的指令[/quote] 我很好奇,既然你不打算转换类型,说明你已经明确知道堆栈上的数据类型,否则即便你用dup,要怎么调用MyHook(string)呢?
Lee_Y_K 2016-05-06
  • 打赏
  • 举报
回复
引用 7 楼 bigbaldy 的回复:
[quote=引用 6 楼 u012758945 的回复:] 那我帮不到你了。。。问一下,你的Hook方法能不能返回object[] 类型,把Hook的参数次序填入,退出方法后按次序把参数unbox 后填入计算堆栈中
非常感谢你的帮助。这个方法是可行,但是针对不同的函数,都需要插入不同的代码,有可能类型并不是int转object,很可能是类A转object,然后还得object转A入栈,这样针对不同的函数参数类型就得插入不同的代码[/quote] 既然都玩到这个份上了,何不再动态一点,根据Hook方法的参数类型动态插入IL代码
bigbaldy 2016-05-06
  • 打赏
  • 举报
回复
引用 6 楼 u012758945 的回复:
那我帮不到你了。。。问一下,你的Hook方法能不能返回object[] 类型,把Hook的参数次序填入,退出方法后按次序把参数unbox 后填入计算堆栈中
非常感谢你的帮助。这个方法是可行,但是针对不同的函数,都需要插入不同的代码,有可能类型并不是int转object,很可能是类A转object,然后还得object转A入栈,这样针对不同的函数参数类型就得插入不同的代码
Lee_Y_K 2016-05-06
  • 打赏
  • 举报
回复
引用 5 楼 bigbaldy 的回复:
[quote=引用 3 楼 u012758945 的回复:] 至于你的"插桩"技术我不是很理解,如果是在C#代码里操作的话, 能不能在“插桩”之前获取 MethodInfo.GetMethodBody().MaxStackSize 属性,然后偏移 Stloc 的索引来存储变量?
maxstacksize属性可以拿到,但用stloc保存有个问题,就是类型,局部变量是有类型的,就算用object那也得加转换指令,我想的最简单的办法就是复制堆栈,可惜,IL没有这样的指令[/quote] 那我帮不到你了。。。问一下,你的Hook方法能不能返回object[] 类型,把Hook的参数次序填入,退出方法后按次序把参数unbox 后填入计算堆栈中
bigbaldy 2016-05-06
  • 打赏
  • 举报
回复
引用 2 楼 shingoscar 的回复:
找到一个看上去很NB的东西
这个之前看过,是动态注入的,偏底层,hook了jit的过程, 不过我自己试了他的代码没有成功,而且将来如果真用这个插桩的话,所有桩点判断都得用C写,这样会麻烦很多
bigbaldy 2016-05-06
  • 打赏
  • 举报
回复
引用 3 楼 u012758945 的回复:
至于你的"插桩"技术我不是很理解,如果是在C#代码里操作的话, 能不能在“插桩”之前获取 MethodInfo.GetMethodBody().MaxStackSize 属性,然后偏移 Stloc 的索引来存储变量?
maxstacksize属性可以拿到,但用stloc保存有个问题,就是类型,局部变量是有类型的,就算用object那也得加转换指令,我想的最简单的办法就是复制堆栈,可惜,IL没有这样的指令
Poopaye 2016-05-05
  • 打赏
  • 举报
回复
bigbaldy 2016-05-05
  • 打赏
  • 举报
回复
有没有什么办法能在Hook函数中获取调用函数的堆栈,这样我的Hook函数声明成无参函数就可以解决,例如VC中使用ESP+X来回溯堆栈,C#中是否也可以?是否有ESP指针类的东西?或者说可以修改调用约定,由调用者平栈

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧