Великий и могучий EBP+4

Тема в разделе "WASM.BEGINNERS", создана пользователем virooz, 26 май 2010.

  1. virooz

    virooz New Member

    Публикаций:
    0
    Регистрация:
    26 май 2010
    Сообщения:
    5
    есть код на delphi

    Код (Text):
    1. function GetCallModuleName: string;
    2. var
    3.   module : Cardinal;
    4.   path : string;
    5. begin
    6.   asm
    7.     mov eax, [ebp+4]
    8.     and eax, 0FFFFF000h
    9.     @1: cmp word ptr [eax], 5A4Dh
    10.     je @2
    11.     sub eax, 1000h
    12.     jmp @1
    13.     @2: mov edx, [eax+3Ch]
    14.     add edx, eax
    15.     cmp dword ptr [edx], 4550h
    16.     jne @1
    17.     mov module, eax
    18.   end;
    19.   SetLength(path, MAX_PATH);
    20.   SetLength(path, GetModuleFileName(module, pchar(path), MAX_PATH));
    21.   Result := path;
    22. end;
    в итоге увидим имя модуля который вызвал эту функцию

    вопрос:
    как переделать функцию так, чтобы она возвращала имя модуля для функции в стеке на уровень ниже?
    то есть не для функции которая вызвала GetCallModuleName а для функции которая вызвала функцию которая вызвала GetCallModuleName :)
     
  2. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Если гарантированно есть стековые кадры (а они, судя по всему, есть), то так:

    Код (Text):
    1. mov eax, [ebp]
    2. mov eax, [eax+4]
    3. and eax, 0FFFFF000h
     
  3. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Както так:
    Код (Text):
    1. STACK_FRAME struct
    2. rEbp        PVOID ? ; PSTACK_FRAME
    3. rEip        PVOID ?
    4. STACK_FRAME ends
    5. PSTACK_FRAME typedef ptr STACK_FRAME
    6.  
    7. Local LdrEntry:PLDR_DATA_TABLE_ENTRY
    8.     mov ecx,NestingLevel
    9.     mov ebx,ebp
    10.     jecxz Ip
    11.     assume ebx:PSTACK_FRAME
    12. @@:
    13.     mov ebx,[ebx].rEbp
    14.     loop @b
    15. Ip:
    16.     invoke LdrFindEntryForAddress, [ebx].rEip, addr LdrEntry
    17.     test eax,eax
    18.     jnz Error
     
  4. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    Вот извращенцы - есть ведь спец. созданные мелкомягкими для этого функции в ntdll.
     
  5. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    d2k9
    RtlCaptureStackBackTrace() и RtlGetCallersAddress() сводятся к RtlWalkFrameChain(), а последняя сделана весьма хитрым образом. Проверяется вхождение адреса в проекцию не сканом базы данных загрузчика, а таблицы RtlpStkDllRanges в RtlpStkIsPointerInDllRange(), она заполняется сразу после проецирования модулей. Обычно это работает, но так всякие крипторы коих уже немеряно про эту переменную ничего не знают, посему функция будет лгать, хотя проекция модуля имеется и вход в лдр настроен. Следует использовать самостоятельную реализацию для бактрейса.