Как поставиьт точку останова на функцию?

Тема в разделе "WASM.RESEARCH", создана пользователем drem1lin, 13 окт 2010.

  1. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    Здравствуйте, в общем ситуация такая: есть программа, для работы с аппаратурой, имеющая в своем составе драйвер и длл, и есть некая тестовая программа использующая эту длл. Длл чем-то упакована (PeID пишет что ASPack 2.12, но 3 скачанных мной распаковщика для аспака сказали что тип "аспак не найден, ничего я делать не буду") В лоб IDA ее не открывает, точнее открывает, но там что-то не то, в секции .data расположен код, что указывает на наличие запаковщика. Необходимо достать алгоритм 1й из функций экспортируемых длл. Тестовая программа эту функцию использует.
    Так как необходимая функция работает с аппаратурой, то она должна общаться с драйвером. При анализе драйвера в нем регистрируется 4 обработчика на создание, закрытие, выгрузку драйвера и обработчик IOCTL-кодов.
    Код (Text):
    1. mov     dword ptr [esi+34h], offset UnloadDriver
    2. mov     dword ptr [esi+70h], offset IOCTLDispatcher
    3. mov     dword ptr [esi+38h], offset Create
    4. mov     dword ptr [esi+40h], offset Close
    Я ставил Syser'ом точку останова на обработчик IOCTL (остальные обработчики точно не реализуют нужный функционал), но при вызове интересующей функции он не останавливался(.
    Поэтому возник вариант используя приложение спуститься в библиотеку и посмотреть как там это сделано, но я не понял как это сделать, так как опыта подобного рода у меня очень мало. Приложение написано на C# и в нем есть отдельная кнопка вызывающая интересующую функцию, и я не понял как остановиться на этом нажатии и спуститься в глубь библиотеки. Думал syser'ом поставить точку останова на обработчик кнопки, я нашел этот обработчик в IDA, но не понял какой адрес он имеет и как его узнать. Подскажите, что мне делать в этой ситуации и как добраться до необходимой функции? Если нужны программа/драйвер/библиотека я могу их скинуть.
     
  2. _Unkn0wn_

    _Unkn0wn_ New Member

    Публикаций:
    0
    Регистрация:
    6 окт 2010
    Сообщения:
    19
    drem1lin
    Если функция экспортируется из DLL, то что мешает приаттачиться отладчиком и поставить бряк на ее начало? Или она загружается динамически при нажатии на эту отдельную кнопку? Тогда, соответсвенно, бряк на LoadLibraryExW и после загрузки DLL опять же бряк на функцию.
     
  3. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    можно найти его в отладчике по сигнатуре - берёшь характерную последовательность байт из кода обработчика и ищешь её поиском.
     
  4. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    Что-то я об этом забыл, надо будет попробовать, просто IDA странно отображает ассемблерный код для этого файла. да и в его уникальности я не уверен
     
  5. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    Так библиотека запакована, и понять куда вставить этот бряк я не могу
     
  6. _Unkn0wn_

    _Unkn0wn_ New Member

    Публикаций:
    0
    Регистрация:
    6 окт 2010
    Сообщения:
    19
    Ида вам отображает MSIL. При загрузке нужно выбрать PE. Да и толку ковыряться в этом коде нет.
    У библиотеки есть экспорт? Не припомню пакеров, сносящих таблицу экспорта. Откройте библиотеку в Иде и нажмите ctrl-E. Там должна быть интересющая вас функция. Вычислить ее адрес в уже загруженной длл - не должно представлять проблему.
     
  7. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Точку останова можно поставить на саму ф-ию DeviceIoControl в kernel32.dll, а не в импорте. А при вызове посмотреть и запомнить адрес возврата, если уж очень интересно. Кроме того, для C# есть декомпилятор -- reflector.
     
  8. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    Попробую, спасибо за информацию, завтра отпишусь что получилось
     
  9. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    Я ставил, на него точку останова, но утонул в вызовах, а какой фильтр написать не знаю. Да и драйвер мне сейчас менее интересен чем библиотека
     
  10. Mika0x65

    Mika0x65 New Member

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

    1. Поставить точку останова на CreateFile с целью поймать открытие файла. После этого можно ставить условную точку останова на DeviceIoControl с условием, что [esp + 4] == HANDLE_VALUE.

    2. Более быстрый, но ресурсоемкий вариант: склонировать две VM с чистой XP (как, у вас нет шаблонной VM с чистой XP?! :) ), затем на одну поставить целевую программу и тщательно сверить результаты работы WinObj (или еще как перебрать объекты, не знаю). Тогда получится вычислить имя устройства (символическую ссылку) и поставить условную точку останова на CreateFile. Получить значение HANDLE и действовать по пункту 1.

    Я бы сделал так, но может кто-нибудь предложит более короткий путь?
     
  11. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    У меня есть символическая ссылка, я дизассемблировал драйвер и нашел. Это тоже я попробую и в пятницу отпишусь
     
  12. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    Судя из кода дизассемблированного драйвера и документации IoCreateSymbolicLink:
    Код (Text):
    1. RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\DDCHELPER");
    2. RtlInitUnicodeString(&DestinationString, L"\\Device\\WinI2C");
    3. v6 = IoCreateSymbolicLink(&SymbolicLinkName, &DestinationString);
    то символьная ссылка это "\\??\\DDCHELPER", вспоминая соглашение о занесении параметров, я в Syser поставил следующий брейк поинт: bpx createfilea(w) if *(esp+4)=="\\??". Но отладчик не всплыл ни разу(. Может я что-то не так делаю?
     
  13. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    Я открыл библиотеку в ИДЕ, в таблице экспорта указан адрес 10003670, а как вычислить ее адрес в загруженной длл, для меня это преставляет проблему, я это 1й раз делаю(. Я пытаюсь что-нибудь нагуглить по данному вопросу, но пока не получается
     
  14. _Unkn0wn_

    _Unkn0wn_ New Member

    Публикаций:
    0
    Регистрация:
    6 окт 2010
    Сообщения:
    19
    drem1lin
    Почитайте про RVA и VA. 0x10003670 - это VA. Чтобы получить RVA надо сделать VA - ImageBase. Далее смотрим по какому адресу будет загружена эта длл и прибавляем к нему RVA.
    Базовые вещи конечно нужно почитать. Пе-файлы, адресация и т.п.
     
  15. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    Придется почитать, а как определить куда загружена длл?
     
  16. drem1lin

    drem1lin Member

    Публикаций:
    0
    Регистрация:
    17 мар 2009
    Сообщения:
    300
    Продолжая свою тему, я добился некоторого успеха, а точнее я смог достать код необходимой мне функции. Это дизассемблированный листинг из IDA.
    Код (Text):
    1. seg000:100038B0                 public function
    2. seg000:100038B0 function          proc near
    3. seg000:100038B0
    4. seg000:100038B0 arg_0           = dword ptr  4
    5. seg000:100038B0
    6. seg000:100038B0                 push    1198238h ;function name
    7. seg000:100038B5                 call    WriteLogToFile
    8. seg000:100038BA                 mov     eax, [esp+4+arg_0]
    9. seg000:100038BE                 add     esp, 4
    10. seg000:100038C1                 cmp     eax, ds:11A0234h
    11. seg000:100038C7                 jnb     short loc_100038D4
    12. seg000:100038C9                 mov     eax, ds:119FBE0h[eax*4]
    13. seg000:100038D0                 test    eax, eax
    14. seg000:100038D2                 jnz     short loc_100038DC
    15. seg000:100038D4
    16. seg000:100038D4 loc_100038D4:                           ; CODE XREF: function+17j
    17. seg000:100038D4                 mov     eax, 70000018h
    18. seg000:100038D9                 retn    4
    19. seg000:100038DC ; ---------------------------------------------------------------------------
    20. seg000:100038DC
    21. seg000:100038DC loc_100038DC:                           ; CODE XREF: function+22j
    22. seg000:100038DC                 cmp     dword ptr [eax+128h], 0
    23. seg000:100038E3                 jnz     short loc_100038FA
    24. seg000:100038E5                 push    119820Ch    ;error
    25. seg000:100038EA                 call    WriteLogToFile
    26. seg000:100038EF                 add     esp, 4
    27. seg000:100038F2                 mov     eax, 70000021h
    28. seg000:100038F7                 retn    4
    29. seg000:100038FA ; ---------------------------------------------------------------------------
    30. seg000:100038FA
    31. seg000:100038FA loc_100038FA:                           ; CODE XREF: function+33j
    32. seg000:100038FA                 push    esi
    33. seg000:100038FB                 mov     esi, [eax]
    34. seg000:100038FD                 cmp     esi, 200h
    35. seg000:10003903                 jnb     short loc_1000391B
    36. seg000:10003905                 push    11981E8h        ;error
    37. seg000:1000390A                 call    WriteLogToFile
    38. seg000:1000390F                 add     esp, 4
    39. seg000:10003912                 mov     eax, 7000001Ch
    40. seg000:10003917                 pop     esi
    41. seg000:10003918                 retn    4
    42. seg000:1000391B ; ---------------------------------------------------------------------------
    43. seg000:1000391B
    44. seg000:1000391B loc_1000391B:                           ; CODE XREF: function+53j
    45. seg000:1000391B                 cmp     dword ptr [esi], 0
    46. seg000:1000391E                 jz      short loc_10003936
    47. seg000:10003920                 push    1198078h    ;error
    48. seg000:10003925                 call    WriteLogToFile
    49. seg000:1000392A                 add     esp, 4
    50. seg000:1000392D                 mov     eax, 7000001Fh
    51. seg000:10003932                 pop     esi
    52. seg000:10003933                 retn    4
    53. seg000:10003936 ; ---------------------------------------------------------------------------
    54. seg000:10003936
    55. seg000:10003936 loc_10003936:                           ; CODE XREF: function+6Ej
    56. seg000:10003936                 mov     eax, [esi+44h]
    57. seg000:10003939                 push    edi
    58. seg000:1000393A                 push    eax
    59. seg000:1000393B                 call    dword ptr ds:1197044h ; RtlEnterCriticalSession
    60. seg000:10003941                 mov     ecx, [esi+40h]
    61. seg000:10003944                 push    esi
    62. seg000:10003945                 call    ecx
    63. seg000:10003947                 mov     edx, [esi+44h]
    64. seg000:1000394A                 add     esp, 4
    65. seg000:1000394D                 push    edx
    66. seg000:1000394E                 mov     edi, eax
    67. seg000:10003950                 call    dword ptr ds:1197040h ; RtlLeaveCriticalSession
    68. seg000:10003956                 push    edi
    69. seg000:10003957                 push    11981D4h         ; all is ok %x
    70. seg000:1000395C                 call    WriteLogToFile
    71. seg000:10003961                 add     esp, 8
    72. seg000:10003964                 mov     eax, edi
    73. seg000:10003966                 pop     edi
    74. seg000:10003967                 pop     esi
    75. seg000:10003968                 retn    4
    76. seg000:10003968 function          endp
    Как видно из кода, функция 4 раза проверяет введенные параметры и является оболочкой над функцией, которая вызывается по адресу 10003945. Я смог достать этот код сдампив библиотеку, но теперь я не могу понять куда следует вызов call ecx. Отладчиком я выпадаю на этих проверках и даже если Syserом изменяю регистр флагов что бы проити через них, то получаю exсeption (в строке 38dc обращение с адресу 128h, так как eax == 0). И соответственно возникает вопрос как узнать значение ecx? Я пока придумал только 1 способ - как нибудь поставиьт брейкпоинт нафункцию RtlEnterCriticalSection с каким-нибудь фильтром. Есть ли еще другие варианты?