예제 #1
0
        // not -
        public LuaValueDataBase EvaluateUnary()
        {
            if (TryTakeNamedToken("not"))
            {
                LuaValueDataBase lhs = EvaluateUnary();

                if (lhs as LuaValueDataError != null)
                {
                    return(lhs);
                }

                return(new LuaValueDataBool(!CoerceToBool(lhs)));
            }

            if (TryTakeToken("-"))
            {
                LuaValueDataBase lhs = EvaluateUnary();

                if (lhs as LuaValueDataError != null)
                {
                    return(lhs);
                }

                var lhsAsNumber = CoerceToNumber(lhs);

                if (lhsAsNumber == null)
                {
                    return(Report("value of the unary '-' operator must be a number"));
                }

                if (lhsAsNumber.extendedType == LuaHelpers.GetIntegerNumberExtendedType())
                {
                    return(new LuaValueDataNumber(-(int)lhsAsNumber.value));
                }

                return(new LuaValueDataNumber(-lhsAsNumber.value));
            }

            return(EvaluateTerminal());
        }
예제 #2
0
        internal static string EvaluateValueAtLuaValue(DkmProcess process, LuaValueDataBase valueBase, uint radix, out string editableValue, ref DkmEvaluationResultFlags flags, out DkmDataAddress dataAddress, out string type)
        {
            editableValue = null;
            dataAddress   = null;
            type          = "unknown";

            if (valueBase == null)
            {
                return(null);
            }

            if (valueBase as LuaValueDataNil != null)
            {
                type = "nil";

                flags |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.ReadOnly;
                return("nil");
            }

            if (valueBase as LuaValueDataBool != null)
            {
                var value = valueBase as LuaValueDataBool;

                type = "bool";

                if (value.value)
                {
                    flags        |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.Boolean | DkmEvaluationResultFlags.BooleanTrue;
                    editableValue = $"{value.value}";
                    return("true");
                }
                else
                {
                    flags        |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.Boolean;
                    editableValue = $"{value.value}";
                    return("false");
                }
            }

            if (valueBase as LuaValueDataLightUserData != null)
            {
                var value = valueBase as LuaValueDataLightUserData;

                type = "user_data";

                flags        |= DkmEvaluationResultFlags.IsBuiltInType;
                editableValue = $"{value.value}";
                return($"0x{value.value:x}");
            }

            if (valueBase as LuaValueDataNumber != null)
            {
                var value = valueBase as LuaValueDataNumber;

                if (value.extendedType == LuaHelpers.GetIntegerNumberExtendedType())
                {
                    type = "int";

                    flags        |= DkmEvaluationResultFlags.IsBuiltInType;
                    editableValue = $"{value.value}";

                    if (radix == 16)
                    {
                        return($"0x{(int)value.value:x8}");
                    }

                    return($"{value.value}");
                }
                else
                {
                    type = "double";

                    flags        |= DkmEvaluationResultFlags.IsBuiltInType;
                    editableValue = $"{value.value}";
                    return($"{value.value}");
                }
            }

            if (valueBase as LuaValueDataString != null)
            {
                var value = valueBase as LuaValueDataString;

                type = value.extendedType == LuaExtendedType.ShortString ? "short_string" : "long_string";

                flags        |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.RawString;
                editableValue = $"{value.value}";
                dataAddress   = DkmDataAddress.Create(process.GetNativeRuntimeInstance(), value.targetAddress, null);
                return($"0x{value.targetAddress:x} \"{value.value}\"");
            }

            if (valueBase as LuaValueDataTable != null)
            {
                var value = valueBase as LuaValueDataTable;

                type = "table";

                flags |= DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable;

                var arrayElementCount = value.value.GetArrayElementCount(process);
                var nodeElementCount  = value.value.GetNodeElementCount(process);

                if (arrayElementCount != 0 && nodeElementCount != 0)
                {
                    return($"0x{value.targetAddress:x} table [{arrayElementCount} element(s) and {nodeElementCount} key(s)]");
                }

                if (arrayElementCount != 0)
                {
                    return($"0x{value.targetAddress:x} table [{arrayElementCount} element(s)]");
                }

                if (nodeElementCount != 0)
                {
                    return($"0x{value.targetAddress:x} table [{nodeElementCount} key(s)]");
                }

                if (!value.value.HasMetaTable())
                {
                    flags &= ~DkmEvaluationResultFlags.Expandable;

                    return($"0x{value.targetAddress:x} table [empty]");
                }

                return($"0x{value.targetAddress:x} table");
            }

            if (valueBase as LuaValueDataLuaFunction != null)
            {
                var value = valueBase as LuaValueDataLuaFunction;

                type = "lua_function";

                flags |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable;
                return($"0x{value.targetAddress:x}");
            }

            if (valueBase as LuaValueDataExternalFunction != null)
            {
                var value = valueBase as LuaValueDataExternalFunction;

                type = "c_function";

                flags |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable;
                return($"0x{value.targetAddress:x}");
            }

            if (valueBase as LuaValueDataExternalClosure != null)
            {
                var value = valueBase as LuaValueDataExternalClosure;

                type = "c_closure";

                flags |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable;
                return($"0x{value.targetAddress:x}");
            }

            if (valueBase as LuaValueDataUserData != null)
            {
                var value = valueBase as LuaValueDataUserData;

                type = "user_data";

                flags |= DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable;
                return($"0x{value.targetAddress:x}");
            }

            if (valueBase as LuaValueDataThread != null)
            {
                var value = valueBase as LuaValueDataThread;

                type = "thread";

                flags |= DkmEvaluationResultFlags.IsBuiltInType | DkmEvaluationResultFlags.ReadOnly;
                return($"0x{value.targetAddress:x}");
            }

            return(null);
        }
