Теперь добавим действие меню "Option 1", как сказано
в условии - действие строки меню "Option 1" 
аналогично кнопке "Option 1". А т.к. действие кнопке
мы уже сделаем, поступим также, как и в предыдущем случае, сделаем
прыжок на уже написанный нами код.

Сперва посмотрим ее ID:

00000F90 90 00 46 00 69 00 6C 00 65 00 00 00 ђ.F.i.l.e...
00000F9C 00 00 00 7D 4F 00 70 00 74 00 69 00 ...}O.p.t.i. ;
7D00 - ID строки меню "Option 1"
00000FA8 6F 00 6E 00 20 00 31 00 20 00 2E 00 o.n. .1. ...
00000FB4 2E 00 2E 00 00 00 00 00 E8 80 4F 00 ........иЂO.

Здесь идет проверка:

00401094 jnz short loc_4010E0
00401096 cmp ax, 7D00h ;
нажата ли меню "Option 1"
0040109A jnz short loc_4010C6 ;
если нет прыгаем на 4010C6
0040109C noped
0040109E noped
004010A3 noped
004010A8 noped
004010AA noped
...
004010C6 ;
прыгаем сюда и продолжаем
004010C6 loc_4010C6: ; CODE XREF: sub_40102B+6Fj
004010C6 cmp ax, 7D01h
004010CA jnz short loc_4010CE
004010CC jmp short loc_401117

После инструкции по адресу 0040109A: jnz short loc_4010C6
мы запишем следующую инструкцию, а именно безусловный переход,
который будет прыгать на код, который мы писали для кнопки "Option 1".
Код для кнопки "Option 1" находится по адресу
00401106, значит инструкция будет такой:

jmp 00401106

Запустим hiew, откроем наш файл, переключимся в режим дизассемблера,
пойдем по адресу 0040109C, нажмем F3, затем F2 и введем:

jmp 00000506

Сохраним F9 и выйдем из hiew.

Проверим программу, запустим и нажмем меню "Option 1" появилось сообщение,
значит с задачей мы справились.

Осталось последнее задание со строкой меню "Option 2", при ее нажатии кнопка 
"Exit" должна стать невидимой, при повторном нажатии появиться.

Как обычно, узнаем ID:

00000FA8 6F 00 6E 00 20 00 31 00 20 00 2E 00 o.n. .1. ...
00000FB4 2E 00 2E 00 00 00 00 00 E8 80 4F 00 ........иЂO. ;
80E8 - ID строки меню "Option 2"
00000FC0 70 00 74 00 69 00 6F 00 6E 00 20 00 p.t.i.o.n. .
00000FCC 32 00 20 00 2E 00 2E 00 2E 00 00 00 2. .........
00000FD8 00 08 00 00 00 00 80 00 02 7D 45 00 ......Ђ..}E.
00000FE4 78 00 69 00 74 00 00 00 80 08 CA 10 x.i.t...Ђ.К.

Проверка на нее в коде отсутствует, поэтому нам придется дописать ее самим.

004010C6 
004010C6 loc_4010C6: ; CODE XREF: sub_40102B+6Fj
004010C6 cmp ax, 7D01h
004010CA jnz short loc_4010CE
004010CC jmp short loc_401117
004010CE ; ---------------------
004010CE 
004010CE loc_4010CE: ; CODE XREF: sub_40102B+9Fj
004010CE cmp ax, 7D02h ;
проверка строки меню
"Exit"

004010D2 jnz short loc_401117
004010D4 push 0
004010D6 push [ebp+arg_0]
004010D9 call EndDialog
004010DE jmp short loc_401117
004010E0 ; ---------------------
004010E0 
004010E0 loc_4010E0: ; CODE XREF: sub_40102B+69j
004010E0 mov edx, [ebp+arg_8]

Мы сделаем переход на свободный участок в файле, куда мы допишем свой код для
проверки нажатия меню "Option 2" и его действия. С помощью hiew найдем свободный участок, я нашел по адресу 401164,
там и будет размещаться наш код.

По адресу 004010CA находится инструкция 

jnz short loc_4010CE

вместо нее мы поставим безусловный переход на свой код,
но прежде запишем или запомним адрес, куда мы возвратимся после
нашего кода - 4010CE. Запустим hiew, откроем наш файл, переключимся в режим дизассемблера,
пойдем по адресу 004010CC, нажмем F3, затем F2 и введем: 

jmp 0000055E

