I am trying to port Enrique Nissim's script from his presentation "Reverse Engineering and Bug Hunting on KMDF Drivers" to IDA 7.4. His original script can be found at:
https://github.com/IOActive/kmdf_re/tree/master/code
My somewhat updated version can be found at: https://github.com/MrSynAckSter/kmdf_re/blob/master/code/kmdf_re.py
While I have eliminated most of the errors, I noticed that on all of the drivers I tried it on some of the constants fail to be added to the IDA database.
Errors like these propagate upon running the script:
(1, '_GUID')
(2, 'GUID')
(3, 'RUNTIME_FUNCTION')
(4, 'UNWIND_INFO_HDR')
(5, 'UNWIND_CODE')
(6, '_UNICODE_STRING')
(7, 'USHORT')
(8, 'PWSTR')
(9, 'WCHAR')
(10, 'wchar_t')
(11, 'FILE')
(12, '_iobuf')
(13, '_MAJOR_FUNCTIONS')
(14, 'MAJOR_FUNCTIONS')
MAJOR_FUNCTIONS: failed to add constant DispatchCreate=0 (0x0)
MAJOR_FUNCTIONS: failed to add constant DispatchCreateNamedPipe=1 (0x1)
MAJOR_FUNCTIONS: failed to add constant DispatchCLose=2 (0x2)
MAJOR_FUNCTIONS: failed to add constant DispatchRead=3 (0x3)
MAJOR_FUNCTIONS: failed to add constant DispatchWrite=4 (0x4)
MAJOR_FUNCTIONS: failed to add constant DispatchQueryInformation=5 (0x5)
MAJOR_FUNCTIONS: failed to add constant DispatchSetInformation=6 (0x6)
MAJOR_FUNCTIONS: failed to add constant DispatchQueryEA=7 (0x7)
MAJOR_FUNCTIONS: failed to add constant DispatchSetEA=8 (0x8)
MAJOR_FUNCTIONS: failed to add constant DispatchFlushBuffers=9 (0x9)
MAJOR_FUNCTIONS: failed to add constant DispatchQueryVolumeInformation=10 (0xA)
MAJOR_FUNCTIONS: failed to add constant DispatchSetVolumeInformation=11 (0xB)
MAJOR_FUNCTIONS: failed to add constant DispatchDirectoryControl=12 (0xC)
MAJOR_FUNCTIONS: failed to add constant DispatchFileSystemControl=13 (0xD)
MAJOR_FUNCTIONS: failed to add constant DispatchDeviceIOControl=14 (0xE)
MAJOR_FUNCTIONS: failed to add constant DispatchInternalDeviceControl=15 (0xF)
MAJOR_FUNCTIONS: failed to add constant DispatchShutdown=16 (0x10)
MAJOR_FUNCTIONS: failed to add constant DispatchLockControl=17 (0x11)
MAJOR_FUNCTIONS: failed to add constant DispatchCleanup=18 (0x12)
MAJOR_FUNCTIONS: failed to add constant DispatchCreateMailslot=19 (0x13)
MAJOR_FUNCTIONS: failed to add constant DispatchQuerySecurity=20 (0x14)
MAJOR_FUNCTIONS: failed to add constant DispatchSetSecurity=21 (0x15)
MAJOR_FUNCTIONS: failed to add constant DispatchPower=22 (0x16)
MAJOR_FUNCTIONS: failed to add constant DispatchSystemControl=23 (0x17)
MAJOR_FUNCTIONS: failed to add constant DispatchDeviceChange=24 (0x18)
MAJOR_FUNCTIONS: failed to add constant DispatchQueryQuota=25 (0x19)
MAJOR_FUNCTIONS: failed to add constant DispatchSetQuota=26 (0x1A)
MAJOR_FUNCTIONS: failed to add constant DispatchPNP=27 (0x1B)
I have narrowed their origin to this bit of the script at line 439:
def load_kmdf_types_into_idb():
header_path = idautils.GetIdbDir()
idaapi.idc_parse_types("".join([header_path, "WDFStructs.h"]), idc.PT_FILE)
for idx in range(1, idc.get_ordinal_qty
()):
#Fails to add some of the types
print((idx, idc.get_numbered_type_name(idx)))
idc.import_type(idx, idc.get_numbered_type_name(idx))
However the IDA documentation doesn't help much in terms of deciphering the "failed to add constant" errors.
https://www.hex-rays.com/products/ida/support/idapython_docs/ida_typeinf-module.html#import_type
import_type(til, idx, name, flags=0)
Copy a named type from til to idb.
Parameters:
til - type library (C++: const til_t *)
idx - the position of the new type in the list of types (structures or enums). -1 means at the end of the list (C++: int)
name - the type name (C++: const char *)
flags - combination of Import type flags (C++: int)
Returns: tid_t
BADNODE on error
The big question for me is why is this type import failing? Is it because the types already exist, or is there some subtle syntax error here? Is the flag parameter here mandatory? The error and documentation make is very difficult to tell exactly what's going on here.
The reason why I care is I believe that the failing imports are contributing to the driver failing to find IoControlls, driver major functions, and other important structures for reverse engineering KMDF drivers.
Here are my main theories for why this is happening:
Somehow the behavior of import_type doesn't exactly work closely enough to the original Til2Idb method that was in the original script.
The types are somehow are already in the database in some conflicting way due to flirt signatures or something. I tried looking for them manually, but I don't see them being added on any of the drivers I have tried with the script.
This is IDA telling me that the constants cant be added because they don't exist in the database and the script is functioning more or less as intended. If this is cases I wish the IDA docs would give me some indication of this behavior.
I hope this makes the question clear guys. I hope you can help!
Update: As an added wrinkle, when I manually import the header file this is parsing IDA doesn't generate any errors.