CDArchive - Improved support for ring based protections

reentrant
Posts: 719
Joined: Mon Jun 08, 2026 1:28 am

CDArchive - Improved support for ring based protections

Post by reentrant »

Hi,
New version of CDArchive is out with following new features:
- Automatic sector merging - no need to specify extrsectdir anymore (if specified, sectors will be dumped to the directory anyway)
- Automatic sector checking and repairing (both in the input image as well as those read by the drive) using ECC codes (RSPC). If a specific sector can be repaired (in the image) it is not read from the device.

List of removed dependencies:
- CDmage
- EccEdc

List of added dependencies:
- Python 3.12 - RS library - no C++ code available anywhere

Example command line:
CDArchive.exe --mode=ext --extrdrive=e --extrstart=100 --extrend=200 --extroverread=0 --extrskip=3 --extrdirection=f --extrdiscmode=cd --extrrefcue="d:\Storage\Sin\Sin.cue"

Example output:

Code: Select all

Initialized C2 module
Extracting error range forward: 100 - 200
Repaired sector with C2: 150
Repaired sector with C2: 151
Repaired sector with C2: 152
Repaired sector with C2: 153
Repaired sector with C2: 154
Repaired sector with C2: 155
Repaired sector with C2: 156
Range direction result: 0 1

Extracted all sectors
Configuration:
- Install Python 3.12 (exactly this major version)
- Adjust PYTHONHOME variable in config file: Plugins\C2Corrector\C2Corrector.ini
- Copy python312.dll from Python installation directory to Plugins\C2Corrector directory

And that's it - no more tedious merging, fixing, checking...

Changelog:
2025-05-26:
- Added extrforceecc option (0/1)
- Mode 2 track support bug fix
Attachments
CDArchive.7z
Imported Redump attachment 21795
(350.04 KiB) Downloaded 2 times
CDArchive - 2025-05-26.7z
Imported Redump attachment 22902
(350.18 KiB) Downloaded 3 times
Last edited by reentrant on Mon May 26, 2025 2:12 pm, edited 1 time in total.
reentrant
Posts: 719
Joined: Mon Jun 08, 2026 1:28 am

Re: CDArchive - Improved support for ring based protections

Post by reentrant »

C2Corrector API (Plugins/C2Corrector/C2Corrector.DLL):

Code: Select all

#pragma pack(push, 1)
typedef struct _C2_CORRECTOR_INIT {
    PVOID pythonEccP;
    PVOID pythonEccQ;
} C2_CORRECTOR_INIT, *PC2_CORRECTOR_INIT;
#pragma pack(pop)

// InitC2
typedef DWORD (WINAPI *pInitC2)(PC2_CORRECTOR_INIT c2InitBlock);

#pragma pack(push, 1)
typedef struct _C2_CORRECTOR_HANDLE {
    PVOID pythonEccP; // C2_CORRECTOR_INIT.pythonEccP
    PVOID pythonEccQ; // C2_CORRECTOR_INIT.pythonEccQ
    PUCHAR sectorData; // Length: 2352 bytes
    PUCHAR c2Pointers; // Length: 2352 / 8 bytes
    PUCHAR c2Repaired; // Length: 2352 / 8 bytes
} C2_CORRECTOR_HANDLE, *PC2_CORRECTOR_HANDLE;
#pragma pack(pop)

// HandleC2
typedef DWORD (WINAPI *pHandleC2)(PC2_CORRECTOR_HANDLE c2HandleBlock);
Steps:
1) Call InitC2 once in main
2) Call HandleC2 multiple times on each re-read

How it works:
ECC (ECCP / ECCQ) code inside data sector (mode 1 / mode 2) is in fact a Reed-Solomon code.
ECCP = RS(26,24) - difference = 2. It means 1 error can be corrected for a row of 26 bytes (or 2 positions without correcting).
ECCQ = RS(45,43) - difference = 2. It means 1 error can be a corrected for a row of 45 bytes (or 2 positions without correcting).

When you combine the RS algorithm with C2 pointers from the device and use the pointers as erasures it's possible to increase algorithm strength twice (2 errors can be corrected).

C2Corrector does just that - it uses C2 pointers as erasures (positions of invalid bytes) and tries to repair the data. Bytes that were repaired are recorded in c2Repaired buffer. This buffer should be combined with C2 buffer received from the device + appropriate repaired bytes should be replaced with data from sectorData buffer.

That's also how drives work internally. Depending on the manufacturer number of iterations varies (re-read + repair). Some are worse, some are better...
Last edited by reentrant on Tue Mar 18, 2025 3:23 pm, edited 1 time in total.
ssjkakaroto
Posts: 286
Joined: Mon Jun 08, 2026 1:26 am

Re: CDArchive - Improved support for ring based protections

Post by ssjkakaroto »

Hi reentrant, is this an alternative to DIC?
reentrant
Posts: 719
Joined: Mon Jun 08, 2026 1:28 am

Re: CDArchive - Improved support for ring based protections

Post by reentrant »

Hi ssjkakaroto, no, it's just a brute-force tool to improve DIC's output...
Last edited by reentrant on Fri Mar 21, 2025 2:03 pm, edited 1 time in total.
Morlit
Posts: 472
Joined: Mon Jun 08, 2026 1:31 am

Re: CDArchive - Improved support for ring based protections

Post by Morlit »

While potentially useful having CDarchive  repair sectors as it extracts them sounds risky.
sarami
Posts: 1762
Joined: Mon Jun 08, 2026 1:27 am

Re: CDArchive - Improved support for ring based protections

Post by sarami »

reentrant wrote:Steps:
1) Call InitC2 once in main
2) Call HandleC2 multiple times on each re-read
If possible, please show me the sample code to call these func.
DiscImageCreator, UmdImageCreator, Conv2multiBin, bin2wav, PS3Auth (needs login), [url=http://www.mediafire.com/file/5cgoy11x6ahc7qh/%2523recompressTo7z_20150109.bat/file]recompressTo7z_20150109.bat[/url]
reentrant
Posts: 719
Joined: Mon Jun 08, 2026 1:28 am

Re: CDArchive - Improved support for ring based protections

Post by reentrant »

Morlit wrote:While potentially useful having CDarchive  repair sectors as it extracts them sounds risky.
Potentially yes, I only use it for hardcore cases like fetching more sectors from the rings...
Last edited by reentrant on Sun Mar 23, 2025 7:51 am, edited 1 time in total.
reentrant
Posts: 719
Joined: Mon Jun 08, 2026 1:28 am

Re: CDArchive - Improved support for ring based protections

Post by reentrant »

sarami wrote:
reentrant wrote:Steps:
1) Call InitC2 once in main
2) Call HandleC2 multiple times on each re-read
If possible, please show me the sample code to call these func.

Code: Select all

DWORD C2Handler::corruptSectorForP(PC2_CORRECTOR_HANDLE c2HandleBlock, DWORD vectorNo, DWORD errorCount, BOOL enablePointers) {
    if(vectorNo >= 43)
        return ERROR_INVALID_PARAMETER;

    PUCHAR dataBuffer = c2HandleBlock->sectorData;
    
    errorCount = min(errorCount, 26);

    for(DWORD i = 0; i < errorCount; ++i) {
        DWORD dataIndex = userDataOffset + 2 * (43 * i + vectorNo) + 1;

        DEBUGPRINTWO(L"Corrupting P vector: 0x%03X: 0x%02X -> 0x%02X\n", dataIndex, dataBuffer[dataIndex], dataBuffer[dataIndex] + 1);

        ++dataBuffer[dataIndex];

        if(enablePointers && c2HandleBlock->c2Pointers) {
            PUCHAR c2Pointer = &c2HandleBlock->c2Pointers[dataIndex >> 3];
            *c2Pointer |= (0x1 << (dataIndex & 0x7));
        }
    }

    return 0;
}

