PYAS 杀毒软件是由 云酱(PYAS杀毒软件官方) 使用Python语言编写的一款防病毒软件
代码是开源的,大大的方便了大家学习
程序作者:bilibili: PYAS杀毒软件官方的个人空间_哔哩哔哩_bilibili
那么我们话不多说,进入今天的主题
那就是分析PYAS杀毒软件的查杀引擎
首先我们定位到PYAS杀毒引擎部分的代码
def api_scan(self, file):
try:
if self.cloud_services == 1:
with open(file, "rb") as f:
text = str(md5(f.read()).hexdigest())
strBody = f'-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="md5s"\r\n\r\n{text}\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="format"\r\n\r\nXML\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="product"\r\n\r\n360zip\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="combo"\r\n\r\n360zip_main\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="v"\r\n\r\n2\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="osver"\r\n\r\n5.1\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="vk"\r\n\r\na03bc211\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="mid"\r\n\r\n8a40d9eff408a78fe9ec10a0e7e60f62\r\n-------------------------------7d83e2d7a141e--'
response = requests.post('http://qup.f.360.cn/file_health_info.php', data=strBody, timeout=3)
return response.status_code == 200 and float(et.fromstring(response.text).find('.//e_level').text) > 50
except:
return False
def sign_scan(self, file):
try:
pe = PE(file, fast_load=True)
pe.close()
return pe.OPTIONAL_HEADER.DATA_DIRECTORY[DIRECTORY_ENTRY["IMAGE_DIRECTORY_ENTRY_SECURITY"]].VirtualAddress == 0
except:
return True
def pe_scan(self,file):
try:
fn = []
pe = PE(file)
pe.close()
for entry in pe.DIRECTORY_ENTRY_IMPORT:
for func in entry.imports:
fn.append(str(func.name, "utf-8"))
for vfl in function_list:
if len(set(fn) & set(vfl)) / len(set(fn) | set(vfl)) == 1.0:
return True
return False
except:
return False
我们来分模块分析一下
第一个模块:360云杀模块
def api_scan(self,file)
def api_scan(self, file):
try:
if self.cloud_services == 1:
with open(file, "rb") as f:
text = str(md5(f.read()).hexdigest())
strBody = f'-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="md5s"\r\n\r\n{text}\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="format"\r\n\r\nXML\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="product"\r\n\r\n360zip\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="combo"\r\n\r\n360zip_main\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="v"\r\n\r\n2\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="osver"\r\n\r\n5.1\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="vk"\r\n\r\na03bc211\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="mid"\r\n\r\n8a40d9eff408a78fe9ec10a0e7e60f62\r\n-------------------------------7d83e2d7a141e--'
response = requests.post('http://qup.f.360.cn/file_health_info.php', data=strBody, timeout=3)
return response.status_code == 200 and float(et.fromstring(response.text).find('.//e_level').text) > 50
except:
return False
不难看出有360的样式,没错 这个是360的云API查杀接口
可以上传MD5来让360进行分析
我们来分段分析一下
with open(file, "rb") as f:
text = str(md5(f.read()).hexdigest())
这一段代码就是获取文件的MD5
strBody = f'-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="md5s"\r\n\r\n{text}\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="format"\r\n\r\nXML\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="product"\r\n\r\n360zip\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="combo"\r\n\r\n360zip_main\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="v"\r\n\r\n2\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="osver"\r\n\r\n5.1\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="vk"\r\n\r\na03bc211\r\n-------------------------------7d83e2d7a141e\r\nContent-Disposition: form-data; name="mid"\r\n\r\n8a40d9eff408a78fe9ec10a0e7e60f62\r\n-------------------------------7d83e2d7a141e--'
这一句话是360云的需要上传的格式
不难看出MD5的位置在
name="md5s"\r\n\r\n{text}\r\n
md5s的后面
然后
response = requests.post('http://qup.f.360.cn/file_health_info.php', data=strBody, timeout=3)
客户端给http://qup.f.360.cn/file_health_info.php发送POST请求,并获取返回值
return response.status_code == 200 and float(et.fromstring(response.text).find('.//e_level').text) > 50
判断是否成功并且
寻找“.//e_level”后面的内容并转换进行对比
嗯...这确实是自制杀软都用的手段呢.
第二个查杀模块:签名查杀模块
def sign_scan(self, file)
def sign_scan(self, file):
try:
pe = PE(file, fast_load=True)
pe.close()
return pe.OPTIONAL_HEADER.DATA_DIRECTORY[DIRECTORY_ENTRY["IMAGE_DIRECTORY_ENTRY_SECURITY"]].VirtualAddress == 0
except:
return True
这个不难看出,就是分析PE结构,判断是否有签名
当然用了别人写好的一个库
from pefile import PE, DIRECTORY_ENTRY
如果有签名就有签名 没签名就直接报毒
返回True
第三个查杀模块:函数对比引擎模块
这是PYAS官方说的自制引擎模块
先上代码
def pe_scan(self,file):
try:
fn = []
pe = PE(file)
pe.close()
for entry in pe.DIRECTORY_ENTRY_IMPORT:
for func in entry.imports:
fn.append(str(func.name, "utf-8"))
for vfl in function_list:
if len(set(fn) & set(vfl)) / len(set(fn) | set(vfl)) == 1.0:
return True
return False
except:
return False
我们得知道这是什么玩意
PE文件详解(六) - masimaro - 博客园 (cnblogs.com)
不理解的可以看看这篇文章
将导入表和导出表讲的很详细了
回归上面代码,我们可以得出
PYAS获取了PE文件的导入表函数
将 PE的函数列表 与病毒库函数里面 相同长度的函数列表 进行了一个对比
如果完全一致 那么就直接返回True 也就是报毒
不一致或者获取导出表函数失败 就返回False
做个小结吧
PYAS有三种查杀方式
1.360云杀
2.签名杀
3.函数对比杀(以前似乎是MD5杀)
用Python的库来实现这些功能确实比较方便
也不是很难...但总而言之,对比其他低质量的自制杀软这个做的还是不错了
而且这毕竟还是错过人人一个杀软潮流的 自制杀毒软件
做的已经蛮好了
文章作者:ShaShen
未经允许,禁止转载