Jump to content

chateau

Members
  • Posts

    7
  • Joined

  • Last visited

Recent Profile Visitors

1,008 profile views

chateau's Achievements

Rookie

Rookie (2/14)

  • Week One Done
  • First Post Rare
  • Conversation Starter Rare

Recent Badges

2

Reputation

  1. Going to public double get_hp() offset address contains the following instructions: "LDR" then "RET", not "PUSH". Do I have to look for another offset address? Also, I don't think PUSH is common for ARM64, but I may be wrong. I do see a lot of STP (store pair) and LDP (load pair) when scrolling through memory, but not PUSH instruction. I'm not sure how to navigate to the 'start of the function' like you've mentioned, it would be nice if you can tell me what I should look for when inspecting the dump that contains many offset addresses, which is something like: // [Address(RVA = "0x1CC4FD4", Offset = "0x1CC4FD4", VA = "0x1CC4FD4")] // [Attribute(Name = "IteratorStateMachineAttribute", RVA = "0xF3BC10", Offset = "0xF3BC10")] // [Attribute(Name = "ObserverDelegateAttribute", RVA = "0xF3BC10", Offset = "0xF3BC10")] public IEnumerator HPChanged(double newHP, long order) // [Address(RVA = "0x1D4A118", Offset = "0x1D4A118", VA = "0x1D4A118")] public void ApplyAllHPChange(double, [Optional] List<>, [Optional] EnemySkill, [Optional] BattleEnemy) // [Token(Token = "0x5040822")] // [Address(RVA = "0x1F57230", Offset = "0x1F57230", VA = "0x1F57230")] public void SetHP(double newMaxHP, double newCurrentHP, bool immediate) // [Token(Token = "0x504061F")] // [Address(RVA = "0x1EBCBFC", Offset = "0x1EBCBFC", VA = "0x1EBCBFC")] public void SetAllHP(double newHP) I agree, when looking for offset addresses I found "CheatViolation" public enum which contains many enum constant values like Damage, EnemyHealthChange etc... I'll come to this later, most important part is that I understand how to patch memory at runtime. I want to be able to have control over health, just to learn about memory patching. The process is more important than the outcome.
  2. My understanding is that I have to use: branch instruction (jump instruction) to control the execution flow and jump to an unused section of memory. code cave (find unused section of memory) to inject additional instructions I have a feeling that this is going to be related to "allocate memory page" on GameGuardian. I've never used GameGuardian before this. I'm curious as to why this was never mentioned before.
  3. Wouldn't that crash the game as you're overwriting instructions you shouldn't? For example, I know the offset address from below (1D4CD45) public double currentHP { get // Offset = "0x1D4CD45" { return default(double); } set { } } Using "offset calculator" I go to the address (base addr + offset addr). Then, I see the following instructions and you're telling me I should just overwrite them all to the following instructions you gave me? (which will give us 0x1234567891234567, but the value here is not important, I'm trying to understand the process). LDR D0, [X0, #0x28]; -- Edit this instruction to: MOVZ X0, #0x4567 RET; -- Edit this instruction to: MOVK X0, #0x9123, LSL #16 STR X19, [SP, #-0x20]!; -- Edit this instruction to: MOVK X0, #0x5678, LSL #32 STP X29, X30, [SP, #0x10]; -- Edit this instruction to: MOVK X0, #0x1234, LSL #48 I can confirm that if I only edit the first line ^ from above to: FMOV D0, #0x3FC0000000 My health will decrease to 0, but I will have godmode (will not be able to die).
  4. How do I apply those multiple lines of instructions using GameGuardian? Do I just overwrite existing instructions?
  5. Hey @MC189, thanks for sharing your insights and making it clear to understand. I'm skimming through the ARM docs, so we use FMOV because we're dealing with double-precision floating-point and D0 is used to store a double-precision value? Thanks for making that clear, the game I'm currently working with is mostly client-sided where (I think) there is no network communication during a battle where I receive damage that changes my health. I totally agree, there is like 50~ health related methods and fields when I search through the il2cpp dump using dnSpy and a lot of duplicate names. Which I'm guessing that means doing a lot of trial and error. I'm not sure if this is relevant in my case. Can you elaborate on this? I think 40590000 hex corresponds to 100 double. How can I write two lines of instruction? Do I just overwrite the instruction below it, which is a RET? On godbolt, when I change the return value to 32 or above "double t() { return 32.0; }" It outputs multiple lines of instructions: .LCPI0_0: .xword 0x4040000000000000 // double 32 t(): // @t() adrp x8, .LCPI0_0 ldr d0, [x8, :lo12:.LCPI0_0] ret How am I suppose to apply this in GameGuardian? Before I read your post I actually tried to modify other health related methods, like get_currentHP(). I've applied arbitrary instructions (where it mostly failed to recognize ARM64 opcode, but a suggestion was made by GameGuardian), after applying the suggestion (shown below), my health was constantly 0, although I was never able to die: FMOV D0, #0x3FC0000000
  6. In the il2cpp dump there is actually two get_hp() method, one under EnemyState class and the other PlayerState class. I've used the get_hp() offset that is under PlayerState class. Can you elaborate? What do you mean by "do some logic in a function to trigger the edit"? There is only 1 player and 1 enemy.
  7. Hi there, I am trying to manipulate memory value (related to health) at runtime based on an identified offset address. I can currently access the memory address that holds the health value by manually searching the exact health value of double type, but this address changes when I close and open the application. I would eventually like to persistently modify the health value after closing and opening the application, without having to manually search for the address. I am unsure what to do next in order to modify the health value using libil2cpp offsets. These are the following steps I've done so far: Used a rooted 64-bit Android emulator (Nox Player) with arm64-v8a instruction set. Retrieved the latest .apk file directly from the Android emulator's root /data directory using "adb pull". Dumped the "libil2cpp.so" file from the game's .apk using il2cppdumper. Used the dumped output from above to identify interesting function names "public double get_hp()" that contains offset addresses such as "Offset: 0x18D0258". On GameGuardian I've used "goto", then selected "Xa" and chose "libil2cpp.so". On GameGuardian I've used "Offset calculator" where the base address is from above and the offset is "18D0258" from step 4. I am presented with a couple of interesting ARM64 instructions: LDR D0, [X0, #0x28]; RET; My understanding is that X0 (general-purpose register, like a variable) holds a memory address and 0x28 offset is added to the X0 register and the result of X0 + 0x28 becomes the accessed memory address, where the value inside it is loaded into the D0 register. Knowing that this is related to public double get_hp() what minimal changes do I need to make so that I can return a specific value to change the health or make it so that the health does not change at all? Thanks!
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.