Как исправить Windows Calculator
===============================================================================
Tutorial 003
Как исправить Windows Calculator =)
(c) CS:ED
===============================================================================
1. Объект взлома.
Он всем знаком - тот самый калькулятор, который ставиться вместе с Виндами. Чего
там ломать ? Ну... иногда удобнее, чтобы он загружался сразу в hex режиме, а не
в dec, как у Микрософта устроено. Вот этим и займемся. Кроме того получаем
забавный побочный эффект и можем хорошо над кем-то подшутить ;)
2. Инструменты.
Win32Dasm 8.9, Hiew 5.6
3. Предварительное исследование.
Для начала надо определить, что, собственно, мы хотим искать ? Поэтому запускаем
калькулятор в Scientific режиме и смотрим на него внимательно:
|===============================================================|
| Calculator |
|---------------------------------------------------------------|
| Edit View Help |
|---------------------------------------------------------------|
| | 0.||
| _______________________________ __________________________ |
| |( )Hex (*)Dec ( )Oct ( )Bin | |(*)Deg ( )Rad ( )Grad | |
| |_______________________________| |_________________________| |
Ага, текущее состояние видно по выбранному пункту в группе RadioButton-ов.
Поэтому ИМХО проще всего для начала найти то место, где задается выбранный
элемент этой группы, а там видно будет.
4. Точка входа
Запускаем Win32Dasm (можно было бы воспользоваться и SoftICE, но зачем же из
пушки по воробьям палить ? :) и открываем Calk.exe (живет в каталоге Виндов)
Файлик маленький, дизассемблируется очень быстро - несколько секунд и все готово
для работы. :)
Сразу запускаем процесс выполнения - Debug -> LoadProcess.
Наблюдаем некоторую суету на экране, появление еще двух окошек и отладчик
останавливается на entry point.
Выбираем Functions -> Imports, чтобы посмотреть список импортированных функций.
Смотрим, чего там у нас получилось и видим единственную функцию, которая
напрямую относится к работе с RadioButton-ами USER32.CheckRadioButton (На самом
деле ее то нам и надо) Смотрим в хелп по API-шным функциям и видим, что у нее
имеется 4 параметра, причем последний - номер активного контрола.
Двойными щелчками по этой строке переходим в то место кода, где встречается эта
функция и жмем F2, чтобы поставить бряки в этих местах (их всего три).
Выглядит это вот таким образом:
* Reference To: USER32.CheckRadioButton, Ord:0031h
|
:00401260 FF1524E34000 Call dword ptr [0040E324]
* Reference To: USER32.CheckRadioButton, Ord:0031h
|
:00403804 FF1524E34000 Call dword ptr [0040E324]
* Reference To: USER32.CheckRadioButton, Ord:0031h
|
:0040506E 8B1D24E34000 mov ebx, dword ptr [0040E324]
Список установленных бряков можно посмотреть в окошке с регистрами, флагами и
прочими интересными штуками :) в поле BPts. Чтобы включить/выключить точку,
можно щелкнуть по ней левой кнопкой мыши (чтобы выделить), а потОм правой.
Звездочка рядом пропадет.
Так. Ловушки расставлены :) Теперь можно щелкнуть F9 и...
Бац ! Сработала точка 0040506E
Замечательно. Точку входа в процесс исследования мы нашли. :)
На самом деле в этом месте фунция еще не вызывается. Мы просто помещаем ее адрес
в регистр ebx, а вызов идет чуть дальше:
* Reference To: USER32.CheckRadioButton, Ord:0031h
|
:0040506E 8B1D24E34000 mov ebx, dword ptr [0040E324]
:00405074 6A7C push 0000007C
:00405076 A304C04000 mov dword ptr [0040C004], eax
:0040507B 6A79 push 00000079
:0040507D A1D8B54000 mov eax, dword ptr [0040B5D8]
:00405082 50 push eax
:00405083 FFD3 call ebx ; вот он
5. Исследование.
Итак, мы знаем, что при запуске переключатель устанавливается функцией по адресу
00405083, причем последний передаваемый ей параметр - это как раз номер будущего
активного контрола.
Параметры мы в данном случае передаем в функцию через стек в обратном порядке,
так что смотрим, чего у нас там лежит:
[esp+00000000] - 000005f8 ....
[esp+00000004] - 00000079 y...
[esp+00000008] - 0000007c |...
[esp+0000000C] - 0000007b {... <- вот он, четвертый параметр CheckRadioButton
Мы знаем, что при запуске в Scientific режиме активным будет Dec. Значит Dec
имеет номер 07bh. Ага.
Можно увидеть это и более наглядно - для этого жмем F8 (шаг вперед), пока не
получим окно с параметрами вызванной функции:
API BOOL Arg00 = CheckRadioButton(Arg01,Arg02,Arg03,Arg04)
API Address=00405083, API Return Address=00405085
Arg01 = (HWND) 000005f8 (Window"Calculator")
Arg02 = (int) 00000079
Arg03 = (int) 0000007c
Arg04 = (int) 0000007b
Все правильно - четыре параметра, последний - номер активного элемента.
BTW, уже здесь мы можем увидеть номер элемента по имени Hex - это Arg03.
Почему ? Да потому что Arg02 и Arg03 - это номера крайних элементов :)
А Hex как раз им и является.
Ну что ж - проверим.
Чтобы изменить значение, лежащее в стеке, щелкаем на Modify Data в том же окне.
С помощью Memory Location задаем значение адреса в памяти esp+0000000C
(0064fcc4h), при этом в поле Mem видим текущее значение - 0000007b
В поле EnterValue пишем 0000007c и щелкаем на маленькую кнопочку Mem, потом
Modify и Close.
Теперь F9 и - Ха ! сработало :) Калькулятор запустился в хекс режиме.
Но действительно ли он в нем находится или мы просто переключили графическое
отображение ?
Никогда не мешает проверять такие вещи, поэтому пишем 5+5, ентер ... мда... не
получилось. Значит к этому месту мы приходим ужЕ в последнюю очередь, а
настройка происходит раньше.
Закрываем калькулятор и смотрим, как мы можем прийти к этой точке кода:
* Referenced by a CALL at Addresses:
|:00401246 , :004016BC , :004030F0 ; т.е. вот оттуда идут вызовы
|
:0040504D 53 push ebx
:0040504E 56 push esi
:0040504F 8B74240C mov esi, dword ptr [esp+0C]
;а здесь мы помещаем в esi некоторое значение, которое
;потОм станет четвертым аргументом CheckRadioButton
:00405053 57 push edi
:00405054 55 push ebp
* Possible Reference to String Resource ID=00001: "Ave"
|
:00405055 BF01000000 mov edi, 00000001
:0040505A 83FE7B cmp esi, 0000007B ; будет активен Dec-режим ?
:0040505D 7409 je 00405068 ; если да, то прыгаем
:0040505F 33FF xor edi, edi
:00405061 A148C04000 mov eax, dword ptr [0040C048]
; какое-то ключевое значение для _не_ Dec режима
:00405066 EB05 jmp 0040506D
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040505D(C)
|
:00405068 A144C04000 mov eax, dword ptr [0040C044]
; какое-то ключевое значение для Dec режима
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405066(U)
|
:0040506D 56 push esi ; ни что иное, как наш главный параметр
* Reference To: USER32.CheckRadioButton, Ord:0031h
|
:0040506E 8B1D24E34000 mov ebx, dword ptr [0040E324]
Т.е. мы попадаем сюда с одного из трех адресов: 00401246, 004016BC, 004030F0,
кладем в esi значение из стека: ss:[esp+0C], после чего действуем в зависимости
от этого значения.
Так. Пробуем поменять параметр на _этом_ этапе, т.е. просто меняем значение в
ss:[esp+0C] перед тем, как оно берется в esi.
Снова запускаем процесс, ставим бряк на 0040504F и F9.
Modify Data, адрес 0064fcdc, значение 0000007c, Mem, Modify, Close.
F9... Хе, кто бы сомневался ;) - хекс режим. Но мы помним, что все надо проверять.
Ок: 5 + 5 =... Yes ! It worked !
Итак, мы знаем теперь, что для запуска калькулятора в хекс режиме, мы должны к
точке 0040504F иметь в стеке (в ss:[esp+0C]) 0000007ch
А чтобы узнать, как туда попадают значения :), снова перезапускаем процесс и
ставим бряки на 00401246, 004016BC, 004030F0
Woops! Сработала точка 00401246 и собственно на этом все :) Потому что мы видим
там вот такой код:
:00401244 6A7B push 0000007B ; вот значение, которое нас интересует
:00401246 E8023E0000 call 0040504D ; а это наша функция
Особо осторожные могут проверить еще раз, но на самом деле на этом исследование
закончено и отладчик можно закрыть (предварительно записав адрес, конечно :)
6. Исправляем
Теперь делаем резервную копию Calk.exe (мало ли чего :), после чего открываем
его в Hiew. Переходим в режим просмотра Асм-кода (Enter два раза), жмем F5,
пишем .1244 и прыгаем в уже знакомую нам точку кода:
.00001244: 6A7B push 07B
.00001246: E8023E0000 call .00000504D ---------- (1)
Переходим в режим редактирования (F3) и меняем байт 7b на 7c
Сохраняем изменения (F9), выходим (Esc) и запускаем исправленную версию программы.
Работает ? =)
Вот так просто. Каких-то пять минут и больше не придется при каждом запуске
переключаться в хекс режим =)
7. Обещанный побочный эффект :)
У нас-то с вами калькулятор давным давно пожизненно переключен в Scientific, ну
так это у нас. ;) Вот интересно, что получиться, если исправленная нами прога
будет грузиться в _обычном_ режиме.
Чтобы увидеть это, запускаем ее, переключаем в Standart (BTW при этом он сам
нормально перейдет в Dec) и выходим. Теперь снова запускаем - Standart.
А теперь набираем наш контрольный пример - 5+5 = ... Wow !!! :))))
Осталось только найти жертву - лучше всего подойдет кто-то, чей комп стоИт
недалеко от вашего и кто как раз сейчас активно занимается какими-нибудь
рассчетами ;)))
Подсуньте ему ваш калькулятор и понаблюдайте ;)
8. Пишем WinCalk.xck
Чтобы самим не забыть, что где исправлять и в качестве инструкции для других
любителей шуток пишем простейший xck файлик:
[BeginXCK]----------------------------------
* Description : [W32] WinCalculator
* Crack subject : Start in HEX mode
* Crack made by : CS:ED
* Crack made at : Jan 8 2000 17:21:00
* Comments : Set HEX mode as default :-)
* Protection : None
* Type of hack : Change parameter for USER32.dll:CheckRadioButton
* Used tools : Win32Dasm 8.9, Hiew v5.6
[BeginCRK]----------------------------------
[W32] WinCalculator
Set HEX mode as default
calk.exe
00001244: 7b 7c
[EndCRK]------------------------------------
[EndXCK]------------------------------------
ЗЫ: Кому не лень, можно еще поставить свой копирайт в окошке About ;)
=================================================================================
Сорцы, сорцы... Hiew !!!
=================================================================================
(c) White Unicorn
Любая часть этого документа может быть скопирована любым из существующих способов :)
(Но если вы оставите в форуме свои замечания по поводу успешного / неуспешного применения солюшена, то это будет совсем хорошо :)