Little Endian & Big Endian

Started by Bully@Wiiplaza, November 24, 2012, 03:56:31 PM

Previous topic - Next topic

Bully@Wiiplaza

I´ve noticed that some game had a weird way of storing statistics: Little Endian!

e.g. 1000 isn´t represented like this -> 000003E8
but like this -> E80300000

http://en.wikipedia.org/wiki/Endianness

I can set a BP write on it to figure who´s updating that amount.

Is there some expected assembly way of converting little endian to big endian or even a direct way of adding/subing to/from it? Would be amazing to know.

I´m basically interested in hacking the amount of points that are gained. I can´t quite do it the "usual" way (+ xxxx etc.), obviously (since it completely messes with the amount instead).
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

dcx2

Very weird.  The PPC can be "switched" into little endian mode with a bit in the Machine State Register (MSR), so it's possible the game is actually running the CPU in little endian mode.

Some part of the game has to be adding etc to the value.  See if you can find it.  There may be a function whose purpose is to add a little endian number to a big endian number, or there may be a function that takes an argument and returns the opposite endian.  Poke around the top few levels of the call stack to see if anything stands out.

Bully@Wiiplaza

The game seems to store each byte individually. r0 is modified by 8030E96C:  7C600378   or   r0,r3,r0 which came from r1 + 9.

Regs:
[spoiler]  CR:48202888  XER:20000000  CTR:800692A8 DSIS:02400000
DAR:93491F6C SRR0:8030E970 SRR1:0000B032   LR:8030E958
  r0:0000004C   r1:8024A318   r2:80241D00   r3:00000040
  r4:8024A321   r5:00000013   r6:8024A300   r7:8024A2F0
  r8:8024A2F4   r9:8024A2F8  r10:0011C26C  r11:8024A368
r12:800692A8  r13:802409C0  r14:0000000C  r15:8017E590
r16:802D5000  r17:808788B4  r18:93491F6C  r19:00000000
r20:00000000  r21:808788B4  r22:00000008  r23:00000001
r24:00000004  r25:80718FF0  r26:93491F64  r27:80710000
r28:80880000  r29:808787A8  r30:00000000  r31:00000001[/spoiler]

