Standard ASM code?

Started by Sharkbyte, May 28, 2010, 02:25:37 PM

Previous topic - Next topic

Sharkbyte

ok, this has been frustrating me for weeks. How does a hacker know what values/commands to put in a standard asm code when i clearly don't even see those commands/values anywhere in wiird's memory?  ???
Anyway i'm going to give out a code that has been hacked from another hacker and show what the disassembler looks like. The breakpoint code i am breakpointing is moon jump at 8110EA50 [spoiler]    set breakpoint: 8110EA50 - Write
CR  : 88000088  XER : 00000000  CTR : 801FFCC0  DSIS: 02400000
DAR : 8110EA50  SRR0: 80395074  SRR1: 0000B032  LR  : 8039502C
r0  : 00000000  r1  : 805D5C18  r2  : 805C8D20  r3  : 00000000
r4  : 0000002A  r5  : 00000025  r6  : 80E06B48  r7  : 80E05C0C
r8  : 80E05C00  r9  : 00000000  r10 : 80E06BAC  r11 : 805D5B48
r12 : 801FFCC0  r13 : 805C4140  r14 : 00000002  r15 : 00000001
r16 : 8055108C  r17 : 00000210  r18 : 000004B0  r19 : 00000003
r20 : 8110BE40  r21 : 810FB620  r22 : 810FCEC0  r23 : 80490000
r24 : 80574A18  r25 : 00000004  r26 : 8110EA00  r27 : 8110BE40
r28 : 00000000  r29 : 00000000  r30 : 00000000  r31 : 00000001

f0  : 00000000  f1  : 403ECD1D  f2  : BF4D4CB7  f3  : BCBF5688
f4  : 40400000  f5  : 40400000  f6  : C3180002  f7  : 00000000
f8  : 00000000  f9  : 00000000  f10 : 00000000  f11 : 00000000
f12 : 3CA3EACC  f13 : 00000000  f14 : 41200000  f15 : 3F800000
f16 : 3D08AB86  f17 : 3D88AB86  f18 : 00000000  f19 : 3E800000
f20 : 42C80000  f21 : 00000000  f22 : 00000000  f23 : 00000000
f24 : 3F800000  f25 : 00000000  f26 : BF860A92  f27 : 00000000
f28 : 00000000  f29 : 00000000  f30 : 40400000  f31 : 3CBF5688

break list
80395074:  D03A0050   stfs   f1,80(r26)
80395078:  40810008   ble-   0x80395080
8039507C:  48000008   b   0x80395084
80395080:  FC600090   fmr   f3,f0
80395084:  D07A0220   stfs   f3,544(r26)
80395088:  C002D690   lfs   f0,-10608(r2)
8039508C:  C0C1002C   lfs   f6,44(r1)
80395090:  EC400032   fmuls   f2,f0,f0
80395094:  C022D7F0   lfs   f1,-10256(r2)
80395098:  EC0601B2   fmuls   f0,f6,f6
8039509C:  ECE2002A   fadds   f7,f2,f0
803950A0:  FC070840   fcmpo   cr0,f7,f1
803950A4:  40810008   ble-   0x803950ac
803950A8:  FC203890   fmr   f1,f7
803950AC:  FC400834   fsqrte   f2,f1
803950B0:  C0A2D6EC   lfs   f5,-10516(r2)



attempting to break 80395074 (execute)

list

CR  : 88000088  XER : 00000000  CTR : 801FFCC0  DSIS: 02400000
DAR : 8110EA50  SRR0: 80395074  SRR1: 0000B032  LR  : 8039502C
r0  : 00000000  r1  : 805D5C18  r2  : 805C8D20  r3  : 00000000
r4  : 0000002D  r5  : 0000002B  r6  : 80E06D3C  r7  : 80E05C0C
r8  : 80E05C00  r9  : 00000002  r10 : 80E06DA0  r11 : 805D5B48
r12 : 801FFCC0  r13 : 805C4140  r14 : 00000002  r15 : 00000001
r16 : 80551080  r17 : 00000000  r18 : 00000000  r19 : 00000000
r20 : 810FFE40  r21 : 810FB410  r22 : 810FCA10  r23 : 80490000
r24 : 80574A18  r25 : 00000004  r26 : 81102C00  r27 : 810FFE40
r28 : 00000000  r29 : 00000000  r30 : 00000002  r31 : 00000001

