Как найти слово в dll

trainzment, во-первых, у тебя несколько ошибок в регулярном выражениии.
1) Точка это спецсимвол и его нужно экранировать.
2) Т.к. в аргументе pattern ты передаешь расширение с точкой, то его тоже нужно экранировать с помощью Regex.Escape()
3) Использование (.+?) может потенциально захватить больше чем нужно.
Я бы записал регулярку так:

C#
1
@".(\..)*\[w\]+" + Regex.Escape(pattern)

Во-вторых, с помощью Regex.Match ты поймаешь только первое вхождение, а их может быть больше. Поэтому нужно использовать Regex.Matches и возвращать из функции массив строк.

C#
1
2
3
4
5
static string[] GetPathArray(string line, string pattern)
{
    MatchCollection matches = Regex.Matches(line, @".(\..)*\[w\]+" + Regex.Escape(pattern));
    return matches.OfType<Match>().Select(m => m.Groups[0].Value).ToArray();
}

В-третьих, я бы заменил Encoding.Default на Encoding.ASCII чтобы не зависеть от региональных настроек системы. Т.к. тебе нужны пути состоящие только из латиницы, то ASCII здесь вполне подходит. Код функции Main тогда можно записать так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using (StreamReader str = new StreamReader(@"D:Tempsteam2.dll", Encoding.ASCII))
{
    int totalMatches = 0;
    while (!str.EndOfStream)
    {
        string line = str.ReadLine();
        string[] foundPath = GetPathArray(line, ".cpp");
        if (foundPath.Length > 0)
        {
            totalMatches += foundPath.Length;
            foreach (string path in foundPath)
            {
                Console.WriteLine(path);
            }
        }
        
    }
    Console.WriteLine(totalMatches);
}

Данный код находит 64 строки без всякого мусора.

P.S. Надеюсь ты понимаешь что подобная трактовка бинарного файла как текстового будет работать только для строк в однобайтовой кодировке. Если понадобится искать Unicode строки, то алгоритм существенно усложнится.

Время на прочтение
6 мин

Количество просмотров 2.5K

Как найти зловреда (нет) с WinDbg

Вступление

В этой статье я покажу, как, например, с помощью WinDbg найти, какой такой зловред (или нет) заменил адрес вызова системной функции в DLL, подгружаемым каким-нибудь приложением. Так я, к примеру, искал почему не загружается модуль защиты в конфигурацию 1С.
Для демонстрации нам понадобится приложение, которое загружает пару DLL: одну из них назовём victim (жертва), другую — хищник injector. Последнняя внедряется в жертву, заменяя вызов системной функции (для простоты возьмём Sleep), и будет вызывать AV при определённых условиях (что понадобится в следующей статье).

Т.к. приложения, написанные на Delphi, “не падают” в core-dump из-за необработаных исключений, то наше главное приложение (DLLInjectionDemo) написано на С, линковано ранним связыванием с DLL-жертвой, а для простоты воспроизведения ситуации, будет загружать DLL-injector, переданную в опциях при запуске, и вызывать в ней метод, который навредит жертве. Конкретно для этой статьи нам подошло бы приложение, написанное на любом языке программирования, но убьём двух зайцев сразу.

Исходные коды приложений написаны на C и Delphi 10.3 Rio Community Edition, и компилируются MinGW и Delphi, как для Win32, так и для Win64 (а также FPC в Lazarus-е).

Итак компилируем обе DLL и главное приложение

> msbuild /t:build victim.dproj /p:Platform=Win32;Config=Debug;DCC_Exeoutput=.
> msbuild /t:build injector.dproj /p:Platform=Win32;Config=Debug;DCC_Exeoutput=.
> mingw32-make

для сборки make-ом от MinGW нужно прописать его в PATH, конечно

и запускаем главное приложение без параметров:

C:Usersdemo>DLLInjectionDemo.exe
Sleeping 100 milliseconds
Done!

Затем запускаем с параметрами -L injector (напомню, что это для того, чтобы эмулировать поведение, когда у приложения уже что-то не так перед вызовом нужной функции)

c:Usersdemo>DLLInjectionDemo.exe -L injector
Loading injector
Searching...
oleaut32.dll
advapi32.dll
user32.dll
kernel32.dll
kernel32.dll
user32.dll
version.dll
kernel32.dll
kernel32.dll
netapi32.dll
oleaut32.dll
Injected
Sleeping 100 milliseconds
New sleep instead of 100
Done!

Тут мы видим, что наше приложение ведёт себя странно, и вместо Sleep происходит что-то неожиданное. Мы смотрим в код нашего приложения и ничего не понимаем (а также представим, что это происходит со слов пользователя программы). Тогда мы просим пользователя снять дамп приложения с помощью менеджера задач (и да, я не сделал GUI-версию, так что, для того, чтобы можно было снять дамп приложения во время его работы, я добавил ключ -i(interactive)). Так что запускаем

c:Usersdemo>DLLInjectionDemo.exe -i -L injector
Loading injector
Searching...
oleaut32.dll
advapi32.dll
user32.dll
kernel32.dll
kernel32.dll
user32.dll
version.dll
kernel32.dll
kernel32.dll
netapi32.dll
oleaut32.dll
Injected
Sleeping 100 milliseconds
New sleep instead of 100
Done!
Press ENTER...

Приложение работает (в данном случае просто ждёт ввода пользователя). Снимаем дамп этого процесса: вызываем диспетчер задач, закладку процессы, находим процесс, правая кнопка мыши, в меню выбираем “Создать файл дампа процесса…”, ждём показа сообщения о завершении снятия дампа и из него копируем или запоминаем путь к файлу дампа.

Затем берём в руки отладчик WinDbg, и открываем в нём этот дамп:

из меню FileOpen Crash Dump (Ctrl+D)

или из командной строки сразу:

%PROGRAM FILES%Windows Kits10Debuggersx64windbg.exe" -z C:UsersdemoApp DataLocalTempDLLInjectionDemo.DMP

Loading Dump File [C:UsersalexAppDataLocalTempDLLInjectionDemo.DMP]
User Mini Dump File with Full Memory: Only application data is available