Function:[spoiler]8030E7E8:  9421FFB0   stwu   r1,-80(r1)
8030E7EC:  7C0802A6   mflr   r0
8030E7F0:  90010054   stw   r0,84(r1)
8030E7F4:  39610050   addi   r11,r1,80
8030E7F8:  4BD5044D   bl   0x8005ec44
8030E7FC:  7C731B78   mr   r19,r3
8030E800:  3F208072   lis   r25,-32654
8030E804:  3B398FF0   subi   r25,r25,28688
8030E808:  3C808088   lis   r4,-32632
8030E80C:  386487A8   subi   r3,r4,30808
8030E810:  800487A8   lwz   r0,-30808(r4)
8030E814:  5400103A   rlwinm   r0,r0,2,0,29
8030E818:  7C630214   add   r3,r3,r0
8030E81C:  80030044   lwz   r0,68(r3)
8030E820:  54030FFE   rlwinm   r3,r0,1,31,31
8030E824:  540007FE   rlwinm   r0,r0,0,31,31
8030E828:  7C001A78   xor   r0,r0,r3
8030E82C:  7C030050   sub   r0,r0,r3
8030E830:  2C000001   cmpwi   r0,1
8030E834:  41820018   beq-   0x8030e84c
8030E838:  4BFFFF69   bl   0x8030e7a0
8030E83C:  38600001   li   r3,1
8030E840:  38990230   addi   r4,r25,560
8030E844:  4CC63182   crclr   6,6
8030E848:  48177819   bl   0x80486060
8030E84C:  48172539   bl   0x80480d84
8030E850:  2C030000   cmpwi   r3,0
8030E854:  41820180   beq-   0x8030e9d4
8030E858:  7E639B78   mr   r3,r19
8030E85C:  48046255   bl   0x80354ab0
8030E860:  482B2F3D   bl   0x805c179c
8030E864:  7C7A1B78   mr   r26,r3
8030E868:  2C030000   cmpwi   r3,0
8030E86C:  41820168   beq-   0x8030e9d4
8030E870:  3AE00001   li   r23,1
8030E874:  3B000004   li   r24,4
8030E878:  3BE00001   li   r31,1
8030E87C:  3BC00000   li   r30,0
8030E880:  3F608071   lis   r27,-32655
8030E884:  3F808088   lis   r28,-32632
8030E888:  3BBC87A8   subi   r29,r28,30808
8030E88C:  48000128   b   0x8030e9b4
8030E890:  7C170000   cmpw   r23,r0
8030E894:  40800010   bge-   0x8030e8a4
8030E898:  80630064   lwz   r3,100(r3)
8030E89C:  7C63C02E   lwzx   r3,r3,r24
8030E8A0:  48000008   b   0x8030e8a8
8030E8A4:  387B5A54   addi   r3,r27,23124
8030E8A8:  4BD5D70D   bl   0x8006bfb4
8030E8AC:  7C761B78   mr   r22,r3
8030E8B0:  28031FFC   cmplwi   r3,8188
8030E8B4:  4180001C   blt-   0x8030e8d0
8030E8B8:  4BFFFEE9   bl   0x8030e7a0
8030E8BC:  38600001   li   r3,1
8030E8C0:  38990278   addi   r4,r25,632
8030E8C4:  7EC5B378   mr   r5,r22
8030E8C8:  4CC63182   crclr   6,6
8030E8CC:  48177795   bl   0x80486060
8030E8D0:  801C87A8   lwz   r0,-30808(r28)
8030E8D4:  5400103A   rlwinm   r0,r0,2,0,29
8030E8D8:  7C9D0214   add   r4,r29,r0
8030E8DC:  38770001   addi   r3,r23,1
8030E8E0:  80040044   lwz   r0,68(r4)
8030E8E4:  7C030000   cmpw   r3,r0
8030E8E8:  40800014   bge-   0x8030e8fc
8030E8EC:  80040064   lwz   r0,100(r4)
8030E8F0:  7C60C214   add   r3,r0,r24
8030E8F4:  82A30004   lwz   r21,4(r3)
8030E8F8:  48000008   b   0x8030e900
8030E8FC:  3ABB5A54   addi   r21,r27,23124
8030E900:  3A800000   li   r20,0
8030E904:  7E5AB214   add   r18,r26,r22
8030E908:  48000094   b   0x8030e99c
8030E90C:  7C630774   extsb   r3,r3
8030E910:  2C03005A   cmpwi   r3,90
8030E914:  40820010   bne-   0x8030e924
8030E918:  9BD20000   stb   r30,0(r18)
8030E91C:  3A940001   addi   r20,r20,1
8030E920:  48000074   b   0x8030e994
8030E924:  2C03004F   cmpwi   r3,79
8030E928:  40820010   bne-   0x8030e938
8030E92C:  9BF20000   stb   r31,0(r18)
8030E930:  3A940001   addi   r20,r20,1
8030E934:  48000060   b   0x8030e994
8030E938:  38810008   addi   r4,r1,8
8030E93C:  4BFFFE69   bl   0x8030e7a4
8030E940:  2C030000   cmpwi   r3,0
8030E944:  41820038   beq-   0x8030e97c
8030E948:  88110001   lbz   r0,1(r17)
8030E94C:  7C030774   extsb   r3,r0
8030E950:  38810009   addi   r4,r1,9
8030E954:  4BFFFE51   bl   0x8030e7a4
8030E958:  2C030000   cmpwi   r3,0
8030E95C:  41820020   beq-   0x8030e97c
8030E960:  88010008   lbz   r0,8(r1)
8030E964:  54032036   rlwinm   r3,r0,4,0,27
8030E968:  88010009   lbz   r0,9(r1)
8030E96C:  7C600378   or   r0,r3,r0
8030E970:  98120000   stb   r0,0(r18) # break
8030E974:  3A940002   addi   r20,r20,2
8030E978:  4800001C   b   0x8030e994
8030E97C:  4BFFFE25   bl   0x8030e7a0
8030E980:  38600001   li   r3,1
8030E984:  389902C4   addi   r4,r25,708
8030E988:  7EA5AB78   mr   r5,r21
8030E98C:  4CC63182   crclr   6,6
8030E990:  481776D1   bl   0x80486060
8030E994:  3AD60001   addi   r22,r22,1
8030E998:  3A520001   addi   r18,r18,1
8030E99C:  7E35A214   add   r17,r21,r20
8030E9A0:  7C75A0AE   lbzx   r3,r21,r20
8030E9A4:  7C600775   extsb.   r0,r3
8030E9A8:  4082FF64   bne+   0x8030e90c
8030E9AC:  3B180008   addi   r24,r24,8
8030E9B0:  3AF70002   addi   r23,r23,2
8030E9B4:  801C87A8   lwz   r0,-30808(r28)
8030E9B8:  5400103A   rlwinm   r0,r0,2,0,29
8030E9BC:  7C7D0214   add   r3,r29,r0
8030E9C0:  80030044   lwz   r0,68(r3)
8030E9C4:  7C170000   cmpw   r23,r0
8030E9C8:  4180FEC8   blt+   0x8030e890
8030E9CC:  7E639B78   mr   r3,r19
8030E9D0:  482B2EB9   bl   0x805c1888
8030E9D4:  39610050   addi   r11,r1,80
8030E9D8:  4BD502B9   bl   0x8005ec90
8030E9DC:  80010054   lwz   r0,84(r1)
8030E9E0:  7C0803A6   mtlr   r0
8030E9E4:  38210050   addi   r1,r1,80
8030E9E8:  4E800020   blr   [/spoiler]
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

