##------------------------------------------------------------------------------ ## TroubleShooting Olrik. ## The Tool that makes a Tech's life easier! ## ## All information can be found at: ## http://artellos.geekstogo.com/ ## ## TroubleShooting Olrik, Copyright 2008 Olrik Lenstra ## All Rights Reserved. ## ##------------------------------------------------------------------------------ ## Importing the Modules required for TSO. ##------------------------------------------------------------------------------ import wx import os, sys import string import win32api import re ##------------------------------------------------------------------------------ ## Calling for the install directory. ##------------------------------------------------------------------------------ instDir = sys.argv[0] instDir = instDir.rsplit(r"\TSO.exe") instDir = str(instDir[0]) ##------------------------------------------------------------------------------ ## Change the directory to the installed directory. ##------------------------------------------------------------------------------ os.chdir(instDir) ##------------------------------------------------------------------------------ ## Setting the text for the version displaying the version, e-mail and site. ##------------------------------------------------------------------------------ versionText = """Troubleshooting Olrik Version 0.10.2.0 E-Mail: o.lenstra@gmail.com Website: http://artellos.geekstogo.com/ Troubleshooting Olrik, Copyright 2008 Olrik Lenstra All Rights Reserved.""" ##------------------------------------------------------------------------------ ## This is the text that is shown in the main screen of the program. ##------------------------------------------------------------------------------ introRaw = """Welcome to Troubleshooting Olrik. Press 'Scan' to start the scan. Please be patient while the program creates a log. The File can be viewed through the 'Logs' button.""" ##------------------------------------------------------------------------------ ## The following will create the frame with buttons and text for the program. ## The frame is not resizable and the Maximize button is disabled. ##------------------------------------------------------------------------------ class MyFrame(wx.Frame): def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(300, 280), style = wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER | wx.MAXIMIZE_BOX)) panel = wx.Panel(self, -1) self.count = 0 self.t = wx.Timer(self) introFont = wx.Font(10, wx.ROMAN, wx.NORMAL, wx.NORMAL) introText = wx.StaticText(panel, -1, introRaw,(50, 10), style=wx.ALIGN_CENTRE) introText.SetFont(introFont) self.myGauge = wx.Gauge(panel, -1, 100, (50, 210), (200, 20)) wx.Button(panel, 1, 'Scan!', (115, 90)) wx.Button(panel, 2, 'Logs', (115, 120)) wx.Button(panel, 3, 'Version', (115, 150)) wx.Button(panel, 4, 'Credits', (115, 180)) self.Bind(wx.EVT_TIMER, self.OnTimer, self.t) self.Bind(wx.EVT_BUTTON, self.OnScan, id=1) self.Bind(wx.EVT_BUTTON, self.OnLogs, id=2) self.Bind(wx.EVT_BUTTON, self.OnVersion, id=3) self.Bind(wx.EVT_BUTTON, self.OnCredits, id=4) self.t.Start(1000, oneShot=False) ##------------------------------------------------------------------------------ ## Define the 'Scan!' Button's event. ## This is the main part of the program. ## 'scan()' has been defined later on in the program. ##------------------------------------------------------------------------------ def OnScan(self, event): ##------------------------------------------------------------------------------ ## The following displays a messagebox at the beginning of the log saying it can take a while. ##------------------------------------------------------------------------------ startScan = '''TSO will now start creating a log. Please be patient as this can take from 5 up to 10 minutes. Please press OK to start TSO.''' dlg2 = wx.MessageDialog(self, startScan, 'Starting TSO.', wx.OK|wx.ICON_INFORMATION) dlg2.ShowModal() dlg2.Destroy() ##------------------------------------------------------------------------------ ## Lets begin with calling the .txt that will be written. ## I want to have a date in the name so first we need to get the date and ## convert it to a file-safe string. ##------------------------------------------------------------------------------ self.count = 0 self.myGauge.SetValue(10) time = wx.Now() time = time.replace(' ', '_') time = time.replace(':', '-') ##------------------------------------------------------------------------------ ## After we set the time in the variable 'time' we can now open the file. ## This is only a temp file as were going to write it away under another name later. ##------------------------------------------------------------------------------ output = open(r"temp.txt", "w") ##------------------------------------------------------------------------------ ## First we want to write a header and the date created to the logfile. ##------------------------------------------------------------------------------ output.write('[size="5"][color="#000080"][b]Troubleshooting Olrik[/b][/color][/size]\n') output.write('Log Created On: ' + wx.Now() + '\n') output.write('\n') ##------------------------------------------------------------------------------ ## Next thing we do is start the DxDiag Log. ## We call the command and read it to dxdiaginfo. ## Then we write the DxDiag Log header to the file we opened. ## After the Log Header is added we add a blank line + the information. ## At the end of this block I delete the 'temp' file 'dxdiag.txt'. ##------------------------------------------------------------------------------ self.myGauge.SetValue(20) os.popen(r'dxdiag /t dxdiag.txt') dxdiaginfo = file('dxdiag.txt', 'r').read() output.write('[size="4"][color="#FF0000"][b]DxDiag Log[/b][/color][/size]\n') output.write('\n') output.write(dxdiaginfo) win32api.DeleteFile('dxdiag.txt') ##------------------------------------------------------------------------------ ## The second in line is the ipconfig command. ## First we run the command and store it in ipconfig.txt ## We then run concealip to make sure public IPs get filtered. ## Then read the info to ipconfiginfo and write it to the file. ##------------------------------------------------------------------------------ self.myGauge.SetValue(30) os.popen(r'ipconfig /all >> ipconfig.txt') concealip() ipconfiginfo = file('ipconfig.txt', 'r').read() output.write('[size="4"][color="#FF0000"][b]Ipconfig Log[/b][/color][/size]\n') output.write(ipconfiginfo) output.write('\n') output.write('\n') win32api.DeleteFile('ipconfig.txt') ##------------------------------------------------------------------------------ ## Ok, now lets do a really long one next, The Ping. ## This one is a bit around-the-point. ## I first call all the diffrent pings and save them to diffrent txt's. ## I then read all those files and use them to write to our log file. ##------------------------------------------------------------------------------ self.myGauge.SetValue(40) os.popen(r'ping www.google.com > ggldp.txt') os.popen(r'ping 66.249.93.104 > gglip.txt') os.popen(r'ping www.yahoo.com > yhodp.txt') os.popen(r'ping 87.248.113.14 > yhoip.txt') os.popen(r'ping www.geekstogo.com > gtgdp.txt') os.popen(r'ping 72.232.218.60 > gtgip.txt') ggldp = file('ggldp.txt', 'r').read() gglip = file('gglip.txt', 'r').read() yhodp = file('yhodp.txt', 'r').read() yhoip = file('yhoip.txt', 'r').read() gtgdp = file('gtgdp.txt', 'r').read() gtgip = file('gtgip.txt', 'r').read() output.write('[size="4"][color="#FF0000"][b]Pinging Log[/b][/color][/size]\n') output.write('[size="2"][color="#4169E1"][b]Google Domain Test[/b][/color][/size]') output.write('\n') output.write(ggldp) output.write('\n') output.write('[size="2"][color="#4169E1"][b]Google IP Test[/b][/color][/size]') output.write('\n') output.write(gglip) output.write('\n') output.write('[size="2"][color="#4169E1"][b]Yahoo Domain Test[/b][/color][/size]') output.write('\n') output.write(yhodp) output.write('\n') output.write('[size="2"][color="#4169E1"][b]Yahoo IP Test[/b][/color][/size]') output.write('\n') output.write(yhoip) output.write('\n') output.write('[size="2"][color="#4169E1"][b]Geeks to Go! Domain Test[/b][/color][/size]') output.write('\n') output.write(gtgdp) output.write('\n') output.write('[size="2"][color="#4169E1"][b]Geeks to Go! IP Test[/b][/color][/size]') output.write('\n') output.write(gtgip) output.write('\n') output.write('\n') win32api.DeleteFile('ggldp.txt') win32api.DeleteFile('gglip.txt') win32api.DeleteFile('yhodp.txt') win32api.DeleteFile('yhoip.txt') win32api.DeleteFile('gtgdp.txt') win32api.DeleteFile('gtgip.txt') ##------------------------------------------------------------------------------ ## Next stop, Netstat. ## Call for the 3 diffrent netstat switches. ## Read them into a variable and then write them to the file. ##------------------------------------------------------------------------------ self.myGauge.SetValue(50) os.popen(r'netstat -nab > netstat1.txt') os.popen(r'netstat -r > netstat2.txt') os.popen(r'netstat -se > netstat3.txt') netstat1 = file('netstat1.txt', 'r').read() netstat2 = file('netstat2.txt', 'r').read() netstat3 = file('netstat3.txt', 'r').read() output.write('[size="4"][color="#FF0000"][b]Netstat Log[/b][/color][/size]\n') output.write('\n') output.write(netstat1) output.write('\n') output.write(netstat2) output.write('\n') output.write(netstat3) output.write('\n') win32api.DeleteFile('netstat1.txt') win32api.DeleteFile('netstat2.txt') win32api.DeleteFile('netstat3.txt') ##------------------------------------------------------------------------------ ## Now lets take the services under the loop. ## Call in the shell, read from file into variable. Add text to the temp file ## and after that write the information to the temp file. ##------------------------------------------------------------------------------ self.myGauge.SetValue(60) os.popen(r'sc query > services.txt') services = file('services.txt', 'r').read() output.write('[size="4"][color="#FF0000"][b]Services Log[/b][/color][/size]\n') output.write('\n') output.write(services) win32api.DeleteFile('services.txt') ##------------------------------------------------------------------------------ ## Next up the HOSTS File. ## Call in the shell, read from file into variable. Add text to the temp file ## and after that write the information to the temp file. ##------------------------------------------------------------------------------ self.myGauge.SetValue(70) os.popen(r'dir C:\Windows\system32\drivers\etc\hosts >> hosts.txt') os.popen(r'echo. >> hosts.txt') os.popen(r'find /V "127.0.0.1" C:\Windows\system32\drivers\etc\hosts >> hosts.txt') hosts = file('hosts.txt', 'r').read() output.write('[size="4"][color="#FF0000"][b]Hosts File Log[/b][/color][/size]\n') output.write('\n') output.write(hosts) win32api.DeleteFile('hosts.txt') ##------------------------------------------------------------------------------ ## Next up the HOSTS File. ## Call in the shell, read from file into variable. Add text to the temp file ## and after that write the information to the temp file. ##------------------------------------------------------------------------------ self.myGauge.SetValue(80) os.popen(r'type "C:\boot.ini" > boot.txt') boot = file('boot.txt', 'r').read() output.write('[size="4"][color="#FF0000"][b]Boot.ini Log[/b][/color][/size]\n') output.write('\n') output.write(boot) win32api.DeleteFile('boot.txt') ##------------------------------------------------------------------------------ ## Lets set the ending and close the log with a nice format and run ## the text through the dos2unix program. ##------------------------------------------------------------------------------ self.myGauge.SetValue(90) output.write('\n[size="5"][color="#000080"][b]END OF LOG FILE, Date of Completion: ' + wx.Now() + '----------[/b][/color][/size]\n') output.close() dos2unix('temp.txt', 'TSOLog_' + time + '.txt') win32api.DeleteFile('temp.txt') self.myGauge.SetValue(100) ##------------------------------------------------------------------------------ ## The following displays a messagebox at the end of the log saying the log is created. ##------------------------------------------------------------------------------ dlg = wx.MessageDialog(self, 'The log is done.\n Press OK to return to TSO.', 'Done Creating Log.', wx.OK|wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() ##------------------------------------------------------------------------------ ## Define the OnTimer and UpDate for the Gauge Bar. ##------------------------------------------------------------------------------ def OnTimer(self, evt): self.UpDate() self.t.Start(-1, oneShot=False) def UpDate(self): self.count += 1 print "Timer called by program ", self.count ##------------------------------------------------------------------------------ ## Define the 'Logs' Button's event. ## This button makes sure that the user can open the log files created in notepad. ##------------------------------------------------------------------------------ def OnLogs(self, event): dlg = wx.FileDialog(self, "Choose a file", os.getcwd(), "", "*.*", wx.OPEN) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() os.popen('notepad ' + path) dlg.Destroy() os.chdir(instDir) ##------------------------------------------------------------------------------ ## This section handles the event for the 'Version' Button. ## Current version can be seen at the top of this file. ##------------------------------------------------------------------------------ def OnVersion(self, event): dlg = wx.MessageDialog(self, versionText, 'Version Troubleshooting Olrik', wx.OK|wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() ##------------------------------------------------------------------------------ ## This section handles the event for the 'Credits' Button. ## We set a variable for the text and let a dialog box pop up ## with the 'Thanks To' and the TERMS. ##------------------------------------------------------------------------------ def OnCredits(self, event): creditsText = """TERMS AND CONDITIONS: DO NOT RESALE, MODIFY OR REMOVE ANY CONTENTS WITHOUT PERMISSION FROM THE AUTHOR. THIS SOFTWARE MUST BE KEPT AS IS. THIS PRODUCT DOES NOT OFFER ANY WARRANTY WHATSOEVER. THE USER ACKNOWLEDGES THAT HE/SHE WILL USE THIS PROGRAM AT HIS/HER OWN RISK. THE AUTHOR IS NOT LIABLE FOR ANY DAMAGE OR HARM CAUSED BY THIS SOFTWARE. IF YOU DO NOT AGREE TO THESE TERMS DISCONTINUE USING THIS SOFTWARE IMMEDIATELY. ------------------- I would like to thank Geeks to Go! for letting me host my tool on their website. Special Thanks to all the people listed below! ------------------- "OldTimer" for awnsering a lot of my questions on many areas, Support and general tips about programing. "wannabe1" for giving me advice, feedback and support in making this program. "Greg Graham" for being an awesome python teacher and helping me with a few scripts. "Tal" for testing every single version of TSO! "GravityGripp" for supporting me and giving me some tips! "Jeroen Dollekamp" for making the icon of my program and correcting me on some spelling mistakes. "[Nemesis]" for giving me inspiration to start doing this and giving me idea's from a batch file I helped him with. Aside from the above list of wonderfull people I'd also like to thank anyone that has shown interrest in the program! ------------------- Cheers all of you! Olrik Lenstra Troubleshooting Olrik, Copyright 2008 Olrik Lenstra All Rights Reserved.""" dlg = dlg = wx.MessageDialog(self, creditsText, 'Credits Troubleshooting Olrik', wx.OK|wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() ##------------------------------------------------------------------------------ ## The following bit makes sure that the frames are being created. ## The icon is also set to TSO.ico. ##------------------------------------------------------------------------------ class MyApp(wx.App): def OnInit(self): frame = MyFrame(None, -1, 'Troubleshooting Olrik') frame.SetIcon(wx.Icon('TSO.exe', wx.BITMAP_TYPE_ICO)) frame.Show(True) frame.Center() return True ##------------------------------------------------------------------------------ ## Define 'main()' to be able to start our program. ##------------------------------------------------------------------------------ def main(): app = MyApp(0) app.MainLoop() ##------------------------------------------------------------------------------ ## Define the dos2unix function. This makes sure we can ## copy and paste the content of notepad straight to the forum. ##------------------------------------------------------------------------------ def dos2unix(inf, outf): ##------------------------------------------------------------------------------ ## Open and read the input file and open the output file for later use. ##------------------------------------------------------------------------------ text = file(inf, "r").read() outf = file(outf, "w") ##------------------------------------------------------------------------------ ## Here we make sure everything ends with a newline so that we don't get double ## blank lines in the text that goes straight to the forum. ##------------------------------------------------------------------------------ text = string.replace(text, '\r\n', '\n') text = string.replace(text, '\r', '\n') ##------------------------------------------------------------------------------ ## Now that we replaced everything with newlines we're going to write it to ## our earlier stated output file. ##------------------------------------------------------------------------------ outf.write(text) ##------------------------------------------------------------------------------ ## Define all the private IP ranges that we're not going to filter in ## the ipconfig part of the program. ## From private4 to private19 is actually 1 range. (Needs to be looked at.) ##------------------------------------------------------------------------------ private1 = r"192\.168\.\d+\.\d+" private2 = r"169\.254\.\d+\.\d+" private3 = r"10\.\d+\.\d+\.\d+" private4 = r"172\.16\.\d+\.\d+" private5 = r"172\.17\.\d+\.\d+" private6 = r"172\.18\.\d+\.\d+" private7 = r"172\.19\.\d+\.\d+" private8 = r"172\.20\.\d+\.\d+" private9 = r"172\.21\.\d+\.\d+" private10 = r"172\.22\.\d+\.\d+" private11 = r"172\.23\.\d+\.\d+" private12 = r"172\.24\.\d+\.\d+" private13 = r"172\.25\.\d+\.\d+" private14 = r"172\.26\.\d+\.\d+" private15 = r"172\.27\.\d+\.\d+" private16 = r"172\.28\.\d+\.\d+" private17 = r"172\.29\.\d+\.\d+" private18 = r"172\.30\.\d+\.\d+" private19 = r"172\.31\.\d+\.\d+" ##------------------------------------------------------------------------------ ## Define concealip. This will make sure no public addresses will be published ## on the forums and decreasing the risk for the poster. ##------------------------------------------------------------------------------ def concealip(): ##------------------------------------------------------------------------------ ## Start a loop to replace the public addresses with X's. ## Currently this part is really inefficient. ##------------------------------------------------------------------------------ lines = file('ipconfig.txt', "r+").readlines() for i in range(len(lines)): if re.search("IP\D+ \:", lines[i]): if not re.search(private1, lines[i]): if not re.search(private2, lines[i]): if not re.search(private3, lines[i]): if not re.search(private4, lines[i]): if not re.search(private5, lines[i]): if not re.search(private6, lines[i]): if not re.search(private7, lines[i]): if not re.search(private8, lines[i]): if not re.search(private9, lines[i]): if not re.search(private10, lines[i]): if not re.search(private11, lines[i]): if not re.search(private12, lines[i]): if not re.search(private13, lines[i]): if not re.search(private14, lines[i]): if not re.search(private15, lines[i]): if not re.search(private16, lines[i]): if not re.search(private17, lines[i]): if not re.search(private18, lines[i]): if not re.search(private19, lines[i]): lines[i] = lines[i].replace('1', 'x') lines[i] = lines[i].replace('2', 'x') lines[i] = lines[i].replace('3', 'x') lines[i] = lines[i].replace('4', 'x') lines[i] = lines[i].replace('5', 'x') lines[i] = lines[i].replace('6', 'x') lines[i] = lines[i].replace('7', 'x') lines[i] = lines[i].replace('8', 'x') lines[i] = lines[i].replace('9', 'x') lines[i] = lines[i].replace('0', 'x') ##------------------------------------------------------------------------------ ## Here we write to the opened file to replace the addresses with X's. ##------------------------------------------------------------------------------ file('ipconfig.txt', "r+").writelines(lines) ##------------------------------------------------------------------------------ ## This makes sure the program has to be called on it's own. ## The program cannot be imported. ##------------------------------------------------------------------------------ if __name__ == '__main__': main()