首页 > 其他分享 >[JS] 一次逆向

[JS] 一次逆向

时间:2024-07-21 12:40:52浏览次数:7  
标签:function 逆向 一次 return ++ JS push length var

开始

此文章为个人学习研究,请勿用于非法用途。

背景是我是小鹤音形用户,常常忘记一个字怎么打,就需要查形;而windows软件的查形太麻烦,网页查询更麻烦,所以我想写脚本,配合我的meow-tool工具快捷的查形。

但是显然,网站的接口是加密的,需要添加sign参数的请求体中;所以首先需要逆向出sign的生成方式。

1、找到sign的生成入口

我们直接搜索sign

image

发现在这里,显然是发fetch请求的地方。

其中,sign = t = x()(e + r),e是密钥fjc_xhup,打断点可以直接看到,r是搜索词,以为例。

直接打断点,开始调试:

image

2、扣代码

进入到x()(e + r)函数中,可以看到,这代码十分眼熟。

image

那么只要扣出u()t.bytesToWords()t.bytesToHex()就行。

  • 先扣出u():

image

image

其中,r,a和t是外部模块的函数,在u中使用了,所以需要一并扣出:

r是n.utf8,a是n.bin.stringToBytes(),我们直接将整个n扣出。

image

在代码中,重命名为oo:

var oo = {
  utf8: {
    stringToBytes: function (e) {
      return oo.bin.stringToBytes(unescape(encodeURIComponent(e)))
    },
    bytesToString: function (e) {
      return decodeURIComponent(escape(oo.bin.bytesToString(e)))
    }
  },
  bin: {
    stringToBytes: function (e) {
      for (var t = [], n = 0; n < e.length; n++)
        t.push(255 & e.charCodeAt(n));
      return t
    },
    bytesToString: function (e) {
      for (var t = [], n = 0; n < e.length; n++)
        t.push(String.fromCharCode(e[n]));
      return t.join("")
    }
  }
};
  • 然后是t.bytesToWords()

image

我们直接将这一段代码扣出:

var t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  , n = {
    rotl: function (e, t) {
      return e << t | e >>> 32 - t
    },
    rotr: function (e, t) {
      return e << 32 - t | e >>> t
    },
    endian: function (e) {
      if (e.constructor == Number)
        return 16711935 & n.rotl(e, 8) | 4278255360 & n.rotl(e, 24);
      for (var t = 0; t < e.length; t++)
        e[t] = n.endian(e[t]);
      return e
    },
    randomBytes: function (e) {
      for (var t = []; e > 0; e--)
        t.push(Math.floor(256 * Math.random()));
      return t
    },
    bytesToWords: function (e) {
      for (var t = [], n = 0, r = 0; n < e.length; n++,
        r += 8)
        t[r >>> 5] |= e[n] << 24 - r % 32;
      return t
    },
    wordsToBytes: function (e) {
      for (var t = [], n = 0; n < 32 * e.length; n += 8)
        t.push(e[n >>> 5] >>> 24 - n % 32 & 255);
      return t
    },
    bytesToHex: function (e) {
      for (var t = [], n = 0; n < e.length; n++)
        t.push((e[n] >>> 4).toString(16)),
          t.push((15 & e[n]).toString(16));
      return t.join("")
    },
    hexToBytes: function (e) {
      for (var t = [], n = 0; n < e.length; n += 2)
        t.push(parseInt(e.substr(n, 2), 16));
      return t
    },
    bytesToBase64: function (e) {
      for (var n = [], r = 0; r < e.length; r += 3)
        for (var o = e[r] << 16 | e[r + 1] << 8 | e[r + 2], a = 0; a < 4; a++)
          8 * r + 6 * a <= 8 * e.length ? n.push(t.charAt(o >>> 6 * (3 - a) & 63)) : n.push("=");
      return n.join("")
    },
    base64ToBytes: function (e) {
      e = e.replace(/[^A-Z0-9+\/]/gi, "");
      for (var n = [], r = 0, o = 0; r < e.length; o = ++r % 4)
        0 != o && n.push((t.indexOf(e.charAt(r - 1)) & Math.pow(2, -2 * o + 8) - 1) << 2 * o | t.indexOf(e.charAt(r)) >>> 6 - 2 * o);
      return n
    }
  };

  • t.bytesToHex()操作一致

结束

到此,其实扣代码已经结束了,关于函数x()(),美化后其实长这样:

