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

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

Автор: FreeExec

Проанализировав содержимое файла 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][0FFFFF254] ; ссылка на буфер с меткой тома диска

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 0000014C0 ——— (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(

Добавить комментарий