예제 #3
0
 public override string GetLuaType()
 {
     return(extendedType == LuaHelpers.GetIntegerNumberExtendedType() ? "int" : "double");
 }
예제 #4
0
        // ..
        public LuaValueDataBase EvaluateConcatenation()
        {
            LuaValueDataBase lhs = EvaluateAdditive();

            if (lhs as LuaValueDataError != null)
            {
                return(lhs);
            }

            if (TryTakeToken(".."))
            {
                LuaValueDataBase rhs = EvaluateAdditive();

                if (rhs as LuaValueDataError != null)
                {
                    return(rhs);
                }

                var lhsAsNumber = lhs as LuaValueDataNumber;
                var lhsAsString = lhs as LuaValueDataString;

                if (lhsAsNumber == null && lhsAsString == null)
                {
                    return(Report("lhs of a concatenation operator must be a number or a string"));
                }

                var rhsAsNumber = rhs as LuaValueDataNumber;
                var rhsAsString = rhs as LuaValueDataString;

                if (rhsAsNumber == null && rhsAsString == null)
                {
                    return(Report("rhs of a concatenation operator must be a number or a string"));
                }

                string lhsString = lhsAsNumber != null ? (lhsAsNumber.extendedType == LuaHelpers.GetIntegerNumberExtendedType() ? $"{(int)lhsAsNumber.value}" : $"{lhsAsNumber.value}") : lhsAsString.value;
                string rhsString = rhsAsNumber != null ? (rhsAsNumber.extendedType == LuaHelpers.GetIntegerNumberExtendedType() ? $"{(int)rhsAsNumber.value}" : $"{rhsAsNumber.value}") : rhsAsString.value;

                return(new LuaValueDataString(lhsString + rhsString));
            }

            return(lhs);
        }
