예제 #1
0
        /// <summary>
        /// Get instructions from stream
        /// </summary>
        /// <param name="initClass">Init class</param>
        /// <param name="result">Result</param>
        public virtual bool TryParse(object initClass, ref ReverseResult result)
        {
            uint insNumber = 0;
            uint offset    = 0;

            if (result == null)
            {
                result = new ReverseResult()
                {
                }
            }
            ;

            if (initClass == null || !(initClass is IInitClassStream ics))
            {
                return(false);
            }

            byte[] all;
            OffsetRelationCache offsetCache = new OffsetRelationCache();
            List <Instruction>  recallJump  = new List <Instruction>();
            List <Instruction>  calls       = new List <Instruction>();

            PrapareResultForOcurrences(result);

            using (MemoryStream ms = new MemoryStream())
            {
                foreach (StreamModule module in ics.GetStream())
                {
                    Types.Module mAdd = new Types.Module()
                    {
                        Name  = module.Name,
                        Start = new IndexOffset()
                        {
                            Offset = (uint)ms.Position,
                            Index  = (uint)result.Instructions.Count
                        },
                        Color = module.Color
                    };

                    Method mEntryPoint = new Method()
                    {
                        Start = mAdd.Start,
                        Name  = "EntryPoint of " + module.Name,
                    };

                    Instruction lastIns = null;

                    try
                    {
                        if (module.Stream is FileStream fi && Path.GetExtension(fi.Name).ToLowerInvariant() == ".json")
                        {
                            #region load file if are json FileStream
                            long originalPos = module.Stream.Position;
                            all = new byte[module.Stream.Length - originalPos];
                            module.Stream.Read(all, 0, all.Length);

                            string json = Encoding.UTF8.GetString(all, 0, all.Length);

                            result = JsonHelper.Deserialize <ReverseResult>(json, true);
                            if (result != null)
                            {
                                // Prepare ocurrences
                                PrapareResultForOcurrences(result);

                                // Fill cache
                                offsetCache.FillWith(result.Instructions);

                                // Process instructions (Jumps)
                                using (MemoryStream msX = new MemoryStream())
                                {
                                    foreach (Instruction i in result.Instructions)
                                    {
                                        ProcessInstruction(result.Instructions, i, offsetCache);

                                        // Recall jumps
                                        if (i.Jump != null && i.Jump.To != null &&
                                            offsetCache.TryGetValue(i.Jump.To.Offset, out uint index, OffsetIndexRelation.OffsetToIndex))
                                        {
                                            i.Jump.To.Index = index;
                                        }

                                        i.Write(msX);
                                    }
                                    result.Bytes = msX.ToArray();
                                }

                                // Regenerate borders
                                result.StyleMethodBorders();
                                // Regenerate ocurrences
                                result.GenerateOcurrences();
                                return(result.Instructions.Count > 0);
                            }

                            module.Stream.Seek(originalPos, SeekOrigin.Begin);
                            #endregion
                        }

                        long max = module.Stream.Length;
                        int  percent = 0, newPercent = 0;

                        while (true)
                        {
                            byte[] opCode = new byte[OpCodeSize];

                            if (module.Stream.Read(opCode, 0, OpCodeSize) != OpCodeSize)
                            {
                                break;
                            }

                            string key = opCode.ToHexString();

                            if (!OpCodeCache.TryGetValue(key, out OpCodeArgumentAttribute read) || read == null)
                            {
                                throw (new OpCodeNotFoundException()
                                {
                                    Offset = offset,
                                    OpCode = opCode,
                                });
                            }

                            OpCodeEmptyArgument arg = read.Create();
                            uint rBytes             = arg.Read(module.Stream);

                            lastIns = new Instruction()
                            {
                                OpCode = new OpCode()
                                {
                                    RawValue    = opCode,
                                    Name        = read.OpCode,
                                    Description = read.Description,
                                    Flags       = read.Flags
                                },
                                Argument = arg.GetType() == typeof(OpCodeEmptyArgument) ? null : arg,
                                Comment  = arg.ASCIIValue,
                                Color    = mAdd.Color,
                            };

                            lastIns.Location.Index  = insNumber;
                            lastIns.Location.Offset = offset;

                            offsetCache.Add(lastIns.Location);

                            ProcessInstruction(result.Instructions, lastIns, offsetCache);

                            if (lastIns.OpCode.Flags.HasFlag(OpCodeFlag.IsCall))
                            {
                                calls.Add(lastIns);
                            }
                            else
                            {
                                if (mEntryPoint != null && lastIns.OpCode.Flags.HasFlag(OpCodeFlag.IsRet))
                                {
                                    mEntryPoint.End = lastIns.Location;

                                    mAdd.Methods.Add(mEntryPoint);
                                    mEntryPoint = null;
                                }
                            }

                            // Recall jumps
                            if (lastIns.Jump != null && !lastIns.Jump.IsDynamic && lastIns.Jump.To.Index == uint.MaxValue)
                            {
                                recallJump.Add(lastIns);
                            }

                            result.Instructions.Add(lastIns);

                            offset += (uint)(rBytes + OpCodeSize);
                            insNumber++;

                            newPercent = (int)((module.Stream.Position * 100) / max);
                            if (percent != newPercent)
                            {
                                percent = newPercent;
                                OnParseProgress?.Invoke(this, percent);
                            }

                            lastIns.Write(ms);
                        }

                        if (mEntryPoint != null)
                        {
                            mEntryPoint.End = lastIns.Location;

                            mAdd.Methods.Add(mEntryPoint);
                            mEntryPoint = null;
                        }
                    }
                    catch (Exception er)
                    {
                        result = null;
                        throw (er);
                    }
                    finally
                    {
                        if (module != null)
                        {
                            module.Dispose();
                        }
                    }

                    long pos = ms.Position;
                    mAdd.End  = lastIns.Location;
                    mAdd.Size = (uint)(pos - mAdd.Start.Offset);

                    ms.Seek(mAdd.Start.Offset, SeekOrigin.Begin);

                    all = new byte[mAdd.Size];
                    ms.Read(all, 0, all.Length);

                    using (SHA1 sha = SHA1.Create())
                        mAdd.Hash = sha.ComputeHash(all, 0, all.Length).ToHexString();

                    result.Modules.Add(mAdd);
                }

                result.Bytes = ms.ToArray();
            }

            // Recall jumps
            foreach (Instruction j in recallJump)
            {
                if (offsetCache.TryGetValue(j.Jump.To.Offset, out uint index, OffsetIndexRelation.OffsetToIndex))
                {
                    j.Jump.To.Index = index;
                }
                else
                {
                    // If enter here, there will be an error
                    j.Jump = null;
                }
            }
예제 #2
0
        public async Task <DataTable> ExecQuery(string Query)
        {
            var result = await connection.PostAsync("/bitrix/admin/sql.php?PAGEN_1=1&SHOWALL_1=1&lang=ru&mode=frame&table_id=tbl_sql",
                                                    new FormUrlEncodedContent(new Dictionary <string, string>
            {
                { "query", Query },
                { "sessid", SessionID }
            })).ConfigureAwait(false);

            var resp = await result.Content.ReadAsStringAsync().ConfigureAwait(false);

            if (result.StatusCode != System.Net.HttpStatusCode.OK)
            {
                throw new Exception(resp);
            }

            bool success = false;

            time = 0;

            DataTable data = new DataTable();

            using (var context = (BrowsingContext)BrowsingContext.New(Configuration.Default))
            {
                using (var document = await context.OpenAsync(req => req.Content(resp)).ConfigureAwait(false))
                {
                    success = document.QuerySelector("div.adm-info-message-green") != null;

                    if (!success)
                    {
                        throw new Exception("Ошибка выполнения запроса.");
                    }

                    document.Domain = this.domain;
                    var header = ((IHtmlTableElement)document.QuerySelector("table#tbl_sql")).Head;
                    foreach (var cell in header.Rows[0].Cells)
                    {
                        data.Columns.Add(new DataColumn(cell.TextContent.TrimStart(new char[] { '\t', '\n' }).TrimEnd(new char[] { '\t', '\n' }), Type.GetType("System.String")));
                    }

                    var   rows      = ((IHtmlTableElement)document.QuerySelector("table#tbl_sql")).Bodies[0].Rows;
                    float totalRows = rows.Length;
                    foreach (var row in rows)
                    {
                        var datarow = data.NewRow();
                        int i       = 0;
                        foreach (var cell in row.Cells)
                        {
                            datarow[i++] = cell.Text();
                        }
                        data.Rows.Add(datarow);
                        OnParseProgress?.Invoke(data.Rows.Count / totalRows);
                    }

                    time = float.Parse(document.QuerySelector("div.adm-info-message").QuerySelector("b").InnerHtml.Replace(".", ","));
                }
            }

            LastQuery = Query;
            return(data);
        }