145 lines
5.1 KiB
Python
145 lines
5.1 KiB
Python
import hashlib
|
|
import json
|
|
|
|
|
|
def build_canonical_symbol_tables(
|
|
swift_files: list,
|
|
objc_files: list,
|
|
method_files: list,
|
|
*,
|
|
enable_objc_symbols: bool,
|
|
prefilter_files,
|
|
type_pattern: str,
|
|
method_pattern: str,
|
|
extract_swift_symbols,
|
|
extract_objc_symbols,
|
|
extract_methods,
|
|
objc_symbol_prefixes: tuple,
|
|
already_obfuscated_re,
|
|
symbol_whitelist,
|
|
symbol_prefix_whitelist: tuple,
|
|
is_system_method,
|
|
split_swift_signature_key,
|
|
) -> dict:
|
|
swift_symbol_files = prefilter_files(swift_files, type_pattern)
|
|
objc_symbol_files = prefilter_files(objc_files, type_pattern) if enable_objc_symbols else []
|
|
method_symbol_files = prefilter_files(method_files, method_pattern)
|
|
|
|
swift_symbols = set()
|
|
objc_symbols = set()
|
|
direct_methods = set()
|
|
objc_selectors = set()
|
|
swift_signatures = {}
|
|
|
|
for file_path in swift_symbol_files:
|
|
swift_symbols.update(extract_swift_symbols(file_path))
|
|
|
|
for file_path in objc_symbol_files:
|
|
objc_symbols.update(extract_objc_symbols(file_path))
|
|
|
|
for file_path in method_symbol_files:
|
|
method_data = extract_methods(file_path)
|
|
direct_methods.update(method_data["direct_names"])
|
|
objc_selectors.update(method_data["objc_selectors"])
|
|
swift_signatures.update(method_data["swift_signatures"])
|
|
|
|
canonical = {
|
|
"swift_symbols": sorted(swift_symbols),
|
|
"objc_symbols": [
|
|
name for name in sorted(objc_symbols)
|
|
if any(name.startswith(prefix) for prefix in objc_symbol_prefixes)
|
|
and not already_obfuscated_re.match(name)
|
|
and name not in symbol_whitelist
|
|
and not name.startswith(symbol_prefix_whitelist)
|
|
],
|
|
"direct_methods": [
|
|
name for name in sorted(direct_methods)
|
|
if name and not already_obfuscated_re.match(name) and name not in symbol_whitelist and not is_system_method(name)
|
|
],
|
|
"objc_selectors": [
|
|
name for name in sorted(objc_selectors)
|
|
if name and not already_obfuscated_re.match(name) and name not in symbol_whitelist and not is_system_method(name)
|
|
],
|
|
"swift_signatures": {},
|
|
}
|
|
|
|
for signature_key in sorted(swift_signatures.keys()):
|
|
base_name, _ = split_swift_signature_key(signature_key)
|
|
if not base_name:
|
|
continue
|
|
if already_obfuscated_re.match(base_name) or base_name in symbol_whitelist or is_system_method(base_name):
|
|
continue
|
|
canonical["swift_signatures"][signature_key] = swift_signatures[signature_key]
|
|
|
|
digest_payload = {
|
|
key: canonical[key]
|
|
for key in ("swift_symbols", "objc_symbols", "direct_methods", "objc_selectors", "swift_signatures")
|
|
}
|
|
canonical["digest"] = hashlib.sha256(
|
|
json.dumps(digest_payload, ensure_ascii=False, sort_keys=True).encode("utf-8")
|
|
).hexdigest()
|
|
return canonical
|
|
|
|
|
|
def build_type_mappings_from_canonical_table(canonical_tables: dict, salt: str, *, enable_objc_symbols: bool, build_unique_mapping, type_prefix: str) -> tuple:
|
|
ordered_names = []
|
|
seen = set()
|
|
for bucket_name in ("objc_symbols", "swift_symbols"):
|
|
for name in canonical_tables.get(bucket_name, []):
|
|
if name in seen:
|
|
continue
|
|
seen.add(name)
|
|
ordered_names.append(name)
|
|
|
|
combined_mapping = build_unique_mapping(ordered_names, salt, prefix=type_prefix)
|
|
mapping_swift = {
|
|
name: combined_mapping[name]
|
|
for name in canonical_tables.get("swift_symbols", [])
|
|
if name in combined_mapping
|
|
}
|
|
mapping_objc = {}
|
|
if enable_objc_symbols:
|
|
mapping_objc = {
|
|
name: combined_mapping[name]
|
|
for name in canonical_tables.get("objc_symbols", [])
|
|
if name in combined_mapping
|
|
}
|
|
return mapping_swift, mapping_objc
|
|
|
|
|
|
def build_method_mapping_from_canonical_table(canonical_tables: dict, salt: str, *, build_unique_mapping, method_prefix: str) -> dict:
|
|
swift_signature_mapping = canonical_tables.get("swift_signatures", {})
|
|
ordered_names = []
|
|
seen = set()
|
|
for bucket in (
|
|
canonical_tables.get("direct_methods", []),
|
|
canonical_tables.get("objc_selectors", []),
|
|
sorted(swift_signature_mapping.keys()),
|
|
):
|
|
for name in bucket:
|
|
if name in seen:
|
|
continue
|
|
seen.add(name)
|
|
ordered_names.append(name)
|
|
|
|
combined_tokens = build_unique_mapping(ordered_names, salt, prefix=method_prefix)
|
|
method_mapping = {
|
|
name: combined_tokens[name]
|
|
for name in canonical_tables.get("direct_methods", [])
|
|
if name in combined_tokens
|
|
}
|
|
method_mapping.update({
|
|
name: combined_tokens[name]
|
|
for name in canonical_tables.get("objc_selectors", [])
|
|
if name in combined_tokens
|
|
})
|
|
|
|
for signature_key in sorted(swift_signature_mapping.keys()):
|
|
if signature_key not in combined_tokens:
|
|
continue
|
|
entry = dict(swift_signature_mapping[signature_key])
|
|
entry["obfuscated"] = combined_tokens[signature_key]
|
|
method_mapping[signature_key] = entry
|
|
|
|
return method_mapping
|