Quantcast

Jump to content

» «
Photo

GTA LCS/VCS research project

19 replies to this topic
fastman92
  • fastman92

    фастман92 | ف

  • Members
  • Joined: 28 Jul 2009
  • None
  • Contribution Award [Mods]

#1

Posted 08 March 2014 - 03:08 PM Edited by fastman92, 28 June 2014 - 09:46 AM.

In this topic I will post about what's already known about LCS/VCS.
Topic will be updated as the research is going on.

I understood the SCM format of LCS/VCS SCM and recognized most of the LCS & VCS SCM commands.
I wrote a simple compiler in C++ for SCM in 3 days.

I made a stripped main.scm for LCS and VCS.

Here's how player looks in LCS with my stripped SCM:
27a2d1312872643.jpg

Test of stripped SCM for VCS:
61f7bc312455555.jpg
My testing script gets 3D coords of player, converts them to 2D screen coords and displays a text 'M_OVER', which i have edited in english.gxt

CLEO library for LCS/VCS?
That would be a great addition for these games, I think.
It would require learning how to develop for PS2.
  • Jeansowaty, Marių and Sweet Bellic like this

Jinx.
  • Jinx.

  • Facade Corporation
  • Joined: 15 Dec 2010
  • Unknown
  • Best WIP Mod 2014 [Grand Theft Auto 3D]

#2

Posted 08 March 2014 - 03:15 PM

Interesting... I have VCS on PS2, but I can't mod the PS2 because it's my cousin's :( . BTW this is awesome! Keep up the good work!


fastman92
  • fastman92

    фастман92 | ف

  • Members
  • Joined: 28 Jul 2009
  • None
  • Contribution Award [Mods]

#3

Posted 08 March 2014 - 06:29 PM Edited by fastman92, 08 March 2014 - 08:29 PM.

How to fix $gp based offsets in MIPS executable?
Some time ago during analysis of GTA LCS executable I found a code like this:
110418312927545.jpg

















.text:00109E0C 080 move $a0, $s2 # file
.text:00109E10 080 jal CFileMgr__Read # Offset is 8 from begginng now, read MAIN section now
.text:00109E14 080 lw $a2, 0x2D34($gp) # num
You see, the data (size of MAIN section read from main.scm) is being loaded from address pointed by a value of $gp + immediate value 0x2D34
 
$gp is the name of MIPS register that points to the global area.
 
In other worlds the address where the value is loaded from = value of $gp + 0x02D34.
From how $gp is used it can be said that a value of $gp is constant - never changes during execution of game code.
 
 
But because $gp is nowhere declared in a function, IDA Pro doesn't know the value of $gp and won't create a reference to memory value.
First of all, we need to know what is the value of $gp
 
In functions CTheScripts::Init $gp is already set up.
We know that CTheScripts::Init must have been called by some function which has yet been called by another higher function.
We can go to reference of our function and see if $gp is set up there.
Actually the function in which $gp is set up is named a start
It's entry point of executable.
24b943312932261.jpg
We see, this code sets all registers to zero.
 
But still zero isn't going to be a value of $gp.
We can look the code below:
8a76e4312933017.jpg









.text:001C6C04 000 la $a0, asc_3D6EF0 # "\nÎ#="
.text:001C6C08 000 li $a1, 0x1FE0000
.text:001C6C0C 000 li $a2, 0x20000
.text:001C6C10 000 la $a3, dword_410180
.text:001C6C14 000 la $t0, loc_1C6CA8
.text:001C6C18 000 move $gp, $a0
We can clearly see the instruction









la $a0, asc_3D6EF0 # "\nÎ#="
$a0 = 0x3D6EF0
Then what happens is $gp gets a value of $a0, which is 0x3D6EF0
 
Let's go back to CTheScripts::Init









.text:00109E10 080 jal CFileMgr__Read # Offset is 8 from begginng now, read MAIN section now
.text:00109E14 080 lw $a2, 0x2D34($gp) # num
In IDA Pro you can press Ctrl + R on operand and set the base address which is 0x3D6EF0 in this case.
Then what we get is









.text:00109E14 080 lw $a2, (_ZN11CTheScripts14MainScriptSizeE - asc_3D6EF0)($gp) # num
But since $gp value is not meaningful, we should better have no reference to asc_3D6EF0 here.
Ctrl + R, check the Treat the base address as a plain number.









.text:00109E14 080 lw $a2, (_ZN11CTheScripts14MainScriptSizeE - 0x3D6EF0)($gp) # num
Now it's better.
 
But there are thousand of $gp references, it would be a hell work to search for $gp register references and set them up manually by hand.
IDA Pro is very interactive tool, when manual analysis of code fails because of the amount of ($gp) references, the IDC/Python may be written to automate the process.
 
I wrote a simple IDC script to fix the $gp references in MIPS executables.
Link to this script: http://pastebin.com/c3Zu4Rix


How to mark data as strings in range of addresses?
A lot of times you may find data that must be strings, but since they're not referenced by any instruction, IDA Pro won't mark them as string values.

Beginning:
0ba489312958507.jpg
And this is where the last string may be found:
40e219312959351.jpg

You can see on the screenshot, one string coming after another.
You could press A in beginning of each string.
But if strings are in a specified range of addresses and they're many, it's more efficient to use a script that will detect and mark strings automatically.
All you need is to set up firstAddress and endAddress in a script.
Link to script: http://pastebin.com/jeVjGZNe
  • LINK/2012 and Sweet Bellic like this

mike43842
  • mike43842

    Player Hater

  • Members
  • Joined: 02 Feb 2013
  • None

#4

Posted 09 March 2014 - 11:58 AM Edited by mike43842, 09 March 2014 - 03:40 PM.

Wow! That very interesting, are you have any idb base of vcs_ps2? And I see you executable of lcs with name of many functions, can you say how to restore native function names?

 

P.S. Have you are skype?


fastman92
  • fastman92

    фастман92 | ف

  • Members
  • Joined: 28 Jul 2009
  • None
  • Contribution Award [Mods]

#5

Posted 09 March 2014 - 12:10 PM Edited by fastman92, 09 March 2014 - 12:10 PM.

I have manually analyzed GTA LCS and VCS executable files in IDA Pro in comparison to GTA III, VC, SA for Android.
The thing is GTA III, VC, SA for Android have original mangled names of functions and since I'm not new to reverse engineering, I could find equivalent functions in LCS and VCS.
As you may guess most of the functions have to be the same in LCS and VCS.

Have you done any software reverse engineering?

Btw, don't report my posts.

mike43842
  • mike43842

    Player Hater

  • Members
  • Joined: 02 Feb 2013
  • None

#6

Posted 09 March 2014 - 12:18 PM Edited by mike43842, 09 March 2014 - 12:19 PM.

Unfortunately i'm not good in Reverse Engineering, but I learn MIPS and x86 asm, and try rewrite some functions in C++, I want transfer opcodes from vcs to SA and that why I'm interested in this post. Can you open your PM?


fastman92
  • fastman92

    фастман92 | ف

  • Members
  • Joined: 28 Jul 2009
  • None
  • Contribution Award [Mods]

#7

Posted 09 March 2014 - 12:23 PM Edited by fastman92, 09 March 2014 - 04:42 PM.

Nothing in PM.

Transferring opcodes is not possible in any other way than putting equivalent IDs in GTA SA game.

For example:
VCS:
00D9=2,store_car_char_is_in %1d% store_to %2d%
SA:




00D9=2,store_car_char_is_in %1d% store_to %2d%
You may want to learn ARM too. Once you grasp the concept of conditional execution, it's getting easier.

----------------------------------------
I decided to test opcodes:
0456:  0 
044E:  0 1 
0451:  0 350 60 
0450:  0 5 5 
0452:  0 0 0 0 128 
0453:  0 0 0 0 0 
That's what I got:
c2d7fd313163002.jpg

----------------------------------------
GTA San Andreas.

I NOPPed instruction at 0x527972 (7 bytes), then I assigned a value of 1 to byte on address 0xB6EC20

This is what I've got:
1b2228313186068.jpg

You see me driving and breaking on street of LS.
  • mike43842 likes this

ScatterBox
  • ScatterBox

    Lost in Los Santos

  • Members
  • Joined: 24 Feb 2014
  • United-States

#8

Posted 10 March 2014 - 01:21 AM

Hmm. PS2 only scm? Or are you going to be working on PSP versions as well?


fastman92
  • fastman92

    фастман92 | ف

  • Members
  • Joined: 28 Jul 2009
  • None
  • Contribution Award [Mods]

#9

Posted 10 March 2014 - 04:41 AM Edited by fastman92, 10 March 2014 - 04:43 AM.

Hmm. PS2 only scm? Or are you going to be working on PSP versions as well?


Is there PSP emulator for PC?

LINK/2012
  • LINK/2012

    LIVIN' IN CODE

  • Feroci
  • Joined: 30 Jan 2011
  • Brazil
  • Best Tool 2014 [Mod Loader]
    Contribution Award [Mods]

#10

Posted 10 March 2014 - 04:45 AM

Hmm. PS2 only scm? Or are you going to be working on PSP versions as well?


Is there PSP emulator for PC?

http://www.ppsspp.org/

ScatterBox
  • ScatterBox

    Lost in Los Santos

  • Members
  • Joined: 24 Feb 2014
  • United-States

#11

Posted 10 March 2014 - 11:46 AM

If you need any help PSP version wise I can help. I have a PSP for testing, and I know some C++ and am learning reverse engineering ATM. Although I don't think I could be much help there, I could, at the least, test everything.


fastman92
  • fastman92

    фастман92 | ف

  • Members
  • Joined: 28 Jul 2009
  • None
  • Contribution Award [Mods]

#12

Posted 10 March 2014 - 06:48 PM

Hmm. PS2 only scm? Or are you going to be working on PSP versions as well?

I looked into PSP version of VCS.
I'm not skilled enough to disassemble and reverse engineer it.

ScatterBox
  • ScatterBox

    Lost in Los Santos

  • Members
  • Joined: 24 Feb 2014
  • United-States

#13

Posted 10 March 2014 - 07:30 PM

Ah, well, I couldn't resist asking.. :p

 

Thanks for looking into it though!


fastman92
  • fastman92

    фастман92 | ف

  • Members
  • Joined: 28 Jul 2009
  • None
  • Contribution Award [Mods]

#14

Posted 11 March 2014 - 06:16 PM Edited by fastman92, 11 March 2014 - 07:36 PM.

I found out what

627a42313632464.jpg

05AC and 05AD opcodes in LCS do.

Screenshot tells it.

I named it
SET_DESTINATION_COORDINATES
CLEAR_DESTINATION_COORDINATES
If destination coordinates are set, an arrow will appear on screen pointed to destination coordinates.

It's 0x0378 and 0x0379 in VCS.

----------------------------------------
Part of my testing script for VCS main.txt:
 
:loop
WAIT 0
USE_TEXT_COMMANDS 1

0377: get_pad_state actionID 0 store_to 1@

000F:   1@ > 0 // (int) var > num
0022: goto_if_false @loop

02EE: get_offset_from_char_in_world_coords $PLAYER_ACTOR offset 0.0 3.0 1.0 store_to 2@ 3@ 4@


REQUEST_MODEL 99

:checkIfModelLoaded
WAIT 0
HAS_MODEL_LOADED 99
GOTO_IF_FALSE @checkIfModelLoaded

GET_GROUND_Z_FOR_3D_COORD 2@ 3@ 4@ 4@

003E: create_char 4 model 99 at 2@ 3@ 4@ store_to 5@ 
015D: set_actor 5@ ped_stats_to 32

MARK_MODEL_AS_NO_LONGER_NEEDED 99
MARK_CHAR_AS_NO_LONGER_NEEDED 5@

wait 1000
GOTO @loop
It spawns a soldier that tries to beat me to the death.

0fc36f313641495.jpg

mike43842
  • mike43842

    Player Hater

  • Members
  • Joined: 02 Feb 2013
  • None

#15

Posted 11 March 2014 - 07:33 PM

fastman92, can you show screen, in code of opcode 0378 in VCS, where are get using model arrow? I know this model is in GAME.dtz, but I can't find in .elf where are this model using, I tried find that at this opcode function but I find nothing.

 

P.S. sorry for my broken English.


fastman92
  • fastman92

    фастман92 | ف

  • Members
  • Joined: 28 Jul 2009
  • None
  • Contribution Award [Mods]

#16

Posted 11 March 2014 - 07:40 PM Edited by fastman92, 11 March 2014 - 07:41 PM.

fastman92, can you show screen, in code of opcode 0378 in VCS, where are get using model arrow? I know this model is in GAME.dtz, but I can't find in .elf where are this model using, I tried find that at this opcode function but I find nothing.
 
P.S. sorry for my broken English.

Sorry, I don't know model is this.
I use a command to set the destination coordinates and it just works.

I have found a better R* name to these commands
 
.rodata:004B8190     aSetpointerarrow:.ascii "SetPointerArrow"<0>
.rodata:004B81A0     aClearpointerarrow:.ascii "ClearPointerArrow"<0>

fastman92
  • fastman92

    фастман92 | ف

  • Members
  • Joined: 28 Jul 2009
  • None
  • Contribution Award [Mods]

#17

Posted 16 March 2014 - 03:20 PM

While building my database I noticed this GTA VC opcode:

045F: set_all_occupants_of_car_leave_car 0@ 4
In decompiled main.scm:
045F: set_all_occupants_of_car_leave_car 0@ 4 
00D6: if 
0038:   $6846 == 0 
004D: goto_if_false @FIRETRU_6945 
03C4: display_onscreen_counter_with_string $6847 type 0 gxt 'F_EXTIN'  // FIRES:
0004: $6846 = 1 
More interestingly I knew this opcode has only one parameter in different games.

I checked how the second parameter of this command in VC is used:
      CRunningScript__CollectParameters(this, &this->_ip, 1u);
      v31 = CPool_CVehicle__atHandle(VehiclePool, opcodeParams[0]);
      AllExitVehicle(v31);
      return 0;
But instead, I found that the game collects only one parameter.

http://gtag.gtagamin...se/opcode/045F/

Of course, GTAG tells it has 2 parameters.

I looked into VC's main.scm and located where the 045F opcode is and what comes the next.

5F 04 03 00 00 04 04 D6 00 04 00
5F 04 - 044F: opcode
03 - local variable, value 00 00 what means 0@

Then the next command is executed:
04 04
0x0404

http://gtag.gtagamin...se/opcode/0404/

which is REGISTER_FIRE_EXTINGUISHED.

I made appropriate changes to my database, generated new INI for Sanny Builder and decompiled VC's main.scm again.
045F: set_all_occupants_of_car_leave_car 0@ 
0404: register_fire_extinguished 
00D6: if 
0038:   $6846 == 0 
004D: goto_if_false @FIRETRU_6945 
03C4: display_onscreen_counter_with_string $6847 type 0 gxt 'F_EXTIN'  // FIRES:
Now the SB's output is much better.

Jeansowaty
  • Jeansowaty

    Have no fear, Olek is here! Mwahahaha...

  • Members
  • Joined: 31 Mar 2013
  • Poland

#18

Posted 20 March 2014 - 05:37 PM

I'll have to say, congratz. It is not often that someone finds a way to mod LCS/VCS!

  • iFres0x and Vice City criminal like this

fastman92
  • fastman92

    фастман92 | ف

  • Members
  • Joined: 28 Jul 2009
  • None
  • Contribution Award [Mods]

#19

Posted 29 March 2014 - 08:37 AM Edited by fastman92, 29 March 2014 - 08:43 AM.

I discovered why Streaming memory fix 2.0 by Alexander Blade is bound to crash the game after ~10 minutes of playing.

Default limit of streamed vehicles is 22. Alexander Blade's plugin increases it.
Default limit of number of members per car group (cargrp.dat stuff) is 23.

The limit of streamed vehicles has to be lower than a limit of number of members per loaded car group.
Otherwise the game will always find there are 23 vehicles loaded and since it's lower or equal to limit of streamed vehicles, it will load them infinitely not freeing a memory.
The game has allocation limit specified by a number of elements.
  • DK22Pac and Silent like this

fastman92
  • fastman92

    фастман92 | ف

  • Members
  • Joined: 28 Jul 2009
  • None
  • Contribution Award [Mods]

#20

Posted 05 April 2014 - 07:49 PM Edited by fastman92, 06 April 2014 - 08:26 AM.

How to rename a list of functions from old names to new names?

Sometimes there comes a time when in IDA Pro we need to rename quite a lot functions and we also have a list of new names that should be assigned.

IDC scripting comes in handy.
I wrote a script to assign new names to functions by first locating them with old names.

http://pastebin.com/kkWqJwKs

You need to define an old name and a new name as follows:



	list.AddMember("_sub_550170", "png_set_unknown_chunks");
	list.AddMember("$CPool_CPtrNodeSingle__constructor", "png_set_unknown_chunk_location");
How to get values from li $at, float in MIPS executable?

While disassembling a MIPS executable I noticed that a part of float values would appear as integer value instead.

f806b9319154770.jpg

Since it's impossible to turn these integer values into float values in IDA Pro, I wrote a Python script that puts a comment that tells a float value used in the instruction.

6fe9b9319155172.jpg
As shown on the screenshot, comment with a value was inserted.

This script will not override existing user comments.

Link to script: http://pastebin.com/GEk306DW
  • DK22Pac, Jeansowaty, Marių and 1 other like this




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users