Advertising (This ad goes away for registered users. You can Login or Register)

Right analog patches reversing and sharing knowledge thread

Forum rules
Forum rule Nº 15 is strictly enforced in this subforum.
Locked
reprep
Posts: 1074
Joined: Tue Dec 17, 2013 4:38 pm

Right analog patches reversing and sharing knowledge thread

Post by reprep »

First things first, this is only my failed attemp, i hope we will share more knowledge here though.

After flow's wonderful GTA right analog patch (and several others) (viewtopic.php?f=5&t=47219), i tried to add analog stick patches to some psp games and failed miserably at start. Well, here i will share what i did and who knows maybe others will share too.

I decided to try the game Oblivion (140 MB one), even though it is a beta, right analog stick usage for it would be cool. I decrypted the EBOOT.BIN on my PSP via prxtool. I then used prxtool –w eboot.bin > eboot.asm to get eboot.asm, works fine. Unfortunately pspdecompiler –c eboot.bin > eboot.c failed miserably with prx.c: invalid section type 0x$08X (section 2)
fatal: main.c: can't load prx `eboot.bin'

I then used popseco.pl (viewtopic.php?f=5&t=5573) to get something more readable than MIPS assembly.
Module name is "Oblivion", even though i couldn't find controller function at first look, by trying all ctrl related functions, it seems reading controller function is sub_0033EBA4 and called only in place, from sub_000EFD7C (readbuttons). also sub_000EFD7C is called from Subroutine sub_000EFEEC and Subroutine sub_000F09D8

here is sub_000EFD7C (readbuttons): It seems to read 8 button at once and CtrlPad structure starts at $s0 + (96)

[spoiler]readbuttons: ; Refs: 0x000F002C 0x000F0A10
0x000EFD7C: 0x27BDFFF0 '...'' - addiu $sp, $sp, -16
0x000EFD80: 0xAFB00000 '....' - sw $s0, 0($sp)
0x000EFD84: 0x00808025 '%...' - move $s0, $a0
0x000EFD88: 0x26040060 '`..&' - addiu $a0, $s0, 96
0x000EFD8C: 0xAFBF0004 '....' - sw $ra, 4($sp)
0x000EFD90: 0x0C0CFAE9 '....' - jal sub_0033EBA4
0x000EFD94: 0x34050008 '...4' - li $a1, 0x8
0x000EFD98: 0x54400006 '..@T' - bnezl $v0, loc_000EFDB4
0x000EFD9C: 0x8E040064 'd...' - lw $a0, 100($s0)
0x000EFDA0: 0xAE000064 'd...' - sw $zr, 100($s0)
0x000EFDA4: 0x34040080 '...4' - li $a0, 0x80
0x000EFDA8: 0xA2040068 'h...' - sb $a0, 104($s0)
0x000EFDAC: 0xA2040069 'i...' - sb $a0, 105($s0)
0x000EFDB0: 0x8E040064 'd...' - lw $a0, 100($s0)

loc_000EFDB4: ; Refs: 0x000EFD98
0x000EFDB4: 0x8E0500E4 '....' - lw $a1, 228($s0)
0x000EFDB8: 0xAE0400E0 '....' - sw $a0, 224($s0)
0x000EFDBC: 0x00852826 '&(..' - xor $a1, $a0, $a1
0x000EFDC0: 0x00A43024 '$0..' - and $a2, $a1, $a0
0x000EFDC4: 0x00803827 ''8..' - not $a3, $a0
0x000EFDC8: 0xAE0600E8 '....' - sw $a2, 232($s0)
0x000EFDCC: 0x00A72824 '$(..' - and $a1, $a1, $a3
0x000EFDD0: 0xAE0500EC '....' - sw $a1, 236($s0)
0x000EFDD4: 0xAE0400E4 '....' - sw $a0, 228($s0)
0x000EFDD8: 0x3C05003E '>..<' - lui $a1, 0x3E
; Data ref 0x003E225C ... 0x00000000 0x00000000 0x00000000 0x00000000
0x000EFDDC: 0xACA4225C '\"..' - sw $a0, 8796($a1)
0x000EFDE0: 0x8FB00000 '....' - lw $s0, 0($sp)
0x000EFDE4: 0x8FBF0004 '....' - lw $ra, 4($sp)
0x000EFDE8: 0x03E00008 '....' - jr $ra
0x000EFDEC: 0x27BD0010 '...'' - addiu $sp, $sp, 16[/spoiler]

and more readable by popseco, nevermind the notes in Turkish:
[spoiler]; Subroutine sub_000EFD7C - Address 0x000EFD7C
sub_000EFD7C: ; Refs: 0x000F002C 0x000F0A10
0x000EFD7C: $sp = $sp + (-16);
0x000EFD80: 0($sp) = $s0;
0x000EFD84: $s0 = $a0;
0x000EFD88: $a0 = $s0 + (96);
0x000EFD8C: 4($sp) = $ra;
0x000EFD90: sub_0033EBA4(); ctrl function padi a0 + 96
0x000EFD94: $a1 = 0x8;
0x000EFD98: if $v0 != 0 then goto no delay loc_000EFDB4;
0x000EFD9C: $a0 = 100($s0);
0x000EFDA0: 100($s0) = $zr;
0x000EFDA4: $a0 = 0x80;
0x000EFDA8: 104($s0) = (byte)$a0;
0x000EFDAC: 105($s0) = (byte)$a0;
0x000EFDB0: $a0 = 100($s0);

loc_000EFDB4: ; Refs: 0x000EFD98
0x000EFDB4: $a1 = 228($s0); pad buttons 8. okunanın 16 x 8 128
0x000EFDB8: 224($s0) = $a0; 224 time yerine ilk pad okumapad atandı
0x000EFDBC: $a1 = $a0 ^ $a1; a0 ilk ve 8. okuma xorlandı, yani değişen tuşlar alındı a1'e
0x000EFDC0: $a2 = $a1 & $a0; a2 ilk okumada basılan ama sonra bırakılan tuşlar oldu a2.
0x000EFDC4: not $a3, $a0 a3 ilk başta basılmayan tuşlar
;
0x000EFDC8: 232($s0) = $a2; 8. okuma analoglar yerine a2 yani ilk okumada basılan sonra bırakılan tuşlar oldu
0x000EFDCC: $a1 = $a1 & $a3; a1 ilk başta basılmayan ama sonra basılan tuşlar oldu
0x000EFDD0: 236($s0) = $a1; 8. okuma reserve yerine a1 yani ilk okumada basılmayan ama sonra basılan tuşlar oldu
0x000EFDD4: 228($s0) = $a0; 8. okuma pad buttons yerine a0 yani ilk pad okuma atandı
0x000EFDD8: $a1 = 0x3E0000;
; Data ref 0x003E225C ... 0x00000000 0x00000000 0x00000000 0x00000000
0x000EFDDC: 8796($a1) = $a0; ilk okuma pad.buttonları 0x3E8796ya gönder
0x000EFDE0: $s0 = 0($sp); s0 a eski değerini ver
0x000EFDE4: $ra = 4($sp);
0x000EFDE8: ($ra)();
0x000EFDEC: $sp = $sp + (16);[/spoiler]

Decompilation via Snowman

[spoiler]struct s0 {
signed char[100] pad100;
uint32_t f100;
signed char f104;
signed char f105;
signed char[118] pad224;
uint32_t f224;
uint32_t f228;
uint32_t f232;
uint32_t f236;
};

int32_t fun_33eba4(int32_t a0, int32_t a1);

uint32_t g58fbc = 0x3e00008;

void fun_efd7c(struct s0* a0) {
int32_t v0_2;
uint32_t a0_3;
uint32_t a1_4;
uint32_t a1_5;

v0_2 = fun_33eba4(reinterpret_cast<int32_t>(a0) + 96, 8);
if (v0_2) {
a0_3 = a0->f100;
} else {
a0->f100 = 0;
a0->f104 = 0x80;
a0->f105 = 0x80;
a0_3 = a0->f100;
}
a1_4 = a0->f228;
a0->f224 = a0_3;
a1_5 = a0_3 ^ a1_4;
a0->f232 = a1_5 & a0_3;
a0->f236 = a1_5 & ~a0_3;
a0->f228 = a0_3;
g58fbc = a0_3;
return;
}

void fun_efd94() {
}

void fun_efd9c() {
}

void fun_efdec() {
}[/spoiler]

0x000EFDA4: $a0 = 0x80;
0x000EFDA8: 104($s0) = (byte)$a0;
0x000EFDAC: 105($s0) = (byte)$a0;

this part looks like it is making Lx and Ly equal to 128, meaning left analog stick in unchanged positon, game moves the camera via L + left analog stick combination, this is what i want to change with right analog stick, but why does this code nullifies left analog stick, how can i find where it uses L + left analog stick combo? Couldn't manage to get more work done by looking at other functions.

That is as far as i got, i will edit if i find more.

EDIT: It is the demo (clear from the gameplay) of an unreleased game, but that has no effect on the thread and meaningless to discuss more.

EDIT2: Added Snowman decompilation output

EDIT3: It seems branch at 0x000EFD98 isn't taken when the buttons are read fine, so analog stick info isn't nullified, still looking for where this info is used though.

EDIT4: Left analog stick horizontal info is used on 0x000F0D78 and left analog stick vertical value is used on 0x000F0DB0, you can change the value from there, still couldn't differentiate between movement and camera though, this value changes both.

EDIT5: sub_000F09D8 is the function to mess with, gets the left analog stick info there, manipulates the values with some float arithmetics which i have no idea. Function is called from 0x0037BAFC and 0x0037BBA4, but these are data values, so where does this function really return to?

EDIT6: also storing zero at $a0 at 0x000F0DD8 (sw $zero 0x0000 $a0) makes Y axis of left analog stick nullified, it is later than the last value i found. Again couldn't find where this value is later used. before replacing it was swc1 $fpr12, 0($a0)
Advertising
Last edited by reprep on Sat May 06, 2017 2:31 pm, edited 9 times in total.
Butcher
Posts: 317
Joined: Mon Dec 12, 2016 11:58 pm

Re: Right analog patches reversing and sharing knowledge thr

Post by Butcher »

Oblivion on PSP is beta and unrelesed official (Canceled)
Advertising
Locked

Return to “Programming and Security”