Форум программистов, компьютерный форум, киберфорум
Программирование драйверов
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
0 / 0 / 0
Регистрация: 12.08.2019
Сообщений: 3
1

Как управлять процессом компиляции и сборки драйвера

12.08.2019, 13:56. Показов 1764. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте.

Некоторое время назад, появилось у меня желание заняться декомпиляцией одного драйвера. Зачем мне это нужно? - да из спортивного интереса, хочу понять как и что этот драйвер делает. Это занятие оказалось весьма увлекательным, декомпилированный исходник постепенно увеличивается, а код драйвера, получаемый при компиляции этого исходника, при определенных условиях, зачастую совпадает (или почти совпадает) с кодом исходного драйвера.

Но, гладко получается не все, в связи с чем прошу у Вас помощи.

Для начала о средствах разработки, посредством которых я работаю:
- Windows Driver Kit (WDK 7600.16385.1);
- Microsoft Visual Studio 2005;
- Visual DDK, который производит некоторую интегрирацию WDK и VS.

Вопрос первый. В коде исходного драйвера, точкой входа в драйвер является следующий код:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 EntryPoint:
        pushfd
        mov ecx,[esp]
        xor dword ptr [esp],00200000h
        popfd
        pushfd
        pop eax
        cmp eax,ecx
        jz  L0001645C
        mov eax,00000001h
        push    ebx
        cpuid
        pop ebx
        and eax,00000F00h
        cmp eax,00000500h
        jc  L0001645C
        jmp L00016288
 L0001645C:
        mov eax,C0000001h
        retn    0008h
где на 17-й строке (jmp L0001645C) происходит переход на функцию DriverEntry (которую писал непосредственно разработчик), и я предполагаю, что приведенный выше кода добавлен компилятором в процессе компиляции.



Когда я компилирую восстановленный мной исходник посредством только WDK (VS используется в качестве редактора текста исходника), точка входа в драйвер, так же имеет участок кода добавленный компилятором (правда выполняющий другие функции):
Assembler
1
2
3
4
5
6
7
 EntryPoint:
        mov edi,edi
        push    ebp
        mov ebp,esp
        call    SUB_L00011105
        pop ebp
        jmp L00010BC0
в котором переход на функцию DriverEntry, написанную мной, происходит в 7-й строке.

Ну и собственно сам вопрос, можно ли, при компиляции, как либо управлять кодом, который добавляется компилятором, или это не управляемый процесс, жестко зашитый в глубины компилятора?

Вопрос второй. Связка VS и WDK (посредством Visual DDK) позволяет, при разработке драйвера, использовать компилятор VS и линкер WDK для создания файла драйвера. В таком варианте, с настройкой оптимизации компилятора для получения минимального размера конечного файла, мне удалось получить код, почти идентичный коду исходного драйвера (за исключением куска кода по которому задан первый вопрос, которого просто нет при компиляции средствами VS). И собственно вопрос, можно ли как либо произвести настройку оптимизации компилятора WDK?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.08.2019, 13:56
Ответы с готовыми решениями:

Как из .NET управлять другим процессом?
В общем-то считал, что в .НЕТ это сделать легче легкого. Как всегда, пока не взялся реализовать)) ...

Ошибка компиляции и сборки
Здравствуйте! Пытаюсь начать изучать assembler...написал первую программу. Вот текст: BIT32; ...

Нюансы ручной сборки, линковки и компиляции
Решив учить более подробно программирование, начав с c++, установил Linux Mint. Смотря первый...

Roslyn, (статическая?) линковка сборки при компиляции
У меня в программе генерируется некоторый код на C# и затем компилируется при помощи...

5
Эксперт Hardware
Эксперт Hardware
6103 / 2347 / 390
Регистрация: 29.07.2014
Сообщений: 3,108
Записей в блоге: 4
13.08.2019, 06:34 2
Цитата Сообщение от alex2711 Посмотреть сообщение
и я предполагаю, что приведенный выше кода добавлен компилятором в процессе компиляции
..не правильно вы полагаете.
это не компилятор вставляет, а разраб проверяет процессор на поддержку инструкции CPUID. Если она НЕ поддерживается - в строке(9) выходим из драйвера. Дальше со-строки(10) вызывается CPUID с EAX=1 или "Features". cmp eax,00000500h проверяет биты [11:8], а это семейство процессора "Family" (Intel/AMD etc).

Цитата Сообщение от alex2711 Посмотреть сообщение
так же имеет участок кода добавленный компилятором (правда выполняющий другие функции):
это пролог и эпилог функции,
который добавляет компилятор, если функция имеет аргументы.
Если аргументов нет, то эта батва не добавляется компилем.

Добавлено через 11 минут
кстати, в сишном хидере "ntstatus.h" перечисляются все коды-ошибок..
например в строке(19) первого листинга имеем mov eax,C0000001h и дальше ret
открываем хидер и видим:
C++
1
2
3
4
5
#define STATUS_UNSUCCESSFUL     0xC0000001
// MessageId: STATUS_UNSUCCESSFUL
// MessageText:
// {Operation Failed}
// The requested operation was unsuccessful.
0
0 / 0 / 0
Регистрация: 12.08.2019
Сообщений: 3
13.08.2019, 13:18  [ТС] 3
Цитата Сообщение от R71MT Посмотреть сообщение
..не правильно вы полагаете.
это не компилятор вставляет, а разраб проверяет процессор на поддержку инструкции CPUID.
Согласен, моё предположение о том, что данный код вставлен компилятором, не верно. Да, это разработчик предусмотрел проверку того, на каком процессоре запускается драйвер, и если процессор не подходящий, то запуск драйвера прекращается.

Но...

Если исходить из того, что код, добавленый используемым мной компилятором является прологом (и это только пролог, а ни как не ...пролог и эпилог функции так как переход непосредственно на саму функцию, которой является NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath), происходит в последней, 7-й строке данного кода jmp L00010BC0), то, код проверки процессора (код из первого листинга, из исходного драйвера), добавлен разработчиком как пролог к функции, причем к точно такой же функции NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) (которая к слову имеет аргументы), и переход на которую осуществляется почти в самом конце пролога (в строке 17 jmp L00016288), если процессор подходящий (следом за этим переходом, в конце этого кода, только выход из драйвера при неподходящем процессоре).

И теперь переформулирую свой вопрос, как можно повлиять на пролог, который добавляется компилятором, мне нужно что бы перед вызовом функции вызывался пролог, который написал я сам, допустим проводящий проверку подходит ли данный процессор для этого драйвера? Это возможно?
0
Эксперт Hardware
Эксперт Hardware
6103 / 2347 / 390
Регистрация: 29.07.2014
Сообщений: 3,108
Записей в блоге: 4
13.08.2019, 15:39 4
Цитата Сообщение от alex2711 Посмотреть сообщение
и это только пролог, а ни как не ...пролог и эпилог функции
с чего-бы это?
пролог - push ebp --> mov ebp,esp, а эпилог - pop ebp --> ret
если учесть call в строке(5), то рано или поздно pop ebp получит управление.
только не понятно, куда подевался тут ret.

Цитата Сообщение от alex2711 Посмотреть сообщение
как можно повлиять на пролог
оформлять функцию в виде функции без параметров.
если параметры всё-таки нужны, то засылать их в стек до вызова функции
мне непонятно одно.. зачем вы ведёте борьбу за лишние 4-байта?
ну есть этот пролог, да и пусть будет.. кому он мешает?
0
0 / 0 / 0
Регистрация: 12.08.2019
Сообщений: 3
13.08.2019, 16:17  [ТС] 5
Увы и ах, ret в данном участке отсутствует. Вот он более полно:
Assembler
1
2
3
4
5
6
7
8
9
 EntryPoint:
        mov edi,edi
        push    ebp
        mov ebp,esp
        call    SUB_L00011105
        pop ebp
        jmp L00010BC0
        int3
        int3
