// 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()); }
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); }
public override string GetLuaType() { return(extendedType == LuaHelpers.GetIntegerNumberExtendedType() ? "int" : "double"); }
// .. 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); }
// + - 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); }
// * / 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); }
// 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()); }
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); }
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}'")); }
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(); }
public ScriptableSink(Lua vm) { LuaVm = vm; LuaHelpers.RegisterLuaFunctions(LuaVm, this); }