def get_bit(bytearr, offset): """ Returns the bit at offset into a bytearray """ byte_idx = offset / 8 bit_idx = offset - (byte_idx * 8) byte = bytearr[byte_idx] bits = BitArray(byte) return bits.get_bit(bit_idx)
def decode(trojan): """ Decode a payload from a trojan AudioFile that has been encoded using the Modify LSB algorithm. Returns a Payload. """ payload_data = [] payload_size_bits = [] payload_size = 0 paybit_stack = [] payload_spacing = 0 paybit_space = 0 for tidx, tbyte in enumerate(trojan.data): # First 32 bytes of the trojan will have the file size of the # payload encoded in their lsb. [0, 31] if 0 <= tidx <= 31: paysize_bit = get_lsb(tbyte) payload_size_bits.append(paysize_bit) # sys.stdout.write("%s" % paysize_bit) # There is no payload data at trojan byte index 32. Let's compute # the integer value of the payload_size here for use later. elif tidx == 32: payload_size = BitArray.from_bits(payload_size_bits).to_int() payload_spacing = int(math.floor((len(trojan.data) - 32) / (payload_size * 8))) print "[modify_lsb] Payload spacing is %s" % payload_spacing print "[modify_lsb] decode - payload_size = %s" % payload_size # print "[modify_lsb] decode - payload_size_bits = %s" % \ # ''.join([str(b) for b in payload_size_bits]) # print "[modify_lsb] bits read" # Trojan bytes [33, n] will have the payload encoded in their lsbs, # where n is payload_size * 8, where payload_size is the number of # bytes in payload. elif 33 <= tidx and len(payload_data) < payload_size: if paybit_space == payload_spacing: payload_bit = get_lsb(tbyte) paybit_stack.append(payload_bit) paybit_space = 0 # We've read enough bits to make a byte. DO IT. if len(paybit_stack) == 8: paybyte = BitArray.from_bits(paybit_stack).to_int() payload_data.append(paybyte) paybit_stack = [] paybit_space += 1 # There's no more payload data to be read from the trojan, let's break else: break print "[modify_lsb] decode - len(payload_data) = %s (result)" % len(payload_data) return Payload(bytearray(payload_data))