@[toc]
需求:
python使用execjs执行解密js代码时候,发现报错,然后经过俩个多小时最终找到问题所在,解决问题。
一、报错内容
报错内容:
UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xa1 in position 26: illegal multibyte sequence
具体:
Exception in thread Thread-1:
Traceback (most recent call last):
File "D:\tools\Python3.6\lib\threading.py", line 916, in _bootstrap_inner
self.run()
File "D:\tools\Python3.6\lib\threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "D:\tools\Python3.6\lib\subprocess.py", line 1083, in _readerthread
buffer.append(fh.read())
UnicodeDecodeError: 'gbk' codec can't decode byte 0xa1 in position 26: illegal multibyte sequence
Traceback (most recent call last):
File "D:/zjf_workspace/003、自己测试用的/002加密和验证码破解/02-js加密破解/022、梦幻西游藏宝阁/执行.py", line 11, in <module>
result = ct.call('decode_desc', _0x1c0cdf)
File "D:\tools\Python3.6\lib\site-packages\execjs\_abstract_runtime_context.py", line 37, in call
return self._call(name, *args)
File "D:\tools\Python3.6\lib\site-packages\execjs\_external_runtime.py", line 92, in _call
return self._eval("{identifier}.apply(this, {args})".format(identifier=identifier, args=args))
File "D:\tools\Python3.6\lib\site-packages\execjs\_external_runtime.py", line 78, in _eval
return self.exec_(code)
File "D:\tools\Python3.6\lib\site-packages\execjs\_abstract_runtime_context.py", line 18, in exec_
return self._exec_(source)
File "D:\tools\Python3.6\lib\site-packages\execjs\_external_runtime.py", line 87, in _exec_
output = self._exec_with_pipe(source)
File "D:\tools\Python3.6\lib\site-packages\execjs\_external_runtime.py", line 103, in _exec_with_pipe
stdoutdata, stderrdata = p.communicate(input=input)
File "D:\tools\Python3.6\lib\subprocess.py", line 863, in communicate
stdout, stderr = self._communicate(input, endtime, timeout)
File "D:\tools\Python3.6\lib\subprocess.py", line 1133, in _communicate
stdout = stdout[0]
IndexError: list index out of range
二、解决方法1:
用python实现内部错误的地方,主要我还是找到了。
问题起源,代码放在浏览器中直接执行代码和nodejs中执行也是可以的,就是python的execjs不能执行。
所以,这就让我纳闷了,明明就破解出来了,然后各种谷歌搜索,寻找答案:最终结果是,python的execjs只支持一些常规的js代码,我哪里知道什么是常规,别慌,用笨方法一步一步return js函数的主要步骤,最终让我找到了原因,用python使用Unicode反编译转中文报错,可能就认为这个不是常规的语句吧,把需要编译的数组返回的python中,使用python chr()函数,自己用python实现就可以了,(这个问题弄了将近我俩个小时才找到原因。。。伤心)
知道了一个python 执行execjs不能识别的问题,
错误图
将js的fromCharCode用python chr函数处理报错地方。
==主要的代码逻辑(后续补充):==
1 | print('result111', result) |
2 | # result111 ['100011', '1110010', '111101101001001', '111111010100111', '100000', '110001', '110010', '110000', '100000', '100000', '100111010010100', '1000100001001100', '100000', '110110000110100', '100011', '1110010', '100011', '1110010', '100111100100100', '101101110110011', '100000', '101011', '110011', '111001', '110110', '100000', '101010001111101', '100111000101101', '100000', '101011', '110110', '111000', '110000', '100011', '1110010', '1000000000010000', '100111001000101', '101111010100110', '100000', '110010', '110000', '110111', '100000', '100000', '100111111101110', '111010000000110', '101100100110001', '1000110100100101', '100000', '110001', '110101100100001', '100011', '1110010', '1001010100111011', '111000010111100', '111101101001001', '111111010100111', '100000', '110001', '110001', '100000', '100000', '1001010101110110', '101110101001100', '101101110011101', '111011111110011', '100000', '101100100101010', '1001011000110011', '111011111110011', '11000000000001', '100000', '111111010100010', '111001110011011', '111010001011001', '100011', '1011001', '100011', '1110010', '100011', '1100011', '110100', '1000100', '1000010', '1000001', '1000110', '110100', '111001001111001', '110010101001000', '1111111100011010', '100011', '1100011', '110100', '1000100', '1000010', '1000001', '1000110', '110100', '110010111100000', '111111010100111', '101001000101011', '1001011001010000', '101001000110110', '100011', '1011001', '100011', '1110010', '100011', '1000111', '101111100000000', '1000111111010000', '101101101010100', '110010101110000', '1111111100011010', '110100', '101101101010100', '101111', '110100', '101101101010100', '100000', '101000', '101001111001100', '110100', '101101101010100', '101001', '100011', '1000111', '100011', '1110010', '111101100100110', '111011111110011', '111010', '100000', '100111101010011', '1000110100101000', '100000', '101011', '110001', '100000', '100111100100100', '101101110110011', '100000', '101011', '110001', '101110', '110101', '100011', '1101110', '100011', '1000111', '100011', '1110010', '111101100100110', '111011111110011', '111010', '100000', '101001010011011', '1001000111001111', '100000', '101011', '110001', '100000', '110110000010100', '1000100001000000', '100000', '101011', '110001', '110000', '100011', '1101110', '100011', '1000111', '100011', '1110010', '111101100100110', '111011111110011', '111010', '100000', '101001010011011', '1001000111001111', '100000', '101011', '110001', '100000', '110110000010100', '1000100001000000', '100000', '101011', '110001', '110000', '100011', '1101110', '100011', '1000111', '100011', '1110010', '111101100100110', '111011111110011', '111010', '100000', '110110000010100', '1000100001000000', '100000', '101011', '110001', '110101', '100000', '1001000000011111', '101111010100110', '100000', '101011', '110001', '101110', '110101', '100011', '1101110', '100011', '1000111', '100011', '1110010', '110011000011111', '100111101001101', '1111111100011010', '1001000000011111', '101111010100110', '100000', '101011', '110010', '100011', '1101110', '100011', '1000111', '100011', '1110010', '110011000011111', '111011011111000', '100111010010010', '101010000001000', '1111111100011010', '100111101010011', '1000110100101000', '100000', '101011', '110010', '100011', '1110010', '100011', '1100011', '1000101', '1000101', '111000', '110010', '1000101', '1000101', '111101100100110', '111011111110011', '111111011000100', '101010000001000', '111010', '100000', '101100110000010', '110000100001111', '1001000111010001', '111101110001101', '111101100100110', '111011111110011', '100011', '1110010', '1001010111101000', '110110100111110', '110011101100001', '100111011110110', '1111111100011010', '1000001010110001', '110011110011100', '101110001110001', '100000', '100011', '1110010', '1001000011101000', '100111101001101', '110011101100001', '100111011110110', '1111111100011010', '110101101100110', '101011001101000', '100000', '100011', '1110010', '101100010011110', '101001010100000', '1001010111101000', '110110100111110', '110001010000000', '1000000011111101', '101100110000010', '110000100001111', '1001000111010001', '111101110001101', '111101101001001', '111111010100111', '110100', '111111010100111', '100011', '1011001', '100011', '1110010', '100011', '1010111', '101001000110110', '1001000000100000', '1000000000000101', '1111111100011010', '11000001010000', '110001100011010', '110000011000101', '1000110100011101', '1000101111111010', '10110000', '100011', '1011001', '100000', '100000'] |
3 | _0x36ab38 = [] |
4 | for i in result: |
5 | print('int(i, 2)',i,int(i, 2)) |
6 | _0x36ab38.append(chr(int(i, 2))) |
7 | |
8 | return ''.join(_0x36ab38) |
其实,int(i, 2)就是将二进制转换成十进制,然后将十进制,使用chr()函数转换为正常的中文字符或者其他字符串。
下面是使用window自带的计算器,二进制转换的结果。和代码的比对。
为了是看到的理解的更清楚,我这里使用python的chr和js的fromCharCode函数将Unicode编码转换成汉语和汉语的标点符号再或者其他语言字符都可以的。
下面是我特意把对比图弄出来,方便不懂得了解下。其实这个就是我当时找到python执行execjs不支持的地方,可能有其他更简单方法,只不过我没有找到。如果帮助到你可以给我点个赞哈,加油!
python实现之后效果图
高兴,美滋滋,晚上能多吃个馒头,哈哈
三、解决方法2、
修改编码文件的默认编码格式为utf-8,默认window下是gbk。
这个是我再次遇见错误,特意来补充一下:
Exception in thread Thread-1:
Traceback (most recent call last):
File "D:\tools\Python3.6\lib\threading.py", line 916, in _bootstrap_inner
self.run()
File "D:\tools\Python3.6\lib\threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "D:\tools\Python3.6\lib\subprocess.py", line 1083, in _readerthread
buffer.append(fh.read())
UnicodeDecodeError: 'gbk' codec can't decode byte 0xb4 in position 211: illegal multibyte sequence
Traceback (most recent call last):
File "D:/zjf_workspace/003、自己测试用的/002加密和验证码破解/02-js加密破解/023、烯牛数据/执行.py", line 44, in <module>
result_decode = get_decode(data)
File "D:/zjf_workspace/003、自己测试用的/002加密和验证码破解/02-js加密破解/023、烯牛数据/执行.py", line 34, in get_decode
result_decode = ct.call('decode_get_data', data)
File "D:\tools\Python3.6\lib\site-packages\execjs\_abstract_runtime_context.py", line 37, in call
return self._call(name, *args)
File "D:\tools\Python3.6\lib\site-packages\execjs\_external_runtime.py", line 92, in _call
return self._eval("{identifier}.apply(this, {args})".format(identifier=identifier, args=args))
File "D:\tools\Python3.6\lib\site-packages\execjs\_external_runtime.py", line 78, in _eval
return self.exec_(code)
File "D:\tools\Python3.6\lib\site-packages\execjs\_abstract_runtime_context.py", line 18, in exec_
return self._exec_(source)
File "D:\tools\Python3.6\lib\site-packages\execjs\_external_runtime.py", line 87, in _exec_
output = self._exec_with_pipe(source)
File "D:\tools\Python3.6\lib\site-packages\execjs\_external_runtime.py", line 103, in _exec_with_pipe
stdoutdata, stderrdata = p.communicate(input=input)
File "D:\tools\Python3.6\lib\subprocess.py", line 863, in communicate
stdout, stderr = self._communicate(input, endtime, timeout)
File "D:\tools\Python3.6\lib\subprocess.py", line 1133, in _communicate
stdout = stdout[0]
IndexError: list index out of range
解决步骤
1、进去错误这个D:\tools\Python3.6\lib\subprocess.py文件
2、搜索:encoding=
这个搜索方式,是我找了好一会才懂,所以记录下来,大家可以参考下。
3、修改编码格式为utf-8
注意事项:
建议备份一行,毕竟修改的是模块的源码,万一弄错了好改回来。敲代码最忌不懂,乱改还不保留,这样很招人烦的,尤其团队合作时。
至此修改完毕,可以尝试运行了
看我的运行,没有错误了,当然这个不是我第一个发现的,这个方法是我觉得之前应该有人遇到过,不过第一个方法是自己当时没有搜到这个方法,自己一点一点断点调试出问题所在,然后用python重写实现的解密逻辑。这个比较简单,原博客我看到的也是一头雾水,因为我看到时,他的图片已经无法打开了,全凭感觉自己搜索的关键词修改,还好让我蒙对了,嘻嘻
参考搜到的博客:
https://www.twblogs.net/a/5c9fb281bd9eee5b1a06835a/zh-cn