/// <summary> /// Search for ZIP 'End of central directory record' near the end of file. /// Returns offset of 'PK' signature or -1 if no signature was found. /// </summary> internal unsafe long SearchForSignature(ArcView file, byte[] signature) { if (signature.Length < 4) { throw new ArgumentException("Invalid ZIP file signature", "signature"); } uint tail_size = (uint)Math.Min(file.MaxOffset, 0x10016L); if (tail_size < 0x16) { return(-1); } var start_offset = file.MaxOffset - tail_size; using (var view = file.CreateViewAccessor(start_offset, tail_size)) using (var pointer = new ViewPointer(view, start_offset)) { byte *ptr_end = pointer.Value; byte *ptr = ptr_end + tail_size - 0x16; for (; ptr >= ptr_end; --ptr) { if (signature[3] == ptr[3] && signature[2] == ptr[2] && signature[1] == ptr[1] && signature[0] == ptr[0]) { return(start_offset + (ptr - ptr_end)); } } return(-1); } }
/// <summary> /// Search for byte sequence within specified section. /// </summary> /// <returns>Offset of byte sequence, if found, -1 otherwise.</returns> public long FindString(Section section, byte[] seq, int step = 1) { if (step <= 0) { throw new ArgumentOutOfRangeException("step", "Search step should be positive integer."); } long offset = section.Offset; if (offset < 0 || offset > m_file.MaxOffset) { throw new ArgumentOutOfRangeException("section", "Invalid executable file section specified."); } uint seq_length = (uint)seq.Length; if (0 == seq_length || section.Size < seq_length) { return(-1); } long end_offset = Math.Min(m_file.MaxOffset, offset + section.Size); unsafe { while (offset < end_offset) { uint page_size = (uint)Math.Min(0x10000L, end_offset - offset); if (page_size < seq_length) { break; } using (var view = m_file.CreateViewAccessor(offset, page_size)) using (var ptr = new ViewPointer(view, offset)) { byte *page_begin = ptr.Value; byte *page_end = page_begin + page_size - seq_length; byte *p; for (p = page_begin; p <= page_end; p += step) { int i = 0; while (p[i] == seq[i]) { if (++i == seq.Length) { return(offset + (p - page_begin)); } } } offset += p - page_begin; } } } return(-1); }