Re[3]: реверс функции - надо узнать оригинал
От: Кодт Россия  
Дата: 19.05.10 08:21
Оценка: 6 (1) +1
Здравствуйте, 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>это то, что можно понять при дизассемблировании


А>>>помогите идентифицировать функции, и если можно пример ее использования


К>>Варианты сигнатур

К>>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); }
К>>  .....
К>>};

D>замысловато, но тоже сильно накручено
Это была иллюстрация

D>поскольку там нет ни одного оператора new


placement new не вызывает ::operator new(size_t).
А ::operator new(void*,size_t) тривиальный, и компилятор его мысленно сократил. И правильно сделал.


К>>Ещё есть подозрения на виртуальное наследование A от B. Тогда sub8 — это, возможно, конструктор: он там довольно хитро устроен.

D>нет, виртуального наследование точно нет

D>я все более полагаюсь на то что это какойто оператор<<

D>но констуркторы в теле меня очень смущают

Попробуй всё более полагаться на возврат объекта по значению.
Перекуём баги на фичи!
Re: реверс функции - надо узнать оригинал
От: Кодт Россия  
Дата: 18.05.10 17:33
Оценка: 1 (1) +1
Здравствуйте, Аноним, Вы писали:

А>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 класса


помогите идентифицировать функции, и если можно пример ее использования
Re[2]: реверс функции - надо узнать оригинал
От: disasm  
Дата: 18.05.10 18:05
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Аноним, Вы писали:


К>
А>>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 — это, возможно, конструктор: он там довольно хитро устроен.


нет, виртуального наследование точно нет

я все более полагаюсь на то что это какойто оператор<<
но констуркторы в теле меня очень смущают
Re[4]: реверс функции - надо узнать оригинал
От: disasm  
Дата: 21.05.10 12:57
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, disasm, Вы писали:


К>Поясняю ещё раз

К>
К>// в исходном коде
К>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();
К>}
К>


да! проверил компилятором + дисасмом, все так и есть
дествительно NRVO
теперь стало на всё на свои места

по этому вопросу тема закрыта
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.