object oriented concepts newbie
i’ve decided to ditch java and tackle c++ and c# this summer!
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.

avoid (void) in c++. use () instead. even K&R finds this weird.
use initialization lists over assignment if possible.
it doesn’t help here at the moment since the value you’re passing is a built-in/intrinsic type. when you start passing objects then it gets interesting. the compiler will create a temporary copy of that object before assignment. so it’s a good idea to get into the habit of using initialization lists. just my 2 cents
sheep::sheep() : offspring(0) {}
sheep::sheep(int x) : offspring(x) { … }
in c#, there’s properties. stuff like get_offspring() or set_offspring(int x) can be written as:
public int OffSpring
{
get { return offspring; }
set { offspring = value; }
}
then you do:
x = obj->OffSpring;
obj->OffSpring = x;
anyways, i would love to do straight C again. if you really want to do C, go for motorola. they do a lot embedded stuff written in C. they’re always looking for fresh graduates over here but not sure back there.
goodluck and talk to you soon.
Comment by xevuz — March 31, 2007 @ 2:21 pm
wow! this is nice! actually, at first i was wondering what “part” of your code is are you referring as “initialization lists”! hahaha but this is some neat stuff you tipped me! =) i’m using them always now =) hehehehe
Comment by sleepy jenkins — April 5, 2007 @ 10:41 am