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

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

  • 相关阅读:
    基于Ubuntu + nextCloud 搭建自己的私人网盘
    基于Ubuntu部署 memcached 服务
    基于Ubuntu搭建Seafile专属网盘
    基于ubuntu搭建 Discuz 论坛
    基于ubuntu搭建 WordPress 个人博客
    基于CentOS 搭建 FTP 文件服务
    搭建 WordPress 个人博客
    Scale-out NAS 和scale-up NAS 系统的优缺点
    鱼缸的启示:Scale-out和Scale-up架构
    整死你个妖精,CDN西游捉妖记!
  • 原文地址:https://www.cnblogs.com/wayland/p/9588587.html
Copyright © 2011-2022 走看看