Toggle menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Code Injection: Difference between revisions

From BDSPedia
No edit summary
No edit summary
Line 3: Line 3:
This documentation makes a few assumptions:
This documentation makes a few assumptions:


- You are using Ghidra
* You are using Ghidra
- You are basing your code on the [[BDSP_Rombase|Rombase]]
* You are basing your code on the [[BDSP_Rombase|Rombase]]


==Mapping Types==
==Mapping Types==
Line 14: Line 14:


<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
    namespace Dpr::Battle::Logic {
namespace Dpr::Battle::Logic {
        struct MyStatus {
    struct MyStatus {
   
    };
        };
}
    }
</syntaxhighlight>
</syntaxhighlight>


Line 27: Line 26:
There's two situations here; Either it has a `klass` and `monitor` field, or it only has `fields`. In the former case, we call it an ILClass, otherwise we call it an ILStruct. In this case, that means it's an ILClass.
There's two situations here; Either it has a `klass` and `monitor` field, or it only has `fields`. In the former case, we call it an ILClass, otherwise we call it an ILStruct. In this case, that means it's an ILClass.
<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
    namespace Dpr::Battle::Logic {
namespace Dpr::Battle::Logic {
        // If ILClass:  `struct T : ILClass<T>`  
    // If ILClass:  `struct T : ILClass<T>`  
        // If ILStruct: `struct T : ILStruct<T>`
    // If ILStruct: `struct T : ILStruct<T>`
        struct MyStatus : ILClass<MyStatus> {   
    struct MyStatus : ILClass<MyStatus> {   
        };
    };
    }
}
</syntaxhighlight>
</syntaxhighlight>


Line 40: Line 39:


<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
    namespace Dpr::Battle::Logic {
namespace Dpr::Battle::Logic {
        struct MyStatus : ILClass<MyStatus> {
    struct MyStatus : ILClass<MyStatus> {
            // All fields go in a nested Fields struct. If it has no fields, don't add it.
        // All fields go in a nested Fields struct. If it has no fields, don't add it.
            // If your type has a supertype (for example, UnityEngine_Behaviour_fields has a field called super of type UnityEngine_Component_fields),
        // If your type has a supertype (for example, UnityEngine_Behaviour_fields has a field called super of type UnityEngine_Component_fields),
            //  You would copy that here (i.e. `struct Fields : UnityEngine::Component::Fields {`)
        //  You would copy that here (i.e. `struct Fields : UnityEngine::Component::Fields {`)
            struct Fields {
        struct Fields {
                // Fill in all elements from the image, creating their types if needed.
            // Fill in all elements from the image, creating their types if needed.
                // You need to remap e.g. System_String_o* to System::String::Object*
            // You need to remap e.g. System_String_o* to System::String::Object*
                // or UnityEngine_GameObject_array to UnityEngine::GameObject::Array
            // or UnityEngine_GameObject_array to UnityEngine::GameObject::Array
                System::String::Object* name;
            System::String::Object* name;
                bool sex;
            bool sex;
                int32_t lang;
            int32_t lang;
                uint32_t id;
            uint32_t id;
                uint8_t fashion;
            uint8_t fashion;
                uint8_t body_type;
            uint8_t body_type;
                uint8_t hat;
            uint8_t hat;
                uint8_t shoes;
            uint8_t shoes;
            };
        };
        };
    };
    }
}
</syntaxhighlight>
</syntaxhighlight>

Revision as of 07:59, 11 February 2024

This page or section contains undocumented information.
Please ensure all of the info is complete!


This documentation makes a few assumptions:

  • You are using Ghidra
  • You are basing your code on the Rombase

Mapping Types

To use the game's types in our code, we first need to map them. For this example, we'll be mapping the type Dpr_Battle_Logic_MyStatus_o.

Knowing we're looking at Dpr_Battle_Logic_MyStatus, this means the class is at `Dpr::Battle::Logic::MyStatus`, so we create the file externals/Dpr/Battle/Logic/MyStatus.h.

 namespace Dpr::Battle::Logic {
     struct MyStatus {
     };
 }

First, we open it in Ghidra's type browser, and we're greeted with this:

There's two situations here; Either it has a `klass` and `monitor` field, or it only has `fields`. In the former case, we call it an ILClass, otherwise we call it an ILStruct. In this case, that means it's an ILClass.

 namespace Dpr::Battle::Logic {
     // If ILClass:  `struct T : ILClass<T>` 
     // If ILStruct: `struct T : ILStruct<T>`
     struct MyStatus : ILClass<MyStatus> {  
     };
 }

Next, we right-click the `fields` row and click "Edit component field". The following shows up:

 namespace Dpr::Battle::Logic {
     struct MyStatus : ILClass<MyStatus> {
         // All fields go in a nested Fields struct. If it has no fields, don't add it.
         // If your type has a supertype (for example, UnityEngine_Behaviour_fields has a field called super of type UnityEngine_Component_fields),
         //  You would copy that here (i.e. `struct Fields : UnityEngine::Component::Fields {`)
         struct Fields {
             // Fill in all elements from the image, creating their types if needed.
             // You need to remap e.g. System_String_o* to System::String::Object*
             // or UnityEngine_GameObject_array to UnityEngine::GameObject::Array
             System::String::Object* name;
             bool sex;
             int32_t lang;
             uint32_t id;
             uint8_t fashion;
             uint8_t body_type;
             uint8_t hat;
             uint8_t shoes;
         };
     };
 }