Delphi World - Компьютерный зал 1.81 Demo2Full
Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Компьютерный зал 1.81 Demo2Full
Чем больше узнаю людей, тем больше люблю компьютеpы...

Опять демка.

Ограничение: управление не более чем 4 компутерами. Старо как мир...

Инструменты: Softice, Hiew, upx, filemon, windasm.

Автор страшно любит модульное программирование и поэтому у него вышло не одна прога, а целых 6. Да-да 6 exe файлов...

  • Computerzal.exe - прога управления клиентами
  • Setup.exe - прога настроек для Computerzal.exe
  • czclient.exe - клиент
  • clientsetup.exe - прога для настройки клиента
  • LogViewPrint.exe - прога для печати логов
  • PassClean.exe - прога для сброса забытых паролей

Две последние нас не интересуют т.к. их подозревать не в чем. А остальные могут нас кидать по-полной.

О "защите": Упакована UPX. Файлы конфигурации криптует. Данные конфигурации клиента тупо пишет в реестр не скрывая ничего. Номер машины и число клиентов заблокировано через ограниечение в элементе Spinedit (edit+updown).

Приступим...

В файле Computerzal.exe искать пока нечего, т.к. н берет данные из файла конфигурации, который генерится из setup.exe. Поэтому начнем с Setup.exe. Распаковываем. Теперь не плохо бы узнать как же задается диапозон значений для spinedit. Так как spinedit состоит из edit и updown то нужно искать разгадку именно в элементе updown, т.е. чтобы изменить число мы кликаем именно на него. Берем win32.hlp и ищем Up-Down Control Messages... Там их не много. И вот что есть интересного:


The UDM_SETPOS message sets the current position for an up-down control
UDM_SETPOS 
wParam = 0; 
lParam = (LPARAM) MAKELONG((short) nPos, 0); 

New position for the up-down control. This parameter must be in the 
range specified by the upper and lower limits for the control.

и вот еще:


The UDM_SETRANGE message sets the minimum and maximum 
positions (range) for an up-down control.
UDM_SETRANGE 
wParam = 0; 
lParam = (LPARAM) MAKELONG((short) nUpper, (short) nLower); 

Maximum position and minimum position for the up-down control. 
Neither position can be greater than the UD_MAXVAL value or 
less than the UD_MINVAL value. In addition, the difference 
between the two positions cannot exceed UD_MAXVAL.

Сообщения это хорошо... Но где жеж взять их численные значения чтоб найти, где происходит ограничивание области значений? Естественно в WWW (World Wide Wreck - всемирная свалка :).


UDM_SETPOS 467
UDM_SETRANGE 465

Теперь дизасмим и ищем "00000465". B вот что я вижу:
* Reference To: USER32.SendMessageA, Ord:0000h
|
:00402C19 8B3DDCD34100 mov edi, dword ptr [0041D3DC]
.........
:00402D10 8B9658030000 mov edx, dword ptr [esi+00000358]
:00402D16 6804000100 push 00010004 ; 1 - минимум 4- максимум...
:00402D1B 6A00 push 00000000 
:00402D1D 6865040000 push 00000465 ; UDM_SETRANGE
:00402D22 52 push edx ; Handle
:00402D23 FFD7 call edi ; SendMessageA

и еще интересный кусок:


:00402D25 8B0D907B4200 mov ecx, dword ptr [00427B90]
:00402D2B 6A04 push 00000004 ; хм.....
:00402D2D 8D442448 lea eax, dword ptr [esp+48]
:00402D31 6A01 push 00000001 ; хм.....
:00402D33 50 push eax
:00402D34 6A04 push 00000004 ; хм.....
:00402D36 C744245424000000 mov [esp+54], 00000024
:00402D3E C744245807020000 mov [esp+58], 00000207
:00402D46 E895ECFFFF call 004019E0 - А это чо за CALL такой?
:00402D4B 8B8E58030000 mov ecx, dword ptr [esi+00000358]
:00402D51 25FFFF0000 and eax, 0000FFFF
:00402D56 50 push eax
:00402D57 6A00 push 00000000
:00402D59 6867040000 push 00000467 ; UDM_SETPOS 
:00402D5E 51 push ecx 
:00402D5F FFD7 call edi ; SendMessageA

Если взять айс и посмотреть что же делает call 004019E0, то можно довольно быстро понять, что в нем происходит чтение из файла конфигурации "Числа машин в сетке". А эти числа что пушатся перед ним - это ограничения! А то мало ли ... вдруг мы чужой файл конфигурации подсунем.

Для упокоения совести ищем "00010004" ... B вот что видим:


:00403305 8B8658030000 mov eax, dword ptr [esi+00000358]
:0040330B 6804000100 push 00010004 - опять!
:00403310 6A00 push 00000000
:00403312 6865040000 push 00000465
:00403317 50 push eax
:00403318 FFD7 call edi
:0040331A 8B8EE0050000 mov ecx, dword ptr [esi+000005E0]
:00403320 B804000000 mov eax, 00000004 - еще одно ограничение
:00403325 3BC8 cmp ecx, eax 
:00403327 7606 jbe 0040332F

Подправив эти push 00010004 можно выставить нунжый максимум числа машин. Осталось проверить еще одну подлость: как бы оно не проверяло перед сохранением файла конфигураци... Поставив bpx на getwindowtexta, а потом bpm на адрес прочтенной строки, можно легко определить, что идет еще одна проверка вот тут:


:00401FC1 8B8424D8060000 mov eax, dword ptr [esp+000006D8]
:00401FC8 C744241824000000 mov [esp+18], 00000024
:00401FD0 83F804 cmp eax, 00000004
:00401FD3 C744241C07020000 mov [esp+1C], 00000207
:00401FDB C78424D800000004000000 mov dword ptr [esp+000000D8], 00000004
:00401FE6 C78424DC0000000A000000 mov dword ptr [esp+000000DC], 0000000A
:00401FF1 C78424E000000076000000 mov dword ptr [esp+000000E0], 00000076
:00401FFC C78424E400000002020000 mov dword ptr [esp+000000E4], 00000202
:00402007 C78424E80000009E020000 mov dword ptr [esp+000000E8], 0000029E
:00402012 C78424EC0000000C030000 mov dword ptr [esp+000000EC], 0000030C
:0040201D C78424F000000078030000 mov dword ptr [esp+000000F0], 00000378
:00402028 C78424F4000000E7030000 mov dword ptr [esp+000000F4], 000003E7
:00402033 760C jbe 00402041
:00402035 B804000000 mov eax, 00000004

С Setup.exe все.

Теперь будет повеселее ... Computerzal.exe

Поставив bpx на createfilea нужно найти место где открывается файл "cz.cfg". Потом bpx readfile и после первого срабатывания, понажимав F12 мы окажемся тут:


:004128C7 6A04 push 00000004 ; Где-то я это уже видел...
:004128C9 8D442464 lea eax, dword ptr [esp+64]
:004128CD 6A01 push 00000001 ; Где-то я это уже видел...
:004128CF 8B8E64040000 mov ecx, dword ptr [esi+00000464]
:004128D5 50 push eax
:004128D6 6A04 push 00000004 ; Где-то я это уже видел...
:004128D8 C744247024000000 mov [esp+70], 00000024
:004128E0 C744247407020000 mov [esp+74], 00000207
:004128E8 E833440000 call 00416D20 ; После этого call в eax лежит число машин
:004128ED 33FF xor edi, edi
:004128EF 68FFFF0000 push 0000FFFF
:004128F4 8D8C24A4000000 lea ecx, dword ptr [esp+000000A4]
:004128FB 57 push edi
:004128FC 51 push ecx
:004128FD 8B8E64040000 mov ecx, dword ptr [esi+00000464]
:00412903 6852030000 push 00000352
:00412908 8986D8010000 mov dword ptr [esi+000001D8], eax - а тут запоминаем число машин...

Дальше возникает умная мысль: "А что если bpm esi+000001D8 ?". Эта мысль приводит нас к тому что мы очень быстро увидим следующие ограничения:


:004121E5 8B9ED8010000 mov ebx, dword ptr [esi+000001D8]
:004121EB 83FB04 cmp ebx, 00000004
:004121EE 0F83FC000000 jnb 004122F0

потом:


:0040CA1F 8B2DF0534400 mov ebp, dword ptr [004453F0]
:0040CA25 8B542414 mov edx, dword ptr [esp+14]
:0040CA29 83FD04 cmp ebp, 00000004
:0040CA2C 8915C4534400 mov dword ptr [004453C4], edx
:0040CA32 7E05 jle 0040CA39

