Итак, используя IDA для дизассемблирования dll, я наткнулся на эту функцию класса:
mov eax, [ecx+4]
mov eax, [eax]
retn
Я знаю, что ecx
означает this
, а eax
— это возвращаемое значение, но я не понимаю, что оно возвращает. Любая помощь?
Итак, используя IDA для дизассемблирования dll, я наткнулся на эту функцию класса:
mov eax, [ecx+4]
mov eax, [eax]
retn
Я знаю, что ecx
означает this
, а eax
— это возвращаемое значение, но я не понимаю, что оно возвращает. Любая помощь?
class C
{
int a;
int *b; // ecx+4
int get_b()
{
return *b;
}
}
Конечно, настоящий тип a
и *b
неизвестен, но оба они 32-битные. a
также может быть указателем на VMT, если в классе есть виртуальные методы или деструкторы.
a
в моем примере).
- person Vladimir Panteleev; 29.06.2010
Эта функция загружает указатель (в eax
) по смещению 4 из того, на что указывает ecx
. Затем следует этот указатель для загрузки 32-битного значения в eax
, которое возвращается из функции.
Это то, что делает функция, но невозможно сказать, что это означает, без дополнительного контекста.
Моя сборка немного заржавела, но первая инструкция что-то загружает в EAX... что-то, на что указывает содержимое регистра ECX... но это слово (4 байта), смещенное от него. Следующая инструкция загружает (перезаписывает) EAX тем, на что указывает EAX.
Это обозначение (квадратные скобки, окружающие вторую или «исходную» операцию этих инструкций MOV (загрузка) указывает на то, что используются режимы косвенной адресации.
Я предполагаю, что это просто способ реализовать своего рода двойную косвенность. Адрес в регистре ECX может указывать на кадр стека или, возможно, на некоторый указатель атрибута C++ "this", на который вы ссылались. Этот адрес, в свою очередь, содержит адрес возвращаемого значения. Таким образом, этот код извлекает адрес в регистр, а затем использует этот адрес в регистре для извлечения значения (попутно в тот же регистр). Этот подход удобен тем, что сохраняет все остальные регистры.
(Кстати, большинство парадигм вызова функций x86 --- системные вызовы, вызовы функций DOS и т. д. оставляют коды возврата функций или системные ошибки... errno в библиотеках stdlib C, в регистре EAX).
Что за вопрос. Если ecx содержит указатель на структуру "this", вы должны точно знать, как это делается. Первый instr получает второе двойное слово, еще один указатель; что это может быть? Мы не можем знать. Этот указатель, который теперь хранится в 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, зависит от многих вещей, которые мы не можем знать.
Это сильно зависит от соглашения о вызовах, используемого исходным компилятором. Довольно нормальная настройка, например. MSVC должен возвращать 32-битные значения в регистре eax. Ответ @Gregs говорит, что он делает, но, как он говорит, смысл зависит от знания более подробной информации о языке реализации и компиляторе.
Если вы хотите понять дизассемблирование, попробуйте просмотреть результаты в своем собственном (C/C++) коде. Это действительно единственный способ получить представление о том, что происходит в чужих DLL.