/* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "crc-itu-t.h" #include "dvdv.h" #define LBA_SIZE 2048 int main(int argc, char ** argv) { FILE *iso; unsigned char buffer[LBA_SIZE], tag_checksum; unsigned short i, is_udf = 0; unsigned short *desc_crc; unsigned short *desc_crc_len; printf("ESRPATCH v0.2 - PS2 ISO patcher for ffgriever's ESR project.\n"); printf("By: bootsector - http://www.brunofreitas.com/\n\n"); if(argc != 2) { printf("Usage: esrpatch \n"); return 1; } if((iso = fopen(argv[1], "rb+")) == NULL) { printf("Error opening ISO.\n"); return 1; } memset(buffer, 0, sizeof(buffer)); // Checks if ISO has an UDF descriptor for(i = 1; i < 64; i++) { fseek(iso, LBA_SIZE * i + 32768, SEEK_SET); fread(buffer, LBA_SIZE, 1, iso); // "NSR" if(!strncmp(buffer + 1, "NSR", 3)) { is_udf = 1; break; } } if(!is_udf) { printf("Error: ISO doesn't contain an UDF descriptor.\n"); fclose(iso); return 1; } // Checks if image is already patched fseek(iso, 14 * LBA_SIZE, SEEK_SET); fread(buffer, LBA_SIZE, 1, iso); if(!strncmp(buffer + 25, "+NSR", 4)) { printf("ISO is already patched.\n"); fclose(iso); return 1; } // Backups LBA 34 into 14 fseek(iso, 34 * LBA_SIZE, SEEK_SET); fread(buffer, LBA_SIZE, 1, iso); fseek(iso, 14 * LBA_SIZE, SEEK_SET); fwrite(buffer, LBA_SIZE, 1, iso); // Backups LBA 50 into 15 fseek(iso, 50 * LBA_SIZE, SEEK_SET); fread(buffer, LBA_SIZE, 1, iso); fseek(iso, 15 * LBA_SIZE, SEEK_SET); fwrite(buffer, LBA_SIZE, 1, iso); // Updates LBA 34 fseek(iso, 34 * LBA_SIZE, SEEK_SET); fread(buffer, LBA_SIZE, 1, iso); // Updates new referenced LBA: Now it points to a DVD_VIDEO structure buffer[0xBC] = 0x80; buffer[0xBD] = 0x00; // Calculates new checksums desc_crc_len = (unsigned short *)(buffer + 10); desc_crc = (unsigned short *)(buffer + 8); *desc_crc = crc_itu_t(0, (buffer + 16), *desc_crc_len); tag_checksum = 0; for(i = 0; i < 4; i++) tag_checksum += buffer[i]; for(i = 5; i < 16; i++) tag_checksum += buffer[i]; buffer[4] = tag_checksum; // Save modified LBA fseek(iso, 34 * LBA_SIZE, SEEK_SET); fwrite(buffer, LBA_SIZE, 1, iso); // Updates LBA 50 fseek(iso, 50 * LBA_SIZE, SEEK_SET); fread(buffer, LBA_SIZE, 1, iso); // Updates new referenced LBA: Now it points to a DVD_VIDEO structure buffer[0xBC] = 0x80; buffer[0xBD] = 0x00; desc_crc_len = (unsigned short *)(buffer + 10); desc_crc = (unsigned short *)(buffer + 8); *desc_crc = crc_itu_t(0, (buffer + 16), *desc_crc_len); // Calculates new checksums tag_checksum = 0; for(i = 0; i < 4; i++) tag_checksum += buffer[i]; for(i = 5; i < 16; i++) tag_checksum += buffer[i]; buffer[4] = tag_checksum; // Save modified LBA fseek(iso, 50 * LBA_SIZE, SEEK_SET); fwrite(buffer, LBA_SIZE, 1, iso); // Writes DVD Video data @ LBA 128 fseek(iso, 128 * LBA_SIZE, SEEK_SET); fwrite(dvdvdata, DVDVDATA_SIZE, 1, iso); fclose(iso); printf("Done!\n"); return 0; }