mirror of
https://github.com/KingKDot/PowerCrypt
synced 2026-06-06 16:04:30 +00:00
108 lines
4.7 KiB
C#
108 lines
4.7 KiB
C#
using PowerCrypt.Obfuscator.Helpers.globals;
|
|
using PowerCrypt.Settings;
|
|
using Spectre.Console;
|
|
using System.Management.Automation.Language;
|
|
using System.Text;
|
|
|
|
namespace PowerCrypt.Obfuscator.Passes
|
|
{
|
|
public class PrePass
|
|
{
|
|
public static string DoPrePrePass(string code)
|
|
{
|
|
if (AppSettings.InsertDecryptFunction)
|
|
{
|
|
Globals.CompressFunctionName = AppSettings.DecryptFunctionName;
|
|
|
|
var customDecryptCode = $"function {AppSettings.DecryptFunctionName} {{param ([string] $inputString);$compressedBytes = [Convert]::FromBase64String($inputString);$memoryStream = [System.IO.MemoryStream]::new($compressedBytes);$decompressedStream = [System.IO.Compression.GzipStream]::new($memoryStream, [System.IO.Compression.CompressionMode]::Decompress);$decompressedStream = [System.IO.Compression.GzipStream]::new([System.IO.MemoryStream]::new($compressedBytes), [System.IO.Compression.CompressionMode]::Decompress);$decompressedStreamReader = [System.IO.StreamReader]::new($decompressedStream);$decompressedString = $decompressedStreamReader.ReadToEnd();return $decompressedString}}\n\n";
|
|
|
|
ScriptBlockAst ast = (ScriptBlockAst)Parser.ParseInput(code, out _, out _);
|
|
var firstNamedBlock = ast.FindAll(item => item is NamedBlockAst, false).FirstOrDefault() as NamedBlockAst;
|
|
|
|
if (firstNamedBlock != null)
|
|
{
|
|
var firstChild = firstNamedBlock.FindAll(item => !(item is NamedBlockAst), true)
|
|
.FirstOrDefault();
|
|
|
|
if (firstChild != null)
|
|
{
|
|
int insertPosition = firstChild.Extent.StartOffset;
|
|
AnsiConsole.MarkupInterpolated($"[yellow]First child found; inserting decrypt code at position {insertPosition}[/]\n");
|
|
code = code.Insert(insertPosition, customDecryptCode);
|
|
}
|
|
else
|
|
{
|
|
AnsiConsole.MarkupLine("[red]No first child found; prepending decrypt code.[/]");
|
|
code = customDecryptCode + code;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AnsiConsole.MarkupLine("[red]No first named block found; prepending decrypt code.[/]");
|
|
code = customDecryptCode + code;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Globals.CompressFunctionName = "DecodeAndDecompressString";
|
|
}
|
|
|
|
if (AppSettings.ProcessExpandableStrings)
|
|
{
|
|
code = SplitExpandableStrings(code);
|
|
}
|
|
|
|
return code;
|
|
}
|
|
|
|
|
|
public static string SplitExpandableStrings(string code)
|
|
{
|
|
ScriptBlockAst ast = (ScriptBlockAst)Parser.ParseInput(code, out _, out _);
|
|
var expandableStrings = ast.FindAll(item => item is ExpandableStringExpressionAst, true).ToList();
|
|
|
|
var obfuscatedCode = new StringBuilder(code);
|
|
|
|
foreach (ExpandableStringExpressionAst expandableString in expandableStrings)
|
|
{
|
|
var parts = new List<string>();
|
|
int lastIndex = expandableString.Extent.StartOffset;
|
|
|
|
foreach (var nestedAst in expandableString.NestedExpressions)
|
|
{
|
|
if (nestedAst.Extent.StartOffset > lastIndex)
|
|
{
|
|
string plainText = code.Substring(lastIndex, nestedAst.Extent.StartOffset - lastIndex);
|
|
if (!string.IsNullOrEmpty(plainText))
|
|
{
|
|
parts.Add($"\"{plainText}\"");
|
|
}
|
|
}
|
|
|
|
parts.Add(nestedAst.Extent.Text);
|
|
lastIndex = nestedAst.Extent.EndOffset;
|
|
}
|
|
|
|
if (lastIndex < expandableString.Extent.EndOffset)
|
|
{
|
|
string remainingText = code.Substring(lastIndex, expandableString.Extent.EndOffset - lastIndex);
|
|
if (!string.IsNullOrEmpty(remainingText))
|
|
{
|
|
parts.Add($"\"{remainingText}\"");
|
|
}
|
|
}
|
|
|
|
string newExpression = $"{string.Join(" + ", parts)}";
|
|
newExpression = newExpression.Substring(1, newExpression.Length - 2);
|
|
|
|
newExpression = $"({newExpression})";
|
|
|
|
obfuscatedCode.Replace(expandableString.Extent.Text, newExpression);
|
|
}
|
|
string output = obfuscatedCode.ToString();
|
|
|
|
return output;
|
|
}
|
|
}
|
|
}
|