Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сохранение указателя на виртуальную функцию-член 
:(
    Опции темы
MrLukS
Дата 4.8.2010, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 31.7.2009

Репутация: нет
Всего: нет



Есть класс:
Код

class SomeClass
{
public:
    virtual void SomeFunc(int SomeParam);
};


Необходимо получить указатель на SomeFunc и сохранить его в переменную. Поиск по Vtable не предлагать - в оригинальном классе огромное количество функций и он все время меняется. 

Код

DWORD dwFuncPtr = &SomeClass::SomeFunc; // Don't work
DWORD dwFuncPtr = reinterpret_cast<DWORD>&SomeClass:SomeFunc; // Don't work
// ... 


Это сообщение отредактировал(а) MrLukS - 4.8.2010, 17:35
PM MAIL   Вверх
bsa
Дата 4.8.2010, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Указатель на не статический метод класса имеет размер в два раза больший, чем обычный указатель. Поэтому в DWORD он не поместится. И вообще, не делай этого. Это плохой тон программирования, ты себя жестко привязываешь к разрядности текущего процессора. Т.е. даже если ты это и сделаешь, то под 64-х битной виндой это работать не будет.
Ты лучше скажи, зачем тебе это надо, и мы посоветуем, как лучше это сделать.

Это сообщение отредактировал(а) bsa - 4.8.2010, 18:08
PM   Вверх
Cheloveck
Дата 4.8.2010, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Цитата(bsa @  4.8.2010,  18:07 Найти цитируемый пост)
в DWORD он не поместится


Цитата(bsa @  4.8.2010,  18:07 Найти цитируемый пост)
не делай этого


Цитата(bsa @  4.8.2010,  18:07 Найти цитируемый пост)
Это плохой тон программирования

угу. 
Делай типа так
Код

#include <iostream>

class SomeClass
{
public:
    virtual void SomeFunc(int SomeParam)
    {
        std::cout << SomeParam << std::endl;
    }
};

typedef void (SomeClass::*SomeFunctT)(int);

void Foo(SomeFunctT pointer)
{
    SomeClass sc;
    (sc.*pointer)(100);
}

int main()
{
    SomeFunctT pointer = &SomeClass::SomeFunc;
    Foo(pointer);
}





--------------------
user posted image
PM Jabber   Вверх
icecrashldr
Дата 4.8.2010, 18:12 (ссылка)    | (голосов:6) Загрузка ... Загрузка ... Быстрая цитата Цитата


Developer
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 5.7.2010

Репутация: нет
Всего: нет



Код

void * ptrVar;
    SomeClass objSomeClass;
    void (__thiscall SomeClass::* ptrSomeFunc)(int);

    ptrSomeFunc = &SomeClass::SomeFunc;
    __asm {
        mov eax, ptrSomeFunc
        mov ptrVar, eax
    }

PM MAIL WWW   Вверх
Cheloveck
Дата 4.8.2010, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Самые распространённые ошибки в 64-битных системах - это попытки записать указатель в 32-битную переменную
http://habrahabr.ru/blogs/cpp/97810/

Добавлено через 53 секунды
icecrashldr, вот так одним махом похоронить переносимость? не хорошо это!


--------------------
user posted image
PM Jabber   Вверх
Abyx
Дата 4.8.2010, 18:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



MrLukS, он не влезет в dword. reinterpret_cast такой каст не выполнит даже если влезет.
надо использовать union.

надо отключить множественное наследование, чтобы указатель мог влезть в dword.
Код

class __single_inheritance SomeClass


подробнее - поиск по форуму
PM MAIL   Вверх
icecrashldr
Дата 4.8.2010, 18:17 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Developer
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 5.7.2010

Репутация: нет
Всего: нет



Код

class SomeClass
{
public:
    virtual 
    void 
    SomeFunc(int SomeParam);

    int someField;
};

void
SomeClass::SomeFunc(int SomeParam)
{
    printf(__FUNCTION__ " value %d \n", someField);
}

int
__cdecl
main(
     int argc,
     char * argv[]
)
{
    void * ptrVar;
    SomeClass objSomeClass;
    void (__thiscall SomeClass::* ptrSomeFunc)(int);

    objSomeClass.someField= 5;

    ptrSomeFunc = &SomeClass::SomeFunc;

    __asm {
        mov eax, ptrSomeFunc
        //mov ptrVar, eax 
        lea ecx, [objSomeClass]
        push 2
        call eax
    }

return 1;
}

Вот полноценный вызов функции ... 

PM MAIL WWW   Вверх
MrLukS
Дата 4.8.2010, 18:24 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 31.7.2009

Репутация: нет
Всего: нет



Cheloveck, код должен работать только в 32 битных системах. Кроме того, я сказал что мне нужно сохранить указатель как число, а не как непосредственно функцию.
icecrashldr, спасибо, это именно то что мне нужно... Я так и думал, что тут без задействования ассемблера не обойтись. 

Указатель нужен для перехвата функции. (MS Detours)

Это сообщение отредактировал(а) MrLukS - 4.8.2010, 18:26
PM MAIL   Вверх
Abyx
Дата 4.8.2010, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



MrLukS, вы свою функцию перехватываете чтоли?)

