Stuck with ARM 64 Code

maceyp

New User
Mar 25, 2020
9
Hi guys,

I appreciate any help given. I've been playing a Racing Manager game where you get different cards that add stats Power; Aero; Grip; Aerodynamics. At first I was looking at ScaleAndSum to see if i could identify there stat weights on which is most important. Like how much does 1 power affect your car, 1 grip etc But i've given up on that even though i found where its at. I will post it anyway as you're all more knowledgeable than me. My old brain just doesn't want to work :D. Thanks to @iAlex whos tutorials have helped me so far I was even able to increase my attack damage in a basic game and was so proud of myself 🤣

Now to what im trying is I've found the Module it calls from however lets say i just wanted to set them all to 100 what would I need to change. I'm in IDA and can see the ADD and also a Branch it loads (most likely the item?) So what would I need to do here.

Code:
.text:0000000000A548D0 F1Simulation.CarStats$$Power            ; DATA XREF: .data.rel.ro:0000000002700218↓o
.text:0000000000A548D0 ; __unwind {
.text:0000000000A548D0                 ADD             X0, X0, #0x10
.text:0000000000A548D4                 B               sub_1B73D68
.text:0000000000A548D4 ; } // starts at A548D0
.text:0000000000A548D4 ; End of function F1Simulation.CarStats$$Power
Now Aero, Grip all do the exact same however they just call a different Branch sub_xxxxx

