笔者出于兴趣或者工作需要,会经常对一些网站的数据进行数据抓取,对于像淘宝、携程、百度这类大型互联网公司的网站,出于安全或者性能考虑,常常会针对网站加入反抓取策略脚本。
在该类脚本中,常见的手法有以下几种:
1. 针对简单数值变量的值,会把它用一个数值表达式来表示,让你没办法一眼看穿它,如:_lkqr = - ((104 | 3525868) % 705192)
2. 把一个简单的数值,用手法1中两个变量进行运算,得到真正数值。如: _set = _lkqr + _lnz
3. 提供一个字符串转换函数,让你无法理解它给你的字符串的真正涵义。
4. 加入一些适当的废代码,让你很难抓住真正的逻辑
5. 把Js调用的方式,采用数组方式来调用。如window.document会写成window[‘document‘]
6. 其他。。。
在这篇文章中,我主要是想针对问题1做了一个简单的小程序,化复杂表达式为简单数值,提高分析效率。
1 ExprEvalUtil expUtil = new ExprEvalUtil(); 2 Regex regex = new Regex(@"\({1,}((0x[0-9a-f]+)|(\d+))(\s*[\+\-\*\/\%\|\&\^\>\<]{1,2}\s*\(*[ \t]*((0x[0-9a-f]+)|(\d+))\s*\)*)+", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled); 3 String jsContent = null; 4 FileStream fs = new FileStream("d:\\somejs.js", FileMode.Open); 5 using (TextReader reader = new StreamReader(fs)) 6 { 7 jsContent = reader.ReadToEnd(); 8 } 9 10 string result = regex.Replace(jsContent, m => 11 { 12 string value = m.Value; 13 int lkValue = 0; 14 int index = -1; 15 while ((index = value.IndexOf(‘(‘, index + 1)) != -1) 16 { 17 lkValue++; 18 } 19 20 int rkValue = 0; 21 //index = 0; 22 while ((index = value.IndexOf(‘)‘, index + 1)) != -1) 23 { 24 rkValue++; 25 } 26 27 String preStr = ""; 28 if (rkValue < lkValue) 29 { 30 value = value.Remove(0, lkValue - rkValue); 31 preStr = new String(‘(‘, lkValue - rkValue); 32 } 33 34 String postStr = ""; 35 if (rkValue > lkValue) 36 { 37 value = value.Remove(value.Length - rkValue + lkValue); 38 postStr = new String(‘)‘, rkValue - lkValue); 39 } 40 41 try 42 { 43 value = expUtil.Eval(value).ToString(); 44 } 45 catch (Exception ex) 46 { 47 return m.Value; 48 } 49 50 return preStr + value + postStr; 51 }); 52 53 Console.WriteLine(result);
其中的ExpEvalUtil代码,我利用了网上的一个Javascript解释器(Jussica)引擎实现,代码如下:
public class ExprEvalUtil { private ScriptEngine engine = new ScriptEngine(); public int Eval(string expr) { return (int)Convert.ChangeType(engine.Evaluate(expr), typeof(int)); } }
通过上述代码进行一个处理后,你是不是觉得有点眼前一新的感觉了?
笔者实际上对后面几个问题解决,也有了新的思路,欢迎更多同学加入探讨
时间: 2024-10-10 18:45:38