在采集器v1.2.2共享版中使用的是v1.2.4的zengl引擎,对脚本进行了简单的异或加密运算,v1.2.4版的下载地址如下: github项目地址为:https://github.com/zenglong/zengl_l...
wxString gl_version_number = "v1.2.2"; //版本号信息 //脚本加密密钥 wxString gl_encrypt_str = "xingkekn&**&$&^^^#(*@(*#&$&*@&$*0029044*&$*@&$*&$&!!~~!!@))__*#**)#(*#(*(@#BUBUWEBudru!<!`ss`x)&idmmn!vnsme&-2-00/54-b-#i`i`!doe#(:shou!udruZ2-0\:cmuQshou@ss`x)udru(:cmuUdru@ees)'udru3-#udru3!hr!lnehgx!ho!cmuUdru@ees!i`i`#__*#**)#(*#(*(@#BU*@&$*0029044*&$*@^^^#(*@(*#&$&*@&$*00290@ees)'udru3-#uhr!lnehgx!&**&$&^^^#(*@(*"; |
encrypt <src> <dest> <xorkey> |
/******************************************************************************** 下面是和虚拟机XOR异或加密运算相关的结构体和枚举等定义 ********************************************************************************/ typedef struct _ZENGL_VM_XOR_ENCRYPT{ ZL_CHAR * xor_key_str; //密钥字符串指针,由用户提供 ZL_INT xor_key_len; //密钥长度 ZL_INT xor_key_cur; //密钥扫描游标 }ZENGL_VM_XOR_ENCRYPT; /******************************************************************************** 上面是和虚拟机解释器XOR异或加密运算相关的结构体和枚举等定义 ********************************************************************************/ |
/*虚拟机结构体定义*/ typedef struct _ZENGL_VM_TYPE { ....................... //省略N行 ZL_CLOCK_T total_time; //执行结束时的总时间,毫秒为单位 ZENGL_EXPORT_VM_MAIN_ARGS * vm_main_args; //用户传递给虚拟机的一些参数 ZL_BOOL isinApiRun; //判断是否通过zenglApi_Run运行的虚拟机 ZL_BOOL isUseApiSetErrThenStop; //判断用户是否在模块函数中通过调用zenglApi_SetErrThenStop来停止虚拟机的 ZENGL_VM_XOR_ENCRYPT xor_encrypt; //异或加密运算相关结构体 /*虚拟机相关的自定义函数*/ ZL_VOID (* init)(ZL_VOID * VM_ARG,ZENGL_EXPORT_VM_MAIN_ARGS * vm_main_args); //虚拟机初始化函数 对应 zenglVM_init }ZENGL_VM_TYPE; /*虚拟机结构体定义结束*/ |
/* 从文件中获取下一个字符 */ ZL_CHAR zengl_getNextchar(ZL_VOID * VM_ARG) { ZL_CHAR ch = ZL_STRNULL; ZL_UCHAR tmpch; ZENGL_VM_TYPE * VM = (ZENGL_VM_TYPE *)VM_ARG; ZENGL_COMPILE_TYPE * compile = &VM->compile; ZENGL_SOURCE_TYPE * source = &(compile->source); if(source->file == ZL_NULL) { source->file = ZENGL_SYS_FILE_OPEN(source->filename,"rb"); //一定要是rb否则二进制加密脚本解析会出错 if(source->file == ZL_NULL) compile->exit(VM_ARG, ZL_ERR_FILE_CAN_NOT_OPEN ,source->filename); } if(source->needread || source->cur >= source->buf_read_len) { if((source->buf_read_len = ZENGL_SYS_FILE_READ(source->buf,sizeof(ZL_UCHAR),ZL_FILE_BUF_SIZE,source->file)) == 0) { if(ZENGL_SYS_FILE_EOF(source->file)) return ZL_FILE_EOF; else compile->exit(VM_ARG, ZL_ERR_FILE_CAN_NOT_GETS ,source->filename); } source->needread = ZL_FALSE; source->cur = 0; } if(VM->xor_encrypt.xor_key_len == 0) //为0表示没有异或密钥,则不进行异或运算 ch = (ZL_CHAR)source->buf[source->cur++]; else { tmpch = source->buf[source->cur++]; ch = (ZL_CHAR)(tmpch ^ (ZL_UCHAR)VM->xor_encrypt.xor_key_str[VM->xor_encrypt.xor_key_cur]); if((++VM->xor_encrypt.xor_key_cur) >= VM->xor_encrypt.xor_key_len) VM->xor_encrypt.xor_key_cur = 0; } compile->col_no++; return ch; } |
char * xor_key_str = "xorkey_334566_hello_world"; //异或密钥字符串,长度没有限制 ........................... //省略N行代码 zenglApi_Reset(VM); zenglApi_Push(VM,ZL_EXP_FAT_INT,0,1415,0); zenglApi_Push(VM,ZL_EXP_FAT_STR,"test second arg",0,0); zenglApi_SetSourceXorKey(VM,xor_key_str); if(zenglApi_Call(VM,"encrypt_script/test.zl","OutIn","clsTest") == -1) //编译执行zengl脚本函数 //if(zenglApi_Call(VM,argv[1],"init","clsTest") == -1) //编译执行zengl脚本函数 main_exit(VM,"错误:编译<test fun call>失败:%s\n",zenglApi_GetErrorString(VM)); zenglApi_Close(VM); |
/** 将token加入AST抽象语法树 */ ZL_VOID zengl_ASTAddNode(ZL_VOID * VM_ARG,ZENGL_TOKENTYPE token) { ..................................... //省略N行代码 case ZL_TK_PLUS: case ZL_TK_MINIS: compile->AST_nodes.nodes[compile->AST_nodes.count].tokcategory = ZL_TKCG_OP_PLUS_MINIS; compile->AST_nodes.nodes[compile->AST_nodes.count].tok_op_level = ZL_OP_LEVEL_PLUS_MINIS; if(compile->AST_nodes.nodes[compile->AST_nodes.count].toktype == ZL_TK_PLUS || !compile->CheckIsNegative(VM_ARG)) { break; } compile->AST_nodes.nodes[compile->AST_nodes.count].toktype = ZL_TK_NEGATIVE; //将减号转为负号单目运算符,并使用和下面的REVERSE一样的优先级 case ZL_TK_REVERSE: case ZL_TK_ADDRESS: compile->AST_nodes.nodes[compile->AST_nodes.count].tokcategory = ZL_TKCG_OP_LOGIC; compile->AST_nodes.nodes[compile->AST_nodes.count].tok_op_level = ZL_OP_LEVEL_REVERSE; break; ..................................... //省略N行代码 } |
/*API接口,用于在用户自定义的模块函数中设置出错信息,然后设置虚拟机停止执行,比zenglApi_Exit好的地方在于,不会长跳转直接结束,而是返回由用户决定退出的时机,有效防止外部C++调用出现内存泄漏或访问异常*/ ZL_EXPORT ZL_EXP_VOID zenglApi_SetErrThenStop(ZL_EXP_VOID * VM_ARG,ZL_EXP_CHAR * errorStr, ...); /*API接口,用户通过此接口设置脚本源代码的XOR异或运算加密密钥*/ ZL_EXPORT ZL_EXP_VOID zenglApi_SetSourceXorKey(ZL_EXP_VOID * VM_ARG,ZL_EXP_CHAR * xor_key_str); /*API接口,用户通过此接口将字符串拷贝到虚拟机中,这样在C++中就可以提前将源字符串资源给手动释放掉,而拷贝到虚拟机中的新分配的资源则会在结束时自动释放掉,防止内存泄漏*/ ZL_EXPORT ZL_EXP_CHAR * zenglApi_AllocMemForString(ZL_EXP_VOID * VM_ARG,ZL_EXP_CHAR * src_str); /*API接口,用户通过此接口在虚拟机中分配一段内存空间*/ ZL_EXPORT ZL_EXP_VOID * zenglApi_AllocMem(ZL_EXP_VOID * VM_ARG,ZL_EXP_INT size); /*API接口,将AllocMem分配的资源手动释放掉,防止资源越滚越大*/ ZL_EXPORT ZL_EXP_VOID zenglApi_FreeMem(ZL_EXP_VOID * VM_ARG,ZL_EXP_VOID * ptr); |
wxString tmpContent = content; if(ex.Compile(pattern,flags)) { MatchCount = ex.GetMatchCount(); if(index >= MatchCount) { return zenglApi_SetErrThenStop(VM_ARG,"bltRegexMatches函数的第二个元组参数无效,正则表达式中共有%d个元组,而你要访问第%d个元组,元组索引值必须小于总元组数" ,MatchCount,index); |
/* 扫描类引用时的节点,将类成员转为数组的索引压入栈中。 如test.test2[3].name.val 如果test2在test类中的索引为1,name在test2类里的索引为2,val在name类的索引为3则 表达式相当于test[1,3,2,3],第一个1代表test2成员,第二个3是test2[3]里的索引3 第三个2代表name,第四个3代表val 然后就按数组的方式将1,3,2,3依次压入栈作为test数组的索引值,所以test类本质上就是 一个数组。 类引用是采用点运算符来连接的,所以该函数采用了堆栈扫描法 先在点运算符的第一个子节点中查找类id,然后使用该类id找到第二个子节点即类成员的 索引,接着将索引PUSH压入栈。 */ ZL_VOID zengl_SymScanDotForClass(ZL_VOID * VM_ARG,ZL_INT nodenum) { ............................................ //省略N行代码 //classid = compile->SymClassMemberTable.members[classMemberIndex].classid; //使用该类成员的类id,为获取后面的成员的索引做准备 classid = compile->SymClassMemberTable.members[classMemberIndex].cls_stmt_classid; //应该使用声明该成员时所使用的类ID信息,而非该成员所在的类结构,因为该成员的成员是声明类里的成员! ............................................ //省略N行代码 } |
class ykVideoPattern lstPages; contentLinks; title; ......................... //省略N行代码 endclass class ykVideo ykVideoPattern p; ......................... //省略N行代码 fun InitPatterns(obj) ykVideo obj; obj.p.lstPages = '(/search_video/q_.*?_orderby_1_page_.*?)"'; ............................. //省略N行代码 endfun endclass |