Also if anyone wants to have a go at working the math for stat weights here is code for this.
Code:
il2cpp:0000000001B73EB8 F1Simulation.CarStats$$ScaleAndSum_0    ; CODE XREF: F1Simulation.CarStats$$ScaleAndSum↑j
il2cpp:0000000001B73EB8                                         ; sub_1B73D68+14C↑j ...
il2cpp:0000000001B73EB8 ; __unwind {
il2cpp:0000000001B73EB8                 STR             D8, [SP,#-0x10+var_40]!
il2cpp:0000000001B73EBC                 STP             X24, X23, [SP,#0x40+var_30]
il2cpp:0000000001B73EC0                 STP             X22, X21, [SP,#0x40+var_20]
il2cpp:0000000001B73EC4                 STP             X20, X19, [SP,#0x40+var_10]
il2cpp:0000000001B73EC8                 STP             X29, X30, [SP,#0x40+var_s0]
il2cpp:0000000001B73ECC                 ADD             X29, SP, #0x40
il2cpp:0000000001B73ED0                 ADRP            X20, #byte_2987AC5@PAGE
il2cpp:0000000001B73ED4                 LDRB            W8, [X20,#byte_2987AC5@PAGEOFF]
il2cpp:0000000001B73ED8                 MOV             X19, X1
il2cpp:0000000001B73EDC                 MOV             V8.16B, V0.16B
il2cpp:0000000001B73EE0                 TBNZ            W8, #0, loc_1B73EFC
il2cpp:0000000001B73EE4                 ADRP            X8, #off_27E9990@PAGE
il2cpp:0000000001B73EE8                 LDR             X8, [X8,#off_27E9990@PAGEOFF]
il2cpp:0000000001B73EEC                 LDR             W0, [X8]
il2cpp:0000000001B73EF0                 BL              sub_8DA114
il2cpp:0000000001B73EF4                 MOV             W8, #1
il2cpp:0000000001B73EF8                 STRB            W8, [X20,#byte_2987AC5@PAGEOFF]
il2cpp:0000000001B73EFC
il2cpp:0000000001B73EFC loc_1B73EFC                             ; CODE XREF: sub_1B73D68+178↑j
il2cpp:0000000001B73EFC                 CBNZ            X19, loc_1B73F08
il2cpp:0000000001B73F00                 MOV             X0, XZR
il2cpp:0000000001B73F04                 BL              sub_9044CC
il2cpp:0000000001B73F08 ; ---------------------------------------------------------------------------
il2cpp:0000000001B73F08
il2cpp:0000000001B73F08 loc_1B73F08                             ; CODE XREF: sub_1B73D68:loc_1B73EFC↑j
il2cpp:0000000001B73F08                 LDR             X8, [X19,#0x18]
il2cpp:0000000001B73F0C                 CBNZ            W8, loc_1B73F24
il2cpp:0000000001B73F10                 BL              sub_9052A4
il2cpp:0000000001B73F14                 MOV             X1, XZR
il2cpp:0000000001B73F18                 MOV             X2, XZR
il2cpp:0000000001B73F1C                 BL              sub_90443C
il2cpp:0000000001B73F20 ; ---------------------------------------------------------------------------
il2cpp:0000000001B73F20                 LDR             X8, [X19,#0x18]
il2cpp:0000000001B73F24
il2cpp:0000000001B73F24 loc_1B73F24                             ; CODE XREF: sub_1B73D68+1A4↑j
il2cpp:0000000001B73F24                 LDR             W20, [X19,#0x20]
il2cpp:0000000001B73F28                 CMP             W8, #1
il2cpp:0000000001B73F2C                 B.HI            loc_1B73F44
il2cpp:0000000001B73F30                 BL              sub_9052A4
il2cpp:0000000001B73F34                 MOV             X1, XZR
il2cpp:0000000001B73F38                 MOV             X2, XZR
il2cpp:0000000001B73F3C                 BL              sub_90443C
il2cpp:0000000001B73F40 ; ---------------------------------------------------------------------------
il2cpp:0000000001B73F40                 LDR             X8, [X19,#0x18]
il2cpp:0000000001B73F44
il2cpp:0000000001B73F44 loc_1B73F44                             ; CODE XREF: sub_1B73D68+1C4↑j
il2cpp:0000000001B73F44                 LDR             W21, [X19,#0x24]
il2cpp:0000000001B73F48                 CMP             W8, #2
il2cpp:0000000001B73F4C                 B.HI            loc_1B73F64
il2cpp:0000000001B73F50                 BL              sub_9052A4
il2cpp:0000000001B73F54                 MOV             X1, XZR
il2cpp:0000000001B73F58                 MOV             X2, XZR
il2cpp:0000000001B73F5C                 BL              sub_90443C
il2cpp:0000000001B73F60 ; ---------------------------------------------------------------------------
il2cpp:0000000001B73F60                 LDR             X8, [X19,#0x18]
il2cpp:0000000001B73F64
il2cpp:0000000001B73F64 loc_1B73F64                             ; CODE XREF: sub_1B73D68+1E4↑j
il2cpp:0000000001B73F64                 LDR             W22, [X19,#0x28]
il2cpp:0000000001B73F68                 CMP             W8, #3
il2cpp:0000000001B73F6C                 B.HI            loc_1B73F84
il2cpp:0000000001B73F70                 BL              sub_9052A4
il2cpp:0000000001B73F74                 MOV             X1, XZR
il2cpp:0000000001B73F78                 MOV             X2, XZR
il2cpp:0000000001B73F7C                 BL              sub_90443C
il2cpp:0000000001B73F80 ; ---------------------------------------------------------------------------
il2cpp:0000000001B73F80                 LDR             X8, [X19,#0x18]
il2cpp:0000000001B73F84
il2cpp:0000000001B73F84 loc_1B73F84                             ; CODE XREF: sub_1B73D68+204↑j
il2cpp:0000000001B73F84                 LDR             W23, [X19,#0x2C]
il2cpp:0000000001B73F88                 CMP             W8, #4
il2cpp:0000000001B73F8C                 B.HI            loc_1B73FA4
il2cpp:0000000001B73F90                 BL              sub_9052A4
il2cpp:0000000001B73F94                 MOV             X1, XZR
il2cpp:0000000001B73F98                 MOV             X2, XZR
il2cpp:0000000001B73F9C                 BL              sub_90443C
il2cpp:0000000001B73FA0 ; ---------------------------------------------------------------------------
il2cpp:0000000001B73FA0                 LDR             X8, [X19,#0x18]
il2cpp:0000000001B73FA4
il2cpp:0000000001B73FA4 loc_1B73FA4                             ; CODE XREF: sub_1B73D68+224↑j
il2cpp:0000000001B73FA4                 LDR             W24, [X19,#0x30]
il2cpp:0000000001B73FA8                 CMP             W8, #5
il2cpp:0000000001B73FAC                 B.HI            loc_1B73FC0
il2cpp:0000000001B73FB0                 BL              sub_9052A4
il2cpp:0000000001B73FB4                 MOV             X1, XZR
il2cpp:0000000001B73FB8                 MOV             X2, XZR
il2cpp:0000000001B73FBC                 BL              sub_90443C
il2cpp:0000000001B73FC0 ; ---------------------------------------------------------------------------
il2cpp:0000000001B73FC0
il2cpp:0000000001B73FC0 loc_1B73FC0                             ; CODE XREF: sub_1B73D68+244↑j
il2cpp:0000000001B73FC0                 ADRP            X8, #off_27F37D0@PAGE
il2cpp:0000000001B73FC4                 LDR             X8, [X8,#off_27F37D0@PAGEOFF]
il2cpp:0000000001B73FC8                 LDR             W19, [X19,#0x34]
il2cpp:0000000001B73FCC                 LDR             X0, [X8] ; Class$System.Math
il2cpp:0000000001B73FD0                 LDRB            W8, [X0,#0x127]
il2cpp:0000000001B73FD4                 TBZ             W8, #1, loc_1B73FE4
il2cpp:0000000001B73FD8                 LDR             W8, [X0,#0xD8]
il2cpp:0000000001B73FDC                 CBNZ            W8, loc_1B73FE4
il2cpp:0000000001B73FE0                 BL              il2cpp_runtime_class_init_0
il2cpp:0000000001B73FE4 ; ---------------------------------------------------------------------------
il2cpp:0000000001B73FE4
il2cpp:0000000001B73FE4 loc_1B73FE4                             ; CODE XREF: sub_1B73D68+26C↑j
il2cpp:0000000001B73FE4                                         ; sub_1B73D68+274↑j
il2cpp:0000000001B73FE4                 ADRP            X8, #dword_1D6DF98@PAGE
il2cpp:0000000001B73FE8                 LDR             S3, [X8,#dword_1D6DF98@PAGEOFF]
il2cpp:0000000001B73FEC                 SCVTF           S0, W20
il2cpp:0000000001B73FF0                 SCVTF           S1, W21
il2cpp:0000000001B73FF4                 SCVTF           S2, W22
il2cpp:0000000001B73FF8                 FMUL            S0, S0, S3
il2cpp:0000000001B73FFC                 FMUL            S1, S1, S3
il2cpp:0000000001B74000                 SCVTF           S4, W23
il2cpp:0000000001B74004                 FMUL            S2, S2, S3
il2cpp:0000000001B74008                 FMUL            S0, S0, S8
il2cpp:0000000001B7400C                 FMUL            S1, S1, S8
il2cpp:0000000001B74010                 SCVTF           S5, W24
il2cpp:0000000001B74014                 FMUL            S4, S4, S3
il2cpp:0000000001B74018                 FADD            S0, S0, S1
il2cpp:0000000001B7401C                 FMUL            S1, S2, S8
il2cpp:0000000001B74020                 SCVTF           S6, W19
il2cpp:0000000001B74024                 FMUL            S5, S5, S3
il2cpp:0000000001B74028                 FADD            S0, S0, S1
il2cpp:0000000001B7402C                 FMUL            S1, S4, S8
il2cpp:0000000001B74030                 FMUL            S3, S6, S3
il2cpp:0000000001B74034                 FADD            S0, S0, S1
il2cpp:0000000001B74038                 FMUL            S1, S5, S8
il2cpp:0000000001B7403C                 FADD            S0, S0, S1
il2cpp:0000000001B74040                 FMUL            S1, S3, S8
il2cpp:0000000001B74044                 FADD            S0, S0, S1
il2cpp:0000000001B74048                 FMOV            S1, #1.0
il2cpp:0000000001B7404C                 MOV             X0, XZR
il2cpp:0000000001B74050                 BL              System.Math$$Min_12242500
il2cpp:0000000001B74054                 LDP             X29, X30, [SP,#0x40+var_s0]
il2cpp:0000000001B74058                 LDP             X20, X19, [SP,#0x40+var_10]
il2cpp:0000000001B7405C                 LDP             X22, X21, [SP,#0x40+var_20]
il2cpp:0000000001B74060                 LDP             X24, X23, [SP,#0x40+var_30]
il2cpp:0000000001B74064                 FMOV            S1, WZR
il2cpp:0000000001B74068                 MOV             X0, XZR
il2cpp:0000000001B7406C                 LDR             D8, [SP+0x40+var_40],#0x50
il2cpp:0000000001B74070                 B               System.Math$$Max_12242252
il2cpp:0000000001B74070 ; } // starts at 1B73EB8
il2cpp:0000000001B74070 ; End of function sub_1B73D68

Thank you all for any help.
 

Delshire

STMFD/LDMFD
Staff member
Junior Modding Team
Nov 7, 2018
248
That
Code:
ADD             X0, X0, #0x10
is just loading what's on the (instance object + 0x10) into X0, go to the dump.cs and in the
F1Simulation.CarStats class find what's the member at 0x10, from there you can figure out what's happening, seems like its just loading that to X0 and passing it as a parameter for the branch (and the return value of that branch is probably stored in x0 also) , also, most likely, just a getter for the "Power".
 

maceyp

New User
Mar 25, 2020
9
That
Code:
ADD             X0, X0, #0x10
is just loading what's on the (instance object + 0x10) into X0, go to the dump.cs and in the
F1Simulation.CarStats class find what's the member at 0x10, from there you can figure out what's happening, seems like its just loading that to X0 and passing it as a parameter for the branch (and the return value of that branch is probably stored in x0 also) , also, most likely, just a getter for the "Power".
Ok this makes sense and I'll look into it, I did notice somewhere else when searching for power in dnspy loading the offset into IDA that had a lot more code. Will log on to PC and look at the dump.cs

UPDATE:

This is what i found under F1Simulation.CarStats.


Code:
// Namespace: F1Simulation
public struct CarStats // TypeDefIndex: 5743
{
    // Fields
    public const string kMinDriverGUID = "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee"; // 0x0
    public const string kMaxDriverGUID = "ffffffff-ffff-ffff-ffff-ffffffffffff"; // 0x0
    public DriverStats m_driver1; // 0x0
    public DriverStats m_driver2; // 0x18
    public ComponentStats m_frontWing; // 0x30
    public ComponentStats m_rearWing; // 0x44
    public ComponentStats m_suspension; // 0x58
    public ComponentStats m_engine; // 0x6C
    public ComponentStats m_gearbox; // 0x80
    public ComponentStats m_brakes; // 0x94

    // Methods
    // RVA: 0xA54890 Offset: 0xA54890 VA: 0xA54890
    public void ApplyDriversModifier(float modifier) { }
    // RVA: 0xA548C8 Offset: 0xA548C8 VA: 0xA548C8
    public void ApplyComponentsModifier(float modifier) { }
    // RVA: 0xA548D0 Offset: 0xA548D0 VA: 0xA548D0
    public float Power(float scale) { }
    // RVA: 0xA548D8 Offset: 0xA548D8 VA: 0xA548D8
    public float Aero(float scale) { }
    // RVA: 0xA548E0 Offset: 0xA548E0 VA: 0xA548E0
    public float Grip(float scale) { }
    // RVA: 0xA548E8 Offset: 0xA548E8 VA: 0xA548E8
    public float PitStopTime() { }
    // RVA: 0xA54918 Offset: 0xA54918 VA: 0xA54918
    private float ScaleAndSum(float scale, int[] values) { }
    // RVA: 0xA5491C Offset: 0xA5491C VA: 0xA5491C
    public float TotalReliability() { }
    // RVA: 0xA5495C Offset: 0xA5495C VA: 0xA5495C
    public float ReliabilityScore() { }
    // RVA: 0x1B74424 Offset: 0x1B74424 VA: 0x1B74424
    public static int ModifyStat(int stat, float modifier) { }
    // RVA: 0x1B74524 Offset: 0x1B74524 VA: 0x1B74524
    public static CarStats MinLoadout() { }
    // RVA: 0x1B74568 Offset: 0x1B74568 VA: 0x1B74568
    public static CarStats MaxLoadout() { }
    // RVA: 0xA54964 Offset: 0xA54964 VA: 0xA54964
    public int GetPowerLevel() { }
    // RVA: 0xA549B8 Offset: 0xA549B8 VA: 0xA549B8
    public int GetCarPowerLevel() { }
    // RVA: 0xA549E8 Offset: 0xA549E8 VA: 0xA549E8
    public int GetCarAeroLevel() { }
    // RVA: 0xA54A18 Offset: 0xA54A18 VA: 0xA54A18
    public int GetCarGripLevel() { }
    // RVA: 0xA54A48 Offset: 0xA54A48 VA: 0xA54A48
    public int GetCarReliabilityLevel() { }
    // RVA: 0xA54A78 Offset: 0xA54A78 VA: 0xA54A78
    public int GetDriversPowerLevel() { }
    // RVA: 0xA54A80 Offset: 0xA54A80 VA: 0xA54A80
    public int GetDriver1PowerLevel() { }
    // RVA: 0xA54AA4 Offset: 0xA54AA4 VA: 0xA54AA4
    public int GetDriver2PowerLevel() { }
    // RVA: 0xA54AC8 Offset: 0xA54AC8 VA: 0xA54AC8
    public float GetNormalizedQualifyingStrength(int driverIndex) { }
}
 
Last edited:

Delshire

STMFD/LDMFD
Staff member
Junior Modding Team
Nov 7, 2018
248
Ok this makes sense and I'll look into it, I did notice somewhere else when searching for power in dnspy loading the offset into IDA that had a lot more code. Will log on to PC and look at the dump.cs

UPDATE:

This is what i found under F1Simulation.CarStats.


Code:
// Namespace: F1Simulation
public struct CarStats // TypeDefIndex: 5743
{
    // Fields
    public const string kMinDriverGUID = "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee"; // 0x0
    public const string kMaxDriverGUID = "ffffffff-ffff-ffff-ffff-ffffffffffff"; // 0x0
    public DriverStats m_driver1; // 0x0
    public DriverStats m_driver2; // 0x18
    public ComponentStats m_frontWing; // 0x30
    public ComponentStats m_rearWing; // 0x44
    public ComponentStats m_suspension; // 0x58
    public ComponentStats m_engine; // 0x6C
    public ComponentStats m_gearbox; // 0x80
    public ComponentStats m_brakes; // 0x94

    // Methods
    // RVA: 0xA54890 Offset: 0xA54890 VA: 0xA54890
    public void ApplyDriversModifier(float modifier) { }
    // RVA: 0xA548C8 Offset: 0xA548C8 VA: 0xA548C8
    public void ApplyComponentsModifier(float modifier) { }
    // RVA: 0xA548D0 Offset: 0xA548D0 VA: 0xA548D0
    public float Power(float scale) { }
    // RVA: 0xA548D8 Offset: 0xA548D8 VA: 0xA548D8
    public float Aero(float scale) { }
    // RVA: 0xA548E0 Offset: 0xA548E0 VA: 0xA548E0
    public float Grip(float scale) { }
    // RVA: 0xA548E8 Offset: 0xA548E8 VA: 0xA548E8
    public float PitStopTime() { }
    // RVA: 0xA54918 Offset: 0xA54918 VA: 0xA54918
    private float ScaleAndSum(float scale, int[] values) { }
    // RVA: 0xA5491C Offset: 0xA5491C VA: 0xA5491C
    public float TotalReliability() { }
    // RVA: 0xA5495C Offset: 0xA5495C VA: 0xA5495C
    public float ReliabilityScore() { }
    // RVA: 0x1B74424 Offset: 0x1B74424 VA: 0x1B74424
    public static int ModifyStat(int stat, float modifier) { }
    // RVA: 0x1B74524 Offset: 0x1B74524 VA: 0x1B74524
    public static CarStats MinLoadout() { }
    // RVA: 0x1B74568 Offset: 0x1B74568 VA: 0x1B74568
    public static CarStats MaxLoadout() { }
    // RVA: 0xA54964 Offset: 0xA54964 VA: 0xA54964
    public int GetPowerLevel() { }
    // RVA: 0xA549B8 Offset: 0xA549B8 VA: 0xA549B8
    public int GetCarPowerLevel() { }
    // RVA: 0xA549E8 Offset: 0xA549E8 VA: 0xA549E8
    public int GetCarAeroLevel() { }
    // RVA: 0xA54A18 Offset: 0xA54A18 VA: 0xA54A18
    public int GetCarGripLevel() { }
    // RVA: 0xA54A48 Offset: 0xA54A48 VA: 0xA54A48
    public int GetCarReliabilityLevel() { }
    // RVA: 0xA54A78 Offset: 0xA54A78 VA: 0xA54A78
    public int GetDriversPowerLevel() { }
    // RVA: 0xA54A80 Offset: 0xA54A80 VA: 0xA54A80
    public int GetDriver1PowerLevel() { }
    // RVA: 0xA54AA4 Offset: 0xA54AA4 VA: 0xA54AA4
    public int GetDriver2PowerLevel() { }
    // RVA: 0xA54AC8 Offset: 0xA54AC8 VA: 0xA54AC8
    public float GetNormalizedQualifyingStrength(int driverIndex) { }
}
ok then from the function definition then what i said earlier is most likely wrong, seems like its just setting the scale parameter on X0 (which makes sense since Xn hold flotating points in arm64, and just using it in the branch as a parameter, you should see what
Code:
B               sub_1B73D68
is calling, in the dump.cs look for 1B73D68, its probably some function that takes a scale parameter.
 

maceyp

New User
Mar 25, 2020
9
ok then from the function definition then what i said earlier is most likely wrong, seems like its just setting the scale parameter on X0 (which makes sense since Xn hold flotating points in arm64, and just using it in the branch as a parameter, you should see what
Code:
B               sub_1B73D68
is calling, in the dump.cs look for 1B73D68, its probably some function that takes a scale parameter.
Without looking that up I do know when looking at the same bit in DNSPY it did say something along the lines of float (scale).

Now there was a bit somewhere it mentions
power = 1f
Aero = 1f and so on.

I guess I'd be more on the line of things looking there?

I really appreciate your help btw, still I'm the learning phase and trying to read up what I can.
 

Delshire

STMFD/LDMFD
Staff member
Junior Modding Team
Nov 7, 2018
248
It's hard to follow from what you've been writing only but first of all you should try to identify how are you going to reference your car only, the class is called CarStats which seems it would be shared for all cars including yours. When you isolate your car then you can just mess with the getters (
GetPowerLevel, GetGripLevel, etc) and just return whatever value you want in those fields, again, this is all in the air since i haven't looked into the game.
 

maceyp

New User
Mar 25, 2020
9
It's hard to follow from what you've been writing only but first of all you should try to identify how are you going to reference your car only, the class is called CarStats which seems it would be shared for all cars including yours. When you isolate your car then you can just mess with the getters (
GetPowerLevel, GetGripLevel, etc) and just return whatever value you want in those fields, again, this is all in the air since i haven't looked into the game.
The reason I thought it was from CarStats is it did seem to be my own. Because on the ServerCarManager, GameRules, and anything related to the game / match uses that CarStats dependencies. However, I'm at work at the moment. so when I get home I will look properly to make sure it is isolated to me. And go from there.

Really do appreciate your help / assistance.
 

maceyp

New User
Mar 25, 2020
9
It's hard to follow from what you've been writing only but first of all you should try to identify how are you going to reference your car only, the class is called CarStats which seems it would be shared for all cars including yours. When you isolate your car then you can just mess with the getters (
GetPowerLevel, GetGripLevel, etc) and just return whatever value you want in those fields, again, this is all in the air since i haven't looked into the game.
Oh, How have i been so dumb..

I just looked at the GetPowerLevel, GetGripLevel etc. Can i can see that LDR is loading different values. 6 in total. Which makes up my car parts i select. (Brakes, Suspension, Front Wing, Rear Wing, Engine, Gearbox) 6 Components.

Then what it seems to be doing is just Adding each Component into W8 before returning that to W0.



If I Replaced ADD W8, W8, W12 with ADD W8, W8, #100 obviously converting it to Hex. So instead of adding W12 argument it would add 100?

Hopefully I'm on the right lines here.

EDIT:

It didn't work so I've gone back to the drawing board where i found CarComponent and CarLoadout where CarLoadout calls on CarComponent here Looks like its related to my Client.
 
Last edited:

maceyp

New User
Mar 25, 2020
9
I managed to get further in. Changing how many cards are required to upgrade no matter the level. O changed this to 1. However it must have some sort of server verification it seems. Don't suppose anyone knows any workaround.

Screenshot_20200328-132608.png
Screenshot_20200328-132556.png