I've seen numerous ways of retrieving installed programs on WinXP+ in python. What is the proper and most robust way of doing this?
Currently I'm accessing HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall and reading each of the keys from there to get a list. (I've been told this isn't the proper way of doing things) I've seen examples of using WMI/Win32com to do this as well but have seen comments along with those implementations that WMI might be turned off on certain machines and that it's not a very reliable solution.
Is there a method which is both proper, and reliable to get a list of installed programs? None of the WMI examples I've seen have worked on this machine (hence my reluctance to use it, I'm only running WinFLP; which is a stripped vers of XP.)
I seem to have also found the TechNet article which my searches have turned up which is provided to a similar answer on my question: http://gallery.technet.microsoft.com/ScriptCenter/en-us/154dcae0-57a1-4c6e-8f9f-b215904485b7 Note that Vista/7 listed under Platforms very clearly says "Nope"...won't work. So the WMI deal seems like it's a no-go...
Being able to retrieve the installed path would be an upside as well, as right now my current code does not account for someone installing on another drive, or in a non-default directory.
The technet script you refer to perfectly works under Win 7 (with Python 2.5 32bits), and I really cannot see why it shouldn't.
Actually, the real weakness of the WMI approach is that it only lists products installed through the Windows Installer. So it's will not give you the full list. Many programs use different installers. Just compare the results between the (Select * from Win32_Product) and what is displayed in the Control Panel. So, unless you are sure that the program that interset you in your listing are installed with MSI, WMI is definitely not an answer.
So it may be not very pythonic, but the best way, as far as I know, is to use the registry as you've done. This is actually how the control panel works, so at least Windows considers it to be the most robust way to do it.
WMI is the correct way to look for installed programs as it will work across different versions of the OS and will be supported going forward. Looking for specific regkeys may work fine for specific versions of Windows but is not guaranteed to work in the future. Here is some simple python code to check for Box Sync which I just tried on Windows 7. Note that not all fields will be available for every product so be aware these will be 'None.'
import wmi
w = wmi.WMI()
for p in w.Win32_Product():
if 'Box, Inc.' == p.Vendor and p.Caption and 'Box Sync' in p.Caption:
print 'Installed {}'.format(p.Version)
The downside I have seen with WMI is it is very slow to start up.
Related
begin TLDR;
I want to write a python3 script to scan through the memory of a running windows process and find strings.
end TLDR;
This is for a CTF binary. It's a typical Windows x86 PE file. The goal is simply to get a flag from the processes memory as it runs. This is easy with ProcessHacker you can search through the strings in the memory of the running application and find the flag with a regex. Now because I'm a masochistic geek I strive to script out solutions for CTFs (for everything really). Specifically I want to use python3, C# is also an option but would really like to keep all of the solution scripts in python.
Thought this would be a very simple task. You know... pip install some library written by someone that's already solved the problem and use it. Couldn't find anything that would let me do what I need for this task. Here are the libraries I tried out already.
ctypes - This was the first one I used, specifically ReadProcessMemory. Kept getting 299 errors which was because the buffer I was passing in was larger than that section of memory so I made a recursive function that would catch that exception, divide the buffer length by 2 until it got something THEN would read one byte at a time until it hit a 299 error. May have been on the right track there but I wasn't able to get the flag. I WAS able to find the flag only if I knew the exact address of the flag (which I'd get from process hacker). I may make a separate question on SO to address that, this one is really just me asking the community if something already exists before diving into this.
pymem - A nice wrapper for ctypes but had the same issues as above.
winappdbg - python2.x only. I don't want to use python 2.x.
haystack - Looks like this depends on winappdbg which depends on python 2.x.
angr - This is a possibility, Only scratched the surface with it so far. Looks complicated and it's on the to learn list but don't want to dive into something right now that's not going to solve the issue.
volatility - Looks like this is meant for working with full RAM dumps not for hooking into currently running processes and reading the memory.
My plan at the moment is to dive a bit more into angr to see if that will work, go back to pymem/ctypes and try more things. If all else fails ProcessHacker IS opensource. I'm not fluent in C so it'll take time to figure out how they're doing it. Really hoping there's some python3 library I'm missing or maybe I'm going about this the wrong way.
Ended up writing the script using the frida library. Also have to give soutz to rootbsd because his or her code in the fridump3 project helped greatly.
I am working on cross platform utility which involves drive scanning and the automagical creation of shell/batch files for the OSs upon which it runs. Unfortunately I cannot find one simple answer.
As stated in these links:
When to use os.name, sys.platform, or platform.system?
Reliably detect Windows in Python
Extract file name from path, no matter what the os/path format
Python: What OS am I running on?
and at http://docs.python.org/library/platform.html#module-platform
The various platform.system(), platform.platform(), sys.platform, os.name() etc. etc. all suffer the problem of not necessarily being future perfect. That is if an OS developer changes things a little, these may not work (at least until patched or revised). So obviously the best solution is to try a small part of each of the above, along with targeting some OS specific executable file with a call().
Which leaves my question:
Since the best way to determine this involves platform.system, sys.platform, and os.name (assuming only generalized recognition is needed), what are the various possible outputs for those programs? The docs.python.org sections on each of these modules only lists a few, and the pages are not exactly current. Specifically I would like to know the possible output on the last three mac OS's, Win XP- Win 8, and just knowing Linux covers my needs there. Any one know what the outputs are or where i can find them?
Thanks in advance.
Clarification:
What I am looking for here is the currently known values so that I can incorporate them into an existing project, with an eye towards future code revision being made easier on my end. So the CURRENT return values are what I am seeking (Last 3 gens of Mac OS* and Win * since beyond that probably isn't much used any more)
Edit: For the specific question of all possible return values:
Related stackoverflow answer for Possible values from sys.platform?
Post with the answers pointed to above:
aix3 aix4 atheos beos5 darwin freebsd2 freebsd3 freebsd4 freebsd5
freebsd6 freebsd7 generic irix5 irix6 linux2 mac netbsd1 next3 os2emx
riscos sunos5 unixware7
Also:
linux3, freebsd8, win32, dos, os2
and others.
(They were asking the same question in Aug 2006.)
Note:
As others have indicated, sys.platform is derived from the name that
the system vendor gives their system.
/Edit.
Not sure it's possible to have something so future-perfect. If you only want to know the OS (mac/win/linux) then see the examples for sys.platform.
Also, keeping things in a separate function like get_os_name lets you control or map the input-output if you see a lot of changes in the future - once a year per OS? Also convenient to combine with the other functions you've mentioned. So you can return a tuple based on (os_name, 32/64bit, variant) (where variant is things like XP, Win8, Darwin, etc.) depending on how it affects your script.
The docs.python.org sections on each of these modules only lists a few, and the pages are not exactly current.
Unfortunately true. But again, it's impossible to account for environments or platforms in the future or even all current ones. The logical thing to do is make sure it works on the current platforms that you have tested/developed for.
I have a working GPIB interface and Linux-GPIB package installed and working.
I only know two commands at the moment, x.write and x.find. I don't know much about Python, but I recognize the dot operator and realize that after importing gpib, I should get some functions at my disposal.
I have not been able to locate the list of GPIB functions.
They are in the gpib library. You reference them like so: gpib.foo().
Add this line into your code:
help(gpib)
And browse through the functions/classes.
If you are working in Python, I think the pyvisa is what you are looking for. It provides lots of useful high level functions which helps you to send a series of SCPI commands to your equipment via GPIB, such as write, read,ask and so on.
As for SCPI commands themselves, usually they will differ from the different vendors. So in terms of what kind of SCPI you should send to the equipment, you should read the corresponding datasheet. But in the other case, you could have installed the drivers which were provided by the vendor. In this case you can send some even higher commands. For instance, if you would like to control a voltage source, they have probably already got the function setvoltage(double voltage). Things will be much more easier for you.
Actually there are many commands available. Except those two you mentioned, there are x.read, x.ask, x.ask_for_value and so on.
But I recommend your to read those help file, I think that will give you a better understanding.
I've gotten omnicompletion with Pysmell to work before, but I can't seem to do it again.
I tried following some steps online, but most, if not all, of them are to vague and assume too much that you know what you are doing to some extent.
Can someone post a full, step-by-step tutorial on how to get code completion working properly, for complete Vim newbies (for dummies?)?
There's also Ctrl+n in insert mode which will autocomplete based on the words it has seen in any of the open buffers (even in other tabs).
You may try Pydiction (Excerpt below)
Description Pydiction allows you to
Tab-complete Python code in Vim,
including: standard, custom and
third-party modules and packages. Plus
keywords, built-ins, and string
literals.
Pyflakes has a vim plugin that does this pretty awesomely. Unlike Pydiction, you don't need to build a dictionary beforehand (so if you're bouncing between different virtualenvs it's a bit less hassle.) I haven't been using it long but it seems very slick.
Try hitting Ctrl-p while typing mid-word. Ctrl-p inserts the most recent word that starts with the prefix you're typing and Ctrl-n inserts the next match. If you have several possibilities, you can hit ctrl-p more than once to substitute each candidate in order.
I am trying to write a cross-platform python program that would run in the background, monitor all keyboard events and when it sees some specific shortcuts, it generates one or more keyboard events of its own. For example, this could be handy to have Ctrl-# mapped to "my.email#address", so that every time some program asks me for my email address I just need to type Ctrl-#.
I know such programs already exist, and I am reinventing the wheel... but my goal is just to learn more about low-level keyboard APIs. Moreover, the answer to this question might be useful to other programmers, for example if they want to startup an SSH connection which requires a password, without using pexpect.
Thanks for your help.
Note: there is a similar question but it is limited to the Windows platform, and does not require python. I am looking for a cross-platform python api. There are also other questions related to keyboard events, but apparently they are not interested in system-wide keyboard events, just application-specific keyboard shortcuts.
Edit: I should probably add a disclaimer here: I do not want to write a keylogger. If I needed a keylogger, I could download one off the web a anyway. ;-)
There is no such API. My solution was to write a helper module which would use a different helper depending on the value of os.name.
On Windows, use the Win32 extensions.
On Linux, things are a bit more complex since real OSes protect their users against keyloggers[*]. So here, you will need a root process which watches one of[] the handles in /dev/input/. Your best bet is probably looking for an entry below /dev/input/by-path/ which contains the strings "kbd" or "keyboard". That should work in most cases.
[*]: Jeez, not even my virus/trojan scanner will complain when I start a Python program which hooks into the keyboard events...
As the guy that wrote the original pykeylogger linux port, I can say there isn't really a cross platform one. Essentially I rewrote the pyhook API for keyboard events to capture from the xserver itself, using the record extension. Of course, this assumes the record extension is there, loaded into the x server.
From there, it's essentially just detecting if you're on windows, or linux, and then loading the correct module for the OS. Everything else should be identical.
Take a look at the pykeylogger source, in pyxhook.py for the class and implimentation. Otherwise, just load that module, or pyhook instead, depending on OS.
I've made a few tests on Ubuntu 9.10. pykeylogger doesn't seems to be working. I've tryied to change the /etc/X11/xorg.conf in order to allow module to be loaded but in that specific version of ubuntu there is no xorg.conf. So, in my opiniion pykelogger is NOT working on ubuntu 9.10 !!
Cross-platform UI libraries such as Tkinter or wxPython have API for keyboard events. Using these you could map «CTRL» + «#» to an action.
On linux, you might want to have a look at pykeylogger. For some strange reason, reading from /dev/input/.... doesn't always work when X is running. For example it doesn't work on ubuntu 8.10. Pykeylogger uses xlib, which works exactly when the other way doesn't. I'm still looking into this, so if you find a simpler way of doing this, please tell me.
Under Linux it's possible to do this quite easily with Xlib. See this page for details:
http://www.larsen-b.com/Article/184.html