Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 12 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Описание метода взлома игры FlashPoint

Обсудить статью на форуме

Массу крэкерских инструментов, видеоуроков и статей вы сможете найти на видеокурсе от нашего сайта. Подробнее здесь.

Проанализировав содержимое файла OperationFlashpoint.exe, я обнаружил, что названия сегментов не содержат не одного символа и экспортируется минимальный набор функций из модулей KERNEL32.DLL, USER32.dll:
LoadLibraryA, GetProcAddress, VirtualProtect, ExitProcess, MessageBoxA. Так обычно поступают, чтобы скрыть содержимое файла от всяких дисассемблеров, т.е. когда файл запакован.

Далее запускаю
SoftICE и ставлю брекпоинт на функцию определения типа устройства (bpx GetDriveTypeA). Вставляем CD и запускаем игру. Убеждаемся, что функцию вызвала игра, а не explorer.exe. Дальше жму F5 пока эту функцию не вызовут с параметром указывающий путь к CD.

00011E2: lea eax,[ebp][-000C]
00011E5: push eax
00011E6: call d,[000407018] ;
GetDriveTypeA
00011EC: mov dl,al ; al
=05 тут мы оказались после выхода из функ.
00011EE: lea edi,[ebp][0FFFFF
254] ; ссылка на буфер с меткой тома диска
00011F4: or ecx,-001
00011F7: xor eax,eax
00011F9: repne scasb
00011FB: not ecx
00011FD: dec ecx ; ecx
равен длине метки
00011FE: add ecx,esi ; esi
соответствует адресу на 4 байта меньше чем адрес буфера, т..е обработке подлежат последние 4 символа
0001200: mov bl,[eax][ecx]
0001203: add bl,dl

0001205: mov [eax][ecx],bl ;увеличивают символы на 5(вернула функ.) позиций дальше

0001208: inc eax
0001209: cmp eax,004
; всего 4 символа
000120C: jl 000001200 -------- (2)
000120E: mov ecx,[ebp][-0010]
0001211: lea edx,[ebp][0FFFFFD1F]
0001217: push ecx
0001218: lea eax,[ebp][0FFFFF254]
000121E: push edx
000121F: push eax
0001220: call 0000014C
0 -------- (3) ; эта функция сравнивает два буфера переданные ей в параметрах
0001225: add esp,00C
0001228: test eax,eax
000122A: jne 0000012D5 -------- (4)

Функция (3) возвращает
0, если буфера одинаковые, и значит (4)-ый переход не осуществляется.
:00401230 lea ecx, dword ptr [ebp-6C]
:00401233 push ecx
:00401234 call dword ptr [00407014] ;
GetStartupInfoA
:0040123A xor eax, eax
:0040123C mov cl, byte ptr [ebp+eax-00000179] ; mrc32.dll
:00401243 mov byte ptr [ebp+eax-00000DAC], cl
:0040124A inc eax
:0040124B test cl, cl
:0040124D jne 0040123C
:0040124F lea edi, dword ptr [ebp+FFFFF254]
:00401255 or ecx, FFFFFFFF
:00401258 xor eax, eax
:0040125A mov dx, word ptr [004080C0]
:00401261 repnz
:00401262 scasb
:00401263 or ecx, FFFFFFFF
:00401266 mov word ptr [edi-01], dx
:0040126A mov edi, dword ptr [ebp+10]
:0040126D repnz
:0040126E scasb
:0040126F not ecx
:00401271 sub edi, ecx
:00401273 lea edx, dword ptr [ebp+FFFFF254]
:00401279 mov esi, edi
:0040127B mov ebx, ecx
:0040127D mov edi, edx
:0040127F or ecx, FFFFFFFF
:00401282 repnz
:00401283 scasb
:00401284 mov ecx, ebx
:00401286 dec edi
:00401287 shr ecx, 02
:0040128A repz
:0040128B movsd
:0040128C mov ecx, ebx
:0040128E lea eax, dword ptr [ebp-28]
:00401291 and ecx, 00000003
:00401294 push eax ; struct _PROCESS_INFORMATION
:00401295 repz
:00401296 movsb
:00401297 lea ecx, dword ptr [ebp-6C]
:0040129A lea edx, dword ptr [ebp+FFFFF254]
:004012A0 push ecx ; struct _STARTUPINFO
:004012A1 push 00000000
:004012A3 push 00000000
:004012A5 push 00000004
:004012A7 push 00000000
:004012A9 push 00000000
:004012AB push 00000000
:004012AD push edx ; mrc32.dll
:004012AE push 00000000
:004012B0 call dword ptr [00407010] ;
CreateProcess
:004012B6 test eax, eax
:004012B8 jne 00401307
...
:00401307 mov ecx, dword ptr [ebp+FFFFFCF8]
:0040130D mov edx, dword ptr [ebp-28]
:00401310 lea eax, dword ptr [ebp-08]
:00401313 add ecx, 00400000
:00401319 push eax
; буфер, сюда вернут старые права
:0040131A push 00000040 ;
новый код доступа, 40h=PAGE_EXECUTE_READWRITE
:0040131C push 00000100
; размер
:00401321 push ecx
; адрес региона для изменения доступа к странице памяти
:00401322 push edx ; HANDLE hProcess
из struct _PROCESS_INFORMATION
:00401323 call dword ptr [0040700C] ;
VirtualProtectEx
:00401329 test eax, eax
:0040132B jne 00401348

