private static bool GuessPointerNode(IntPtr address, IProcessReader process, out BaseNode node)
        {
            Contract.Requires(process != null);

            node = null;

            if (address.IsNull())
            {
                return(false);
            }

            var section = process.GetSectionToPointer(address);

            if (section == null)
            {
                return(false);
            }

            if (section.Category == SectionCategory.CODE)             // If the section contains code, it should be a function pointer.
            {
                node = new FunctionPtrNode();

                return(true);
            }
            if (section.Category == SectionCategory.DATA || section.Category == SectionCategory.HEAP)             // If the section contains data, it is at least a pointer to a class or something.
            {
                // Check if it is a vtable. Check if the first 3 values are pointers to a code section.
                var possibleVmt = process.ReadRemoteObject <ThreePointersData>(address);
                if (process.GetSectionToPointer(possibleVmt.Pointer1)?.Category == SectionCategory.CODE &&
                    process.GetSectionToPointer(possibleVmt.Pointer2)?.Category == SectionCategory.CODE &&
                    process.GetSectionToPointer(possibleVmt.Pointer3)?.Category == SectionCategory.CODE)
                {
                    node = new VirtualMethodTableNode();

                    return(true);
                }

                // Check if it is a string.
                var data = process.ReadRemoteMemory(address, IntPtr.Size * 2);
                if (data.Take(IntPtr.Size).InterpretAsSingleByteCharacter().IsLikelyPrintableData())
                {
                    node = new Utf8TextPtrNode();

                    return(true);
                }
                if (data.InterpretAsDoubleByteCharacter().IsLikelyPrintableData())
                {
                    node = new Utf16TextPtrNode();

                    return(true);
                }

                // Now it could be a pointer to something else but we can't tell. :(
                node = new PointerNode();

                return(true);
            }

            return(false);
        }
Exemple #2
0
        public void Load(string filePath, ILogger logger)
        {
            using (var connection = new SQLiteConnection($"Data Source={filePath}"))
            {
                connection.Open();

                var classes = new Dictionary <int, ClassNode>();
                var vtables = new Dictionary <int, VirtualMethodTableNode>();

                foreach (var row in Query(connection, "SELECT tbl_name FROM sqlite_master WHERE tbl_name LIKE 'class%'"))
                {
                    var id = Convert.ToInt32(row["tbl_name"].ToString().Substring(5));

                    var classRow = Query(connection, $"SELECT variable, comment FROM class{id} WHERE type = 2 LIMIT 1").FirstOrDefault();
                    if (classRow == null)
                    {
                        continue;
                    }

                    // Skip the vtable classes.
                    if (classRow["variable"].ToString() == "VTABLE")
                    {
                        var vtableNode = new VirtualMethodTableNode();

                        Query(connection, $"SELECT variable, comment FROM class{id} WHERE type = 16")
                        .Select(e => new VirtualMethodNode
                        {
                            Name    = Convert.ToString(e["variable"]),
                            Comment = Convert.ToString(e["comment"])
                        })
                        .ForEach(vtableNode.AddNode);

                        foreach (var method in vtableNode.Nodes.Where(m => m.Name == "void function()"))
                        {
                            method.Name = string.Empty;
                        }

                        vtables.Add(id, vtableNode);

                        continue;
                    }

                    var node = new ClassNode(false)
                    {
                        Name    = classRow["variable"].ToString(),
                        Comment = classRow["comment"].ToString()
                    };

                    project.AddClass(node);

                    classes.Add(id, node);
                }

                foreach (var kv in classes)
                {
                    ReadNodeRows(
                        Query(connection, $"SELECT variable, comment, type, length, ref FROM class{kv.Key} WHERE type != 2"),
                        kv.Value,
                        classes,
                        vtables,
                        logger
                        ).ForEach(kv.Value.AddNode);
                }
            }
        }