Форум программистов, компьютерный форум, киберфорум
Assembler для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.75/88: Рейтинг темы: голосов - 88, средняя оценка - 4.75
Ушел с форума
Автор FAQ
16279 / 7604 / 1065
Регистрация: 11.11.2010
Сообщений: 13,617
1

А что находится внутри функции MessageBox или как еще можно создать MessageBox?

12.04.2012, 13:58. Показов 16635. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Помните сказку о лягушке-царевне? Что необходимо было сделать, чтобы убить Кащея-бессмертного? ― нужно было сперва с кучей приключений попасть на некий остров, на острове найти дуб, с дуба снять ларец,
«в ларце ― заяц, в зайце ― утка, в утке ― яйцо, в яйце ― игла, а на кончике иглы ― смерть Кащеева...»
Казалось бы, что может быть проще функции MessageBox? Но кто-нибудь задавал себе вопрос ― «а что находится внутри MessageBox?» Может быть это поможет сделать наши программы еще меньше.

Запускаем программу выводящую MessageBox на экран в дебаггере Ollydbg и в тот момент, когда курсор доходит до строки call MessageBoxA нажимаем не на F8 (Step over), а на клавишу F7 (Step into) и оказываемся внутри функции MessageBoxA ― оказывается здесь происходит перекодировка ASCII-строк заголовка и текста сообщений в UNICODE и вызов функции MessageBoxW, снова жмем на F7 ― оказывается внутри MessageBoxW функция MessageBoxExA, которая имеет на один параметр больше, чем MessageBoxA и MessageBoxW и этот параметр (dwLanguageId) равен 0 (LANG_NEUTRAL), остальные же параметры совпадают полностью. Внутри MessageBoxExA находится функция MessageBoxExW. Внутри MessageBoxExW ― функция MessageBoxTimeoutA, у которой на один параметр больше, чем у MessageBoxExW и этот параметр (Timeout) равен -1. Внутри MessageBoxTimeoutA, как можно было догадаться MessageBoxTimeoutW. Внутри MessageBoxTimeoutW - MessageBoxIndirectA эта функция позволяет поменять иконку у MessageBox и может вызвать Справку, но мы оставляем эти параметры с нулевым значением. Внутри MessageBoxIndirectA находится точно такая же но с UNICODE строками функция MessageBoxIndirectW SoftModalMessageBox. У Indy/Clerk я нашел ссылку на NtRaiseHardError ― вызов MessageBox на уровне ядра.

Традиционный способ определения Unicode-строки:
Код
usz dw 'U', 'n', 'i', 'c', 'o', 'd', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g', 0
Меня этот способ не устраивал, поэтому, я написал для этой цели макрос du (define unicode string), чтобы без проблем переводить ASCII-строки в UNICODE-строки
Код
du	macro string
local bslash
bslash = 0
irpc c,<string>
if bslash eq 0
	if '&c' eq "\";;управляющая последовательность символов
	bslash = 1
	elseif '&c' eq "ё"
	db 51h,4
	elseif '&c' eq "Ё"
	db 1,4
	elseif '&c' gt 127
	db ('&c'- 0B0h),4;;кириллица
	else
	dw '&c'          ;;латиница
	endif
else
bslash = 0
	if '&c' eq "n"    ;;  \n = новая строка
        DW 0Dh,0Ah
        elseif '&c' eq "\";;  \\ = обратная косая черта (\)
        dw '\'
        elseif '&c' eq "r";;  \r = возврат каретки
        dw 0Dh
        elseif '&c' eq "l";;  \l = LF
        dw 0Ah
        elseif '&c' eq "s"
        dw 20h
        elseif '&c' eq "c"
        dw 3Bh
        elseif '&c' eq "t";;  \t = табуляция 
        dw 9
	endif
endif
endm
dw 0
endm
этот макрос превращает ASCII-символы латиницы в UNICODE-символы добавлением после кода символа нуля, а для кириллицы заменяет 0 на 4 и сдвигает код символа на 176, в конце UNICODE-строки ставится ноль, терминирующий строку. Всё, что требуется от пользователя ― после du написать строку в угловых скобках. То есть представить Unicode-строку так:
Код
usz: du <Unicode string>
обратите внимание, что после названия строки стоит двоеточие.
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
; masm windows gui #
.686P
.model flat
;include windows.inc
include native.inc
include ntstatus.inc
includelib user32.lib
includelib ntdll.lib
extern _imp__MessageBoxA@16:dword
extern _imp__MessageBoxW@16:dword
extern _imp__MessageBoxExA@20:dword
extern _imp__MessageBoxExW@20:dword
extern _imp__MessageBoxTimeoutA@24:dword
extern _imp__MessageBoxTimeoutW@24:dword
extern _imp__SoftModalMessageBox@4:dword
extern _imp__MessageBoxIndirectA@4:dword
extern _imp__MessageBoxIndirectW@4:dword
extern _imp__NtRaiseHardError@24:dword
;extern _imp__KiFastSystemCall@0:dword
MB_ICONASTERISK     equ 40h 
MB_OK           equ 0
; structures
MSGBOXPARAMSA STRUCT
  cbSize                DWORD      ?
  hwndOwner             DWORD      ?
  hInstance             DWORD      ?
  lpszText              DWORD      ?
  lpszCaption           DWORD      ?
  dwStyle               DWORD      ?
  lpszIcon              DWORD      ?
  dwContextHelpId       DWORD      ?
  lpfnMsgBoxCallback    DWORD      ?
  dwLanguageId          DWORD      ?