:00401348 mov edx, dword ptr [ebp+FFFFFCF8]
:0040134E lea eax, dword ptr [ebp-08]
:00401351 push eax
; буфер, сюда вернут количество записанных байт
:00401352 mov eax, dword ptr [ebp-28]
:00401355 lea ecx, dword ptr [ebp+FFFFFD70]
:0040135B push 00000100 ;
размер буфера
:00401360 add edx, 00400000
:00401366 push ecx ;
адресоткуда скопировать (12FCA4)
:00401367 push edx ;
адрескуда писать (44CCBF)
:00401368 push eax ; HANDLE hProcess
:00401369 call dword ptr [00407008] ;
WriteProccessMemory
:0040136F test eax, eax
:00401371 je 0040137C
:00401373 cmp dword ptr [ebp-08], 00000100
:0040137A je 00401398
; осуществляется прыжок

:00401398 mov ecx, dword ptr [ebp-24]
:0040139B push ecx ; HANDLE hThread
:0040139C call dword ptr [00407004] ;
ResumeThread
:004013A2 mov edx, dword ptr [ebp-28]
:004013A5 push FFFFFFFF ;
количество миллисикунд
:004013A7 push edx ; HANDLE hHandle
:004013A8 call dword ptr [00407000] ;
WaitForSingleObject

Теперь разберемся во всех вызывающихся функциях.
GetStartupInfo нужна для получения одноименной структуры, требующейся для функции создания процесса - CreateProcess. Создаем процесс используя файл mrc32.dll, он то и есть ядро игры. Затем функцией VirtualProtectEx назначаем новые права коду загруженного модуля, а именно разрешаем выполнять этот код. Потом туда копируем код из адреса 12FCA4, и передаем управление созданному процессу, функцией WaitForSingleObject. Единственная трудность это получить код который мы копируем для исполнения. Можно было конечно переписать эти 256 байт и руками, но я сделал по другому.

Вставляю
CD, ставлю брекпоинт на функцию GetDriveTypeA (bpx GetDriveTypeA), запускаю игру. После вылета в функцию, ставлю еще один брекпоинт (bpx 401355),жму F5. Теперь мне нужны адреса трех функций CreateFileA, WriteFile, ExitProcess. Получаю их поможью команды EXP (exp CreateFileA), в ответ должно быть что-то такое:
exp CreateFileA
KERNEL32
001B:77E7A837 CreateFileA
exp WriteFile
KERNEL32
001B:77E79D8C WriteFile
exp ExitProcess
KERNEL32
001B:77E75CB5 ExitProcess


Затем задаю параметры первой функции, прямо в стек.
d esp ##
показать стек
e
## начать редактировать его



Должно это выглядеть как-то так. Функция на языке Си выгледит так: CreateFileA(&filename, 0x40000000, 0, 0, 2, 0x80, 0); 8C 9D E7 77 – это адрес возврата (на функцию WriteFile = 77E79D8C), туда попадаем после завершения функции CreateFileA. По адресу 0012E198 (98 E1 12 00) находится имя файла завершающееся нулевым символом. Этот файл должен сущуствовать. Теперь ставим указатель на начало функции CreateFileA.
r eip=77E7A837
# изменяем значение регистра EIP
bpx WriteFile #
что отловить момент когда завершится первая функция
Жму F5. Если все нормально, то должен остановится на первой команде функции WriteFile, а EAX не равняться FFFFFFFF, потому что это код ошибки. У меня EAX=000007CC, это хэндл на только что созданный файл.
Задаю параметры второй функции, прямо в стек.
d esp ##
показать стек
e
## начать редактировать его




Должно это выглядеть как-то так. Функция на языке Си выгледит так:
WriteFile(hHandle, 0x0012FCA4, 100, 0x0012E1C8, 0); где hHandle=0x7CC, 0x0012FCA4 адрес буфера ради которого все и затеял, 100 его размер, 0x0012E1C8 – сюда напишут сколько реально записали байт. 5B 5C E7 77 – это адрес возврата (на функцию ExitProcess = 77E75CB5), туда попадаем после завершения функции CreateFileA. Теперь у меня есть все чтобы с имитировать запуск игры, т.е. написать загрузчик самому без всяких выкрутасов.

