; ; +-------------------------------------------------------------------------+ ; ¦ This file is generated by The Interactive Disassembler (IDA) ¦ ; ¦ Copyright (c) 2005 by DataRescue sa/nv, <ida@datarescue.com> ¦ ; ¦ Licensed to: Sebastian Porst, 1 user std, 05/2005 ¦ ; +-------------------------------------------------------------------------+ ; .text:100607D0 .text:100607D0 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ .text:100607D0 .text:100607D0 .text:100607D0 GetVbrTag proc near ; CODE XREF: sub_10059240+77p .text:100607D0 .text:100607D0 pTagData = dword ptr 4 .text:100607D0 buf = dword ptr 8 .text:100607D0 .text:100607D0 mov ecx, [esp+buf] .text:100607D4 push ebx .text:100607D5 push ebp .text:100607D6 push esi .text:100607D7 xor eax, eax .text:100607D9 push edi .text:100607DA mov edi, [esp+10h+pTagData] .text:100607DE mov dword ptr [edi+8], 0 ; pTagData->flags = 0; .text:100607E5 mov dl, [ecx+1] ; buf[1] .text:100607E8 .text:100607E8 The local variable "int hmode" is not put on the stack but kept in ebx .text:100607E8 .text:100607E8 movzx ebx, byte ptr [ecx+3] .text:100607EC mov al, dl .text:100607EE and dl, 0F0h ; Some preparation for the first if .text:100607F1 shr ebx, 6 .text:100607F4 shr eax, 3 .text:100607F7 and eax, 1 .text:100607FA mov ebp, eax .text:100607FC movzx eax, byte ptr [ecx+2] .text:10060800 mov esi, eax .text:10060802 mov [esp+10h+pTagData], ebp ; h_id = (buf[1] >> 3) & 1; .text:10060806 shr eax, 4 .text:10060809 shl ebp, 4 .text:1006080C add eax, ebp .text:1006080E mov eax, ds:bitrate_table[eax*4] .text:10060815 mov ebp, [esp+10h+pTagData] .text:10060819 .text:10060819 The local variable "int h_sr_index" is not put on the stack but kept in esi .text:10060819 .text:10060819 shr esi, 2 .text:1006081C and esi, 3 ; h_sr_index = (buf[2] >> 2) & 3; .text:1006081F cmp dl, 0E0h ; if ((buf[1]>>4)==0xE) .text:10060822 mov [esp+10h+buf], eax .text:10060826 jnz short loc_10060831 .text:10060828 mov edx, ds:samplerate_table2[esi*4] ; pTagData->samprate = samplerate_table[2][h_sr_index]; .text:1006082F jmp short loc_1006083B .text:10060831 ; --------------------------------------------------------------------------- .text:10060831 .text:10060831 loc_10060831: ; CODE XREF: GetVbrTag+56j .text:10060831 lea eax, [esi+ebp*4] .text:10060834 mov edx, ds:samplerate_table[eax*4] ; pTagData->samprate = samplerate_table[h_id][h_sr_index]; .text:1006083B .text:1006083B loc_1006083B: ; CODE XREF: GetVbrTag+5Fj .text:1006083B test ebp, ebp ; if( h_id ) .text:1006083D mov [edi+4], edx .text:10060840 jz short loc_1006084C .text:10060842 cmp ebx, 3 ; if( h_mode != 3 ) .text:10060845 jz short loc_10060851 .text:10060847 add ecx, 36 ; buf+=(32+4); .text:1006084A jmp short loc_10060859 .text:1006084C ; --------------------------------------------------------------------------- .text:1006084C .text:1006084C loc_1006084C: ; CODE XREF: GetVbrTag+70j .text:1006084C cmp ebx, 3 .text:1006084F jz short loc_10060856 .text:10060851 .text:10060851 There's some heavy compiler optimization here. The +21 part which .text:10060851 can be found in both if-clauses is reduced to one. .text:10060851 .text:10060851 loc_10060851: ; CODE XREF: GetVbrTag+75j .text:10060851 add ecx, 21 ; buf+=(17+4); .text:10060854 jmp short loc_10060859 .text:10060856 ; --------------------------------------------------------------------------- .text:10060856 .text:10060856 loc_10060856: ; CODE XREF: GetVbrTag+7Fj .text:10060856 add ecx, 13 ; buf+=(9+4); .text:10060859 .text:10060859 More compiler optimization here. VBRTag is the string literal 'Xing' .text:10060859 VBRTag2 is the string literal 'Info'. .text:10060859 .text:10060859 .text:10060859 loc_10060859: ; CODE XREF: GetVbrTag+7Aj .text:10060859 ; GetVbrTag+84j .text:10060859 mov al, [ecx] .text:1006085B .text:1006085B Here come the if-clauses .text:1006085B .text:1006085B cmp al, 'X' .text:1006085D jz short loc_10060863 ; buf[0] != VBRTag[0] .text:1006085F cmp al, 'I' .text:10060861 jnz short return0 ; buf[0] != VBRTag2[0] .text:10060863 .text:10060863 loc_10060863: ; CODE XREF: GetVbrTag+8Dj .text:10060863 mov al, [ecx+1] .text:10060866 cmp al, 'i' .text:10060868 jz short loc_1006086E ; buf[1] != VBRTag[1] .text:1006086A cmp al, 'n' .text:1006086C jnz short return0 ; buf[1] != VBRTag2[1] .text:1006086E .text:1006086E loc_1006086E: ; CODE XREF: GetVbrTag+98j .text:1006086E mov al, [ecx+2] .text:10060871 cmp al, 'n' ; buf[2] != VBRTag[2] .text:10060873 jz short loc_10060879 .text:10060875 cmp al, 'f' ; buf[2] != VBRTag2[2] .text:10060877 jnz short return0 .text:10060879 .text:10060879 loc_10060879: ; CODE XREF: GetVbrTag+A3j .text:10060879 mov al, [ecx+3] .text:1006087C cmp al, 'g' ; buf[3] != VBRTag[3] .text:1006087E jz short loc_1006088B .text:10060880 cmp al, 'o' ; buf[3] != VBRTag2[3] .text:10060882 jz short loc_1006088B .text:10060884 .text:10060884 return0: ; CODE XREF: GetVbrTag+91j .text:10060884 ; GetVbrTag+9Cj ... .text:10060884 pop edi .text:10060885 pop esi .text:10060886 pop ebp .text:10060887 xor eax, eax .text:10060889 pop ebx .text:1006088A retn .text:1006088B ; --------------------------------------------------------------------------- .text:1006088B .text:1006088B loc_1006088B: ; CODE XREF: GetVbrTag+AEj .text:1006088B ; GetVbrTag+B2j .text:1006088B xor edx, edx .text:1006088D add ecx, 4 ; buf+=4; .text:10060890 .text:10060890 More compiler optimization: The function ExtractI4 has been inlined. .text:10060890 .text:10060890 mov [edi], ebp .text:10060892 mov dh, [ecx] .text:10060894 movzx eax, byte ptr [ecx+2] .text:10060898 add ecx, 4 .text:1006089B mov dl, [ecx-3] .text:1006089E shl edx, 8 .text:100608A1 or edx, eax .text:100608A3 movzx eax, byte ptr [ecx-1] .text:100608A7 shl edx, 8 .text:100608AA or edx, eax .text:100608AC test dl, 1 ; if( head_flags & FRAMES_FLAG ) .text:100608AF mov [edi+8], edx ; pTagData->flags = ExtractI4(buf) .text:100608B2 .text:100608B2 The local variable "head_flags" is kept in edx. It's not put .text:100608B2 on the stack. .text:100608B2 .text:100608B2 jz short loc_100608D3 .text:100608B4 .text:100608B4 Here comes the inlined ExtractI4 again .text:100608B4 .text:100608B4 movzx esi, byte ptr [ecx+2] .text:100608B8 xor eax, eax .text:100608BA mov ah, [ecx] .text:100608BC mov al, [ecx+1] .text:100608BF shl eax, 8 .text:100608C2 or eax, esi .text:100608C4 movzx esi, byte ptr [ecx+3] .text:100608C8 shl eax, 8 .text:100608CB or eax, esi .text:100608CD mov [edi+0Ch], eax ; pTagData->frames = ExtractI4(buf) .text:100608D0 add ecx, 4 ; buf+=4 .text:100608D3 .text:100608D3 loc_100608D3: ; CODE XREF: GetVbrTag+E2j .text:100608D3 test dl, 2 ; if( head_flags & BYTES_FLAG ) .text:100608D6 jz short loc_100608F7 .text:100608D8 .text:100608D8 And more inlined ExtractI4 .text:100608D8 .text:100608D8 movzx esi, byte ptr [ecx+2] .text:100608DC xor eax, eax .text:100608DE mov ah, [ecx] .text:100608E0 mov al, [ecx+1] .text:100608E3 shl eax, 8 .text:100608E6 or eax, esi .text:100608E8 movzx esi, byte ptr [ecx+3] .text:100608EC shl eax, 8 .text:100608EF or eax, esi .text:100608F1 mov [edi+10h], eax ; pTagData->bytes .text:100608F4 add ecx, 4 ; buf+=4; .text:100608F7 .text:100608F7 loc_100608F7: ; CODE XREF: GetVbrTag+106j .text:100608F7 test dl, 4 ; if( head_flags & TOC_FLAG ) .text:100608FA jz short loc_10060914 .text:100608FC lea esi, [edi+18h] .text:100608FF test esi, esi ; if( pTagData->toc != NULL ) .text:10060901 jz short loc_10060911 .text:10060903 xor eax, eax .text:10060905 .text:10060905 Here comes the for-loop .text:10060905 for(i=0;i<NUMTOCENTRIES;i++) .text:10060905 .text:10060905 .text:10060905 loc_10060905: ; CODE XREF: GetVbrTag+13Fj .text:10060905 mov bl, [eax+ecx] .text:10060908 mov [esi+eax], bl ; pTagData->toc[i] = buf[i]; .text:1006090B inc eax .text:1006090C cmp eax, 64h .text:1006090F jl short loc_10060905 .text:10060911 .text:10060911 loc_10060911: ; CODE XREF: GetVbrTag+131j .text:10060911 add ecx, 64h ; buf+=NUMTOCENTRIES; .text:10060914 .text:10060914 loc_10060914: ; CODE XREF: GetVbrTag+12Aj .text:10060914 test dl, 8 ; if( head_flags & VBR_SCALE_FLAG ) .text:10060917 mov dword ptr [edi+14h], 0FFFFFFFFh ; pTagData->vbr_scale = -1; .text:1006091E jz short loc_1006093F .text:10060920 .text:10060920 More inlined ExtractI4 .text:10060920 .text:10060920 movzx eax, byte ptr [ecx+2] .text:10060924 xor edx, edx .text:10060926 mov dh, [ecx] .text:10060928 mov dl, [ecx+1] .text:1006092B shl edx, 8 .text:1006092E or edx, eax .text:10060930 movzx eax, byte ptr [ecx+3] .text:10060934 shl edx, 8 .text:10060937 or edx, eax .text:10060939 mov [edi+14h], edx ; pTagData->vbr_scale = ExtractI4(buf); .text:1006093C add ecx, 4 ; buf+=4; .text:1006093F .text:1006093F Here comes the calculation ((h_id+1)*72000*h_bitrate) / pTagData->samprate; .text:1006093F .text:1006093F loc_1006093F: ; CODE XREF: GetVbrTag+14Ej .text:1006093F lea eax, [ebp+1] .text:10060942 imul eax, [esp+10h+buf] .text:10060947 imul eax, 72000 .text:1006094D cdq .text:1006094E idiv dword ptr [edi+4] .text:10060951 add ecx, 15h ; buf+=21; .text:10060954 mov [edi+7Ch], eax ; pTagData->headersize = calculation result .text:10060957 .text:10060957 The following lines are .text:10060957 .text:10060957 enc_delay = buf[0] << 4; .text:10060957 enc_delay += buf[1] >> 4; .text:10060957 enc_padding= (buf[1] & 0x0F)<<8; .text:10060957 enc_padding += buf[2]; .text:10060957 .text:10060957 movzx eax, byte ptr [ecx+1] .text:1006095B movzx esi, byte ptr [ecx] .text:1006095E movzx ecx, byte ptr [ecx+2] .text:10060962 mov edx, eax .text:10060964 and eax, 0Fh .text:10060967 shr edx, 4 .text:1006096A shl esi, 4 .text:1006096D shl eax, 8 .text:10060970 add edx, esi .text:10060972 add eax, ecx .text:10060974 test edx, edx .text:10060976 jl short loc_10060980 ; if (enc_delay<0 .text:10060978 cmp edx, 3000 ; || enc_delay > 3000) .text:1006097E jle short loc_10060983 .text:10060980 .text:10060980 loc_10060980: ; CODE XREF: GetVbrTag+1A6j .text:10060980 or edx, 0FFFFFFFFh ; enc_delay=-1; .text:10060983 .text:10060983 loc_10060983: ; CODE XREF: GetVbrTag+1AEj .text:10060983 test eax, eax .text:10060985 jl short loc_1006098E ; if (enc_padding<0 .text:10060987 cmp eax, 3000 ; || enc_padding > 3000) .text:1006098C jle short loc_10060991 .text:1006098E .text:1006098E loc_1006098E: ; CODE XREF: GetVbrTag+1B5j .text:1006098E or eax, 0FFFFFFFFh ; enc_padding=-1; .text:10060991 .text:10060991 loc_10060991: ; CODE XREF: GetVbrTag+1BCj .text:10060991 mov [edi+84h], eax ; pTagData->enc_padding=enc_padding; .text:10060997 mov [edi+80h], edx ; pTagData->enc_delay=enc_delay; .text:1006099D pop edi .text:1006099E pop esi .text:1006099F pop ebp .text:100609A0 mov eax, 1 ; return 1; .text:100609A5 pop ebx .text:100609A6 retn .text:100609A6 GetVbrTag endp .text:100609A6 .text:100609A6 ; ---------------------------------------------------------------------------