call SUB_L00011105 вызывает следующую функцию (которую тоже писал не я, ее добавил компилятор):
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 SUB_L00011105:
        mov eax,[L0001103C]
        mov ecx,BB40E64Eh
        test    eax,eax
        jz  L00011117
        cmp eax,ecx
        jnz L00011131
 L00011117:
        mov eax,[ntoskrnl.exe!KeTickCount]
        mov eax,[eax]
        xor eax,L0001103C
        mov [L0001103C],eax
        jnz L00011131
        mov eax,ecx
        mov [L0001103C],eax
 L00011131:
        not eax
        mov [L00011040],eax
        retn
ну а по jmp L00010BC0 идет переход на DriverEntry, которую писал я:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
 L00010BC0:
        mov edi,edi
        push    ebp
        mov ebp,esp
        sub esp,00000050h
        mov eax,[L0001103C]
        xor eax,ebp
        mov [ebp-04h],eax
        push    ebx
        push    esi
        mov esi,[ebp+08h]
        push    edi
        mov edi,[ebp+0Ch]
        pushfd
        mov ecx,[esp]
        xor dword ptr [esp],00200000h
        popfd
        push    SWC00011004__Registry_Machine_Software
        lea eax,[ebp-38h]
        push    eax
        mov [L000110D4],esi
        call    [ntoskrnl.exe!RtlInitUnicodeString]
        lea eax,[ebp-38h]
        mov [ebp-48h],eax
        lea eax,[ebp-50h]
        push    eax
        xor ebx,ebx
        push    00000001h
        push    esi
        mov dword ptr [ebp-50h],00000018h
        mov [ebp-4Ch],ebx
        mov dword ptr [ebp-44h],00000240h
        mov [ebp-40h],ebx
        mov [ebp-3Ch],ebx
        call    [ntoskrnl.exe!ZwOpenKey]
        test    eax,eax
        jz  L00010C4A
        push    esi
        call    [ntoskrnl.exe!ZwClose]
        mov esi,C0000001h
        push    esi
        push    00010001h
        call    SUB_L000105BC
        mov eax,esi
        jmp L00010D2C
 L00010C4A:
        push    edi
        call    SUB_L000109BC
        cmp eax,ebx
        jz  L00010C5C
        push    eax
        push    00010002h
        jmp L00010CCF
 L00010C5C:
        mov eax,L00010998
        mov [esi+70h],eax
        mov [esi+38h],eax
        mov [esi+40h],eax
        mov dword ptr [esi+28h],L00011050
        call    SUB_L0001082A
        test    eax,eax
        jnz L00010CDE
        push    ebx
        push    L000110C4
        push    L0001104C
        push    L000110CC
        call    [ntoskrnl.exe!PsGetVersion]
        mov eax,[L000110CC]
        movzx   ecx,al
        mov [L000110D0],ecx
        mov ecx,[L0001104C]
        cmp eax,00000005h
        jnz L00010CB7
        cmp ecx,ebx
        jz  L00010CC0
        cmp ecx,00000001h
        jz  L00010CC0
        cmp ecx,00000002h
        jz  L00010CC0
 L00010CB7:
        cmp eax,00000006h
        jnz L00010CDE
        cmp ecx,ebx
        jnz L00010CDE
 L00010CC0:
        mov eax,[L000110C0]
        cmp [eax],ebx
        jz  L00010CD6
        push    ebx
        push    00010004h
 L00010CCF:
        call    SUB_L000105BC
        jmp L00010CDE
 L00010CD6:
        push    00000001h
        push    ebx
        call    SUB_L000107E2
 L00010CDE:
        xor ecx,ecx
        lea eax,[ebp-20h]
 L00010CE3:
        mov dl,cl
        inc dl
        inc ecx
        mov [eax],dl
        inc eax
        cmp cx,0019h
        jc  L00010CE3
        push    00000019h
        lea eax,[ebp-20h]
        push    eax
        push    00000002h
        push    00000001h
        call    SUB_L000104E4
        xor ecx,ecx
        lea eax,[ebp-30h]
 L00010D05:
        mov dl,cl
        add dl,1Ah
        inc ecx
        mov [eax],dl
        inc eax
        cmp cx,0029h
        jc  L00010D05
        push    00000029h
        lea eax,[ebp-30h]
        push    eax
        push    00000006h
        push    00000005h
        call    SUB_L000104E4
        mov dword ptr [esi+34h],L00010962
        xor eax,eax
 L00010D2C:
        mov ecx,[ebp-04h]
        pop edi
        pop esi
        xor ecx,ebp
        pop ebx
        call    SUB_L00010D42
        leave
        retn    0008h
