fix overflows in seeking and pad offsets

This commit is contained in:
sammiq 2018-10-14 17:57:08 +11:00
parent ea84949ac8
commit 9034b44053
4 changed files with 41 additions and 41 deletions

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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")