cocos creator2.x 项目逆向之cc._PrefabInfo

特别的手段:

const newDescriptor = {
  get() {
      return this._fileId || '';
  },
  set(newValue) {
      if (newValue === '64jAJXypRFQ7maRwNeIp5W') {
          debugger;
      }
      this._fileId = newValue;
  }
};

Object.defineProperty(cc._PrefabInfo.prototype, 'fileId', newDescriptor);

 

通过特别方式查到了cc.PrefabInfo反序列的地方:

(function anonymous(s, o, d, k) {
    var prop;
    prop = d.root;
    if (typeof prop !== "undefined") {
        if (prop) {
            s._deserializeObjField(o, prop, "root");
        } else
            o.root = null;
    }
    prop = d.asset;
    if (typeof prop !== "undefined") {
        if (prop) {
            s._deserializeObjField(o, prop, "asset");
        } else
            o.asset = null;
    }
    prop = d.fileId;
    if (typeof prop !== "undefined") {
        o.fileId = prop;
    }
    prop = d.sync;
    if (typeof prop !== "undefined") {
        o.sync = prop;
    }
}
)

将构建后的prefab还原成最初项目工程中prefab文件,主要是寻找asset属性, 这个asset对象实际存放的是预制体引用信息。

 属性赋值的地方:

 这个就是关键所在,如果是uuid,直接给了result(Details对象),  如果是其他属性会obj[propName].    

这个就是查看某个cc.Prefab对象里_prefab属性里, cc._prefabInfo asset属性为空的原因。 这个obj就是cc.PrefabInfo对象

我切换到了release模式:

 asset字段属性是3, 但是索引中不存在3

发现了新的线索:

prefab 的引用信息其实存在:

 只不过没有进行asset属性赋值。

尝试改造:

function asAsset(uuid, obj) {
    if (obj && obj instanceof cc.Asset) {
        obj._uuid = uuid;
        return obj;
    }
    obj = new cc.Asset();
    obj._uuid = uuid;
    return obj;
};

cc.deserialize.Details.prototype.assignAssetsBy = function (getter) {
    for (var i = 0, len = (this.uuidList).length; i < len; i++) {
        var obj = (this.uuidObjList)[i];
        var prop = (this.uuidPropList)[i];
        var uuid = (this.uuidList)[i];
        obj[prop] = getter(uuid, prop);
    }
};

改造之后,发现没有生效,一顿查,找到了罪魁祸首:

 

虽然有引用信息,但是又被pop了, 导致引用的uuid丢失,又又又扑了空。

先临时让641行uuid的判断失效, uuid=null

调试了一天, 发现这个引用信息不会写入到json中, 所以不可能百分百还原, 不过这个信息丢失没有什么大影响

posted @ 2025-04-02 09:47  浪浪辛  阅读(347)  评论(3)    收藏  举报