UT2003 -> backup works using twin sectors


/*    twinpeak.cpp   */


#include <windows.h>
#include <stdio.h>



HANDLE	hImgFile = INVALID_HANDLE_VALUE, hSubFile = INVALID_HANDLE_VALUE;

DWORD	dwImgFileSize, dwSubFileSize;
DWORD	dwSectorCount;

DWORD*	dwSectorTable = NULL;



void Exit()
{
	// clean up stuff
	if(hImgFile != INVALID_HANDLE_VALUE) CloseHandle(hImgFile);
	if(hSubFile != INVALID_HANDLE_VALUE) CloseHandle(hSubFile);
	if (dwSectorTable != NULL) delete dwSectorTable;
	ExitProcess(0);
}

bool OpenImageFile(char * szFileName)
{
	char szName[256];

	// construct file name
	lstrcpy(szName, szFileName);
	lstrcat(szName,".img");
	
	// open the file
	hImgFile= CreateFile(szName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
	
	if(hImgFile==INVALID_HANDLE_VALUE) {
		printf("cannot open input file: 
");
		return false;
	}
	
	// get the filesize;
	dwImgFileSize = GetFileSize(hImgFile,0);

	return true;
}

bool OpenSubFile(char * szFileName)
{
	char szName[256];

	// construct file name
	lstrcpy(szName, szFileName);
	lstrcat(szName,".sub");
	
	// open the file
	hSubFile= CreateFile(szName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
	
	if(hSubFile==INVALID_HANDLE_VALUE) {
		printf("cannot open subchannel file: 
");
		return false;
	}
	
	// get the filesize;
	dwSubFileSize = GetFileSize(hSubFile,0);

	return true;
}

void CreateTwinSectorList()
{
	dwSectorTable = new DWORD[dwSectorCount];
	if(dwSectorTable == NULL) Exit();

	for(DWORD dwCount=0; dwCount < dwSectorCount; dwCount++) {
		dwSectorTable[dwCount]=1;
	}
}

void InsertTwinSectors(int nRangeStart, int nRangeEnd, int nTwinCount, int nStep)
{
	int nRangeLength = nRangeEnd - nRangeStart;

	for(int nCount=nRangeStart; nCount < nRangeStart+nRangeLength; nCount+= nStep) {
		dwSectorTable[nCount] += nTwinCount;
	}
}

void ShowInfo()
{
	DWORD dwNewSectors = 0;

	// get new sector count
	for(DWORD dwCount=0; dwCount < dwSectorCount; dwCount++) {
		dwNewSectors += dwSectorTable[dwCount];
	}

	printf("Original sector count: %d",dwSectorCount);
	printf("  (%d) mb
",dwSectorCount/512);
	
	printf("New sector count: %d",dwNewSectors);
	printf("  (%d) mb
",dwNewSectors/512);
}

void WriteNewImgFile()
{
	HANDLE hFile;
	DWORD  dwSize = 2352;
	BYTE   aData[3000];

	DWORD  dwStarCounter = 0;

	printf("
Now writing image file:");

	// try to open the file
	hFile= CreateFile("patched.img",GENERIC_READ | GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
	if(hFile==INVALID_HANDLE_VALUE) {
		printf("
error: cannot write new image file");
		Exit();
	}

	// write the new file with twin sectors
	for(DWORD dwCount = 0;dwCount<dwSectorCount;dwCount++) {
		if( ReadFile(hImgFile, aData, dwSize, &dwSize, 0) == 0 ) {
			printf("
error: cannot read image file");
			Exit();
		}

		for(DWORD dwRepeat = 0; dwRepeat < dwSectorTable[dwCount] ;dwRepeat++) {
			if( WriteFile(hFile, aData, dwSize, &dwSize, 0) == 0) {
				printf("
error: cannot write image file");
				Exit();
			}
		}

		// update funky stars
		dwStarCounter++;
		if(dwStarCounter == dwSectorCount/10) {
			printf("*");
			dwStarCounter=0;
		}
	}


	CloseHandle(hFile);
}

void WriteNewSubFile()
{
	HANDLE hFile;
	DWORD  dwSize = 96;
	BYTE   aData[3000];

	DWORD dwStarCounter = 0;

	printf("
Now writing subchannel file: ");

	// try to open the file
	hFile= CreateFile("patched.sub",GENERIC_READ | GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
	if(hFile==INVALID_HANDLE_VALUE) {
		printf("
error: cannot write new subchannel file");
		Exit();
	}
	
	// write the new file with twin sectors
	for(DWORD dwCount = 0;dwCount<dwSectorCount;dwCount++) {
		if( ReadFile(hSubFile, aData, dwSize, &dwSize, 0) == 0 ) {
			printf("
error: cannot read subchannel file");
			Exit();
		}
		for(DWORD dwRepeat = 0; dwRepeat < dwSectorTable[dwCount] ;dwRepeat++) {
			if( WriteFile(hFile, aData, dwSize, &dwSize, 0)== 0 ) {
				printf("
error: cannot write subchannel file");
				Exit();
			}
		}

		// update funky stars
		dwStarCounter++;
		if(dwStarCounter == dwSectorCount/10) {
			printf("*");
			dwStarCounter=0;
		}
	}


	CloseHandle(hFile);
}


void main(int nArgs, char *szArgs[])
{
	printf("TwinPeak v0.1

");
	
	// check command line
	if(nArgs < 2)  {
		printf("
usage: twinpeak <ccd image name without ext.>
");
		Exit();
	}

	// open image file
	if(!OpenImageFile(szArgs[1])) {
		Exit();
	}

	// open subchannel file
	if(!OpenSubFile(szArgs[1]))   {
		Exit();
	}

	// check sector count
	dwSectorCount = dwImgFileSize / 2352;
	if(dwSectorCount*2352 != dwImgFileSize) {
		printf("
error: image file size is no multiple of 2352
");
		Exit();
	}

	// check subchannel size
	if(dwSectorCount*96 != dwSubFileSize) {
		printf("
error: subchannel file does not match image file
");
		Exit();
	}

	// initialize list
	CreateTwinSectorList();

	/* check out the mds file 
	   of UT2003 german to see
	   where to put twin sectors */

	InsertTwinSectors( 1700, 2300, 1, 6);
	InsertTwinSectors( 3600, 4900, 1, 6);
	InsertTwinSectors( 5500, 6600, 1, 6);
	InsertTwinSectors( 6900, 7400, 1, 6);
	InsertTwinSectors( 8300, 8800, 1, 6);
	InsertTwinSectors( 9100, 9600, 1, 6);
	InsertTwinSectors( 10100, 10600, 1, 6);
	InsertTwinSectors( 10800, 11400, 1, 6);
	InsertTwinSectors( 12600, 13100, 1, 6);
	InsertTwinSectors( 13400, 14500, 1, 6);
	InsertTwinSectors( 15500, 16100, 1, 6);
	InsertTwinSectors( 16200, 16800, 1, 6);
	InsertTwinSectors( 17500, 18600, 1, 6);
	InsertTwinSectors( 19000, 19600, 1, 6);
	InsertTwinSectors( 19900, 20400, 1, 6);
	InsertTwinSectors( 20600, 21000, 1, 6);
	InsertTwinSectors( 21600, 22100, 1, 6);
	InsertTwinSectors( 23400, 23900, 1, 6);
	InsertTwinSectors( 24400, 25400, 1, 6);
	InsertTwinSectors( 26000, 26800, 1, 6);
	InsertTwinSectors( 27100, 27600, 1, 6);
	InsertTwinSectors( 28200, 29400, 1, 6);
	InsertTwinSectors( 29600, 30000, 1, 6);
	InsertTwinSectors( 30600, 31200, 1, 6);
	InsertTwinSectors( 31800, 33600, 1, 6);
	InsertTwinSectors( 33800, 34400, 1, 6);

	// show some details
	ShowInfo();

	// write new files
	WriteNewImgFile();
	WriteNewSubFile();
	
	printf("
done.");
	Exit();
}




just copied ut2003. tested on 4 drives, all work :wink:

This would mean that Venom was too pessimistic. Does the image work on several types of cd-r?

topic fixed!

i tried cdr and rw

Is there a possibility to automatize this?

sure

blindwrite has a tool called bwt creator or something like that.
that’s where the numbers are from.

now if someone could make a program to do this but load mds files so you don’t have to change the code for every game…

A small patching program…

Nice work Blackcheck.

good one blackcheck

/me humbly bows down

:bow: :bow: :bow:

Congratulations,blackcheck!!!:bow:

I’ve one question: would be these twin sectors copyable, for example, by CloneCD or Alcohol (in better words make a copy of a copy)?

LOL, Blackcheck, you seem to be rather stubborn.:wink:
Have you tried to look at physical parameters of such CD-R in BWABuilder?
Also I am wondering on what drives did it work for you - the way you insert twin sectors you will not be even able to read them on many drives. You will simply get a lot of bad sectors.

Originally posted by VeNoM386
LOL, Blackcheck, you seem to be rather stubborn.:wink:
Have you tried to look at physical parameters of such CD-R in BWABuilder?
Also I am wondering on what drives did it work for you - the way you insert twin sectors you will not be even able to read them on many drives. You will simply get a lot of bad sectors.

  1. i sure am…

  2. yes, it looks like the securom diagram, but with bigger peaks.

  3. i tried on aopen cdrw24 liteon 24x and two noname 40x drives.

i have tried various patterns , and 1,6 worked best.
i’m not saying that this is the ultimative bulletproof way to
copy securom. this is just an example how it worked for me.

the point is that the new securom CAN be copied. now others can find ways to do it reliably.

Venom’s other point was that (if I recall correctly) a simple check would enable the SecuROM loader to detect twin sectors. This maybe like AWS, some burners / readers work, others don’t. The point is, if you only want to make a copy for personal backup, as long as your CDROM drive can read the twin sectors then it doesn’t matter what other drives can.

Venom is technically correct, you can’t physically copy the protections. However there may be tricks that will fool the loader. :slight_smile:

Unfortunately, in the way you try it CANNOT be copied. What you did is just only a far approximation.

1)The density of CD you made does not match original even in the near approach and can be easily detected - I bet SONY already enhances their code;-)I wonder how it works at all - their bug.

2)The peaks that your CD produces will strongly depend on the reading step: 9, 13, 27 etc will produce different peaks.This is also because inital sector offset is random.

3)What is most important - your CD is not readable on most CDROMs, as I already told (eg. Plextor, Toshiba)

I have a Toshiba 1502, my brother has Unreal Tounament => blackcheck only needs to send the compiled tool and I’ll see whether it works on Toshiba drives or not.

<1)The density of CD you made does not match original even in
<the near approach and can be easily detected - I bet SONY
<already enhances their code;-)I wonder how it works at all -
<their bug.

sure, clonecd’s bad sectors, aws etc can be detected easily,too…

<2)The peaks that your CD produces will strongly depend on the
<reading step: 9, 13, 27 etc will produce different peaks.This is
<also because inital sector offset is random.

i haven’t debugged the loader with my copy yet. but as i recall
the stepping does not change that often. so maybe my copy
won’t work with different steps.

<3)What is most important - your CD is not readable on most
<CDROMs, as I already told (eg. Plextor, Toshiba)

uhm if that’s true it’s bad… but not my problem :wink:

btw i just copied hotel giant this way…

Venom seems to be right. Images modified with Blackcheck’s funky star generator :wink: are not readable without errors on my Toshiba XM-6202B CD-ROM drive (firmware 1119). It reports about 25 bad sectors per 2000 sectors. No read errors, however, on a Lite-On LTD-165H DVD-ROM drive (firmware CH0Q).

oh and talking about DT, when will we get to be able to change the driver name or is that a technical impossibility. It seems that every time a new game / patch is released the new driver is blacklisted (sorry this is O/T but Venom visits this forum :slight_smile: )

The file from Blackcheck can be easily compiled in Visual Studio., just create new Win32 console application and paste the code there…:wink:
@AtomicX: currently I am changing driver name with every new version, I hope they get bored some day…:wink: