Skip to content

Instantly share code, notes, and snippets.

@struppigel
Last active March 2, 2025 11:32
Show Gist options
  • Save struppigel/7f24f8730f3f41605f7a64cc39835cee to your computer and use it in GitHub Desktop.
Save struppigel/7f24f8730f3f41605f7a64cc39835cee to your computer and use it in GitHub Desktop.
# Uses PowerShell and dnlib to decrypt strings dynamically
# requires pythonnet: pip install pythonnet
# requires dnlib.dll: adjust path below if necessary, remove ZoneIdentifier if you downloaded it
#
# This is applicable for samples that have a non-generic static decrypt method with an integer
# Small changes to the PS script will make it also work for non-static or generic methods
# Caution: This script runs the sample's code!
# author: Karsten Hahn @ G DATA CyberDefense
import clr
import subprocess
import os
import sys
clr.AddReference(r'dnlib.dll')
import dnlib
from dnlib.DotNet import *
from dnlib.DotNet.Emit import OpCodes
ps_script = r"""
$nums = @(extractedargs)
$assembly = [Reflection.Assembly]::LoadFile("filename")
$method = $assembly.ManifestModule.ResolveMethod(decrypttoken)
$nums | ForEach-Object {
try {
"$($_):" + $method.Invoke($null, @($_.PSObject.BaseObject))
} catch {}
} | Out-File -FilePath tempfile -Encoding UTF8
"""
def extract_values_from_method(method):
if not method.HasBody: return []
values = []
instr = [x for x in method.Body.Instructions]
while len(instr) >= 2:
ldc_i4 = instr[0]
call_instr = instr[1]
if ldc_i4.OpCode.Code == OpCodes.Ldc_I4.Code and call_instr.OpCode.Code == OpCodes.Call.Code:
i4_val = ldc_i4.GetLdcI4Value()
values.append(i4_val)
instr = instr[1:]
return values
def extract_values_from_module(module):
values =[]
for t in module.GetTypes():
for m in t.Methods:
values.extend(extract_values_from_method(m))
return values
def decrypt_strings_from_method(method, strings_dict):
if not method.HasBody: return []
instr = [x for x in method.Body.Instructions]
while len(instr) >= 2:
ldc_i4 = instr[0]
call_instr = instr[1]
if ldc_i4.OpCode.Code == OpCodes.Ldc_I4.Code and call_instr.OpCode.Code == OpCodes.Call.Code:
i4_val = ldc_i4.GetLdcI4Value()
if i4_val in strings_dict:
dec_str = strings_dict.get(i4_val)
call_instr.OpCode = OpCodes.Ldstr
call_instr.Operand = dec_str
ldc_i4.OpCode = OpCodes.Nop
print('decoded', i4_val, ':', dec_str)
instr = instr[1:]
def decrypt_strings_from_module(module, strings_dict):
values =[]
for t in module.GetTypes():
for m in t.Methods:
decrypt_strings_from_method(m, strings_dict)
def dynamic_string_decrypt(values, token, filename):
tempfile = "result.tmp"
global ps_script
ps_script = ps_script.replace('decrypttoken',token)
ps_script = ps_script.replace('extractedargs', str(values)[1:-1])
ps_script = ps_script.replace('filename', filename)
ps_script = ps_script.replace('tempfile', tempfile)
print("executing decrypt method...")
# Run the PowerShell script and capture its output.
result = subprocess.run(
["powershell.exe", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", ps_script],
capture_output=True,
text=True,
check=True
)
with open(tempfile, "rb") as f:
# utf-8-sig removes the BOM
output = f.read().decode(encoding="utf-8-sig").rstrip()
output_dict = {}
for line in output.splitlines():
key, sep, value = line.partition(':')
key = int(key)
if len(value.strip()) > 0:
output_dict[key] = value.strip()
os.remove(tempfile)
return output_dict
def main(afile, decrypt_token):
module = ModuleDefMD.Load(afile)
values = extract_values_from_module(module)
print("extracted decrypt indices", len(values))
strings_dict = dynamic_string_decrypt(values, decrypt_token, afile)
decrypt_strings_from_module(module, strings_dict)
print("decrypted strings", len(strings_dict))
outfile = afile + '.deobfus'
module.Write(outfile)
print()
print('Done decrypting, output written to', outfile)
if __name__ == '__main__':
if len(sys.argv) < 3:
print('usage: python string_decrypter.py <inputfile> <decrypt_method_token>')
else:
afile = sys.argv[1]
token = sys.argv[2]
main(afile, token)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment