Почему в аргумент функции передается стэк?

Здравствуйте, я далек от ассемблера и с горем пополам разбираюсь в нем при помощи ida c гидрой. Так вот, все было хорошо, пока я не встретил подобный метод. Как так получается, что объект которому принадлежит метод является стэком.
603d2f0909eb1744957217.png

Возможно это статическая функция, но как ее тогда вызывать с с++, если я не могу передать стэк

603d485f1c135170887493.png
  • Вопрос задан
  • 208 просмотров
Решения вопроса 1
@galaxy
Имхо, что здесь происходит:
на стеке лежит некоторый объект некоторого класса, вершина стека (esp) при этом является адресом этого объекта (т.е. this);
this передается в метод через регистр ecx (есть такое соглашение, регистр уже заботливо переименован в листинге);
также this сохраняется в какой-то стековой переменной;
туда же (в метод), но уже через стек, передается некий указатель на поле какого-то объекта.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
freeExec
@freeExec
Участник OpenStreetMap
Это локальная переменная, в которую вызванная функцию должна вернуть результат.
Ответ написан
@Mercury13
Программист на «си с крестами» и не только
Итак, на стеке лежит локальный объект, и так совпало, что его адрес совпадает с регистром esp. Стек на x86 растёт вниз, так что такое бывает.
Для этого объекта мы вызываем функцию с соглашением вызова cdecl thiscall и одним dword-параметром, предположительно указателем. Функция возвращает указатель/ссылку на объект — видимо для «текучего интерфейса».

Как я понял, вы подставным DLL или подобной дрянью хотите вызвать эту функцию, верно? Тогда в DLL пишем примерно такое.
#include <iostream>

class X
{
public:
    // Наделай полей — непонятно, какой нужен размер объекта, но минимум 7 dword
    uint32_t field0 = 0, field4 = 0, field8 = 0, fieldC = 0,
           field10 = 0, field14 = 0, field18 = 0;
    // Просто тестовая функция, тебе не нужна
    X& doSmth(void* param);
};


// Просто тестовая функция, тебе не нужна
X& X::doSmth(void* param)
{
    std::cout << "My address is " << this << std::endl;
    std::cout << "My param is " << param << std::endl;
    return *this;
}

// Известно, что параметр — указатель/ссылка, но какого типа — неизвестно.
// Пусть будет void*.
using PFunc = X& (X::*)(void*);

int main()
{    
    PFunc func = &X::doSmth;  // Тебе надо reinterpret_cast<PFunc>(0x471440)
    X x;
    auto param = reinterpret_cast<void*>(0x5678);  // Или придумай, чему должен равняться этот param
    (x.*func)(param);
    return 0;
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы