JObfuscator.psm1
|
################################################################################ # # JObfuscator Web API client for PowerShell. # Obfuscate and protect Java source against analysis. # # Version : PowerShell SDK v1.0.0 # PowerShell : Windows PowerShell 5.1 / PowerShell 7+ # Author : Bartosz Wójcik (support@pelock.com) # Project : https://www.pelock.com/products/jobfuscator # Homepage : https://www.pelock.com # ################################################################################ Set-StrictMode -Version Latest if ($PSVersionTable.PSVersion.Major -lt 6) { [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 } Add-Type -AssemblyName System.IO.Compression | Out-Null $script:JoApiUrl = 'https://www.pelock.com/api/jobfuscator/v1' $script:JoUserAgent = 'PELock JObfuscator' $script:JoTimeoutSec = 3600 function Get-JoAdler32 { param([Parameter(Mandatory)] [byte[]]$Data) $modAdler = 65521 $a = 1 $b = 0 foreach ($byte in $Data) { $a = ($a + $byte) % $modAdler $b = ($b + $a) % $modAdler } return [uint32](($b -shl 16) -bor $a) } function Compress-JoZlib { param([Parameter(Mandatory)] [string]$Source) $bytes = [System.Text.Encoding]::UTF8.GetBytes($Source) $ms = New-Object System.IO.MemoryStream try { $deflate = New-Object System.IO.Compression.DeflateStream($ms, [System.IO.Compression.CompressionMode]::Compress, $true) try { $deflate.Write($bytes, 0, $bytes.Length) } finally { $deflate.Dispose() } $deflated = $ms.ToArray() } finally { $ms.Dispose() } $adler = Get-JoAdler32 -Data $bytes $output = New-Object byte[] ($deflated.Length + 6) $output[0] = 0x78 $output[1] = 0xDA [Buffer]::BlockCopy($deflated, 0, $output, 2, $deflated.Length) $output[$output.Length - 4] = [byte](($adler -shr 24) -band 0xFF) $output[$output.Length - 3] = [byte](($adler -shr 16) -band 0xFF) $output[$output.Length - 2] = [byte](($adler -shr 8) -band 0xFF) $output[$output.Length - 1] = [byte]($adler -band 0xFF) return [Convert]::ToBase64String($output) } function Expand-JoZlib { param([Parameter(Mandatory)] [string]$CompressedBase64) $data = [Convert]::FromBase64String($CompressedBase64) if ($data.Length -lt 6) { throw 'Invalid zlib payload.' } $payloadLength = $data.Length - 6 $ms = New-Object System.IO.MemoryStream($data, 2, $payloadLength) try { $deflate = New-Object System.IO.Compression.DeflateStream($ms, [System.IO.Compression.CompressionMode]::Decompress) try { $reader = New-Object System.IO.StreamReader($deflate, [System.Text.Encoding]::UTF8) try { return $reader.ReadToEnd() } finally { $reader.Dispose() } } finally { $deflate.Dispose() } } finally { $ms.Dispose() } } function ConvertTo-JoFormBody { param([Parameter(Mandatory)] [hashtable]$Fields) $parts = foreach ($key in $Fields.Keys) { $name = [uri]::EscapeDataString([string]$key) $value = [uri]::EscapeDataString([string]$Fields[$key]) '{0}={1}' -f $name, $value } return ($parts -join '&') } function Invoke-JoApiRequest { param([Parameter(Mandatory)] [hashtable]$Fields) $body = ConvertTo-JoFormBody -Fields $Fields $headers = @{ 'User-Agent' = $script:JoUserAgent } try { return Invoke-RestMethod -Uri $script:JoApiUrl -Method Post -Body $body ` -ContentType 'application/x-www-form-urlencoded' -Headers $headers ` -TimeoutSec $script:JoTimeoutSec } catch { return $false } } class JObfuscator { static [string] $API_URL = 'https://www.pelock.com/api/jobfuscator/v1' hidden [string] $_api_key = '' [bool] $enable_compression = $true [bool] $array_int_crypt = $true [bool] $array_char_crypt = $true [bool] $array_double_crypt = $true [bool] $array_string_crypt = $true [bool] $remove_comments = $true [bool] $split_strings = $false [bool] $crypt_strings = $true [bool] $rename_methods = $true [bool] $shuffle_methods = $true [bool] $ints_math_crypt = $true [bool] $dbls_math_crypt = $true [bool] $rename_variables = $true [bool] $mix_code_flow = $true [bool] $string_char_vault = $true [bool] $ints_from_double_math = $true [bool] $opaque_mixer_chain = $true [bool] $complexify_booleans = $true [bool] $try_finally_noise = $true [bool] $ints_to_arrays = $true [bool] $dbls_to_arrays = $true static [int] $ERROR_SUCCESS = 0 static [int] $ERROR_INPUT_SIZE = 1 static [int] $ERROR_INPUT = 2 static [int] $ERROR_PARSING = 3 static [int] $ERROR_OBFUSCATION = 4 static [int] $ERROR_OUTPUT = 5 JObfuscator() { $this.Initialize($null) } JObfuscator([string]$ApiKey) { $this.Initialize($ApiKey) } hidden [void] Initialize([string]$ApiKey) { $this._api_key = $ApiKey $this.enable_compression = $true $this.array_int_crypt = $true $this.array_char_crypt = $true $this.array_double_crypt = $true $this.array_string_crypt = $true $this.remove_comments = $true $this.split_strings = $false $this.crypt_strings = $true $this.rename_methods = $true $this.shuffle_methods = $true $this.ints_math_crypt = $true $this.dbls_math_crypt = $true $this.rename_variables = $true $this.mix_code_flow = $true $this.string_char_vault = $true $this.ints_from_double_math = $true $this.opaque_mixer_chain = $true $this.complexify_booleans = $true $this.try_finally_noise = $true $this.ints_to_arrays = $true $this.dbls_to_arrays = $true } [object] Login() { $params = @{ command = 'login' } return $this.PostRequest($params) } [object] ObfuscateJavaFile([string]$JavaFilePath) { if (-not (Test-Path -LiteralPath $JavaFilePath -PathType Leaf)) { return $false } try { $source = [System.IO.File]::ReadAllText((Resolve-Path -LiteralPath $JavaFilePath).Path) } catch { return $false } if ([string]::IsNullOrEmpty($source)) { return $false } return $this.ObfuscateJavaSource($source) } [object] obfuscate_java_file([string]$java_file_path) { return $this.ObfuscateJavaFile($java_file_path) } [object] ObfuscateJavaSource([string]$JavaSource) { $params = @{ command = 'obfuscate' source = $JavaSource } return $this.PostRequest($params) } [object] obfuscate_java_source([string]$java_source) { return $this.ObfuscateJavaSource($java_source) } [object] PostRequest([hashtable]$ParamsArray) { if ($this._api_key) { $ParamsArray['key'] = $this._api_key } $flags = @( 'array_int_crypt', 'array_char_crypt', 'array_double_crypt', 'array_string_crypt', 'remove_comments', 'split_strings', 'crypt_strings', 'rename_methods', 'shuffle_methods', 'ints_math_crypt', 'dbls_math_crypt', 'rename_variables', 'mix_code_flow', 'string_char_vault', 'ints_from_double_math', 'opaque_mixer_chain', 'complexify_booleans', 'try_finally_noise', 'ints_to_arrays', 'dbls_to_arrays' ) foreach ($flag in $flags) { if ($this.$flag) { $ParamsArray[$flag] = '1' } } if ($ParamsArray.ContainsKey('source') -and $this.enable_compression -and $ParamsArray['source']) { $ParamsArray['source'] = Compress-JoZlib -Source ([string]$ParamsArray['source']) $ParamsArray['compression'] = '1' } $result = Invoke-JoApiRequest -Fields $ParamsArray if ($result -eq $false -or $null -eq $result) { return $false } $errorCode = 0 $errorProperty = $result.PSObject.Properties['error'] if ($null -ne $errorProperty) { $errorCode = [int]$errorProperty.Value } $outputProperty = $result.PSObject.Properties['output'] if ($null -ne $outputProperty -and $this.enable_compression -and $errorCode -eq [JObfuscator]::ERROR_SUCCESS) { $result.output = Expand-JoZlib -CompressedBase64 ([string]$outputProperty.Value) } return $result } [object] post_request([hashtable]$params_array) { return $this.PostRequest($params_array) } } function New-JObfuscator { <# .SYNOPSIS Creates a JObfuscator Web API client. .DESCRIPTION Factory for the JObfuscator class. Empty or invalid keys run demo mode. Most strategy flags default to $true (split_strings defaults to $false), matching the PHP SDK PostRequest surface. .PARAMETER ApiKey Activation key from PELock. .EXAMPLE $client = New-JObfuscator -ApiKey 'ABCD-ABCD-ABCD-ABCD' $result = $client.ObfuscateJavaSource($javaSource) #> [CmdletBinding()] [OutputType([JObfuscator])] param( [string]$ApiKey ) if ([string]::IsNullOrWhiteSpace($ApiKey)) { return [JObfuscator]::new($null) } return [JObfuscator]::new($ApiKey) } Export-ModuleMember -Function @('New-JObfuscator') |