Reverse Engineering for Beginners

(avery) #1

CHAPTER 51. C++ CHAPTER 51. C++


Some additional CPU time is needed for doing look-ups in these tables and finding the right virtual method address, thus
virtual methods are widely considered as slightly slower than common methods.


In GCC-generated code theRTTItables are constructed slightly differently.


51.2 ostream


Let’s start again with a “hello world” example, but now we are going to use ostream:


#include


int main()
{
std::cout << "Hello, world!\n";
}


Almost any C++ textbook tells us that the<<operation can be replaced (overloaded) for other types. That is what is done in
ostream. We see thatoperator<<is called for ostream:


Listing 51.18: MSVC 2012 (reduced listing)

$SG37112 DB 'Hello, world!', 0aH, 00H


_main PROC
push OFFSET $SG37112
push OFFSET ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::cout
call ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?⤦
Ç$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits >
add esp, 8
xor eax, eax
ret 0
_main ENDP


Let’s modify the example:


#include


int main()
{
std::cout << "Hello, " << "world!\n";
}


And again, from many C++ textbooks we know that the result of eachoperator<<in ostream is forwarded to the next one.
Indeed:


Listing 51.19: MSVC 2012

$SG37112 DB 'world!', 0aH, 00H
$SG37113 DB 'Hello, ', 00H


_main PROC
push OFFSET $SG37113 ; 'Hello, '
push OFFSET ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::cout
call ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?⤦
Ç$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits >
add esp, 8


push OFFSET $SG37112 ; 'world!'
push eax ; result of previous function execution
call ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?⤦
Ç$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
add esp, 8

xor eax, eax
ret 0
_main ENDP


If we would renameoperator<<method name tof(), that code will looks like:

Free download pdf