Bully@Wiiplaza

#3
Bump.

Here´s some ridiculous way I came up with on how to convert little endian <-> big endian ;D ;D ;D
lis r12, 0xXXXX
lis r10, 0xQQQQ

lbz r11, 0xYYYY (r12)
stb r11, 0xWWWW + 3 (r10)
lbz r11, 0xYYYY + 1 (r12)
stb r11, 0xWWWW + 2 (r10)
lbz r11, 0xYYYY + 2 (r12)
stb r11, 0xWWWW + 1 (r10)
lbz r11, 0xYYYY + 3 (r12)
stb r11, 0xWWWW (r10)
lwz r11, 0xWWWW (r10)

We read each byte manually and store them back inversed to some random RAM location. Finally, we load the full 32bit word into r11.
Caution! We need to convert back before writing to our address.

Any better ideas than that? :)
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

James0x57

I think this is right

~11 lines, pseudo asm, needs 3 registers (counting the one that has the 32bit value to be byte reversed) and no storage:


if register a = 01020304

c = a<<16  # (shift left 16 bits) // c = 0304
a = a>>16  # (shift right 16 bits -- make sure left zeros)  // a = 0102
b = a<<8
b = b AND 0x0000FF00 //might not be needed if there's specific asm for special shifting
a = a>>8
a = b OR a   # a = 0201
b = c<<8
c = c>>8
c = b OR c   # c = 0403
c = c<<16
a = c OR a   # a = 04030201


Bully@Wiiplaza

Doesn´t look like an ideal solution either, but thank you for this, James. :o
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully

megazig


James0x57

Gah! I knew there was an instruction but I could not find it. lol Thanks megazig


dcx2

#8
Quote from: James0x57 on November 26, 2012, 09:11:22 PM
b = b AND 0x0000FF00 //might not be needed if there's specific asm for special shifting

I believe what you were looking for was rlwimi (Rotate Left Word Immediate then Mask Insert).  It allows you to rotate a register, and then generate a bit mask (like rlwinm style bit mask, see that thread where brkirch goes into detail), and then insert the masked bits directly into the destination register.  Quite a complex instruction, but it can be very handy.  http://pds.twi.tudelft.nl/vakken/in101/labcourse/instruction-set/rlwimi.html

rlwimi would allow you to mask and insert each byte at the appropriate area with just four instructions.  Assuming r12 has the word of interest and r11 is where you want it (and I *think* this will work, but rlwimi is confusing so I may have misunderstood the docs, and some of the numbers may need tweaked)

rlwimi r11, r12, 24, 0, 7 # rotate r12 to the left 24 bits (byte 3 rotated to byte 0), then mask off bits 0-7 (byte 0), and overwrite byte 0 of r12
rlwimi r11, r12, 8, 8, 15 # rotate r12 to the left 8 bits (byte 2 rotated to byte 1), mask off bits 8-15 (byte 1), overwrite byte 1 of r12
rlwimi r11, r12, 24, 16, 23 # r12 to the left 24 bits (= rotate right by 8 bits), mask off byte 2, overwrite byte 2 of r12
rlwimi r11, r12, 8, 24, 31 # r12 to the left 8 bits (= rotate right 24 bits), mask off byte 3, overwrite byte 3 of r12

However, megazig is right, lwbrx (Load Word Byte-Reversed indeXed) is the way to go.  Kudos for remembering that instruction!  However, I thought the rlwimi instruction might be enlightening too.

EDIT:

hmm....can we do this in three instructions?

rlwimi r11, r12, 24, 0, 23
rlwimi r11, r12, 8, 8, 15
rlwimi r11, r12, 8, 24, 31

Bully@Wiiplaza

I just used "megazig´s" instructions
Quote from: megazig on November 26, 2012, 10:53:25 PM
lwbrx, stwbrx
and yeah, confirmed working! ^_^
My Wii hacking site...
http://bullywiihacks.com/

My youtube account with a lot of hacking videos...
http://www.youtube.com/user/BullyWiiPlaza

~Bully