I am trying to analyse ARCue.pl software.
In most cases You are right. But with one not - it is not very dificult to get addresses and decode bin files:
Code:
* Calculate the three disc ids used by AR
my ($discId1, $discId2, $cddbDiscId) = (0, 0, 0);
{
use integer;
for (my $trackNo = 0; $trackNo <= $trackCount; $trackNo++) {
my $trackOffset = $trackOffsets[$trackNo];
$discId1 += $trackOffset;
$discId2 += ($trackOffset ? $trackOffset : 1) * ($trackNo + 1);
if ($trackNo < $trackCount) {
$cddbDiscId = $cddbDiscId + sumDigits(int($trackOffset/75) + 2);
}
}
$cddbDiscId = (($cddbDiscId % 255) << 24) + ((int($trackOffsets[$trackCount]/75) - int($trackOffsets[0]/75)) << 8) + $trackCount;
$discId1 &= 0xFFFFFFFF;
$discId2 &= 0xFFFFFFFF;
$cddbDiscId &= 0xFFFFFFFF;
}
Code:
print "Checking AccurateRip database\n\n";
* See if we can find the disc in the database
my $arUrl = sprintf("http://www.accuraterip.com/accuraterip/%.1x/%.1x/%.1x/dBAR-%.3d-%.8x-%.8x-%.8x.bin",
$discId1 & 0xF, $discId1>>4 & 0xF, $discId1>>8 & 0xF, $trackCount, $discId1, $discId2, $cddbDiscId);
my $arDiscNotInDb = 0;
my $arNetworkFailed = 0;
my $response = $lwpUserAgent->get($arUrl);
if (!$response->is_success) {
if ($response->status_line =~ m/^404/) {
$arDiscNotInDb = 1;
}else{
$arNetworkFailed = $response->status_line;
}
}
* Extract CRCs from response data
my $arCrcCount = 0;
my @arTrackConfidences = ();
my @arTrackCRCs = ();
if (!($arDiscNotInDb || $arNetworkFailed)) {
my $arCrcData = $response->content;
my $ptr = 0;
while ($ptr < length($arCrcData)) {
my ($chunkTrackCount, $chunkDiscId1, $chunkDiscId2, $chunkCddbDiscId);
* Force perl to interpret these values as signed integers
{
use integer;
$chunkTrackCount = unpack("c",substr($arCrcData,$ptr,1));
$chunkDiscId1 = unpack("V",substr($arCrcData,$ptr+1,4)) + 0;
$chunkDiscId2 = unpack("V",substr($arCrcData,$ptr+5,4)) + 0;
$chunkCddbDiscId = unpack("V",substr($arCrcData,$ptr+9,4)) + 0;
}
$ptr +=13;
if ( $chunkTrackCount != $trackCount
|| $chunkDiscId1 != $discId1
|| $chunkDiscId2 != $discId2
|| $chunkCddbDiscId != $cddbDiscId ) {
croak("Track count or Disc IDs don't match.");
}
* How if it flagged that a track is not in the database?
for (my $track = 0; $track < $trackCount; $track++) {
my ($trackConfidence, $trackCrc);
* Force perl to interpret these values as signed integers
{
use integer;
$trackConfidence = unpack("c",substr($arCrcData,$ptr,1));
$trackCrc = unpack("V",substr($arCrcData,$ptr+1,4)) + 0;
$ptr += 9;
}
if ($arCrcCount == 0){
$arTrackConfidences[$track] = [];
$arTrackCRCs[$track] = [];
}
$arTrackConfidences[$track]->[$arCrcCount] = $trackConfidence;
$arTrackCRCs[$track]->[$arCrcCount] = $trackCrc;
}
$arCrcCount++;
}
}
Code:
printf "Track\tRipping Status\t\t[Disc ID: %08x-%08x]\n\n", $discId1, $cddbDiscId;
* Calculate a CRC for each track
my @trackCRCs = ();
my ($accuratelyRipped, $notAccuratelyRipped, $notInDatabase) = (0, 0, 0);
for (my $trackNo = 0; $trackNo < $trackCount; $trackNo++) {
seek($FH, $dataOffset + $trackOffsets[$trackNo] * 2352, 0);
my ($frame, $CRC);
$CRC = 0;
for (my $frameNo = 0; $frameNo < $trackLengths[$trackNo]; $frameNo++) {
if (read($FH, $frame, 2352) != 2352) { croak ("read failed.") };
{
use integer;
$CRC += processFrame($frame, $frameNo, $trackLengths[$trackNo], $trackNo == 0, $trackNo == $trackCount - 1);
}
}
{
use integer;
$trackCRCs[$trackNo] = $CRC & 0xFFFFFFFF;
}
if ($arDiscNotInDb) {
printf " %d\tTrack not present in database. [%08x]\n",
$trackNo + 1, $trackCRCs[$trackNo];
$notInDatabase++;
} elsif ($arNetworkFailed) {
printf " %d\t [%08x]\n",
$trackNo + 1, $trackCRCs[$trackNo];
} else {
my $foundCrc = 0;
my $foundCrcMatch = 0;
for (my $arCrcNo=0; $arCrcNo < $arCrcCount; $arCrcNo++) {
if ($arTrackConfidences[$trackNo]->[$arCrcNo] != 0){
$foundCrc = 1;
if ($arTrackCRCs[$trackNo]->[$arCrcNo] == $trackCRCs[$trackNo]) {
printf " %d\tAccurately Ripped (confidence %d) [%08x]\n",
$trackNo + 1, $arTrackConfidences[$trackNo]->[$arCrcNo], $arTrackCRCs[$trackNo]->[$arCrcNo];
$accuratelyRipped++;
$foundCrcMatch = 1;
last;
}
}
}
if (!$foundCrc) {
printf " %d\tTrack not present in database. [%08x]\n",
$trackNo + 1, $trackCRCs[$trackNo];
$notInDatabase++;
}elsif (!$foundCrcMatch) {
printf " %d\t** Rip not accurate ** (confidence %d) [%08x] [%08x]\n",
$trackNo + 1, $arTrackConfidences[$trackNo]->[0], $arTrackCRCs[$trackNo]->[0], $trackCRCs[$trackNo];
$notAccuratelyRipped++;
}
}
}
print "\n_______________________\n\n";
if ($arDiscNotInDb) {
print "Disc not present in AccurateRip database.\n";
} elsif ($arNetworkFailed) {
print "Failed to get $arUrl : " . $arNetworkFailed . "\n";
} elsif ($accuratelyRipped == $trackCount) {
print "All Tracks Accurately Ripped.\n";
} else {
if ($notAccuratelyRipped >= 3) {
print "Your CD disc is possibly a different pressing to the one(s) stored in AccurateRip.\n"
}
printf "Track(s) Accurately Ripped: %d\n", $accuratelyRipped;
printf "**** Track(s) Not Ripped Accurately: %d ****\n", $notAccuratelyRipped;
printf "Track(s) Not in Database: %d\n", $notInDatabase;
}
print "\n\n\n";
}
I will try to modify somehow this script...