MSGBOXPARAMSA ENDS
 
MSGBOXDATA struct       
     params              MSGBOXPARAMSA <>
     pwndOwner           DWORD ?
     wLanguageId         DWORD ?
     pidButton           DWORD ?         ; // Array of button IDs
     ppszButtonText      DWORD ?         ; // Array of button text strings
     cButtons            DWORD ?
     DefButton           DWORD ?
     CancelId            DWORD ?
     Timeout             DWORD ?
MSGBOXDATA ends
; macros
du  macro string
    irpc c,<string>
    db '&c',0
    endm
    dw 0
    endm
.code
start:  xor ebx,ebx
    mov esi,ebx
    push MB_ICONASTERISK or MB_OK
    push offset MsgCaption
    push [Msg+esi*4]
    push ebx
    call _imp__MessageBoxA@16
;---------------------------------------
    inc esi
    push MB_ICONASTERISK or MB_OK
    push offset TitleText
    push [Msg+esi*4]
    push ebx
    call _imp__MessageBoxW@16
;----------------------------------------
    inc esi
    push ebx
    push MB_ICONASTERISK or MB_OK
    push offset MsgCaption
    push [Msg+esi*4]
    push ebx
    call _imp__MessageBoxExA@20
;-----------------------------------------
    inc esi
    push ebx
    push MB_ICONASTERISK or MB_OK
    push offset TitleText
    push [Msg+esi*4]
    push ebx
    call _imp__MessageBoxExW@20
;-----------------------------------------
    inc esi
        push -1
        push ebx
        push MB_ICONASTERISK or MB_OK
        push offset MsgCaption
        push [Msg+esi*4]
        push ebx
        call _imp__MessageBoxTimeoutA@24
;------------------------------------------
    inc esi
        push -1
        push ebx
        push MB_ICONASTERISK or MB_OK
        push offset TitleText
        push [Msg+esi*4]
        push ebx
        call _imp__MessageBoxTimeoutW@24
;------------------------------------------
        sub esp,sizeof(MSGBOXPARAMSA);40
    mov edi,esp
    assume edi:ptr MSGBOXPARAMSA
    mov dword ptr [edi].cbSize,sizeof(MSGBOXPARAMSA)
    mov dword ptr [edi].hwndOwner,ebx
    mov dword ptr [edi].hInstance,400000h
    mov dword ptr [edi].lpszText,offset Msg8
    mov dword ptr [edi].lpszCaption,offset MsgCaption
    mov dword ptr [edi].dwStyle,MB_ICONASTERISK or MB_OK;:= MB_USERICON;
    mov dword ptr [edi].lpszIcon,ebx;:= PCHAR('MYICO');
    mov dword ptr [edi].dwContextHelpId,ebx;:= 0;
    mov dword ptr [edi].lpfnMsgBoxCallback,ebx;:= nil;
    mov dword ptr [edi].dwLanguageId,ebx;:= LANG_NEUTRAL;   
    push edi
        call _imp__MessageBoxIndirectA@4
;--------------------------------------------------------
    mov dword ptr [edi].cbSize,sizeof(MSGBOXPARAMSA)
    mov dword ptr [edi].hwndOwner,ebx
    mov dword ptr [edi].hInstance,400000h
    mov dword ptr [edi].lpszText,offset Msg9
    mov dword ptr [edi].lpszCaption,offset TitleText
    mov dword ptr [edi].dwStyle,MB_ICONASTERISK or MB_OK
    mov dword ptr [edi].lpszIcon,ebx;:= PCHAR('MYICO');
    mov dword ptr [edi].dwContextHelpId,ebx;:= 0;
    mov dword ptr [edi].lpfnMsgBoxCallback,ebx;:= nil;
    mov dword ptr [edi].dwLanguageId,ebx;:= LANG_NEUTRAL;   
    push edi
        call _imp__MessageBoxIndirectW@4
    add esp,sizeof(MSGBOXPARAMSA)
;-------------------------------------------------------------------------
        sub esp,sizeof MSGBOXDATA+8
;  local mbd:MSGBOXDATA
;  local bufid[1]:DWORD
;  local bufstr[1]:DWORD
    lea eax,[esp+4];bufid
    mov dword ptr[eax],1
    mov [esp],offset _OK
        lea edi,[esp+8]
    mov [edi].cbSize,sizeof MSGBOXPARAMSA
    mov [edi].hwndOwner,ebx
    mov [edi].lpszText,offset Msg7
    mov [edi].lpszCaption,offset TitleText
    mov [edi].dwStyle,MB_ICONASTERISK or MB_OK
        assume edi:ptr MSGBOXDATA
    mov [edi].pwndOwner,ebx;0
    mov [edi].wLanguageId,ebx;0
    mov [edi].pidButton,eax
    mov [edi].ppszButtonText,esp;offset bufstr
    mov [edi].cButtons,1
    mov [edi].DefButton,ebx;0
    mov [edi].CancelId,1
    mov [edi].Timeout,-1
    push edi
    call _imp__SoftModalMessageBox@4
    assume edi:nothing
    add esp,sizeof MSGBOXDATA+8
;------------------------------------------------------------------
ShowMessage proc
Local MessageBuffer[38h]:WCHAR;в Num+Num1 в вордах
Local Message[2]:UNICODE_STRING
Local HardErrorPointer[3]:PVOID
;первый параметр
    lea edi,MessageBuffer
    mov Message.Buffer+sizeof(UNICODE_STRING)*0,edi
    mov Message.MaximumLength+sizeof(UNICODE_STRING)*0,Num
    mov Message._Length+sizeof(UNICODE_STRING)*0,Num-2
    lea edx,Message+sizeof(UNICODE_STRING)*0
    mov HardErrorPointer+sizeof(PVOID)*0,edx;pwText
    mov esi,offset MessageText
    mov ecx,Num+Num1
    rep movsb
;второй параметр
    lea edi,MessageBuffer+Num
    mov Message.Buffer+sizeof(UNICODE_STRING)*1,edi
    mov Message.MaximumLength+sizeof(UNICODE_STRING)*1,Num1
    mov Message._Length+sizeof(UNICODE_STRING)*1,Num1-2
    lea edx,Message+sizeof(UNICODE_STRING)*1
    mov HardErrorPointer+sizeof(PVOID)*1,edx;pwCaption
;третий параметр
        mov HardErrorPointer+sizeof(PVOID)*2,MB_ICONASTERISK+MB_OK;uType
        lea edx,HardErrorPointer
    push offset x;куда функция запишет выбранный юзером ответ (если тип, 
;переданный в следующем параметре, предполагает выбор ответа пользователем)
    push ebx;0 варианты ответов
    push edx;указатель на массив параметров
    push 3;общее число параметров
    push 00000011b;маска, еденичные биты которой соответствуют тем 
;параметрам, которые имеют тип PUNICODE_STRING, а нули -- остальным параметрам
    push STATUS_SERVICE_NOTIFICATION;статус ошибки
    call _imp__NtRaiseHardError@24
;--------------------------------------------------
;меняем первый параметр
    lea edi,MessageBuffer
    mov Message.Buffer+sizeof(UNICODE_STRING)*0,edi
    mov Message.MaximumLength+sizeof(UNICODE_STRING)*0,Num3
    mov Message._Length+sizeof(UNICODE_STRING)*0,Num3-2
    lea edx,Message+sizeof(UNICODE_STRING)*0
    mov HardErrorPointer+sizeof(PVOID)*0,edx;pwText
    mov esi,offset MessageText2
    mov ecx,Num3
    rep movsb
        lea edx,HardErrorPointer
    mov eax,0B6h;ID NtRaiseHardError для WinXP
    push offset x
    push ebx
    push edx
    push 3
    push 00000011b
    push STATUS_SERVICE_NOTIFICATION;статус ошибки
    push offset @f
    mov edx,7FFE0300h
    call dword ptr ds:[edx]
@@:
;--------------------------------------------------
;меняем первый параметр
    lea edi,MessageBuffer
    mov Message.Buffer+sizeof(UNICODE_STRING)*0,edi
    mov Message.MaximumLength+sizeof(UNICODE_STRING)*0,Num4
    mov Message._Length+sizeof(UNICODE_STRING)*0,Num4-2
    lea edx,Message+sizeof(UNICODE_STRING)*0
    mov HardErrorPointer+sizeof(PVOID)*0,edx;pwText
    mov esi,offset MessageText3
    mov ecx,Num4
    rep movsb
        lea edx,HardErrorPointer
    mov eax,0B6h;ID NtRaiseHardError для WinXP
    push offset x
    push ebx
    push edx
    push 3
    push 00000011b
    push STATUS_SERVICE_NOTIFICATION;статус ошибки
    push offset @f
    push offset @f
    mov edx,esp
    db 0Fh,34h;sysenter
