Адрес возврата функции

Тема в разделе "LANGS.C", создана пользователем mofer, 18 июл 2010.

  1. mofer

    mofer Константин

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    10
    Нужно найти утечку объектов создаваемых функцией. Для этого я каждому объекту сделал свойство адрес возврата из ф-и создания (можно приблизительно сказать где утечка)

    Вот например для памяти:
    Код (Text):
    1. #include <windows.h>
    2. #include <crtdbg.h>
    3.  
    4. class CMalloc
    5. {
    6. public:
    7.     CMalloc() {
    8.         _RPT1(0, "[%p] create\n", this);
    9.     }
    10.  
    11.     virtual bool __stdcall CreateBuffer(unsigned uSize, void** ppBuffer) {
    12.         // было бы замечательно если бы был оператор __return_address
    13.         return CreateBufferEx(0, uSize, ppBuffer);
    14.     }
    15.    
    16.     bool CreateBufferEx(const void* retaddr, unsigned uSize, void** ppBuffer) {
    17.         *ppBuffer = malloc(uSize);
    18.         return *ppBuffer != NULL;
    19.     }
    20. };
    21.  
    22. #include <pshpack1.h>
    23. struct CreateBufferInfo
    24. {
    25.     const void* retaddr;
    26.  
    27.     CMalloc* pThis;
    28.     unsigned uSize;
    29.     void**   ppBuffer;
    30. };
    31. #include <poppack.h>
    32.  
    33. bool __stdcall CreateBufferEntry(CreateBufferInfo* p)
    34. {
    35.     _RPT2(0, "[%p] hook, ra = %p\n", p->pThis, p->retaddr);
    36.     return p->pThis->CreateBufferEx(p->retaddr, p->uSize, p->ppBuffer);
    37. }
    38.  
    39. __declspec(naked) bool __stdcall CreateBufferHook(CMalloc* pThis, unsigned uSize, void** ppBuffer)
    40. {
    41.     __asm {
    42.         lea     eax, [esp]
    43.         push    eax
    44.         call    CreateBufferEntry
    45.         ret
    46.     }
    47. }
    48.  
    49. void main()
    50. {
    51.     CMalloc mem;
    52.     void* ptr;
    53.  
    54. //  mem.CreateBuffer(1, &ptr);
    55.     CreateBufferHook(&mem, 1, &ptr);
    56.  
    57. // осталось теперь подменить vtable
    58. //  mem.CreateBuffer = CreateBufferHook;
    59. }
    Проблема в том что naked ф-и нельзя сделать для члена класса я переопределил ф-ю vtable (для virtual bool __stdcall CreateBuffer) и пришлось писать на C. Может я изобрел велосипед и есть более простой способ?
    жаль нет оператора типа __return_addr - адрес возврата из ф-и.
    что можете предложить для х64?
     
  2. izl3sa

    izl3sa New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2010
    Сообщения:
    164
    Адрес:
    Spb
    естественно есть =) но это тоже не плюсы впрочем.

    стандартный стековый фрейм (вниз - более младшие адреса)

    argn
    ...
    arg0
    ret
    ebp
    local0
    ...
    localn

    и соответственно берем адрес либо arg0 либо local0

    тогда
    ret = *(DWORD *)((DWORD)&arg0 - 4) = *(DWORD *)((DWORD)&local0 + 8)
    соответственно, подгоняем под разные случае, размер элементов и тд. К примеру может быть поднят флаг /GS и тогда придется во втором случае адаптировать оффсет, тк на стеке между local и ebp будет ebp поксоренный с security cookies. И в общем для arg0 нужно смотреть какая конвенция вызовов, но это не ваш случай.

    Ps только заметил x64 ... ну там возможно тоже самое, я их не ковырял =) только размеры элементов другие =)
     
  3. mofer

    mofer Константин

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    10
    да, это проще, если есть исходники.
    я просто делал hook для одного сом'a...

    type Function(param0, param1, ...) {
    size_t ret_addr = *((size_t*)&param0 - 1);
    }

    class A
    {
    type __stdcall/__cdecl Function(param0, param1, ...) {
    size_t ret_addr = *((size_t*)&param0 - 2); // в стеке еще указатель на vtable, для __thiscall он в ecx
    }

    };

    работает и для x64. Спасибо.
     
  4. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Есть _ReturnAddress и _AddressOfReturnAddress
     
  5. mofer

    mofer Константин

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    10
    Не знал, но это же microsoft specific.
    я просто не нашел в стандарте языка.
     
  6. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    В стандарте конечно нет, как и понятия адрес возврата.
     
  7. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    угу, не на всех платформах используется такая модель вызова функций.