peinjector/src/loader.py

283 lines
12 KiB
Python
Raw Normal View History

2024-02-08 19:04:07 +08:00
#####################################
## 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_parse(version: str) -> list:
return [int(i) for i in version.split(".")]
2024-02-08 19:04:07 +08:00
def __version_compare(ver1: str, ver2: str) -> int:
version1 = __version_parse(ver1)
version2 = __version_parse(ver2)
for (i, j) in zip(version1, version2):
if i != j:
return 1 if i > j else -1
2024-02-08 19:04:07 +08:00
return 0
def version_check(configuration: dict, pkg_name: str) -> int:
ERROR_MESSAGE = "load moudle [{}] failed: PEinjector version too {}, need [{}]"
try:
if not "compatibility" in configuration or not "injector" in configuration["compatibility"]:
return 0
with open(f"{disk}/PEinjector/VERSION", 'r', encoding="utf-8") as f:
version = f.readlines()[0].rstrip("\n\r")
2024-02-10 20:54:35 +08:00
if "min" in configuration["compatibility"]["injector"]:
plugver = configuration["compatibility"]["injector"]["min"]
if __version_compare(version, plugver) == -1:
log.warn(ERROR_MESSAGE.format(pkg_name, "low", plugver))
return 5
2024-02-10 20:54:35 +08:00
if "max" in configuration["compatibility"]["injector"]:
plugver = configuration["compatibility"]["injector"]["max"]
if __version_compare(version, plugver) == 1:
log.warn(ERROR_MESSAGE.format(pkg_name, "high", plugver))
return 6
2024-02-10 20:54:35 +08:00
except Exception as e:
log.warn(f"load moudle [{pkg_name}] failed: {e}")
return 7
2024-02-10 21:02:45 +08:00
def file_check(file_json: dict, pkg_name: str) -> int:
2024-02-08 19:04:07 +08:00
try:
2024-02-10 20:54:35 +08:00
for i in file_json.get("compatibility", {}).get("file", {}).get("must", []):
if not os.path.exists(i):
log.warn(f"load moudle [{pkg_name}] failed: " +
f"Cannot find file: [{i}]")
return 8
for i in file_json.get("compatibility", {}).get("file", {}).get("mustnot", []):
if os.path.exists(i):
log.warn(f"load moudle [{pkg_name}] failed: " +
f"Find incompatible file: [{i}]")
return 9
2024-02-08 19:04:07 +08:00
except:
log.warn(f"load moudle [{pkg_name}] failed: " +
"Unknown error in file check")
return 10
return 0
actions = {"onboot": [], "onload": []}
2024-02-10 21:02:45 +08:00
def load_package(pkg_name: str) -> int:
2024-02-08 19:04:07 +08:00
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:
2024-02-10 20:54:35 +08:00
file_json = json.load(json.decoder.JSONDecodeError)
except json.decoder.JSONDecodeError:
log.warn(f"load moudle [{pkg_name}] failed: " +
"Json syntax error")
return 3
2024-02-08 19:04:07 +08:00
except Exception as exp:
log.warn(f"load moudle [{pkg_name}] failed: " +
"Unknown error in read file ("+repr(exp)+")")
return 2
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"])
2024-02-10 12:55:33 +08:00
add_action_head = False
2024-02-08 19:04:07 +08:00
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))
2024-02-10 12:55:33 +08:00
if event == "onload":
add_action_head = True
2024-02-08 19:04:07 +08:00
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")
2024-02-10 12:55:33 +08:00
if "start" in file_json:
if not add_action_head:
actions[event].append((0, pkg_name))
if "icon" in file_json["start"]:
for i in ("command", "name", "icon"):
if i not in file_json["start"]["icon"]:
log.warn(f"load moudle [{pkg_name}] warning: " +
f"Load icon syntax error (lost \"{i}\"), igrone")
2024-02-10 16:15:59 +08:00
if len(file_json["start"]["icon"]["icon"]) < 2 or file_json["start"]["icon"]["icon"][1] != ':':
file_json["start"]["icon"]["icon"] = pkg_path + \
"/"+file_json["start"]["icon"]["icon"]
if len(file_json["start"]["icon"]["command"]) < 2 or file_json["start"]["icon"]["command"][1] != ':':
file_json["start"]["icon"]["command"] = pkg_path + \
"/"+file_json["start"]["icon"]["command"]
actions["onload"].append(
(6, file_json["start"]["icon"]["command"], file_json["start"]["icon"]["icon"], file_json["start"]["icon"]["name"]))
if "path" in file_json["start"]:
for i in file_json["start"]["path"]:
if len(i) < 2 or i[1] != ':':
i = pkg_path + \
"/"+i
actions["onload"].append((7, i))
2024-02-10 17:32:07 +08:00
if "reg" in file_json:
for i in file_json["reg"]:
if len(i) < 2 or i[1] != ':':
i = pkg_path + \
"/"+i
actions["onload"].append((8, i))
2024-02-08 19:04:07 +08:00
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)
2024-02-10 12:55:33 +08:00
action.save_action(actions["onload"])
2024-02-08 19:04:07 +08:00
alog = action.do_action(actions["onboot"])
with open(config.ACTIONLOGPATH.replace("{DISK}", utils.find_disk()), "w") as file:
file.write(alog)
except Exception as exp:
log.break_err("Exception \n"+str(traceback.format_exc(exp)))
raise exp