2010-06-29 3 views
3

Таким образом, при использовании IDA разбирать DLL, я наткнулся на этот класс функции:Смешение функция

mov eax, [ecx+4] 
mov eax, [eax] 
retn 

Я знаю ecx означает this и eax это возвращаемое значение, но я не в состоянии понять, что он возвращается. Любая помощь?

ответ

1
class C 
{ 
    int a; 
    int *b; // ecx+4 

    int get_b() 
    { 
     return *b; 
    } 
} 

Конечно, фактический тип a и *b неизвестен, но они оба типа 32-разрядных. a также может быть указателем на VMT, если класс имеет какие-либо виртуальные методы или деструкторы.

+0

О, но в этом классе ecx + 4 фактически является самой функцией в vftable. Так что это значит ...? –

+0

Это ничего не меняет. Указатель * в vtable хранится в поле первого класса ('a' в моем примере). –

+0

Как я могу найти, что такое ecx + 4? –

3

Эта функция загружает указатель (в eax) со смещением 4 от любого ecx указывает на. Затем следует, что указатель на загрузку 32-битного значения в eax, который возвращается из функции.

Вот что функция делает, но нельзя сказать, что это означает без намного больше контекста.

+0

Весьма вероятно, что он возвращает первый элемент int или reference класса с vtable или второй из структуры без одного. –

+0

Можете ли вы показать это в синтаксисе C или C++? Hex-Rays возвращает: return \ * \ * (DWORD \ * \ *) (это + 4); На самом деле, что делает функция? –

+0

kotarou3, объясненный с помощью «pic» в моем ответе, следуйте «стрелкам», и вы можете конвертировать на любой язык, с которым вы знакомы. Вы здесь предполагаете, что язык - это C/C++, вероятно, C++, если вы говорите об этом, и любой другой ответ, предполагающий, что он может быть, должен принять определенную среду исполнения; Я думаю (но я не уверен), стандарты C++ не определяют, как должно выполняться время выполнения, или даже как класс или объект «выполняется на низком уровне», поэтому, если нет контекста, ... – ShinTakezou

0

Моя сборка немного ржавая, но первая инструкция загружает что-то в EAX ... то, на что указывает содержимое регистра ECX ... но которое является словом (4 байта), смещенным оттуда. Следующая инструкция затем загружает (переписывает) EAX с тем, на что указывает EAX.

Это обозначение (квадратные скобки вокруг второго или «источник» операции этих варисторов) инструкции (нагрузки показывает, что косвенные режимы адресации используются.

Я предполагаю, что это просто способ реализовать тип двоичного указателя. Адрес в регистре ECX может указывать на фрейм стека или, возможно, на некоторый указатель атрибута C++ «this», на который вы ссылались. Этот адрес, в свою очередь, содержит адрес возвращаемого значения Таким образом, этот код вытаскивает адрес в регистр, а затем использует этот адрес в регистре, чтобы вытащить значение (со-попутно в тот же регистр). Этот подход хорош тем, что он сохраняет все остальные регистры.

(Кстати, большинство функций вызова функции x86 --- системные вызовы, вызовы функций DOS и т. Д. Оставляют коды возврата функций или системные ошибки ... errno в библиотеках stdlib C в регистре EAX).

0

Какой вопрос. Если ecx содержит указатель на «эту» структуру, вы должны знать, как это делается точно. Первый instr, получает второй dword, другой указатель; что это может быть? Мы не можем знать. Этот указатель теперь содержится в eax, вероятно, указывает на другую структуру или что-то еще. Первое указанное значение помещается в eax, и это то, что возвращает func.

ecx -------> dword dataA offset 0 
        dword dataB offset 4 

    mov eax, [ecx + 4] 

eax = dataB ----> dword dataC offset 0 

    mov eax, [eax] 

eax = dataC 

Что именно dataC точно, зависит от множества вещей, которые мы не можем знать.

0

Это сильно зависит от соглашения о вызовах, используемого исходным компилятором. Довольно нормальная установка, например, MSVC должен возвращать 32-битные значения в регистре eax. Ответ @Gregs говорит, что он делает, но, по его словам, значение зависит от знания более подробной информации о языке реализации и компиляторе.

Если вы хотите понять дизассемблирования, попробуйте просмотреть результаты по своему (C/C++) коду. Это действительно единственный способ получить представление о том, что происходит в DLL других.