Сохраним F9, но не выходим из hiew, а пойдем по адресу 401164, где будем
писать свой код. Сначала нам надо проверить нажата ли меню "Option 2",
cmp eax, 80E8 (ID строки меню "Option 2", который мы посмотрели в ресурсах),
если не нажата возвращаемся, jnz 4010CE. Теперь нам надо определить состояние кнопки "Exit" (является ли она скрытой
в данный момент), для этого будем использовать
IsWindowEnabled (опpеделяет, является ли окно pазpешенным для ввода с мыши и с клавиатуpы,
паpаметpы: Wnd - идентификатоp окна, возвpащаемое значение
- не нуль если окно pазpешено, 0 - если нет). Но для ее использовании
сначала нам нужно узнать идентификатор этого окна,
найдем его с помощью GetDlgItem (считывает описатель оpгана упpавления, содеpжащийся в указанном блоке диалога,
паpаметpы: Dlg - блок диалога, содеpжащий оpган упpавления,
IDDlgItem - идентификатоp оpгана упpавления, возвpащаемое значение в
eax - идентификатоp оpгана упpавления, 0 - если указанный оpган упpавления не существует).

Dlg и IDDlgItem нам известны, код будет выглядеть так:

push 80E8h ; 80E8 - ID строки меню "Option 2"
push [ebp+8] ;
Dlg
call GetDlgItem

Теперь воспользуемся IsWindowEnabled:

push eax ; идентификатоp кнопки
"Exit
"
call IsWindowEnabled

Если кнопка "Exit" была скрыта - в eax будет 0, иначе 1.

1: cmp eax, 0 ; если скрыта
2: jz 5 ; прыгаем на 5
3: mov ebx,0 ; иначе записываем в ebx=0, для скрытия кнопки
4: jmp 6 ; и пропускаем следующую инструкцию
5: mov ebx,1 ; и устанавливаем ebx=1, для активизации кнопки

push 80E8h ; 80E8 - ID строки меню "Option 2"
push [ebp+8] ;
Dlg
call GetDlgItem ;
снова получим
идентификатор кнопки "Exit", он нам понадобится для EnableWindow


И, наконец, EnableWindow (разpешает или блокиpует ввод с мыши и с клавиатуpы в окно или в оpган упpавления,
паpаметpы: Wnd - блокиpуемое или pазблокиpуемое окно,
Enable - не нуль для pазpешения, нуль - для блокиpования).

push ebx ; если ebx=0, EnableWindow скроет кнопку, иначе покажет.
push eax ;
идентификатоp кнопки
"Exit"

call EnableWindow ;
вызов EnableWindow

и возвращаемся с нашего кода:

jmp 4010CE

Теперь запишем все это с помощью hiew. Находясь по адресу
401164 нажмем F3, затем F2 и начнем вводить:

cmp eax, 80E8
jnz 000004CE
push 80E8
push [ebp][8]
call 00000532
push eax
call 0000055C
cmp eax, 0
jz 0000058C
mov ebx,0
jmp 00000593
mov ebx,1
push 80E8
push [ebp][8]
call 00000532
push ebx
push eax
call 00000526
jmp 000004CE

Сохраняем F9 и выходим из hiew.

В дизассемблере код будет выглядеть следующим образом:

:00401164 3DEB800000 cmp eax, 000080EB ;
нажата ли меню "Option 2"
:00401169 0F855FFFFFFF jnz 004010CE ;
если не нажата возвращаемся на 004010CE
:0040116F 68EB800000 push 000080EB ;
(ID строки меню "Option 2", который мы посмотрели в ресурсах)
:00401174 FF7508 push [ebp+08] ;
Dlg, блок диалога,
содержащий оpган упpавления

:00401177 E8DAFFFFFF call 00401132 ;
вызов GetDlgItem
:0040117C 50 push eax ;
кладем в стек идентификатор меню "Option 2"
:0040117D E8B6FFFFFF call 0040115C ;
вызов IsWindowEnabled
:00401182 83F800 cmp eax, 00000000 ;
если скрыта
:00401185 7407 je 0040118E ;
прыгаем на 5
:00401187 BB00000000 mov ebx, 00000000 ;
иначе записываем в ebx=0, для скрытия кнопки
:0040118C EB05 jmp 00401193 ;
и пропускаем следующую инструкцию

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401185(C)
|
:0040118E BB01000000 mov ebx, 00000001 ;
и устанавливаем ebx=1, для активизации кнопки

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040118C(U)
|

* Possible Ref to Menu: MenuID_0BBA, Item: "Option 2 ..."
|
:00401193 68E8800000 push 000080E8 ;
кладем в стек ID строки меню "Option 2"
:00401198 FF7508 push [ebp+08] ;
Dlg, блок диалога, содеpжащий оpган упpавления
:0040119B E892FFFFFF call 00401132 ;
снова получим идентификатоp кнопки "Exit", он нам понадобится для EnableWindow
:004011A0 53 push ebx ;
если ebx=0, EnableWindow скроет кнопку, иначе покажет
:004011A1 50 push eax ;
идентификатоp кнопки
"Exit"

:004011A2 E87FFFFFFF call 00401126 ;
вызов EnableWindow
:004011A7 E922FFFFFF jmp 004010CE ;
возврат

Запускаем программу и нажимаем меню "Option 2", кнопка "Exit" появляется, нажимаем
повторно - она исчезает. Теперь программа полностью работает. Все пункты задания выполнены.

Подписаться
Уведомить о
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии