• 简谈对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对其进行静态织入,总之省事就好了。

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

  • 相关阅读:
    使用bink播放视频
    Vertex Shader And Pixel Shader
    Points Versus Pixels in Cocos2D
    ogre_机器人在10个位置循环走动
    简单播放声音PlaySound
    Vertex Shader 入门代码
    加载地形的类
    Animation Cache in Cocos2diphone v2.0.0
    [转]Rad Video Tools使用手册
    CSound类源文件
  • 原文地址:https://www.cnblogs.com/wayland/p/9588587.html
Copyright © 2020-2023  润新知