##################################### ## PEinjector/loader ## ##################################### import utils import os import shutil import log import json import traceback import config import action loaded_package = [] loaderr_pkgs = [] disk = "" lists = [] def version_check(file_json, pkg_name): try: if "compatibility" in file_json: if "injector" in file_json["compatibility"]: with open(f"{disk}/PEinjector/VERSION", "r", encoding="utf-8") as file: version = file.readlines()[0].rstrip("\n\r") if "min" in file_json["compatibility"]["injector"]: plugver = file_json["compatibility"]["injector"]["min"] def vererr(): log.warn(f"load moudle [{pkg_name}] failed: " + f"PEinjector version too low, need [{plugver}]") if int(plugver.split(".")[0]) > int(version.split(".")[0]): vererr() return 5 elif int(plugver.split(".")[0]) == int(version.split(".")[0]): if plugver.split(".")[1] > version.split(".")[1]: vererr() return 5 elif int(plugver.split(".")[1]) == int(version.split(".")[1]): if int(plugver.split(".")[2]) > int(version.split(".")[2]): vererr() return 5 if "max" in file_json["compatibility"]["injector"]: plugver = file_json["compatibility"]["injector"]["max"] def vererr(): log.warn(f"load moudle [{pkg_name}] failed: " + f"PEinjector version too high, need [{plugver}]") if int(plugver.split(".")[0]) < int(version.split(".")[0]): vererr() return 6 elif int(plugver.split(".")[0]) == int(version.split(".")[0]): if int(plugver.split(".")[1] < version.split(".")[1]): vererr() return 6 elif plugver.split(".")[1] == version.split(".")[1]: if int(plugver.split(".")[2] < version.split(".")[2]): vererr() return 6 except: log.warn(f"load moudle [{pkg_name}] failed: " + "The version number is formatted incorrectly") return 7 return 0 def file_check(file_json, pkg_name): try: if "compatibility" in file_json: if "file" in file_json["compatibility"]: if "must" in file_json["compatibility"]["file"]: for i in file_json["compatibility"]["file"]["must"]: if not os.path.exists(i): log.warn(f"load moudle [{pkg_name}] failed: " + f"Cannot find file: [{i}]") return 8 if "mustnot" in file_json["compatibility"]["file"]: for i in file_json["compatibility"]["file"]["mustnot"]: if os.path.exists(i): log.warn(f"load moudle [{pkg_name}] failed: " + f"Find incompatible file: [{i}]") return 9 except: log.warn(f"load moudle [{pkg_name}] failed: " + "Unknown error in file check") return 10 return 0 actions = {"onboot": [], "onload": []} def load_package(pkg_name): pkg_path = f"{disk}/PEinjector/package/{pkg_name}" loaded_package.append(pkg_name) if "manifest.json" not in os.listdir(pkg_path): log.warn(f"load moudle [{pkg_name}] failed: " + "Cannot find manifest.json") return 1 try: with open(pkg_path+"/"+"manifest.json", "r", encoding="utf-8") as file: file_str = file.read() except Exception as exp: log.warn(f"load moudle [{pkg_name}] failed: " + "Unknown error in read file ("+repr(exp)+")") return 2 try: file_json = json.loads(file_str) except: log.warn(f"load moudle [{pkg_name}] failed: " + "Json syntax error") return 3 for i in ("version", "name", "author", "introduce"): if i not in file_json: log.warn(f"load moudle [{pkg_name}] failed: " + f"\"{i}\" key not in manifest.json") return 4 retvar = version_check(file_json, pkg_name) if retvar != 0: return retvar retvar = file_check(file_json, pkg_name) if retvar != 0: return retvar if "dependence" in file_json: try: for i in file_json["dependence"]: if i not in lists: log.warn(f"load moudle [{pkg_name}] failed: " + f"Cannot find dependence [{i}]") return 11 if retvar in loaderr_pkgs: log.warn(f"load moudle [{pkg_name}] failed: " + f"dependence [{i}] loaded failed") return 12 if retvar not in loaded_package: log.info(f"load moudle [{i}] from [{pkg_name}]") retvar = load_package(i) if retvar != 0: loaderr_pkgs.append(i) log.warn(f"load moudle [{pkg_name}] failed: " + f"dependence [{i}] loaded failed") return 12 except: log.warn(f"load moudle [{pkg_name}] failed: " + f"Cannot find dependence [{i}]") data_list = [] if "data" in file_json: j = -1 prep_flag = False if pkg_name not in os.listdir(config.DATAPATH.replace("{DISK}", utils.find_disk())): log.info(f"prep moudle [{pkg_name}] data") prep_flag = True for i in file_json["data"]: j += 1 flag = False for event in ("from", "to"): if event not in i or i[event] == "": log.warn(f"load moudle [{pkg_name}] warning: " + f"Load data syntax error on {event}[{j}] (lost \"{event}\"), igrone") flag = True break if flag: continue data_list.append(i) if prep_flag: data_dir = config.DATAPATH.replace( "{DISK}", utils.find_disk())+"/"+pkg_name os.mkdir(data_dir) if os.path.isfile(pkg_path+"/"+i["from"]): shutil.copyfile(( pkg_path+"/"+i["from"]).replace("/", "\\"), (data_dir+"/"+i["to"])) else: shutil.copytree( pkg_path+"/"+i["from"], data_dir+"/"+i["to"]) if "load" in file_json: open_symlink = config.USE_SYMLINK if "symlink" in file_json["load"] and file_json["load"] == False: open_symlink = False if "mode" in file_json["load"]: for event in ("onboot", "onload"): if event not in file_json["load"]["mode"]: continue actions[event].append((0, pkg_name)) if type(file_json["load"]["mode"][event]) != list: log.warn(f"load moudle [{pkg_name}] failed: " + f"Load commands syntax error on {event} (must be a list)") return 13 j = -1 for i in file_json["load"]["mode"][event]: j += 1 if "type" not in i: log.warn(f"load moudle [{pkg_name}] warning: " + f"Load commands syntax error on {event}[{j+1}] (lost \"type\"), igrone") continue if i["type"] == "force_copy" or (i["type"] == "copy" and open_symlink == False): flag = False for check in ("from", "to"): if check not in i: flag = True log.warn(f"load moudle [{pkg_name}] warning: " + f"Load commands syntax error on {event}[{j+1}] (lost \"{check}\"), igrone") break if flag: continue if not os.path.exists(pkg_path+"/"+i["from"]): log.warn(f"load moudle [{pkg_name}] warning: " + f"Load commands file error on {event}[{j+1}] (cannot find \"{i['from']}\"), igrone") continue actions[event] += action.force_copy(pkg_path, pkg_name, data_list, i["from"], i["to"]) elif i["type"] == "copy": flag = False for check in ("from", "to"): if check not in i: flag = True log.warn(f"load moudle [{pkg_name}] warning: " + f"Load commands syntax error on {event}[{j+1}] (lost \"{check}\"), igrone") break if flag: continue if not os.path.exists(pkg_path+"/"+i["from"]): log.warn(f"load moudle [{pkg_name}] warning: " + f"Load commands file error on {event}[{j+1}] (cannot find \"{i['from']}\"), igrone") continue actions[event] += action.copy(pkg_path, pkg_name, data_list, i["from"], i["to"]) elif i["type"] == "start": flag = False for check in ("command", ): if check not in i: flag = True log.warn(f"load moudle [{pkg_name}] warning: " + f"Load commands syntax error on {event}[{j+1}] (lost \"{check}\"), igrone") break if flag: continue actions[event] += action.start( pkg_name, data_list, i["command"]) else: log.warn(f"load moudle [{pkg_name}] warning: " + f"Load commands syntax error on {event}[{j+1}] (unknown type), igrone") def load(): try: global disk, lists log.info("start load") disk = utils.find_disk() lists = os.listdir(f"{disk}/PEinjector/package") with open(config.DISABLEPATH.replace("{DISK}", disk), "r") as file: disable_packages = [i.rstrip("\n\r") for i in file.readlines()] for packs in lists: if packs not in loaded_package and packs not in disable_packages: log.info(f"load moudle [{packs}]") retvar = load_package(packs) if retvar == 0: loaderr_pkgs.append(packs) filename = action.save_action(actions["onload"]) alog = action.do_action(actions["onboot"]) with open(config.ACTIONLOGPATH.replace("{DISK}", utils.find_disk()), "w") as file: file.write(alog) os.system(f'..\\env\\pythonw.exe hook.py "{filename}"') except Exception as exp: log.break_err("Exception \n"+str(traceback.format_exc(exp))) raise exp