но асм там полюбому не нужен

Это сообщение отредактировал(а) Abyx - 4.8.2010, 18:30
PM MAIL   Вверх
MrLukS
Дата 4.8.2010, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 31.7.2009

Репутация: нет
Всего: нет



Abyx, я функцию из API перехватываю.  
Я промучился часов 5 пытаясь нагуглить что-нибудь, а на асме все и понятно, и работает. 
PM MAIL   Вверх
Cheloveck
Дата 4.8.2010, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Цитата(MrLukS @  4.8.2010,  18:24 Найти цитируемый пост)
Я так и думал, что тут без задействования ассемблера не обойтись. 

Обойтись!
Код

#include <iostream>
#include <memory>

class SomeClass
{
public:
    virtual void SomeFunc(int SomeParam)
    {
        std::cout << SomeParam << std::endl;
    }
};

typedef void (SomeClass::*SomeFunctT)(int);

struct Pointer
{
    SomeFunctT m_pointer;
    std::auto_ptr<SomeClass> mp_object;
};

void Foo(ptrdiff_t number)
{
    Pointer * p = reinterpret_cast<Pointer *>(number);
    SomeClass * obj = p->mp_object.get();
    (obj->*(p->m_pointer))(100);
}

int main()
{
    std::auto_ptr<SomeClass> obj(new SomeClass);
    SomeFunctT pf = &SomeClass::SomeFunc;
    Pointer * pointer = new Pointer;
    pointer->m_pointer = pf;
    pointer->mp_object = obj;
    ptrdiff_t number = reinterpret_cast<ptrdiff_t>(pointer);
    Foo(number);
    delete pointer;
}

http://codepad.org/ewI1DmX7

Это сообщение отредактировал(а) Cheloveck - 4.8.2010, 18:54


--------------------
user posted image
PM Jabber   Вверх
Abyx
Дата 4.8.2010, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



вместо __thiscall удобно использовать __fastcall
PM MAIL   Вверх
MrLukS
Дата 4.8.2010, 18:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 31.7.2009

Репутация: нет
Всего: нет



Chelovek, слишком сложный код. Повторяю, мне не нужна переносимость, код должен работать только в 32 битной системе.
Abyx, к сожалению, мне нужен именно _thiscall. 

Немного порыл в сторону VTable:
Код

size_t** vtable = *reinterpret_cast<size_t***>(new SomeClass);

Теперь, по сути, vtable это двумерный массив указателей на виртуальные функции. Вот только почему-то там нет адреса &SomeClass::SomeFunc
PM MAIL   Вверх
Cheloveck
Дата 4.8.2010, 19:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Цитата(MrLukS @  4.8.2010,  18:57 Найти цитируемый пост)
слишком сложный код.

да C++ вообще язык сложный......


--------------------
user posted image
PM Jabber   Вверх
Abyx
Дата 4.8.2010, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



MrLukS, опишите вашу проблему подробнее
PM MAIL   Вверх
Cheloveck
Дата 4.8.2010, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Цитата(MrLukS @  4.8.2010,  18:57 Найти цитируемый пост)
Немного порыл в сторону VTable

vtlb не специфицирована. все компиляторы реализуют её как хотят. юзать её тоже крайне не желательно.


