x86-64: как функции выковырять адрес кто ея вызвал?

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

x86-64: как функции выковырять адрес кто ея вызвал?

Сообщение Cheb » 10.08.2015 18:52:32

Для i386 хакнул просто: объявил как cdecl, потом сделал mov eax, [ebp + 4].
Для 64 бит тупо скопипастил.
Но недавно прослышал, что под x86-64 компилятор вежливо игнорирует все соглашения вызова. Встал вопрос: будет ли работать mov rax, [rbp + 8] ?

См.: используется при составлении сообщения об экранированной ошибке для отслеживания точки перехода между исполняемыми модулями. Ктулхуфтагн: экзешник вызывает функцию в DLL, которая вызывает функцию в экзешнике, внутри каждой функции экранируются исключения, чтобы потом поднять обратно после возврата из неё посредством AfterEfCheck. ExpExpAddress() парсит Dwarf2 блок и выдаёт имя файла и строки исходника.

Код: Выделить всё
  procedure AfterEfCheck; cdecl;
  var
    CallerAddr: pointer;
    thread: TBackgroundThread = nil;
    pes: PMotherSehState;
  begin
    asm
    {$ifdef cpu64}
     mov rax, [rbp + 8]
     mov [CallerAddr], rax
    {$else}
     mov eax, [ebp + 4] //read the caller's EIP
     mov [CallerAddr], eax
    {$endif}
    end;

    pes:= GetExceptionState();

    if pes^.IsModuleThread and Assigned(Module.ThreadManager) then begin
      thread:= Module.ThreadManager.GetCurrentThread;
      if not Assigned(thread) then begin
        Mother^.State.StateTrashedRestartRequired:= true;
        AddLog('Unable to identify the thread Id=%0 to pass exception to.'
          + #10#13'  Putting the thread in an infinite loop.'#10#13'  %1',
          [pointer(GetCurrentThreadId()), StopDying()]);
        repeat Sleep(1000) until false; //hang the thread;
      end;
    end;

    if pes^.NowDying then
      if pes^.DyingAfterTrueException
      then  Die(RuEn(
        'Исключение коллбэк-функции модуля-матки'#10#13'  принято шлюзом %0',
        'The mother module callback function exception'#10#13'  received at %0'),
        [ExpExpAddress(CallerAddr)])
      else begin
        //re-raise silently
        pes^.NowDying:= true;
        raise exception.create('');
      end;
  end;
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Re: x86-64: как функции выковырять адрес кто ея вызвал?

Сообщение runewalsh » 11.08.2015 12:52:36

Код: Выделить всё
get_caller_addr(get_caller_frame(get_frame))


>RuEn
>NowDying
>DyingAfterTrueException

Костыли-костылики.
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 578
Зарегистрирован: 27.04.2010 00:15:25

Re: x86-64: как функции выковырять адрес кто ея вызвал?

Сообщение Cheb » 11.08.2015 14:19:04

get_caller_addr(get_caller_frame(get_frame))

[facepalm times twenty] :oops: Использую ж такое в 100500 других мест :oops:

Костыли-костылики.

Причём в линуксе, ЕМНИП, всё отлично работало и без оных.
Улыбаемся и благодарим родной мелкософт за замечательный дизайн виндовой SEH системы.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 35

Рейтинг@Mail.ru