Beispiel #1
0
        public void Invoke(Dictionary <string, object> options)
        {
            int id = (int)options["id"];

            Threads.Client client = Threads.CmdEngine.theInstance.GetTargetClient(false);

            if (id >= client.hooks.Count || client.hooks[id].name == null)
            {
                throw new ArgumentException(Program.GetResourceString("Commands.Unhook.NotFound"));
            }

            Threads.HookEntry entry = client.hooks[id];
            // If client is under the current hook, cancel the operation with TargetNotApplicable
            if (client.hookOep == entry.oep)
            {
                throw new ArgumentException(Program.GetResourceString("Threads.CmdEngine.TargetNotApplicable"));
            }

            // Prepare & send CMD_UNHOOK packets
            client.Send(Puppet.Util.Serialize(new Puppet.PACKET_CMD_UNHOOK(0)));
            client.Send(Puppet.Util.Serialize(new Puppet.PACKET_INTEGER(entry.oep)));

            // Expect ACK(0)
            Puppet.PACKET_ACK pktAck;
            pktAck = Puppet.Util.Deserialize <Puppet.PACKET_ACK>(client.Expect(Puppet.PACKET_TYPE.ACK));
            if (pktAck.status != 0)
            {
                throw new ArgumentException(Util.Win32ErrorToMessage((int)pktAck.status));
            }

            // Remove entry from client's hooks
            //client.hooks.Remove(entry); // This will cause following hooks' IDs change
            client.hooks[id] = new Threads.HookEntry();

            Logger.I(Program.GetResourceString("Commands.Unhook.Uninstalled", id, entry.name));
            Threads.Gui.theInstance.InvokeOn((FMain Me) => Me.RefreshGuiHooks());
        }
Beispiel #2
0
        public Dictionary <string, object> Parse(string cmd)
        {
            Threads.HookEntry entry = new Threads.HookEntry();
            entry.beforeActions = new List <Dictionary <string, object> >();
            entry.afterActions  = new List <Dictionary <string, object> >();
            entry.stack         = entry.ret = 0;

            int state = 0; // FSM on option parsing; 0 - Begin, 1 - Convention/Stack, 2 - Before, 3 - After

            OptionSet options = new OptionSet()
            {
                {
                    "before",
                    x =>
                    {
                        FSMTest(1, state);

                        if (x != null)
                        {
                            state = 2;
                        }
                    }
                },
                {
                    "after",
                    x =>
                    {
                        FSMTest(1, state);

                        if (x != null)
                        {
                            state = 3;
                        }
                    }
                },
                {
                    "convention=",
                    x =>
                    {
                        FSMTest(1, state);

                        if (Array.IndexOf(conventionsX86, x) >= 0 || Array.IndexOf(conventionsX64, x) >= 0)
                        {
                            entry.convention = x;
                        }
                        else
                        {
                            throw new ArgumentException("convention");
                        }
                    }
                },
                {
                    "stack:,",
                    (x, y) =>
                    {
                        FSMTest(1, state);

                        try
                        {
                            entry.stack = Convert.ToUInt64(x);
                            if (y != null)
                            {
                                entry.ret = Convert.ToUInt64(y);
                            }
                        }
                        catch
                        {
                            throw new ArgumentException("stack");
                        }
                    }
                },
                {
                    "echo=",
                    x =>
                    {
                        FSMTest(2, state);

                        (state == 2 ? entry.beforeActions : entry.afterActions).Add(new Dictionary <string, object>()
                        {
                            { "verb", "echo" },
                            { "echo", Util.RemoveQuotes(x, true) }
                        });
                    }
                },
                {
                    "dump=,",
                    (x, y) =>
                    {
                        FSMTest(2, state);

                        if (x[0] != '{' || x[x.Length - 1] != '}' || y[0] != '{' || y[y.Length - 1] != '}')
                        {
                            throw new ArgumentException("dump");
                        }

                        (state == 2 ? entry.beforeActions : entry.afterActions).Add(new Dictionary <string, object>()
                        {
                            { "verb", "dump" },
                            { "addr", x.Substring(1, x.Length - 2) },
                            { "size", y.Substring(1, y.Length - 2) }
                        });
                    }
                },
                {
                    "ctx=,",
                    (x, y) =>
                    {
                        FSMTest(2, state);

                        (state == 2 ? entry.beforeActions : entry.afterActions).Add(new Dictionary <string, object>()
                        {
                            { "verb", "ctx" },
                            { "key", Util.RemoveQuotes(x, true) },
                            { "value", Util.RemoveQuotes(y, true) }
                        });
                    }
                },
                {
                    "verdict=",
                    x =>
                    {
                        FSMTest(2, state);

                        if (Array.IndexOf(state == 2 ? verdictsBefore : verdictsAfter, x) < 0)
                        {
                            throw new ArgumentException("verdict");
                        }

                        if (state == 2)
                        {
                            entry.beforeVerdict = x;
                        }
                        else
                        {
                            entry.afterVerdict = x;
                        }
                    }
                },
                {
                    "<>",
                    x =>
                    {
                        FSMTest(0, state);

                        if (x.StartsWith("0x"))
                        {
                            entry.addrMode = "addr";
                            try
                            {
                                entry.addr = UInt64.Parse(x.Substring(2), System.Globalization.NumberStyles.HexNumber);
                            }
                            catch
                            {
                                throw new ArgumentException("addr");
                            }
                        }
                        else if (x[0] == '*')
                        {
                            entry.addrMode = "pattern";
                            try
                            {
                                entry.pattern = PatternToBinary(x);
                            }
                            catch
                            {
                                throw new ArgumentException("pattern");
                            }
                        }
                        else
                        {
                            entry.addrMode = "symbol";
                            entry.symbol   = x;
                        }
                        entry.name = x; // Save hook expression as hook's name
                        state      = 1;
                    }
                }
            };

            Util.ParseOptions(cmd, options);

            return(new Dictionary <string, object>()
            {
                { "verb", "hook" },
                { "entry", entry }
            });
        }
Beispiel #3
0
        public void Invoke(Dictionary <string, object> options)
        {
            Threads.HookEntry entry  = (Threads.HookEntry)options["entry"];
            Threads.Client    client = Threads.CmdEngine.theInstance.GetTargetClient(false);

            if (entry.name == null)
            {
                Logger.I(Program.GetResourceString("Commands.Hook.Header"));

                for (int i = 0; i < client.hooks.Count; i++)
                {
                    Threads.HookEntry hook = client.hooks[i];

                    // Skip the removed hooks
                    if (hook.name == null)
                    {
                        continue;
                    }

                    Logger.I(Program.GetResourceString("Commands.Hook.Format",
                                                       i,
                                                       client.OepToString(hook.oep),
                                                       hook.name
                                                       ));
                }
                return;
            }

            // Check convention or fill in default values
            string[] conventions = (client.bits == 32 ? conventionsX86 : conventionsX64);
            if (entry.convention == null)
            {
                entry.convention = conventions[0];
            }
            else if (Array.IndexOf(conventions, entry.convention) < 0)
            {
                throw new ArgumentException(Program.GetResourceString("Threads.CmdEngine.TargetNotApplicable"));
            }

            // If the hook already exists, overwrite anything but OEP instead
            foreach (Threads.HookEntry hook in client.hooks)
            {
                if (hook.name == entry.name)
                {
                    Logger.W(Program.GetResourceString("Commands.Hook.HookExists", entry.name));
                    entry.oep = hook.oep;
                    client.hooks[client.hooks.IndexOf(hook)] = entry;
                    return;
                }
            }

            // Prepare CMD_HOOK packets
            Puppet.PACKET_CMD_HOOK pktHook = new Puppet.PACKET_CMD_HOOK(0);
            byte[] bufMethod;

            switch (entry.addrMode)
            {
            case "symbol":
                pktHook.method = 0;
                bufMethod      = Puppet.Util.SerializeString(entry.symbol);
                break;

            case "pattern":
                pktHook.method = 1;
                bufMethod      = Puppet.Util.SerializeBinary(entry.pattern);
                break;

            case "addr":
                pktHook.method = 2;
                bufMethod      = Puppet.Util.Serialize(new Puppet.PACKET_INTEGER(entry.addr));
                break;

            default:
                // Input is sanitized so this should not happen
                throw new ArgumentException();
            }

            // Send packets
            client.Send(Puppet.Util.Serialize(pktHook));
            client.Send(bufMethod);

            // Expect ACK(0)
            Puppet.PACKET_ACK pktAck;
            pktAck = Puppet.Util.Deserialize <Puppet.PACKET_ACK>(client.Expect(Puppet.PACKET_TYPE.ACK));
            if (pktAck.status != 0)
            {
                throw new ArgumentException(Util.Win32ErrorToMessage((int)pktAck.status));
            }

            // Fill OEP into entry
            Puppet.PACKET_INTEGER pktOep;
            pktOep    = Puppet.Util.Deserialize <Puppet.PACKET_INTEGER>(client.Expect(Puppet.PACKET_TYPE.INTEGER));
            entry.oep = pktOep.data;

            // Add entry to client's hooks
            int id = client.hooks.Count;

            client.hooks.Add(entry);

            Logger.I(Program.GetResourceString("Commands.Hook.Installed", id, entry.name, client.OepToString(entry.oep)));
            Threads.Gui.theInstance.InvokeOn((FMain Me) => Me.RefreshGuiHooks());
        }