@@:
;--------------------------------------------------------
    lea edi,MessageBuffer
    mov Message.Buffer+sizeof(UNICODE_STRING)*0,edi
    mov Message.MaximumLength+sizeof(UNICODE_STRING)*0,Num2
    mov Message._Length+sizeof(UNICODE_STRING)*0,Num2-2
    lea edx,Message+sizeof(UNICODE_STRING)*0
    mov HardErrorPointer+sizeof(PVOID)*0,edx;pwText
    mov esi,offset MessageText1
    mov ecx,Num2
    rep movsb
        lea edx,HardErrorPointer
    mov eax,0B6h;ID NtRaiseHardError для WinXP
    push offset x
    push ebx
    push edx
    push 3
    push 00000011b
    push STATUS_SERVICE_NOTIFICATION;статус ошибки
    mov edx,esp
    int 2Eh
    add esp,18h
    leave
    retn
ShowMessage endp
 
MessageText: du <NtRaiseHardError>
Num = $-MessageText
TitleText: du <Iczelion Tutorial #2:MessageBox>
Num1 = $-TitleText
MessageText1: du <int 2Eh>
Num2 equ $-MessageText1
MessageText2: du <KiFastSystemCall>
Num3 equ $-MessageText2
MessageText3: du <sysenter>
Num4 equ $-MessageText3
x dd 0
Msg dd Msg1,Msg2,Msg3,Msg4,Msg5,Msg6,Msg7,Msg8,Msg9
Msg1    db 'MessageBoxA',0
Msg2:   du <MessageBoxW>
Msg3    db 'MessageBoxExA',0
Msg4:   du <MessageBoxExW>
Msg5    db 'MessageBoxTimeoutA',0
Msg6:   du <MessageBoxTimeoutW>
Msg7:   du <SoftModalMessageBox>
Msg8    db 'MessageBoxIndirectA',0
Msg9:   du <MessageBoxIndirectW>
MsgCaption db "Iczelion Tutorial #2:MessageBox",0
_OK:    du <OK>
end start
10
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.04.2012, 13:58
Ответы с готовыми решениями:

MessageBox: Как сделать так, чтобы если окно модальное, при клике на родительское окно MessageBox мигал?
Здравия всем! Никак не найду нужный MB_*, как можно сделать так, чтобы если сделать MessageBox...

Два раза открывается MessageBox.Show после второго вызова MessageBox
Здравствуйте! Подскажите пожалуйста... Мне вот надо было сделать диалоговое окно для ввода данных...

Можно ли с помощью хуков отловить вызовы функций CreateFile или MessageBox
можно ли с помощью хуков отловить допустим функции CreateFile или MessageBox? и какой для этого...

При нажатии в одном messagebox "Нет" всё равно появляется другой messagebox
При удалении записи сделал messagebox с подтверждением Да или Нет. При нажатии Нет всё равно...

20
Charles Kludge
11.08.2014, 18:52     А что находится внутри функции MessageBox или как еще можно создать MessageBox?
  #21

Не по теме:

murderer, можно ещё глянуть в Wine source.

Цитата Сообщение от murderer Посмотреть сообщение
Да хотелось бы прочитать оригинальный мануал
Возьми сырцы виндавса 1.0 - вряд ли там что-то изменилось с годами.:jokingly:

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.08.2014, 18:52

Как создать лимит message messagebox?
У меня проблема с окном сообщения вместо одного message box У меня появляется бесконечное message...

Как создать MessageBox без паузы
когда я вызываю MessageBox, обработка кода останавливается. можно ли как-то вызвать MessageBox,...

Как создать несколько MessageBox.Show?
Помогите пж! Как создать несколько сообщений messagebox? Мне нужно, чтобы вылазило не одно ...

Как создать button для закрытия form (messagebox)?
Подскажите пожалуйста, как прописать button, чтобы при нажатии на него выходило окно &quot;Вы хотите...

MessageBox в новом потоке или как std::async
Хочу немодальный MessageBox, потому запускаю в отдельном потоке. Вот вопрос: 1. Почему если...

Как определить, что сторонний процесс показал MessageBox
Вот запускаю процесс Shell(Path, AppWinStyle.NormalFocus) При запуске мне процесс выдает...


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

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