Овощи.

Тема в разделе "WASM.HEAP", создана пользователем Clerk, 9 окт 2010.

  1. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    green
    Ага, а перед ним стандартный пролог:
    Код (Text):
    1. NtQuerySystemInformation:
    2.     SEH_Prolog()
    3.     ...
    4.     Jmp [DispatchTable + ecx*4]
    5.    
    6. [0]:
    7.     ...
    8.     ExpGetSystemBasicInformation()
    9.     ...
    10.    
    11. ExpGetSystemBasicInformation:
    12.     SEH_prolog()
    13.     ...
    Реально ваша ситуация не нужна.
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    PSR1257
    Ваше решение не работоспособно, так как:
    1. Разность SFN исходной и конечной процедур не постоянна.
    2. Локальные параметры не постоянны.
    3. Адреса не известны.
     
  3. PSR1257

    PSR1257 New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2008
    Сообщения:
    933
    Clerk

    Можете сдампить реальный фрейм и я вам составлю сигну к нему? Примерно 20h-40h от RET_ADDR?

    При применении сигнатуры это разве имеет значение? Мы сканируем стек в поисках фрейма.
     
  4. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    PSR1257
    Не универсально. Вариантов фрейма может быть очень много.
     
  5. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    PSR1257
    Код (Text):
    1. Call stack of main thread
    2. Address    Stack      Procedure / arguments                                              Called from                   Frame
    3. 0012F948   7C91C135   Sfc.0040100A                                                       ntdll.7C91C12F                0012F9BC
    4. 0012F94C   76BE0000     Arg1 = 76BE0000
    5. 0012F950   00242078     Arg2 = 00242078
    6. 0012F954   00242118     Arg3 = 00242118
    7. 0012F9C0   7C91629D   ? ntdll._LdrpWalkImportDescriptor@8                                ntdll.7C916298                0012F9BC
    8. 0012FC70   7C9164B3   ? ntdll._LdrpLoadDll@24                                            ntdll.7C9164AE                0012FC6C
    9. 0012FC74   00000000     Arg1 = 00000000
    10. 0012FC78   00142A68     Arg2 = 00142A68
    11. 0012FC7C   0012FF60     Arg3 = 0012FF60
    12. 0012FC80   0012FF40     Arg4 = 0012FF40
    13. 0012FC84   0012FF5C     Arg5 = 0012FF5C
    14. 0012FC88   00000001     Arg6 = 00000001
    15. 0012FF18   7C801BBD   ? <jmp.&ntdll.LdrLoadDll>                                          kernel32.7C801BB8             0012FF14
    16. 0012FF1C   00142A68     Arg1 = 00142A68
    17. 0012FF20   0012FF60     Arg2 = 0012FF60
    18. 0012FF24   0012FF40     Arg3 = 0012FF40
    19. 0012FF28   0012FF5C     Arg4 = 0012FF5C
    20. 0012FF80   7C801D72   ? kernel32.LoadLibraryExW                                          kernel32.LoadLibraryExA+1A    0012FF7C
    21. 0012FF84   7FFDEC00     FileName = "psapi.dll"
    22. 0012FF88   00000000     hFile = NULL
    23. 0012FF8C   00000000     Flags = 0
    24. 0012FF94   7C801DA8   kernel32.LoadLibraryExA                                            kernel32.LoadLibraryA+28      0012FF90
    25. 0012FF98   0040108A     FileName = "psapi.dll"
    26. 0012FF9C   00000000     hFile = NULL
    27. 0012FFA0   00000000     Flags = 0
    28. 0012FFB0   00401140   Sfc._LoadLibraryA@4                                                Sfc.0040113B                  0012FFAC
    29. 0012FFB4   0040108A     FileName = "psapi.dll"
    30. 0012FFC4   7C817067   Includes Sfc.00401140                                              kernel32.7C817064             0012FFC0
    ESP 0012F948
    EBP 0012F9BC
    EIP 00401046 Sfc._LdrpManifestProberRoutine@12

    http://pastebin.com/1Mm1rQDb
     
  6. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Весь топик не читал. Могу повторить чью-то идею... Решал похожую задачу, искал нужный стековый фрейм путём перебора всех фреймов выше текущего с целью поиска сигнатуры функции (точнее группы сигнатур, т.к. были несколько версий функции). Решение не универсальное, но рабочее для заданных условий.

    UPD: Сигнатуру искал в коде, т.е. смотрел адрес возврата и "осматривал" его окрестность.
     
  7. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    7mm
    Известно:
    o Адрес исходной функции, при выходе из которой необходимо получить управление.
    o Калбэк известен, в нём наш код.
    Не известно:
    o Адреса функций.
    o Вложенность, тоесть число функций.
    o Адреса возврата в функции.
     
  8. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Clerk
    Клерк, если говорить про моё решение схожей задачи, то мне нужна была бы какая-нибудь сигнатура исходной функции, рядом с адресом возврата.

    Код (Text):
    1. BOOL HijackStackFrame(PSTACK_FRAME pStackFrame)
    2. {
    3.     ULONG NewEip = pStackFrame->Eip - 4;
    4.  
    5.     if (REF_DWORD(NewEip) == MAGIC_SING_1) {
    6.         for (int i=0; i<64; i++, NewEip--) {
    7.             if ((REF_DWORD(NewEip) & 0x00FFFFFF) == MAGIC_SIGN_2) {
    8.                 pStackFrame->Eip = NewEip;
    9.                 return TRUE;
    10.             }
    11.         }
    12.     }
    13.  
    14.     return FALSE;
    15. }
    16.  
    17. VOID SearchForCaller()
    18. {
    19.     PSTACK_FRAME pStackFrame;
    20.  
    21.     GET_STACK_FRAME(pStackFrame);
    22.     while (pStackFrame->Ebp) {
    23.         if (HijackStackFrame(pStackFrame)) {
    24.             return;
    25.         }
    26.         pStackFrame = (PSTACK_FRAME)pStackFrame->Ebp;
    27.     }
    28. }
     
  9. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    7mm
    Ваше решение не рабочее. Сигнатуры не известны, так как не известны адреса возврата.
     
  10. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Ну вам же в динамике надо, универсально =) Тогда да, моё решение покатит в случае, если получится динамически определять сигнатуру. Мне нужно было в статике всё это решить, т.е. я взял дизасм и выбрал из функции сигнатуру. Только не пойму, почему "сигнатуры не известны, так как не известны адреса возврата"? По-моему, такому подходу похрен на количество и качество промежуточных функций - вы сигнатурой определяете одну единственную, целевую (исходную).
     
  11. PSR1257

    PSR1257 New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2008
    Сообщения:
    933
    Clerk

    Спасибо, надеюсь что в короткое время дам ответ. Идейка не новая и опробованная - 7mm к примеру юзал - по всем ощущениям должно прокатить. Не прокатит - так и отпишу.
     
  12. PSR1257

    PSR1257 New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2008
    Сообщения:
    933
    Clerk

    Вот пример фильтра: Предполагаем что верхний элемент в данный момент в S (0012F948):

    Код (Text):
    1. 0012F948   7C91C135   ; Элемент принадлежит IB ntdll или даже >>24 == 0x7C.
    2. 0012F94C   76BE0000   ;  Тут наверное 0xFFFF == 0x0000, надо экспериментировать
    3. 0012F950   00242078   ; Нужно знать что это, но уже можно >>24 == 0x00
    4. 0012F954   00242118   ; Нужно знать что это, но уже можно >>24 == 0x00
    5.                                 ; Возможно также S[i-0x10]&0xFFFF0000 == S[i-0x0C]&0xFFFF0000
    6. 0012F9C0   7C91629D   ; -14h Элемент принадлежит IB ntdll
    7. 0012FC70   7C9164B3   ; -18h Элемент принадлежит IB ntdll
    8. 0012FC74   00000000   ; -1Ch Просто == 0x0000000 или (если счетчик) &0xFF == 0
    9. 0012FC78   00142A68   ; -20h ??
    10. 0012FC7C   0012FF60   ; -24h Возможно (S[i-24h]-S[i-28h]) == 0x20, также S[i-24h] и S[i-28h] принадлежит стеку.
    11. 0012FC80   0012FF40   ; -28h
    12. 0012FC84   0012FF5C   ; -2Ch
    13. 0012FC88   00000001   ; == 00000001
    14. ...
    Ну и так далее.

    PS Как указал 7mm, можно также ходить по предполагаемым адресам в стеке - если это ссылка на конкретный код в Ntdll, то (код вряд ли сильно плавает) это также может быть куском сигны.
     
  13. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    PSR1257
    Я бы смотрел не абсолютные значения в адресов в стеке, а, например, разности между адресами и вершиной.

    UPD: Кстати говоря, вектор таких значений может с достаточной степенью точности идентифицировать целевую функцию.
     
  14. PSR1257

    PSR1257 New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2008
    Сообщения:
    933
    7mm

    Да-да, это я как пример указал - нужно абстрагироваться от конкретного положения модулей в памяти. Допустим если я пишу "адрес принадлежит IB Ntdll", то это имеется в виду для текущей машины и он получен заранее.
     
  15. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Clerk
    Т.е. под "универсальным" Вы подразумеваете решение, которое работает в пределах системного кода windows определённых версий?
    Тогда вопросов нет...
     
  16. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Всем.
    Вот вы предлагаете всякое фуфло. Мой семпл лежит выше, он позволяет решить абсолютно любую в NT подобную задачу(я есчо не сталкивался с теми, которые не могбы посредством этого решить). Ваши способы унылы, сигнатуры там какието не рабочие и прочая ахинея. Семпл в студию.
     
  17. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Клерк, может я чего-то не понимаю. Есть условие:
    - Дана некая целевая функция X, причём её адрес известен.
    - Известно также, что в процессе своей работы эта функция вызывает некий колбэк - Y, наш колбэк.
    Требуется из колбэка Y изменить поведение потока таким образом, чтобы получить управление при возврате в X. Так?..

    Тогда, последовательность вызовов будет следующая:
    Код (Text):
    1. SomeFunction -> X -> A1 -> A2 -> ... -> An -> Y
    При этом, в стеке будет сформирована следующая цепочка стековых фреймов:
    Код (Text):
    1. [SomeFunction(EIP), EBP] -> [X(EIP), EBP] -> [A1(EIP), EBP] -> [A2(EIP), EBP] -> ... [An(EIP), EBP]
    Вся сложность заключается в том, каким образом идентифицировать целевую функцию X, т.е. как определить, что адрес X(EIP), лежащий в стековом фрейме [X(EIP), EBP] принадлежит именно функции X?

    В этом вся проблема что ли?..

    Ну так вам было предложено минимум несколько путей решения этой задачи. Один с использованием кодовых сигнатур, другой - с использованием стековых. Третий - с помощью так вами любимых графов, когда происходит парсинг целевой функции с целью определения процедурных ветвлений.

    Управление на выходе можно получить используя как прямую замену адреса возврата, так и инвалидации оного.

    Короче, что-то я не догоняю, кто тут овощ, кто нет...
     
  18. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    7mm
    Вы овощ тут.
    SomeFunction не известна, откуда вам знать кто сервис или функу какую вызвал. Решения адекватного я не видел, которое можно реально заюзать.
     
  19. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    SomeFunction может и не быть, не суть важно. Или мы друг-друга не понимаем, или все мы немного овощи. Для вас ещё раз: из X может быть выделена сигнатура, чтобы её можно было проверить? Если да, то проверяете в цикле по всем стековым фреймам наличие этой сигнатуры.

    Если нет... Не знаю, может способ с графами и не достаточно универсален, ибо товарищ green указал на возможные сложности, да вы и сами знаете о них. Тогда, может быть стоит попробовать такую штуку:

    Вы в колбеке Y трейсите функцию X, с целью выполнения инструкции call. После этого, производите поиск наличия адреса занесённого в стек в последовательности стековых фреймов, лежащих выше фрейма Y. Если есть такой адрес, то значит, что вы попали в Y из X именно с этого call'а. Если нет, отпускаете поток и ждёте следующего процедурного ветвления.
     
  20. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    7mm
    Мне лень читать всю вашу ахинею, вот http://www.wasm.ru/forum/viewtopic.php?pid=400383#p400383 простейшие задачи три, решение есть ?
    А матчасть всю вашу эту я знаю досконально, я спросил кто может решить проблему.

    Сказано что решить без исключений, какие есчо трассировки.