Программно узнать количество параметров функции

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by hiphop191817, 15 Aug 2010.

  1. hiphop191817

    hiphop191817 New Member

    Joined:
    25 Apr 2009
    Messages:
    26
    Likes Received:
    0
    Reputations:
    0
    Дано: название библиотеки и название какой-то функции из этой библиотеки(например GlobalRealloc из kernel32.dll)
    Задача: программно узнать количество параметров этой функции.
     
  2. BrainDeaD

    BrainDeaD Elder - Старейшина

    Joined:
    9 Jun 2005
    Messages:
    774
    Likes Received:
    292
    Reputations:
    214
    используй System.Reflection

    что-то вроде:
    Code:
    Assembly asm = Assembly.Load(“kernel32.dll”);
    Type[] typelist = asm.GetTypes();
    foreach (Type type in typelist)
    {
    MethodInfo[] mlist = type.GetMethods();
    foreach (MethodInfo m in mlist)
    {
    ParameterInfo[] pi = m.GetParameters();
    }
    }
    
     
  3. Irdis

    Irdis Elder - Старейшина

    Joined:
    6 Feb 2006
    Messages:
    248
    Likes Received:
    52
    Reputations:
    3
    Ну ооочень сомневаюсь, что такое прокатит; kernel32.dll это же не # сборка, а нечто С подобное, которое про типы вообще первый раз слышит.
    => typelist будет пуст;
    (хотя может и сообразит .net; но это будет сверхъестественно)
    Тут скорее надо как то через winApi доставать список экспортируемых функций и т.д...
     
    #3 Irdis, 15 Aug 2010
    Last edited: 15 Aug 2010
  4. BrainDeaD

    BrainDeaD Elder - Старейшина

    Joined:
    9 Jun 2005
    Messages:
    774
    Likes Received:
    292
    Reputations:
    214
    я так понял, это был всего лишь пример. именно для kernel32 это действительно может не работать, не пробовал.
    для таких вещей есть http://www.pinvoke.net/
     
  5. hiphop191817

    hiphop191817 New Member

    Joined:
    25 Apr 2009
    Messages:
    26
    Likes Received:
    0
    Reputations:
    0
    А через таблицу экспорта(или другие элементы pe формата) никто не знает как?
    Необязательно приводить код, можно просто сам алгоритм
     
  6. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    В таблице экспорта не содержится никакой информации об аргументах или возвращаемом значении функциии. Узнать число аргументов можно лишь проанализировав код функции. Все stdcall-функции (все WinAPI являются таковыми) обязаны чистить за собой стек после передачи в них параметров перед завершением исполнения. Соответственно, если после исполнения функции стек стал короче на 8 байт (относительно начала тела функции) - у функции 1 параметр, если на 12 байт - 2 параметра, на 16 - 3, и так далее. Не могу сказать, как это точно определить, потому что вытаскивать параметры из стека можно не одним способом, а ведь в функции могут быть еще локальные переменные, которые тоже требуют места в стеке, и которые по окончании ее исполнения удаляются, и все это надо учитывать...
     
    #6 GRRRL Power, 16 Aug 2010
    Last edited: 16 Aug 2010
    1 person likes this.
  7. flacs

    flacs Member

    Joined:
    28 Jan 2009
    Messages:
    81
    Likes Received:
    31
    Reputations:
    6
    Проанализировал 5 случайно взятых функций, из библиотеки kernel32.dll, как и сказал GRRRL Power, все WinAPI функции являются stdcall
    За это отвечается asm инструкция
    , где после нее указывается размер насколько стек чистить,
    Если учесть что каждый параметр передает туда лишь указатель (а указатель у нас размере 4 байта), то можно слегкостью расчитать сколько параметров содержит функция.
    Например GlobalAlloc
    Содержит два аргумента, -> в теле ее функции имеется "логичная" инстуркция
    Все что тебе нужно это продиасмить код функции, найти опкод интскции retn, и retn %n div 4%. Я не знаю является ли этод метод универсальным, проверил лишь на 5 случайных функциях либы kernel32.dll.
     
    1 person likes this.
  8. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Если предположить, что все WinAPI функции используют исключительно её (и не используют всяких pop, sub esp и подобных манипуляций с переданными параметрами), то анализ несколько упрощается. Но эта инструкция может встретиться и посередине функции, а не в самом её конце. Да и дойти до этой инструкции не слишком просто программно, придется анализировать все предыдущие инструкции, потому что они все разной длины, то есть писать небольшой дизассемблер, видимо.
    В функциях без аргументов может использоваться просто retn/ret (опкод C3).
    А есть же еще функции с произвольным числом параметров, вроде wsprintf...
     
    #8 GRRRL Power, 16 Aug 2010
    Last edited: 16 Aug 2010
  9. desTiny

    desTiny Elder - Старейшина

    Joined:
    4 Feb 2007
    Messages:
    1,006
    Likes Received:
    444
    Reputations:
    94
    для системных библиотек есть pdb.
     
  10. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    1) просто так зная DLL ты не сможешь узнать кол-во параметрво для функции, если конечно либа не в специфическом сишном формате, когда имена импорта имеют описание аргументов.
    2) бери исходники любого пабликовского криптора который умеет работать с таблицей импорат и выдирай оттуда функцию обхода импорта. Кстати я тут выкладывал функцию для сырой загрузки DLL и вот там я пробегался по импорту, чтобы найти адрес нужной функции. так что там можешь выбрать механизм получения имен.
    3) как выше люди сказали чтобы узнать кол-во аргументов нужны или хидеры или исходники или отладочные символы или на крайняк lib файлы полученные после компила.
    4) ну или анализировать либу, на предмет определенного компилятора и анализить заголовок функции, определяя ручками сколько данных в стеке было заюзайно. для сишный и дельфовых либ можно такое замутить. но очень муторно.