fn = function encryptData(data, options) {
    if (data === undefined || data === null) {
        throw new Error("Illegal argument " + data);
    }

    // u 是一个函数用来处理数据转换
    var processedData = u(data, options);
    var bytes = t.wordsToBytes(processedData);
    
    if (options && options.asBytes) {
        return bytes;
    } else if (options && options.asString) {
        // a 是一个对象或模块,用来提供 bytesToString 方法
        return a.bytesToString(bytes);
    } else {
        // t 也是一个对象或模块,用来提供 bytesToHex 方法
        return t.bytesToHex(bytes);
    }

    // 实际 => t.wordsToBytes(data).bytesToHex()
}

而调试发现,实际只是t.wordsToBytes(u(e, undefined)).bytesToHex(),需要的代码已经出来了:

var t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  , n = {
    rotl: function (e, t) {
      return e << t | e >>> 32 - t
    },
    rotr: function (e, t) {
      return e << 32 - t | e >>> t
    },
    endian: function (e) {
      if (e.constructor == Number)
        return 16711935 & n.rotl(e, 8) | 4278255360 & n.rotl(e, 24);
      for (var t = 0; t < e.length; t++)
        e[t] = n.endian(e[t]);
      return e
    },
    randomBytes: function (e) {
      for (var t = []; e > 0; e--)
        t.push(Math.floor(256 * Math.random()));
      return t
    },
    bytesToWords: function (e) {
      for (var t = [], n = 0, r = 0; n < e.length; n++,
        r += 8)
        t[r >>> 5] |= e[n] << 24 - r % 32;
      return t
    },
    wordsToBytes: function (e) {
      for (var t = [], n = 0; n < 32 * e.length; n += 8)
        t.push(e[n >>> 5] >>> 24 - n % 32 & 255);
      return t
    },
    bytesToHex: function (e) {
      for (var t = [], n = 0; n < e.length; n++)
        t.push((e[n] >>> 4).toString(16)),
          t.push((15 & e[n]).toString(16));
      return t.join("")
    },
    hexToBytes: function (e) {
      for (var t = [], n = 0; n < e.length; n += 2)
        t.push(parseInt(e.substr(n, 2), 16));
      return t
    },
    bytesToBase64: function (e) {
      for (var n = [], r = 0; r < e.length; r += 3)
        for (var o = e[r] << 16 | e[r + 1] << 8 | e[r + 2], a = 0; a < 4; a++)
          8 * r + 6 * a <= 8 * e.length ? n.push(t.charAt(o >>> 6 * (3 - a) & 63)) : n.push("=");
      return n.join("")
    },
    base64ToBytes: function (e) {
      e = e.replace(/[^A-Z0-9+\/]/gi, "");
      for (var n = [], r = 0, o = 0; r < e.length; o = ++r % 4)
        0 != o && n.push((t.indexOf(e.charAt(r - 1)) & Math.pow(2, -2 * o + 8) - 1) << 2 * o | t.indexOf(e.charAt(r)) >>> 6 - 2 * o);
      return n
    }
  };


var oo = {
  utf8: {
    stringToBytes: function (e) {
      return oo.bin.stringToBytes(unescape(encodeURIComponent(e)))
    },
    bytesToString: function (e) {
      return decodeURIComponent(escape(oo.bin.bytesToString(e)))
    }
  },
  bin: {
    stringToBytes: function (e) {
      for (var t = [], n = 0; n < e.length; n++)
        t.push(255 & e.charCodeAt(n));
      return t
    },
    bytesToString: function (e) {
      for (var t = [], n = 0; n < e.length; n++)
        t.push(String.fromCharCode(e[n]));
      return t.join("")
    }
  }
};

var r = oo.utf8, a = oo.bin;

var tt = n

