- 添加新的Hook点
- Java版本
- 添加hook点
- 添加检测类型
- 构造参数并进入checker
- PHP 版本
- 新增hook点
- 新增hook点
- Java版本
添加新的Hook点
Java版本
添加hook点
根据自己的hook点在com.baidu.openrasp.hook包中添加一个继承自AbstractClassHook的类,并实现getType和isClassMatched两个方法进行hook点的匹配,并在hookMethod方法中的内部类的onMethodEnte方法和onMethodExit方法进行hook点前后的逻辑插入,具体代码如下:
package com.baidu.openrasp.hook;import com.baidu.openrasp.HookHandler;import javassist.CannotCompileException;import javassist.CtClass;import javassist.NotFoundException;import java.io.IOException;/*** 自定义hook点继承自AbstractClassHook*/public class MyHook extends AbstractClassHook {/*** 返回自定义的hook点类型名称*/@Overridepublic String getType() {return "string_replace";}@Overrideprotected void hookMethod(CtClass ctClass) throws IOException, CannotCompileException, NotFoundException {/** 获取要插入函数开始的代码* 参数 "$0,$1,$2" 表示获取带插入函数的 this,第一个参数以及第二个参数* 然后用获取的参数调用HookHandler.checkStringReplaceEnter这个静态方法* 最后三个参数代表HookHandler.checkStringReplaceEnter方法的参数类型*/String srcBefore = getInvokeStaticSrc(HookHandler.class, "checkStringReplaceEnter","$0,$1,$2", String.class, String.class, String.class);// 在String.replace函数开始的地方,插入刚才获取的代码片段,第三个个参数为函数签名信息insertBefore(ctClass, "replace", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", srcBefore);/** 获取要插入函数结束的代码* 参数 "$_" 代表获取待插入函数的返回值* 最后用获取的内容调用HookHandler.checkStringReplaceExit这个静态方法*/String srcAfter = getInvokeStaticSrc(HookHandler.class, "checkStringReplaceExit", "$_", String.class);/** 在String.replace函数结束的地方,插入刚才获取的代码片段,第三个个参数为函数签名信息* 最后一个参数为true代表在异常退出的地方异常会插入响应的代码段*/insertAfter(ctClass, "replace", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", srcAfter, true);}/*** 匹配需要hook的类名*/@Overridepublic boolean isClassMatched(String className) {return "java.lang.String".equals(className);//该hook点hook的是java.lang.String类}}
将如上实现的hook点加入com.baidu.openrasp.transformer.CustomClassTransformer的构造方法中,实现字节码的转换,代码如下:
public CustomClassTransformer() {hooks = new HashSet<AbstractClassHook>();addHook(new MyHook()); // 将hook点加入transformer}
添加检测类型
在 com.baidu.openrasp.plugin.checker.CheckParameter 中添加相应的检测类型
public enum Type {// 添加相应的检测类型,checker使用JsChecker代表该hook点的参数使用js插件检测// 除了JsChecker之外还可以根据com.baidu.openrasp.plugin.checker包下面的其他checker进行自定义checker// 第一个参数是检测类型名称,第二个是检测使用的checkerREPLACE("replace", new JsChecker()),String name;Checker checker;Type(String name, Checker checker) {this.name = name;this.checker = checker;}@Overridepublic String toString() {return name;}}
构造参数并进入checker
编写hook点中调用的 HookHandler.checkStringReplaceEnter 和 HookHandler.checkStringReplaceExit 方法,来实现具体的检测逻辑,检测逻辑中可以调用js插件,示例如下:
public static void checkStringReplaceEnter(String str,String regex,String replacement){// 如下是构造参数并进入checker的操作// 构造参数HashMap<String, Object> param = new HashMap<String, Object>();param.put("str",str);param.put("regex", regex);param.put("replacement", replacement);// 进入第三步中设置的checker,第一个参数是检测类型名称,第二个参数是检测参数mapdoCheck(CheckParameter.Type.REPLACE, param);}
参考资料
- Javassist 框架参考文档: javassist
PHP 版本
新增hook点
假设我们要新增hook_class下的hook_function方法,其对应的检测类型为hook_type,则新增HOOK过程如下:
- 在hook文件夹下新建新增hook点对应文件,建议命名方式为
openrasp_hook_class.cc,同时将其添加至config.m4及config.w32 - 引入
openrasp_hook.h,根据业务需求,选择合适的HOOK方式:前置HOOK(PRE_HOOK_FUNCTION_EX),后置HOOK(POST_HOOK_FUNCTION_EX)以及前后同时HOOK(HOOK_FUNCTION_EX),根据选择的HOOK方式合理定义前置处理函数及后置处理函数,形如:
#include "openrasp_hook.h"HOOK_FUNCTION_EX(hook_function, hook_class, hook_type);void pre_hook_class_hook_function_hook_type(OPENRASP_INTERNAL_FUNCTION_PARAMETERS){//do something...}void post_hook_class_hook_function_hook_type(OPENRASP_INTERNAL_FUNCTION_PARAMETERS){//do something...}