--------------------
user posted image
PM Jabber   Вверх
Abyx
Дата 4.8.2010, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



Код

auto temp = &Cls::Met;
DWORD fptr = *(DWORD*)&temp;

но это только если 
Код

static_assert(sizeof(temp) == sizeof(DWORD))

для этого надо запрещать множественное наследование

Это сообщение отредактировал(а) Abyx - 4.8.2010, 19:12
PM MAIL   Вверх
MrLukS
Дата 4.8.2010, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 31.7.2009

Репутация: нет
Всего: нет



Есть класс SomeClass. Описание класса выше. 

Код

int EntryPoint(SomeClass *entryClass){ ... } // Точка входа


Необходимо перехватить с помощью MS Detours 2.1 функцию entryClass->SomeFunc(), функция-перехватчик:
Код

int SomeFunc_detour(int param1)
{ return SomeFunc_trampoline(0); }


Заголовки SomeClass в первом посте. 

// Edit: в оригинальном SomeClass ЕСТЬ наследование. Я не имею права изменять этот класс.

Это сообщение отредактировал(а) MrLukS - 4.8.2010, 19:15
PM MAIL   Вверх
Abyx
Дата 4.8.2010, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



Цитата(MrLukS @  4.8.2010,  20:12 Найти цитируемый пост)
в оригинальном SomeClass ЕСТЬ наследование.

множественное? %)

вобщем надо смотреть чему равен размер указателя на член класса
PM MAIL   Вверх
MrLukS
Дата 4.8.2010, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 31.7.2009

Репутация: нет
Всего: нет



Код

class SomeClass001
{
... 59 виртуальных функций
}

class SomeClass002 : public SomeClass001
{
... 31 виртуальная функция
}

class SomeClass003 : public SomeClass002
{
... 5-10 функций
}

Каким образом узнать размер указателя?

Это сообщение отредактировал(а) MrLukS - 4.8.2010, 19:27
PM MAIL   Вверх
Modul
Дата 4.8.2010, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



А почему бы не передать указатель на объект и вызвать нужный метод.

Что для С было нужно и просто, для С++ напоминает жуть !
--------------------
I'll be back !
PM MAIL   Вверх
Abyx
Дата 4.8.2010, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



Цитата(MrLukS @  4.8.2010,  20:27 Найти цитируемый пост)
Каким образом узнать размер указателя?

sizeof'ом %)
PM MAIL   Вверх
MrLukS
Дата 4.8.2010, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 31.7.2009

Репутация: нет
Всего: нет



И так, вот полный код:
Код

#include <windows.h>
#include <stdio.h>
#include "Detours/detours.h"

class SomeClass001
{
public:
    virtual int someFunc001(int someParam)
    {
        printf("[%s(%i)] called\n", __FUNCTION__, someParam);
        return someParam*1;
    }
};

class SomeClass002 : public SomeClass001
{
public:
    virtual int someFunc002(int someParam)
    {
        printf("[%s(%i)] called\n", __FUNCTION__, someParam);
        return someParam*2;
    }
};

class SomeClass : public SomeClass002
{
public:
    virtual int someFunc003(int someParam)
    {
        printf("[%s(%i)] called\n", __FUNCTION__, someParam);
        return someParam*3;
    }
};

/* Class for detouring */
class Detour
{
public:
    typedef int (T_someFunc001)(int someParam); // hook type
    typedef int (Detour::*T__someFunc001)(int someParam); // trampoline type
    
    T_someFunc001 someFunc001; // Hook
    static T__someFunc001 __someFunc001; // Trampoline
};

Detour::T__someFunc001 Detour::__someFunc001 = NULL; // Trampoline = NULL
int Detour::someFunc001(int someParam) // Hook
{
    printf("[%s(%i)] called (hook)\n", __FUNCTION__, someParam);
    
    (this->*__someFunc001)(someParam); // << CRASH! :-(
    
    printf("[%s] this: %p\n", __FUNCTION__, this);
    printf("[%s] trampoline: %p\n", __FUNCTION__, Detour::__someFunc001);
    return someParam*3; // Default: by 1
}

int main()
{
    printf("\n========================\n");
    
    // Create
    SomeClass* targetClass = new SomeClass();
    
    // Call function
    targetClass->someFunc001(1);
    
    // Init detours
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    
    // Detour attach
    Detour::__someFunc001 = reinterpret_cast<Detour::T__someFunc001>(&SomeClass::someFunc001); // Save pointer
    DetourAttach(&(PVOID&)Detour::__someFunc001,(PVOID)(&(PVOID&)Detour::someFunc001));
    
    // Do changes
    LONG l = DetourTransactionCommit();
    printf("DetourTransactionCommit = %d\n", l);
    
    // Try another call
    targetClass->someFunc001(1);
    // FAIL! :-(
    
    // Try to call hook
    Detour* d = new Detour();
    d->someFunc001(123);
    // CRASH! :-(
    
    // TODO: don't forget about removing detours!
    printf("\n===========D============\n");
    return 0;
}

К сожалению, код не выполняет своей главной функции, к тому же крашиться при попытке вызова оригинальной функции. 
PM MAIL   Вверх
Леопольд
Дата 4.8.2010, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(MrLukS)
Сохранение указателя на виртуальную функцию-член
Цитата(Modul @  4.8.2010,  19:45 Найти цитируемый пост)
Что для С было нужно и просто, для С++ напоминает жуть ! 
С каких пор в Си есть виртуальные функции?
Всё что можно в Си, можно и в С++...



--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Abyx
Дата 4.8.2010, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



Цитата(MrLukS @  4.8.2010,  21:50 Найти цитируемый пост)
к тому же крашиться при попытке вызова оригинальной функции.  

для этого есть отладчик
PM MAIL   Вверх
MrLukS
Дата 4.8.2010, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 31.7.2009

Репутация: нет
Всего: нет



Abyx, =\ Я показал где ошибка: я не могу сохранить указатель на функцию. 73 строка, выдает неправильный указатель.
PM MAIL   Вверх
Abyx
Дата 4.8.2010, 22:07 (ссылка) |    (голосов:4) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



MrLukS, вам еще рано этим заниматься. сначала изучите матчасть.
PM MAIL   Вверх
MrLukS
Дата 4.8.2010, 22:28 (ссылка)    | (голосов:6) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 31.7.2009

Репутация: нет
Всего: нет



Abyx, я знаю матчасть. Я не знаю лишь STL, который я никогда не использовал. И надеюсь никогда не буду использовать. Привык, видите-ли, не использовать всякие примочки и кодить на чистом языке... 


