You are not logged in.
Pages: 1
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
@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
There was also a key which automatically aimed at the "best available ball" in pool (not always so accurate, but pretty good)
Offline
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
1 | .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
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 0A8F: 1@ = 0@ - @_printf 000E: 1@ -= 0x49481B 0A8C: write_memory 0x49480B size 1 value 0x 44 virtual_protect 1 0A8C: write_memory 0x 494816 size 1 value 0xE 9 virtual_protect 1 0A8C: write_memory 0x 494817 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 FF 742404 // push [esp+04] B8B0DD 5200 // mov eax, 0052DDB0 FFD 0 // call eax C20C 00 // ret 000C end :_isKeyJustPressed hex FF 742404 // push [esp+04] B850E 45200 // mov eax, 0052E450 FFD 0 // call eax C20C 00 // 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} 30C 0 // xor al, al E 9 // 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
At 008A61D4 there is a pointer to the CLEO opcodes handler. Something like that (CLEO 1 source):
1 2 3 4 5 6 | 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 A 4 00 // mov edx, [0xA49960+eax*4+edx] 81 C 2 60 99 A 4 00 // add edx, 0xA49960 FF E 2 // 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
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.
Last edited by Deji (09-01-2011 21:46)
Offline
I've already said where you should start. It's at 0x8A61D4.
Offline
Ah, I understand much better how CLEO works now.
I'm not sure why, but it's crashing when 0662 is run
1 2 3 4 5 6 | 0A8D: 2@ = read_memory 0x8A61D 4 size 4 virtual_protect 0 000A: 2@ += 0x 7 0A8D: 2@ = read_memory 2@ size 4 virtual_protect 1 000A: 2@ += 0x2B 28 0A8D: 2@ = read_memory 2@ size 4 virtual_protect 0 0A8C: write_memory 0x495E 80 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
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
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
Pages: 1