Martin Haag on Fri Sep 23 23:20:38 UTC 2005
>Hi,
>
>I've recorded some USB traffic with SniffUSB from the Medion MD6190
>scanner tonight. I am going to analyse them in the near future, but if
>one can't wait the scans are available on
>http://mibix.de/wiki/index.php/MD6190_USB_Recording .

Great recordings! Very similar to the ones from CanoScan 3200F.
The most important to me was scan5 that contained the firmware
upload. The code is similar to the CanoScan code, but not
identical. Interestingly enough, the code contains string descriptors
that say it is Canon/CanoScan :).

>By the way, maybe someone can give me some hints how to analyse such a
>huge amount of data :) I thought about comparing always two of the
>files with a block orientated compare tool such as beyond compare on
>wind-ws.  ( hm I can't belive that I sayed this. Ok let's use diff *g*
>)

A good start is a text log filter that reduces the data to more manageable
form, like one here:
---- snip ---- snip ---- snip ---
#!perl

$newimage = 1;
$image = 0;
$imagect = 0;
%pipe2ep = ();

while ( <> ) {
    if ( /UsbSnoop/ ) {
        next;
    }
    if ( /Driver/ ) {
        next;
    }
    if ( /Pipes\[(.)\] : PipeHandle\s+= 0x(........)/ ) {
        if ( $pipe_number == $1 ) {
            $pipe2ep{ $2 } = $endpoint_address;
#            print( "handle $2 endpoint $endpoint_address\n" );
        }
        next;
    }
    if ( /Pipes\[(.)\] : EndpointAddress\s+= 0x(..)/ ) {
        $pipe_number = $1;
        $endpoint_address = $2;
        next;
    }
    if ( /^[0-9]{8}\s+([0-9]+\.[0-9]{8})\s+([<>]).*URB *([0-9]+)/ ) {
        $t = $1;
        $d = $2;
        $u = $3;
        $type = <>;
        $type =~ /([A-Z_]+)/;
        $type = $1;
        
#        print "$d $type\n";

        if ( $type eq "URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER" ) {
            $endp = <>;
            $endp =~ /= (........)/;
            $endp = $pipe2ep{$1};
            $tbuflen = <>; #read one line off
            $tbuflen = <>;
            $tbuflen =~ /TransferBufferLength = (........)/;
            $tbuflen = $1;
            $dir = ( ( hex($endp) & 0x80 ) == 0 ) ? "o" : "i";
            $dd = ( ( hex($endp) & 0x80 ) == 0 ) ? ">" : "<";
            if ( $d ne $dd ) {
                next;
            }
            if ( $newimage == 1 && $image == 1 ) {
                $imagect++;
                $newimage = 0;
            }
            if ( $image == 0 ) {
                $fname = sprintf "%04d$dir.bin", $u;
            }
            else {
                $fname = sprintf "image%02d.bin", $imagect;
            }
            printf "%012.8f/%012.8f:%04d B$dd ep=$endp tl=$tbuflen 
fn=\"$fname\"\n",
                   $t,0,$u;
            open DF, ">>$fname";
            binmode DF;
            while ( <> ) {
                if ( /TransferBufferMDL/ ) {
                    last;
                }
            }
            while ( <> ) {
                next if ( /^[0-9]{8}\s+[0-9]+\.[0-9]{8}\s+$/ );
                next if ( /^[0-9]{8}\s+[0-9]+\.[0-9]{8}\s+[[:xdigit:]]{4}:\s$/ 
);
                last if ( /UrbLink/ );
                /^[0-9]{8}\s+[0-9]+\.[0-9]{8}\s+([[:xdigit:]]{2})\s$/;
                print DF pack "C", hex $1;
            }
            close DF;
            next;
        }


        if ( $d eq ">" ) {
            $td = $t;
            $urb = $u;
            $tyd = $type;
            if ( $type eq "URB_FUNCTION_ABORT_PIPE" ) {
                $endp = <>;
                $endp =~ /endpoint 0x000000(..)/;
                $endp = $1;
            }
            elsif ( $type eq "URB_FUNCTION_RESET_PIPE" ) {
                $endp = <>;
                $endp =~ /endpoint 0x000000(..)/;
                $endp = $1;
            }
            elsif ( $type eq "URB_FUNCTION_SELECT_CONFIGURATION" ) {
                while ( <> ) {
                    if ( /iConfiguration *= 0x(..)/ ) {
                        $conf = $1;
                        last;
                    }
                }
            }
            elsif ( $type eq "URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE" ) {
                while ( <> ) {
                    if ( /DescriptorType *= (..) \(([^)]+)\)/ ) {
                        $dtype = $1;
                        $dname = $2;
                        last;
                    }
                }
            }
            elsif ( $type eq "URB_FUNCTION_VENDOR_DEVICE" ) {
                $vdata = "";
                while ( <> ) {
                    if ( /TransferFlags *= 000000(..)/ ) {
                        $tf = $1;
                    }
                    elsif ( /TransferBufferLength = 0000(....)/ ) {
                        $tbl = $1;
                    }
                    elsif ( /RequestTypeReservedBits = (..)/ ) {
                        $rt = $1
                    }
                    elsif ( /Request *= (..)/ ) {
                        $rq = $1
                    }
                    elsif ( /Value *= (....)/ ) {
                        $vl = $1;
                    }
                    elsif ( /Index *= (....)/ ) {
                        $ix = $1;
                        last;
                    }
                    elsif ( /^[0-9]{8}\s+[0-9]+\.[0-9]{8}\s+( 
[[:xdigit:]]{2})\s$/ ) {
                        $vdata .= $1;
                    }
                }
            }
        }
        elsif ( $d eq "<" ) {
            $tb = $t;
            $tyu = $type;
            if ( $type eq "URB_FUNCTION_ABORT_PIPE" ) {
                printf "%012.8f/%012.8f:%04d AP ep=%s\n",$td,$tb,$urb,$endp; 
            }
            elsif ( $type eq "URB_FUNCTION_RESET_PIPE" ) {
                printf "%012.8f/%012.8f:%04d RP ep=%s\n",$td,$tb,$urb,$endp; 
            }
            elsif ( $type eq "URB_FUNCTION_SELECT_CONFIGURATION" ) {
                printf "%012.8f/%012.8f:%04d SC cf=%s\n",$td,$tb,$urb,$conf; 
            }
            elsif ( $tyd eq "URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE" ) {
                $ddata = "";
                while ( <> ) {
                    if ( /TransferBufferLength *= 0000(....)/ ) {
                        $tbl = $1;
                    }
                    elsif ( /^[0-9]{8}\s+[0-9]+\.[0-9]{8}\s+( 
[[:xdigit:]]{2})\s$/ ) {
                        $ddata .= $1;
                    }
                    elsif( /SetupPacket/ ) {
                        printf "%012.8f/%012.8f:%04d ", $td,$tb,$urb;
                        # print "GD $dtype ($dname) bl=$tbl ";
                        print "GD ty=$dtype bl=$tbl ";
                        print "dt=$ddata\n";
                        last;
                    }
                }
            }
            elsif ( $tyd eq "URB_FUNCTION_VENDOR_DEVICE" ) {
                while ( <> ) {
                    if ( /^[0-9]{8}\s+[0-9]+\.[0-9]{8}\s+( [[:xdigit:]]{2})\s$/ 
) {
                        $vdata .= $1;
                    }
                    elsif( /SetupPacket/ ) {
                        printf "%012.8f/%012.8f:%04d ",$td,$tb,$urb;
                        if ( $tf == 0 ) {
                            print "> ";
                        }
                        else {
                            print "< ";
                        }
                        print "rt=$rt rq=$rq vl=$vl ix=$ix bl=$tbl ";
                        print "dt=$vdata\n";

                        $image = ( $vl eq '0030' ) ? 1 : 0;
                        $newimage = 1;

                        last;
                    }
                }
            }
        }
    }
}
---- snip ---- snip ---- snip ---
(I have a different version of the snooper so I quickly modified my earlier
script. This looks like it works OK but there may be problems with
some logs. Let me know and I will make a fix.)

It eats the text logs and outputs a reduced info about the USB transfers
one info per line, like from scan5.txt:
---
000.00297971/000.00818260:0001 GD ty=01 bl=0012 dt= 12 01 10 01 ff ff ff 40 61 
04 7b 03 01 01 00 01 00 01
000.00862316/000.01213450:0002 GD ty=02 bl=0009 dt= 09 02 27 00 01 01 00 c0 00
000.01244879/000.01812912:0003 GD ty=02 bl=0027 dt= 09 02 27 00 01 01 00 c0 00 
09 04 00 00 03 ff ff ff 00 07 05 81 02 40 00 00 07 05 02 02 40 00 00 07 05 83 
03 08 00 10
000.01872640/000.08083681:0004 SC cf=00
000.64165837/000.64507890:0005 < rt=c0 rq=04 vl=0040 ix=0000 bl=0004 dt= 00 00 
00 0c
000.64541441/000.64903808:0006 > rt=40 rq=0c vl=0040 ix=0000 bl=0001 dt= 00
000.64928669/000.65303522:0007 < rt=c0 rq=0c vl=00e1 ix=ffe2 bl=0001 dt= 00
000.65331542/000.65703434:0008 < rt=c0 rq=0c vl=00e1 ix=ffed bl=0001 dt= 03
000.65731204/000.66103399:0009 > rt=40 rq=04 vl=00e0 ix=ffed bl=0002 dt= 03 00
000.66208053/000.66605645:0010 < rt=c0 rq=04 vl=0040 ix=0000 bl=0004 dt= 00 00 
00 0c
000.66637242/000.67003375:0011 > rt=40 rq=04 vl=00f0 ix=0000 bl=0005 dt= 00 00 
00 00 00
000.67027485/000.67403316:0012 < rt=c0 rq=04 vl=0040 ix=0000 bl=0004 dt= 00 00 
00 0c
000.67433429/000.67802721:0013 > rt=40 rq=04 vl=00f3 ix=0000 bl=0004 dt= 00 41 
00 00
000.67828929/000.00000000:0014 B> ep=02 tl=00008200 fn="0014o.bin"
001.20546997/001.20900762:0015 < rt=c0 rq=04 vl=0040 ix=0000 bl=0004 dt= 00 00 
00 0c
...
---
GD is get descriptor, SC is select configuration,
< indicates control read, > a control write B> a bulk write ect.
In addition it extracts the bulk transfers to files in binary form
so the images can be extracted there. None of the files contained
any image data, though, so I could not test that.
The bulk transfers to the scanner are mostly some kind of configuration
parameters and curves (gamma, mask etc.) which I call mystery files
and try to figure out from the firmware. I am not that far yet, though.