예제 #5
0
        // + -
        public LuaValueDataBase EvaluateAdditive()
        {
            LuaValueDataBase lhs = EvaluateMultiplicative();

            if (lhs as LuaValueDataError != null)
            {
                return(lhs);
            }

            string token = TryTakeOneOfTokens(new[] { "+", "-" });

            if (token != null)
            {
                var lhsAsNumber = CoerceToNumber(lhs);

                if (lhsAsNumber == null)
                {
                    return(Report("lhs of a numeric binary operator must be a number"));
                }

                LuaValueDataBase rhs = EvaluateMultiplicative();

                if (rhs as LuaValueDataError != null)
                {
                    return(rhs);
                }

                var rhsAsNumber = CoerceToNumber(rhs);

                if (rhsAsNumber == null)
                {
                    return(Report("rhs of a '+' binary operator must be a number"));
                }

                if (token == "+")
                {
                    if (lhsAsNumber.extendedType == LuaHelpers.GetIntegerNumberExtendedType() && rhsAsNumber.extendedType == LuaHelpers.GetIntegerNumberExtendedType())
                    {
                        return(new LuaValueDataNumber((int)lhsAsNumber.value + (int)rhsAsNumber.value));
                    }

                    return(new LuaValueDataNumber(lhsAsNumber.value + rhsAsNumber.value));
                }

                if (token == "-")
                {
                    if (lhsAsNumber.extendedType == LuaHelpers.GetIntegerNumberExtendedType() && rhsAsNumber.extendedType == LuaHelpers.GetIntegerNumberExtendedType())
                    {
                        return(new LuaValueDataNumber((int)lhsAsNumber.value - (int)rhsAsNumber.value));
                    }

                    return(new LuaValueDataNumber(lhsAsNumber.value - rhsAsNumber.value));
                }
            }

            return(lhs);
        }
예제 #6
0
        // * /
        public LuaValueDataBase EvaluateMultiplicative()
        {
            LuaValueDataBase lhs = EvaluateUnary();

            if (lhs as LuaValueDataError != null)
            {
                return(lhs);
            }

            string token = TryTakeOneOfTokens(new[] { "*", "/" });

            if (token != null)
            {
                var lhsAsNumber = CoerceToNumber(lhs);

                if (lhsAsNumber == null)
                {
                    return(Report("lhs of a numeric binary operator must be a number"));
                }

                LuaValueDataBase rhs = EvaluateUnary();

                if (rhs as LuaValueDataError != null)
                {
                    return(rhs);
                }

                var rhsAsNumber = CoerceToNumber(rhs);

                if (rhsAsNumber == null)
                {
                    return(Report("rhs of a numeric binary operator must be a number"));
                }

                if (token == "*")
                {
                    if (lhsAsNumber.extendedType == LuaHelpers.GetIntegerNumberExtendedType() && rhsAsNumber.extendedType == LuaHelpers.GetIntegerNumberExtendedType())
                    {
                        return(new LuaValueDataNumber((int)lhsAsNumber.value * (int)rhsAsNumber.value));
                    }

                    return(new LuaValueDataNumber(lhsAsNumber.value * rhsAsNumber.value));
                }

                if (token == "/")
                {
                    // Always floating-point
                    return(new LuaValueDataNumber(lhsAsNumber.value / rhsAsNumber.value));
                }
            }

            return(lhs);
        }
