Здравствуйте, disasm, Вы писали:
А>>>над первым арументом(arg0) кроме тех действий что я описал выше в функции, не происходит. А>>>тоесть он используеться именно два раза как конструктор и далее возращаеться на выходе из функции
К>>Примерно так должна работать функция, возвращающая объект по значению. К>>Вызывающая сторона выделяет у себя на стеке память под временный объект и отдаёт указатель в функцию. К>>Функция в точке return (либо, если сделана оптимизация NRVO, в точке создания локального объекта) делает placement new и вызывает конструктор для данного указателя.
D>не совсем понял...
Поясняю ещё раз
// в исходном коде
Some foo()
{
if(...)
return Some(xxxxx);
else
return Some(yyyyy);
}
void bar()
{
foo().buz(); // Some::buz
}
// как это на самом деле
Some* foo(void* buf)
{
if(...)
return new(buf) Some(xxxxx); // гуглить "placement new" !!!else
return new(buf) Some(yyyyy);
}
void bar()
{
char buf[sizeof(Some)];
Some* tmp = foo(buf);
tmp->buz();
tmp->~Some();
}
К>>Ну и правильно. Сколько разных объектов функция возвращает, столько разных конструкторов и вызывается. К>>Они же вызываются не вместе, а вместо друг друга. if-then-else.
D>да! но перед ними и после них есть определенные действия с разными переменными
Some foo()
{
if(...)
{
Another var;
.....
Some x(xxxxx); // гуглить NRVO
.....
return x; // var.~Another()
}
else { ..... }
}
К>>Я точно не смотрел, как у известных мне компиляторов выглядит конвенция вызова функций, возвращающих объект. К>>Очень может быть, что они уподобляются всяким strcpy: указатель на буфер на входе, указатель на тот же буфер на выходе.
D>GNU C++ D>обьект возращаеться через EAX
Этого недостаточно. Нужно выяснить — в каком порядке передаются аргументы в конвенции thiscall у функции, возвращающей объект по значению.
Возможно, this идёт вторым, а не первым параметром (первым идёт указатель на буфер возвращаемого объекта).
D>временный обьект был нужен D>вот пример использование sub_8
Для всех будет лучше, если ты перестанешь делать вид, что объекты передаются по ссылке. Если там указатели — значит указатели.
"Объект передаётся в EAX" — глупости или жесточайшая оптимизация (когда размер объекта равен 4 и у него тривиальные конструкторы-деструкторы).
И не забывай оборачивать код в тэги [c]-[/c].
D>D::somefunc()
D>{
D> B tmp2;// стековая переменная
// конструктор здесь вызывается? если нет - это не стековая переменная, а только буфер под неё
D> sub_8(tmp2, m_tmp1); // m_tmp1 это обьект A член класса D
D> // думаю очень похоже на оператор и тогда
D> //вместо sub_8(tmp2, m_tmp1); было бы tmp2 << m_tmp1;
// это очень похоже на tmp2 = sub_8(*m_tmp1);
D> printf("%s\n", tmp2.GetStr());
D> tmp2.~B();
D>}
D>это то, что можно понять при дизассемблировании
А>>>помогите идентифицировать функции, и если можно пример ее использования
К>>Варианты сигнатур
D>замысловато, но тоже сильно накручено
Это была иллюстрация
D>поскольку там нет ни одного оператора new
placement new не вызывает ::operator new(size_t).
А ::operator new(void*,size_t) тривиальный, и компилятор его мысленно сократил. И правильно сделал.
К>>Ещё есть подозрения на виртуальное наследование A от B. Тогда sub8 — это, возможно, конструктор: он там довольно хитро устроен. D>нет, виртуального наследование точно нет
D>я все более полагаюсь на то что это какойто оператор<< D>но констуркторы в теле меня очень смущают
Попробуй всё более полагаться на возврат объекта по значению.
А>B sub_8(B arg0, A arg4)
А>{
А> ...
А> if (..)
А> {
А> ...
А> arg0.B::B(??); // под вопросами некие аргументы
А> ...
А> } else
А> {
А> ...
А> arg0.B::B(????); // под вопросами некие другие чем в первом случае аргументы
А> ...
А> }
А> return arg0;
А>}
А>над первым арументом(arg0) кроме тех действий что я описал выше в функции, не происходит. А>тоесть он используеться именно два раза как конструктор и далее возращаеться на выходе из функции
Примерно так должна работать функция, возвращающая объект по значению.
Вызывающая сторона выделяет у себя на стеке память под временный объект и отдаёт указатель в функцию.
Функция в точке return (либо, если сделана оптимизация NRVO, в точке создания локального объекта) делает placement new и вызывает конструктор для данного указателя.
А>функция очень похожа на operator<< А>но! меня настораживает что первый аргумент этой функции инициализируеться дважды в ней как конструктор!(и в этом я тоже на 100% уверен — именно два раза конструктор а не просто члены класса B)
Ну и правильно. Сколько разных объектов функция возвращает, столько разных конструкторов и вызывается.
Они же вызываются не вместе, а вместо друг друга. if-then-else.
А>но извесно то что в любой оператор передаеться ссылка & на обьект, и уже повторно он врядли сможет проинициализироваться?! А>так же как видите функция sub_8 возращает этот же B класс
Я точно не смотрел, как у известных мне компиляторов выглядит конвенция вызова функций, возвращающих объект.
Очень может быть, что они уподобляются всяким strcpy: указатель на буфер на входе, указатель на тот же буфер на выходе.
А>в теле кода где используеться эта функция, сразу же после использования ее разворачиваеться код деструктора B класса
Значит, временный объект не понадобился — и тут же разрушен.
А>помогите идентифицировать функции, и если можно пример ее использования
Варианты сигнатур
class B { ..... };
class A {
.....
static B sub8_v1(A* otherA) { return cond ? B(xxxxx) : B(yyyyy); }
B sub8_v2(/*this*/) { return cond ? B(xxxxx) : B(yyyyy); }
// для извращенцевstatic B* sub8_v3(char* raw, A* otherA) { return cond ? new(raw)B(xxxxx) : new(raw)B(yyyyy); }
.....
};
void use()
{
A a;
A::sub8_v1(&a);
a.sub8_v2();
// для извращенцевunion {
char raw[sizeof(B)];
double ensure_best_alignment;
} buffer;
A::sub8_v3(buffer.raw, &a).~B();
}
Ещё есть подозрения на виртуальное наследование A от B. Тогда sub8 — это, возможно, конструктор: он там довольно хитро устроен.
Перекуём баги на фичи!
реверс функции - надо узнать оригинал
От:
Аноним
Дата:
18.05.10 16:25
Оценка:
суть
есть программа под реверс
в ней уже точно на все 100% определена определенная группа функций
которые пренадлежат одному и тому же классу
выглядит это так
sub_1
sub_2
sub_3
sub_4
sub_5
sub_6
sub_7
sub_8
sub_9
sub_10
sub_11
...
sub_20
как извесно что в функциях класса первый аргумент это this
все функции уже разобраны
осталась одна под номером sub_8
абсолютно извесно что это точно функция этого же класса
но! есть один ньюанс, эот первый параметр этой функции не this
а пареметром этой функции под номером 8 идёт совсем другой класс, но! внутри функии через этот параметр инициализируються констуркторы этого другого класса
выглядит это так
назовем группу распознаных функций — классом A, а не известного класса — классом B
тогда функция под номером 1 или другие будут выглядеть как то так
sub_1(A arg0/* this */)
{
}
итд, другие функции этого A класса
за исключением функции под номером 8
выглядит она так
B sub_8(B arg0, A arg4)
{
...
if (..)
{
...
arg0.B::B(??); // под вопросами некие аргументы
...
} else
{
...
arg0.B::B(????); // под вопросами некие другие чем в первом случае аргументы
...
}
return arg0;
}
над первым арументом(arg0) кроме тех действий что я описал выше в функции, не происходит.
тоесть он используеться именно два раза как конструктор и далее возращаеться на выходе из функции
функция очень похожа на operator<<
но! меня настораживает что первый аргумент этой функции инициализируеться дважды в ней как конструктор!(и в этом я тоже на 100% уверен — именно два раза конструктор а не просто члены класса B)
но извесно то что в любой оператор передаеться ссылка & на обьект, и уже повторно он врядли сможет проинициализироваться?!
так же как видите функция sub_8 возращает этот же B класс
в теле кода где используеться эта функция, сразу же после использования ее разворачиваеться код деструктора B класса
помогите идентифицировать функции, и если можно пример ее использования
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Аноним, Вы писали:
К>
А>>B sub_8(B arg0, A arg4)
А>>{
А>> ...
А>> if (..)
А>> {
А>> ...
А>> arg0.B::B(??); // под вопросами некие аргументы
А>> ...
А>> } else
А>> {
А>> ...
А>> arg0.B::B(????); // под вопросами некие другие чем в первом случае аргументы
А>> ...
А>> }
А>> return arg0;
А>>}
К>
А>>над первым арументом(arg0) кроме тех действий что я описал выше в функции, не происходит. А>>тоесть он используеться именно два раза как конструктор и далее возращаеться на выходе из функции
К>Примерно так должна работать функция, возвращающая объект по значению. К>Вызывающая сторона выделяет у себя на стеке память под временный объект и отдаёт указатель в функцию. К>Функция в точке return (либо, если сделана оптимизация NRVO, в точке создания локального объекта) делает placement new и вызывает конструктор для данного указателя.
не совсем понял...
А>>функция очень похожа на operator<< А>>но! меня настораживает что первый аргумент этой функции инициализируеться дважды в ней как конструктор!(и в этом я тоже на 100% уверен — именно два раза конструктор а не просто члены класса B)
К>Ну и правильно. Сколько разных объектов функция возвращает, столько разных конструкторов и вызывается. К>Они же вызываются не вместе, а вместо друг друга. if-then-else.
да! но перед ними и после них есть определенные действия с разными переменными
А>>но извесно то что в любой оператор передаеться ссылка & на обьект, и уже повторно он врядли сможет проинициализироваться?! А>>так же как видите функция sub_8 возращает этот же B класс
К>Я точно не смотрел, как у известных мне компиляторов выглядит конвенция вызова функций, возвращающих объект. К>Очень может быть, что они уподобляются всяким strcpy: указатель на буфер на входе, указатель на тот же буфер на выходе.
GNU C++
обьект возращаеться через EAX
А>>в теле кода где используеться эта функция, сразу же после использования ее разворачиваеться код деструктора B класса
К>Значит, временный объект не понадобился — и тут же разрушен.
временный обьект был нужен
вот пример использование sub_8
D::somefunc()
{
B tmp2;// стековая переменная
sub_8(tmp2, m_tmp1); // m_tmp1 это обьект A член класса D
// думаю очень похоже на оператор и тогда
//вместо sub_8(tmp2, m_tmp1); было бы tmp2 << m_tmp1;
printf("%s\n", tmp2.GetStr());
tmp2.~B();
}
это то, что можно понять при дизассемблировании
А>>помогите идентифицировать функции, и если можно пример ее использования
К>Варианты сигнатур К> К>class B { ..... };
К>class A { К> ..... К> static B sub8_v1(A* otherA) { return cond ? B(xxxxx) : B(yyyyy); } К> B sub8_v2(/*this*/) { return cond ? B(xxxxx) : B(yyyyy); } К> // для извращенцев К> static B* sub8_v3(char* raw, A* otherA) { return cond ? new(raw)B(xxxxx) : new(raw)B(yyyyy); } К> ..... К>};
замысловато, но тоже сильно накручено
поскольку там нет ни одного оператора new
К>void use() К>{ К> A a;
К> A::sub8_v1(&a);
К> a.sub8_v2();
К> // для извращенцев К> union { К> char raw[sizeof(B)]; К> double ensure_best_alignment; К> } buffer; К> A::sub8_v3(buffer.raw, &a).~B(); К>} К>
врядли это выглядело так в оригинале ))))))
я привел пример выше как это используеться
К>Ещё есть подозрения на виртуальное наследование A от B. Тогда sub8 — это, возможно, конструктор: он там довольно хитро устроен.
нет, виртуального наследование точно нет
я все более полагаюсь на то что это какойто оператор<<
но констуркторы в теле меня очень смущают