欢迎光临散文网 会员登陆 & 注册

研究笔记

2022-09-19 22:55 作者:スレーブ_スレイヤー  | 我要投稿

是的,我遇到了一个人生终极难题:

我把DLL注入到某个Unity游戏里,DLL内部的逻辑是去获取某个对象的地址(利用函数指针调用某个GET函数),因为这个游戏是C#写的,所以这个地址对应的是一个C#对象,但因为编译方式是C++,所以最终运行的时候到底是怎么样,我也不知道,大概还是按C++的来,因为不存在.NET虚拟机(大概吧,不懂,到底最后运行的时候有没有一个类似JVM的东西回收内存呢?感觉是没有的


因为它是一个C#对象,C++里面没有等价的对象,因为存在一些逻辑复杂的函数,我也模拟不出这样一个对象,所以我开启了Cli功能,它允许在C++代码里使用C#。

然后我直接把这个对象所在的DLL导入进来了,这样我就可以像正向开发一样,做逆向才能做到的事(函数指针爬


此时变故发生了,我把函数指针的返回值类型指定为了C#的引用类型,结果函数指针失效了。


本来就只是返回一个64位内存地址,鬼知道C#的这个类型又干了什么。于是我又试了Cli自带的内部指针功能,但是它不支持复杂对象,就算我把地址先存起来,再转成内部指针,也是没用的。


此时我的心态发生了一点变化,只好打下这些字来稳定我的血压。

首先,C#是一个抄袭JAVA的产物,JAVA的特色就是不让程序员操作内存,C#自然也一样。

因为存在垃圾回收机制,如果我把某个地址赋值给了C#的引用,此时垃圾回收系统是感知不到的,也就是说这个地址就不归垃圾回收管了,这是.NET虚拟机最不能允许的事,也是C#诞生的原因,它就是为了不让你操作内存的,所以把一个存在于.NET虚拟机外部的地址赋值给一个C#的引用,这是不可能的。


所以没必要纠结了,乖乖用函数指针把。同时,歌颂C++的伟大吧,这样一对比就能发现C++给了程序员多大的自由,虽然这种自由多数时候只是增加出错概率,但是......

但是在这种时候,除了C++真的没有什么语言可以完美实现我想要的功能了。


另外,il2cpp编译完肯定就不运行在Mono或者CLR虚拟机上了,都已经编译成机器码了还有必要纠结吗。所以反向变回C#对象,本身就挺无厘头的,C#的代码,编译成il中间码,再编译回C++,再编译成机器码,然后再在运行时,把这个机器码创建的对象反向变回C#里的,存在于CLR虚拟机上的对象,多少有点......emmmm,就很离谱,不太现实。


所以说,可以把Cli关了,该怎么调用怎么调用吧。


而且想了下,我都已经知道C#里的类的结构了,具体实现也有现成的汇编代码,理论上用已有的这些信息逆出一个等价的C++类,应该不是难事吧,理论上。

唯一麻烦的点是,x64不支持内联汇编,单独建文件会显得极度臃肿。


总之,求求你别再碰C#了。不过C#写UI是真的香,梦回远古时期安卓各种xml(Winform爬,Qt爬


研究笔记的评论 (共 条)

分享到微博请遵守国家法律