#1 08-01-2011 00:23

Deji
From: UK
Registered: 09-11-2008
Posts: 189
Website

Restoring Rockstars Original Opcodes

Original Topic

I made a start on restoring Rockstars original opcodes which were NOP'd out. I don't think I'll get too much further than I have so far (struggling on 0662 at the moment) as my ASM skills aren't the best.

It'd probably be easier if I knew C++, but ASM is still mostly easier for me at the moment and I want to practise writing it.

Offline

#2 08-01-2011 00:56

Sergey81
Registered: 19-12-2008
Posts: 654

Re: Restoring Rockstars Original Opcodes

@Deji -

For example, pressing "1" on the bee game will increase your life count for as long as you keep the key held down (0735: 0x31). "S" can be used in quite a lot of missions to skip the mission.

Wow, thats really works, i guess it's might be useful for...something cool:D

Offline

#3 08-01-2011 01:34

Deji
From: UK
Registered: 09-11-2008
Posts: 189
Website

Re: Restoring Rockstars Original Opcodes

There was also a key which automatically aimed at the "best available ball" in pool (not always so accurate, but pretty good) smile

Offline

#4 09-01-2011 06:14

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Restoring Rockstars Original Opcodes

to "revive" 0662... CLEO 4 has the similar opcode 0ACA. Make it so the 0662 will call the 0ACA handler.

find where 0ACA is located by following the CLEO opcode table (pointer @ 008A61D4) and change 0662's address

.text:00495E80                     dd offset @@opcode_0662 ; jumptable 00494017 case 32

write there address of 0ACA and every 0662 will now call 0ACA opcode with the given string parameter.

Offline

#5 09-01-2011 15:08

Deji
From: UK
Registered: 09-11-2008
Posts: 189
Website

Re: Restoring Rockstars Original Opcodes

I've found all handlers for CLEO 4, but it's updated quite a lot and it'd be nice for the script to work with CLEO 3 until everyone can use CLEO 4 without compatibility errors etc.

I believe 0662 might have originally called the _printf function. I believe listener made an .asi to log what was passed to that file, but it causes huge log files.


I've tried to call on _showTextBox and then jump back to the opcode handler, but it didn't work:

0A8F: 1@ = 0@ - @_printf
000E: 1@ -= 0x49481B
0A8C: write_memory 0x49480B size 1 value 0x44 virtual_protect 1
0A8C: write_memory 0x494816 size 1 value 0xE9 virtual_protect 1
0A8C: write_memory 0x494817 size 4 value 1@ virtual_protect 1
0A8F: 1@ = 0@ - @_printf_jmp
0A8F: 2@ = 0x495DDF - 1@
0A8C: write_memory 1@ size 4 value 2@ virtual_protect 1
0A93: end_custom_thread

:_isKeyPressed
hex
FF742404        // push [esp+04]
B8B0DD5200      // mov eax, 0052DDB0
FFD0            // call eax
C20C00          // ret 000C
end

:_isKeyJustPressed
hex
FF742404        // push [esp+04]
B850E45200      // mov eax, 0052E450
FFD0            // call eax
C20C00          // ret 000C
end

:_printf
hex
{6A00            // push 00
6A00            // push 00
6A00            // push 00
8D4C247C        // lea ecx, [esp+7Ch]
51              // push ecx
B8E08B5800      // mov eax,00588BE0
FFD0            // call eax}
30C0            // xor al, al
E9              // jmp 00495DE3
end

:_printf_jmp
hex
00000000
end

Even with no functional code, jumping back causes a crash to desktop. Not sure why.


Just tried to do it with CLEO 4's API, but my .cleo failed to launch. Also, despite removing loads of code from one of the examples, it compiles at over 25kb.. which is much more than the original .cleo file. Dunno if my compiler is screwing up there or something, but at least I finally managed to compile something!


For me to use 0ACA to do this, for the time being, how would it work? In IDA, I see the address as being 10003E50, but I'm not sure where it would start in SA.

Last edited by Deji (09-01-2011 15:12)

Offline

#6 09-01-2011 20:55

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Restoring Rockstars Original Opcodes

At 008A61D4 there is a pointer to the CLEO opcodes handler. Something like that (CLEO 1 source):

 8B 44 24 04            // mov eax, [esp+4+Opcode]
 66 2D 8C 0A            // sub ax, 0x0A8C
 BA @CLEO_Pointers      // mov edx, @CLEO_Pointers
 8B 94 82 60 99 A4 00   // mov edx, [0xA49960+eax*4+edx]
 81 C2 60 99 A4 00      // add edx, 0xA49960
 FF E2                  // jmp edx

@CLEO_Pointers is a table of opcode handlers. Read 008A61D4, than add needed number of bytes to read the address of that table and read it. You will get an address of the list of opcodes. Use the debugger to see how it looks like. Add needed number of bytes to read the address of 0ACA opcode. Than write this address at 00495E80

Offline

#7 09-01-2011 21:45

Deji
From: UK
Registered: 09-11-2008
Posts: 189
Website

Re: Restoring Rockstars Original Opcodes

Yeah, I'd considered that method before. But where would CLEO be positioned in the memory? Is the position absolute or would I have to read a pointer to get there?


Unfortunately, I also just messed up my IDB (I'd spent so long adding structures) and have to redownload. sad

Last edited by Deji (09-01-2011 21:46)

Offline

#8 10-01-2011 01:08

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Restoring Rockstars Original Opcodes

I've already said where you should start. It's at 0x8A61D4.

Offline

#9 10-01-2011 18:23

Deji
From: UK
Registered: 09-11-2008
Posts: 189
Website

Re: Restoring Rockstars Original Opcodes

Ah, I understand much better how CLEO works now.


I'm not sure why, but it's crashing when 0662 is run

0A8D: 2@ = read_memory 0x8A61D4 size 4 virtual_protect 0
000A: 2@ += 0x7
0A8D: 2@ = read_memory 2@ size 4 virtual_protect 1
000A: 2@ += 0x2B28
0A8D: 2@ = read_memory 2@ size 4 virtual_protect 0
0A8C: write_memory 0x495E80 size 4 value 2@ virtual_protect 0

The value written to the 0662 pointer must be correct. The ASM at that memory location matches what's shown in the disassembler. Crashes at 0x2059F9F, for some reason. Seems totally irrelevant since no written value points there..

Offline

#10 10-01-2011 19:21

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Restoring Rockstars Original Opcodes

oh, I know what's happened. sorry you can't use the CLEO opcode in this way, as when 0662 jumps at 0ACA after executing it returns not in the sa opcode handler but in the CLEO one. so, different stacks, etc -> crash.

Other way is to write a pure asm code directly in a cleo script and change the address 0x00494812 with the asm address. the asm code should include 2 functions: one that wlll read the string param (CScriptThread__getStringParam) and the second that will pass this string to the printf function.

Offline

#11 10-01-2011 20:10

Deji
From: UK
Registered: 09-11-2008
Posts: 189
Website

Re: Restoring Rockstars Original Opcodes

That was the original plan. Instead, I let the original 0662 function get the string and then made a jump to my ASM, which passed the pointer to _printf, but it didn't work (crash to desktop).

Guess this isn't going to be as hard as restoring the debug file logging functions, though.

I should really get going with C++, then it would be much easier.

Last edited by Deji (10-01-2011 20:11)

Offline

Board footer

Powered by FluxBB