Created
September 30, 2015 00:58
-
-
Save chyyran/b2b96a1be80a7fd55874 to your computer and use it in GitHub Desktop.
Finds an IP.bin from a dreamcast ISO or CDI file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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