예제 #7
0
        // not - #
        public LuaValueDataBase EvaluateUnary()
        {
            if (TryTakeNamedToken("not"))
            {
                LuaValueDataBase lhs = EvaluateUnary();

                if (lhs as LuaValueDataError != null)
                {
                    return(lhs);
                }

                return(new LuaValueDataBool(!CoerceToBool(lhs)));
            }

            if (TryTakeToken("-"))
            {
                LuaValueDataBase lhs = EvaluateUnary();

                if (lhs as LuaValueDataError != null)
                {
                    return(lhs);
                }

                var lhsAsNumber = CoerceToNumber(lhs);

                if (lhsAsNumber == null)
                {
                    return(Report("value of the unary '-' operator must be a number"));
                }

                if (lhsAsNumber.extendedType == LuaHelpers.GetIntegerNumberExtendedType())
                {
                    return(new LuaValueDataNumber(-(int)lhsAsNumber.value));
                }

                return(new LuaValueDataNumber(-lhsAsNumber.value));
            }

            if (TryTakeToken("#"))
            {
                LuaValueDataBase lhs = EvaluateUnary();

                if (lhs as LuaValueDataError != null)
                {
                    return(lhs);
                }

                if (process == null)
                {
                    return(Report("Can't load value - process memory is not available"));
                }

                if (lhs is LuaValueDataTable table)
                {
                    return(new LuaValueDataNumber(table.value.arraySize));
                }

                if (lhs is LuaValueDataString str)
                {
                    return(new LuaValueDataNumber(str.value.Length));
                }

                return(Report("Value is not a table or a string"));
            }

            return(EvaluateTerminal());
        }
예제 #8
0
        public LuaValueDataBase EvaluatePostExpressions(LuaValueDataBase value)
        {
            if (TryTakeToken(".") || TryTakeToken(":"))
            {
                string name = TryParseIdentifier();

                if (name == null)
                {
                    return(Report("Failed to find member name"));
                }

                if (value is LuaValueDataTable table)
                {
                    value = LookupTableMember(table.value, name);
                }
                else if (value is LuaValueDataUserData userData)
                {
                    if (userData.value.metaTable != null)
                    {
                        value = LookupTableMember(userData.value.metaTable, name);
                    }
                }

                if (value as LuaValueDataError != null)
                {
                    return(value);
                }

                return(EvaluatePostExpressions(value));
            }

            if (TryTakeToken("["))
            {
                var table = value as LuaValueDataTable;

                if (table == null)
                {
                    return(Report("Value is not a table"));
                }

                var index = EvaluateOr();

                if (index as LuaValueDataError != null)
                {
                    return(index);
                }

                if (process == null)
                {
                    return(Report("Can't load table - process memory is not available"));
                }

                // Check array index
                var indexAsNumber = index as LuaValueDataNumber;

                if (indexAsNumber != null && indexAsNumber.extendedType == LuaHelpers.GetIntegerNumberExtendedType())
                {
                    int result = (int)indexAsNumber.value;

                    if (result > 0 && result - 1 < table.value.GetArrayElementCount(process))
                    {
                        if (!TryTakeToken("]"))
                        {
                            return(Report("Failed to find ']' after '['"));
                        }

                        var arrayElements = table.value.GetArrayElements(process);

                        return(EvaluatePostExpressions(arrayElements[result - 1]));
                    }
                }

                foreach (var element in table.value.GetNodeKeys(process))
                {
                    var elementKey = element.LoadKey(process, table.value.batchNodeElementData);

                    if (elementKey.GetType() != index.GetType())
                    {
                        continue;
                    }

                    if (elementKey.LuaCompare(index))
                    {
                        if (!TryTakeToken("]"))
                        {
                            return(Report("Failed to find ']' after '['"));
                        }

                        return(EvaluatePostExpressions(element.LoadValue(process, table.value.batchNodeElementData)));
                    }
                }

                return(Report($"Failed to find key '{index.AsSimpleDisplayString(10)}' in table"));
            }

            return(value);
        }
예제 #9
0
        public LuaValueDataBase LookupVariable(string name)
        {
            if (process == null || functionData == null)
            {
                return(Report($"Can't lookup variable - process memory is not available"));
            }

            for (int i = 0; i < functionData.activeLocals.Count; i++)
            {
                var local = functionData.activeLocals[i];

                if (local.name == name)
                {
                    ulong address = frameBaseAddress + (ulong)i * LuaHelpers.GetValueSize(process);

                    var result = LuaHelpers.ReadValue(process, address);

                    if (result == null)
                    {
                        return(Report($"Failed to read variable '{name}'"));
                    }

                    return(result);
                }
            }

            if (luaClosure != null)
            {
                int envIndex = -1;

                for (int i = 0; i < functionData.upvalues.Count; i++)
                {
                    var upvalue = functionData.upvalues[i];

                    if (upvalue.name == name)
                    {
                        LuaUpvalueData upvalueData = luaClosure.ReadUpvalue(process, i, functionData.upvalueSize);

                        if (upvalueData == null || upvalueData.value == null)
                        {
                            return(Report($"Failed to read variable '{name}'"));
                        }

                        return(upvalueData.value);
                    }

                    if (upvalue.name == "_ENV")
                    {
                        envIndex = i;
                    }
                }

                if (LuaHelpers.luaVersion == 501)
                {
                    var envTable = luaClosure.ReadEnvTable_5_1(process);

                    if (envTable == null)
                    {
                        return(Report($"Failed to read environment value"));
                    }

                    var value = LookupTableMember(envTable, name);

                    if (value as LuaValueDataError == null)
                    {
                        return(value);
                    }
                }
                else
                {
                    // Check _ENV.name
                    if (envIndex != -1)
                    {
                        LuaUpvalueData upvalueData = luaClosure.ReadUpvalue(process, envIndex, functionData.upvalueSize);

                        if (upvalueData == null || upvalueData.value == null)
                        {
                            return(Report($"Failed to read environment value"));
                        }

                        var value = LookupTableValueMember(upvalueData.value, name);

                        if (value as LuaValueDataError == null)
                        {
                            return(value);
                        }
                    }
                }
            }

            return(Report($"Failed to find variable '{name}'"));
        }
예제 #10
0
        public void Handle(GSMParameters param, NormalBurst source, L3Handler l3, byte[] l2Data, int startOffset)
        {
            if (param.PacketDumper != null)
            {
                param.PacketDumper.WriteL2Data(l2Data);
            }

            Builder.Length = 0;

            /* BCCH and CCCH packets have pseudo L2 headers (GSM 04.07 11.3.1) */
            if (source.GetType() == typeof(BCCHBurst) || source.GetType() == typeof(CCCHBurst))
            {
                Builder.Append("Pseudo L2 Header").Append(Environment.NewLine);

                if (source.ChannelEncrypted)
                {
                    Builder.Append("======= encrypted =======").Append(Environment.NewLine);
                }

                /* call LUA script */
                if (param.LuaVm != null)
                {
                    LuaHelpers.CallFunction(param.LuaVm, "L2DataReceived", true, source, null, param);
                }

                /* pass to L3 handler if not empty and skip pseudo length */
                if (!PacketIsEmpty(l2Data, 1))
                {
                    l3.Handle(l2Data, 1, param);
                }
            }
            else
            {
                /* always show empty/multiframe messages if requested */
                ShowMessage = ShowAllMessages;

                /* show if encrypted */
                if (source.ChannelEncrypted)
                {
                    ShowMessage |= ShowCryptedMessages;
                    Builder.Append("======= encrypted =======").Append(Environment.NewLine);
                }

                L2Data.Payload     = l2Data;
                L2Data.StartOffset = startOffset;

                /* call LUA script */
                if (param.LuaVm != null)
                {
                    LuaHelpers.CallFunction(param.LuaVm, "L2DataReceived", true, source, L2Data, param);
                }

                if (L3Handler.ExceptFieldsEnabled || ShowMessage)
                {
                    Builder.Append("SAPI: ").Append(L2Data.SAPI).Append("  C/R: ").Append((L2Data.CR ? "1" : "0")).Append("  EA: ").Append((L2Data.EA ? "1" : "0")).Append("  ");
                    Builder.Append("M: ").Append((L2Data.M ? "1" : "0")).Append("  ");
                    Builder.Append("EL: ").Append((L2Data.EL ? "1" : "0")).Append("  ");
                    Builder.Append("L: ").Append(L2Data.Length).Append("  ");

                    switch (L2Data.FrameFormat)
                    {
                    case eFrameFormat.S_Format:
                        Builder.Append("S Format, N(R)=").Append(L2Data.NR).Append(" S=").Append(L2Data.S).Append(" ").Append((eSupervisory)L2Data.S);
                        break;

                    case eFrameFormat.U_Format:
                        Builder.Append("U Format, U=").Append(L2Data.U).Append(" ").Append((eUnnumbered)L2Data.U);
                        break;

                    case eFrameFormat.I_Format:
                        Builder.Append("I Format, N(R)=").Append(L2Data.NR).Append(" N(S)=").Append(L2Data.NS).Append(" ");
                        break;
                    }
                }

                /* check if there is enough space in the buffer */
                if (L2Data.Length + packetBufferOffset <= packetBuffer.Length && L2Data.Length + L2Data.DataStart <= L2Data.Payload.Length)
                {
                    /* dont buffer when its the same frame number (retransmission) */
                    if (!L2Data.M || LastNS < L2Data.NS)
                    {
                        Array.Copy(L2Data.Payload, L2Data.DataStart, packetBuffer, packetBufferOffset, L2Data.Length);
                        packetBufferOffset += L2Data.Length;
                        LastNS              = L2Data.NS;
                    }
                    else
                    {
                        if (L3Handler.ExceptFieldsEnabled || ShowMessage)
                        {
                            Builder.Append("!! Retransmission !! ");
                        }
                    }
                }
                else
                {
                    if (DumpFaulty)
                    {
                        Builder.Append("Faulty length?! Length = ").Append((packetBufferOffset + L2Data.Length)).Append(Environment.NewLine);
                        Builder.Append("Raw L2 data").Append(Environment.NewLine);
                        Builder.Append("    ").Append(DumpBytes(l2Data)).Append(Environment.NewLine);
                        ShowMessage = true;
                    }
                }

                /* that counter is just for convinience */
                NumPackets++;

                /* when reached the last packet, pass it to L3 handler */
                if (!L2Data.M)
                {
                    if (L3Handler.ExceptFieldsEnabled || ShowMessage)
                    {
                        if (NumPackets > 1)
                        {
                            Builder.Append("(packet ").Append(NumPackets).Append(", total ").Append(packetBufferOffset).Append(" bytes)").Append(Environment.NewLine);
                        }
                        else
                        {
                            Builder.Append(Environment.NewLine);
                        }
                    }

                    /* but only pass it through when there is any data */
                    if (packetBufferOffset > 0)
                    {
                        /* allocate a new array with the correct size */
                        byte[] buf = new byte[packetBufferOffset];
                        Array.Copy(packetBuffer, buf, buf.Length);

                        if (!PacketIsEmpty(buf))
                        {
                            l3.Handle(buf, 0, param);
                        }
                    }

                    /* reset the buffer etc */
                    packetBufferOffset = 0;
                    for (int pos = 0; pos < packetBuffer.Length; pos++)
                    {
                        packetBuffer[pos] = 0xCC;
                    }
                    NumPackets = 0;
                    LastNS     = -1;
                }
                else if (L3Handler.ExceptFieldsEnabled || ShowMessage)
                {
                    Builder.Append("(packet ").Append(NumPackets).Append(")").Append(Environment.NewLine);
                }
            }

            if (DumpRawData && (L3Handler.ExceptFieldsEnabled || ShowMessage))
            {
                Builder.Append("Raw L2 data").Append(Environment.NewLine);
                Builder.Append("    ").Append(DumpBytes(l2Data)).Append(Environment.NewLine);
            }

            StatusMessage = Builder.ToString();
        }
예제 #11
0
 public ScriptableSink(Lua vm)
 {
     LuaVm = vm;
     LuaHelpers.RegisterLuaFunctions(LuaVm, this);
 }