【问题标题】:Reverse-engineer a Javascript object?对 Javascript 对象进行逆向工程?
【发布时间】:2011-02-23 06:45:35
【问题描述】:

我有一个 Javascript 对象,我想传入更多参数,但文档不存在。我唯一的选择似乎是对 Javascript 对象进行逆向工程,看看我可以传入哪些参数和值。

例如,我想查看对象是否有“缩放”参数,以及我可以将哪些值传递给“mapType”参数:

<script type="text/javascript" src="http://maps.google.com/maps?oe=utf-8&amp;file=api&amp;v=2&amp;key=your-gmap-key"></script>
<script type="text/javascript" src="https://share.findmespot.com/spot-widget/js/SpotMain.js"></script>
<script type="text/javascript">
 var widget = new Spot.Ui.LiveWidget({ renderTo: "spot-live-widget",
   feeds: [ "0Wl3diTJcqqvncI6NNsoqJV5ygrFtQfBB" ],
   height: 400,
   width: 500,
   mapType: "physical"
 });
</script>
<div id="spot-live-widget"/>

关于如何做到这一点的任何想法?

【问题讨论】:

  • 我不确定是否有标准的方法来执行此操作。由于没有预先声明属性,因此您必须能够弄清楚正在访问的内容......代码是否可读?

标签: javascript debugging object reverse-engineering


【解决方案1】:

嗯...你可以看看源...

您的代码指向https://share.findmespot.com/spot-widget/js/SpotMain.js 这导致https://share.findmespot.com/spot-widget/js/Spot.js,您使用http://jsbeautifier.org/ 解压缩它,这表明不,它不能在其构造函数中采用“缩放”参数,但它确实有一个setZoomAndCenter 方法

setZoomAndCenter: function (C) {
    var B = new GLatLngBounds;
    for (var A = 0; A < C.length; A++) {
        B.extend(C[A].getPoint())
    }
    this._map.setZoom(this._map.getBoundsZoomLevel(B));
    this._map.setCenter(B.getCenter())
},

从这里我们可以看到它有一个'private'成员_map,它有一个setZoom方法。

这有帮助吗?

更新

上述方法实际上是Spot.Ui.MapRenderer的成员,而不是LiveWidget。

MapRenderer 由 LiveWidget 内部使用,但未公开...

【讨论】:

  • 哇,它不仅有帮助!这个棒极了!!它让我经历了很多......但在尝试时卡在一个未定义的函数上:widget.setZoomAndCenter(new GLatLng(0, 0), 6);我尝试正确吗?
  • 我对这个小部件一无所知,除了我看了一眼。哪个函数未定义? "setZoomAndCenter" in widget 返回什么(如果方法存在则为真)?
【解决方案2】:

Function#toString

如果您调用函数实例的toString 方法,大多数Javascript 实现都会返回函数的源代码:

function foo() {
    return a;
}
alert(foo.toString()); // Alerts "function foo() { return a; }"

这是非标准行为,但得到广泛支持;您可能会发现它对逆向工程非常有用。在Spot.Ui.LiveWidget 函数上调用它可能很有趣,在绑定到它返回的对象的属性的函数上也是如此。这让我们...

编辑当然,如果unobfuscated source is available(对肖恩大喊),你就不需要这个了……

循环遍历属性:for..in

如果它真的是一个 Javascript 对象,你可以这样做来找出它有什么属性:

var name, own;

for (name in obj) {
    own = obj.hasOwnProperty(name);
    alert(name + " (" + (own ? "own" : "inherited") + ")");
}

这会告诉你它的(可枚举的)属性的名称,以及这些是实例本身的属性,还是它的原型对象。

for..in 示例

function Thingy() {
}
Thingy.prototype.alpha = "a";

var t = new Thingy();
t.beta = "2";

上面的循环会显示:

 alpha(继承)
    测试版(自己的)

(排名不分先后)

更多信息

可枚举与不可枚举属性

请注意,并非所有属性都是“可枚举的”。例如,所有(或几乎所有)由规范指定的对象(如ArrayString 等)的属性都是不可枚举的。但直到最近,这只是 Javascript 实现本身可以完成的事情;没有将您的 自己的 属性标记为不可枚举的机制。新的第 5 版规范提供了一种方法,但它并未得到广泛支持或使用(目前)。

不存在的属性

您查询的对象可能会根据属性是否存在而改变其行为;在这种情况下,您无法知道,因为不存在的属性不会出现在 for..in 循环中(与存在但具有 undefined 值的属性不同,它确实存在)。例如:

function doSomething(options) {
    if (options.foo) {
        // There's a `foo` and it has a value; do something with it
}

options 上的foo 属性可能根本不存在,因此这种逆向工程不会显示代码对它做了什么。

警告

不要在主机对象(例如 DOM 节点)上尝试上面的 for..in 循环。它可能在某些实现中起作用,但通常不会,并且在某些情况下(IE6)它会使浏览器崩溃。不过,它对于 Javascript 对象是完全安全的。

【讨论】:

    【解决方案3】:

    无法保证配置参数中列出的属性将与结果对象的属性相匹配,或者即使它们是,它们也会被复制到结果对象中。

    找出答案的唯一方法是查看 LiveWidget“构造函数”函数中的代码,并查看它期望从配置参数中获得哪些属性。

    【讨论】:

      猜你喜欢
      • 2016-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 1970-01-01
      • 2013-05-30
      • 2018-08-26
      • 2014-02-22
      相关资源
      最近更新 更多