ClaudeZoo / volatility

Automatically exported from code.google.com/p/volatility
GNU General Public License v2.0
0 stars 0 forks source link

driverirp plugin for x86 and x64 (attn: moyix pdbparse) #232

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Hey guys, here's a patch to devicetree.py which adds the driverirp plugin for 
x86 and x64. The old version (from malware.py) used to check each IRP function 
for inline API hooks, but since I haven't ported the ApiHooks plugin to 2.1 
yet, the attached version lacks that behavior (it will be added back once 
ApiHooks is committed). 

So I'm using ATTN moyix/pdbparse because to get the plugin working on x64 I had 
to override an inaccuracy in our auto-generated profiles for x64.  In 
particular, I had to use the following modification:

class MalwareIrpx64(obj.ProfileModification):
    """For some reason, our auto-generated vtypes for x64 
    windows profiles say that _DRIVER_OBJECT.MajorFunction 
    is an array of 56 pointer voids. However, it is really
    an array of 28, just like x86.   
    """
    before = ['WindowsObjectClasses']
    conditions = {'os': lambda x: x == 'windows', 
                  'memory_model': lambda x: x == '64bit'}
    def modification(self, profile):
        profile.merge_overlay({"_DRIVER_OBJECT" : [None, 
            {'MajorFunction': [None, 
                    ['array', 28, ['pointer', ['void']]]],
            }]}) 

So as described, and as you can see below, the auto-generated vtypes say that 
MajorFunction is an array of 56 pointer voids, but there are only 28 IRPs. 

http://code.google.com/p/volatility/source/browse/trunk/volatility/plugins/overl
ays/windows/win7_sp0_x64_vtypes.py#6141

'_DRIVER_OBJECT' : [ 0x150, {
   ...
    'MajorFunction' : [ 0x70, ['array', 56, ['pointer', ['void']]]], 
} ],

Luckily, not all arrays to pointer voids in our profiles are problematic. All 
others except MajorFunction are accurate. For example:

$ grep array volatility/plugins/overlays/windows/win7_sp0_x64_vtypes.py | grep 
pointer | grep void
    'StackTrace' : [ 0x18, ['array', 13, ['pointer64', ['void']]]],
    'StackTrace' : [ 0x38, ['array', 8, ['pointer64', ['void']]]],
    'LastAcquireTrace' : [ 0x78, ['array', 8, ['pointer64', ['void']]]],
    'LastReleaseTrace' : [ 0xb8, ['array', 8, ['pointer64', ['void']]]],
    'StackTrace' : [ 0x20, ['array', 16, ['pointer64', ['void']]]],
    'Guards' : [ 0x10, ['array', 2, ['pointer64', ['void']]]],
    'StackTrace' : [ 0x8, ['array', 7, ['pointer64', ['void']]]],
    'CurrentPacket' : [ 0x0, ['array', 3, ['pointer64', ['void']]]],
    'StackTrace' : [ 0x50, ['array', 8, ['pointer64', ['void']]]],
    'ParentStackTrace' : [ 0x90, ['array', 8, ['pointer64', ['void']]]],
    'StackTrace' : [ 0x0, ['array', 16, ['pointer64', ['void']]]],
    'CommonBuffer' : [ 0x10, ['array', 2, ['pointer64', ['void']]]],
    'SystemReserved1' : [ 0x110, ['array', 54, ['pointer64', ['void']]]],
    'glDispatchTable' : [ 0x9f0, ['array', 233, ['pointer64', ['void']]]],
    'TlsSlots' : [ 0x1480, ['array', 64, ['pointer64', ['void']]]],
    'DbgSsReserved' : [ 0x16a0, ['array', 2, ['pointer64', ['void']]]],
    'Instrumentation' : [ 0x16b8, ['array', 11, ['pointer64', ['void']]]],
    'Unused1' : [ 0x68, ['array', 3, ['pointer64', ['void']]]],
    'DriverContext' : [ 0x0, ['array', 4, ['pointer64', ['void']]]],
    'FileHandles' : [ 0x598, ['array', 6, ['pointer64', ['void']]]],
    'MajorFunction' : [ 0x70, ['array', 56, ['pointer', ['void']]]], <------- sticks out like a sore thumb!
    'FoExtPerTypeExtension' : [ 0x8, ['array', 7, ['pointer64', ['void']]]],
    'StackTrace' : [ 0x10, ['array', 62, ['pointer64', ['void']]]],
    'StackTrace' : [ 0x10, ['array', 5, ['pointer64', ['void']]]],
    'StackTrace' : [ 0x8, ['array', 8, ['pointer64', ['void']]]],
    'Stack' : [ 0x8, ['array', 1, ['pointer64', ['void']]]],

Since the inaccuracy is not wide in scope and can easily be managed with the 
profile modification introduced with the patch, I don't think there's any 
reason to re-auto generate the profiles if/when there's an update to pdbparse 
that outputs the correct array size. However, if there's some other reasons in 
the future to re auto-generate them, we should remember to also take care of 
this at the same time. 
I 

Original issue reported on code.google.com by michael.hale@gmail.com on 12 Mar 2012 at 10:46

Attachments:

GoogleCodeExporter commented 9 years ago
I would guess it's the fault of this line:
http://code.google.com/p/pdbparse/source/browse/tpi_vtypes.py#7

For things like function pointers (or any LF_POINTER), the pointer size isn't 
specified explicitly, so it defaults to assuming it's 4 bytes.

I'm not sure what the best way to fix this is – I don't know of a way to get 
the architecture from the PDB file directly, so perhaps a command line option 
would be best?

Original comment by moo...@gmail.com on 13 Mar 2012 at 12:22

GoogleCodeExporter commented 9 years ago
In the long term, definitely, but for now I've just regenerated the 64-bit 
profiles with the value hard-coded to 8-bytes (r1546).  I've opened an 
enhancement request [1] in pdbparse to track it so we don't have to keep this 
one open after driverirp goes in the tree.

MHL, the profile modification should have no effect now, but best to get rid of 
unnecessary code.  

[1] http://code.google.com/p/pdbparse/issues/detail?id=7

Original comment by mike.auty@gmail.com on 13 Mar 2012 at 1:00

GoogleCodeExporter commented 9 years ago
Thanks guys. Ikelos - no problem, I'll leave off the profile modification from 
driverirp. 

Original comment by michael.hale@gmail.com on 13 Mar 2012 at 1:08

GoogleCodeExporter commented 9 years ago
This issue was closed by revision r1547.

Original comment by michael.hale@gmail.com on 13 Mar 2012 at 1:17