From 4637fd0d973e1941e781c1b424c375c1a88c9dcc Mon Sep 17 00:00:00 2001 From: TinyCaviar <379645931@qq.com> Date: Sat, 12 Aug 2023 13:48:27 +0800 Subject: [PATCH] backup --- .idea/deployment.xml | 14 ++ .../convert_pkl_to_json.py | 38 ++++- Genius3/raw-feature-extractor/func.py | 2 +- Genius3/raw-feature-extractor/read_idaFILE.py | 2 +- Genius3/raw-feature-extractor/test.py | 133 ++++++++++++++++-- 5 files changed, 171 insertions(+), 18 deletions(-) create mode 100644 .idea/deployment.xml diff --git a/.idea/deployment.xml b/.idea/deployment.xml new file mode 100644 index 0000000..81b14c5 --- /dev/null +++ b/.idea/deployment.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Genius3/raw-feature-extractor/convert_pkl_to_json.py b/Genius3/raw-feature-extractor/convert_pkl_to_json.py index c07301c..84cac1c 100644 --- a/Genius3/raw-feature-extractor/convert_pkl_to_json.py +++ b/Genius3/raw-feature-extractor/convert_pkl_to_json.py @@ -12,6 +12,7 @@ def convert(start, end): cfg_dir = "D:\\hkn\\infected\\datasets\\virusshare_infected{}_cfg".format(workflow) output_dir = "D:\\hkn\\infected\\datasets\\virusshare_infected{}_json".format(workflow) dot_dir = "D:\\hkn\\infected\\datasets\\virusshare_infected{}_dot".format(workflow) + log_path = "D:\\hkn\\infected\\datasets\\logging\\convert_log{}.log".format(workflow) process_log_path = "D:\\hkn\\infected\\datasets\\logging\\convert_process_log{}.log".format(workflow) @@ -36,8 +37,8 @@ def convert(start, end): except ValueError: process_log.write("index {}, {} process failed. ValueError occurred.\n".format(index, cfg)) continue - - cfg_file.close() + finally: + cfg_file.close() dot_file_path = os.path.join(dot_dir, name + '.dot') if not os.path.exists(dot_file_path): @@ -45,24 +46,47 @@ def convert(start, end): else: # 打开dot文件获取fcg raw_function_edges = [] + # 2023.8.12 bug fix: ida生成的fcg(.dot)文件包含了所有函数,data.raw_graph_list仅包含了内部函数 + functions_list = [] with open(dot_file_path, 'r') as dot: for line in dot: if '->' in line: raw_function_edges.append(re.findall(r'\b\d+\b', line)) + elif 'label' in line: + functions_list.append(line[line.find('= "') + 3:line.find('",')]) + + # 没有内部函数被检测到,保险起见还是不要这数据了 + if raw_function_edges.__len__() == 0: + continue # 为当前pe文件创建json对象 json_obj = { 'hash': data.binary_name[11:], - 'function_number': data.raw_graph_list.__len__(), - 'function_edges': [[d[0] for d in raw_function_edges], [d[1] for d in raw_function_edges]], + # 2023.8.12 bug fix: 这里获取的是内部函数的数量 + # 'function_number': data.raw_graph_list.__len__(), + 'function_number': len(functions_list), + 'function_edges': [[int(d[0]) for d in raw_function_edges], + [int(d[1]) for d in raw_function_edges]], 'acfg_list': [], - 'function_names': [] + 'function_names': functions_list } + + # 2023.8.12 bug fix: data.raw_graph_list是ida检测到的内部函数,不包括外部函数,因此函数列表和函数数量不能从这里获取 # 读取pkl文件,一个acfg由一个函数分解而来 for acfg in data.raw_graph_list: + # 函数为外部函数,不需要构建cfg + if acfg.funcname != 'start' and acfg.funcname != 'start_0' and 'sub_' not in acfg.funcname: + continue + # 这里2是因为Genius框架提取特征时将后代数量放在2 offspring = [d.get('v')[2] for d in acfg.g.node.values()] + # 这边可能会出现不知名的原因两个数组长度不一致,按理来说应该是一致的 + # 以框架为主,将bb_features数组削减为和g.node长度一致 + diff = acfg.g.__len__() - len(acfg.bb_features) + if diff != 0: + del acfg.bb_features[diff:] # 将后代数量的特征放入bb_features中 + for i, offs in enumerate(offspring): acfg.bb_features[i].append(offs) @@ -73,7 +97,7 @@ def convert(start, end): } json_obj['acfg_list'].append(acfg_item) - json_obj['function_names'].append(acfg.funcname) + # json_obj['function_names'].append(acfg.funcname) # 将结果写入json本地文件 result = json.dumps(json_obj, ensure_ascii=False) @@ -89,4 +113,4 @@ def convert(start, end): if __name__ == '__main__': - convert(20, 35) + convert(0, 35) diff --git a/Genius3/raw-feature-extractor/func.py b/Genius3/raw-feature-extractor/func.py index 6e67820..33020aa 100644 --- a/Genius3/raw-feature-extractor/func.py +++ b/Genius3/raw-feature-extractor/func.py @@ -139,7 +139,7 @@ def get_func_cfgs_c(ea): icfg = cfg.getCfg(func, externs_eas, ea_externs) func_f = get_discoverRe_feature(func, icfg[0]) bb_f = get_bb_features(func) - raw_g = raw_graph(funcname, icfg, func_f, bb_f) # todo 为每个bb生成bb_features + raw_g = raw_graph(funcname, icfg, func_f, bb_f) raw_cfgs.append(raw_g) # raw_graphs 是另一个python class,存储raw_graph的list。定义在 raw_graph.py #print(raw_g.__dict__) #print(raw_g) 由于raw_graph、raw_graphs都是class,直接print只会打印,不能打印对象的属性。 #https://blog.51cto.com/steed/2046408 print_obj、 print(obj.__dict__) diff --git a/Genius3/raw-feature-extractor/read_idaFILE.py b/Genius3/raw-feature-extractor/read_idaFILE.py index 463b53d..aae5416 100644 --- a/Genius3/raw-feature-extractor/read_idaFILE.py +++ b/Genius3/raw-feature-extractor/read_idaFILE.py @@ -15,7 +15,7 @@ def print_obj(obj): # sub_10F20 308 反编译代码有字符串,但是这个特征提取里没有字符串 constant,可能是间接引用的,不识别。看了下所有函数的特征,几乎都没有字符串常量,可能都是写在别的地方然后引用的。 # sub_166C4 393 if __name__ == '__main__': - testpath = "D:\\hkn\\infected\\datasets\\virusshare_infected11_cfg\\VirusShare_5c088a2a6e0391b7c6ab22e4648eab3a.ida" + testpath = "D:\\hkn\\infected\\datasets\\virusshare_infected23_cfg\\VirusShare_9ba64176b2ca61212ff56a5b4eb546ff.ida" fr = open(testpath, 'r') data = pickle.load(fr) #一个二进制文件的acfgs fr.close() diff --git a/Genius3/raw-feature-extractor/test.py b/Genius3/raw-feature-extractor/test.py index 4a5c124..8cb8f16 100644 --- a/Genius3/raw-feature-extractor/test.py +++ b/Genius3/raw-feature-extractor/test.py @@ -1,7 +1,11 @@ +# coding=utf-8 import re import os import subprocess import time +import json +import random +import shutil def func(): @@ -19,20 +23,20 @@ def func1(): print(f[:-4]) -def gen_dir(): +def create_dir(): parent_dir = "D:\\hkn\\infected\\datasets" - for workflow in range(0, 35): + for workflow in range(35, 40): + # 生成raw data文件夹 # infected = "virusshare_infected{}".format(workflow) # cfg = "virusshare_infected{}_cfg".format(workflow) # dot = "virusshare_infected{}_dot".format(workflow) - # jsonl = "virusshare_infected{}_json".format(workflow) - iout = "virusshare_infected{}_iout".format(workflow) - + jsonl = "virusshare_infected{}_json".format(workflow) # os.mkdir(os.path.join(parent_dir, infected)) # os.mkdir(os.path.join(parent_dir, cfg)) # os.mkdir(os.path.join(parent_dir, dot)) - # os.mkdir(os.path.join(parent_dir, jsonl)) - os.rmdir(os.path.join(parent_dir, iout)) + os.mkdir(os.path.join(parent_dir, jsonl)) + # iout = "virusshare_infected{}_iout".format(workflow) + # os.rmdir(os.path.join(parent_dir, iout)) # os.rmdir(os.path.join(parent_dir, ida)) @@ -77,8 +81,119 @@ def delete_error(): os.remove(os.path.join(json_dir, name)) +def check_json(): + for workflow in range(5, 16): + json_dir = 'D:\\hkn\\infected\\datasets\\virusshare_infected{}_json'.format(workflow) + for json_file in os.listdir(json_dir): + f = open(os.path.join(json_dir, json_file), 'r') + try: + data = json.load(f) + except UnicodeDecodeError: + continue + finally: + f.close() + for acfg in data['acfg_list']: + if acfg['block_number'] != len(acfg['block_features']): + print("{} {}\n".format(workflow, json_file)) + + +# 临时函数,删除所有jsonl文件 +def delete_jsonl(): + for workflow in range(0, 35): + json_dir = 'D:\\hkn\\infected\\datasets\\virusshare_infected{}_json'.format(workflow) + for f in os.listdir(json_dir): + os.remove(os.path.join(json_dir, f)) + + +# 临时函数,重命名pt文件使之与代码相符 +def rename(): + tag_set = ['train', 'test', 'valid'] + for tag in tag_set: + data_dir = 'D:/hkn/infected/datasets/proprecessed_pt/{}_malware/'.format(tag) + for index, f in enumerate(os.listdir(data_dir)): + os.rename(os.path.join(data_dir, f), os.path.join(data_dir, 'm' + f)) + for tag in tag_set: + data_dir = 'D:/hkn/infected/datasets/proprecessed_pt/{}_malware/'.format(tag) + for index, f in enumerate(os.listdir(data_dir)): + os.rename(os.path.join(data_dir, f), os.path.join(data_dir, 'malware_{}.pt'.format(index))) + + +def split_samples(): + path = 'D:\\hkn\\infected\\datasets\\proprecessed_pt\\all' + out = 'D:\\hkn\\infected\\datasets\\proprecessed_pt' + os_list = os.listdir(path) + random.shuffle(os_list) + # 8/1/1 分数据 + train_len = int(len(os_list) * 0.8) + test_len = int(train_len / 8) + for index, f in enumerate(os_list): + if index < train_len: + shutil.copy(os.path.join(path, f), os.path.join(out, 'train_malware')) + elif train_len <= index < train_len + test_len: + shutil.copy(os.path.join(path, f), os.path.join(out, 'test_malware')) + else: + shutil.copy(os.path.join(path, f), os.path.join(out, 'valid_malware')) + + +def half_divide(): + src = 'D:\\hkn\\infected\\datasets\\proprecessed_pt' + + test = 'D:\\hkn\\infected\\datasets\\proprecessed_pt\\test_malware' + valid = 'D:\\hkn\\infected\\datasets\\proprecessed_pt\\valid_malware' + + flag = True + for f in os.listdir(src): + if 'pt' not in f: + continue + if flag: + shutil.copy(os.path.join(src, f), test) + else: + shutil.copy(os.path.join(src, f), valid) + flag = not flag + + +def copy_train_data(): + all = 'D:\\hkn\\infected\\datasets\\proprecessed_pt\\all' + dest = 'D:\\hkn\\infected\\datasets\\proprecessed_pt\\train_malware' + train = set(os.listdir(all)) - set(os.listdir('D:\\hkn\\infected\\datasets\\proprecessed_pt\\test_malware')) - set(os.listdir('D:\\hkn\\infected\\datasets\\proprecessed_pt\\valid_malware')) + for f in train: + shutil.copy(os.path.join(all, f), dest) + + +def clear_dot(): + for workflow in range(0, 35): + path = 'D:\\hkn\\infected\\datasets\\virusshare_infected{}_dot\\'.format(workflow) + for name in os.listdir(path): + full = os.path.join(path, name) + f = open(full, 'r') + data = f.read() + f.close() + if 'start' not in data and 'sub_' not in data: + # print("delete") + os.remove(full) + + +def read_test(): + dot_file_path = "D:\\hkn\\infected\\datasets\\virusshare_infected23_dot\\VirusShare_9ba64176b2ca61212ff56a5b4eb546ff.dot" + with open(dot_file_path, 'r') as dot: + for line in dot: + if '->' in line: + print(re.findall(r'\b\d+\b', line)) + elif 'label' in line: + print(line[line.find('= "') + 3:line.find('",')]) + + if __name__ == '__main__': - # gen_dir() + # create_dir() # change_max_item_lines() # subprocess.call('taskkill /im idaq64.exe /f') - delete_error() + # delete_error() + # test() + # delete_jsonl() + # check_json() + split_samples() + rename() + # half_divide() + # copy_train_data() + # clear_dot() + # read_test() \ No newline at end of file