You can download the Immunity Debugger pyCommand from the link below.
(Note : you must be logged in to be able to download this plugin)
If you want to show your respect for my free tools and free support, please consider a small donation :
Download :
Version for Immunity Debugger v1.73 :
pvefindaddr for ImmDbg v1.73 only (Log in before downloading this file !)
Installation :
Drop the file in the pycommands folder within your Immunity Debugger installation folder. You can get the list of functions and parameters by running !pvefindaddr (without arguments) from the input box at the bottom of Immunity Debugger. Look at the “Log” window for output.
Tip : check for updates on a regular basis. You can use command !pvefindaddr update to check for updates at any time, or run !pvefindaddr update get to retrieve the latest version and update itself.
Related scripts :
Some ‘happy pvefindaddr’ users asked me if it would be possible to compare the output of files generated with pvefindaddr and only list matching entries. This may be handy when you need to compare for example ppr pointers from XP SP2 and XP SP3 systems.
So I decided to release a little perl script that will do just that. Before you run the script, make sure the output is generated using the same version of pvefindaddr, and (obviously) using the same query.
You can download the script here :
PVE findaddr Compare addresses utility (Log in before downloading this file !)
You can specify 2 or 3 files and it will list the matching entries in all files. (Obviously, the output will only make sense if the files were created on different systems, but using the same pvefindaddr command. Enjoy !
pvefindaddr Version history :
Current version : v2.0.7 (august 23, 2010)
Added function “omelet”. Usage : see http://www.corelan.be:8800/index.php/2010/08/22/exploit-notes-win32-eggs-to-omelet
Older versions:
v2.0.6 (august 20, 2010)
* added functionality to make the plugin update itself. If you run “!pvefindaddr update get” or ”!pvefindaddr selfupdate”, then the plugin will update itself if a new version is available.
v2.0.5 (august 20, 2010)
* Fixed bug in safeseh detection routine.
v2.0.4 (august 17, 2010)
* fixed a few bugs in the “suggest” function and “functions” function
v2.0.3 (august 15, 2010)
* Improved indication of Unicode pointers, taking advantage of ANSI tranformations
* Improved “functions” function
* Some minor fixes
* Fixed a bug in “rop” function, which resulted in generating too many gadgets.
* Added option -i to the rop function, allowing you to ignore pointers from modules that have the fixup flag set
* Stack pivot pointers (‘rop” function) are now written to file as well as displayed in a table (rop_stackpivot.txt)
v1.36 (july 13th, 2010)
Minor change : added dll version number info in module tables (output to file).
v1.35 (july 8th, 2010)
- Added feature “modules” : !pvefindaddr modules will show a table with all loaded modules and information about fixup, safeseh, aslr, nxcompat, path, etc
- Changed “rop” : if a rop.txt file is generated on a ASLR aware module, then gadget offsets to the baseaddress of that module are displayed.
v1.34 (june 15, 2010)
Updated !pvefindaddr rop (will get you more and better gadgets)
Added new function “ropcall”, which will look for DEP bypass function calls in all loaded non-aslr modules.
v1.32 (may 5 2010)
General changes
- when the output of a pvefindaddr action is written to a file, and that file already exists, this “old” file is renamed to .txt.old first. This will allow you to go back to the previous results (if you forgot to save them first)
- every time the output of a pvefindaddr actions is written to a file, the file will start with a table, listing with all loaded modules at that time, include a number of properties (base address, size, path, and an indication whether the module is safeseh protected, subject to aslr, and might get rebased (fixup).
- added support for modules that are subject to fixup. This might be a good indication if a dll will get rebased. When doing normal searches (such as jmp to a register or finding a p/p/r pointer, the search will exclude pointers from modules that are have the fixup flag set). Of course, if you specify a module (as opposed to performing the search in all modules), you will get the results from that module, regardless of the fact that it’s ASLR protected or not, has the fixup flag set or not, etc. Script kiddie alert : It is important to understand this behaviour when evaluating/interpreting the results from search queries.
New functions
- !pvefindaddr rop : this new function will search for gadgets that can be used when using the ROP technique to bypass DEP (or just to build exploits in general). The search will find all chains, and will perform instruction/opcode splitting to find possible alternative gadgets when jumping into the middle of an instruction. Without parameters, !pvefindaddr rop will search all modules. It is clear that this process can take a very long time (up to days). So it is advised to specify a module when using this new function. Futhermore, you can optionally specify a register to further filter gadgets, and you can also specify “nonull” to filter out all pointers that contain null bytes.
The output (rop.txt) will be split into several parts :
* basic/relatively safe instructions (POP, INC, DEC, MOV, etc)
* safe instructions + other instructions, but no calls/jumps
* instructions with calls/jumps to functions in kernel32.dll, ntdll.dll, user32.dll etc (might come handy)
* other instructions
- !pvefindaddr jrop : this function will look for pointers that will lead to jumping to the address at the top of the stack. Of course, a pointer to a simple “RET” will do as well, so you’ll probably won’t need this function a lot.
Enjoy !
v1.31 (12 april 2010)
- made important performance changes to the routines that will determine if a module is safeseh compiled, aslr compiled or not
- added feature to the encode function. You can now have the plugin read bytes from memory and use those bytes as input for the encoding function. (This can be helpful if you have written some intructions directly in the debugger and want to use those as input for the encoding function)
Let’s say you want to read 34 bytes starting from 0x0012fdc1 and want to encode those 34 bytes, then the command would look like this :
!pvefindaddr encode ascii -b0x0012fdc1 34
(note, no space between -b and the baseaddress). If you want to specify badchars, just enter them after the size parameter
- added function “find”. This function allows you to search for a series of bytes in memory and display some information about each location. Output will be written to find.txt
Syntax : !pvefindaddr find 41414141 (will search for “AAAA”) (no spaces between the bytes, unlike !pvefindaddr fa)
Version 1.30 (9 april 2010)
- Improved routine to determine module path
- added feature “info” : !pvefindaddr info 0×1234567 (shows info about a given address within the context of the currently debugged application)
Version 1.29 (9 april 2010)
- Output to file now includes full path of the module a given address belongs to (if possible to determine)
- Fixed output bug in txt files, that prevented display of the indicator specifying whether a given address is made up of alphanum chars only or not.
Version 1.28 (1 april 2010)
Output to file now indicates access permissions for each address (Read, Write, Execute)
Version 1.27 (27 march 2010)
Fixed minor table output bug in pvefindaddr compare
Version 1.26 (23 march 2010)
- Added second “encode” function. You can now use the “ascii” and “alphanum” keywords when encoding. The only difference between these two is the set of allowed characters in the SUB instructions. Ascii will basically allow all ascii printable characters, while alphanum only uses numbers and alphabet characters.
Obviously, in any case, the encoder will not be entirely alphanum, because some instructions (SUB EAX for example) will still use opcode that may not fit the alphanum definition. The encoder implemented in pvefindaddr is not a real encoder – it just allows you to create a self-decoding stub as explained in various articles and exploits. (see offensive-security.com, abysssec.com etc)
Usage :
!pvefindaddr encode ascii “bytes to encode”
!pvefindaddr encode alphanum “bytes to encode”
- Added basic support for filtering bad chars in the “encode” function
After the “bytes to encode”, you can specify the list with bad chars that should be avoided. The bad char evasion function is still basic, so it may not be perfect yet… (especially with alphanum), but it can give you a head start compared to when you have to do it manually.
Usage :
!pvefindaddr encode ascii “bytes to encode” “bytes_to_avoid”
The “bytes_to_avoid” needs to be a list with bytes (2 characters per byte, no spaces, no 0x or \x characters). Example :
!pvefindaddr encode ascii 81C2FFE2 5C2A
(0x5C and 0x2A are the bad chars in this example)
- Improved output of “assemble” function. Previous versions only show the opcodes for individual instructions. The current version will also output the entire bytecode as one string (so it becomes easier to copy & paste bytecode if it consists of multiple instructions
- Added feature to “assemble” function. You can now automatically invoke the encode function after assembling instructions to opcode.
Example :
!pvefindaddr assemble sub edx,0×235#inc eax#jmp edx encode ascii [optional badchars]
This will generate the opcodes for the 3 instructions, will put the opcodes after each other, and will then encode the entire bytecode with the given encoder (ascii or alphanum). You can optionally specify bad chars.
Version 1.25 (20 march 2010)
Added new feature : custom decoder
Purpose : In this and in this article, and in this exploit, I mentioned the use a custom printable-ascii encoder. Building that particular encoder (or decoder, depends on how you look at it) can be done manually (as explained in those articles), but I have now implemented the logic into pvefindaddr as well.
Usage : There are 2 ways to invoke the encoder :
!pvefindaddr encode ascii “bytes” (where “bytes” are just the bytes that need to be encoded, without quotes, spaces or \x or 0x characters). Example : !pvefindaddr encode ascii 8BC253040000FFE2
!pvefindaddr encode ascii “filename” (where “filename” points to a file that contains the bytes that need to be encoded)
The output of the decoding routine will be written to the Log window and to a file called encode.txt
Note : the current implementation does not deal with bad chars. But it should be really easy to filter out any bad chars once you already have the decoder in front of you :)
Version 1.23 (18 march 2010)
Added tag in output files, indicating if a certain address is made up of numbers/alphabet compatible characters only.
Version 1.22 (15 march 2010)
Added feature “offset”, which allows you to calculate the offset between 2 addresses (or registers). Feature implemented for people that are too lazy to open calc themselves
Added tag in output files, indicating if a certain address is made up of ascii printable characters only.
Version 1.21 (13 feb 2010)
I decided to cease support for ImmDbg v1.74 for a while, until a new version of ImmDbg has been re-released.
The new version of the plugin has better support for unicode in the “findmsp”, “suggest” and “compare” functions.
Version 1.20 (06 feb 2010)
- Fixed some issues with “jo”
- Added feature in !pvefindaddr suggest. If you have used AAAA or BBBB to overflow a buffer, !pvefindaddr suggest will try to ‘guess’ the offset to EIP or SEH even though you did not use a metasploit pattern. Results may not be really accurate, but should give you an impression of the payload size that needs to be used.
Example :
- create a .m3u file with 5000 A’s
- open the file in s.o.m.p.l. player
- when application crashes (in Immunity), run
!pvefindaddr suggest
output :
Log data
Address Message
0BADF00D
0BADF00D
0BADF00D **************************************
0BADF00D Getting safeseh table – please wait…
0BADF00D **************************************
0BADF00D
0BADF00D
0BADF00D ————————————————————————-
0BADF00D Searching for metasploit pattern references
0BADF00D ————————————————————————-
0BADF00D [1] Searching for first 8 characters of Metasploit pattern : Aa0Aa1Aa
0BADF00D =====================================================================
0BADF00D ** Could not find begin of Metasploit pattern in memory ! **
0BADF00D
0BADF00D [2] Checking register addresses and contents
0BADF00D ============================================
0BADF00D – Register EAX is overwritten with AAAA – Try using a Metasploit pattern next time
0BADF00D – Register EBX is overwritten with AAAA – Try using a Metasploit pattern next time
0BADF00D
0BADF00D [3] Checking seh chain
0BADF00D ======================
0BADF00D – Checking seh chain entry at 0x0012eb2c, value 40048762
0BADF00D – Checking seh chain entry at 0x0012fb7c, value 41414141
0BADF00D => record is overwritten with AAAA
0BADF00D Trying to guess the startlocation of the buffer with AAAA’s
0BADF00D Please wait, this may take a long time…
0012EB48 Start of string may have be found at 0012EB48
0BADF00D That means that SEH may have been overwritten after about 4148 bytes (more or less – I could be wrong !)
0BADF00D (including 4 null bytes… )
0BADF00D Again, this is just a guess – try using a Metasploit pattern instead of AAAA
0BADF00D ————————————————————————-
0BADF00D Exploit payload information and suggestions :
0BADF00D ———————————————
0BADF00D [+] Sorry, you’ll have to analyse this vulnerability manually
0BADF00D ———————————————
v1.19 (02 feb 2010)
- Improved !pvefindaddr jo (search for pointers to jump to reg+offset)
Usage :
!pvefindaddr jo reg offset (search for offsets between -offset and +offset)
!pvefindaddr jo reg offset module (search for offsets between -offset and +offset, only in given module)
!pvefindaddr jo reg minoffset maxoffset (search for offset between minoffset and maxoffset)
!pvefindaddr jo reg minoffset maxoffset module (search for offset between minoffset and maxoffset only in given module)
- Improved output to file (now includes safeseh/aslr information for each address found)
v1.18 (31 jan 2010)
Added feature !pvefindaddr assemble
Added feature !pvefindaddr peb
Improved some functions and output formatting
v1.17 (20 jan 2010)
Added feature !pvefindaddr a (will search for add esp,8 + ret)
Included search for add esp,8+ret in “jseh” as well. If you are looking for an address to bypass Safeseh, you should try !pvefindaddr jseh all
v1.16 (19 jan 2010)
Added 2 new features :
- !pvefindaddr update : check for updates and reports if a new version of the plugin is available for download
- !pvefindaddr compare : allows you to compare bytecode(shellcode) in a file with contents in memory. This feature will search for the bytecode dynamically and will compare each instance with the original bytecode in a file.
v1.15 (14 jan 2010)
Good news – The folks at Immunity replied to my questions about the changed attributes and I have now fixed all “broken” code in the plugin. At the same time, they had to fix some issues in certain pycommands and have released a new version (which still has the same version number). My advise is to download the latest version of Immunity Debugger from the Immunity website, and use v1.15 (or higher) of the pvefindaddr plugin to make things work again.
Update : Immunity has removed this version from their download page and are downgrading all 1.74 versions back to 1.73 due to a number of bugs. As a result, I now maintain 2 versions of the plugin (see above) : one for v1.73 and one for v1.74
In case you want to test, you can get a (possibly broken) Immunity Debugger v1.74 here
File temporarily unavailable, contact peter.ve [at] corelan.be to report this broken linkv1.14 (13 jan 2010)
- Immunity Debugger v1.74 was released today, but the plugin stopped working. The “Log” method/attribute was changed to “log” so I replaced all “.Log” occurences with “.log”. The current version works with v1.74 (I have not tested all functionality though). If this new version does not work with the previous versions of Immunity Debugger anymore, simply rename all “.log” instances back to “.Log” and it should work fine
Update : apparently not only the .Log attribute was changed. I noticed that some other things stopped working too, so perhaps it’ s not a good time to upgrade yet …
v1.13 (10 jan 2010)
- fixed some minor log output issues
v1.12 (09 jan 2010)
- fixed bug in “jseh all” (thanks ekse for reporting this issue)
v1.11 (29 dec 2009)
- Added new function “suggest”. You need to crash the application using a metasploit pattern. Then, running !pvefindaddr suggest at crash time, will evaluate registers and will try to suggest possible exploit code/payload (in perl) based on offsets and register values. This obviously won’t work in all cases, but it can save you some time
v1.10 (29 dec 2009)
- Added 2 new functions : pattern_create and pattern_offset. Guess what these will do (from within your debugger !)
v1.9 (28 dec 2009)
- Added support for metasploit pattern unicode search in seh chain. (So if a seh record is overwritten with metasploit pattern in unicode format, the offset will be calculated automatically). (Option was added to the findmsp function)
- Added feature in findmsp : When running !pvefindaddr findmsp without arguments, a search in registers and seh chain is performed. But you can now also run findmsp + argument, which will emulate Metasploit’s pattern_offset functionality. You can either specify a 4 character ascii string, or a 10 byte address (in 0x……..) format. If the pattern is found in the built-in Metasploit pattern, the offset will be calculated and displayed.
v1.8 (28 dec 2009)
Added function p1 (search for pop pop ret in non-safeseh and non-aslr aware modules only)
v1.7 (27 dec 2009)
Added 3 new functions :
fa : find A’s
jo : find addresses that will allow you to jump to a register+offset
findmsp : find reference to Metasploit pattern in registers (addresses + values) and sehchain
pvefindaddr for ImmDbg v1.73 only (Log in before downloading this file !)
PVE findaddr Compare addresses utility (Log in before downloading this file !)
