CiklumCPPSat24032012:ArtyomBondartsov-MicrosoftDetours&GoogleMockForC++InDevelopmentUsingReverseEngineering...

Preview:

DESCRIPTION

 

Citation preview

Bondartsov Artyom,Ciklum

Microsoft Detours and

Google Mock for C++ in development

using reverse engineering

Цели

•Библиотеки detour и gmock

•Есть проблемка с телепортацией... ©The Big Bang Theory

Что такое Detours?

Detours

Detours

Принцип работы

Caller function

Принцип работыDetours

Your function

Callee function

Caller prolog*

Caller function

Принцип работыDetours

Your function

Callee function

Caller prolog*

* - replaced by unconditional jump original instructions

Caller function

Принцип работыDetours

Your function

Callee function

Caller prolog*

* - replaced by unconditional jump original instructions

Принцип работыDetours

… CalleeFunction: jmp YourFunction

CalleeFunction+5: push edi … Prolog: push ebp mov ebp,esp push ebx push esi jmp CalleeFunction+5

… CalleeFunction: push ebp mov ebp,esp push ebx push esi push edi …

Detours

Обзор

ОбзорDetours

•Статические

•Динамические

Трамплины*:

* - пролог

ОбзорDetours

Статический

ОбзорDetours Статический пролог

#include <windows.h> #include <detours.h>

DETOUR_TRAMPOLINE( void WINAPI SleepTrampoline( DWORD ), Sleep ); void WINAPI SleepDetour( DWORD dw ) { return SleepTrampoline( dw ); } void main( ) { DetourFunctionWithTrampoline( ( PBYTE )SleepTrampoline, ( PBYTE )SleepDetour); Sleep( 0 ); DetourRemove( ( PBYTE )SleepTrampoline, ( PBYTE )SleepDetour); }

* - обращайте внимание на соглашения о вызове

ОбзорDetours

Динамический

ОбзорDetours Динамический пролог

#include <windows.h> #include <detours.h>

typedef void (WINAPI *SleepType)( DWORD );static SleepType SleepTrampoline = 0;

void WINAPI DynamicSleep( DWORD dw ) { return SleepTrampoline( dw ); } void main( ) { SleepTrampoline = ( SleepType )DetourFunction( (PBYTE)Sleep, ( PBYTE )DynamicSleep ); Sleep( 0 ); DetourRemove( (PBYTE)SleepTrampoline, ( PBYTE )DynamicSleep ); }

*-обращайте внимание на соглашения о вызове

ОбзорDetours

Еще Detours “умеет внедрение”

Detours

Detours

9.999 / 64

Detours

ДемонстрацияЗапуск своего кода в контексте IDA Pro

Google mock

Что такое Gmock?

Google mock

•Mock класс

•Ожидания

•Действия

•Совпадения

Google mock

Mock класс

Google mock Mock класс

•MOCK_METHODn

•MOCK_CONST_METHODn

•MOCK_METHODn_T

•MOCK_CONST_METHODn_T

Объявляется:

Google mock

•Виртуальные методы

•Невиртуальные методы

•Свободные функции

•Шаблоны классов

Use cases:

Mock класс

Google mock Виртуальные методы

struct Foo { virtual bool Transform( Gadget* g ) = 0;

protected: virtual void Resume();

private: virtual int GetTimeOut();};

struct MockFoo : public Foo { MOCK_METHOD1( Transform, bool( Gadget* g ) ); MOCK_METHOD0( Resume, void() ); MOCK_METHOD0( GetTimeOut, int() );};

*- mock-методы в секции public

Mock класс

Google mock

•Виртуальные методы

•Невиртуальные методы

•Свободные функции

•Шаблоны классов

Use cases:

Mock класс

Google mock Невиртуальные методы

*- AppendPacket отстутствует

struct ConcretePacketStream { void AppendPacket( Packet* packet ); const Packet* GetPacket( size_t number) const; size_t NumberOfPackets() const;};

struct MockPacketStream { MOCK_CONST_METHOD1( GetPacket, const Packet*( size_t number) ); MOCK_CONST_METHOD0( NumberOfPackets, size_t() );};

Mock класс

Google mock

•Виртуальные методы

•Невиртуальные методы

•Свободные функции

•Шаблоны классов

Use cases:

Mock класс

Google mock

•Виртуальные методы

•Невиртуальные методы

•Свободные функции

•Шаблоны классов

Use cases:

Mock класс

Google mock Шаблоны классов

*- обратите внимание на _T

template < typename Elem >struct StackInterface { virtual ~StackInterface();

virtual int GetSize() const = 0; virtual void Push( const Elem& x ) = 0;};

template < typename Elem >struct MockStack : public StackInterface< Elem > { MOCK_CONST_METHOD0_T( GetSize, int() ); MOCK_METHOD1_T( Push, void( const Elem& x ) );};

Mock класс

Google mock

Ожидания

Google mock

EXPECT_CALL( mock_object, method( matchers ) ) .Times( cardinality ) .WillOnce( action ) .WillRepeatedly( action );

Ожидания

Google mock

EXPECT_CALL( turtle, Forward( _ ) ); EXPECT_CALL( turtle, Forward( 10 ) ) .Times( 2 );

*- ожидания просматриваются в порядке обратном их объявлению

Ожидания

Google mock

Действия

Google mock

•Возвращают значение

•Побочные эффекты

•Функция как действие

•Составное действие

•ACTION макрос

Действия

Google mock

struct MockFoo : public Foo { MOCK_METHOD0( GetBar, Bar&() ); MOCK_METHOD1( Calculate, int( int ) );};...MockFoo foo;Bar bar;EXPECT_CALL( foo, GetBar() ) .WillOnce( ReturnRef( bar ) );EXPECT_CALL(foo, Calculate( 10 ) ) .WillOnce( ReturnArg< 0 >( ) );

Возвращают значениеДействия

Google mock

•Возвращают значение

•Побочные эффекты

•Функция как действие

•Составное действие

•ACTION макрос

Действия

Google mock

struct MockMutator : public Mutator { MOCK_METHOD2( Mutate, void( bool mutate, int* value ) );};...MockMutator mutator;EXPECT_CALL( mutator, Mutate( true, _ ) ) .WillOnce( SetArgPointee< 1 >( 5 ) );

Побочные эффектыДействия

Google mock

•Возвращают значение

•Побочные эффекты

•Функция как действие

•Составное действие

•ACTION макрос

Действия

Google mock

struct MockFoo : public Foo { MOCK_METHOD1( ComplexJob, bool( int x ) );};struct Helper { bool ComplexJob( int x );};...MockFoo foo;Helper helper;EXPECT_CALL( foo, ComplexJob( _ ) ) .WillOnce( Invoke( &helper, &Helper::ComplexJob ) );

Функция как действиеДействия

Google mock

•Возвращают значение

•Побочные эффекты

•Функция как действие

•Составное действие

•ACTION макрос

Действия

Google mock

struct MockMutator : public Mutator { MOCK_METHOD1( MutateInt, bool( int* value ) );};...MockMutator mutator;EXPECT_CALL( mutator, MutateInt( _ ) ) .WillOnce( DoAll( SetArgPointee< 0 >( 5 ),

Return( true ) ) );

Составное действиеДействия

Google mock

•Возвращают значение

•Побочные эффекты

•Функция как действие

•Составное действие

•ACTION макрос

Действия

Google mock

ACTION_P( Add, n ) { return arg0 + n; }

EXPECT_CALL( foo, Calc( 10 ) ) .WillOnce( ReturnAdd( 5 ) );

ACTION макросДействия

Google mock

Совпадения

Google mock

foo.DoThat( “Hello”, 5 );

Совпадения

Google mock

EXPECT_CALL( foo, DoThat( "Hello", 5 ) );

Совпадения

Google mock

•Wildcards

•Простые сравнения

•Строковые совпадения

•Контейнерные совпадения

•Member совпадения

•Составные совпадения

•…

•MATCHER макрос

Совпадения

Google mock

EXPECT_CALL( foo, DoThat( _, 5 ) );

Совпадения Wildcards

Google mock

•Wildcards

•Простые сравнения

•Строковые совпадения

•Контейнерные совпадения

•Member совпадения

•Составные совпадения

•…

•MATCHER макрос

Совпадения

Google mock

EXPECT_CALL( foo, DoThat( NotNull(), Ge( 5 ) ) );

Простые сравненияСовпадения

Google mock

•Wildcards

•Простые сравнения

•Строковые совпадения

•Контейнерные совпадения

•Member совпадения

•Составные совпадения

•…

•MATCHER макрос

Совпадения

Google mock

EXPECT_CALL( foo, DoAlso( HasSubstring(“Hey”) ) );

Строковые совпаденияСовпадения

Google mock

•Wildcards

•Простые сравнения

•Строковые совпадения

•Контейнерные совпадения

•Member совпадения

•Составные совпадения

•…

•MATCHER макрос

Совпадения

Google mock

MOCK_METHOD1( Foo, void( const vector< int >& numbers ) );

EXPECT_CALL( mock, void( ElementsAre( 1, Gt( 0 ), _, 5 ) ) );

Контейнерные совпаденияСовпадения

Google mock

•Wildcards

•Простые сравнения

•Строковые совпадения

•Контейнерные совпадения

•Member совпадения

•Составные совпадения

•…

•MATCHER макрос

Совпадения

Google mock

MOCK_METHOD1( Foo, void( Bar ) );

EXPECT_CALL( mock, void( Field(&Bar::first, Le( 10 ) ) ) );

Member совпаденияСовпадения

Google mock

•Wildcards

•Простые сравнения

•Строковые совпадения

•Контейнерные совпадения

•Member совпадения

•Составные совпадения

•…

•MATCHER макрос

Совпадения

Google mock

EXPECT_CALL( foo, DoAlso( AnyOf(“Hey”, “Dolly”) ) );

Составные совпаденияСовпадения

Google mock

•Wildcards

•Простые сравнения

•Строковые совпадения

•Контейнерные совпадения

•Member совпадения

•Составные совпадения

•…

•MATCHER макрос

Совпадения

Google mock

MATCHER_P( IsDivisibleBy, n, "" ) { return ( arg % n ) == 0; }

EXPECT_CALL( mock, Calc(IsDivisibleBy( 10 ) ) );

MATCHER макросСовпадения

Google mock

Virtual vs. nonvirtual?

Google mock

Google mock

ДемонстрацияТестирование отреверсенного кода в gmock

Заключение...

Recommended