Skip to Content.
Sympa Menu

freetds - RE: [freetds] RPC/Packet Type 3 Format

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "Lowden, James K" <LowdenJK AT bernstein.com>
  • To: 'FreeTDS Development Group' <freetds AT lists.ibiblio.org>
  • Subject: RE: [freetds] RPC/Packet Type 3 Format
  • Date: Fri, 18 Jul 2003 17:42:39 -0400

> From: lists-tds AT mymailfilter.net [mailto:lists-tds AT mymailfilter.net]
> Sent: July 18, 2003 11:06 AM
>
> declare @a char(1)
> set @a = 'x'
> exec foo @a output
...
> declare @a char(1)
> set @a = 'A'
> exec foo @a output

I ran your message through this, to lay out each block as a line:

$ grep ^0 Format.txt \
|cut -b1-53 \
|perl -ne'chop; ($l, $h)=split / /;
print $/ if $l lt $pre;
print "$h|";
$pre=$l;'

If you ignore the first 16 * 3 + 6 = 54 bytes, you arrive at the 03 RPC
token. Among all the queries you sent, the "prefix" varies in just three
places. One is the length, right after the 03 token and the 01 status flag.
The other two are both in the "0060" block:

$ grep -n ^0060 Format.txt |cut -b1-58
19:0060 6c 00 00 00 09 04 00 01 32 6c 00 00 00 64 00 65
39:0060 6c 00 00 00 09 04 00 01 32 6c 00 00 00 64 00 65
59:0060 5e 00 00 00 09 04 00 01 32 5e 00 00 00 64 00 65
85:0060 6e 00 00 00 09 04 00 01 32 6e 00 00 00 64 00 65
105:0060 7a 00 00 00 09 04 00 01 32 7a 00 00 00 64 00 65
134:0060 a8 00 00 00 09 04 00 01 32 a8 00 00 00 64 00 65
173:0060 46 01 00 00 09 04 00 01 32 46 01 00 00 64 00 65
^^ ^^ ^^ ^^

It looks to me like a length of some kind:

$ grep -n ^0060 Format.txt \
|cut -b1-58 \
|perl -ne '($a, $lb, $hb, $x) = split;
$len= eval("0x$hb$lb");
printf "%d: $hb$lb (%3d): %5d (0x%0x)\n",
++$i, $len,
($len - $pre), ($len - $pre);
$pre = $len'
1: 006c (108): 108 (0x6c)
2: 006c (108): 0 (0x0)
3: 005e ( 94): -14 (0xfffffff2)
4: 006e (110): 16 (0x10)
5: 007a (122): 12 (0xc)
6: 00a8 (168): 46 (0x2e)
7: 0146 (326): 158 (0x9e)

The output is the query number, the little endian value of bytes 60-61h, a
colon, and how much bigger it is than the prior query's. IOW, query #3 has a
value at offset 0x60 of 0x5e, which is 14 less than the 0x6c in queries #1
and #2.

You will note that these numbers correspond exactly to the differences in
the lengths of the blocks you sent. Query #4 is in fact 16 bytes longer
than #3, etc.

OK, so what's 108 bytes in #1 and 95 bytes in #3? Sure enough, the query
size. Here's #3 again:

0000 00 08 7c c2 42 c2 00 03 47 8b 23 05 08 00 45 00 ..|.B...G.#...E.
0010 00 c6 84 bc 40 00 80 06 1f c9 0a 00 2c 4c 0a 00 ....@.......,L..
0020 15 61 07 e3 05 99 ea 2b b1 2e bf e3 8a 0c 50 18 .a.....+......P.
0030 fa a9 4b 1b 00 00
(start of packet) --> 03 01 00 9e 00 00 01 00 ff ff ..K.............
0040 0b 00 00 00 00 01 26 04 04 ff ff ff ff 00 00 63 ......&........c
0050 00 00 00 00 09 04 00 01 32 ff ff ff ff 00 00 63 ........2......c
0060 5e 00 00 00 09 04 00 01 32 5e 00 00
(start of query) --> 00 64 00 65 ^.......2^...d.e
0070 00 63 00 6c 00 61 00 72 00 65 00 20 00 40 00 61 .c.l.a.r.e. .@.a
0080 00 20 00 63 00 68 00 61 00 72 00 28 00 31 00 29 . .c.h.a.r.(.1.)
0090 00 0d 00 0a 00 73 00 65 00 74 00 20 00 40 00 61 .....s.e.t. .@.a
00a0 00 20 00 3d 00 20 00 27 00 41 00 27 00 0d 00 0a . .=. .'.A.'....
00b0 00 65 00 78 00 65 00 63 00 20 00 66 00 6f 00 6f .e.x.e.c. .f.o.o
00c0 00 20 00 40 00 61 00 0d 00 0a
(start of trailer) --> 00 00 00 26 04 04 . .@.a.......&..
00d0 01 00 00 00 ....

I'm not sure what the byte order really is, whether the query begins or ends
with a NULL, but regardless the query text is 0x5e (94) bytes long.

The trailing bytes:

00 00 00 26 04 04 01 00 00 00

are also invariant among these queries.

What other conclusions can we draw?

The first two queries:

> declare @a char(1) set @a = 'x' exec foo @a output
> declare @a char(1) set @a = 'A' exec foo @a output

differ only by input. As far as ADO is concerned, @a isn't a variable but a
piece of text. Consequently, the prefixes and trailers are identical.
Perhaps a variety of placeholders would yield up more differences. Maybe an
RPC to a "linked" server or an ad-hoc data source ("SELECT * FROM
OPENROWSET") would employ them.

Thanks for the data, Jeff. I hope I'm being some use to you. So far, we
haven't found much interesting, but that's not too surprising. TDS has a
lot of "magic" bytes that don't do anything as far as we know. We start off
guessing and work from there.

Regards,

--jkl
-----------------------------------------
The information contained in this transmission may contain privileged and
confidential information and is intended only for the use of the person(s)
named above. If you are not the intended recipient, or an employee or agent
responsible for delivering this message to the intended recipient, any
review, dissemination, distribution or duplication of this communication is
strictly prohibited. If you are not the intended recipient, please contact
the sender immediately by reply e-mail and destroy all copies of the original
message. Please note that we do not accept account orders and/or instructions
by e-mail, and therefore will not be responsible for carrying out such orders
and/or instructions.






Archive powered by MHonArc 2.6.24.

Top of Page