diff --git a/ctypes_generation/com_parser.py b/ctypes_generation/com_parser.py index e89e6d1..58c763a 100644 --- a/ctypes_generation/com_parser.py +++ b/ctypes_generation/com_parser.py @@ -143,8 +143,11 @@ class WinComParser(Parser): Method = namedtuple("Method", ["ret_type", "name", "args"]) MethodArg = namedtuple("MethodArg", ["type", "byreflevel", "name"]) class WinCOMVTABLE(object): - def __init__(self, name): - self.name = name + def __init__(self, vtbl_name): + self.vtbl_name = vtbl_name + if not vtbl_name.endswith("Vtbl"): + raise ValueError("Com interface are expected to finish by got <{0}".format(vtbl.name)) + self.name = vtbl_name[:-len("Vtbl")] self.methods = [] def add_method(self, ret_type, method_name, args): diff --git a/ctypes_generation/generate.py b/ctypes_generation/generate.py index d1cd17e..82d322c 100644 --- a/ctypes_generation/generate.py +++ b/ctypes_generation/generate.py @@ -83,12 +83,15 @@ FUNC_FILE = "winfunc.txt" STRUCT_FILE = "winstruct.txt" DEF_FILE = "windef.txt" NTSTATUS_FILE = "ntstatus.txt" +NAME_TO_IID_FILE = "interface_to_iid.txt" COM_INTERFACE_DIR_GLOB = "com/*.txt" GENERATED_STRUCT_FILE = "winstructs" GENERATED_FUNC_FILE = "winfuncs" GENERATED_DEF_FILE = "windef" GENERATED_NTSTATUS_FILE = "ntstatus" +GENERATED_COM_FILE = "interfaces" +#GENERATED_NAME_TO_IID_FILE = "com_iid" OUT_DIRS = ["..\windows\generated_def"] if len(sys.argv) > 1: @@ -123,17 +126,14 @@ def verif_funcs_type(funcs, structs, enums): raise ValueError("UNKNOW PARAM TYPE {0}".format(param_type)) -yolo_struct = [x[:-4] for x in os.listdir(r"C:\Users\hakril\Documents\Work\COM\dump")] +try: + yolo_struct = [x[:-4] for x in os.listdir(r"C:\Users\hakril\Documents\Work\COM\dump")] +except WindowsError: + yolo_struct = [] def verif_com_interface_type(vtbls, struc, enum): all_struct_name = get_all_struct_name(structs, enums) - all_interface_name = [] - - #ALSO accept void - for vtbl in vtbls: - if not vtbl.name.endswith("Vtbl"): - raise ValueError("Com interface are expected to finish by got <{0}".format(vtbl.name)) - all_interface_name.append(vtbl.name[:-len("Vtbl")]) + all_interface_name = [vtbl.name for vtbl in vtbls] for vtbl in vtbls: #print(vtbl) @@ -148,6 +148,7 @@ def verif_com_interface_type(vtbls, struc, enum): if param_type not in known_type and param_type not in all_struct_name + all_interface_name: #if param_type != "ITypeInfo": if param_type in yolo_struct: + import pdb;pdb.set_trace() print("Ned to extract <{0}> from dump".format(param_type)) import shutil #shutil.copy(r"C:\Users\hakril\Documents\Work\COM\dump\{0}.txt".format(param_type), "com") @@ -248,32 +249,76 @@ def generate_struct_ctypes(structs, enums): return ctypes_str +data = open(NAME_TO_IID_FILE).read() +iids_def = {} +for line in data.split("\n"): + name, iid = line.split("|") + part_iid = iid.split("-") + str_iid = [] + str_iid.append("0x" + part_iid[0]) + str_iid.append("0x" + part_iid[1]) + str_iid.append("0x" + part_iid[2]) + str_iid.append("0x" + part_iid[3][:2]) + str_iid.append("0x" + part_iid[3][2:]) + for i in range(6): str_iid.append("0x" + part_iid[4][i * 2:(i + 1) * 2]) + iids_def[name] = ", ".join(str_iid), iid +#full_name_to_iid = name_to_iid_header + "\n".join(iids_def) + + com_interface_header = """ -from windows.simple_com import * +import functools import ctypes +from winstructs import * + +class IID(IID): + def __init__(self, Data1, Data2, Data3, Data4, name=None, strid=None): + self.name = name + self.strid = strid + super(IID, self).__init__(Data1, Data2, Data3, Data4) + + def __repr__(self): + if self.strid is None: + return super(IID, self).__repr__() + if self.name is None: + return ''.format(self.strid.upper()) + return ''.format(self.strid.upper(), self.name) + +def generate_IID(Data1, Data2, Data3, Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48, **kwargs): + return IID(Data1, Data2, Data3, (BYTE*8)(Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48), **kwargs) + + +class COMInterface(ctypes.c_void_p): + _functions_ = { + } + + def __getattr__(self, name): + if name in self._functions_: + return functools.partial(self._functions_[name], self) + return super(COMInterface, self).__getattribute__(name) """ com_interface_template = """ class {0}(COMInterface): + IID = generate_IID({2}, name="{0}", strid="{3}") + _functions_ = {{ {1} }} """ com_interface_comment_template = """ #{0} -> {1}""" -com_interface_method_template = """ "{0}": ctypes.WINFUNCTYPE({1}),""" +com_interface_method_template = """ "{0}": ctypes.WINFUNCTYPE({1})({2}, "{0}"),""" def generate_com_interface_ctype(vtbls): - print(vtbls) define = [] - all_name = [vtbl.name.strip("Vtbl") for vtbl in vtbls] + all_name = [vtbl.name for vtbl in vtbls] for vtbl in vtbls: methods_string = [] - for method in vtbl.methods: + for method_nb, method in enumerate(vtbl.methods): args_to_define = method.args[1:] #ctypes doesnt not need the This #import pdb;pdb.set_trace() str_args = [] - methods_string.append(com_interface_comment_template.format(method.name, ", ".join([("*"* arg.byreflevel) + arg.name +":"+arg.type for arg in args_to_define]))) + methods_string.append(com_interface_comment_template.format(method.name, ", ".join([arg.name +":"+ ("*"* arg.byreflevel) +arg.type for arg in args_to_define]))) for arg in args_to_define: type = arg.type byreflevel = arg.byreflevel @@ -288,9 +333,10 @@ def generate_com_interface_ctype(vtbls): for i in range(byreflevel): type = "POINTER({0})".format(type) str_args.append(type) - methods_string.append(com_interface_method_template.format(method.name, ", ".join([method.ret_type] + str_args))) + methods_string.append(com_interface_method_template.format(method.name, ", ".join([method.ret_type] + str_args), method_nb)) #import pdb;pdb.set_trace() - define.append((com_interface_template.format(vtbl.name, "\n".join(methods_string)))) + iid_python, iid_str = iids_def[vtbl.name] + define.append((com_interface_template.format(vtbl.name, "\n".join(methods_string), iid_python, iid_str))) return com_interface_header + "\n".join(define) def write_to_out_file(name, data): @@ -317,7 +363,6 @@ structs_code = open(STRUCT_FILE, 'r').read() defs = def_parser.WinDefParser(def_code).parse() funcs = func_parser.WinFuncParser(funcs_code).parse() structs, enums = struct_parser.WinStructParser(structs_code).parse() - vtbls = parse_com_interfaces(glob.glob(COM_INTERFACE_DIR_GLOB)) validate_structs(structs, enums, defs) @@ -337,9 +382,17 @@ funcs_ctypes = generate_funcs_ctypes(funcs) structs_ctypes = generate_struct_ctypes(structs, enums) com_interface_ctypes = generate_com_interface_ctype(vtbls) -f = open("yolo.py", "w") -f.write(com_interface_ctypes) -f.close() +# Create name -> IID file + +name_to_iid_header = """ +from winstructs import IID, BYTE + +""" + + +#f = open("yolo.py", "w") +#f.write(com_interface_ctypes) +#f.close() for out_dir in OUT_DIRS: if not os.path.exists(out_dir): @@ -348,7 +401,8 @@ for out_dir in OUT_DIRS: write_to_out_file(GENERATED_DEF_FILE, defs_ctypes) write_to_out_file(GENERATED_FUNC_FILE, funcs_ctypes) write_to_out_file(GENERATED_STRUCT_FILE, structs_ctypes) - +write_to_out_file(GENERATED_COM_FILE, com_interface_ctypes) +#write_to_out_file(GENERATED_NAME_TO_IID_FILE, full_name_to_iid) NTSTATUS_HEAD = """ class NtStatusException(Exception): diff --git a/ctypes_generation/winstruct.txt b/ctypes_generation/winstruct.txt index 0ee5ea4..864d902 100644 --- a/ctypes_generation/winstruct.txt +++ b/ctypes_generation/winstruct.txt @@ -388,6 +388,203 @@ typedef enum NET_FW_RULE_DIRECTION_ { NET_FW_RULE_DIR_MAX = 3 } NET_FW_RULE_DIRECTION; + +typedef enum tag_WBEMSTATUS { + WBEM_NO_ERROR = 0, + WBEM_S_NO_ERROR = 0, + WBEM_S_SAME = 0, + WBEM_S_FALSE = 1, + WBEM_S_ALREADY_EXISTS = 0x40001, + WBEM_S_RESET_TO_DEFAULT = 0x40002, + WBEM_S_DIFFERENT = 0x40003, + WBEM_S_TIMEDOUT = 0x40004, + WBEM_S_NO_MORE_DATA = 0x40005, + WBEM_S_OPERATION_CANCELLED = 0x40006, + WBEM_S_PENDING = 0x40007, + WBEM_S_DUPLICATE_OBJECTS = 0x40008, + WBEM_S_ACCESS_DENIED = 0x40009, + WBEM_S_PARTIAL_RESULTS = 0x40010, + WBEM_S_SOURCE_NOT_AVAILABLE = 0x40017, + WBEM_E_FAILED = 0x80041001, + WBEM_E_NOT_FOUND = 0x80041002, + WBEM_E_ACCESS_DENIED = 0x80041003, + WBEM_E_PROVIDER_FAILURE = 0x80041004, + WBEM_E_TYPE_MISMATCH = 0x80041005, + WBEM_E_OUT_OF_MEMORY = 0x80041006, + WBEM_E_INVALID_CONTEXT = 0x80041007, + WBEM_E_INVALID_PARAMETER = 0x80041008, + WBEM_E_NOT_AVAILABLE = 0x80041009, + WBEM_E_CRITICAL_ERROR = 0x8004100a, + WBEM_E_INVALID_STREAM = 0x8004100b, + WBEM_E_NOT_SUPPORTED = 0x8004100c, + WBEM_E_INVALID_SUPERCLASS = 0x8004100d, + WBEM_E_INVALID_NAMESPACE = 0x8004100e, + WBEM_E_INVALID_OBJECT = 0x8004100f, + WBEM_E_INVALID_CLASS = 0x80041010, + WBEM_E_PROVIDER_NOT_FOUND = 0x80041011, + WBEM_E_INVALID_PROVIDER_REGISTRATION = 0x80041012, + WBEM_E_PROVIDER_LOAD_FAILURE = 0x80041013, + WBEM_E_INITIALIZATION_FAILURE = 0x80041014, + WBEM_E_TRANSPORT_FAILURE = 0x80041015, + WBEM_E_INVALID_OPERATION = 0x80041016, + WBEM_E_INVALID_QUERY = 0x80041017, + WBEM_E_INVALID_QUERY_TYPE = 0x80041018, + WBEM_E_ALREADY_EXISTS = 0x80041019, + WBEM_E_OVERRIDE_NOT_ALLOWED = 0x8004101a, + WBEM_E_PROPAGATED_QUALIFIER = 0x8004101b, + WBEM_E_PROPAGATED_PROPERTY = 0x8004101c, + WBEM_E_UNEXPECTED = 0x8004101d, + WBEM_E_ILLEGAL_OPERATION = 0x8004101e, + WBEM_E_CANNOT_BE_KEY = 0x8004101f, + WBEM_E_INCOMPLETE_CLASS = 0x80041020, + WBEM_E_INVALID_SYNTAX = 0x80041021, + WBEM_E_NONDECORATED_OBJECT = 0x80041022, + WBEM_E_READ_ONLY = 0x80041023, + WBEM_E_PROVIDER_NOT_CAPABLE = 0x80041024, + WBEM_E_CLASS_HAS_CHILDREN = 0x80041025, + WBEM_E_CLASS_HAS_INSTANCES = 0x80041026, + WBEM_E_QUERY_NOT_IMPLEMENTED = 0x80041027, + WBEM_E_ILLEGAL_NULL = 0x80041028, + WBEM_E_INVALID_QUALIFIER_TYPE = 0x80041029, + WBEM_E_INVALID_PROPERTY_TYPE = 0x8004102a, + WBEM_E_VALUE_OUT_OF_RANGE = 0x8004102b, + WBEM_E_CANNOT_BE_SINGLETON = 0x8004102c, + WBEM_E_INVALID_CIM_TYPE = 0x8004102d, + WBEM_E_INVALID_METHOD = 0x8004102e, + WBEM_E_INVALID_METHOD_PARAMETERS = 0x8004102f, + WBEM_E_SYSTEM_PROPERTY = 0x80041030, + WBEM_E_INVALID_PROPERTY = 0x80041031, + WBEM_E_CALL_CANCELLED = 0x80041032, + WBEM_E_SHUTTING_DOWN = 0x80041033, + WBEM_E_PROPAGATED_METHOD = 0x80041034, + WBEM_E_UNSUPPORTED_PARAMETER = 0x80041035, + WBEM_E_MISSING_PARAMETER_ID = 0x80041036, + WBEM_E_INVALID_PARAMETER_ID = 0x80041037, + WBEM_E_NONCONSECUTIVE_PARAMETER_IDS = 0x80041038, + WBEM_E_PARAMETER_ID_ON_RETVAL = 0x80041039, + WBEM_E_INVALID_OBJECT_PATH = 0x8004103a, + WBEM_E_OUT_OF_DISK_SPACE = 0x8004103b, + WBEM_E_BUFFER_TOO_SMALL = 0x8004103c, + WBEM_E_UNSUPPORTED_PUT_EXTENSION = 0x8004103d, + WBEM_E_UNKNOWN_OBJECT_TYPE = 0x8004103e, + WBEM_E_UNKNOWN_PACKET_TYPE = 0x8004103f, + WBEM_E_MARSHAL_VERSION_MISMATCH = 0x80041040, + WBEM_E_MARSHAL_INVALID_SIGNATURE = 0x80041041, + WBEM_E_INVALID_QUALIFIER = 0x80041042, + WBEM_E_INVALID_DUPLICATE_PARAMETER = 0x80041043, + WBEM_E_TOO_MUCH_DATA = 0x80041044, + WBEM_E_SERVER_TOO_BUSY = 0x80041045, + WBEM_E_INVALID_FLAVOR = 0x80041046, + WBEM_E_CIRCULAR_REFERENCE = 0x80041047, + WBEM_E_UNSUPPORTED_CLASS_UPDATE = 0x80041048, + WBEM_E_CANNOT_CHANGE_KEY_INHERITANCE = 0x80041049, + WBEM_E_CANNOT_CHANGE_INDEX_INHERITANCE = 0x80041050, + WBEM_E_TOO_MANY_PROPERTIES = 0x80041051, + WBEM_E_UPDATE_TYPE_MISMATCH = 0x80041052, + WBEM_E_UPDATE_OVERRIDE_NOT_ALLOWED = 0x80041053, + WBEM_E_UPDATE_PROPAGATED_METHOD = 0x80041054, + WBEM_E_METHOD_NOT_IMPLEMENTED = 0x80041055, + WBEM_E_METHOD_DISABLED = 0x80041056, + WBEM_E_REFRESHER_BUSY = 0x80041057, + WBEM_E_UNPARSABLE_QUERY = 0x80041058, + WBEM_E_NOT_EVENT_CLASS = 0x80041059, + WBEM_E_MISSING_GROUP_WITHIN = 0x8004105a, + WBEM_E_MISSING_AGGREGATION_LIST = 0x8004105b, + WBEM_E_PROPERTY_NOT_AN_OBJECT = 0x8004105c, + WBEM_E_AGGREGATING_BY_OBJECT = 0x8004105d, + WBEM_E_UNINTERPRETABLE_PROVIDER_QUERY = 0x8004105f, + WBEM_E_BACKUP_RESTORE_WINMGMT_RUNNING = 0x80041060, + WBEM_E_QUEUE_OVERFLOW = 0x80041061, + WBEM_E_PRIVILEGE_NOT_HELD = 0x80041062, + WBEM_E_INVALID_OPERATOR = 0x80041063, + WBEM_E_LOCAL_CREDENTIALS = 0x80041064, + WBEM_E_CANNOT_BE_ABSTRACT = 0x80041065, + WBEM_E_AMENDED_OBJECT = 0x80041066, + WBEM_E_CLIENT_TOO_SLOW = 0x80041067, + WBEM_E_NULL_SECURITY_DESCRIPTOR = 0x80041068, + WBEM_E_TIMED_OUT = 0x80041069, + WBEM_E_INVALID_ASSOCIATION = 0x8004106a, + WBEM_E_AMBIGUOUS_OPERATION = 0x8004106b, + WBEM_E_QUOTA_VIOLATION = 0x8004106c, + WBEM_E_RESERVED_001 = 0x8004106d, + WBEM_E_RESERVED_002 = 0x8004106e, + WBEM_E_UNSUPPORTED_LOCALE = 0x8004106f, + WBEM_E_HANDLE_OUT_OF_DATE = 0x80041070, + WBEM_E_CONNECTION_FAILED = 0x80041071, + WBEM_E_INVALID_HANDLE_REQUEST = 0x80041072, + WBEM_E_PROPERTY_NAME_TOO_WIDE = 0x80041073, + WBEM_E_CLASS_NAME_TOO_WIDE = 0x80041074, + WBEM_E_METHOD_NAME_TOO_WIDE = 0x80041075, + WBEM_E_QUALIFIER_NAME_TOO_WIDE = 0x80041076, + WBEM_E_RERUN_COMMAND = 0x80041077, + WBEM_E_DATABASE_VER_MISMATCH = 0x80041078, + WBEM_E_VETO_DELETE = 0x80041079, + WBEM_E_VETO_PUT = 0x8004107a, + WBEM_E_INVALID_LOCALE = 0x80041080, + WBEM_E_PROVIDER_SUSPENDED = 0x80041081, + WBEM_E_SYNCHRONIZATION_REQUIRED = 0x80041082, + WBEM_E_NO_SCHEMA = 0x80041083, + WBEM_E_PROVIDER_ALREADY_REGISTERED = 0x80041084, + WBEM_E_PROVIDER_NOT_REGISTERED = 0x80041085, + WBEM_E_FATAL_TRANSPORT_ERROR = 0x80041086, + WBEM_E_ENCRYPTED_CONNECTION_REQUIRED = 0x80041087, + WBEM_E_PROVIDER_TIMED_OUT = 0x80041088, + WBEM_E_NO_KEY = 0x80041089, + WBEM_E_PROVIDER_DISABLED = 0x8004108a, + WBEMESS_E_REGISTRATION_TOO_BROAD = 0x80042001, + WBEMESS_E_REGISTRATION_TOO_PRECISE = 0x80042002, + WBEMESS_E_AUTHZ_NOT_PRIVILEGED = 0x80042003, + WBEMMOF_E_EXPECTED_QUALIFIER_NAME = 0x80044001, + WBEMMOF_E_EXPECTED_SEMI = 0x80044002, + WBEMMOF_E_EXPECTED_OPEN_BRACE = 0x80044003, + WBEMMOF_E_EXPECTED_CLOSE_BRACE = 0x80044004, + WBEMMOF_E_EXPECTED_CLOSE_BRACKET = 0x80044005, + WBEMMOF_E_EXPECTED_CLOSE_PAREN = 0x80044006, + WBEMMOF_E_ILLEGAL_CONSTANT_VALUE = 0x80044007, + WBEMMOF_E_EXPECTED_TYPE_IDENTIFIER = 0x80044008, + WBEMMOF_E_EXPECTED_OPEN_PAREN = 0x80044009, + WBEMMOF_E_UNRECOGNIZED_TOKEN = 0x8004400a, + WBEMMOF_E_UNRECOGNIZED_TYPE = 0x8004400b, + WBEMMOF_E_EXPECTED_PROPERTY_NAME = 0x8004400c, + WBEMMOF_E_TYPEDEF_NOT_SUPPORTED = 0x8004400d, + WBEMMOF_E_UNEXPECTED_ALIAS = 0x8004400e, + WBEMMOF_E_UNEXPECTED_ARRAY_INIT = 0x8004400f, + WBEMMOF_E_INVALID_AMENDMENT_SYNTAX = 0x80044010, + WBEMMOF_E_INVALID_DUPLICATE_AMENDMENT = 0x80044011, + WBEMMOF_E_INVALID_PRAGMA = 0x80044012, + WBEMMOF_E_INVALID_NAMESPACE_SYNTAX = 0x80044013, + WBEMMOF_E_EXPECTED_CLASS_NAME = 0x80044014, + WBEMMOF_E_TYPE_MISMATCH = 0x80044015, + WBEMMOF_E_EXPECTED_ALIAS_NAME = 0x80044016, + WBEMMOF_E_INVALID_CLASS_DECLARATION = 0x80044017, + WBEMMOF_E_INVALID_INSTANCE_DECLARATION = 0x80044018, + WBEMMOF_E_EXPECTED_DOLLAR = 0x80044019, + WBEMMOF_E_CIMTYPE_QUALIFIER = 0x8004401a, + WBEMMOF_E_DUPLICATE_PROPERTY = 0x8004401b, + WBEMMOF_E_INVALID_NAMESPACE_SPECIFICATION = 0x8004401c, + WBEMMOF_E_OUT_OF_RANGE = 0x8004401d, + WBEMMOF_E_INVALID_FILE = 0x8004401e, + WBEMMOF_E_ALIASES_IN_EMBEDDED = 0x8004401f, + WBEMMOF_E_NULL_ARRAY_ELEM = 0x80044020, + WBEMMOF_E_DUPLICATE_QUALIFIER = 0x80044021, + WBEMMOF_E_EXPECTED_FLAVOR_TYPE = 0x80044022, + WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES = 0x80044023, + WBEMMOF_E_MULTIPLE_ALIASES = 0x80044024, + WBEMMOF_E_INCOMPATIBLE_FLAVOR_TYPES2 = 0x80044025, + WBEMMOF_E_NO_ARRAYS_RETURNED = 0x80044026, + WBEMMOF_E_MUST_BE_IN_OR_OUT = 0x80044027, + WBEMMOF_E_INVALID_FLAGS_SYNTAX = 0x80044028, + WBEMMOF_E_EXPECTED_BRACE_OR_BAD_TYPE = 0x80044029, + WBEMMOF_E_UNSUPPORTED_CIMV22_QUAL_VALUE = 0x8004402a, + WBEMMOF_E_UNSUPPORTED_CIMV22_DATA_TYPE = 0x8004402b, + WBEMMOF_E_INVALID_DELETEINSTANCE_SYNTAX = 0x8004402c, + WBEMMOF_E_INVALID_QUALIFIER_SYNTAX = 0x8004402d, + WBEMMOF_E_QUALIFIER_USED_OUTSIDE_SCOPE = 0x8004402e, + WBEMMOF_E_ERROR_CREATING_TEMP_FILE = 0x8004402f, + WBEMMOF_E_ERROR_INVALID_INCLUDE_FILE = 0x80044030, + WBEMMOF_E_INVALID_DELETECLASS_SYNTAX = 0x80044031 +} WBEMSTATUS; + typedef struct _LDR_DATA_TABLE_ENTRY { PVOID Reserved1[2]; LIST_ENTRY InMemoryOrderLinks; @@ -1302,7 +1499,7 @@ typedef struct _GUID { ULONG Data1; USHORT Data2; USHORT Data3; - UCHAR Data4[ 8 ]; + BYTE Data4[ 8 ]; } GUID, IID, *REFIID; @@ -1376,7 +1573,7 @@ union TMP_variant_sub_union{ ULONGLONG *pullVal; INT *pintVal; UINT *puintVal; - _tagBRECORD __VARIANT_NAME_4; + _tagBRECORD _VARIANT_NAME_4; }; typedef enum tagTYPEKIND { @@ -1400,7 +1597,7 @@ typedef struct __tagVARIANT { WORD wReserved1; WORD wReserved2; WORD wReserved3; - TMP_variant_sub_union __VARIANT_NAME_3; + TMP_variant_sub_union _VARIANT_NAME_3; } _tagVARIANT, VARIANT, VARIANTARG, *LPVARIANT, *LPVARIANTARG;