fix overflows in seeking and pad offsets
This commit is contained in:
parent
ea84949ac8
commit
9034b44053
11
README.md
11
README.md
|
@ -1,5 +1,5 @@
|
||||||
dec-decoder: an iso.dec decoder written in Go
|
dec-decode: an iso.dec decoder written in Go
|
||||||
==============================================
|
============================================
|
||||||
|
|
||||||
This tool implements the NASOS method of decoding .iso.dec files
|
This tool implements the NASOS method of decoding .iso.dec files
|
||||||
back into plain .iso files.
|
back into plain .iso files.
|
||||||
|
@ -43,5 +43,12 @@ Usage
|
||||||
Arguments:
|
Arguments:
|
||||||
Files: list of files to decode
|
Files: list of files to decode
|
||||||
|
|
||||||
|
Status
|
||||||
|
------
|
||||||
|
|
||||||
|
System | Size | Status
|
||||||
|
--------|------|-------
|
||||||
|
Wii | DVD5 | Working
|
||||||
|
Wii | DVD9 | Working
|
||||||
|
GameCube| DISC | Untested
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package main
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -50,11 +49,7 @@ func decodeGameCube(r *os.File, outPath string) {
|
||||||
padOffset = 0
|
padOffset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
rawOffset := binary.LittleEndian.Uint32(startBuffer.Next(4))
|
if setNextOffset(r, startBuffer) {
|
||||||
if rawOffset != 0xffffffff {
|
|
||||||
offset := rawOffset << 8
|
|
||||||
checkOffset(r, offset)
|
|
||||||
r.Seek(int64(offset), io.SeekStart)
|
|
||||||
wrote := uint64(blockTransferWithHash(r, w, transfer, hash))
|
wrote := uint64(blockTransferWithHash(r, w, transfer, hash))
|
||||||
bytesWritten += wrote
|
bytesWritten += wrote
|
||||||
padOffset += wrote
|
padOffset += wrote
|
||||||
|
|
|
@ -30,9 +30,9 @@ func checkPosition(s io.Seeker) int64 {
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkOffset(s io.Seeker, offset uint32) {
|
func checkOffset(s io.Seeker, offset int64) {
|
||||||
pos := checkPosition(s)
|
pos := checkPosition(s)
|
||||||
if pos != int64(offset) {
|
if pos != offset {
|
||||||
vLog("READ: position: %x expected: %x", pos, offset)
|
vLog("READ: position: %x expected: %x", pos, offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,15 +41,23 @@ type byteProvider interface {
|
||||||
Next(n int) []byte
|
Next(n int) []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func readNextOffset(s io.Seeker, p byteProvider) uint32 {
|
func readNextOffset(s io.Seeker, p byteProvider) (int64, bool) {
|
||||||
offset := binary.LittleEndian.Uint32(p.Next(4)) << 8
|
rawOffset := binary.LittleEndian.Uint32(p.Next(4))
|
||||||
checkOffset(s, offset)
|
if rawOffset != 0xffffffff {
|
||||||
return offset
|
offset := int64(rawOffset) << 8
|
||||||
|
checkOffset(s, offset)
|
||||||
|
return offset, true
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func setNextOffset(s io.Seeker, p byteProvider) {
|
func setNextOffset(s io.Seeker, p byteProvider) bool {
|
||||||
offset := readNextOffset(s, p)
|
offset, ok := readNextOffset(s, p)
|
||||||
s.Seek(int64(offset), io.SeekStart)
|
if ok {
|
||||||
|
_, err := s.Seek(offset, io.SeekStart)
|
||||||
|
errorExit(err)
|
||||||
|
}
|
||||||
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func blockTransfer(r io.Reader, w io.Writer, buffer []byte) int {
|
func blockTransfer(r io.Reader, w io.Writer, buffer []byte) int {
|
||||||
|
|
|
@ -67,7 +67,7 @@ func decodeWii(r *os.File, outPath string, sectorSize uint) {
|
||||||
for i := uint64(0); i < partitions[0].PartitionOffset; i += 1024 {
|
for i := uint64(0); i < partitions[0].PartitionOffset; i += 1024 {
|
||||||
readNextOffset(r, startBuffer) // we don't need this
|
readNextOffset(r, startBuffer) // we don't need this
|
||||||
bytesWritten += uint64(blockTransferWithHash(r, w, transfer, hash))
|
bytesWritten += uint64(blockTransferWithHash(r, w, transfer, hash))
|
||||||
vLog("\nWRITE: offset: %x\n", bytesWritten)
|
vLog("WRITE: offset: %x\n", bytesWritten)
|
||||||
}
|
}
|
||||||
fmt.Println("Done")
|
fmt.Println("Done")
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ func decodeWii(r *os.File, outPath string, sectorSize uint) {
|
||||||
for i := uint64(0); i < partitions[j].DataOffset; i += 1024 {
|
for i := uint64(0); i < partitions[j].DataOffset; i += 1024 {
|
||||||
setNextOffset(r, startBuffer)
|
setNextOffset(r, startBuffer)
|
||||||
bytesWritten += uint64(blockTransferWithHash(r, w, transfer, hash))
|
bytesWritten += uint64(blockTransferWithHash(r, w, transfer, hash))
|
||||||
vLog("\nWRITE: offset: %x\n", bytesWritten)
|
vLog("WRITE: offset: %x\n", bytesWritten)
|
||||||
}
|
}
|
||||||
fmt.Println("Done")
|
fmt.Println("Done")
|
||||||
|
|
||||||
|
@ -92,33 +92,28 @@ func decodeWii(r *os.File, outPath string, sectorSize uint) {
|
||||||
wrote := uint64(blockTransferWithHash(r, w, transfer, hash))
|
wrote := uint64(blockTransferWithHash(r, w, transfer, hash))
|
||||||
bytesWritten += wrote
|
bytesWritten += wrote
|
||||||
dataSize += wrote
|
dataSize += wrote
|
||||||
vLog("\nWRITE: offset: %x\n", bytesWritten)
|
vLog("WRITE: offset: %x\n", bytesWritten)
|
||||||
|
|
||||||
writeBuffer := NewFixedRecord(0x7C00)
|
writeBuffer := NewFixedRecord(0x7C00)
|
||||||
transfer2 := make([]byte, 1024)
|
transfer2 := make([]byte, 1024)
|
||||||
|
|
||||||
for k := 0; k < 31; k++ {
|
for k := 0; k < 31; k++ {
|
||||||
if (padOffset & 0x3FFFF) == 0 {
|
if (padOffset & 0x3FFFF) == 0 {
|
||||||
vLog("\nPADDING: block: %d id: %s\n", padBlock, id)
|
vLog("PADDING: block: %d id: %s\n", padBlock, id)
|
||||||
padding = generatePaddingBlock(padBlock, id, 0)
|
padding = generatePaddingBlock(padBlock, id, 0)
|
||||||
padBlock++
|
padBlock++
|
||||||
padOffset = 0
|
padOffset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
rawOffset := binary.LittleEndian.Uint32(startBuffer.Next(4))
|
if setNextOffset(r, startBuffer) {
|
||||||
if rawOffset != 0xffffffff {
|
|
||||||
offset := rawOffset << 8
|
|
||||||
checkOffset(r, offset)
|
|
||||||
r.Seek(int64(offset), io.SeekStart)
|
|
||||||
|
|
||||||
padOffset += uint64(blockTransfer(r, writeBuffer, transfer2))
|
padOffset += uint64(blockTransfer(r, writeBuffer, transfer2))
|
||||||
vLog("\ntfr %d poffset: %x buffer: %x\n", k, padOffset, writeBuffer.Len())
|
vLog("tfr %d poffset: %x buffer: %x\n", k, padOffset, writeBuffer.Len())
|
||||||
} else {
|
} else {
|
||||||
slice := padding[padOffset : padOffset+1024]
|
slice := padding[padOffset : padOffset+1024]
|
||||||
_, err = writeBuffer.Write(slice)
|
_, err = writeBuffer.Write(slice)
|
||||||
errorExit(err)
|
errorExit(err)
|
||||||
padOffset += 1024
|
padOffset += 1024
|
||||||
vLog("\npad %d poffset: %x buffer: %x\n", k, padOffset, writeBuffer.Len())
|
vLog("pad %d poffset: %x buffer: %x\n", k, padOffset, writeBuffer.Len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iv := getIV(transfer)
|
iv := getIV(transfer)
|
||||||
|
@ -128,10 +123,10 @@ func decodeWii(r *os.File, outPath string, sectorSize uint) {
|
||||||
_, err = w.Write(output)
|
_, err = w.Write(output)
|
||||||
errorExit(err)
|
errorExit(err)
|
||||||
bytesWritten += 0x7C00
|
bytesWritten += 0x7C00
|
||||||
vLog("\nWRITE: offset: %x\n", bytesWritten)
|
vLog("WRITE: offset: %x\n", bytesWritten)
|
||||||
|
|
||||||
dataSize += 0x7C00
|
dataSize += 0x7C00
|
||||||
vLog("\nDATA SIZE: %d / %d\n", dataSize, partitions[j].DataSize)
|
vLog("DATA SIZE: %d / %d\n", dataSize, partitions[j].DataSize)
|
||||||
}
|
}
|
||||||
fmt.Println("Done")
|
fmt.Println("Done")
|
||||||
|
|
||||||
|
@ -140,22 +135,17 @@ func decodeWii(r *os.File, outPath string, sectorSize uint) {
|
||||||
padBlock = uint32(bytesWritten / 0x40000)
|
padBlock = uint32(bytesWritten / 0x40000)
|
||||||
for bytesWritten != partitions[j].PartitionEndOffset {
|
for bytesWritten != partitions[j].PartitionEndOffset {
|
||||||
if (padOffset & 0x3FFFF) == 0 {
|
if (padOffset & 0x3FFFF) == 0 {
|
||||||
vLog("\ngenerate padding: %d %s\n", padBlock, id)
|
vLog("generate padding: %d %s\n", padBlock, id)
|
||||||
padding = generatePaddingBlock(padBlock, id, 0)
|
padding = generatePaddingBlock(padBlock, id, 0)
|
||||||
padBlock++
|
padBlock++
|
||||||
padOffset = 0
|
padOffset = bytesWritten % 0x40000
|
||||||
}
|
}
|
||||||
|
|
||||||
rawOffset := binary.LittleEndian.Uint32(startBuffer.Next(4))
|
if setNextOffset(r, startBuffer) {
|
||||||
if rawOffset != 0xffffffff {
|
|
||||||
offset := rawOffset << 8
|
|
||||||
checkOffset(r, offset)
|
|
||||||
r.Seek(int64(offset), io.SeekStart)
|
|
||||||
|
|
||||||
wrote := uint64(blockTransferWithHash(r, w, transfer, hash))
|
wrote := uint64(blockTransferWithHash(r, w, transfer, hash))
|
||||||
bytesWritten += wrote
|
bytesWritten += wrote
|
||||||
padOffset += wrote
|
padOffset += wrote
|
||||||
vLog("\ntfr WRITE: offset: %x\n", bytesWritten)
|
vLog("WRITE: tfr - poffset: %x offset: %x\n", padOffset, bytesWritten)
|
||||||
} else {
|
} else {
|
||||||
slice := padding[padOffset : padOffset+1024]
|
slice := padding[padOffset : padOffset+1024]
|
||||||
io.Copy(hash, bytes.NewBuffer(slice))
|
io.Copy(hash, bytes.NewBuffer(slice))
|
||||||
|
@ -163,7 +153,7 @@ func decodeWii(r *os.File, outPath string, sectorSize uint) {
|
||||||
errorExit(err)
|
errorExit(err)
|
||||||
bytesWritten += 1024
|
bytesWritten += 1024
|
||||||
padOffset += 1024
|
padOffset += 1024
|
||||||
vLog("\npad WRITE: offset: %x\n", bytesWritten)
|
vLog("WRITE: pad - poffset: %x offset: %x\n", padOffset, bytesWritten)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println("Done")
|
fmt.Println("Done")
|
||||||
|
|
Loading…
Reference in New Issue