Autor
|
Tema: Leer archivo ROM y obtener información (Leído 5,814 veces)
|
Meta
|
Hola: He hecho un boceto no funcional, que tiene que leer una ROM de una Super Nintendo, en este caso uso el juego Ultimate Mortal Kombat 3. Toda l ainformación que se indica arriba nada más cargar el archivo este programa tiene que mostrarlo. No se la mejor manera de hacerlo. Por ejemplo, en la cabecera ROM del programa aparece el título que encuentra dentro de la ROM. Mirando con este editor hexadecimal gratuito lo he encontrado en la posición de dirección de memoria concretament esta 101C0 muestar el título como indica en la imagen de abajo. Siempre son de longituda 15 carácteres o bytes contando hasta los espacios en blanco. Así que cualquier ROM debe buscar ese título dentro del juego. Quiero hacer este programa poco a poco y tome forma, así que abajo les dejo las descargas y hagan pruebas. Pensé en buscar la posición de memoria que casi siempre es el mismo en los 4 MB que pesa el archivo, en otros programas que funciona de maravilla los detecta aunque la posición de memoria sea diferente, no todas las ROM son iguales, así que creo que busca los 15 bytes del título. El programa original lo descargas aquí que este si es funcional y quiero hacer lo mismo. ¿Por qué iba ahcer lo mismo si ya existe? La respuesta es que en cada pestaña haré funcione de cada programa para hacerlo todo en uno, este es el primero de los cuantos que hay por ahí. ¿Alguna ayuda para hacerlo? Descargas: Editor HexadecimalProyecto Visual C# para facilitar los ejemplos. ROM funcional de SNES para cargarlo en el proyecto y verlo en el editor hexadecimal. Saludos.
|
|
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Desconectado
Mensajes: 9.878
|
¿Cual es la pregunta en cuestión?, imagino que en Google podrás encontrar las especificaciones del formato SMC aun hoy en día, y sabiendo eso sería suficiente para localizar e identificar toda la información que necesitas. Si la pregunta es "¿cómo obtener el nombre?": Public Function GetRomName(ByVal filepath As String) As String Dim buffer As Byte() = Enumerable.Repeat(New Byte, capacidadDelNombre).ToArray Using fs As New FileStream(filepath, FileMode.Open) fs.Seek(offset, SeekOrigin.Begin) fs.Read(buffer, 0, capacidadDelNombre) fs.Close() End Using Return String.Join("", From b As Byte In buffer Select Convert.ToChar(b)).TrimEnd({" "c}) End Function
Saludos!
|
|
« Última modificación: 5 Junio 2015, 12:07 pm por Eleкtro »
|
En línea
|
|
|
|
Meta
|
Hola: Lo he pasado a C#, espero que no importe. public string GetRomName(string filepath) { byte[] buffer = Enumerable .Repeat(new byte(), capacidadDelNombre ).ToArray; using (FileStream fs = new FileStream (filepath, FileMode .Open)) { fs.Seek(offset, SeekOrigin.Begin); fs.Read(buffer, 0, capacidadDelNombre); fs.Close(); } return string.Join("", from b in bufferConvert.ToChar(b)).TrimEnd({ ' ' }); }
http://converter.telerik.com/¿Cómo ese código encuentre el nombre? Da error en C#. 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; // No olvidar. namespace SNES_EP { public partial class Form_Principal : Form { public Form_Principal() { InitializeComponent(); } private void button_Abrir_Click(object sender, EventArgs e) { Abrir_Archivo(); Leer_ROM(); } public string GetRomName(string filepath) { int capacidadDelNombre = 15; string offset = "101C0"; byte[] buffer = Enumerable .Repeat(new byte(), capacidadDelNombre ).ToArray; using (FileStream fs = new FileStream (filepath, FileMode .Open)) { fs.Seek(offset, SeekOrigin.Begin); fs.Read(buffer, 0, capacidadDelNombre); fs.Close(); } return string.Join("", from b in bufferConvert.ToChar(b)).TrimEnd({ ' ' }); } void Leer_ROM() { } void Abrir_Archivo() { if (openFileDialog1.ShowDialog() == DialogResult.OK) { textBox_Archivo.Text = openFileDialog1.FileName.ToString(); } } private void checkBox_Información_CheckedChanged(object sender, EventArgs e) { if (checkBox_Información .Checked == true) { Width = 643; Height = 783; } else { Width = 643; Height = 508; } } private void abrirArchivoToolStripMenuItem_Click(object sender, EventArgs e) { } } }
En VB. Imports System.Collections.Generic Imports System.ComponentModel Imports System.Data Imports System.Drawing Imports System.Linq Imports System.Text Imports System.Threading.Tasks Imports System.Windows.Forms Imports System.IO ' No olvidar. Namespace SNES_EP Public Partial Class Form_Principal Inherits Form Public Sub New() InitializeComponent() End Sub Private Sub button_Abrir_Click(sender As Object, e As EventArgs) Abrir_Archivo() Leer_ROM() End Sub Private Sub Leer_ROM() End Sub Private Sub Abrir_Archivo() If openFileDialog1.ShowDialog() = DialogResult.OK Then textBox_Archivo.Text = openFileDialog1.FileName.ToString() End If End Sub Private Sub checkBox_Información_CheckedChanged(sender As Object, e As EventArgs) If checkBox_Información.Checked = True Then Width = 643 Height = 783 Else Width = 643 Height = 508 End If End Sub Private Sub abrirArchivoToolStripMenuItem_Click(sender As Object, e As EventArgs) End Sub End Class End Namespace
Vamos haber si esto sale.
|
|
|
En línea
|
|
|
|
Eleкtro
Ex-Staff
Desconectado
Mensajes: 9.878
|
Da error Si un código te da error, al menos especifica que error, el mensaje de error, y donde se produce, se te ha dicho ya en varias ocasiones en otros posts. Dicho esto, el error que tienes es obvio, los valores hexadecimales en .Net no se manejan cómo strings, el datatype que espera el parámetro " offset" del método " FileStream.Seek()" es un entero (Int64/Long), por ende, debes usar un valor de ese tipo. De todas formas te comento que la manera de utilizar valores hexadecimales es escribiendo enteros literales (menos aquellos métodos que acepten un formato de String hexadecimal). En VB.Net: Dim value as Integer = &H101C0 En C#: ➢ FileStream.Seek Method - MSDN➢ Convert.ToInt64(String, Int32) Method - MSDN➢ Hexadecimal literals (C#) - MSDN➢ Hexadecimal literals (Visual Basic) - MSDNSaludos
|
|
« Última modificación: 5 Junio 2015, 13:57 pm por Eleкtro »
|
En línea
|
|
|
|
Meta
|
Hola: Gracias por la información. Me he olvidado de comentar los errores. Sorry. He encontrado un código hecho en C#, lo que veo que es muy viejo, ya que la programación tiene cosas diferente, algunos detalles básicos. Te dejo el archivo original. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; namespace SnesKit { public enum BankTypeEnum { Lo, Hi }; public class RomDump { // Indica si la ROM tiene el smc header o no bool SmcHeader; // Indica la localización del header de SNES int HeaderLocation; // Array con los datos de la ROM public byte[] Data; // Los diferentes datos que obtenemos de la ROM public string Name; public byte Layout; public byte CartridgeType; public byte RomSize; public byte RamSize; public byte CountryCode; public byte LicenseCode; public byte VersionNumber; ushort Checksum; ushort ChecksumCompliment; public BankTypeEnum BankType; // Esta funcion permite el analisis de ROMS de SNES con extensiones SMC y SFC public RomDump(byte[] rom) { this.Data = rom; // Comprobamos si existe el header smc if (this.Data.Length % 1024 == 512) SmcHeader = true; else if (this.Data.Length % 1024 == 0) SmcHeader = false; else throw new Exception ("Archivo de rom invalida."); this.HeaderLocation = 0x81C0; if (HeaderIsAt(0x07FC0)) // La Rom es LoROM { this.BankType = BankTypeEnum.Lo; } else if (HeaderIsAt(0x0FFC0)) { this.BankType = BankTypeEnum.Hi; } // Leemos el Header ReadHeader(); } // Función para comprobar si el header esta en la dirección correcta private bool HeaderIsAt(ushort addr) { this.HeaderLocation = addr; return VerifyChecksum(); } // Offset 0x07FC0 in a headerless LoROM image (LoROM rom sin smc header) // Offset 0x0FFC0 in a headerless HiROM image (HiROM rom sin smc header) // verifica el checksum private bool VerifyChecksum() { // La rom tiene header smc if (SmcHeader) this.HeaderLocation += 512; this.ChecksumCompliment = BitConverter.ToUInt16(this.Get(0x1C, 0x1D), 0); this.Checksum = BitConverter.ToUInt16(this.Get(0x1E, 0x1F), 0); ushort ver = (ushort)(this.Checksum ^ this.ChecksumCompliment); return (ver == 0xFFFF); } private void ReadHeader() { this.Name = Encoding.ASCII.GetString(this.Get(0x00, 0x14)); // 21 chars this.Layout = this.At(0x15); this.CartridgeType = this.At(0x16); this.RomSize = this.At(0x17); this.RamSize = this.At(0x18); this.CountryCode = this.At(0x19); this.LicenseCode = this.At(0x1A); this.VersionNumber = this.At(0x1B); } private string GetROmB() { return String.Format("{0}", this.RomSize); } private byte[] Get(int from, int to) { return this.Data.Skip(this.HeaderLocation + from).Take(to - from + 1).ToArray(); } private byte At(int addr) { return this.Data[this.HeaderLocation + addr]; } } }
En Visual Basic convertido. Imports System.Collections.Generic Imports System.ComponentModel Imports System.Data Imports System.Drawing Imports System.Linq Imports System.Text Imports System.Windows.Forms Imports System.IO Namespace SnesKit Public Enum BankTypeEnum Lo Hi End Enum Public Class RomDump ' Indica si la ROM tiene el smc header o no Private SmcHeader As Boolean ' Indica la localización del header de SNES Private HeaderLocation As Integer ' Array con los datos de la ROM Public Data As Byte() ' Los diferentes datos que obtenemos de la ROM Public Name As String Public Layout As Byte Public CartridgeType As Byte Public RomSize As Byte Public RamSize As Byte Public CountryCode As Byte Public LicenseCode As Byte Public VersionNumber As Byte Private Checksum As UShort Private ChecksumCompliment As UShort Public BankType As BankTypeEnum ' Esta funcion permite el analisis de ROMS de SNES con extensiones SMC y SFC Public Sub New(rom As Byte()) Me.Data = rom ' Comprobamos si existe el header smc If Me.Data.Length Mod 1024 = 512 Then SmcHeader = True ElseIf Me.Data.Length Mod 1024 = 0 Then SmcHeader = False Else Throw New Exception("Archivo de rom invalida.") End If Me.HeaderLocation = &H81c0 If HeaderIsAt(&H7fc0) Then ' La Rom es LoROM Me.BankType = BankTypeEnum.Lo ElseIf HeaderIsAt(&Hffc0) Then Me.BankType = BankTypeEnum.Hi End If ' Leemos el Header ReadHeader() End Sub ' Función para comprobar si el header esta en la dirección correcta Private Function HeaderIsAt(addr As UShort) As Boolean Me.HeaderLocation = addr Return VerifyChecksum() End Function ' Offset 0x07FC0 in a headerless LoROM image (LoROM rom sin smc header) ' Offset 0x0FFC0 in a headerless HiROM image (HiROM rom sin smc header) ' verifica el checksum Private Function VerifyChecksum() As Boolean ' La rom tiene header smc If SmcHeader Then Me.HeaderLocation += 512 End If Me.ChecksumCompliment = BitConverter.ToUInt16(Me.[Get](&H1c, &H1d), 0) Me.Checksum = BitConverter.ToUInt16(Me.[Get](&H1e, &H1f), 0) Dim ver As UShort = CUShort(Me.Checksum Xor Me.ChecksumCompliment) Return (ver = &Hffff) End Function Private Sub ReadHeader() Me.Name = Encoding.ASCII.GetString(Me.[Get](&H0, &H14)) ' 21 chars Me.Layout = Me.At(&H15) Me.CartridgeType = Me.At(&H16) Me.RomSize = Me.At(&H17) Me.RamSize = Me.At(&H18) Me.CountryCode = Me.At(&H19) Me.LicenseCode = Me.At(&H1a) Me.VersionNumber = Me.At(&H1b) End Sub Private Function GetROmB() As String Return [String].Format("{0}", Me.RomSize) End Function Private Function [Get](from As Integer, [to] As Integer) As Byte() Return Me.Data.Skip(Me.HeaderLocation + from).Take([to] - from + 1).ToArray() End Function Private Function At(addr As Integer) As Byte Return Me.Data(Me.HeaderLocation + addr) End Function End Class End Namespace
Creo un proyecto nuevo que se llama igual SnesKit. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SnesKit { class Program { static void Main(string[] args) { } } }
Indicado arriba, justo donde pone class Program lo llamaré como el archivo original public class RomDump como indica abajo. No se si esto es obligatorio. Ver código justo abajo. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SnesKit { public class RomDump { static void Main(string[] args) { } } }
El código original no veo que use este código que se crea indicado abajo. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SnesKit { public class RomDump { static void Main(string[] args) { } } }
He intentado incrustar el código para que me funcione y no me sale. ¿Hay alguna posibilidad? Saludos.
|
|
|
En línea
|
|
|
|
43H4FH44H45H4CH49H56H45H
Wiki
Desconectado
Mensajes: 502
|
Lo primero es que debes empezar a estudiar desde el comienzo lo que es .NET, generalidades de namespace, clases, métodos, diferencias entre proyectos con Windows Forms y de consola, etc.
Pero si no quieres aprender nada de eso y solo quieres copiar y pegar, te basta con crear una clase en un proyecto de Windows Forms con ese código y utilizarla desde el formulario principal.
|
|
|
En línea
|
-R IP :0100 -A 100 2826:0100 MOV AH,09 2826:0102 MOV DX,109 2826:0105 INT 21 2826:0105 MOV AH,08 2826:0105 INT 21 2826:0107 INT 20 2826:0109 DB 'MI NICK ES CODELIVE.$' 2826:0127 -R BX :0000 -R CX :20 -N CODELIVE.COM -W
|
|
|
Meta
|
Hola: Verdad. Ahora quiero probar esto cuanto antes. Empecé otra vez. Creé una nueva referencia. Añadí el código dentro. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; namespace SnesKit { public enum BankTypeEnum { Lo, Hi }; public class RomDump { // Indica si la ROM tiene el smc header o no bool SmcHeader; // Indica la localización del header de SNES int HeaderLocation; // Array con los datos de la ROM public byte[] Data; // Los diferentes datos que obtenemos de la ROM public string Name; public byte Layout; public byte CartridgeType; public byte RomSize; public byte RamSize; public byte CountryCode; public byte LicenseCode; public byte VersionNumber; ushort Checksum; ushort ChecksumCompliment; public BankTypeEnum BankType; // Esta funcion permite el analisis de ROMS de SNES con extensiones SMC y SFC public RomDump(byte[] rom) { this.Data = rom; // Comprobamos si existe el header smc if (this.Data.Length % 1024 == 512) SmcHeader = true; else if (this.Data.Length % 1024 == 0) SmcHeader = false; else throw new Exception ("Archivo de rom invalida."); this.HeaderLocation = 0x81C0; if (HeaderIsAt(0x07FC0)) // La Rom es LoROM { this.BankType = BankTypeEnum.Lo; } else if (HeaderIsAt(0x0FFC0)) { this.BankType = BankTypeEnum.Hi; } // Leemos el Header ReadHeader(); } // Función para comprobar si el header esta en la dirección correcta private bool HeaderIsAt(ushort addr) { this.HeaderLocation = addr; return VerifyChecksum(); } // Offset 0x07FC0 in a headerless LoROM image (LoROM rom sin smc header) // Offset 0x0FFC0 in a headerless HiROM image (HiROM rom sin smc header) // verifica el checksum private bool VerifyChecksum() { // La rom tiene header smc if (SmcHeader) this.HeaderLocation += 512; this.ChecksumCompliment = BitConverter.ToUInt16(this.Get(0x1C, 0x1D), 0); this.Checksum = BitConverter.ToUInt16(this.Get(0x1E, 0x1F), 0); ushort ver = (ushort)(this.Checksum ^ this.ChecksumCompliment); return (ver == 0xFFFF); } private void ReadHeader() { this.Name = Encoding.ASCII.GetString(this.Get(0x00, 0x14)); // 21 chars this.Layout = this.At(0x15); this.CartridgeType = this.At(0x16); this.RomSize = this.At(0x17); this.RamSize = this.At(0x18); this.CountryCode = this.At(0x19); this.LicenseCode = this.At(0x1A); this.VersionNumber = this.At(0x1B); } private string GetROmB() { return String.Format("{0}", this.RomSize); } private byte[] Get(int from, int to) { return this.Data.Skip(this.HeaderLocation + from).Take(to - from + 1).ToArray(); } private byte At(int addr) { return this.Data[this.HeaderLocation + addr]; } } }
Ahora a investigar com lo llamo y lo ejecute. https://msdn.microsoft.com/es-es/library/z2kcy19k.aspx?f=255&MSPPError=-2147217396https://msdn.microsoft.com/es-es/library/ee461504.aspxhttps://www.youtube.com/watch?v=Mu2LYOhEMpMSi que tengo que leer. Gracias por todo.
|
|
« Última modificación: 6 Junio 2015, 21:24 pm por Meta »
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
como puedo leer lo que pone en un archivo y usar la informacion? (vb.net)
.NET (C#, VB.NET, ASP)
|
faralito
|
2
|
3,249
|
30 Diciembre 2008, 18:19 pm
por faralito
|
|
|
Obtener informacion?
Programación Visual Basic
|
CAR3S?
|
7
|
4,412
|
13 Febrero 2011, 23:54 pm
por CAR3S?
|
|
|
Obtener información de varios objetos al leer archivo serializado
Java
|
Aikanáro Anário
|
4
|
14,138
|
11 Febrero 2012, 03:56 am
por Aikanáro Anário
|
|
|
¿leer información enviando email con ssl?
Hacking
|
kaniho
|
0
|
1,887
|
26 Julio 2014, 23:17 pm
por kaniho
|
|
|
[Ayuda] Manejo de archivo .dat y Enviar Query para Obtener Informacion
.NET (C#, VB.NET, ASP)
|
**Aincrad**
|
0
|
2,243
|
21 Noviembre 2019, 17:14 pm
por **Aincrad**
|
|