zoukankan      html  css  js  c++  java
  • 简谈对ldind.i*的理解

    首次见到ldind.i*的实际用法,缘于一个准备偷懒的巧合。
    因为项目启用了开发经验不是那么丰富的技术,所以有些内容经验需要进行一些“理论指导/培训和知识迁移”。
    公司之前的项目多采用单独字段存储(单机游戏存储在本地)及JsonDotNet(即NewtonJson,弱网游,存档上传服务器)序列化存储的方式,而项目中采用了ProtoBuff的方式,因此很多时候需要根据插件的调整而修改内存加密的“适配”方案,鉴于一贯的偷懒原则,所以很随意大胆的就考虑是否可以直接尝试修改内置的数据类型(eg:int32,在mscorlib.dll中)。。。
    直接到引擎安装目录下,找到对应文件并将其拖入我们的小工具ILSpy打开(不同版本的U3D引擎使用的版本可能不同),可以看到如下的命名空间结构:

    基本的数据类型就在System下,如图:

    分别切成C#及IL的方式查看下源码(以下均以常用的int类型为例,可以直接在线看源码: https://referencesource.microsoft.com/#mscorlib/system/int32.cs):

    这里选取了CompareTo函数为例,对应的IL代码为:

    看到这里第一反应是奇怪,这就不得不先提一下class/struct类型的内存结构及ldind.i*的解释:

    通过msdn(OpCodes.Ldind_I*系列字段,https://msdn.microsoft.com/zh-cn/library/azure/system.reflection.emit.opcodes.ldind_i(v=vs.100).aspx?cs-save-lang=1&cs-lang=vb)及wiki,具体释义及过程如图:

    而作为int类型的第一个字段m_value,该地段的地址即为int结构的地址,可以参见下面的小示例:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.InteropServices;
    
    class Program
    {
    	static unsafe void Main(string[] args)
    	{
    		StructTest tStructTest = new StructTest();
    		tStructTest.A = 100;
    		Console.WriteLine("0x{0:x}", (int)&tStructTest);
    		Console.WriteLine("0x{0:x}", (int)&tStructTest.A);
    	}
    }
    
    public struct StructTest
    {
    	public int A;
    };
    

      因此才会出现在ILSpy中的反编译结果显示为直接将this与参数value进行比较的情形。

    分析到这里就告一段落,接下来的偷懒可以尝试直接下载源码重新编译mscorlib.dll的形式进行测试,亦或者使用mono.cecil对其进行静态织入,总之省事就好了。

    之后有时间再来进行底层基础类型的修改测试了。

  • 相关阅读:
    HDU4366 Successor 线段树+预处理
    POJ2823 Sliding Window 单调队列
    HDU寻找最大值 递推求连续区间
    UVA846 Steps 二分查找
    HDU3415 Max Sum of MaxKsubsequence 单调队列
    HDU时间挑战 树状数组
    UVA10168 Summation of Four Primes 哥德巴赫猜想
    UESTC我要长高 DP优化
    HDUChess 递推
    HDU4362 Dragon Ball DP+优化
  • 原文地址:https://www.cnblogs.com/wayland/p/9588587.html
Copyright © 2011-2022 走看看