var u = function (e, n) {

  e.constructor == String ? e = n && "binary" === n.encoding ? a.stringToBytes(e) : r.stringToBytes(e) : o(e) ? e = Array.prototype.slice.call(e, 0) : Array.isArray(e) || e.constructor === Uint8Array || (e = e.toString());
  for (var i = tt.bytesToWords(e), l = 8 * e.length, f = 1732584193, c = -271733879, s = -1732584194, d = 271733878, p = 0; p < i.length; p++)
    i[p] = 16711935 & (i[p] << 8 | i[p] >>> 24) | 4278255360 & (i[p] << 24 | i[p] >>> 8);
  i[l >>> 5] |= 128 << l % 32,
    i[14 + (l + 64 >>> 9 << 4)] = l;
  var v = u._ff
    , h = u._gg
    , y = u._hh
    , m = u._ii;
  for (p = 0; p < i.length; p += 16) {
    var g = f
      , b = c
      , _ = s
      , w = d;
    f = v(f, c, s, d, i[p + 0], 7, -680876936),
      d = v(d, f, c, s, i[p + 1], 12, -389564586),
      s = v(s, d, f, c, i[p + 2], 17, 606105819),
      c = v(c, s, d, f, i[p + 3], 22, -1044525330),
      f = v(f, c, s, d, i[p + 4], 7, -176418897),
      d = v(d, f, c, s, i[p + 5], 12, 1200080426),
      s = v(s, d, f, c, i[p + 6], 17, -1473231341),
      c = v(c, s, d, f, i[p + 7], 22, -45705983),
      f = v(f, c, s, d, i[p + 8], 7, 1770035416),
      d = v(d, f, c, s, i[p + 9], 12, -1958414417),
      s = v(s, d, f, c, i[p + 10], 17, -42063),
      c = v(c, s, d, f, i[p + 11], 22, -1990404162),
      f = v(f, c, s, d, i[p + 12], 7, 1804603682),
      d = v(d, f, c, s, i[p + 13], 12, -40341101),
      s = v(s, d, f, c, i[p + 14], 17, -1502002290),
      f = h(f, c = v(c, s, d, f, i[p + 15], 22, 1236535329), s, d, i[p + 1], 5, -165796510),
      d = h(d, f, c, s, i[p + 6], 9, -1069501632),
      s = h(s, d, f, c, i[p + 11], 14, 643717713),
      c = h(c, s, d, f, i[p + 0], 20, -373897302),
      f = h(f, c, s, d, i[p + 5], 5, -701558691),
      d = h(d, f, c, s, i[p + 10], 9, 38016083),
      s = h(s, d, f, c, i[p + 15], 14, -660478335),
      c = h(c, s, d, f, i[p + 4], 20, -405537848),
      f = h(f, c, s, d, i[p + 9], 5, 568446438),
      d = h(d, f, c, s, i[p + 14], 9, -1019803690),
      s = h(s, d, f, c, i[p + 3], 14, -187363961),
      c = h(c, s, d, f, i[p + 8], 20, 1163531501),
      f = h(f, c, s, d, i[p + 13], 5, -1444681467),
      d = h(d, f, c, s, i[p + 2], 9, -51403784),
      s = h(s, d, f, c, i[p + 7], 14, 1735328473),
      f = y(f, c = h(c, s, d, f, i[p + 12], 20, -1926607734), s, d, i[p + 5], 4, -378558),
      d = y(d, f, c, s, i[p + 8], 11, -2022574463),
      s = y(s, d, f, c, i[p + 11], 16, 1839030562),
      c = y(c, s, d, f, i[p + 14], 23, -35309556),
      f = y(f, c, s, d, i[p + 1], 4, -1530992060),
      d = y(d, f, c, s, i[p + 4], 11, 1272893353),
      s = y(s, d, f, c, i[p + 7], 16, -155497632),
      c = y(c, s, d, f, i[p + 10], 23, -1094730640),
      f = y(f, c, s, d, i[p + 13], 4, 681279174),
      d = y(d, f, c, s, i[p + 0], 11, -358537222),
      s = y(s, d, f, c, i[p + 3], 16, -722521979),
      c = y(c, s, d, f, i[p + 6], 23, 76029189),
      f = y(f, c, s, d, i[p + 9], 4, -640364487),
      d = y(d, f, c, s, i[p + 12], 11, -421815835),
      s = y(s, d, f, c, i[p + 15], 16, 530742520),
      f = m(f, c = y(c, s, d, f, i[p + 2], 23, -995338651), s, d, i[p + 0], 6, -198630844),
      d = m(d, f, c, s, i[p + 7], 10, 1126891415),
      s = m(s, d, f, c, i[p + 14], 15, -1416354905),
      c = m(c, s, d, f, i[p + 5], 21, -57434055),
      f = m(f, c, s, d, i[p + 12], 6, 1700485571),
      d = m(d, f, c, s, i[p + 3], 10, -1894986606),
      s = m(s, d, f, c, i[p + 10], 15, -1051523),
      c = m(c, s, d, f, i[p + 1], 21, -2054922799),
      f = m(f, c, s, d, i[p + 8], 6, 1873313359),
      d = m(d, f, c, s, i[p + 15], 10, -30611744),
      s = m(s, d, f, c, i[p + 6], 15, -1560198380),
      c = m(c, s, d, f, i[p + 13], 21, 1309151649),
      f = m(f, c, s, d, i[p + 4], 6, -145523070),
      d = m(d, f, c, s, i[p + 11], 10, -1120210379),
      s = m(s, d, f, c, i[p + 2], 15, 718787259),
      c = m(c, s, d, f, i[p + 9], 21, -343485551),
      f = f + g >>> 0,
      c = c + b >>> 0,
      s = s + _ >>> 0,
      d = d + w >>> 0
  }
  return tt.endian([f, c, s, d])
};



