Files
Andrea Cristaldi 492ffc428b First commit
2025-08-28 17:14:35 +02:00

87 lines
2.9 KiB
C#

// DefenderRuleParser
// Author: Andrea Cristaldi 2025 - https://github.com/andreacristaldi/DefenderRuleParser
// This project is licensed under the Apache 2.0 License.
/*
* Summary: Parses embedded LUA-like script fragments when present.
* Origin: dump-driven; string/range harvesting from observed script chunks.
* Role: Surfaces script markers and literals for intel.
*/
using DefenderRuleParser2;
using DefenderRuleParser2.Models;
using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
namespace DefenderRuleParser2.Parsers
{
public class LuaParser : ISignatureParser
{
private static readonly byte[] LuaHeader = new byte[] { 0x1B, 0x4C, 0x75, 0x61 };
public void Parse(BinaryReader reader, int size, uint threatId)
{
long offset = reader.BaseStream.Position;
try
{
byte[] buffer = reader.ReadBytes(size);
int headerIndex = FindLuaHeader(buffer);
if (headerIndex == -1)
{
Logger.Info($"[LUA] Threat ID: {threatId} | Lua header not found.");
return;
}
byte[] luaCode = new byte[buffer.Length - headerIndex];
Array.Copy(buffer, headerIndex, luaCode, 0, luaCode.Length);
string luaPath = Logger.OutputFolder + $"lua_script_{threatId}.lua";
File.WriteAllBytes(luaPath, luaCode);
Logger.Info($"[LUA] Threat ID: {threatId} | Extracted Lua script to: {luaPath}");
if (ThreatDatabase.TryGetThreat(threatId, out var threat))
{
threat.Signatures.Add(new SignatureEntry
{
Type = "SIGNATURE_TYPE_LUASTANDALONE",
Offset = offset,
Pattern = new List<string> { $"Extracted: {luaPath}" },
Parsed = true,
ConditionType = "PRESENT",
ConditionValue = 1
});
}
}
catch (Exception ex)
{
Logger.Error($"[LUA] Error parsing at offset 0x{offset:X}: {ex.Message}");
}
finally
{
reader.BaseStream.Seek(offset + size, SeekOrigin.Begin);
}
}
private int FindLuaHeader(byte[] data)
{
for (int i = 0; i <= data.Length - LuaHeader.Length; i++)
{
bool match = true;
for (int j = 0; j < LuaHeader.Length; j++)
{
if (data[i + j] != LuaHeader[j])
{
match = false;
break;
}
}
if (match) return i;
}
return -1;
}
}
}