PSPx форум

PSPx форум (https://www.pspx.ru/forum/index.php)
-   PSP хакинг и девелопмент (https://www.pspx.ru/forum/forumdisplay.php?f=195)
-   -   (WIP) Портирование decap патча на Prince of Persia: Rival Swords (https://www.pspx.ru/forum/showthread.php?t=110097)

BlackDaemon 29.04.2020 10:28

(WIP) Портирование decap патча на Prince of Persia: Rival Swords
 
Вложений: 3
Порт decap патча RhymeKidder'a для PSP версии Rival Swords (ULUS-10240), включает разрубание монстров в игре. Залил во вложения пропатченный boot.bin и написанную на скорую руку простенькую утилитку, которая патчит boot.bin или iso образ.
Большое спасибо riku.kh3 и Yoti за помощь! :good:
Нажмите для увеличения

скриншоты
Нажмите для увеличения
Нажмите для увеличения
Нажмите для увеличения

Нажмите для увеличения
Нажмите для увеличения
Нажмите для увеличения

архив
На днях я попробовал изучить исходники патча RhymeKidder'a для PC версии, как он включает decap (разрубание монстров), нашёл похожий код в PSP версии с помощью ghidra, получилось даже частично включить decap внеся грубые правки в пару функций.

Небольшая видео-демка с частично включённым decap для монстров dark reptus:
https://streamable.com/ul4nx0


Код:

//PC - thunk_FUN_00849c30(), PS2 - thunk_FUN_004c0a80(), PSP - thunk_FUN_003132b4()
                HookMem( HOOK_CALL, 0x5e5ecb, (DWORD) &decap_brute ); //PS2 - 0x1a8fb4? PSP - 0x4096c?
                HookMem( HOOK_CALL, 0x675f29, (DWORD) &decap_archer ); //PS2 - 0x233144? PSP - 0xcd194?
               
                //dark reptus decap
                HookMem( HOOK_CALL, 0x6a3bb9, (DWORD) &decap ); //PS2 - 0x389d14, PSP - 0x20ed40

                HookMem( HOOK_CALL, 0x701fb8, (DWORD) &decap ); //PS2 - 0x2ff6f8? PSP - 0x173c18?
                HookMem( HOOK_CALL, 0x70200c, (DWORD) &decap ); //PS2 - 0x2ff798? PSP - 0x173cbc?
               
                HookMem( HOOK_CALL, 0x74662d, (DWORD) &decap ); //PS2 - 0x3fae88? PSP - 0x24b580?
                HookMem( HOOK_CALL, 0x746676, (DWORD) &decap ); //PS2 - 0x3faf1c? PSP - 0x24b618?
               
                HookMem( HOOK_CALL, 0x7b6d8b, (DWORD) &decap ); //PS2 - 0x442b98? PSP - 0x29294c?
                HookMem( HOOK_CALL, 0x7b6dd0, (DWORD) &decap ); //PS2 - 0x442c2c? PSP - 0x2929e4?

К сожалению, с полноценным пропатчиванием возникла проблема, а именно в первых двух функциях, для которых применяется более громоздкий алгоритм. Возник вопрос - чем возможно хукнуть вызов функции в boot.bin и какой аналог asm кода должен быть для MIPS?

decap.h
Код:

int g_blood_addr;



int WINAPI decap()
{
        if( READ32(g_blood_addr) == 0 ) return 1;
        else return 0;
}




void WINAPI fix_brute( DWORD *a_ptr )
{
        // broken animation - brute  (wall vault, counter)
        if( *(a_ptr+0) == 0x04 && *(a_ptr+1) == 0x03 &&
            *(a_ptr+2) == 0x83 && *(a_ptr+3) == 0x82 )
        {
                *(a_ptr+0) = 3;
                *(a_ptr+1) = 4;
                return;
        }
}




void __declspec(naked) decap_brute()
{
        __asm
        {
                pushfd
                push ecx
                push edx


                lea eax, [16+esp+34h]
                push eax
                call fix_brute


                call decap


                pop edx
                pop ecx
                popfd
                retn
        }
}




void WINAPI fix_archer( DWORD *a_ptr )
{
}




void __declspec(naked) decap_archer()
{
        __asm
        {
                pushfd
                push ecx
                push edx


                lea eax, [16+esp+34h]
                push eax
                call fix_archer


                call decap


                pop edx
                pop ecx
                popfd
                retn
        }
}



Edit: добавил во вложения тестовый boot.bin (ULUS-10240) с заменённой через hex decap функцией (без фиксов под brute/archer).

Yoti 29.04.2020 14:05

Исходники это, конечно, хорошо, но лучше бы ссылку на источник. В каком виде он сделан? Если это dll, то в случае с psp по аналогии писать плагин. Либо писать вставки кода в свободные места исполняшки с возвратом обратно. Мануал к архитектуре вот, например.

BlackDaemon 29.04.2020 14:21

Вложений: 1
Yoti, источник был здесь, залил во вложения, т.к. ссылка там уже мертва. Да, сделано в виде dll-инжекта.

Yoti 29.04.2020 15:01

Лучший пример модуля-патчера с загрузчиком оригинального eboot для внедрения в образ вот тут: https://github.com/RaienryuuNoNatsu/ZeroAoVoice-PSP

riku.kh3 30.04.2020 06:57

На PSP хуки вам не нужны, продолжайте делать все так же, как и до этого делали - вносить правки непосредственно в сами функции. Если что-то где-то не влезает - заменяете одну из инструкций бранчем, по новому адресу возвращаете замененную инструкцию, свой код и ставите бранч назад (или используете связку jal-jr). Место для своего кода можно взять там, где обрабатываются строки с различными ошибками (0x47D2D4-0x47D30C например).

"decap_archer" вызывает пустую "fix_archer", которая вообще ничего не делает, после чего вызывает саму "decap". То есть ее сразу на "decap" можно заменить.

Остается только "decap_brute" (вернее "fix_brute"): она смотрит одно из значений в стэке. Если оно равно 0x82830304, то это значение заменяется на 0x82830403. Это надо в отладчике уже смотреть где оно на PSP в стэке. Должно быть что-то вроде того:
Код:

0x47D2D4:
b        0x47D294
nop
0x47D2DC (decap_brute):
lui        v0,0x8283
addiu        v0, v0, 0x304
lw        v1, 0x???(sp) //адрес_в_стэке
bne        v0, v1, лэйбл
nop
addiu        v0, v0, 0xFF
sw        v0, 0x???(sp) //адрес_в_стэке
лэйбл:
jr
li      v0, 1

(по адресу 0x4096c заменить 'jal 0x1E688' на 'jal 0x47D2DC')

BlackDaemon 30.04.2020 10:50

Вложений: 1
riku.kh3, спасибо, пробую ковыряться. Сначала в гидре добавил инструкции, затем скопировал их в hex значениях и попробовал заменить в ELF. Но пока что-то не совсем выходит. Эмулятор видит инструкции иначе :scratch_one-s_head:
Нажмите для увеличения


Код:

        0047d2d4 ef ff 00 10    b          LAB_0047d294
        0047d2d8 00 00 00 00    _nop
        0047d2dc 83 82 02 3c    lui        v0,0x8283
        0047d2e0 04 03 42 24    addiu      v0,v0,0x304
        0047d2e4 00 00 a3 8f    lw        v1,0x0(sp) //temp
        0047d2e8 03 00 62 14    bne        v1,v0,LAB_0047d2f8
        0047d2ec 00 00 00 00    _nop
        0047d2f0 ff 00 42 24    addiu      v0,v0,0xff
        0047d2f4 00 00 a2 af    sw        v0,0x0(sp) //temp
                            LAB_0047d2f8                                    XREF[1]:    0047d2e8(j) 
        0047d2f8 08 00 e0 03    jr        ra
        0047d2fc 01 00 02 20    _li        v0,0x1

Edit: посмотрел ещё перед вызовом функции состояние регистров
Нажмите для увеличения


Edit 2: попробовал в эмуляторе поменять местами значения регистров s3 и s6, это решает проблему с исчезновением монстра при добивании его контр-атакой ;)

riku.kh3 30.04.2020 11:54

Выглядит нормально.
Эмулятор, да, он вместо связки lui и addiu будет отображать псевдоинструкцию 'li v0, 0x82830304'.

Вот так тогда попробуйте:
Код:

0x47D2D4:
b        0x47D294
0x47D2D8 (decap_brute):
li        v0, 0x82
bne        s7, v0, лэйбл
li        v0, 0x83
bne        s2, v0, лэйбл
li        v0, 0x03
bne        s3, v0, лэйбл
li        v0, 0x04
bne        s6, v0, лэйбл
nop
li        s3, 0x04
li        s6, 0x03
лэйбл:
jr
li      v0, 1

(по адресу 0x4096c заменить 'jal 0x1E688' на 'jal 0x47D2D8')

И у вас там в гидре криво некоторые инструкции добавились. В самом эмуляторе попробуйте их скомпилировать (правый клик по инструкции --> Assemble Opcode) и из вкладки 'Memory' переписать hex-значения (одна инструкция = 4 байта).

BlackDaemon 30.04.2020 13:01

Вложений: 1
Попробовал сгенерить hex-код, заменить. В эмуляторе половину инструкций по непонятным причинам выводит битыми:crazy:
Нажмите для увеличения


Код:

        0047d2d4 ef ff 00 10    b          LAB_0047d294
        0047d2d8 82 00 02 20    _li        v0,0x82
        0047d2dc 09 00 e2 16    bne        s7,v0,LAB_0047d304
        0047d2e0 83 00 02 24    _li        v0,0x83
        0047d2e4 07 00 42 16    bne        s2,v0,LAB_0047d304
        0047d2e8 03 00 02 20    _li        v0,0x3
        0047d2ec 05 00 62 16    bne        s3,v0,LAB_0047d304
        0047d2f0 04 00 02 20    _li        v0,0x4
        0047d2f4 03 00 82 16    bne        s4,v0,LAB_0047d304
        0047d2f8 00 00 00 00    _nop
        0047d2fc 04 00 13 20    li        s3,0x4
        0047d300 03 00 16 20    li        s6,0x3
                            LAB_0047d304                                    XREF[4]:    0047d2dc(j), 0047d2e4(j),
                                                                                          0047d2ec(j), 0047d2f4(j) 
        0047d304 08 00 e0 03    jr        ra
        0047d308 01 00 02 20    _li        v0,0x1

Edit: попробую сейчас через эмулятор сгенерить опкоды
Edit2: всёравно ломает инструкции, вот скопированные из дизасма PPSSPP + прикрепил ELF
Код:

1000FFEF
34020082
16E20009
34020083
16420007
34020003
16620005
34020004
16C20003
00000000
34130004
34160003
03E00008
34020001


riku.kh3 30.04.2020 13:14

А, нет, стоп, это не Гидра виновата. Тут таблица релокаций ELF вносит изменения в код при загрузке, в ней занулить надо несколько мест. Замените в эмуляторе инструкции на правильные, если все нормально будет работать я посмотрю где там таблица.

BlackDaemon 30.04.2020 13:40

riku.kh3, я тоже начал подозревать, что что-то переписывает код :D

BlackDaemon добавил 30.04.2020 в 13:40
Потестил чуть код через замену в эмуляторе, вроде всё норм работает :good:
https://streamable.com/kywdld

riku.kh3 30.04.2020 13:57

Вложений: 1
Проверяйте.

BlackDaemon 30.04.2020 14:44

riku.kh3, потестил чуть, вроде бы всё нормально. Большое спасибо! :good: Добавил только переход для 0x4096c на 0x47D2D8, и основной decap функции 0x3132b4 заменил код на return 1. Ночью сделаю ещё тест-драйв по сюжетке, если всё будет стабильно то будет релиз :)

riku.kh3 30.04.2020 15:05

Тогда еще лучше вот так, понадежнее должно быть:
Код:

0x47D2D4:
b        0x47D294
nop
0x47D2DC (decap_brute):
bne        s7, v0, лэйбл
li        v0, 0x83
bne        s2, v0, лэйбл
li        v0, 0x03
bne        s3, v0, лэйбл
li        v0, 0x04
bne        s6, v0, лэйбл
nop
li        s3, 0x04
li        s6, 0x03
лэйбл:
jr
li      v0, 1

(по адресу 0x4096c заменить 'jal 0x1E688' на 'jal 0x47D2DC', по адресу 0x40970 заменить 'nop' на 'li v0, 0x82')

BlackDaemon 01.05.2020 14:54

riku.kh3, прошёл сюжетку, проблем на эмуляторе не возникло :good: Обновил шапку, прикрепил пропатченный бутник и простенькую утилитку :)

BlackDaemon 31.03.2021 15:51

Небольшое обновление - убрана цензура крови, теперь она как и положено красная :D

DiMonOON 24.05.2021 06:43

BlackDaemon, вы можете дать ссылку на уже пропатченый образ игры?

BlackDaemon 07.02.2023 15:40

Вложений: 1
Давненько меня здесь не было :bye: Нашёл, наконец, как убрать цензуру в начале игры:diablo: Пока как тестовый патч, но надеюсь, что ничего случайно не поломалось:D Попробую на днях пройти, если всё будет ок, то обновлю в шапке.

Нажмите для увеличения
Нажмите для увеличения
Нажмите для увеличения
Нажмите для увеличения

BlackDaemon 07.02.2023 20:54

Upd: прошёл сюжетку, PPSSPP крашнулся один раз, но скорее всего из-за того, что savestate'ами баловался. Обновил шапку, добавил последнюю версию патча. Есть ранние наработки по пересадке эффектов крови песочным монстрам, но из-за того, что ресурсы игры плохо изучены результат пока не совсем удовлетворителен.


Текущее время: 04:20. Часовой пояс GMT +3.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc. Перевод: zCarot
PSPx Forum - Сообщество фанатов игровых консолей.