Symbol search path is: srv*
Executable search path is: 
Windows 7 Version 7601 (Service Pack 1) MP (4 procs) Free x64
Product: WinNt, suite: SingleUserTS
Machine Name:
Debug session time: Thu Jul  4 08:46:18.000 2019 (UTC + 3:00)
System Uptime: 17 days 12:25:45.404
Process Uptime: 0 days 0:00:10.000
........................
For analysis of this file, run !analyze -v
ntdll!NtRequestWaitReplyPort+0xa:
00000000`77bcddfa c3              ret

подсказке For analysis of this file, run !analyze -v пока следовать не будем (хотя любопытствующие могут и последовать, ничего страшного не произойдёт).

Нас интересует IAT — таблица адресов импорта (Import Address Table) — DLL, в которой произошла подмена адреса (почему? потому что мы знаем, что сами хотим заменить адрес в IAT 😉 ). К счастью, для анализа всех PE-структур загруженных модулей (будь то DLL или процесс) отладчик WinDbg из Windows 10 SDK (который легко и непринуждённо ставится в том числе и на Windows 7) уже имеет встроенные средства, не вынуждая нас самим отправляться на “странные берега”, как бы мы это сделали в WinDbg 6, например.

Так что воспользуемся своим счастьем. Сначала найдём адреса загруженных модулей:

lm

0:000> lm
start             end                 module name
00000000`003b0000 00000000`003db000   injector   (deferred)             
00000000`00400000 00000000`00412000   DLLInjectionDemo   (deferred)             
00000000`00520000 00000000`00616000   victim     (deferred)             
00000000`6e580000 00000000`6e5b4000   libmingwex_2   (deferred)             
00000000`72870000 00000000`72886000   netapi32   (deferred)             
...

Nota bene: На 32-битной ОС адреса, естественно отличаются от 64-битных…

Убеждаемся, что наши DLL загружены, нам нужна IAT жертвы, для этого достаточно выполнить команду !dh с ключом -a:

!dh 009c0000 -a

или можно прям

!dh victim -a

0:000> !dh victim -a

File Type: DLL
FILE HEADER VALUES
     14C machine (i386)
       A number of sections
5E5F4251 time date stamp Wed Mar  4 09:53:21 2020

       0 file pointer to symbol table
       0 number of symbols
      E0 size of optional header
    A18E characteristics
            Executable
            Line numbers stripped
            Symbols stripped
            Bytes reversed
            32 bit word machine
            DLL

OPTIONAL HEADER VALUES
     10B magic #
    2.25 linker version
   CE400 size of code
   1BA00 size of initialized data
       0 size of uninitialized data
   CF79C address of entry point
    1000 base of code
         ----- new -----
0000000000400000 image base
    1000 section alignment
     200 file alignment
       2 subsystem (Windows GUI)
    5.00 operating system version
    0.00 image version
    5.00 subsystem version
   F6000 size of image
     400 size of headers
       0 checksum
0000000000000000 size of stack reserve
0000000000000000 size of stack commit
0000000000100000 size of heap reserve
0000000000001000 size of heap commit
       0  DLL characteristics
   DD000 [      A4] address [size] of Export Directory
   DA000 [    105C] address [size] of Import Directory
   F3000 [    2A00] address [size] of Resource Directory
       0 [       0] address [size] of Exception Directory
       0 [       0] address [size] of Security Directory
...

листаем до таблиц импорта kernel32.dll (в которой находится нужная нам функция Sleep)

Nota bene: На 32-битной ОС количество секций_IMAGE_IMPORT_DESCRIPTOR отличается от таковых на 64-битной. Последнее, вероятно, связано с разницей компиляторов Delphi для этих платформ.

...
  _IMAGE_IMPORT_DESCRIPTOR 00000000005fa03c
    kernel32.dll
              005FA398 Import Address Table
              005FA11C Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

       003C7C7C    0 Sleep
       76EE184A    0 VirtualFree
       76EE1832    0 VirtualAlloc
       76EE16DC    0 lstrlenW
       76EE4422    0 VirtualQuery
       76EE110C    0 GetTickCount
...

Видим, что базовый адрес этой функции отличается от

базового адреса `kernel32.dll`

0:000> !dh kernel32

File Type: DLL
FILE HEADER VALUES
     14C machine (i386)
       4 number of sections
5708A7E3 time date stamp Sat Apr  9 10:57:39 2016

...
         ----- new -----
0000000076ed0000 image base
...

т.е. 0000000076ed0000

Найдём куда же ведёт этот адрес, другими словами — какому модулю он принадлежит?

В WinDbg команда lm имеет опцию а для этого:

0:000> lma 003C7C7C    
Browse full module list
start             end                 module name
00000000`003b0000 00000000`003db000   injector   (deferred)             

Ага, вот кто виноват! Только нам как будто непонятно что это за модуль. Посмотрим пристальней (укажем ключ v для lm)

0:000> lma 003C7C7C v
Browse full module list
start             end                 module name
00000000`003b0000 00000000`003db000   injector   (deferred)             
    Image path: z:habrDLLInjectionDemoinjector.dll
    Image name: injector.dll
    Browse all global symbols  functions  data
    Timestamp:        Wed Mar  4 09:53:12 2020 (5E5F4248)
    CheckSum:         00000000
    ImageSize:        0002B000
    Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4
    Information from resource tables:

А вот где находится наш виновник!

Image path: C:Usersdemoinjector.dll

Дальше выясняем уже откуда он взялся и как его удалить, но это уже история нас не касается.

Вот так и мне в реальных условиях достаточно быстро удалось найти на предустановленной ОС от производителя некую странную DLL, которая перехватывала вызов функции WriteFile.

Приложение из этой статьи я использую в следующей, в которой хочу показать читателю, как можно с помощью WinDbg выяснить почему (или хотя бы примерно где) приложение упало с Access Violation, произошедшим в DLL, написанном на Delphi, когда удалённая отладка недоступна по какой-либо причине. При том, что Delphi не имеет средств анализа дампа приложения, и не умеет генерировать PDB-файлы.


Форум программистов Vingrad

Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы
Создание опроса
> Поиск функции в .dll библиотеке, с помощью Dependency Walker 

V

   

Опции темы

MarkHunt
Дата 14.6.2013, 19:06 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Новичок

Профиль
Группа: Участник
Сообщений: 23
Регистрация: 7.3.2013

Репутация: нет
Всего: нет

Здравствуйте! Заранее извиняюсь, если я ошибся разделом форума.
В общем у меня следующая проблема.
У меня есть некая dll библиотека, из которой мне нужно вызвать определённые функции. И мне нужно узнать точные названия этих функций и типы и кол-во параметров, которые нужно передать в них, ну и получить какой-то результат. Так вот, я почитал в интернете, что можно возпользоваться программой Dependency Walker, для того чтобы посмотреть какие функции имеются в dll файле. Но я не понял как пользоваться этой программой, чтобы найти то, что мне нужно.
Чтобы немного разобраться в программе, я для примера попробовал посмотреть файл user32.dll. Я точно знаю, что в этой библиотеке есть функция LockWorkStation, которая блокирует комп (её ещё можно вызвать клавишами Win + L). Ну, допустим я хочу найти эту функцию в библиотеке, узнать какие параметры в неё можно передавать, что она будет возвращать мне и т.д. И можно ли вообще сделать такое? В общем когда я открываю user32.dll с помощью этой программы, вижу такую картину. Но что делать дальше?
user posted image
Может быть есть кто-то, кто встречался с подобым или просто знает что-то из этой области? Заранее, благодарен за помощь.

Это сообщение отредактировал(а) MarkHunt – 14.6.2013, 22:41

PM MAIL   Вверх
feodorv
Дата 14.6.2013, 22:23 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
****

Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45

В программе два раза кликните мышкой по интересующей Вас функции, откроется браузер с соответствующей страницей англоязычной MSDN. Там и прочитаете про параметры вызова функции.
(Картинки не видно)))

——————–

Напильник, велосипед, грабли и костыли – основные инструменты программиста…

PM MAIL   Вверх
MarkHunt
Дата 14.6.2013, 22:53 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Новичок

Профиль
Группа: Участник
Сообщений: 23
Регистрация: 7.3.2013

Репутация: нет
Всего: нет

Цитата(feodorv @  14.6.2013,  22:23 Найти цитируемый пост)
Картинки не видно

Странно, конечно. Перезалил на другой хостинг, может сейчас будет видна.

Цитата(feodorv @  14.6.2013,  22:23 Найти цитируемый пост)
В программе два раза кликните мышкой по интересующей Вас функции, откроется браузер с соответствующей страницей англоязычной MSDN.

Что-то не нашёл, куда эт так кликать нужно.

Добавлено через 9 минут и 48 секунд
Кстати, вообще можно ли узнать как-то, какие функции есть в dll-ке и как их использовать, без справочника (с помощью той же программы например)? Или обязательно нужно иметь API к dll файлу?

PM MAIL   Вверх
feodorv
Дата 14.6.2013, 23:14 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
****

Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45

Цитата(MarkHunt @  14.6.2013,  23:53 Найти цитируемый пост)
Перезалил на другой хостинг, может сейчас будет видна.

Теперь видно)))

Цитата(MarkHunt @  14.6.2013,  23:53 Найти цитируемый пост)
Что-то не нашёл, куда эт так кликать нужно.

На панели справа, где список функций.

Цитата(MarkHunt @  14.6.2013,  23:53 Найти цитируемый пост)
Кстати, вообще можно ли узнать как-то, какие функции есть в dll-ке и как их использовать, без справочника (с помощью той же программы например)? 

Список экспортируемых и импортируемых функций (то есть их имена) доступен в dll. А вот параметры вызова, возвращаемое значение (в C) etc в dll не пишется (да и зачем???). Подобную информацию можно получить из .h файла.

——————–

Напильник, велосипед, грабли и костыли – основные инструменты программиста…

PM MAIL   Вверх
MarkHunt
Дата 14.6.2013, 23:46 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Новичок

Профиль
Группа: Участник
Сообщений: 23
Регистрация: 7.3.2013

Репутация: нет
Всего: нет

feodorv, спасибо. Наконец-таки разобрался где эти функции искать  smile Просто, у меня на картинке, справа два списка функций, и я сначала не понял в какой именно список смотреть. Оказывается надо было слева (в дереве объектов) выбрать именно user32.dll, тогда справа верхний список пропадёт, а останется только нижний. В нём то и будет список функций из user32.dll.

У меня ещё небольшой вопрос  smile 
Обязательно ли прилагается к .dll-файлу .h-файл, или .h-файл может и вовсе отсутствовать?

PM MAIL   Вверх
feodorv
Дата 15.6.2013, 01:41 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
****

Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45

Цитата(MarkHunt @  15.6.2013,  00:46 Найти цитируемый пост)
Обязательно ли прилагается к .dll-файлу .h-файл, или .h-файл может и вовсе отсутствовать? 

Нет, не обязательно. Вижу такие варианты:

  • библиотека является системной, тогда соответствующий .h файл прилагается к компилятору или является частью какого-либо DSK. Если в соответствующем .h файле не описана экспортируемая из dll функция (для Microsoft дело обычное), то тогда на помощь приходит интернет (впрочем, он всегда приходит на помощь, особенно в случае поиска примера применения искомой функции)
  • библиотека является плагином (как вариант – COM сервером), тогда .h файл (скорее всего) будет отсутствовать, так как соглашения о вызовах и параметрах задаётся самой программой, к которой эта dll идёт плагином
  • библиотека идёт в составе стороннего программного продукта, тогда всё зависит от разработчика (обычно смысла в предоставлении внутренней информации нет, соответственно, нет и .h файла)
  • библиотека предназначена для использования третьими лицами, вот тогда .h файл существенно необходим

В любом случае .h файл нужен только на этапе компиляции той или иной программы. Когда компиляция позади, .h уже не нужен.

——————–

Напильник, велосипед, грабли и костыли – основные инструменты программиста…

PM MAIL   Вверх
MarkHunt
Дата 15.6.2013, 08:00 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Новичок

Профиль
Группа: Участник
Сообщений: 23
Регистрация: 7.3.2013

Репутация: нет
Всего: нет

feodorv, большое спасибо, за толковое объяснение

PM MAIL   Вверх
xvr
Дата 16.6.2013, 12:01 (ссылка)
|    (голосов:1)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
****

Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223

Цитата(feodorv @  15.6.2013,  01:41 Найти цитируемый пост)
библиотека является плагином (как вариант – COM сервером),

Хочу добавить пару слов к этому варианту. 

Если библиотека является COM сервером, то в ней может присутствовать Type Library (а может и не присутствовать). Если она есть, то из нее можно извлечь практически полную информацию о классах и методах этой библиотеки. Попробуйте открыть вашу dll как Type Library в утилите OLE-COM Object Viewer (идет в составе MS VS и в MS SDK)

PM MAIL   Вверх



















Ответ в темуСоздание новой темы
Создание опроса
Правила форума “C/C++: Системное программирование и WinAPI”

Fixin

GremlinProg

xvr

feodorv

  • Большое количество информации и примеров с использованием функций WinAPI
    можно найти в

    MSDN

  • Описание сообщений, уведомлений и примеров
    с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в

    MSDN Control Library

  • Непосредственно, перед созданием новой темы, проверьте заголовок
    и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля “Название темы”, обратите внимание
    на наличие и содержание панели “А здесь смотрели?”,
    возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится
    проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code],
    или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей
    ссылкой, расположенной напротив названия темы.
  • Один топик – один вопрос!
  • Перед тем как создать тему –

    прочтите это
    .

На данный раздел распространяются

Правила форума

и

Правила раздела С++:Общие вопросы

.


Если Вам понравилась атмосфера форума, заходите к нам чаще!
С уважением,
Chipset,
Step,
Fixin,
GremlinProg,
xvr.
feodorv.

 

0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »

Возможно этот вопрос ранее освещался….
я создаю библиотеку классов .net framework следующей структуры

public class1{
   метод1();
   метод2();
}

и собираю ее.
Далее я создаю консольное приложение и хочу написать функцию которая прочтет эту dll и выведит назнание класса и методов… пытаюсь хотя-бы считать все содержимое

using (BinaryReader reader = new BinaryReader(File.Open(pathAll, FileMode.Open)))
            {
                while (reader.PeekChar() > -1)
                {
                    Console.WriteLine(reader.ReadString());
                }
            }

И разумеется я получаю бред. Подскажите, как быть?

задан 24 авг 2020 в 14:11

parabol's user avatar

aepot's user avatar

aepot

45.1k5 золотых знаков22 серебряных знака50 бронзовых знаков

ответ дан 24 авг 2020 в 14:13

3

        Assembly SampleAssembly = Assembly.LoadFrom(pathAll);

        Console.WriteLine(SampleAssembly.GetName());
        foreach (Type oType in SampleAssembly.GetTypes())
        {
            Console.WriteLine(oType.Name);

            foreach(MemberInfo members in oType.GetMembers())
            {
                Console.WriteLine("    " + members.Name);
            }
            Console.WriteLine();
        }

ответ дан 24 авг 2020 в 14:46

parabol's user avatar

Я перепробовал много методов, но я все еще запутался.
я заменяю «слово» на символ и строку var.
я поместил слово из x в другой var, но это не удалось.
что не так с этим кодом?

#include <iostream>
#include <fstream>
using namespace std;
int main() {
char x[99];
fstream file;
file.open("data.txt",ios::in);
for (int i=1 ; !file.eof() ; i++) {
file.getline(x,99,' ');
if(x=="word")
cout << "found";}
file.close();
return 0;
}

-3

Решение

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

    #include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{
cout  << "Write the path of the filen" ;
string path ;
cin >> path ;

ifstream file(path.c_str()) ;

if(file.is_open()) //checking if files exists
{
cout << "Write the word you're searching forn" ;
string word ;
cin >> word ;

int countwords = 0 ;
string candidate ;
while( file >> candidate ) // for each candidate word read from the file
{
if( word == candidate ) ++countwords ;
}

cout << "The word '" << word << "' has been found " << countwords << " times.n" ;
return 0;
}
else
{
cout << "Error! File not found!n" ;
return 1 ;
}
}

0

Другие решения

Других решений пока нет …

Добавить комментарий