diff --git a/code/kmdf_re_ida_74.py b/code/kmdf_re_ida_74.py index e05c2db..b46cf3e 100644 --- a/code/kmdf_re_ida_74.py +++ b/code/kmdf_re_ida_74.py @@ -1,5 +1,3 @@ -# Port by @M4x_1997 - #https://zairon.wordpress.com/2008/02/15/idc-script-and-stack-frame-variables-length/ import idautils @@ -9,7 +7,10 @@ import ida_bytes import ida_search import ida_ida +import os, sys + +FUNCATTR_FRAME = 0x18 # idacode debug g_vars = {} # Global variables g_functions_stack = set() # Keep track of function addresses whose stack members were erased @@ -28,6 +29,9 @@ OFFSET_WdfRequestRetrieveUnsafeUserInputBuffer = 0x888 OFFSET_WdfRequestRetrieveUnsafeUserOutputBuffer = 0x890 +PROTO_WDFVERSIONBIND = "NTSTATUS WdfVersionBind(PDRIVER_OBJECT pDevObj, PUNICODE_STRING RegPath, PWDF_BIND_INFO BindInfo, PVOID ComponentGlobals);" + +FIND_FUNCTION_ARG_LOOP = 30 def print_guid(guid): data = "GUID(" @@ -37,30 +41,30 @@ def print_guid(guid): data += "{:#04x},".format(part2) part3 = struct.unpack(" mov ebx, eax -> ebx = idx0; eax = idx1 :return: the address where the argument is being set """ - for _ in range(20): # looks up to 20 instructions behind + for _ in range(FIND_FUNCTION_ARG_LOOP): # looks up to FIND_FUNCTION_ARG_LOOP instructions behind addr = idc.prev_head(addr) if idc.print_insn_mnem(addr) == mnemonic and idc.print_operand(addr, idx_operand) == operand: return addr @@ -171,7 +175,7 @@ def find_wdf_callback_through_immediate(mnemonic, operand, val): def list_xref_to_wdf_callback(function_offset): calls_to_pfn_list = [] try: - for xref in idautils.XrefsTo(g_vars["_WDFFUNCTIONS"]+function_offset): + for xref in idautils.XrefsTo(g_vars["_WDFFUNCTIONS"] + function_offset): calls_to_pfn_list.append(xref.frm) except StopIteration: # this is case 2 or 3 @@ -181,7 +185,7 @@ def list_xref_to_wdf_callback(function_offset): if call_pfn != None: calls_to_pfn_list.append(call_pfn) if len(calls_to_pfn_list) == 0: - call_pfn = find_wdf_callback_through_immediate("mov", 1,function_offset) + call_pfn = find_wdf_callback_through_immediate("mov", 1, function_offset) if call_pfn != None: calls_to_pfn_list.append(call_pfn) return calls_to_pfn_list @@ -191,15 +195,15 @@ def list_xref_to_wdf_callback(function_offset): def find_WdfDeviceInitSetIoInCallerContextCallback(): function_offset = OFFSET_WdfDeviceInitSetIoIncallerContextCallback try: - call_pfn = idautils.XrefsTo(g_vars["_WDFFUNCTIONS"]+function_offset).next().frm + call_pfn = next(idautils.XrefsTo(g_vars["_WDFFUNCTIONS"] + function_offset)).frm except StopIteration: # this is case 2! - call_pfn = find_wdf_callback_through_immediate("mov", 1,function_offset) + call_pfn = find_wdf_callback_through_immediate("mov", 1, function_offset) if call_pfn is None: call_pfn = find_wdf_callback_through_immediate("call", 0, function_offset) if call_pfn != None: - idc.OpStroffEx(call_pfn,0,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) + idc.op_stroff(call_pfn, 0, (idaapi.get_struc_id("_WDFFUNCTIONS")), 0) lea_addr = find_function_arg(call_pfn, "lea", "r8", 0) EvtWdfIoInCallerContext = idc.get_operand_value(lea_addr, 1) idc.set_name(EvtWdfIoInCallerContext, 'EvtWdfIoInCallerContext') @@ -221,13 +225,13 @@ def find_WdfDeviceCreateDeviceInterface(): call_pfnWdfDeviceCreateDeviceInterface = find_wdf_callback_through_immediate("call", 0, function_offset) if call_pfnWdfDeviceCreateDeviceInterface: calls_to_pfn_list.append(call_pfnWdfDeviceCreateDeviceInterface) - idc.OpStroffEx(call_pfnWdfDeviceCreateDeviceInterface,0,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) + idc.op_stroff(call_pfnWdfDeviceCreateDeviceInterface,0,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) if len(calls_to_pfn_list) == 0: call_pfnWdfDeviceCreateDeviceInterface = find_wdf_callback_through_immediate("mov", 1,function_offset) if call_pfnWdfDeviceCreateDeviceInterface: calls_to_pfn_list.append(call_pfnWdfDeviceCreateDeviceInterface) - idc.OpStroffEx(call_pfnWdfDeviceCreateDeviceInterface,1,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) + idc.op_stroff(call_pfnWdfDeviceCreateDeviceInterface,1,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) for k, pfn_call in enumerate(calls_to_pfn_list): lea_guid = find_function_arg(pfn_call, "lea", "r8", 0) @@ -236,7 +240,7 @@ def find_WdfDeviceCreateDeviceInterface(): assign_struct_to_address(interface_guid, "GUID") g_vars["_InterfaceGUID" + str(k)] = interface_guid print("_InterfaceGUID: ", hex(interface_guid)) - guid_bytes = idc.GetManyBytes(interface_guid, 0x10) + guid_bytes = idc.get_bytes(interface_guid, 0x10) print_guid(guid_bytes) @@ -245,39 +249,39 @@ def find_WdfDriverCreate(): # If the XREF to wdfFunctions + function_offset exists.. then we're in case 1! try: - call_pfnWdfDriverCreate = idautils.XrefsTo(g_vars["_WDFFUNCTIONS"]+function_offset).next().frm + call_pfnWdfDriverCreate = next(idautils.XrefsTo(g_vars["_WDFFUNCTIONS"] + function_offset)).frm except StopIteration: # this is case 2! - call_pfnWdfDriverCreate = find_wdf_callback_through_immediate("mov", 1,function_offset) + call_pfnWdfDriverCreate = find_wdf_callback_through_immediate("mov", 1, function_offset) if call_pfnWdfDriverCreate != None: - idc.OpStroffEx(call_pfnWdfDriverCreate,1,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) + idc.op_stroff(call_pfnWdfDriverCreate, 1, (idaapi.get_struc_id("_WDFFUNCTIONS")),0) else: call_pfnWdfDriverCreate = find_wdf_callback_through_immediate("call", 0, function_offset) - idc.OpStroffEx(call_pfnWdfDriverCreate,0,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) + idc.op_stroff(call_pfnWdfDriverCreate,0,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) if call_pfnWdfDriverCreate != None: # First identify the RealDriverEntry :) current_func = idaapi.get_func(call_pfnWdfDriverCreate) - idc.set_name(current_func.startEA, "_DriverEntry_") - - argument_DriverConfig_addr = find_function_arg_with_operand_value(call_pfnWdfDriverCreate, "mov", "rsp", 0x20, 0) - register_DriverConfig = idc.print_operand(argument_DriverConfig_addr, 1) - lea_DriverConfig_addr = find_function_arg(argument_DriverConfig_addr, "lea", register_DriverConfig, 0) + idc.set_name(current_func.start_ea, "_DriverEntry_") + print("call WdfDriverCreate: {:#x}".format(call_pfnWdfDriverCreate)) + lea_DriverConfig_addr = find_function_arg(call_pfnWdfDriverCreate, "lea", "r9", 0) + # print("lea_DriverConfig_addr: {:#x}".format(lea_DriverConfig_addr)) # Get stack and the stack operand offset current_func = idaapi.get_func(lea_DriverConfig_addr) - stack_id = idc.GetFrame(current_func) + stack_id = idc.get_func_attr(current_func.start_ea, FUNCATTR_FRAME) opnd = idc.print_operand(lea_DriverConfig_addr, 1) if "rsp" in opnd: stack_member_offset = idc.get_operand_value(lea_DriverConfig_addr, 1) elif "rbp" in opnd: var_x = opnd.split("+")[-1][:-1] # [rbp+57h+var_80] -> var_80 - members, _ = retrieve_stack_members(current_func) + members, _ = retrieve_stack_members(current_func.start_ea) inverted_members = {v:k for k, v in members.items()} + # print(inverted_members) try: stack_member_offset = inverted_members[var_x] except KeyError as msg: - print(msg) + print("{} invalid!".format(msg)) return else: @@ -286,18 +290,20 @@ def find_WdfDriverCreate(): #idc.SetMemberName(stack_id, stack_member_offset, "_DriverConfig") struct_id = idaapi.get_struc_id("_WDF_DRIVER_CONFIG") - struct_size = idc.GetStrucSize(struct_id) + struct_size = idc.get_struc_size(struct_id) # First check if we have already touch this function stack before #if function_stack_erased(current_func): # need to take care of the already defined structs # pass #else: - delete_all_function_stack_members(current_func, force=True) - idc.AddStrucMember(stack_id, "driver_config", + delete_all_function_stack_members(current_func.start_ea, force = True) + idc.add_struc_member(stack_id, "driver_config", stack_member_offset, idc.FF_BYTE|idc.FF_DATA, -1, struct_size) - idc.SetMemberType(stack_id, stack_member_offset, idc.FF_STRU|idc.FF_DATA, struct_id, 1) + idc.set_member_type(stack_id, stack_member_offset, idc.FF_STRUCT|idc.FF_DATA, struct_id, 1) + # print("done!!!") + def find_WdfIoQueueCreate(): @@ -305,7 +311,7 @@ def find_WdfIoQueueCreate(): calls_to_pfn_list = [] try: - for xref in idautils.XrefsTo(g_vars["_WDFFUNCTIONS"]+function_offset): + for xref in idautils.XrefsTo(g_vars["_WDFFUNCTIONS"] + function_offset): call_pfnWdfIoQueueCreate = xref.frm calls_to_pfn_list.append(call_pfnWdfIoQueueCreate) except StopIteration: @@ -315,46 +321,48 @@ def find_WdfIoQueueCreate(): call_pfnWdfIoQueueCreate = find_wdf_callback_through_immediate("call", 0, function_offset) if call_pfnWdfIoQueueCreate: calls_to_pfn_list.append(call_pfnWdfIoQueueCreate) - idc.OpStroffEx(call_pfnWdfIoQueueCreate,0,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) + idc.op_stroff(call_pfnWdfIoQueueCreate,0,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) if len(calls_to_pfn_list) == 0: call_pfnWdfIoQueueCreate = find_wdf_callback_through_immediate("mov", 1,function_offset) if call_pfnWdfIoQueueCreate: calls_to_pfn_list.append(call_pfnWdfIoQueueCreate) - idc.OpStroffEx(call_pfnWdfIoQueueCreate,1,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) + idc.op_stroff(call_pfnWdfIoQueueCreate, 1, (idaapi.get_struc_id("_WDFFUNCTIONS")), 0) for pfn_call in calls_to_pfn_list: lea_argument_addr = find_function_arg(pfn_call, "lea", "r8", 0) # Get stack and the stack operand offset current_func = idaapi.get_func(lea_argument_addr) - stack_id = idc.GetFrame(current_func) + stack_id = idc.get_func_attr(current_func.start_ea, FUNCATTR_FRAME) stack_member_offset = idc.get_operand_value(lea_argument_addr, 1) struct_id = idaapi.get_struc_id("_WDF_IO_QUEUE_CONFIG") - struct_size = idc.GetStrucSize(struct_id) + struct_size = idc.get_struc_size(struct_id) # First check if we have already touch this function stack before - if function_stack_erased(current_func): + if function_stack_erased(current_func.start_ea): # need to take care of the already defined structs # If the arguments collide then this will fail pass else: - delete_all_function_stack_members(current_func) + delete_all_function_stack_members(current_func.start_ea) print("Erased the stack members") - idc.AddStrucMember(stack_id, "queue_config", + idc.add_struc_member(stack_id, "queue_config", stack_member_offset, idc.FF_BYTE|idc.FF_DATA, -1, struct_size) - idc.SetMemberType(stack_id, stack_member_offset, idc.FF_STRU|idc.FF_DATA, struct_id, 1) + idc.set_member_type(stack_id, stack_member_offset, idc.FF_STRUCT|idc.FF_DATA, struct_id, 1) print("IOQueue Creation at: " + hex(pfn_call)) + # [BUG] set type def find_WdfControlDeviceInitAllocate(): + breakpoint() function_offset = OFFSET_WdfControlDeviceInitAllocate call_pfn = None try: - for xref in idautils.XrefsTo(g_vars["_WDFFUNCTIONS"]+function_offset): + for xref in idautils.XrefsTo(g_vars["_WDFFUNCTIONS"] + function_offset): call_pfn = xref.frm except StopIteration: # this is case 2 or 3 @@ -362,12 +370,12 @@ def find_WdfControlDeviceInitAllocate(): if call_pfn is None: call_pfn = find_wdf_callback_through_immediate("call", 0, function_offset) if call_pfn: - idc.OpStroffEx(call_pfn,0,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) + idc.op_stroff(call_pfn,0,(idaapi.get_struc_id("_WDFFUNCTIONS")), 0) if call_pfn is None: - call_pfn = find_wdf_callback_through_immediate("mov", 1,function_offset) + call_pfn = find_wdf_callback_through_immediate("mov", 1, function_offset) if call_pfn: - idc.OpStroffEx(call_pfn,1,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) + idc.op_stroff(call_pfn, 1, (idaapi.get_struc_id("_WDFFUNCTIONS")), 0) lea_sddl = find_function_arg(call_pfn, "lea", "r8", 0) unicode_sddl = idc.get_operand_value(lea_sddl, 1) @@ -376,48 +384,48 @@ def find_WdfControlDeviceInitAllocate(): print("Control Device SDDL at: ", hex(unicode_sddl)) - def assign_kmdf_structure_types(address): # Get the jmp to de import - jmp_import_ea = next(idautils.XrefsTo(address)).frm + jmp_import_ea = next(idautils.XrefsTo(address)).frm # first reference to WdfVersionBind, can be call or jmp + call_wdfVersionBind = 0 + # print("jmp_import_ea : {:#x}".format(jmp_import_ea)) + if idc.print_insn_mnem(jmp_import_ea) == "call": + call_wdfVersionBind = jmp_import_ea + # There is only one XREF to WdfVersionBind - call_wdfVersionBind = next(idautils.XrefsTo(jmp_import_ea)).frm - print(hex(call_wdfVersionBind)) + call_wdfVersionBind = call_wdfVersionBind if call_wdfVersionBind else next(idautils.XrefsTo(jmp_import_ea)).frm + print("call WdfVersionBind: {:#x}".format(call_wdfVersionBind)) + argument_WdfBindInfo = find_function_arg(call_wdfVersionBind, "lea", "r8", 0) if argument_WdfBindInfo is None: - print("Error: Argument WdfBindInfo wasn't found!") + print("Error: Argument wdfBindInfo wasn't found!") return wdfBindInfo = idc.get_operand_value(argument_WdfBindInfo, 1) - idc.set_name(wdfBindInfo, '_WdfBindInfo') - print("WdfBindInfo Struct: ", hex(wdfBindInfo)) - if not assign_struct_to_address(wdfBindInfo, "_WDF_BIND_INFO"): - print("The _WDF_BIND_INFO struct wasn't found in the database") - return + idc.SetType(wdfBindInfo, "WDF_BIND_INFO") + idc.set_name(wdfBindInfo, "WdfBindInfo") + print("WdfBindInfo Struct: {:#x}".format(wdfBindInfo)) g_vars["_WDF_BIND_INFO"] = wdfBindInfo - # Assign ComponentGlobals Name + argument_WdfComponentGlobals = find_function_arg(call_wdfVersionBind, "lea", "r9", 0) wdfComponentGlobals = idc.get_operand_value(argument_WdfComponentGlobals, 1) + idc.set_name(wdfComponentGlobals, "WdfComponentGlobals") g_vars["_WDF_COMPONENT_GLOBALS"] = wdfComponentGlobals - idc.set_name(wdfComponentGlobals, '_WdfComponentGlobals') + # Now assign the WDFFUNCTIONS to FuncTable - wdfFunctions = idc.get_qword(wdfBindInfo+0x20) + wdfFunctions = idc.get_qword(wdfBindInfo + 0x20) g_vars["_WDFFUNCTIONS"] = wdfFunctions - assign_struct_to_address(wdfFunctions, "_WDFFUNCTIONS") + idc.SetType(wdfFunctions, "PWDFFUNCTIONS") idc.set_name(wdfFunctions, 'g_WdfF_Functions') - #if not assign_struct_to_address(wdfFunctions, "_WDFFUNCTIONS"): - # print("The _WDFFUNCTIONS struct wasn't found in the database") - # return - # Callback to get the EA of WdfVersionBind def imp_cb(ea, name, ord): - if not name: - print("%08x: ord#%d" % (ea, ord)) - else: - print("%08x: %s (ord#%d)" % (ea, name, ord)) + # if not name: + # print("%08x: ord#%d" % (ea, ord)) + # else: + # print("%08x: %s (ord#%d)" % (ea, name, ord)) if name == "WdfVersionBind": assign_kmdf_structure_types(ea) return False @@ -428,68 +436,70 @@ def imp_cb(ea, name, ord): ############################################################################## 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()): - print(idx, idc.get_numbered_type_name(idx)) - idc.import_type(idx, idc.get_numbered_type_name(idx)) - -############################################################################## - - -############################################################################## - -load_kmdf_types_into_idb() -for module_idx in range(idaapi.get_import_module_qty()): - if idaapi.get_import_module_name(module_idx) == "WDFLDR": - idaapi.enum_import_names(module_idx, imp_cb) - -if len(list_xref_to_wdf_callback(OFFSET_WdfDeviceCreateDeviceInterface)) == 0: - print("The driver is not exposing any DeviceInterface") -if len(list_xref_to_wdf_callback(OFFSET_WdfDeviceCreateSymbolicLink)) == 0: - print("The driver is not creating a Symbolic Link") -if len(list_xref_to_wdf_callback(OFFSET_WdfIoQueueCreate)) == 0: - print("The driver is not creating an IOQueue") -if len(list_xref_to_wdf_callback(OFFSET_WdfDeviceInitSetIoIncallerContextCallback)) == 0: - print("The driver is not setting an EvtInCallerContextCallback") -for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveInputMemory): - print("Call To WdfRequestRetrieveInputMemory: " + hex(i)) -for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveOutputMemory): - print("Call To WdfRequestRetrieveOutputMemory: " + hex(i)) -for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveInputBuffer): - print("Call To WdfRequestRetrieveInputBuffer: " + hex(i)) -for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveOutputBuffer): - print("Call To WdfRequestRetrieveOutputBuffer: " + hex(i)) -for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveInputWdmMdl): - print("Call To WdfRequestRetrieveInputWdmMdl: " + hex(i)) -for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveOutputWdmMdl): - print("Call To WdfRequestRetrieveOutputWdmMdl: " + hex(i)) -for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveUnsafeUserInputBuffer): - print("Call To WdfRequestRetrieveUnsafeUserInputBuffer: " + hex(i)) -for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveUnsafeUserOutputBuffer): - print("Call To WdfRequestRetrieveUnsafeUserOutputBuffer: " + hex(i)) - + return idaapi.idc_parse_types(os.path.dirname(sys.argv[0]) + "/WDFStructs.h", idc.PT_FILE) def supress_exception(cb): try: + # print("try {}".format(cb)) cb() - except: + # print("{} done".format(cb)) + except Exception as e: + print(e) pass -g_vars["ERASE_STACK_MEMBERS"] = True - -supress_exception(find_WdfDriverCreate) -supress_exception(find_WdfIoQueueCreate) -supress_exception(find_WdfDeviceInitSetIoInCallerContextCallback) -supress_exception(find_WdfDeviceCreateDeviceInterface) -supress_exception(find_WdfControlDeviceInitAllocate) - - - - +############################################################################## +############################################################################## +def main(): + if load_kmdf_types_into_idb() != 0: + print("Invalid header file {}".format(os.path.dirname(sys.argv[0]) + "/WDFStructs.h")) + return + for module_idx in range(idaapi.get_import_module_qty()): + if idaapi.get_import_module_name(module_idx) == "WDFLDR": + idaapi.enum_import_names(module_idx, imp_cb) + else: + assert("doesn't import WDFLDR.sys, maybe not WDF drivers") + + + if len(list_xref_to_wdf_callback(OFFSET_WdfDeviceCreateDeviceInterface)) == 0: + print("The driver is not exposing any DeviceInterface") + if len(list_xref_to_wdf_callback(OFFSET_WdfDeviceCreateSymbolicLink)) == 0: + print("The driver is not creating a Symbolic Link") + if len(list_xref_to_wdf_callback(OFFSET_WdfIoQueueCreate)) == 0: + print("The driver is not creating an IOQueue") + if len(list_xref_to_wdf_callback(OFFSET_WdfDeviceInitSetIoIncallerContextCallback)) == 0: + print("The driver is not setting an EvtInCallerContextCallback") + + for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveInputMemory): + print("Call To WdfRequestRetrieveInputMemory: " + hex(i)) + for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveOutputMemory): + print("Call To WdfRequestRetrieveOutputMemory: " + hex(i)) + for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveInputBuffer): + print("Call To WdfRequestRetrieveInputBuffer: " + hex(i)) + for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveOutputBuffer): + print("Call To WdfRequestRetrieveOutputBuffer: " + hex(i)) + for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveInputWdmMdl): + print("Call To WdfRequestRetrieveInputWdmMdl: " + hex(i)) + for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveOutputWdmMdl): + print("Call To WdfRequestRetrieveOutputWdmMdl: " + hex(i)) + for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveUnsafeUserInputBuffer): + print("Call To WdfRequestRetrieveUnsafeUserInputBuffer: " + hex(i)) + for i in list_xref_to_wdf_callback(OFFSET_WdfRequestRetrieveUnsafeUserOutputBuffer): + print("Call To WdfRequestRetrieveUnsafeUserOutputBuffer: " + hex(i)) + + + + g_vars["ERASE_STACK_MEMBERS"] = True + + supress_exception(find_WdfDriverCreate) + supress_exception(find_WdfIoQueueCreate) + supress_exception(find_WdfDeviceInitSetIoInCallerContextCallback) + supress_exception(find_WdfDeviceCreateDeviceInterface) + supress_exception(find_WdfControlDeviceInitAllocate) + +main() """ # 00000000167ED lea r8, [rbp+190h+var_170] @@ -506,12 +516,12 @@ def supress_exception(cb): target_struct_id = idaapi.get_struc_id("_WDF_DRIVER_CONFIG") target_struc = idaapi.get_struc(target_struct_id ) -idc.DelStrucMember(stack_id, stack_member_offset) -AddStrucMember(stack_id, "driver_config", stack_member_offset, FF_BYTE|FF_DATA, -1, GetStrucSize(target_struct_id)) -idc.SetMemberType(stack_id, stack_member_offset, idc.FF_STRU|idc.FF_DATA, target_struct_id, 1) +idc.del_struc_member(stack_id, stack_member_offset) +add_struc_member(stack_id, "driver_config", stack_member_offset, FF_BYTE|FF_DATA, -1, get_struc_size(target_struct_id)) +idc.set_member_type(stack_id, stack_member_offset, idc.FF_STRUCT|idc.FF_DATA, target_struct_id, 1) -idc.SetMemberType(stack_id, stack_member_offset, idc.FF_BYTE|idc.FF_DATA, target_struct_id, 0x20) +idc.set_member_type(stack_id, stack_member_offset, idc.FF_BYTE|idc.FF_DATA, target_struct_id, 0x20) set_member_tinfo(None, stack_struc ,stack_member ,0, target_struc, 0, 0)