With best regards,

Lauri Pirttiaho
Oulu
Finland


...................................................................
Luukku Plus paketilla p??set eroon tila- ja turvallisuusongelmista.
Hanki Luukku Plus ja helpotat el?m??si. http://www.mtv3.fi/luukku
From [email protected]  Sat Sep 24 23:31:16 2005
From: [email protected] (Bertrik Sikken)
Date: Sat Sep 24 23:31:44 2005
Subject: [sane-devel] USB recordings MD6190 available
In-Reply-To: <[email protected]>
References: <[email protected]>
Message-ID: <[email protected]>

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Martin Haag wrote:
>> Hi,
>>
>> I've recorded some USB traffic with SniffUSB from the Medion MD6190
>> scanner tonight. I am going to analyse them in the near future, but if
>> one can't wait the scans are available on
>> http://mibix.de/wiki/index.php/MD6190_USB_Recording .
>>
>> By the way, maybe someone can give me some hints how to analyse such a
>> huge amount of data  :)  I thought about comparing always two of the
>> files with a block orientated compare tool such as beyond compare on
>> wind-ws.  ( hm I can't belive that I sayed this. Ok let's use diff *g*


Using a text editor grep, sort and uniq helps a lot already  :)  ...

It seems to me, that in the USB control messages, the 'value' is some
kind of command or register index.
So far, I've seen commands 0023, 0024, 002b, 002c, 002d, 0040, 0050,
0071, 00b0, 00d0, 00e0, 00e1, 00f0, 00f3 and 00f4.
For some commands, apparently the 'index' is also used, this is the
case for commands 002b, 002c, 00e0 and 00e1.

Command 002d appears to be a status register for button presses:
0 = no button, 1 = print, 2 = mail, 3 = user, 4 = ocr and 5 = scan.

Command 0040 seems to be a generic status inquiry command, which returns
4 bytes. Bytes 2 and 3 of this seem some kind of counter (line
number perhaps? or buffer level?)
(There is also a write to register 0040 that I cannot explain yet)

Commands 00E0 and 00E1 seem to complement each other. Command 00E0
is used for writing data while command 00E1 is used to read data
back. Perhaps some sub-system in the scanner, like the analog
front-end?

I think command 00F0 sets the address for transfer from/to internal
RAM and commands 00F3 and 00F4 prepare the scanner to read or
write bulk data, where the command data encodes the number of
16-bit words to transfer.

I have not been able to identify the command that sets the
scan area settings, although the data sent with command 0050
contains the numbers 2400 and 12000 which looks like some sort
of resolution setting.

Regards,
Bertrik
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (MingW32)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFDNeHEETD6mlrWxPURAgnHAJ9gmSyMc7P+/ctO9WLhrbUN53LS7wCfTQ69
HzJ74mcVeRjSaSXZ+Ys3jKs=
=ObJQ
-----END PGP SIGNATURE-----

Reply via email to