MCPcopy Create free account
hub / github.com/ELMERIKH/PyinMemoryPE / parse_rich_header

Method parse_rich_header

pythonmemorymodule/pefile.py:3190–3269  ·  view source on GitHub ↗

Parses the rich header see http://www.ntcore.com/files/richsign.htm for more information Structure: 00 DanS ^ checksum, checksum, checksum, checksum 10 Symbol RVA ^ checksum, Symbol size ^ checksum... ... XX Rich, checksum, 0, 0,...

(self)

Source from the content-addressed store, hash-verified

3188 self.full_load()
3189
3190 def parse_rich_header(self):
3191 """Parses the rich header
3192 see http://www.ntcore.com/files/richsign.htm for more information
3193
3194 Structure:
3195 00 DanS ^ checksum, checksum, checksum, checksum
3196 10 Symbol RVA ^ checksum, Symbol size ^ checksum...
3197 ...
3198 XX Rich, checksum, 0, 0,...
3199 """
3200
3201 # Rich Header constants
3202 #
3203 DANS = 0x536E6144 # 'DanS' as dword
3204 RICH = 0x68636952 # 'Rich' as dword
3205
3206 rich_index = self.__data__.find(
3207 b"Rich", 0x80, self.OPTIONAL_HEADER.get_file_offset()
3208 )
3209 if rich_index == -1:
3210 return None
3211
3212 # Read a block of data
3213 try:
3214 # The end of the structure is 8 bytes after the start of the Rich
3215 # string.
3216 rich_data = self.__data__[0x80 : rich_index + 8]
3217 # Make the data have length a multiple of 4, otherwise the
3218 # subsequent parsing will fail. It's not impossible that we retrieve
3219 # truncated data that it's not a multiple.
3220 rich_data = rich_data[: 4 * int(len(rich_data) / 4)]
3221 data = list(
3222 struct.unpack("<{0}I".format(int(len(rich_data) / 4)), rich_data)
3223 )
3224 if RICH not in data:
3225 return None
3226 except PEFormatError:
3227 return None
3228
3229 # get key, raw_data and clear_data
3230 key = struct.pack("<L", data[data.index(RICH) + 1])
3231 result = {"key": key}
3232
3233 raw_data = rich_data[: rich_data.find(b"Rich")]
3234 result["raw_data"] = raw_data
3235
3236 ord_ = lambda c: ord(c) if not isinstance(c, int) else c
3237
3238 clear_data = bytearray()
3239 for idx, val in enumerate(raw_data):
3240 clear_data.append((ord_(val) ^ ord_(key[idx % len(key)])))
3241 result["clear_data"] = bytes(clear_data)
3242
3243 # the checksum should be present 3 times after the DanS signature
3244 #
3245 checksum = data[1]
3246 if data[0] ^ checksum != DANS or data[2] != checksum or data[3] != checksum:
3247 return None

Callers 1

full_loadMethod · 0.95

Calls 5

findMethod · 0.80
get_file_offsetMethod · 0.80
indexMethod · 0.80
unpackMethod · 0.45
packMethod · 0.45

Tested by

no test coverage detected