Студентам с вопросами о лабораторных работах сюда

Тема в разделе "WASM.BEGINNERS", создана пользователем IceStudent, 11 ноя 2006.

  1. Noga

    Noga New Member

    Публикаций:
    0
    Регистрация:
    10 окт 2008
    Сообщения:
    92
    Тоже по этой теме вопросик. А почему у меня masm ругается на push byte ptr [buf_b] ? buf_b db 10 dup(?)
     
  2. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Noga
    Потому что в стек нельзя заносить байты, можно word и dword, но при вызове API стек болжен быть выравнен на dword, иначе будут глюки (поэкспериментируй с MessageBox - на ней это очень наглядно, чтобы увидеть достаточно перед/после invoke сделать push/pop ax), т.е. если заносишь word, то либо заноси их парами, либо выравнивай через sub esp, 2
    В твоём случае правильно
    1. movsx eax, byte ptr [buf_b] ; знаковое число
    push eax
    2. movzx eax, byte ptr [buf_b] ; беззнаковое число
    push eax
    3. push dword ptr [buf_b] ; поместить в стек сразу 4 байта из буфера
     
  3. Max_Cohen

    Max_Cohen New Member

    Публикаций:
    0
    Регистрация:
    10 янв 2009
    Сообщения:
    19
    Адрес:
    Где-то здесь
    Здравствуйте,
    как можно изменить системное время и дату
    Код (Text):
    1. COM asm
    2. ...
    3. code segment
    4. begin:
    5. mov cx, 0101h ; часы и минуты
    6. mov dh, 01h ; секунды
    7. mov ah, 2
    8. int 1ah ;  01:01:01 время
    9. exit:
    10. int 20h
    11. code ends
    12. end begin
    что-то не получается...
     
  4. Noga

    Noga New Member

    Публикаций:
    0
    Регистрация:
    10 окт 2008
    Сообщения:
    92
    Здравствуйте,

    Я бы хотел поподробней изучить адресацию, так как сейчас возникают сложности с использованием регистров при адресации с индексированием. У меня в наличии есть Интеловские маны и Зубков, но к сожалению мне похоже этого - не достаточно. Можете есть какой-нибудь мануал ? Английский - не проблема.
     
  5. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.784
    Noga
    сложность с использованием регистров при адресации с индексированием? при использовании 16 разрядов, наверное? Ищи в сети Пильщиков В.Н."Программирование на языке ассемблера IBM PC"
    а если на пальцах
    база индекс смещение
    BP DI off8
    BX SI off16
    -- --- ---
    то есть под 16 разрядов при косвенной адресации может быть сочетание из базового (BX либо BP)индексного (DI либо SI) и смещения (8- или 16-разрядного смещения либо смещения нет), то есть только [BX+SI+offset] или [BP+SI] или [DI] или [SI] другие регистры (CX, AX, SP, DX) в качестве индексных или базовых использоваться не могут
     
  6. Noga

    Noga New Member

    Публикаций:
    0
    Регистрация:
    10 окт 2008
    Сообщения:
    92
    Mikl___

    Спасибо, почитаю. Но у меня проблема при использовании 32 разрядов. Бывает так, что не хватает регистров и мне интересно, как можно грамотно выйти из этого положения, хочется примеров.
     
  7. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.784
    Noga
    Как-то всё расплывчато. Для подсказки хотелось бы конкретики, пиши в личку
     
  8. KOROL

    KOROL New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2009
    Сообщения:
    1
    Здравствуйте.Недавно начал изучать ассемблер.Пытаюсь по примерам разобраться с защищенным режимом и прерываниями в нем.
    Код (Text):
    1. format binary
    2. use16
    3. org 0x7c00
    4. start:
    5. jmp init
    6. GDT:
    7.   dd 0,0
    8.   code_desc db 0xff,0xff,0x00,0x00,0x00,10011010b,11001111b,0x00
    9.   data_desc db 0xff,0xff,0x00,0x00,0x00,10010010b,11001111b,0x00
    10.   video_desc db 0xff,0xff,0x00,0x80,0x0B,10010010b,01000000b,0x00
    11.   GDT_size equ $-GDT
    12.   label GDTR fword at _GDTR
    13.   _GDTR:
    14.     dw GDT_size-1
    15.     dd GDT
    16. IDT:
    17.   dw int_EOI,0x08,1000111000000000b,0
    18.   dw syscall_handler,0x08,1000111000000000b,0
    19.   dw int_EOI,0x08,1000111000000000b,0
    20.   dw int_EOI,0x08,1000111000000000b,0
    21.   dw int_EOI,0x08,1000111000000000b,0
    22.   dw int_EOI,0x08,1000111000000000b,0
    23.   dw int_EOI,0x08,1000111000000000b,0
    24.   dw int_EOI,0x08,1000111000000000b,0
    25.   dw int8,0x08,1000111000000000b,0
    26.   dw int9,0x08,1000111000000000b,0
    27.   dw int_EOI,0x08,1000111000000000b,0
    28.   dw int_EOI,0x08,1000111000000000b,0
    29.   dw int_EOI,0x08,1000111000000000b,0
    30.   dw exGP_handler,0x08,1000111000000000b,0
    31.   dw int_EOI,0x08,1000111000000000b,0
    32.   dw int_EOI,0x08,1000111000000000b,0
    33.   dw int_EOI,0x08,1000111000000000b,0
    34.   dw int_EOI,0x08,1000111000000000b,0
    35.   dw int_EOI,0x08,1000111000000000b,0
    36.   dw int_EOI,0x08,1000111000000000b,0
    37.   dw int_EOI,0x08,1000111000000000b,0
    38.   dw int_EOI,0x08,1000111000000000b,0
    39.   dw int_EOI,0x08,1000111000000000b,0
    40.   dw int_EOI,0x08,1000111000000000b,0
    41.   IDT_size equ $-IDT
    42. label IDTR fword at _IDTR
    43.   _IDTR:
    44.     dw IDT_size-1
    45.     dd IDT
    46. label REAL_IDT fword at IDT_R
    47. IDT_R:
    48.   dw 0x3FF
    49.   dd 0
    50. init:
    51.   mov ax,3
    52.   int 10h
    53.   mov ax,cs
    54.   mov ds,ax
    55.   mov ss,ax
    56.   mov ax,start
    57.   mov sp,ax
    58.   mov bp,ax
    59.   mov ah,2
    60.   mov al,10
    61.   xor ch,ch
    62.   mov cl,2
    63.   xor dx,dx
    64.   mov bx,start+512
    65.   int 13h
    66.   jnc continue_loading
    67. jmp to_display
    68.   error db 'R',2,'e',2,'a',2,'d',2,' ',2,'e',2,'r',2,'r',2,'o',2,'r',2,' '
    69.   error_len db $-error
    70. to_display:
    71.   mov ax,0xB800
    72.   mov es,ax
    73.   mov si,error
    74.   xor di,di
    75.   mov cx,word [error_len]
    76.   xor ch,ch
    77.   rep movsb
    78.   jmp $
    79. ends:
    80.   rb 510-(ends-start)
    81.   db 0x55,0xAA
    82. continue_loading:
    83.   in al,0x92
    84.   or al,2
    85.   out 0x92,al
    86.   cli
    87.   in al,0x70
    88.   or al,0x80
    89.   out 0x70,al
    90.   lgdt [GDTR]
    91.   lidt [IDTR]
    92.   mov eax,cr0
    93.   inc al
    94.   mov cr0,eax
    95.   jmp 00001000b:PM_entry
    96. use32
    97. PM_entry:
    98.   mov ax,00010000b
    99.   mov ds,ax
    100.   mov ss,ax
    101.   mov ax,00011000b
    102.   mov es,ax
    103. ;  in al,0x70
    104. ;  and al,0x7f
    105. ;  out 0x70,al
    106. ;  sti
    107.    jmp $
    108. ;...
    Запускаю Bochs,на чтении с floopy зацикливается.Не могли бы подсказать где что-то не так?По-моему при
    Код (Text):
    1. mov cr0,eax
    Все понял,пустой дескриптор вещь необходимая.
     
  9. Noga

    Noga New Member

    Публикаций:
    0
    Регистрация:
    10 окт 2008
    Сообщения:
    92
    Здравствуйте,

    Продолжаю свое изучение, наткнулся на странную проблему. А именно после вызова wsprintf - MessageBox появляется без "декораций".

    Код (Text):
    1. .ELSE
    2.         invoke MessageBox,NULL,ADDR buffer,ADDR AppName,MB_SERVICE_NOTIFICATION
    3.         invoke c_Encrypt,ADDR buffer,scount
    4.             invoke wsprintf,ADDR array,ADDR ifmt,pw_hash_res ; Если закоментить - всё ок
    5.         invoke MessageBox,NULL,ADDR array,ADDR AppName,MB_OK
    6. .ENDIF
    7. ........
    8. ;Make simple password hash
    9. c_Encrypt proc e_addr:DWORD, c1_count:DWORD
    10.     xor eax,eax
    11.     mov ecx,c1_count
    12.     mov edi,e_addr
    13.         pw_hash:        
    14.         add al,[edi]
    15.         inc edi
    16.         loop pw_hash
    17.         mov pw_hash_res,al        
    18.     ret
    19. c_Encrypt EndP
     
  10. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.784
    Noga
    После вызова wsprintf необходимо самому чистить стек в данном случае от 3-х параметров (ADDR array,ADDR ifmt,pw_hash_res) -- классически add esp,3*4 или если экономить байты троекратным pop ecx
     
  11. un

    un New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2009
    Сообщения:
    6
    Здравствуйте!
    У меня проблемка с базонезависимом кодом. С помощью статей по этой тематики на вашем сайте и на сайте Bill/TROC навоял програмку.
    Код (Text):
    1. .386
    2.  
    3. .model  flat,stdcall
    4. option  casemap : none
    5.  
    6. include \TEST\MASM32\include\windows.inc
    7.  
    8. MIN_KERNEL_SEARCH_BASE  equ 070000000h
    9. MAX_API_STRING_LENGTH   equ 150
    10.  
    11. .code
    12. main:
    13.     pushad
    14.     call    Delta
    15.  
    16. Delta:
    17.     pop     ebp
    18.     sub     ebp, offset Delta
    19.     push    dword ptr [esp + 20h]
    20.     call    GetKernelBase
    21.     or  eax, eax
    22.     jz  EP
    23.     mov [ebp + dwKernelBase], eax
    24.  
    25.     lea eax, [ebp + offset szCF]            ;CreateFileA
    26.     push    eax
    27.     push    [ebp + dwKernelBase]
    28.     call    GetProcAddr
    29.     mov [ebp + _CF], eax
    30.  
    31.     lea eax, [ebp + offset szEP]            ;ExitProcess
    32.     push    eax
    33.     push    [ebp + dwKernelBase]
    34.     call    GetProcAddr
    35.     mov [ebp + _EP], eax
    36.  
    37.     lea eax, [ebp + offset szRF]            ;ReadFile
    38.     push    eax
    39.     push    [ebp + dwKernelBase]
    40.     call    GetProcAddr
    41.     mov [ebp + _RF], eax
    42.  
    43.     lea eax, [ebp + offset szLoadLibrary]
    44.     push    eax
    45.     push    [ebp + dwKernelBase]
    46.     call    GetProcAddr
    47.     mov [ebp + _LoadLibrary], eax
    48.  
    49.     lea     eax, [ebp + offset szGetProcAddress]
    50.     push    eax
    51.     push    [ebp + dwKernelBase]
    52.     call    GetProcAddr
    53.     mov [ebp + _GetProcAddress], eax
    54.  
    55.     lea     eax, [ebp + offset szUser32]
    56.     push    eax
    57.     call    [ebp + _LoadLibrary]
    58.     mov [ebp + dwUserBase], eax
    59.  
    60.     lea eax, [ebp + offset szMB]            ;MessageBoxA
    61.     push    eax
    62.     push    [ebp + dwUserBase]
    63.     call    GetProcAddr
    64.     mov [ebp + _MB], eax
    65. ;-------------------------------------------> Собственно сома прога
    66.     push    NULL
    67.     push    FILE_ATTRIBUTE_NORMAL
    68.     push    OPEN_ALWAYS
    69.     push    NULL
    70.     push    FILE_SHARE_READ or FILE_SHARE_WRITE
    71.     push    GENERIC_READ
    72.     lea eax, [ebp + offset FileN]
    73.     push    eax
    74.     call    [ebp + _CF]
    75.     mov [ebp + dFile], eax  
    76.  
    77.     push    NULL
    78.     lea eax, [ebp + offset num]
    79.     push    eax
    80.     mov eax, 512
    81.     push    eax
    82.     lea eax, [ebp + offset buf]
    83.     push    eax
    84.     mov eax, [ebp + dFile]
    85.     push    eax
    86.     call    [ebp + _RF]
    87.     mov edx, dword ptr buf+43h ;[ebp + buf+43h]
    88.  
    89.     .IF edx == SN
    90.     push    MB_OK
    91.     lea     eax, [ebp + offset _ttl]
    92.     push    eax
    93.     lea     eax, [ebp + offset _msg]
    94.     push    eax
    95.     push    NULL
    96.     call    [ebp + _MB]
    97.     .ELSE
    98.     push    MB_ICONERROR
    99.     lea     eax, [ebp + offset _ttl2]
    100.     push    eax
    101.     lea     eax, [ebp + offset _msg2]
    102.     push    eax
    103.     push    NULL
    104.     call    [ebp + _MB]
    105.     push    NULL
    106.     call    [ebp + _EP]
    107.     .ENDIF
    108.  
    109. EP:
    110.     mov ebx, 401000h
    111.     jmp ebx
    112. ;-------------------------------------------> Конец
    113. GetKernelBase   PROC USES edi esi, dwTopStack : dword
    114.     mov edi, dwTopStack
    115.     and edi, 0FFFF0000h
    116.  
    117.     .WHILE  TRUE
    118.  
    119.     .IF word ptr [edi] == IMAGE_DOS_SIGNATURE
    120.         mov esi, edi
    121.         add esi, [esi + 03ch]
    122.  
    123.     .IF dword ptr [esi] == IMAGE_NT_SIGNATURE
    124.     .BREAK
    125.     .ENDIF
    126.  
    127.     .ENDIF
    128.  
    129. ExceptCont:
    130.     sub edi, 010000h
    131.  
    132.     .IF edi < MIN_KERNEL_SEARCH_BASE
    133.     mov edi, 0BFF70000h
    134.         .BREAK
    135.     .ENDIF
    136.  
    137.     .ENDW
    138.  
    139.     xchg    eax, edi   
    140.     ret
    141.  
    142. GetKernelBase   ENDP
    143.  
    144. GetProcAddr PROC USES esi edi ecx ebx edx, dwDllBase : dword, szApi : LPSTR
    145.     mov esi, dwDllBase
    146.     cmp word ptr [esi], IMAGE_DOS_SIGNATURE
    147.     jnz @@BadExit
    148.     add esi, [esi + 03ch]
    149.     cmp dword ptr [esi], IMAGE_NT_SIGNATURE
    150.     jnz @@BadExit
    151.     mov edi, szApi
    152.     mov ecx, MAX_API_STRING_LENGTH
    153.     xor al, al
    154.     repnz   SCASB
    155.     mov ecx, edi
    156.     sub     ecx, szApi
    157.     mov     edx, [esi + 078h]
    158.     add     edx, dwDllBase
    159.     assume  edx : ptr IMAGE_EXPORT_DIRECTORY
    160.     mov     ebx, [edx].AddressOfNames
    161.     add     ebx, dwDllBase
    162.     xor eax, eax
    163.  
    164.     .REPEAT
    165.     mov     edi, [ebx]
    166.     add     edi, dwDllBase
    167.     mov     esi, szApi
    168.     push    ecx
    169.     repz    CMPSB
    170.  
    171.     .IF ZERO?
    172.         .BREAK
    173.     .ENDIF
    174.  
    175.     pop ecx
    176.     add ebx, 4
    177.     inc eax
    178.  
    179.     .UNTIL  eax == [edx].NumberOfNames
    180.  
    181.     mov     esi, [edx].AddressOfNameOrdinals
    182.     add     esi, dwDllBase
    183.     push    edx
    184.     mov     ebx, 2
    185.     xor edx, edx
    186.     mul     ebx
    187.     add     eax, esi
    188.     xor ecx, ecx
    189.     mov     word ptr cx, [eax]
    190.     pop     edx
    191.     mov     edi, [edx].AddressOfFunctions
    192.     xor edx, edx
    193.     mov     ebx, 4
    194.     mov     eax, ecx
    195.     mul     ebx
    196.     add     eax, dwDllBase
    197.     add     eax, edi
    198.     mov     eax, [eax]
    199.     add     eax, dwDllBase
    200.     jmp     @@ExitProc
    201.     assume  edx : nothing
    202.  
    203. @@BadExit:
    204.     xor eax, eax
    205.  
    206. @@ExitProc:
    207.     ret
    208.  
    209. GetProcAddr ENDP
    210.  
    211. Constants:
    212. dFile   dd  0
    213. num dd  0
    214. FileN   db  "\\.\i:", 0      ;<- буква флешки
    215. SN  dd  0F82FFCFCh          ;<- заранее посмотренный номер дающийся при форматировании флешки
    216. buf db  512 dup (0)
    217. _ttl    db  "Ключ верный!", 0
    218. _msg    db  "Для продолжения нажмите ''ОК''", 0
    219. _ttl2   db  "Неверный ключ!", 0
    220. _msg2   db  "Для завершения нажмите ''ОК''", 0
    221.  
    222. dwKernelBase    dd  0
    223. dwUserBase  dd  0
    224. szLoadLibrary   db  "LoadLibraryA", 0
    225. szGetProcAddress    db  "GetProcAddress", 0
    226. szUser32        db  "user32", 0
    227. _LoadLibrary    dd  0
    228. _GetProcAddress dd  0
    229.  
    230. szMB    db  "MessageBoxA", 0
    231. szCF    db  "CreateFileA", 0
    232. szRF    db  "ReadFile", 0
    233. szEP    db  "ExitProcess", 0
    234. _MB dd  0
    235. _CF dd  0
    236. _RF dd  0
    237. _EP dd  0
    238. _exit_:
    239.  
    240. end main
    241.  
    242.  
    243. Компилировал следующим образом:
    244. \MASM32\BIN\ml.exe  /c /coff /Zp1   Protect_D.bat
    245. \MASM32\BIN\link.exe  /SUBSYSTEM:WINDOWS /SECTION:.text,EWR Protect_D.obj
    246. del *.obj
    Так вот проблема в следующем, после компиляции не будучи встроеной она робит нормально, но после внедрения неробит. Что делать?

    Заранее благодарен за ответ.
     
  12. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    Не встраивать?
     
  13. un

    un New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2009
    Сообщения:
    6
    censored
    Ето конечно весело, но задание на курсач гласит, что надо
     
  14. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    un
    Чтобы получить ответ, надо четко поставить вопрос.
     
  15. un

    un New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2009
    Сообщения:
    6
    censored
    Эх если бы я знал что конкретно не работает, ну если желаете могу изложить всю суть вопроса и проблемы.
    Значит так, получил я задание на курсач: "Разработать программу защиты готового программного обеспечения". А суть етого в следующем, надо разработать программу которая будет внедрять код защит в готовое ПО ну и саму защиту. По етому принципу вирусы делаются и следовательно я от етого матерьяла и отталкивался. Ну с инфектором проблем особых небыло (т.к. готовых полно, да и статей немало понаписано), а вот со-второй частью проблема за проблемой и потому что знаний у меня в асме особых нет, да и времени в обрез.
    Ладно чет я разошолся, значит так с грехом пополам я написал программу (см. выше), которая производит проверку некого номера флешки, коий дается ей случайным образом при ее форматировании и если все ОК передает управление оснновной программе.
    Вот, но когда я ее компилю и запускаяю (для проверки) она все нормально отрабатывает, потом беру Hex едактором и убираю из откомпелированной проги защиты лишнюю дребедень РЕшную, внедряю ее в подопытную прогу. Ибудучи внедренный моя прога не проходит проверку и выдет сообщение что ключь не тот.
    Так вот я и незнаю почему так, может я где то с Дельтой намудрил, а может еще что.
    А раз львиную долю инфы я накапал на WASMе, и подумал спросить именно сдесь.
     
  16. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    un
    Так уже лучше.
    Программу не запускал, так как нету возможности собрать. Предположения почему не работает:
    1. проблема именно во внедрении кода.
    вызывает сомнения. куда внедряете? в точку входа или еще куда-то? уверены что все правильно вырезаете?
    2. есть сомнения в:
    Код (Text):
    1. push dword ptr [esp + 20h]
    2. call GetKernelBase
    Что за esp + 0x20?
    и
    Код (Text):
    1. mov edx, dword ptr buf+43h ;[ebp + buf+43h]
    2.  
    3. .IF edx == SN
    адресация должна быть position-independent. т.е. чтото вроде lea eax, [ebp + buf] / mov edx, [eax + 43h]

    Было бы неплохо посмотреть на защищенный блокнот к примеру.
     
  17. un

    un New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2009
    Сообщения:
    6
    censored
    1.
    Извеняюсь забыл уточнить, внедряю в последнюю секцию путем ее расширения. А насчет вырезки, я также делал на етойже про грамме, тока она вызывает MessageBox и передает управление основной программе.
    2.
    Все что связано с вызовом функций придумано не мной, я позоимствовал ето у Bill/TROC
    3. Могу сделать, но я ненаю как его выложить
     
  18. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    Выложите на любой адекватный обменик.
    GetKernelBase можно переписать более коротко и надежно так (NT+):
    Код (Text):
    1.     mov eax, fs:[30h]
    2.     mov eax, [eax+0Ch]
    3.     mov esi, [eax+1Ch]
    4.     lodsd
    5.     mov eax, [eax+08h]
     
  19. un

    un New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2009
    Сообщения:
    6
    Прошу прощения за долгое молчание, с инетом проблемы были.
    1. Попробывал Ваш пример с GetKernelBase, но чет не компелируется.
    2. Вылажил уже зараженный Notepad и приложил все исходники навсякий случай
    Вот: http://letitbit.net/download/63b71684603/Call.rar.html
     
  20. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    Код (Text):
    1. @@ -75,7 +75,6 @@
    2.     lea     eax, [ebp + offset FileN]
    3.     push    eax
    4.     call        [ebp + _CF]
    5. -        .IF eax != -1
    6.     mov     [ebp + dFile], eax  
    7.  
    8.     push    NULL
    9. @@ -89,9 +88,8 @@
    10.     push    eax
    11.     call        [ebp + _RF]
    12.     mov     edx, dword ptr [ebp + buf+43h]
    13. -        mov             eax, [ebp + SN]
    14.  
    15. -   .IF     edx == eax
    16. +   .IF     edx == SN
    17.     push    MB_OK
    18.     lea         eax, [ebp + offset _ttl]
    19.     push    eax
    20. @@ -101,8 +99,7 @@
    21.     call        [ebp + _MB]
    22.     mov     ebx, 401082h        ;передача точки входа Блокнота
    23.     jmp     ebx
    24. -        .ENDIF
    25. -        .ELSE
    26. +   .ELSE
    27.     push    MB_ICONERROR
    28.     lea         eax, [ebp + offset _ttl2]
    29.     push    eax