def normalize_NtQueryValueKey(pre, post): if pre is None or post is None: return # Normalize only if the syscall succeded if post.getRetval().getVal().getValue() == "0": # get the KeyValueInformationClass kvic = pre.getArgument(3).getVal().getValue() void = post.getArgument(4).getVal().getValue() void = decode_base64(void) if kvic == '0': # KeyValueBasicInformation assert False, "TODO" elif kvic == '1': # KeyValueFullInformation titleindex, type, dataoffset, datalength, namelength = \ struct.unpack("LLLLL", void[0:20]) data = void[20:20+namelength] data = decode_unicode(data) v = StructArgument(name = "KeyValueInformation", typ = "KEY_VALUE_FULL_INFORMATION") v.addField(BasicArgument(name = "TitleIndex", typ = "ULONG", v = titleindex)) v.addField(BasicArgument(name = "Type", typ = "ULONG", v = type)) v.addField(BasicArgument(name = "DataOffset", typ = "ULONG", v = dataoffset)) v.addField(BasicArgument(name = "DataLength", typ = "ULONG", v = datalength)) v.addField(BasicArgument(name = "NameLength", typ = "ULONG", v = namelength)) v.addField(BasicArgument(name = "Name", typ = "PWCHAR", v = data)) post.getArgument(4).setVal(v) elif kvic == '2': # KeyValuePartialInformation titleindex, type, datalength = struct.unpack("LLL", void[0:12]) data = void[12:12+datalength] v = StructArgument(name = "KeyValueInformation", typ = "KEY_VALUE_PARTIAL_INFORMATION") v.addField(BasicArgument(name = "TitleIndex", typ = "ULONG", v = titleindex)) v.addField(BasicArgument(name = "Type", typ = "ULONG", v = type)) v.addField(BasicArgument(name = "DataLength", typ = "ULONG", v = datalength)) # XXX we should parse the 'Type' field and update the type # of the "Data" field accordingly if type == REG_DWORD: data = struct.unpack("L", data)[0] v.addField(BasicArgument(name = "Data", typ = "PUCHAR", v = data)) post.getArgument(4).setVal(v) else: assert False, "! Unexpected KEY_VALUE_INFORMATION_CLASS value '%s'" % kvic
def normalize_NtSetValueKey(pre, post): if pre is None: return # String & word if pre.getArgument(4) and pre.getArgument(4).getVal().isBasic(): argument = pre.getArgument(5) data = decode_base64(argument.getVal().getValue()) typ = int(pre.getArgument(4).getVal().getValue()) if typ in [REG_SZ, REG_EXPAND_SZ]: argument.getVal().setValue(decode_unicode(data)) argument.getVal().setType("PWSTR") elif typ == REG_DWORD: data = struct.unpack("L", data)[0] argument.getVal().setValue(str(data)) argument.getVal().setType("DWORD")
def normalize_value(val): if val.getType().startswith("PUNICODE_STRING"): # UNICODE_STRING # The argument could be NULL if not val.isStruct() or not val.hasField("Length"): return l = int(val.getField("Length").getValue()) if l > 0: assert val.hasField("Buffer") buf = val["Buffer"] try: data = decode_base64(buf.getValue()) # FIXME: data should be converted to unicode -- the following line is just a workaround!!! data = decode_unicode(data) buf.setValue(data) except TypeError, e: print "! WARNING: incorrect base64 value '%s'" % data