u._ff = function (e, t, n, r, o, a, u) {
  var i = e + (t & n | ~t & r) + (o >>> 0) + u;
  return (i << a | i >>> 32 - a) + t
}

u._gg = function (e, t, n, r, o, a, u) {
  var i = e + (t & r | n & ~r) + (o >>> 0) + u;
  return (i << a | i >>> 32 - a) + t
}

u._hh = function (e, t, n, r, o, a, u) {
  var i = e + (t ^ n ^ r) + (o >>> 0) + u;
  return (i << a | i >>> 32 - a) + t
}

u._ii = function (e, t, n, r, o, a, u) {
  var i = e + (n ^ (t | ~r)) + (o >>> 0) + u;
  return (i << a | i >>> 32 - a) + t
}

u._blocksize = 16, u._digestsize = 16



let res = u('fjc_xhup啊', undefined)

console.log(res);

var rrr = tt.wordsToBytes(res)

console.log(rrr)

console.log(tt.bytesToHex(rrr))

测试情况如下:
image

image

剩下的就是写py脚本,然后ahk命令行调用。

标签:function,逆向,一次,return,++,JS,push,length,var
From: https://www.cnblogs.com/refiz/p/18314355

相关文章

  • mockjs 使用案例
    案例importMock,{Random}from"mockjs";constresData=Mock.mock({ //key中min-max代表随机生成5到10条数组数据 'list|5-10':[{ //value@id可以随机生成id 'id':'@id', 'name':'@name', 'image'......
  • DRF如何反序列化json?
    我使用React作为前端,django作为后端。我使用fetchAPI向服务器发送POST请求。数据通过JSON.stringify()传递。该请求将被Django中的视图拦截,数据可在视图函数的请求参数中获取。至少这是我所理解的。现在,当我访问request.body时,我惊讶地得到了一个字典。......
  • 基于java+ssm+jsp校园饮品奶茶网络销售平台毕业设计项目源码和文档
    前言......
  • 基于java+ssm+jsp新冠病例智能统计与相应预防措施分析系统毕业设计项目源码和文档
    前言......
  • 【D3.js in Action 3 精译_020】2.6 用 D3 设置与修改元素样式 + 名人专访(Nadieh Brem
    当前内容所在位置第一部分D3.js基础知识第一章D3.js简介(已完结)1.1何为D3.js?1.2D3生态系统——入门须知1.3数据可视化最佳实践(上)1.3数据可视化最佳实践(下)1.4本章小结第二章DOM的操作方法(已完结)2.1第一个D3可视化图表2.2环境准备2.3......
  • 如何将 JSON 数据写入文件?
    如何将存储在字典data中的JSON数据写入文件?f=open('data.json','wb')f.write(data)这会给出错误:TypeError:Mustbestringorbuffer,notdict这个错误提示你不能直接将一个字典写入文件,你需要先将它转换为字符串。Python的json库可......
  • eggjs的部署小结
    eggjs的部署小结 eggjs项目部署步骤:1、本地初始化代码mkdiregg-example&&cdegg-examplenpminitegg--type=simplenpmi首先本地初始化代码,并跑起来测试本地没问题。2、项目利用git或者ftp推到服务器上面注意:此过程不必讲node_modules文件夹传上去。3、线上......
  • 将 Met Office 数据点 JSON 读入 Panda
    我正在使用MetOfficeDatapointAPI下载JSON格式的英国天气数据。然后我想将该JSON文件读入pandasDataFrame。JSON文件的格式如图所示{"SiteRep":{"Wx":{"Param":[{"name":"FDm","units":"C","$":"FeelsLikeDa......
  • js删除网页中图片width 和 height
    js删除网页中图片width和height更新日期:2024-06-1423:14:36来源:网络js删除网页中图片width和height一段代码轻松搞定适用于:电脑端网页带图片属性导致移动网页显示错位/错误备注:需搭配jquery.min.js(注!jquery-2.0以上版本不再支持IE6/7/8)并不是最新的版本就......
  • 在pyspark(python)中将json字符串扩展到多列
    我需要将Json对象(b列)扩展到多列。从此表中,A列B列id1[{a:1,b:'letter1'}]id2[{a:1,b:'letter2',c:3,d:4}]对......