Количество параметров api функций

Тема в разделе "WASM.BEGINNERS", создана пользователем kaledonia007, 18 авг 2010.

  1. kaledonia007

    kaledonia007 New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2010
    Сообщения:
    35
    Собственно проблема в следующем - имеется название api функции а надо узнать количество её параметров.
    Вопрос вроде бы простой но на практике никак это реализовать не получается - если искать конец функции( retn n), дизассемблизируя код в библиотеках, то тут основная проблема-дойти до этого retn потому как это тогда придётся выполнять последовательно команды а не просто превращать шестнадцатиричные коды в команды ассемблера.

    Вот например когда я в delphi набираю какую-нибудь функцию, то мне тут же высвечивается количество параметров и даже их названия - видимо он читает это из какой-то базы данных.
     
  2. v_over

    v_over New Member

    Публикаций:
    0
    Регистрация:
    18 авг 2010
    Сообщения:
    18
    Считает из базы, а именно из объявления в заголовках.
     
  3. kaledonia007

    kaledonia007 New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2010
    Сообщения:
    35
    Эти заголовки в самих dll хранятся или где?
     
  4. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Подобные задачи невозможно решить статически не используя граф. Создаёте базовый граф(Nesting Level = 1) и трассируете его, выполняя поиск инструкции Ret N. Для этого движка http://files.virustech.org/indy/Code/XcptGp/ калбэк будет элементарным, просто юзаете IsRetOpcode() и извлекаете размер.
     
  5. gorodon

    gorodon New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2009
    Сообщения:
    301
    kaledonia007
    Когда вы работаете в среде разработки (delphi в частности) то интерфейсы функций загружаются из специальных файлов (посмотрите в папке delphi\lib\) - не зря же вы пишите что-то типа:
    uses
    Windows, Messages, Dialogs, StdCtrls....;

    После сборки dll в ней в прямом виде нет информации об интерфейсах экспортируемых функций (зависит от конвенций вызова) - здесь надо анализировать код... можно определить кол-во и размер переменных... возьмите IDA - попробуйте...
     
  6. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    А может не надо.
     
  7. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Код (Text):
    1. ; +
    2. ; o !GP_PARSE_SEPARATE
    3. ;
    4. GpTraceCallback:
    5.     %GET_CURRENT_GRAPH_ENTRY
    6. GpTraceCallbackInternal proc uses ebx esi edi GpEntry:PVOID, ArgsCount:PVOID
    7.     mov esi,GpEntry
    8.     mov ebx,ArgsCount
    9.     test dword ptr [esi + EhEntryType],TYPE_MASK    ; !HEADER_TYPE_LINE
    10.     jne Exit
    11.     cmp dword ptr [ebx],-1
    12.     mov edi,BLOCK_HEADER._Size[esi]
    13.     mov esi,BLOCK_HEADER.Address[esi]
    14.     jne Exit
    15. Ip:
    16.     invoke QueryPrefixLength, Esi
    17.     movzx ecx,byte ptr [esi + eax]
    18.     cmp cl,0C3H ; retn
    19.     je ip_ret
    20.     cmp cl,0CBH ; retf
    21.     je ip_ret
    22.     cmp cl,0C2H ; retn x
    23.     je ip_ret_x
    24.     cmp cl,0CAh ; retf x
    25.     je ip_ret_x
    26.     Call VirXasm32
    27.     test eax,eax
    28.     jz Exit
    29.     add esi,eax
    30.     sub edi,eax
    31.     ja Ip
    32. Exit:
    33.     ret
    34. ip_ret:
    35.     xor eax,eax
    36.     jmp Store
    37. ip_ret_x:
    38.     movzx eax,word ptr [esi + eax + 1]
    39. Store:
    40.     shr eax,2
    41.     mov dword ptr [ebx],eax
    42.     jmp Exit
    43. GpTraceCallbackInternal endp
    Вызываем так:
    Код (Text):
    1. Local ArgsCount:ULONG
    2.     lea eax,ArgsCount
    3.     mov ArgsCount,-1
    4.     push eax
    5.     %GET_GRAPH_ENTRY GpTraceCallback
    6.     push eax
    7.     push GpBase ; Graph base addr.
    8.     Call GpTrace
    Получаем число параметров в ArgsCount.
     
  8. fsd

    fsd New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2010
    Сообщения:
    353
    N может быть разным, нужно еще модификацию esp учитывать
    + размеры параметров могут быть не только 4 байта
     
  9. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    fsd
    Для stdcall пример привидите системного кода, для которого нужно учитывать esp'mod.
     
  10. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    fsd
    В NT размер параметра не может быть не 4 байта, так как архитектура требует выравнивание стека на 4 байта. Изучайте матчасть, только потом лечите.
     
  11. fsd

    fsd New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2010
    Сообщения:
    353
    Иди ты наверное в гости
    p.s. Вопрос никак не касался каких то там выравниваний, положить в стек можно и 2 байта
     
  12. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    fsd
    Можно но не юзается, а значит и не нужно.
     
  13. qwe8013

    qwe8013 New Member

    Публикаций:
    0
    Регистрация:
    28 май 2009
    Сообщения:
    198
    fsd
    Положить-то можно, но api требует выравнивание на 4, так что если параметр-word он будет выровнен нулями.
     
  14. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    Clerk
    Как всегда в ударе! С учётом того что любой параметр можно представить как DWORD открываются интересные перспективы по универсальным хукам...
    А топик стартер видно просто спросил как узнать параметры функции по её названию... Вкл. метод дедукции с учётом темы дельфи...
    Делаем вывод: http://msdn.microsoft.com/ru-ru/default.aspx ему в помощь ;)
     
  15. ptr

    ptr New Member

    Публикаций:
    0
    Регистрация:
    14 мар 2009
    Сообщения:
    130
  16. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Опишу кратко движок, мб кто юзать будет. Архитектура проста и логична.
    В данном случае базовый граф это список описателей каждой инструкции, причём только её размера, поэтому и базовый. Позволяет оптимально решить многие задачи, например:
    o Определение принадлежности инструкции графу, в частном случае процедуре. Определять вызывающий калбэк код.
    o Искать ссылки на инструкции.
    o Определять начало процедур, их размер и тп.
    o Разделять процедуры на разных уровнях вложенности.
    o Отделять процедуры от стороннего кода.
    o Выполнять всевозможный анализ кода, поиск приватных ссылок, переменных и процедур.
    Все инструкции разделены на 4 условных типа, это безусловные ветвления(jxx), условные ветвления(jcc, jcx), процедурные ветвления(call) и линейные инструкции, не изменяющие непосредственно Ip(Ip' = Ip + OpSize). Так как граф занимает много памяти, то в целях оптимизации группа из нескольких линейных инструкций описывается одним описателем(в теле линейного блока нет меток, тоесть ветвлений в этот блок не на начало его), это задаётся при создании графа. Каждый описатель это структура содержащая следующую информацию(http://files.virustech.org/indy/Code/XcptGp/Table.inc):
    o Ссылку на инструкцию.
    o Размер блока/инструкции.
    o Ссылку на описатель следующей инструкции.
    o Ссылку на описатель предыдущей инструкции.
    o Для ветвлений адрес куда выполняется ветвление.
    o Ссылку на описатель инструкции, на которую происходит ветвление.
    o Пользовательские данные и различные флажки.
    Все описатели в графе связаны между собой ссылками. Тоесть выполнено абстрагирование от кода. Полноценный граф, в отличие от базового содержит более подробную информацию об инструкциях, что реализуется не расширением описателей, а введением ссылок на расширенную информацию, извлекаемую дизассемблером. Это излишне для прикладных задач. На все свободные поля описателей налаживается маска, это сделано в целях оптимизации. Тоесть граф должен быть выравнен в памяти на границу 4'х байт, при этом младшие биты ссылок свободны и заполнены флажками. Младшие два бита описателя определяют его тип. При создании графа его размер не известен. По этой причине буфер в котором создаётся граф должен иметь в конце не доступную или стророжевую страницу(PAGE_NOACCESS/PAGE_GUARD). При обращении к этой странице буфер может быть расширен http://files.virustech.org/indy/Code/XcptGp/, http://files.virustech.org/indy/Code/IDP/Bin/Graph/Dasm/Belong/.
    Трассировка графа - перечисление описателей графа(http://files.virustech.org/indy/Code/XcptGp/Temp/GrpTrace.asm), причём это не просто перечисление подряд идущих описателей, а логичное перечисление, при котором вначале перечисляются описатели кода до безусловного ветвления, либо окончания линейного блока, после чего начинается трассировка первой ветви, на которую обнаружено условное/процедурное ветвление и тд. Трассировщик помечает перечисленные описатели выполняя инверсию флажка, это ставит запрет на следующие действия:
    o Рекурсивный вызов трассировщика.
    o Неожиданное прекращение трассировки, это выход из трассировочного калбэка, либо исключения. Для обхода этого можно выполнить цикл очистки флажка трассировщика в графе, после исполнения трассировки.
    Такого типа трассировка является медленной. Может использоваться быстрая трассировка, она не логична и это простое перечисление подряд идущих описателей:
    Код (Text):
    1. GpDirectSearchEntryReferenceInternal proc uses ebx GpBase:PVOID, GpLimit:PVOID, GpEntry:PVOID
    2.     mov ebx,GpBase
    3. Check:
    4.     cmp GpLimit,ebx
    5.     ja @f
    6.     xor eax,eax
    7.     jmp Exit
    8. @@:
    9.     cmp GpEntry,ebx
    10.     mov eax,dword ptr [ebx + EhEntryType]
    11.     je Next
    12.     mov ecx,dword ptr [ebx + EhFlink]
    13.     and ecx,NOT(TYPE_MASK)
    14.     cmp GpEntry,ecx
    15.     je Save
    16.     and eax,TYPE_MASK
    17.     jz Next
    18.     cmp eax,HEADER_TYPE_JXX
    19.     mov ecx,dword ptr [ebx + EhBranchLink]
    20.     je IsValid
    21.     test dword ptr [ebx + EhBranchType],BRANCH_DEFINED_FLAG
    22.     jz Next
    23. IsValid:
    24.     and ecx,NOT(TYPE_MASK)
    25.     cmp GpEntry,ecx
    26.     je Save
    27. Next:
    28.     add ebx,ENTRY_HEADER_SIZE
    29.     jmp Check
    30. Save:
    31.     mov eax,ebx
    32. Exit:
    33.     ret
    34. GpDirectSearchEntryReferenceInternal endp
    Флажки и структуры определены в хидере.