import logging

from malduck.extractor import Extractor
from malduck.procmem import ProcessMemory
from malduck.yara import YaraRuleMatch

from ..utils import Config, get_rule_metadata

logger = logging.getLogger(__name__)


class Phoreal(Extractor):
    family = "phoreal"
    yara_rules = ("phoreal",)
    overrides = []

    @Extractor.rule
    def phoreal(self, p: ProcessMemory, match: YaraRuleMatch) -> Config | bool:
        _info: Config = get_rule_metadata(match)
        return _info

    @Extractor.extractor("rcdata")
    def PHOREAL_RC4_key(self, p: ProcessMemory, addr: int):
        from malduck import rc4

        key_size = 17  # apparently hardcoded in phoreal
        key_addr = addr + 6  # offset from start of string
        ct_addr = key_addr + 17
        max_size = 200

        key = bytearray()
        ct = bytearray()

        logger.info("[+] Found RC4 passphrase @ %X" % key_addr)

        for offset in range(0, key_size):
            o = p.uint8v(key_addr + offset)
            if o:
                key.append(o)

        logger.info("[+] RC4 passphrase: " + key.hex())

        nc = 0  # null counter
        for offset in range(0, max_size):
            o = p.uint8v(ct_addr + offset)
            if o:
                ct.append(o)

            if o == 0:
                nc += 1
            else:
                nc = 0
            if nc == 2:
                break

        logger.info("[+] RC4 cyphertext: " + ct.hex())

        rc4_decode = rc4(key, ct)

        logger.info("[+] RC4 decrypted plaintext: %s" % str(rc4_decode))

        domains = str(rc4_decode).split(";")
        domains[0] = domains[0].split("'")[1]
        del domains[-1]

        conf = {
            "rc4_key": key.hex(),
            self.family: {"plaintext": str(rc4_decode), "domains": domains},
        }
        return conf
