前情回顾:
猿人学第二题,手撕OB混淆给你看(step2-字符串数字回填)
函数调用还原
这一步会使用上一步生成的 02_ob_string_number.json
文件和开端生成的02_ob_left_3.js
文件
最终生成一份02_ob_call_function_reload.js
文件和一份 02_ob_call_function_reload.json
文件
上一章已经将函数调用时的参数都还原出来了,
把
_0x434ddb[$dbsm_0x42c3(qQOQo0, OOQQ1I) + 'EU'] = $dbsm_0x42c3(qoo1ql, I1LoO1) + 'Yu',
还原成了
_0x434ddb[$dbsm_0x42c3('0x1db', '30Py') + 'EU'] = $dbsm_0x42c3('0x1a5', 'Xgak') + 'Yu',
结构分析
这一章需要将所有调用$dbsm_0x42c3
函数的地方进行还原
还原的方式就是找到函数调用的节点,获取其参数后,
接着调用nodejs 运行 02_ob_left_3.js
文件里的$dbsm_0x42c3
函数,
将得到的返回值,替换所找到的函数调用节点.
我们先观察一下,函数调用节点的模样
整个节点类型是 CallExpression 函数调用节点, callee 子节点的name属性为 $dbsm_0x42c3,
并且所有的参数都是 Literal 类型
接下来就可以编写代码
代码
# test.py
""" 函数调用还原 """
def call_function_reload(node, ctx):
if type(node) == list:
for item in node:
call_function_reload(item, ctx)
return
elif type(node) != dict:
return
# 捕获一个 CallExpression 节点
if node['type'] == 'CallExpression':
try:
if node['callee']['name'] == '$dbsm_0x42c3': # 确认函数名
arg_list = []
for item in node['arguments']: # 提取所有参数
if item['type'] != 'Literal':
break
arg_list.append(item['value'])
else:
# 这里有一个隐藏的彩蛋,如果是用GBK去解码会触发报错,就会引起关注,就有可能发现这个彩蛋
value = ctx.call('$dbsm_0x42c3', *arg_list)
print(value) # 这里加入一个print() 省的以为程序卡死了
new_node = {'type': 'Literal', 'value': value}
node.clear()
node.update(new_node)
return
except KeyError:
pass
for key in node.keys():
call_function_reload(node[key], ctx)
""" ********************************************************* """
if __name__ == '__main__':
# 生成基础文件
...
""" 字符串与数字回填[ok] """
...
""" 函数调用还原[ok](此步骤及其耗时,估计是需要用python 频繁调用nodejs的原因) """
with open('02_ob_string_number.json', 'r', encoding='utf8') as f:
data = json.loads(f.read())
with open('02_ob_left_3.js', 'r', encoding='utf-8') as f:
ctx = execjs.compile(f.read())
call_function_reload(data, ctx)
with open('02_ob_call_function_reload.json', 'w', encoding='utf8') as f:
f.write(json.dumps(data))
os.system('node JsonToJs 02_ob_call_function_reload.json 02_ob_call_function_reload.js')
程序运行结束后,我们打开新生成的02_ob_call_function_reload.js
文件观察一下,
所有调用 $dbsm_0x42c3
函数的地方都已经被字符串替换
至此,函数调用还原已完成,我们把
_0x434ddb[$dbsm_0x42c3('0x1db', '30Py') + 'EU'] = $dbsm_0x42c3('0x1a5', 'Xgak') + 'Yu',
还原成了
_0x434ddb['Swi' + 'EU'] = 'pLE' + 'Yu',
本文使用 文章同步助手 同步