Reverse Engineering for Beginners

(avery) #1

CHAPTER 21. STRUCTURES CHAPTER 21. STRUCTURES


#include <assert.h>
#include <stdlib.h>
#include <memory.h>


struct float_as_struct
{
unsigned int fraction : 23; // fractional part
unsigned int exponent : 8; // exponent + 0x3FF
unsigned int sign : 1; // sign bit
};


float f(float in)
{
float f=in;
struct float_as_struct t;


assert (sizeof (struct float_as_struct) == sizeof (float));

memcpy (&t, &f, sizeof (float));

t.sign=1; // set negative sign
t.exponent=t.exponent+2; // multiply d by 2 n (n here is 2)

memcpy (&f, &t, sizeof (float));

return f;
};


int main()
{
printf ("%f\n", f(1.234));
};


Thefloat_as_structstructure occupies the same amount of memory asfloat, i.e., 4 bytes or 32 bits.


Now we are setting the negative sign in the input value and also, by adding 2 to the exponent, we thereby multiply the
whole number by 22 , i.e., by 4.


Let’s compile in MSVC 2008 without optimization turned on:


Listing 21.27: Non-optimizing MSVC 2008

_t$ = -8 ; size = 4
_f$ = -4 ; size = 4
__in$ = 8 ; size = 4
?f@@YAMM@Z PROC ; f
push ebp
mov ebp, esp
sub esp, 8


fld DWORD PTR __in$[ebp]
fstp DWORD PTR _f$[ebp]

push 4
lea eax, DWORD PTR _f$[ebp]
push eax
lea ecx, DWORD PTR _t$[ebp]
push ecx
call _memcpy
add esp, 12

mov edx, DWORD PTR _t$[ebp]
or edx, -2147483648 ; 80000000H - set minus sign
mov DWORD PTR _t$[ebp], edx

mov eax, DWORD PTR _t$[ebp]
shr eax, 23 ; 00000017H - drop significand
and eax, 255 ; 000000ffH - leave here only exponent
add eax, 2 ; add 2 to it
and eax, 255 ; 000000ffH
shl eax, 23 ; 00000017H - shift result to place of bits 30:23
Free download pdf