/// <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); } }
byte[] DecryptIndex(ArcView idx) { int idx_size = (int)idx.MaxOffset - 4; byte[] output = new byte[idx_size]; using (var view = idx.CreateViewAccessor(0, (uint)idx.MaxOffset)) unsafe { var rng = new CRuntimeRandomGenerator(); rng.SRand(view.ReadInt32(idx_size)); byte *ptr = view.GetPointer(0); try { for (int i = 0; i < idx_size; ++i) { output[i] = (byte)(ptr[i] ^ IndexKey[rng.Rand() % IndexKey.Length]); } return(output); } finally { view.SafeMemoryMappedViewHandle.ReleasePointer(); } } }
/// <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> private unsafe long SearchForSignature(ArcView file) { 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)) { byte *ptr_end = view.GetPointer(start_offset); byte *ptr = ptr_end + tail_size - 0x16; try { for (; ptr >= ptr_end; --ptr) { if (6 == ptr[3] && 5 == ptr[2] && 'K' == ptr[1] && 'P' == ptr[0]) { return(start_offset + (ptr - ptr_end)); } } return(-1); } finally { view.SafeMemoryMappedViewHandle.ReleasePointer(); } } }
byte[] DecryptIndex(ArcView idx) { int idx_size = (int)idx.MaxOffset-4; byte[] output = new byte[idx_size]; using (var view = idx.CreateViewAccessor (0, (uint)idx.MaxOffset)) unsafe { m_rng.SRand (view.ReadInt32 (idx_size)); byte* ptr = view.GetPointer (0); try { for (int i = 0; i < idx_size; ++i) { output[i] = (byte)(ptr[i] ^ IndexKey[m_rng.Rand() % IndexKey.Length]); } return output; } finally { view.SafeMemoryMappedViewHandle.ReleasePointer(); } } }
private long SkipExeHeader(ArcView file) { long offset = 0x10; long pe_offset = file.View.ReadUInt32(0x3c); if (pe_offset < file.MaxOffset && 0x4550 == file.View.ReadUInt32(pe_offset)) // 'PE' { int opt_header = file.View.ReadUInt16(pe_offset + 0x14); // SizeOfOptionalHeader offset = file.View.ReadUInt32(pe_offset + 0x54); // SizeOfHeaders long section_table = pe_offset + opt_header + 0x18; int count = file.View.ReadUInt16(pe_offset + 6); // NumberOfSections if (section_table + 0x28 * count < file.MaxOffset) { for (int i = 0; i < count; ++i) { uint size = file.View.ReadUInt32(section_table + 0x10); uint addr = file.View.ReadUInt32(section_table + 0x14); if (file.View.AsciiEqual(section_table, ".rsrc\0")) { // look within EXE resource section offset = addr; break; } section_table += 0x28; if (0 != size) { offset = Math.Max((long)addr + size, offset); } } } } unsafe { while (offset < file.MaxOffset) { uint page_size = (uint)Math.Min(0x10000L, file.MaxOffset - offset); if (page_size < 0x20) { break; } using (var view = file.CreateViewAccessor(offset, page_size)) { byte *page_begin = view.GetPointer(offset); byte *page_end = page_begin + page_size - 0x10; try { for (byte *ptr = page_begin; ptr != page_end; ++ptr) { // TODO: search every byte only when inside resource section, // otherwise stick to paragraph boundary. int i = 0; while (ptr[i] == s_xp3_header[i]) { if (++i == s_xp3_header.Length) { // check whether index offset is non-zero if (0 == *(uint *)(ptr + i)) { break; } return(offset + (ptr - page_begin)); } } } } finally { view.SafeMemoryMappedViewHandle.ReleasePointer(); } } offset += page_size - 0x10; } } return(0); }