DWORD C2Handler::corruptSectorForQ(PC2_CORRECTOR_HANDLE c2HandleBlock, DWORD vectorNo, DWORD errorCount, BOOL enablePointers) {
    if(vectorNo >= 26)
        return ERROR_INVALID_PARAMETER;

    PUCHAR dataBuffer = c2HandleBlock->sectorData;
    
    errorCount = min(errorCount, 43);

    for(DWORD i = 0; i < errorCount; ++i) {
        DWORD dataIndex = userDataOffset + 2 * ((43 * vectorNo + 44 * i) % 1118);

        DEBUGPRINTWO(L"Corrupting Q vector: 0x%03X: 0x%02X -> 0x%02X\n", dataIndex, dataBuffer[dataIndex], dataBuffer[dataIndex] + 1);

        ++dataBuffer[dataIndex];

        if(enablePointers && c2HandleBlock->c2Pointers) {
            PUCHAR c2Pointer = &c2HandleBlock->c2Pointers[dataIndex >> 3];
            *c2Pointer |= (0x1 << (dataIndex & 0x7));
        }
    }

    return 0;
}

#include "C2Handler.hpp"

#include <FileOps/FileOps.hpp>

DWORD WINAPI InitC2(PC2_CORRECTOR_INIT c2InitBlock) {
    return C2Handler::initC2(c2InitBlock);
}

DWORD WINAPI HandleC2(PC2_CORRECTOR_HANDLE c2HandleBlock) {
    return C2Handler::handleC2(c2HandleBlock);
}
#ifdef _DEBUG
int main() {
    C2_CORRECTOR_INIT c2InitBlock = {};

    DWORD retVal = InitC2(&c2InitBlock);
    if(!retVal) {
        UCHAR sectorData[2352];
        UCHAR c2Pointers[2352 / 8] = {};
        UCHAR c2Repaired[2352 / 8] = {};

        if(!(retVal = FileOps::readData(L"sector.data.in", sectorData, sizeof(sectorData)))) {
            C2_CORRECTOR_HANDLE c2HandleBlock = {};
            c2HandleBlock.pythonEccP = c2InitBlock.pythonEccP;
            c2HandleBlock.pythonEccQ = c2InitBlock.pythonEccQ;
            c2HandleBlock.sectorData = sectorData;
            c2HandleBlock.c2Pointers = c2Pointers;
            c2HandleBlock.c2Repaired = c2Repaired;

            //C2Handler::corruptSectorForP(&c2HandleBlock, 0, 2, FALSE);
            //retVal = HandleC2(&c2HandleBlock);

            //C2Handler::corruptSectorForP(&c2HandleBlock, 0, 3, TRUE);
            //retVal = HandleC2(&c2HandleBlock);

            C2Handler::corruptSectorForQ(&c2HandleBlock, 0, 2, TRUE);
            retVal = HandleC2(&c2HandleBlock);

            FileOps::writeData(L"sector.data.out", c2HandleBlock.sectorData, sizeof(sectorData));
            FileOps::writeData(L"sector.c2pre.out", c2HandleBlock.c2Pointers, sizeof(c2Pointers));
            FileOps::writeData(L"sector.c2post.out", c2HandleBlock.c2Repaired, sizeof(c2Repaired));
        }
    }

    return retVal ? EXIT_FAILURE : EXIT_SUCCESS;
}
#else
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
    return TRUE;
}
#endif
reentrant
Posts: 719
Joined: Mon Jun 08, 2026 1:28 am

Re: CDArchive - Improved support for ring based protections

Post by reentrant »

Keep in mind, when you pass c2Pointers bitmap, ECC algorithm will only repair bytes which are marked as 1 in C2 bitmap. If the repair is successful bits in c2Repaired bitmap will be set and it's up to you to merge c2Repaired bitmap + write appropriate bytes from sectorData into the image file...
sarami
Posts: 1762
Joined: Mon Jun 08, 2026 1:27 am

Re: CDArchive - Improved support for ring based protections

Post by sarami »

reentrant wrote:Configuration:
- Install Python 3.12 (exactly this major version)
- Adjust PYTHONHOME variable in config file: Plugins\C2Corrector\C2Corrector.ini
- Copy python312.dll from Python installation directory to Plugins\C2Corrector directory
Is python312.dll 64-bit only? Or does it work in 32bit dll? Are C2Corrector.dll and boost_python312-vc143-mt-x64-1_87.dll also 64bit only? It fails to load using LoadLibrary.
DiscImageCreator, UmdImageCreator, Conv2multiBin, bin2wav, PS3Auth (needs login), [url=http://www.mediafire.com/file/5cgoy11x6ahc7qh/%2523recompressTo7z_20150109.bat/file]recompressTo7z_20150109.bat[/url]
Post Reply