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
|
||||
back into plain .iso files.
|
||||
|
@ -43,5 +43,12 @@ Usage
|
|||
Arguments:
|
||||
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 (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
@ -50,11 +49,7 @@ func decodeGameCube(r *os.File, outPath string) {
|
|||
padOffset = 0
|
||||
}
|
||||
|
||||
rawOffset := binary.LittleEndian.Uint32(startBuffer.Next(4))
|
||||
if rawOffset != 0xffffffff {
|
||||
offset := rawOffset << 8
|
||||
checkOffset(r, offset)
|
||||
r.Seek(int64(offset), io.SeekStart)
|
||||
if setNextOffset(r, startBuffer) {
|
||||
wrote := uint64(blockTransferWithHash(r, w, transfer, hash))
|
||||
bytesWritten += wrote
|
||||
padOffset += wrote
|
||||
|
|
|
@ -30,9 +30,9 @@ func checkPosition(s io.Seeker) int64 {
|
|||
return pos
|
||||
}
|
||||
|
||||
func checkOffset(s io.Seeker, offset uint32) {
|
||||
func checkOffset(s io.Seeker, offset int64) {
|
||||
pos := checkPosition(s)
|
||||
if pos != int64(offset) {
|
||||
if pos != offset {
|
||||
vLog("READ: position: %x expected: %x", pos, offset)
|
||||
}
|
||||
}
|
||||
|
@ -41,15 +41,23 @@ type byteProvider interface {
|
|||
Next(n int) []byte
|
||||
}
|
||||
|
||||
func readNextOffset(s io.Seeker, p byteProvider) uint32 {
|
||||
offset := binary.LittleEndian.Uint32(p.Next(4)) << 8
|
||||
checkOffset(s, offset)
|
||||
return offset
|
||||
func readNextOffset(s io.Seeker, p byteProvider) (int64, bool) {
|
||||
rawOffset := binary.LittleEndian.Uint32(p.Next(4))
|
||||
if rawOffset != 0xffffffff {
|
||||
offset := int64(rawOffset) << 8
|
||||
checkOffset(s, offset)
|
||||
return offset, true
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func setNextOffset(s io.Seeker, p byteProvider) {
|
||||
offset := readNextOffset(s, p)
|
||||
s.Seek(int64(offset), io.SeekStart)
|
||||
func setNextOffset(s io.Seeker, p byteProvider) bool {
|
||||
offset, ok := readNextOffset(s, p)
|
||||
if ok {
|
||||
_, err := s.Seek(offset, io.SeekStart)
|
||||
errorExit(err)
|
||||
}
|
||||
return ok
|
||||
}
|
||||
|
||||
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 {
|
||||
readNextOffset(r, startBuffer) // we don't need this
|
||||
bytesWritten += uint64(blockTransferWithHash(r, w, transfer, hash))
|
||||
vLog("\nWRITE: offset: %x\n", bytesWritten)
|
||||
vLog("WRITE: offset: %x\n", bytesWritten)
|
||||
}
|
||||
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 {
|
||||
setNextOffset(r, startBuffer)
|
||||
bytesWritten += uint64(blockTransferWithHash(r, w, transfer, hash))
|
||||
vLog("\nWRITE: offset: %x\n", bytesWritten)
|
||||
vLog("WRITE: offset: %x\n", bytesWritten)
|
||||
}
|
||||
fmt.Println("Done")
|
||||
|
||||
|
@ -92,33 +92,28 @@ func decodeWii(r *os.File, outPath string, sectorSize uint) {
|
|||
wrote := uint64(blockTransferWithHash(r, w, transfer, hash))
|
||||
bytesWritten += wrote
|
||||
dataSize += wrote
|
||||
vLog("\nWRITE: offset: %x\n", bytesWritten)
|
||||
vLog("WRITE: offset: %x\n", bytesWritten)
|
||||
|
||||
writeBuffer := NewFixedRecord(0x7C00)
|
||||
transfer2 := make([]byte, 1024)
|
||||
|
||||
for k := 0; k < 31; k++ {
|
||||
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)
|
||||
padBlock++
|
||||
padOffset = 0
|
||||
}
|
||||
|
||||
rawOffset := binary.LittleEndian.Uint32(startBuffer.Next(4))
|
||||
if rawOffset != 0xffffffff {
|
||||
offset := rawOffset << 8
|
||||
checkOffset(r, offset)
|
||||
r.Seek(int64(offset), io.SeekStart)
|
||||
|
||||
if setNextOffset(r, startBuffer) {
|
||||
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 {
|
||||
slice := padding[padOffset : padOffset+1024]
|
||||
_, err = writeBuffer.Write(slice)
|
||||
errorExit(err)
|
||||
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)
|
||||
|
@ -128,10 +123,10 @@ func decodeWii(r *os.File, outPath string, sectorSize uint) {
|
|||
_, err = w.Write(output)
|
||||
errorExit(err)
|
||||
bytesWritten += 0x7C00
|
||||
vLog("\nWRITE: offset: %x\n", bytesWritten)
|
||||
vLog("WRITE: offset: %x\n", bytesWritten)
|
||||
|
||||
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")
|
||||
|
||||
|
@ -140,22 +135,17 @@ func decodeWii(r *os.File, outPath string, sectorSize uint) {
|
|||
padBlock = uint32(bytesWritten / 0x40000)
|
||||
for bytesWritten != partitions[j].PartitionEndOffset {
|
||||
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)
|
||||
padBlock++
|
||||
padOffset = 0
|
||||
padOffset = bytesWritten % 0x40000
|
||||
}
|
||||
|
||||
rawOffset := binary.LittleEndian.Uint32(startBuffer.Next(4))
|
||||
if rawOffset != 0xffffffff {
|
||||
offset := rawOffset << 8
|
||||
checkOffset(r, offset)
|
||||
r.Seek(int64(offset), io.SeekStart)
|
||||
|
||||
if setNextOffset(r, startBuffer) {
|
||||
wrote := uint64(blockTransferWithHash(r, w, transfer, hash))
|
||||
bytesWritten += wrote
|
||||
padOffset += wrote
|
||||
vLog("\ntfr WRITE: offset: %x\n", bytesWritten)
|
||||
vLog("WRITE: tfr - poffset: %x offset: %x\n", padOffset, bytesWritten)
|
||||
} else {
|
||||
slice := padding[padOffset : padOffset+1024]
|
||||
io.Copy(hash, bytes.NewBuffer(slice))
|
||||
|
@ -163,7 +153,7 @@ func decodeWii(r *os.File, outPath string, sectorSize uint) {
|
|||
errorExit(err)
|
||||
bytesWritten += 1024
|
||||
padOffset += 1024
|
||||
vLog("\npad WRITE: offset: %x\n", bytesWritten)
|
||||
vLog("WRITE: pad - poffset: %x offset: %x\n", padOffset, bytesWritten)
|
||||
}
|
||||
}
|
||||
fmt.Println("Done")
|
||||
|
|
Loading…
Reference in New Issue