前情回顾:
猿人学第二题,手撕OB混淆给你看(Step1-开篇)
猿人学第二题,手撕OB混淆给你看(step2-字符串数字回填)
猿人学第二题,手撕OB混淆给你看(step3-函数调用还原)
猿人学第二题,手撕OB混淆给你看(step4-对象调用还原)
猿人学第二题,手撕OB混淆给你看(step5-分支流程判断)
控制流平坦化
这一章会使用上一章生成的 02_ob_if_reload.json文件
最终生成一份02_ob_sort_reload.js文件和一份 02_ob_sort_reload.json 文件
上一章,我们剔除了if 语句里面的无用代码,将
function () {
if ('QcUHF' !== 'QcUHF') {
return ![];
} else {
_0x4643a3 = !![];
return ...
}
}
还原成了
function () {
{
_0x4643a3 = !![];
return ...
}
}
结构分析
在02_ob_sort_reload.js文件中搜索 while 关键字,找到类似于下图的代码
这一章平坦化控制流,看下面这张图就能明白意思:
![](https://img-blog.csdnimg.cn/img_convert/4d753098eae458a81c12b15ad8a02efb.png)
程序的执行顺序并非从上至下,而是以切割出的字符串列表为标准来顺序执行的,
这样会给我们代码阅读带来很大的困扰,所以需要还原出真实的执行顺序,
这就是控制流平坦化
接下来分析代码段的结构树,可以看到
整个结构包含在一个列表中,while 节点是该列表的第二个元素,执行顺序在第一个元素中.
所以,我们只要按照执行顺序,提取出执行语句块,将其加入一个列表中,
然后用新的列表,替换掉整个node节点即可
![](https://img-blog.csdnimg.cn/img_convert/c8d83214e81aec8148cb8ca7db0b77a7.png)
代码
# test.py
""" 控制流平坦化 """
def sort_code(node):
if type(node) == list:
active = False
try:
# 捕获一个控制流节点(这是一个包含执行顺序和while节点的列表节点)
if len(node) == 2:
if node[1]['type'] == 'WhileStatement':
var1 = node[0]['expression']['expressions'][0]
var2 = node[0]['expression']['expressions'][1]
if var1['right']['type'] == 'CallExpression' and var2['right']['type'] == 'Literal':
active = True
if not active:
raise KeyError
except (KeyError, TypeError):
for item in node:
sort_code(item)
return
elif type(node) == dict:
for key in node.keys():
sort_code(node[key])
return
else:
return
sort_list = var1['right']['callee']['object']['value'].split('|') # 控制流程顺序列表
cases_list = node[1]['body']['body'][0]['cases'] # 原控制流列表
result_list = [cases_list[int(i)]['consequent'][0] for i in sort_list] # 新的控制流列表
node.clear()
node.extend(result_list)
for item in node:
sort_code(item)
""" ********************************************************* """
if __name__ == '__main__':
# 生成基础文件
...
""" 字符串与数字回填[ok] """
...
""" 函数调用还原[ok] """
...
""" 对象调用还原[ok] """
...
""" 分支流程判断[ok] """
...
""" 控制流平坦化[ok] """
with open('02_ob_if_reload.json', 'r', encoding='utf8') as f:
data = json.loads(f.read())
sort_code(data)
with open('02_ob_sort_reload.json', 'w', encoding='utf8') as f:
f.write(json.dumps(data))
os.system('node JsonToJs 02_ob_sort_reload.json 02_ob_sort_reload.js')
运行代码后, 可以看到,顺序已经被重构
![](https://img-blog.csdnimg.cn/img_convert/b3b133d713a843f1c4dcab2862b68e12.png)
至此,OB反混淆所有步骤完成, 得到 02_ob_sort_reload.js文件
该文件内的代码已不再难以阅读,我们可以轻易的找到,其设置cookie 的接口,
但是现在的代码还是不能正常运行的,因为其中相关反调试,检测部分的代码还在,
我们需要手动删除这些干扰运行的代码,直至获取到正确的M值.
![](https://img-blog.csdnimg.cn/img_convert/4fb0de3dc64441e75716c6a1a9fff03f.png)
最后可运行的JS代码在第一章开端的最后已经给出,这里不再重复
end
![](https://img-blog.csdnimg.cn/img_convert/5a1c9e0cd3727dc8ea352d517dc82e4b.png)
|