Skip to content

Instantly share code, notes, and snippets.

@chyyran
Created September 30, 2015 00:58
Show Gist options
  • Save chyyran/b2b96a1be80a7fd55874 to your computer and use it in GitHub Desktop.
Save chyyran/b2b96a1be80a7fd55874 to your computer and use it in GitHub Desktop.
Finds an IP.bin from a dreamcast ISO or CDI file.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
namespace DreamcastIPBINExtractor
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
using (FileStream stream = File.Open(@"C:\3ds\s.cdi", FileMode.Open))
{
long headerPos = GetHeaderOffset(stream);
stream.Seek(headerPos, SeekOrigin.Begin);
byte[] buffer = new byte[0x100];
byte[] data = new byte[0x9];
stream.Read(buffer, 0, buffer.Length);
Array.Copy(buffer, 0x40, data, 0, data.Length);
/*
header = 0x0 SEGA SEGAKATANA for 0x10 bytes (0xF bytes without 0x20 space)
internal name = 0x80 for 0x80 bytes
serial number (id) = 0x40 for 9 bytes
*/
MessageBox.Show(Encoding.UTF8.GetString(data));
}
}
private long GetHeaderOffset(Stream stream)
{
byte[] header = new byte[] { 0x53, 0x45, 0x47, 0x41, 0x20, 0x53, 0x45, 0x47, 0x41, 0x4B, 0x41, 0x54, 0x41, 0x4E, 0x41 };
byte[] buffer = new byte[1024 * 1024]; //read a MiB at a time
for (int i = 1; i < stream.Length / 1024; i++)
{
long streamPos = (stream.Length - (i * buffer.Length));
if (streamPos < 0) break;
stream.Position = streamPos;
stream.Read(buffer, 0, buffer.Length);
var index = IndexOfSequence(buffer, header, 0);
if (index.Count > 0)
{
int bufferIndex = index[0];
long streamIndex = streamPos + bufferIndex;
return streamIndex;
}
}
return 0;
}
//adapted from http://stackoverflow.com/posts/332667
public static List<int> IndexOfSequence(byte[] buffer, byte[] pattern, int startIndex)
{
List<int> positions = new List<int>();
int i = Array.IndexOf<byte>(buffer, pattern[0], startIndex);
while (i >= 0 && i <= buffer.Length - pattern.Length)
{
byte[] segment = new byte[pattern.Length];
Buffer.BlockCopy(buffer, i, segment, 0, pattern.Length);
if (segment.SequenceEqual<byte>(pattern))
positions.Add(i);
i = Array.IndexOf<byte>(buffer, pattern[0], i + pattern.Length);
}
return positions;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment