Reversing : The Hacker's Guide to Reverse Engineering

(ff) #1
00401042 mov [eax+0xc],ecx
00401045 mov [eax+0x10],ecx
00401048 mov [eax+0x14],ecx
0040104b mov ecx,esi
0040104d mov esi,[esp+0xc]
00401051 mov edx,ecx
00401053 mov [eax],edi
00401055 shr ecx,0x2
00401058 lea edi,[eax+0x18]
0040105b rep movsd
0040105d mov ecx,edx
0040105f and ecx,0x3
00401062 rep movsb
00401064 pop edi
00401065 pop esi
00401066 ret

The important thing about this version of allocate_objectis the sup-
plied buffer length’s data type. When reading assembly language code, you
must always be aware of every little detail—that’s exactly where all the valu-
able information is hidden. See if you can find the difference between this
function and the earlier version.
It turns out that this function is treating the buffer length as a signed
short. This creates a potential problem because in C and C++ the compiler
doesn’t really care what you’re doing with an integer—as long as it’s defined
as signedand it’s converted into a longer data type, it will be sign extended,
no matter what the target data type is. In this particular example, malloc
takes a size_t, which is of course unsigned. This means that the buffer
length would be sign extended before it is passed into mallocand to the code
that adds 0x18to it. Here is what you should be looking for:


00401022 movsx esi,word ptr [esp+0xc]

This line copies the parameter from the stack into ESI, while treating it as a
signed shortand therefore sign extendsit. Sign extending means that if the
buffer length parameter has its most significant bit set, it would be converted
into a negative 32-bit number. For example, a buffer length of 0x9400(which
is 37888 in decimal) would become 0xffff9400 (which is 4294939648 in dec-
imal), instead of 0x00009400.
Generally, this would cause an overflow bug in the allocation size and the
allocation would simply fail, but if you look carefully you’ll notice that this
problem also brings back the bug looked at earlier, where adding the header size
to the user-supplied buffer length causedan overflow. That’s because the MOVSX
instruction can generate the same large negative values that were causing the
overflow earlier. Consider a case where the function is fed 0xfff8as the buffer
length. The MOVSXinstruction would convert that into 0xfffffff8, and you’d


Auditing Program Binaries 261
Free download pdf