Спасибо за помощь, дальше буду разбираться как-нибудь сам. Наверное перепишу проект на асме.. Там хотя-бы не будет таких мук с классами.
PM MAIL   Вверх
Леопольд
Дата 4.8.2010, 22:37 (ссылка) |  (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(MrLukS @  4.8.2010,  22:28 Найти цитируемый пост)
я знаю матчасть
Сильно сомневаюсь. Вот bsa, пожалуй, может так сказать... smile

Цитата(MrLukS @  4.8.2010,  22:28 Найти цитируемый пост)
Я не знаю лишь STL, который я никогда не использовал. И надеюсь никогда не буду использовать. Привык, видите-ли, не использовать всякие примочки и кодить на чистом языке... 
Довольно неразумный подход, отказываться от библиотек.

Чисто так, для сведения. VTBL не имеет никакого отношения к стандарту С++. Реализация вольна осуществлять  "виртуальный" вызов функции на своё усмотрение.

Это сообщение отредактировал(а) Леопольд - 4.8.2010, 22:40


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
MrLukS
Дата 4.8.2010, 22:53 (ссылка)    | (голосов:4) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 31.7.2009

Репутация: нет
Всего: нет



Цитата
Сильно сомневаюсь.
Можете не сомневаться   smile Или по вашему 3 года кодинга - это незнание матчасти? (STL не в счет!) 

Цитата

Довольно неразумный подход, отказываться от библиотек.

Знаю, однако только так я смогу контролировать все, что накодил. Не люблю, как я уже сказал, пользоваться готовым закрытым кодом, да еще и работающим неизвестно как. Темболее это же мелкомягкие...  smile 

Проблему решил, vtable творят чудеса  smile 

smile 
PM MAIL   Вверх
Cheloveck
Дата 4.8.2010, 23:22 (ссылка) |    (голосов:4) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Цитата(MrLukS @  4.8.2010,  22:53 Найти цитируемый пост)
готовым закрытым кодом, да еще и работающим неизвестно как. 

STL полностью открыта

Цитата(MrLukS @  4.8.2010,  22:53 Найти цитируемый пост)
Темболее это же мелкомягкие... 

STL специфицируется стандартом C++ и должна работать одинаково во всех реализациях (включая время выполнения операций). А реализация от M$ не худшая.


--------------------
user posted image
PM Jabber   Вверх
Леопольд
Дата 5.8.2010, 00:35 (ссылка) |    (голосов:5) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(MrLukS @  4.8.2010,  22:53 Найти цитируемый пост)
 Или по вашему 3 года кодинга - это незнание матчасти?
 Вполне возможно...
Как минимум, добровольный отказ от STL наталкивает на эту мысль.

Добавлено @ 00:39
Цитата(MrLukS @  4.8.2010,  22:53 Найти цитируемый пост)
Не люблю, как я уже сказал, пользоваться готовым закрытым кодом, да еще и работающим неизвестно как.
Standard Template Library - всё в хидерах, это всё же шаблоны...

Это сообщение отредактировал(а) Леопольд - 5.8.2010, 00:39


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
mes
Дата 5.8.2010, 08:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(MrLukS @  4.8.2010,  21:53 Найти цитируемый пост)
Проблему решил, vtable творят чудеса

Имхо, к проблеме Вы подошли не с той стороны.. Вопрос нужно было задавать не о том, как запомнить адрес виртуальной функции, а о том как можно решить ту задачу, для который Вы решили запоминать функции...

 что именно Вам нужно непонятно, но посмотрите это :  http://codepad.org/edtM5QhB


--------------------
PM MAIL WWW   Вверх
bsa
Дата 5.8.2010, 10:27 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(MrLukS @  4.8.2010,  23:53 Найти цитируемый пост)
Можете не сомневаться    Или по вашему 3 года кодинга - это незнание матчасти? (STL не в счет!) 

Когда у меня был опыт работы на С++ 5-7-ми лет, я с удивлением открыл для себя, что я не знаю языка - тоже не знал STL. Более того, сейчас я знаю и STL, и boost умею пользоваться, но опять же, не могу утверждать, что я отлично знаю С++.
То что ты пытаешься использовать vtable это вообще называется "грязный хак". И применять его в не академических целях мягко говоря глупо.
Я, честно говоря, так и не понял, зачем нужен этот MS Detours. Но есть подозрение, что это тоже сродни "грязному хаку".
Кстати, если тебе нужно ловить начало выполнения определенных методов, то можешь в них воткнуть вызов какой-то пустой внешней функции, адрес которой и передашь этому detours.
PM   Вверх
Abyx
Дата 5.8.2010, 10:44 (ссылка)    | (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



Цитата(bsa @  5.8.2010,  11:27 Найти цитируемый пост)
Я, честно говоря, так и не понял, зачем нужен этот MS Detours.

собственно вам следовало с этого и начинать, и не писать "грязный хак" и т.п.
если бы вы знали зачем нужен Detours, в каких случаях он применим, вы бы не писали про хаки.

перехват функций подразумевает знание особенностей кода который перехватывается, так что это совсем не хак.
если надо перехватывать код в чужой 32разрядной программе скомпилированной VC++, то очевидно что там не будет проблем с тем что у уже скомпилированной программы внезапно поменяется разрядность и компилятор.
PM MAIL   Вверх
icecrashldr
Дата 5.8.2010, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Developer
*


Профиль
Группа: Участник
Сообщений: 122
Регистрация: 5.7.2010

Репутация: нет
Всего: нет



Может быть стоит использовать dbgeng? 
Апи предоставляется из пакета Debugging Tool for Windows, и это "отладчик-апи" хорошо совместно с Visual studio.
Поставить бряки и дело то с концом ...

PM MAIL WWW   Вверх
mes
Дата 5.8.2010, 11:27 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Abyx @  5.8.2010,  09:44 Найти цитируемый пост)
обственно вам следовало с этого и начинать, и не писать "грязный хак" и т.п.

1. начинать надо было тс. правильно освещать задание
2. если даже сузить рамки задачи,  хак не перестает быть хаком
3. не резковаты ли Вы ?


--------------------
PM MAIL WWW   Вверх
Abyx
Дата 5.8.2010, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



mes
1. ТС написал что он перехватывает функцию и использует Detours. Это вполне достаточно чтобы понять задание.
2. что есть хак? поведение компилятора полностью определено документацией компилятора.
как устроена vftable у MSVC написано в документации MSVC и множестве статей, в том числе и от MS. где тут хак?
3. писать о том в чем не разбираешься - это не есть хорошо. особенно писать "я не знаю что это такое но это плохо"
PM MAIL   Вверх
Modul
Дата 5.8.2010, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 17.2.2006

Репутация: нет
Всего: нет



Цитата(mes @  5.8.2010,  08:49 Найти цитируемый пост)
Вопрос нужно было задавать не о том, как запомнить адрес виртуальной функции, а о том как можно решить ту задачу, для который Вы решили запоминать функции...


Цитата(bsa @  5.8.2010,  10:27 Найти цитируемый пост)
То что ты пытаешься использовать vtable это вообще называется "грязный хак". И применять его в не академических целях мягко говоря глупо.


Вот и я о том же говорил. 

Нужно правильно задачу поставить, а не писать - мне нужно...вызвать закорючку.

Т.е. человеку кажется, что он прав.
А как можно даже с заказчиком вести разговор, если он не может ее сформулировать !  smile 
--------------------
I'll be back !
PM MAIL   Вверх
mes
Дата 5.8.2010, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Abyx @  5.8.2010,  10:54 Найти цитируемый пост)
как устроена vftable у MSVC написано в документации MSVC и множестве статей, в том числе и от MS. 

а где сказано что компилятoр MSVC(кроме косвенных упоминаний таких как thiscall), и что остальные рассматривать не надо ?..

Цитата(Abyx @  5.8.2010,  10:54 Найти цитируемый пост)
что есть хак? 

грубо: то что делается в обход предусмотренного способа использования.
smile




--------------------
PM MAIL WWW   Вверх
Abyx
Дата 5.8.2010, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



разговор скатился в никуда. ТС вроде как решил свою задачу, а вы обсуждаете хз что %)
PM MAIL   Вверх
asd
Дата 6.8.2010, 10:41 (ссылка)    | (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 25.6.2006

Репутация: нет
Всего: 1



MrLukS
Если вам нужно перехватить какую-то ф-ию в классе, то может сделать так?

class SomeClass2: public SomeClass
{
public:
    virtual void SomeFunc(int SomeParam)
    {
        ...
        SomeClass::SomeFunc(int SomeParam);
        ...
    }
};

и юзать SomeClass2 вместо SomeClass
PM MAIL   Вверх
bsa
Дата 8.8.2010, 16:37 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(asd @  6.8.2010,  11:41 Найти цитируемый пост)
сли вам нужно перехватить какую-то ф-ию в классе, то может сделать так?

читай внимательно все сообщения. Речь не про это.
PM   Вверх
asd
Дата 9.8.2010, 08:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 25.6.2006

Репутация: нет
Всего: 1



Прочитал ещё раз. Так про что речь? Про то что надо во что бы то ни стало получить указатель на метод, чтобы передать его в дллку для логирования? Ну, да, тогда мой пост вообще мимо кассы. Но, имхо, логировать действия своего кода с помощью сторонней либки, как-то странно.
PM MAIL   Вверх
Abyx
Дата 9.8.2010, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



"логирование" - теперь это так называется ))
PM MAIL   Вверх
xvr
Дата 12.8.2010, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



В С++ НЕТ стандартного способа получить абсолютный адрес виртуального (да и не виртуального тоже) метода класса. 
Это возможно только либо через расширения языка (как в gcc например), либо через точное знание внутреннего устройства транслируемого С++ кода (для любого компилятора). И в любом случае это на 100% не переносимо.

PM MAIL   Вверх
Abyx
Дата 12.8.2010, 21:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



xvr, для задачи ТСа переносимость не нужна, это какбэ очевидно
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1903 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.