f0  : 00000000  f1  : 403ECD1D  f2  : BF4D4CB7  f3  : BCBF5688
f4  : 40400000  f5  : 40400000  f6  : C3200003  f7  : 00000000
f8  : 00000000  f9  : 00000000  f10 : 00000000  f11 : 00000000
f12 : 3DD595D1  f13 : 00000000  f14 : 41200000  f15 : 3F800000
f16 : 3D08AB86  f17 : 3D88AB86  f18 : 00000000  f19 : 3E800000
f20 : 42C80000  f21 : 00000000  f22 : 00000000  f23 : 00000000
f24 : 3F800000  f25 : 00000000  f26 : BF860A92  f27 : 3F296A10
f28 : 41D3C494  f29 : 00000000  f30 : 40400000  f31 : 3CBF5688


80395074:  D03A0050   stfs   f1,80(r26)
80395078:  40810008   ble-   0x80395080
8039507C:  48000008   b   0x80395084
80395080:  FC600090   fmr   f3,f0
80395084:  D07A0220   stfs   f3,544(r26)
80395088:  C002D690   lfs   f0,-10608(r2)
8039508C:  C0C1002C   lfs   f6,44(r1)
80395090:  EC400032   fmuls   f2,f0,f0
80395094:  C022D7F0   lfs   f1,-10256(r2)
80395098:  EC0601B2   fmuls   f0,f6,f6
8039509C:  ECE2002A   fadds   f7,f2,f0
803950A0:  FC070840   fcmpo   cr0,f7,f1
803950A4:  40810008   ble-   0x803950ac
803950A8:  FC203890   fmr   f1,f7
803950AC:  FC400834   fsqrte   f2,f1
803950B0:  C0A2D6EC   lfs   f5,-10516(r2)


[/spoiler]    284B732A FBFF0400
C2395074 00000004
2C130003 4182000C
D03A0050 4800000C
3D804170 919A0050
60000000 00000000
E0000000 80008000
284B732A 00000000
04395074 D03A0050
E0000000 80008000
  cmpwi r19,3
beq- 0x0C
stfs f1,80(r26)
b 0x0C
lis r12,16752
stw r12,80(r26)
nop
I can provide additional information before the breakpoint if necessary. I just don't understand where these values/commands come from.  ???  ???  ???

wiiztec

What are you talking about?
If there's any code at all that you want to be button activated, or even able to toggle on & off, and I have the game, just PM me and I'll make it happen

ZiT

#2
C2395074 00000004
2C130003 4182000C
D03A0050 4800000C
3D804170 919A0050

60000000 00000000
=
1)04395074 4BC6E18C : b 0x80003200 : (Empty memory address)
2) 04003200 2C130003 : cmpwi r19,3
3) 04003204 4182000C : beq- 0x80003210
4) 04003208 D03A0050 : stfs f1,80(r26)
5) 0400320C 4800000C : b 0x80003218
6) 04003210 3D804170 : lis r12,16752
7) 04003214 919A0050 : stw r12,80(r26)
8)04003218 48391E60 : b 0x80395078 (= 80395074 + 00000004)
-The C2 code can shorten this long instruction like the above-mentioned.

2) - 7) = Instruction group that hacker voluntarily added.





wiiztec

Why would they have to be somewhere else in memory?
If there's any code at all that you want to be button activated, or even able to toggle on & off, and I have the game, just PM me and I'll make it happen

dcx2

A CPU executes Machine Code.  This is the 1s and 0s.  Humans aren't very good at reading Machine Code.  For instance, the instruction 3D804170 looks very confusing to us.

That is why we use assembly.  There is a one-to-one conversion from Machine Code to ASM.  In this case, 3D804170 = lis r12,16752.  Sometimes you can read a little bit, though.  For instance, the last 16 bits of this instruction are an Immediate; specifically, the value 16752.  Well, I can tell you that 16752 = 0x4170.  Look at the machine code - 3D804170.

When writing an ASM code, we start with a goal in mind, and then write some instructions that accomplish that goal.  The keys to this code are r19 (some conditional value) and 80(r26) (some location in memory that holds an interesting value).  We want to write either f1 (the "original" value) or 41700000 (the hacked value) to 80(r26), depending on r19.

Here's the code with some comments

2) 04003200 2C130003 : cmpwi r19,3      # is there a 3 in r19?
3) 04003204 4182000C : beq- 0x80003210   # if so, skip this section
4) 04003208 D03A0050 : stfs f1,80(r26)      # store f1 to 80(r26)
5) 0400320C 4800000C : b 0x80003218      # skip to the finish
6) 04003210 3D804170 : lis r12,16752      # put 41700000 into r12
7) 04003214 919A0050 : stw r12,80(r26)      # store r12 to 80(r26)

So, in the event that r19 has a 3 in it, the code will put 41700000 at the address 80(r26).  The blue instructions will be executed.

2) 04003200 2C130003 : cmpwi r19,3      # is there a 3 in r19?
3) 04003204 4182000C : beq- 0x80003210   # if so, skip this section
4) 04003208 D03A0050 : stfs f1,80(r26)      # store f1 to 80(r26)
5) 0400320C 4800000C : b 0x80003218      # skip to the finish
6) 04003210 3D804170 : lis r12,16752      # put 41700000 into r12
7) 04003214 919A0050 : stw r12,80(r26)      # store r12 to 80(r26)

If there is no 3 in r19, the code will put f1 into 80(r26).

2) 04003200 2C130003 : cmpwi r19,3      # is there a 3 in r19?
3) 04003204 4182000C : beq- 0x80003210   # if so, skip this section
4) 04003208 D03A0050 : stfs f1,80(r26)      # store f1 to 80(r26)
5) 0400320C 4800000C : b 0x80003218      # skip to the finish
6) 04003210 3D804170 : lis r12,16752      # put 41700000 into r12
7) 04003214 919A0050 : stw r12,80(r26)      # store r12 to 80(r26)

ZiT

Thank you for the explanation ;D :p

dcx2

Quote from: Sharkbyte on May 28, 2010, 04:01:49 PM
How does an individual decide what to add volutarily when and/where?  ???

what to add: stare at the ASM for a while in the disassembler.  Get a feel for what values are in what registers.  Write notes.

It also helps to familiarize yourself with the various ASM instructions the PowerPC can use.  http://pds.twi.tudelft.nl/vakken/in1200/labcourse/instruction-set/

when/where to add: C2 codes "hook" ASM.  You need to find somewhere in the ASM that has the interesting values during the breakpoint.  We don't know what's in r26 and it could very well change.  However, at the instruction 80395074, r26 has the pointer that we're interested in, r19 has the value we're interested in, etc.

The code handler will take care of writing the branches that make the game jump to your hook and back.

dcx2

There are 32 registers, r0-r31.  Some of them are always forbidden (r1 and r2, specifically).  Never, ever, ever use those registers.  Okay, well, sometimes you can use r1, but there are very special rules that you have to follow very carefully or it will crash...don't use r1 unless you understand the stack conventions that you must follow.

Where did r12 come from?  The author of the code chose r12, probably because it's a "safe register".  You must carefully evaluate the ASM to see what registers it is using.  This is the tricky part about doing ASM codes.  You don't really know for sure what registers are safe.  If r12 had some important pointer in it, and we write over that pointer, it is game over.

How do you know what is safe?  Some people choose any register that has a 0 in it, but that method frightens me because some registers are actually holding a 0.

If something is loading r12 with a value (e.g. "li r12, 0", "addi r12, r3, 1", etc), then it doesn't matter what's in r12 at that point, because it will be over-written.  Any time a register is explicitly written to, that register is safe for all the instructions at the address BEFORE the register is written to, but AFTER the last time it is read from.

If there are no safe registers, you can make some room on the stack and push/pop a few registers to make them safe.  But it is tricky.  I wrote a little bit more about finding safe registers and identifying dependencies here.

http://wiird.l0nk.org/forum/index.php/topic,5407.msg46274.html#msg46274

ZiT

I use r12 when there is no empty register.

As for it, r12 is not usually used excluding the jump of the function.

I learnt this from Y.S.

wiiztec

Couldn't you use any register other than r1 & r2 as long as your C2 code sets it back to it's original value when it's done using it?
If there's any code at all that you want to be button activated, or even able to toggle on & off, and I have the game, just PM me and I'll make it happen

Romaap

Yes, this is done by pushing them on the stack at the start of your code and restoring them at the end of your code.

wiiztec

No i'm talking about doing it yourself with li or lis then ori
If there's any code at all that you want to be button activated, or even able to toggle on & off, and I have the game, just PM me and I'll make it happen

dcx2

That would only work if the value in the register was a constant.  Like if there was an li r0,3 before your C2 code, then you know nothing but 3 will ever be in r0.

However, if r0 was loaded from a pointer, the value could change.  The only way to preserve it would be pushing/popping.

wiiztec

Not so if there was a register with an address close to a portion of unused memory you could store the register there then load it back in at the end of your C2 code

Well actually that's not surefire either because the register you'd be using as a pointer could change
If there's any code at all that you want to be button activated, or even able to toggle on & off, and I have the game, just PM me and I'll make it happen

Romaap

Pushing/Poping from the stack is the same as storing it in unused memory, the stack is just a chunk in memory where values are stored temporary.