И вот здесь, в конце, появляется ret

Мне это нужно, не для экономии нескольких байт, я хочу восстановить исходник и во всех подробностях понять как и что делает этот драйвер.

Добавлено через 14 минут
Смысл того что я делаю, сводится к тому, чтобы выставить настройки компиляции такими, какими они были у разработчика. Вероятно, со временем, я сам смогу найти ответы на свои вопросы, но с Вашей помощью, я надеюсь, эти ответы будет проще отыскать.

P.S. На всякий случай, для данной функции я не в состоянии передать параметры, функция вызывается операционной системой при старте, при загрузке драйвера.
0
6770 / 2739 / 384
Регистрация: 17.02.2013
Сообщений: 4,047
14.08.2019, 20:32 6
Цитата Сообщение от alex2711 Посмотреть сообщение
Ну и собственно сам вопрос, можно ли, при компиляции, как либо управлять кодом, который добавляется компилятором, или это не управляемый процесс, жестко зашитый в глубины компилятора?
Косвенно можно влиять на этот процесс. Ну ты-же видишь, что первой-же проверкой после EntryPoint является проверка запущен ли декомпилированный драйвер на пне или не на пне. Если он запущен на компьютере с 386 или 486 процессором, то драйвер немедленно посылает операционку на буквы C0000001h. А в коде твоего варианта этой проверки нет. Ну так значит ты компилируешь свой код без указания целевого процессора, а разработчик указал компилятору целевой процессор 586.

Добавлено через 17 минут
Цитата Сообщение от alex2711 Посмотреть сообщение
- Windows Driver Kit (WDK 7600.16385.1);
Тут такой компилятор
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.207 for 80x86
Что-то я не вижу в нем других опций кроме
/arch:<SSE|SSE2> minimum CPU architecture requirements, one of:
SSE - enable use of instructions available with SSE enabled CPUs
SSE2 - enable use of instructions available with SSE2 enabled CPUs

Наверно разработчик использовал VS. Укажи в настройках этой студии целовой процессор Пень = 586. Есть наверно у нее такие настройки. И посмотри появится ли у тебя эта преамбула с инструкцией cpuid при компиляции.
0
14.08.2019, 20:32
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.08.2019, 20:32
Помогаю со студенческими работами здесь

Ошибки при компиляции сборки декомпилированной DnSpy
Декомпилировал Assembly-CSharp с помощью DnSpy, и когда я хочу скомпилировать мне выдаёт кучу...

Изменить версию сборки при каждой компиляции
Здравствуйте! Подскажите пожалуйста как сделать так чтобы при каждой компиляции изменялся номер...

Научите делать (интегрировать в PE и обычные сборки драйвера и программы)
Кто научит делать сборку PE windows, с автоустановкой интегрированных драйверов и программ. +...

Какие есть сборки для установки без компиляции?
Есть ли какие-нибудь сборки для моментальной установки без сборки оси? Мне как новичку сложно с...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru