Pycommands Tutorial
Pycommands Tutorial
Hey guys so I have been playing around a lot with the Grey Hat Python book and just been walking through the book
chapter by chapter so I thought I might share some of the stuff that I have learned so that a) it stays in my mind and b)
you guys can also learn more.
Essentially PyCommands are commands (or more specifically, Python scripts) that you can run from within Immunity
Debugger that allow you to essentially control various parts of the debugger while it is running. This essentially means
that Immunity Debugger is what is known as a "scriptable debugger", and if you don't know what that means, please
use your good friend Google who will kindly tell you a much better answer than I can provide here :)
Getting Started
Okay first off we are going to need to get Immunity Debugger, which can be downloaded from here:
http://debugger.immunityinc.com/register.html
Please note that the registration info is not needed. In fact you can just click next and continue on.
Next, take a look at the API help guide. While its not much it will help you to make future programs so go ahead and
take a look though what functions Immunity Debugger provides for you. It might not make sense right now, but it will
give you an idea of the power that is involved.
Running A PyCommand
To run a command, make sure that it is in you PyCommands folder in Immunity Debugger and then find that white box
at the bottom and enter:
And then once done, check the Log window (if you don't know where that is, then just go to View and then select Log)
Also please note that all of the scripts that we will be viewing/writing today are based on Python 2.x, not Python 3.x.
Make sure you remember that as there are slight differences between the two, and thus this might affect your results.
Just saying...feel free to use 3.x if you REALLY want to (hehe).
Basic Structure of A PyCommand Script
Okay what follows is what you need at a minimal outline to create PyCommand script:
#!/usr/bin/env python
def main(args):
# Instantiate a immlib.Debugger instance of the current debugger process that is running right now.
imm = Debugger()
*Any commands would go here at this point. Sorry about formatting as Blogger is a bi**h with code ;)*
# This command is not required, its only so that the command returns input to the user so that they know that
the script is done (this is displayed below the white box where you enter the commands)
imm.log("String goes here %d" % a number in this case, *if you want, instead of the code displaying
0xBADF00D, it will display the memory address you place here (note that the decimal value you place here
will be converted into a hex value*)
This writes the given message to Immunity Debuggers logs (which can be viewed via View>
Logs). If an address is specified, then that is used in place of the address 0xBADF00D.
imm.updateLog()
Normally when a script runs, the log will only be updated after the script has finished running.
If you want the logs to update at a certain spot instead of waiting till the end, then place this
after your calls to imm.log() to have Immunity's logs update themselves right then and there.
Useful if you doing CPU intensive processes and you want to notify the user of what's going on,
however note that this will cause the process to take a bit longer to run than if you didn't use the
updateLog() call.
Creates a table with the name (in this case Name) and then adds the columns with their given
names to the table
Pretty self explanatory, 0 is just the number (starting from 0) of the table
imm.readMemory(address, size)
Read size bytes from the address located in address and return them.
imm.writeMemory(address, buf)
Write the assembly buffer buf into the address located at address
imm.ps()
List all the running processes and return (according to the docs) a "list of tuples with process
information (pid, name, path, services, tcp list, udp list)"
imm.searchCommands(cmd)
Search in all loaded executables for a given command (the command must be given as a string)
with newlines represented by "\n" (minus quotes)
imm.getRegs()
imm.setRegs(reg, value)
Sets the register represented by the string reg to the DWORD value value.
imm.getPEB()
imm.getPEBaddress():
imm.getAddress(expression)
Okay that should be enough for you to get most scripts done. If you need to write to a file at any time, the
process is the same as you would do in a normal python script.
Again I claim no credit for these. They are all the work of Justin Setiz and all credit goes to him for creating these
except for one which I will mention shortly.
badchar,py
def main(args):
imm = Debugger()
bad_char_found = False
# Shellcode to verify
shellcode = "<INSERT SHELLCODE HERE>"
shellcode_length = len(shellcode)
imm.log("***************************************")
count += 1
if bad_char_found:
imm.log("[*****]")
imm.log("Bad char found %s" % debug_shellcode[count])
imm.log("Expected to find: %s" % shellcode[count])
imm.log("[*****]")
else:
imm.log("[*****]")
imm.log("No bad characters found :) Your good to go!")
imm.log("[*****]")
This is the only piece of code that is mine. The creator of this technique was Damian Gomez of Immunity.
def main(args):
imm = Debugger()
# This is the initial test to see what it was before:
result = result.encode("HEX")
result = result.encode("HEX")
findantidep.py
Included by default in Immunity Debugger. This is a GUI program that takes you through the process of disabling DEP
on a specific process you are debugging and then returning execution to the area of code your shellcode is in. I will let
you figure out how to use this because your probably smart enough to figure it out yourself if you have a need to use it
(and space. may make separate tutorial on it as its an entire tutorial in itself to be honest)
End
Thats all fokes. Hopefully you can continue to use the examples given above in combination with the API guide to
create some awesome scripts. And if you create something really awsome, let me know and if its good i'll post it up on
here along with your name :)