Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: EAC CRC calculation mismatch in grabber/WAV editor when [No use of nul (Read 12457 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

EAC CRC calculation mismatch in grabber/WAV editor when [No use of nul

Well, maybe it's a well-known problem (and maybe the solution was already found - then, please, follow me to the specified topic/page)...

The speech concerns about [No use null samples in CRC calculations] checkbox. Let us consider the following situation:

We have an AudioCD, and we grab it to image.wav.

1) The checkbox is unchecked. Then EAC uses ALL samples to calculate checksum of audiodata to write it into a LOG-file. Hence we have standard CRC32-algorithm that's applied to complete audiodata stream. EAC calculates 32-bit value (denote it by X) and writes this X into LOG in hexadecimal representation.

Then, if we use Tools|Process WAV feature of EAC and process obtained image file, we get the same CRC value in the UL-corner of the window (Checksum: X). Everything is OK  But this is only a half.

2) The checkbox is checked. Then EAC skips null samples while calculating CRC. Hence we have the standard CRC32-algorithm, but for the audiodata stream where all two-byte zeros were dropped. Obviously, we obtain (in general case) another CRC32 value (denote it by Y). This value will be written into a LOG.

Strange things begin here: when we use Tools|Process WAV feature of EAC and process obtained image file, we get another value (denote it by Z). Y <> Z in general case!!!

So, EAC Audioeditor cannot calculate the same CRC value in this case (obviously, there is an error in calculator).

Moreover, i've started to explore, what's the hell. And found the reason of this mismatching. And I'll speak about it later and 'll post complete description of problem/solution if anybody is interested in it (otherwise it's is air-shaking).

Oh, some words about versions: this occurs in EAC 0.95b4 and (as my friends report me) in latter versions too...

Thank you for reading!
Waiting for your comments!
Sorry for my English!

EAC CRC calculation mismatch in grabber/WAV editor when [No use of nul

Reply #1
Yeah, the problem has been identified before, but isn't one of those things that was ever pursued to any serious extent.

Please explain how the EAC's wave processor calculates CRCs when instructed to ignore null samples.  I'm interested in knowing.

EAC CRC calculation mismatch in grabber/WAV editor when [No use of nul

Reply #2
Yeah, the problem has been identified before, but isn't one of those things that was ever pursued to any serious extent.

Please explain how the EAC's wave processor calculates CRCs when instructed to ignore null samples.  I'm interested in knowing.

OK, so I'll continue  Thank u for your answer!

Of course, I couldn't complete this job w/o some diassembly works, that, MAYBE violate the EAC license agreement concerned reverse engeneering and so on. But since these digs lead us to the Truth, I think it's not the time to call for lawmakers.


In the programmer terms, let RIP_CRC(bool bUseFlag) be the macro that calculates CRC while ripping CDs, and WAV_ED_CRC(bool bUseFlag) be the macro that calculates CRC in WAVE Editor. The parameter bUseFlag is the "No use of nul samples..." checkbox state.

So, in these terms, we have that

Code: [Select]
RIP_CRC(false) = WAV_ED, _CRC(false)
RIP_CRC(true) != WAV_ED_CRC(true) (!!! WTF??? !!!)


The solution of this inconsistency lies in the algorythm of WAV_ED_CRC(true) that is buggy (!). And You may easily check this. Take a stereo WAVe file, and calculate CRC using WAVE Editor. You get value CRC=X. Then, modify ANY nonzero sample on RIGHT channel of this file (let us consider that L word is the lower, and R is the higher one in DWORD sample representation). And then calculate it again. You get the SAME value X.

But, obviously, this cannot be true if the procedure works fine.

Here is the assembly of the WAV_ED_CRC(true) [buggy]
(the listing is from IDA Pro 5.0)
Code: [Select]
.text:0045E520; int __stdcall proc_CRC_Calc_BUF_Ignore_Word_Zeros_S1(int count,int p_CRC,int pBuffer,int old_CRC)
.text:0045E520 proc_CRC_Calc_BUF_Ignore_Word_Zeros_S1 proc near
.text:0045E520 count               = dword ptr  8
.text:0045E520 p_CRC               = dword ptr  0Ch
.text:0045E520 pBuffer             = dword ptr  10h
.text:0045E520 old_CRC             = dword ptr  14h
.text:0045E520
.text:0045E520                     push ebp
.text:0045E521                     mov ebp, esp
.text:0045E523                     push ebx
.text:0045E524                     push esi
.text:0045E525                     push edi
.text:0045E526                     push eax
.text:0045E527                     push ebx
.text:0045E528                     push ecx
.text:0045E529                     push edx
.text:0045E52A                     push esi
.text:0045E52B                     push edi
.text:0045E52C                     mov esi, [ebp+old_CRC]
.text:0045E52F                     mov edi, [ebp+pBuffer]
.text:0045E532                     mov edx, [ebp+p_CRC]
.text:0045E535                     mov eax, [ebp+count]
.text:0045E538                     mov ecx, [edx]
.text:0045E53A
.text:0045E53A cycle:
; ---------------------------------------------------------
; here we obtain
; only lower word of [edi], that is L-R-sample
; the higher word is unused
; ---------------------------------------------------------
.text:0045E53A                     mov bx, [edi]
.text:0045E53D                     cmp bx, 0
.text:0045E541                     jz  short end_if__1
.text:0045E543                     push eax
.text:0045E544                     push edx
.text:0045E545                     push ecx
.text:0045E546                     call proc_CRC_TwoByte_BX_ptr_ESI
.text:0045E54B                     pop ecx
.text:0045E54C                     pop edx
.text:0045E54D                     pop eax
.text:0045E54E                     mov bx, [edi]
.text:0045E551                     cmp bx, 32768
.text:0045E556                     jnz short end_if__0
.text:0045E558                     mov bx, 8001h
.text:0045E55C
.text:0045E55C end_if__0:
.text:0045E55C                     cmp bx, cx
.text:0045E55F                     jle short end_if__1
.text:0045E561                     mov cx, bx
.text:0045E564
.text:0045E564 end_if__1:
.text:0045E564                     ror ecx, 10h
.text:0045E567                     cmp bx, cx
.text:0045E56A                     jge short end_if__2
.text:0045E56C                     mov cx, bx
.text:0045E56F
.text:0045E56F end_if__2:
.text:0045E56F                     ror ecx, 10h
; ---------------------------------------------------------
; we increment EDI by 4, so we skip right (or left?) channel
; ---------------------------------------------------------
.text:0045E572                     add edi, 4
.text:0045E575                     sub eax, 1
.text:0045E578                     cmp eax, 0
.text:0045E57B                     jge short cycle
.text:0045E57D                     mov [edx], ecx
.text:0045E57F                     pop edi
.text:0045E580                     pop esi
.text:0045E581                     pop edx
.text:0045E582                     pop ecx
.text:0045E583                     pop ebx
.text:0045E584                     pop eax
.text:0045E585                     pop edi
.text:0045E586                     pop esi
.text:0045E587                     pop ebx
.text:0045E588                     pop ebp
.text:0045E589                     retn 10h
.text:0045E589 proc_CRC_Calc_BUF_Ignore_Word_Zeros_S1 endp
;
------------------------------------------------------------------------


And here is the assembly of the WAV_ED_CRC(false) [normal, non-buggy]
Code: [Select]
.text:0045E590 proc_CRC_Calc_BUF_NoIgnore_Word_Zeros_S2 proc near
.text:0045E590
.text:0045E590 arg_0               = dword ptr  8
.text:0045E590 arg_4               = dword ptr  0Ch
.text:0045E590 arg_8               = dword ptr  10h
.text:0045E590 arg_C               = dword ptr  14h
.text:0045E590
.text:0045E590                     push ebp
.text:0045E591                     mov ebp, esp
.text:0045E593                     push ebx
.text:0045E594                     push esi
.text:0045E595                     push edi
.text:0045E596                     push eax
.text:0045E597                     push ebx
.text:0045E598                     push ecx
.text:0045E599                     push edx
.text:0045E59A                     push esi
.text:0045E59B                     push edi
.text:0045E59C                     mov esi, [ebp+arg_C]
.text:0045E59F                     mov edi, [ebp+arg_8]
.text:0045E5A2                     mov edx, [ebp+arg_4]
.text:0045E5A5                     mov eax, [ebp+arg_0]
.text:0045E5A8                     mov ecx, [edx]
.text:0045E5AA
.text:0045E5AA loc_45E5AA:
.text:0045E5AA                     push eax
.text:0045E5AB                     push edx
.text:0045E5AC                     push ecx
; -----------------------------------
; calculate left channel (lower word)
; -----------------------------------
.text:0045E5AD                     mov bx, [edi]
.text:0045E5B0                     call proc_CRC_TwoByte_BX_ptr_ESI
; -----------------------------------
; calculate left channel (high word)
; -----------------------------------
.text:0045E5B5                     mov bx, [edi+2]
.text:0045E5B9                     call proc_CRC_TwoByte_BX_ptr_ESI
.text:0045E5BE                     pop ecx
.text:0045E5BF                     pop edx
.text:0045E5C0                     pop eax
.text:0045E5C1                     mov bx, [edi]
.text:0045E5C4                     cmp bx, 8000h
.text:0045E5C9                     jnz short loc_45E5CF
.text:0045E5CB                     mov bx, 8001h
.text:0045E5CF
.text:0045E5CF loc_45E5CF:
.text:0045E5CF                     cmp bx, cx
.text:0045E5D2                     jle short loc_45E5D7
.text:0045E5D4                     mov cx, bx
.text:0045E5D7
.text:0045E5D7 loc_45E5D7:
.text:0045E5D7                     ror ecx, 10h
.text:0045E5DA                     cmp bx, cx
.text:0045E5DD                     jge short loc_45E5E2
.text:0045E5DF                     mov cx, bx
.text:0045E5E2
.text:0045E5E2 loc_45E5E2:
.text:0045E5E2                     ror ecx, 10h
.text:0045E5E5                     add edi, 4
.text:0045E5E8                     sub eax, 1
.text:0045E5EB                     cmp eax, 0
.text:0045E5EE                     jge short loc_45E5AA
.text:0045E5F0                     mov [edx], ecx
.text:0045E5F2                     pop edi
.text:0045E5F3                     pop esi
.text:0045E5F4                     pop edx
.text:0045E5F5                     pop ecx
.text:0045E5F6                     pop ebx
.text:0045E5F7                     pop eax
.text:0045E5F8                     pop edi
.text:0045E5F9                     pop esi
.text:0045E5FA                     pop ebx
.text:0045E5FB                     pop ebp
.text:0045E5FC                     retn 10h
.text:0045E5FC proc_CRC_Calc_BUF_NoIgnore_Word_Zeros_S2 endp


Please notice that these routines are different (maybe this is done so for optimisations) (well, my routine written completely in MASM32 works quicker  )

Here are some source code for PROPER CRC calculations...
http://dmvn.myftp.org/soft/wavcrc32-gui-0.11-only.rar [w/o SOURCE, optimized version in MASM]
http://dmvn.myftp.org/soft/wavcrc32-conso...22-gui-0.11.rar [C/C++ complete source + console/GUI executables]

OK, now you know all the Truth. At least, about CRC calculations in EAC.

A few words to complete our digs and get up to the surface. Some time ago I've reported this to Andre via mailing to eac@exactaudiocopy.org, but there were no answer, so I'm not sure that my mail was delivered.

Anyway, greynol, I hope this bug will be fixed. The solution is easy as multiply 2 by 2  So we should only verify that Andre knows about it

EAC CRC calculation mismatch in grabber/WAV editor when [No use of nul

Reply #3
Well, my dynamicDNS host has changed, so I've updated all links to software

Btw, no news from EAC developer by this subj... Strange, very strange...

EAC CRC calculation mismatch in grabber/WAV editor when [No use of nul

Reply #4
Andre has recently been made aware of this:
http://www.digital-inn.de/exact-audio-copy...latest-eac.html

I apologize for not remembering to tell him back when you presented the issue.

EAC CRC calculation mismatch in grabber/WAV editor when [No use of nul

Reply #5
Never mind. The main matter is that he knows about it NOW.

EAC CRC calculation mismatch in grabber/WAV editor when [No use of nul

Reply #6
dmvn: is it possible that you could update the program to support reading in files in batch?

I tried wavcrc32.exe *.wav but it doesn't work.

EAC CRC calculation mismatch in grabber/WAV editor when [No use of nul

Reply #7
The original links are dead. I used this search query on yahoo.com (google failed) to find an alternative link:
http://download.nnover.ru/data/uf/3468314/...22-gui-0.11.rar [C/C++ complete source + console/GUI executables]

Also, in case a few years from now someone will be looking for the source code like I was, here it is:
http://pastebin.com/M3DxtHqX [wavcrc32: complete source code]

Cheers!