Приведен пример загрузчика:

File calldll.asm
;--------------------------CUT HERE----------------------
.386
.model flat, stdcall
option casemap :none ; case sensitive
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data?
buff db 100h dup (?)
prin db 100h dup (?)
.code
start:
jmp @F
libName db "mrc32.dll",0
include patch.inc
@@:

push offset buff
call GetStartupInfo
 
push offset prin
push offset buff
push 0
push 0
push 4
push 0
push 0
push 0
push offset libName
push 0
call CreateProcess
mov eax, offset [prin+20h]
push eax
push 000040h
push 000100h
mov ecx, 44CCBFh
push ecx
mov eax, dword ptr [prin]
push eax
call VirtualProtectEx
mov eax, offset [prin+20h]
push eax
push 000100h
push offset patch
push 44CCBFh
mov eax, dword ptr [prin]
push eax
call WriteProcessMemory
mov eax, dword ptr [prin+4]
push eax
call ResumeThread
push 0000FFh
mov eax, dword ptr [prin]
push eax
call WaitForSingleObject
invoke ExitProcess,eax
end start
file patch.ini
;--------------------------CUT HERE----------------------
patch:
db 055h,08Bh,0ECh,06Ah,0FFh,068h,018h,024h,06Eh,000h,068h,0ECh,020h,06Ch,000h,064h
db 0A1h,000h,000h,000h,000h,050h,064h,089h,025h,000h,000h,000h,000h,083h,0ECh,058h
db 053h,056h,057h,089h,065h,0E8h,0FFh,015h,00Ch,052h,06Ch,000h,033h,0D2h,08Ah,0D4h
db 089h,015h,0C8h,070h,077h,000h,08Bh,0C8h,081h,0E1h,0FFh,000h,000h,000h,089h,00Dh
db 0C4h,070h,077h,000h,0C1h,0E1h,008h,003h,0CAh,089h,00Dh,0C0h,070h,077h,000h,0C1h
db 0E8h,010h,0A3h,0BCh,070h,077h,000h,033h,0F6h,056h,0E8h,0CAh,052h,0FFh,0FFh,059h
db 085h,0C0h,075h,008h,06Ah,01Ch,0E8h,06Fh,04Eh,027h,000h,059h,089h,075h,0FCh,0E8h
db 0B9h,062h,0FFh,0FFh,0FFh,015h,0D8h,051h,06Ch,000h,0A3h,064h,08Bh,077h,000h,0E8h
db 08Fh,02Ah,0FFh,0FFh,0A3h,0FCh,070h,077h,000h,0E8h,0A3h,0A0h,0FFh,0FFh,0E8h,037h
db 0A1h,0FFh,0FFh,0E8h,0F4h,036h,0FFh,0FFh,089h,075h,0D0h,08Dh,045h,0A4h,050h,0FFh
db 015h,010h,052h,06Ch,000h,0E8h,0FEh,0FEh,0FFh,0FFh,089h,045h,09Ch,0F6h,045h,0D0h
db 001h,074h,006h,00Fh,0B7h,045h,0D4h,0EBh,003h,06Ah,00Ah,058h,050h,0FFh,075h,09Ch
db 056h,056h,0FFh,015h,0E8h,050h,06Ch,000h,050h,0E8h,099h,087h,0FDh,0FFh,089h,045h
db 0A0h,050h,0E8h,0F3h,036h,0FFh,0FFh,08Bh,045h,0ECh,08Bh,008h,08Bh,009h,089h,04Dh
db 098h,050h,051h,0E8h,060h,001h,000h,000h,059h,059h,0C3h,08Bh,065h,0E8h,0FFh,075h
db 098h,0E8h,0C3h,036h,0FFh,0FFh,083h,03Dh,004h,071h,077h,000h,001h,075h,005h,0E8h
; ------------------END CUT -----------------------
file compl.bat
;--------------------------CUT HERE----------------------
@echo off
e:\masm32\bin\ml /Zf /Zi /c /coff /w calldll.asm
if errorlevel 1 goto exit
echo _
echo MASM32 OK *************************************************
echo _
e:\masm32\bin\Link /DEBUG /SUBSYSTEM:WINDOWS calldll.obj
:exit
pause
; ------------------END CUT -----------------------

Весь архив можно скачать (и он вроде даже работает J
) http://freeexec.pisem.net/Donwloads/OperFlashPoint_noCD.rar

Автор: FreeExec
E-mail: freeExec@mail.ru



Обсуждение статьи: Описание метода взлома игры FlashPoint >>>


Материалы находятся на сайте https://exelab.ru



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS