in the name of zero

March 31, 2007

object oriented concepts newbie

Filed under: hermetic studies

i’ve decided to ditch java and tackle c++ and c# this summer!

“A single question can be more influential than a thousand statements.”
Bo Bennett

by some malevolent influence yesterday, i found myself looking for c plus plus object oriented programming tutorials. i made steady progress for a few minutes until after my nth compilation. got sidetracked when i realized that i haven’t actually encountered any c++ crackmes at the usual place.

so i’m posting my experiments here in the hopes of finding someone to point me to some related articles on the subject matter.

void __attribute__ ((constructor)) myctor()
{
        cout<<"--- little red riding hood goes to the farm ---\n";
}
	
void __attribute__ ((destructor)) mydtor()
{
        cout<<"--- little red riding hood  goes home ---\n";
}
	
class sheep {
        int offspring;
	
        public:
                sheep(void);
                sheep(int);
                ~sheep(void);
                int get_offspring(void);
};
	
sheep::sheep(void)
{
        offspring = 0;
}
	
sheep::sheep(int x)
{
        cout<<"mommy sheep is having sex with daddy sheep\n";
        offspring = x;
}
	
sheep::~sheep(void)
{
        cout<<"mommy sheep dies after giving birth\n";
}
	
int sheep::get_offspring(void)
{
        return offspring;
}
	
int main(int t, char **c)
{
        sheep philippine_sheep(5);
	
        cout<<"they have "<<philippine_sheep.get_offspring()<<" babies\n";
	
        cout<<"\n\tgoddamn i feel like a chump!\n";
	
        return 0;
}

“so what’s it like under the hood?” i was curious so i peeked a little.

the first thing i noticed (thru “strings”) is that it uses libstdc++.so and not libc.so it’s rather easy to figure out judging from the filenames alone. then from what i saw at objdump, the procedure linkage table is totally different from that of a c binary. it also bother me a bit that i couldn’t find “cout” anywhere… i moved along. (i discovered something about it later though)

before going further, i used objdump –demangle to make reading more convenient.

entry startup is familiar as it’s still the usual libc startup i’ve encountered many times. push registers, envp, argv, argc .. and then jump to libc_start_main(). before jumping to main(), i browsed a little bit and saw the disassembly of the class methods i made. so far so good.

my first question goes how come there are two (2) declarations of each method!? disassembly below:

0804881c <sheep::sheep()>:
 804881c:       55                      push   ebp
 804881d:       89 e5                   mov    ebp,esp
 804881f:       8b 45 08                mov    eax,DWORD PTR [ebp+8]
 8048822:       c7 00 00 00 00 00       mov    DWORD PTR [eax],0x0
 8048828:       c9                      leave
 8048829:       c3                      ret    
	
0804882a <sheep::sheep()>:
 804882a:       55                      push   ebp
 804882b:       89 e5                   mov    ebp,esp
 804882d:       8b 45 08                mov    eax,DWORD PTR [ebp+8]
 8048830:       c7 00 00 00 00 00       mov    DWORD PTR [eax],0x0
 8048836:       c9                      leave
 8048837:       c3                      ret    

this is where it started getting interesting.

instantiating a class seems like lots of work. in my program, i used the overloaded constructor which takes an int parameter.

 ; sheep philippine_sheep(5);
	
 80487de:       6a 05                   push   0x5		; constructor argument
 80487e0:       8d 45 e8                lea    eax,[ebp-24]	; addr of object
 80487e3:       50                      push   eax		; push addr of object as well
 80487e4:       e8 75 ff ff ff          call   804875e <sheep::sheep(int)> ; call the class constructor. (right?)
 

i followed sheep::sheep(int) … again, there are two declarations of this.

0804875e <sheep::sheep(int)>:
 804875e:       55                      push   ebp
 804875f:       89 e5                   mov    ebp,esp		; prolog
 8048761:       83 ec 08                sub    esp,0x8
 8048764:       83 ec 08                sub    esp,0x8		; 0x10 space
 8048767:       68 c0 8a 04 08          push   0x8048ac0	; "mommy sheep is having sex..."
 804876c:       68 b8 9e 04 08          push   0x8049eb8	; cout@glibcpp
 8048771:       e8 5a fe ff ff          call   80485d0		; std::basic_ostream....
 8048776:       83 c4 10                add    esp,0x10		; cleanup
 8048779:       8b 55 08                mov    edx,DWORD PTR [ebp+8]	; main() local var...
 804877c:       8b 45 0c                mov    eax,DWORD PTR [ebp+12]	; constructor argument (5)
 804877f:       89 02                   mov    DWORD PTR [edx],eax	; save it inside the object
 8048781:       c9                      leave  				; epilog
 8048782:       c3                      ret    				; return to callee
 8048783:       90                      nop				; no operation

i learned two things here. first is that i found out that “cout” is not being called directly. (perhaps other functions as well)

Disassembly of section .bss:
	
08049eb8 <std::cout@@GLIBCPP_3.2>:

the second is how an object’s variables are being handled (basically). to verify, i ran gdb.

gdb $ hb *0x080487e4
	
gdb $ r
--- little red riding hood goes to the farm ---
Breakpoint 1, 0x080487e4 in main ()
	
gdb $ nexti
mommy sheep is having sex with daddy sheep
0x080487e9 in main ()
	
gdb $ reg
     eax:00000005 ebx:B7EE0FF4  ecx:0000000A  edx:BFFE9450     eflags:00000282
     esi:B7FEDC80 edi:BFFE94C4  esp:BFFE9430  ebp:BFFE9468     eip:080487E9
     cs:0073  ds:007B  es:007B  fs:0000  gs:0000  ss:007B    o d I t S z a p c 
	
gdb $ x/x $edx
0xbffe9450:     0x00000005

i guess that wraps my first few steps in larning object oriented programming. will post more as soon as able.

Get free blog up and running in minutes with Blogsome | Theme designs available here