Прога запустилась... появились дополнительные машины! но они неактивны :((( Вот блин... Ну так это ... bpx enablewindow. После этого меня просто достало жать F5 (т.к. очень много раз срабатывало) и я решил глянуть чо ж оно там стока блокирует... и вылез тут:


:0041212B 8B8FC8000000 mov ecx, dword ptr [edi+000000C8]
:00412131 6A00 push 00000000 ; disable
:00412133 03CE add ecx, esi
:00412135 E8EC710100 call 00429326 ; enablewindow
:0041213A 8B8FCC000000 mov ecx, dword ptr [edi+000000CC]
:00412140 6A00 push 00000000 ; disable
:00412142 03CE add ecx, esi
:00412144 E8DD710100 call 00429326 ; enablewindow
:00412149 8B8FD8000000 mov ecx, dword ptr [edi+000000D8]
:0041214F 6A00 push 00000000 ; disable
:00412151 03CE add ecx, esi
:00412153 E8CE710100 call 00429326 ; enablewindow

и т.д.

Я поднялся на уровень вверх:


:00411A84 6A00 push 00000000
:00411A86 8BCE mov ecx, esi
:00411A88 E883060000 call 00412110
:00411A8D 8D4C241C lea ecx, dword ptr [esp+1C]

Это call который блокирует новые машины! Я просто перепрыгнул с адреса 411A84 (push не делал) на

411A8D и все машины стали активными. Тока вот еще два глюка... почему-то не горит "Free" и почему-то горят на некоторых машинах зеленые квадратитики как-будто они уже подключены. Закраска делается через Setbkcolor. Поэтому легко можно определить что надпись "Free" блокирует ограничение:


:0040BF62 8B08 mov ecx, dword ptr [eax]
:0040BF64 56 push esi
:0040BF65 83F903 cmp ecx, 00000003 ; А тут они с 0 считают :)
:0040BF68 57 push edi
:0040BF69 0F8FF0020000 jg 0040C25F

И вот остался последний огромный глюк + последнее ограничение. Глюк с подключением клиента... Состоит он в том, что прога падает при попытке подключения клиента с номером больше 4, квадратики подключения клиента ваще никак не реагируют, прога падает при выходе... А причина всего этого, скажу я вам, это называется глюк из-за статических массивов. При попытке содния более чем 4 машин мы просто вылазим запределы выделенного пространнства и поганим другие переменные. Ну и прога в том числе тоже поганит наши данные... Будем исправлять...

Прога падает тут:


:0040DE1D 8B4668 mov eax, dword ptr [esi+68]
:0040DE20 53 push ebx
:0040DE21 8B0CB8 mov ecx, dword ptr [eax+4*edi] - в edi идет номер машины
:0040DE24 83C170 add ecx, 00000070
:0040DE27 51 push ecx
:0040DE28 8D4C2424 lea ecx, dword ptr [esp+24]
:0040DE2C E8C79B0000 call 004179F8

в ecx попадает не то значение... и потом внутри call 004179F8 оно слетает окончательно...

[eax+4*edi]... Пляшут относительно eax. Eax не меняется... меняется тока индекс - это 100% работа с одномерным массивом! Чтоже у нас в EAX там у нас 4453F8. Делаем d 4453F8 и н смотрим чо там делается... будет цикл который заполнит DWORD числами массив. Длинна массива равна коичеству машин. Делаем bpr 445408 xxxxxx RW (откуда я знаю скока вы себе там машин сделаете). Я сделал именно 445408, а не 4453f8 т.к. первые 4 dword числа нас не интересуют они и так в пезопасности. А теперь будем следить, где начнутся попытки читать или писать. Начнутся они совсем рядом:


:0040E097 8B869C000000 mov eax, dword ptr [esi+0000009C]
:0040E09D 8818 mov byte ptr [eax], bl

в esi+0000009C будет лежать адрес 6-го элемента нашего массива машин... Будем разбираться откду он там берется. Вот тут он берется:


:0040F4F8 8D95E0FEFFFF lea edx, dword ptr [ebp-120] - Вот!
:0040F4FE 898898000000 mov dword ptr [eax+00000098], ecx
:0040F504 8B07 mov eax, dword ptr [edi]
:0040F506 89909C000000 mov dword ptr [eax+0000009C], edx - а тут сохраняем.

ebp меняется но вот вычитаемое остается константой. Все что нам нужно, это заставить программу использовать данные где-нить подальше от нашего массива. Я сделал это очень просто:


:0040F4F8 lea edx, dword ptr [ebp-60]
:0040F4FB nop
:0040F4FC nop
:0040F4FD nop

Теперь у меня еще аж 120h-60h=C0h места. C0h /4h = 30h = 48 машин. Прям как в зарегеной :)

После такого изменения прога больше не падает и можно управлять машинами! Остался тока глюк с индикацией подключения. Ну тут все тоже связано с EBP :) Поставив bpx на SetBkColor я нашел в чем глюк:


:0040CDBD 8A8508544400 mov al, byte ptr [ebp+00445408]
:0040CDC3 8A8D38544400 mov cl, byte ptr [ebp+00445438]

и тут:


:0040D01C 8A8508544400 mov al, byte ptr [ebp+00445408]

Это естественно. Т.к. мы же сдвинули адреса переменных на C0h, а прога обращается по старым адресам.

Нужно сделать:


:0040CDBD 8A85C8544400 mov al, byte ptr [ebp+004454С8]
:0040CDC3 8A8DF8544400 mov cl, byte ptr [ebp+004454F8]
:0040D01C 8A85C8544400 mov al, byte ptr [ebp+004454C8]

Теперь и мигает как надо :)

Клинта и сетап к нему ломайте сами. Я задолбался уже писать этот туториал...

Проект Delphi World © Выпуск 2002 - 2017
Автор проекта: Эксклюзивные курсы программирования