[hook.js]通用Javascript函数钩子及其他

2019-03-02 23:43|来源: 网路

 

2013.02.16<:article id=post_content>

最近看Dom Xss检测相关的Paper,涉及到Hook Javascript函数,网上翻了一下,貌似没有什么通用的函数钩子脚本,自己用就自己写一个吧。最后有代码地址,前面写下mind storm的过程。
最经典且简单的Javascript函数钩子的写法应该是下面这样了:

var _alert = alert;
window.alert =function(s){
       console.log("Hooked!");
        _alert(s);}

不过这种Hook方式跟闹着玩儿似的,用到实际生产上通用性不好,效率也不高。

国内比较早看到的介绍Javascript函数劫持的文章应该是安全焦点上luoluo写的《浅谈javascript函数劫持》,用Javascript函数钩子实现了一个简单的内联代码调试器。后来看到了大风在08年搞了一个anehta的攻击平台,其中有一段能够hook任意Javascript函数的代码,看了下有一些问题,不过毕竟钩子只是anehta其中一个功能。这里贴出部分代码,有兴趣可以到这里看完整版:

 

hook:function(funcNameHooked,RealFuncAfterHooked, hookFunc){try{
                  setTimeout(function(){//alert("hook before: "+window[funcNameHooked]);// 保存原函数
                          window[RealFuncAfterHooked]= window[funcNameHooked];//window[funcNameHooked] = window[hookFunc];// 参数个数可以根据需要进行调整
                          window[funcNameHooked]=function(param1,param2,param3,param4,param5,param6,param7){// 劫持参数var newParam =newArray();// 先执行注入的函数; 需要返回被劫持后的参数,作为新参数传入原函数
                                  newParam = window[hookFunc](param1,param2, param3, param4, param5, param6, param7)//alert("newParam= "+newParam);// 再执行原函数
                                  window[RealFuncAfterHooked](newParam[0], newParam[1], newParam[2], newParam[3], 
                                                              newParam[4], newParam[5], newParam[6]);// 不注入参数,直接执行原函数;                            //window[RealFuncAfterHooked](param1,param2,param3,param4,param5,param6,param7);  }//alert("hook after: "+window[funcNameHooked]);},10);returntrue;}catch(e){returnfalse;}},

 

这段代码固定了被Hook的函数所在对象是window,这样对于自定义对象中的函数及原型对象中的函数(String.prototype)就没办法进行Hook了。而且参数param[1-7]是写死在函数里的,通用性不太好,其实可以用arguments对象来实现变参。
因为要做的是函数钩子,函数又都是Function对象的实例,那么直接给Function.prototype添加hook和unhook函数就可以了。
按照这个思路自己写了一个,简单封装了一下,能够对普通的全局函数(eg:alert),自定义类中的函数(eg:cat.Eat()),以及原型对象中的函数(eg:String.prototype.slice)进行hook。可以防止函数被二次hook而导致的callback in callback。代码不长这里就贴出来了,也可以到github上去看,有测试样例和详细的参数说明。

functionHooks(){return{
initEnv:function(){Function.prototype.hook =function(realFunc,hookFunc,context,funcName){var _context =null;//函数上下文var _funcName =null;//函数名

		_context = context || window;
		_funcName = funcName || getFuncName(this);
		_context[realFunc]=this;if(_context[_funcName].prototype && _context[_funcName].prototype.isHooked){
			console.log("Already has been hooked,unhook first");returnfalse;}function getFuncName (fn){// 获取函数名var strFunc = fn.toString();var _regex =/function\s+(\w+)\s*\(/;var patten = strFunc.match(_regex);if(patten){return patten[1];};return'';}try{eval('_context[_funcName] = function '+_funcName+'(){\n'+'var args = Array.prototype.slice.call(arguments,0);\n'+'var obj = this;\n'+'hookFunc.apply(obj,args)\n'+'return _context[realFunc].apply(obj,args);\n'+'};');
			_context[_funcName].prototype.isHooked =true;returntrue;}catch(e){
			console.log("Hook failed,check the params.");returnfalse;}}Function.prototype.unhook =function(realFunc,funcName,context){var _context =null;var _funcName =null;
		_context = context || window;
		_funcName = funcName;if(!_context[_funcName].prototype.isHooked){
			console.log("No function is hooked on");returnfalse;}
		_context[_funcName]= _context[realFunc];delete _context[realFunc];returntrue;}},
cleanEnv:function(){if(Function.prototype.hasOwnProperty("hook")){deleteFunction.prototype.hook;}if(Function.prototype.hasOwnProperty("unhook")){deleteFunction.prototype.unhook;}returntrue;}};}


转自:http://www.cnblogs.com/sideny/p/3347568

相关问答

更多
  • Module_invoke_all()是创建自己的钩子的票据: 请参阅API: http://api.drupal.org/api/drupal/includes--module.inc/function/module_invoke_all 然后看看这个伟大的写作: http://web.archive.org/web/20101227170201/http://himerus.com/blog/himerus/creating-hooks-your-drupal-modules (编辑:在http://h ...
  • 我认为问题是关于Cucumber.js 1.3x,这是相当古老的。 在Cucumber.js 3.x中,没有AfterStep钩子,相反,有一个名为“setDefinitionFunctionWrapper”的函数,它可以包装一个步骤定义,你有机会得到步骤定义返回结果并操纵它。 这是关于setDefinitionFunctionWrapper的文档 I think the question is about Cucumber.js 1.3x, which is pretty old. In Cucumber ...
  • 我唯一想到的是使用信号事件。 http://nodejs.org/docs/v0.3.1/api/process.html#signal_Events The only thing that comes to my mind is using signal events. http://nodejs.org/docs/v0.3.1/api/process.html#signal_Events
  • 发生这种情况是因为发布状态是发布前的draft 。 您可以在通知方法中创建一个条件来检查帖子的状态,如下所示: add_action('publish_news', 'notification'); function notification($post){ global $post; if($post->post_status == 'draft'){ //do something here } } 只有在发布帖子时,这才会触发您想要做的事情。 That is happening ...
  • 我从来没有听说过用于挂钩COM对象函数的API挂钩。 COM对象的成员函数并没有真正的不同,如果你坚持通常的挂钩准则,它实际上可以很好地挂钩。 几年前,我不得不挂钩专有CRM解决方案的COM组件以将其连接到数据库服务器。 该应用程序运行良好,并且运行稳定多年。 I've never heard of API hooking used to hook COM object functions. Member functions of COM Objects are not really that differ ...
  • 如果您使用的是babel,则可以在babel配置中添加babel-plugin-module-resolver 。 一个Babel插件,用于在使用Babel编译代码时为模块添加新的解析器。 此插件允许您添加包含模块的新“根”目录。 它还允许您为目录,特定文件甚至其他npm模块设置自定义别名。 模块解析器可能会与webpack2模块处理冲突,因此您只想将其限制为测试: .babelrc示例: "env": { "test": { "plugins": [ ["modul ...
  • 您需要将HHOOK变量存储在全局内存中。 不要将它声明为调用SetWindowsHookEx()的任何函数的局部变量。 编辑 :这是一个基于类的32位CPU示例: class THookKeyboardLL { private: HHOOK hHook; void *pProxy; static LRESULT CALLBACK ProxyStub(THookKeyboardLL *This, int nCode, WPARAM wParam, LPARAM lParam); ...
  • 你可以重写jquery的css函数来实现这个目的。 你可能需要这个: jQuery.fn是什么意思? function backup($dom) { //console.log("backup dom:", $dom); $("h3").after($dom); } var fn = { css: $.fn.css }; $.fn.css = function() { backup(this.clone()); return fn.css.apply(this, arg ...
  • 版本0.8.2添加了一个特殊的_uihooks功能 添加初步API,用于在Blaze打算插入,移动或删除DOM元素时注册要运行的挂钩。 例如,您可以使用这些挂钩在插入,移动或删除节点时为节点设置动画。 要使用它们,可以在容器DOM元素上设置_uihooks属性。 _uihooks是一个对象,可以包含以下三个属性的任何子集: insertElement:function(node,next):当Blaze打算在元素next之前插入DOM元素节点时调用 moveElement:function(node,nex ...
  • 要阅读有关钩子文档的信息,请参阅http://codex.wordpress.org/Plugin_API/Filter_Reference和http://codex.wordpress.org/Plugin_API/Action_Reference 。 这两个站点将告诉您在调用钩子(动作或过滤器)时wordpress传递的参数的数量和类型。 或者您可以查看wordpress源本身。 如果您使用的是像WebStorm这样的IDE,那么您可以执行Edit-> Find-> Find in Path并搜索钩子名 ...