class DetectAntiTechniques:
    def __init__(self, file, report):
        self.file = file
        self.report = report

    def AntiDbg(self, ApiCalls):

        antidbg_api_calls = [
            "CheckRemoteDebuggerPresent",
            "IsDebuggerPresent",
            "GetThreadContext",
            "OutputDebugString",
            "UnhandledExceptionFilter",
            "ZwQueryInformation",
            "WudfIsAnyDebuggerPresent",
            "SetUnhandledExceptionFilter",
        ]
        suspicious_api_calls = [
            "CloseHandle",
            "AddVectoredExceptionHandler",
            "RemoveVectoredExceptionHandler",
            "GetProcessHeap",
            "Process32First",
            "Process32Next",
            "TerminateProcess",
            "IsWindowsVistaOrGreater",
            "SetHandleInformation",
            "NtQueryInfoProcess",
            "NtYieldExecution",
            "FindWindow",
            "GetWindowThreadProcessId",
        ]

        detections = [
            api_call for api_call in antidbg_api_calls if api_call in ApiCalls
        ]
        suspicions = [
            api_call for api_call in suspicious_api_calls if api_call in ApiCalls
        ]

        for api_call in detections:
            self.report.IndicateDetection("ANTIDBG " + api_call)
        for api_call in suspicions:
            self.report.IndicateSuspicion("ANTIDBG " + api_call)

    def AntiVM(self, ApiHooks):
        assembly_tricks = {
            "Red Pill": b"\x0f\x01\x0d\x00\x00\x00\x00\xc3",
            "VirtualPc trick": b"\x0f\x3f\x07\x0b",
            "VMware trick": b"VMXh",
            "VMCheck.dll": b"\x45\xC7\x00\x01",
            "VMCheck.dll for VirtualPC": b"\x0f\x3f\x07\x0b\xc7\x45\xfc\xff\xff\xff\xff",
            "Xen": b"XenVMM",
            "Bochs & QEmu CPUID Trick": b"\x44\x4d\x41\x63",
            "Torpig VMM Trick": b"\xE8\xED\xFF\xFF\xFF\x25\x00\x00\x00\xFF\x33\xC9\x3D\x00\x00\x00\x80\x0F\x95\xC1\x8B\xC1\xC3",
            "Torpig (UPX) VMM Trick": b"\x51\x51\x0F\x01\x27\x00\xC1\xFB\xB5\xD5\x35\x02\xE2\xC3\xD1\x66\x25\x32\xBD\x83\x7F\xB7\x4E\x3D\x06\x80\x0F\x95\xC1\x8B\xC1\xC3",
        }
        registry_tricks = {
            "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0",
            "HARDWARE\\Description\\System",
            "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0",
            "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 1\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0",
            "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 2\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0",
            "SYSTEM\\ControlSet001\\Control\\SystemInformation",
            "HARDWARE\\ACPI\\DSDT\\VBOX__ (VBOX)",
            "HARDWARE\\ACPI\\FADT\\VBOX__ (VBOX)",
            "HARDWARE\\ACPI\\RSDT\\VBOX__ (VBOX)",
            "SOFTWARE\\Oracle\\VirtualBox Guest Additions (VBOX)",
            "SYSTEM\\ControlSet001\\Services\\VBoxGuest (VBOX)",
            "SYSTEM\\ControlSet001\\Services\\VBoxMouse (VBOX)",
            "SYSTEM\\ControlSet001\\Services\\VBoxService (VBOX)",
            "SYSTEM\\ControlSet001\\Services\\VBoxSF (VBOX)",
            "SYSTEM\\ControlSet001\\Services\\VBoxVideo (VBOX)",
            "SOFTWARE\\VMware, Inc.\\VMware Tools (VMWARE)",
            "SOFTWARE\\Wine (WINE)",
            "SOFTWARE\\Microsoft\\Virtual Machine\\Guest\\Parameters (HYPER-V)",
            "SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum",
            "SYSTEM\\CurrentControlSet\\Enum\\IDE",
            "SYSTEM\\CurrentControlSet\\Enum\\SCSI",
        }
        file_tricks = {
            "system32\\drivers\\VBoxMouse.sys",
            "system32\\drivers\\VBoxGuest.sys",
            "system32\\drivers\\VBoxSF.sys",
            "system32\\drivers\\VBoxVideo.sys",
            "system32\\vboxdisp.dll",
            "system32\\vboxhook.dll",
            "system32\\vboxmrxnp.dll",
            "system32\\vboxogl.dll",
            "system32\\vboxoglarrayspu.dll",
            "system32\\vboxoglcrutil.dll",
            "system32\\vboxoglerrorspu.dll",
            "system32\\vboxoglfeedbackspu.dll",
            "system32\\vboxoglpackspu.dll",
            "system32\\vboxoglpassthroughspu.dll",
            "system32\\vboxservice.exe",
            "system32\\vboxtray.exe",
            "system32\\VBoxControl.exe",
            "system32\\drivers\\vmmouse.sys",
            "system32\\drivers\\vmhgfs.sys",
            "system32\\drivers\\vm3dmp.sys",
            "system32\\drivers\\vmci.sys",
            "system32\\drivers\\vmhgfs.sys",
            "system32\\drivers\\vmmemctl.sys",
            "system32\\drivers\\vmmouse.sys",
            "system32\\drivers\\vmrawdsk.sys",
            "system32\\drivers\\vmusbmouse.sys",
        }
        directory_tricks = {
            "%PROGRAMFILES%\\oracle\\virtualbox guest additions",
            "%PROGRAMFILES%\\VMWare",
        }
        pe_file = open(self.file, "rb")
        buf = pe_file.read()
        for trick in assembly_tricks:
            pos = buf.find(assembly_tricks[trick])
            if pos > -1:
                self.report.IndicateDetection(("ANTIVM 0x%x %s" % (pos, trick)))

        for apicall in ApiHooks:
            if "File" in apicall[0]:
                if apicall[1] in file_tricks:
                    self.report.IndicateDetection("ANTIVM " + apicall[1])
            elif "Reg" in apicall[0]:
                if apicall[1] in registry_tricks:
                    self.report.IndicateDetection("ANTIVM " + apicall[1])
            elif "Directory" in apicall[0]:
                if apicall[1] in directory_tricks:
                    self.report.IndicateDetection("ANTIVM " + apicall[1])

    def AntiSandBox(self, ApiCalls):
        anti_sandbox = [
            "NtDelayExecution",
            "Sleep",
            "CreateTimerQueue",
            "CreateTimerQueueTimer",
            "WaitForSingleObject",
            "CreateWaitableTimer",
            "IcmpSendEcho",
            "__cpuid",
            "__rdtsc",
            "SetTimer",
        ]
        for apicall in ApiCalls:
            if apicall in anti_sandbox:
                self.report.IndicateSuspicion("ANTISANDBOX " + apicall)

    def DLLInjection(self, ApiCalls):
        dll_injection = [
            "CreateRemoteThread",
            "SetWindowsHooksEx",
            "NtCreateThreadEx",
            "RtlCreateUserThread",
        ]
        for apicall in ApiCalls:
            if apicall in dll_injection:
                self.report.IndicateDetection("DLL INJECTION " + apicall)

    def run(self, ApiCalls, ApiHooks):

        self.AntiDbg(ApiCalls)
        self.AntiVM(ApiHooks)
        self.AntiSandBox(ApiCalls)
        self.DLLInjection(ApiCalls)
