Disc Copy Protection Systems - How Do They Work?

Games and other software often come with protection that requires you to use the original copy of a disc. There are several major methods of copy protection, which I will explain in detail below. But first, I want to explain what a CD looks like up close…
Data is stored on a CD in unit blocks called sectors, which can only be read or written in their entirety. By default the sector size on CDFS is 2048 bytes, which means that each read/write operation must be done on a multiple of 2048 bytes. At the beginning of a disc there is a gap of 16 sectors (32KB) with no data written to it. What follows it is the file system header, which provides information about the disc and the data on it. After this data the disc remains blank, since there is no data to write to it.
Data in non-data sectors
The initial 16 sectors can have arbitrary data written to them since they are never read by the OS or hardware device. This data can be used to verify if the disc was copied file-by-file instead of sector-by-sector. The program seeks to offset 0 from the start of the disc, then reads the initial 16 sectors. This also applies to sectors after the end of the file system data, if there is free space. The data on these sectors can be verified in some way in the program to make sure it is the original disc. This method seems pretty attractive to developers who want a “quick fix”, since it can be achieved using nothing but the Win32 APIs CreateFile, SetFilePointer, ReadFile, and CloseHandle. However, this is pretty much useless now since nearly all modern CD copy software uses sector-by-sector copying.
Here’s a quick demo on how it would work in terms of code:
 
// C# Code...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;

namespace LowLevelRead
{

    class Program
    {
        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern IntPtr CreateFile(
           string fileName,
           [MarshalAs(UnmanagedType.U4)] FileAccess fileAccess,
           [MarshalAs(UnmanagedType.U4)] FileShare fileShare,
           IntPtr securityAttributes,
           [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
           int flags,
           IntPtr template);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);

        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern uint SetFilePointer(
            [In] IntPtr hFile,
            [In] int lDistanceToMove,
            [Out] out int lpDistanceToMoveHigh,
            [In] uint dwMoveMethod);

        static void Main()
        {
            // open the drive's raw device, where the drive is specified as \.X: where X is the drive letter.
            IntPtr hDevice = CreateFile(@"\.X:", FileAccess.Read, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
            int dummy = 0;
            // seek to beginning of drive
            uint ret = SetFilePointer(hDevice, 0x0000, out dummy, 0);
            // each sector is 2048 bytes, so you must read in multiples of 2048
            int sectorSize = 2048;
            // we're reading 16 sectors, so make the buffer big enough
            byte[] buffer = new byte[sectorSize * 16];
            uint br = 0;
            // read the first 16 sectors (32kb) into the buffer
            bool ok = ReadFile(hDevice, buffer, (uint)sectorSize * 16, out br, IntPtr.Zero);
            // clean up!
            CloseHandle(hDevice);
            // the buffer[] array now contains the bytes stored in the first 16 sectors of the disc.
            // if you test this with a mounted ISO they should all be zero.
            // you can open up an ISO file in a hex editor and modify the first 32kb to contain whatever you like
            // this will then appear in the buffer
            //
            // please remember that if you try to burn this crafted, your disc burner (or disc burner software) may completely ignore these sectors.
            // normally this protection is put in place using custom hardware/software.
            Console.ReadLine();
        }
    }
}
 
Invalid error correction data
Each sector on a disc has structural data that is not directly readable by the software which includes EDC (error detection) and ECC (error correction) designed to help prevent scratches and dirt from causing errors. Specialized hardware can write bad values to these structures for specific individual sectors so that when the program attempts to read them they get a read error. These errors are expected for these specific sectors, so if the disc is a copy or mounted ISO the errors will not occur and the program will detect a copy. Unfortunately, modern CD drive hardware can ignore these bad values and will not issue a read error. Programs such as Daemon Tools that allow you to mount disc images may also be wise to such tricks and will emulate disc read errors when it detects a protected disc.

Duplicate sector entries
Each sector on the disc is addressed inside the sector header as both relative and logical absolute positions. This means that each sector header contains some sort of identification that states that it is in fact the sector the drive is trying to seek to. If this identification is forged, the disc read mechanism can be tricked into thinking it has got to the right sector when in fact it has not. Consider the way disc drives work – the CD spins in a set direction at a set speed and the laser moves to the disc to read a track (single circle of sectors) in order to fetch the data it needs. So what if the disc contains two entries for sector number 1337? We put one in its normal position (1336, 1337, 1338, etc…) and one further after, for example between 9000 and 9001.
Normal disc reads would begin at 0 and move forward, selecting the next sector and checking that its address is the next one it wants. When it hits this wrongly placed second sector with address 1337, it ignores it and carries on as usual since it isn’t looking for sector 1337. When it actually wants sector 1337, it looks at the start of the disc and then seeks forward to find it. However, if we seek to sector 8800 and then tell it to read sector 1337, it will immediately continue seeking forward and find the duplicate sector between 9000 and 9001. Essentailly the read mechanism is lazy and just looks for the first occurance of the sector’s address from the current position. This allows us to fool it into thinking it’s found the sector. Copy protection uses this to hide secret data on the disc in order to verify that it is an original and not a copy.
Creating a disc with such protection involves custom hardware and at the moment has no easy solution. Even sector-by-sector copying cannot bypass this method since there is no way for the copying software to know where it might encounter one of these duplicate sectors. In order to create a working copy, the disc must either be copied raw using special hardware, or be copied using software that is designed to detect these duplicate sectors, which is extremely slow since it must try to seek to every possible sector from every single header position.
DPM
A new method of protection called Data Position Measurement measures the physical position of sectors on the disc and compares them to a stored set of values. Since mass-produced game CDs are stamped (think moulded disc surface instead of burned) the positions are identical for every disc. If you try to copy the disc using any method, the media you write to will not match the original positions. If you create a disc image, the positions are (usually) generated uniformly as to appear normal, but they will not match the original positions either. More advanced copy protection such as the newer versions of SecuROM use DPM. Newer disc image creation software such as Alcohol 120% can duplicate these measurements and put them in the image file. Daemon Tools allows you to emulate RPMS, which fools DPM algorithms into thinking it’s the original disc.

0 comments:

Post a Comment