Source External IMaterialSystem (IMaterial)

DREDD

Administrator
Administrator
Administrator
Administrator
Status
Offline
Joined
Apr 18, 2019
Messages
147
Reaction score
249
Material:
C++:
class c_material {
public:
    c_material() = default;
 
    c_material(const uint32_t& address) {
        this->address = address;
    }
 
    void alpha_modulate(float alpha) {
        auto eax = get_shader_params();
 
        if (!eax) return;
 
        auto ecx = process.read<uint32_t>(eax + 0x14);
        process.write<float>(ecx + 0xC, alpha);
    }
 
    void color_modulate(float r, float g, float b) {
        auto eax = get_shader_params();
 
        if (!eax) return;
 
        auto ecx = process.read<uint32_t>(eax + 0x10);
        process.write<rgb>(ecx + 0xC, rgb(r, g, b));
    }
 
    std::string get_name() {
        return process.read_string(get_name_by_offset(process.read<uint8_t>(process.get_vfunc<uint32_t>(this->address, 0) + 2)));
    }
 
    std::string get_texture_group_name() {
        return process.read_string(get_name_by_offset(process.read<uint8_t>(process.get_vfunc<uint32_t>(this->address, 1) + 2)));
    }
 
    operator uint32_t() const noexcept { return this->address; }
private:
    uint32_t address;
 
    uint32_t get_shader_params() {
        auto shader_params_vfunc = process.get_vfunc<uint32_t>(this->address, 41);
        return process.read<uint16_t>(shader_params_vfunc) == 0x498B ? c_material(process.read<uint32_t>(this->address + 0x4)).get_shader_params() : process.read<uint32_t>(this->address + 0x24);
    }
 
    uint32_t get_name_by_offset(uint8_t offset) {
        /*
            0F B7 C0                movzx   eax, ax
            8D 0C 40                lea     ecx, [eax+eax*2]
            8B 47 04                mov     eax, [edi+4]
            0F B7 54 88 08          movzx   edx, word ptr [eax+ecx*4+8]
            8D 0C 88                lea     ecx, [eax+ecx*4]
            8B 47 24                mov     eax, [edi+24h]
            0F B7 49 0A             movzx   ecx, word ptr [ecx+0Ah]
            8B 04 90                mov     eax, [eax+edx*4]
            83 C0 0A                add     eax, 0Ah
            03 C1                   add     eax, ecx
        */
 
        auto eax = uint32_t(process.read<uint16_t>(this->address + offset));
        auto ecx = eax + eax * 2;
        eax = process.read<uint32_t>(n_material_system::material_global_var_thing + 4);
        auto edx = uint32_t(process.read<uint16_t>(eax + ecx * 4 + 8));
        ecx = eax + ecx * 4;
        eax = process.read<uint32_t>(n_material_system::material_global_var_thing + 0x24);
        ecx = uint32_t(process.read<uint16_t>(ecx + 0x0A));
        eax = process.read<uint32_t>(eax + edx * 4);
        eax += 0x0A + ecx;
 
        return eax;
    }
};
Material System:

C++:
class c_material_system : public onion::c_interface_base {
public:
    material_handle first_material() {
        auto current_handle = process.read<material_handle>(this->address + 0x250);
            
        while (current_handle != invalid_material()) {
            const auto next_handle = process.read<material_handle>(process.read<uint32_t>(this->address + 0x244) + 16 * current_handle);
            if (next_handle == invalid_material())
                break;
 
            current_handle = next_handle;
        }
 
        return current_handle;
    }
 
    material_handle next_material(material_handle material) {
        unsigned __int16 materialHandle_local; // dx@1
        int materialInterface_240h_local; // edi@1
        int handleArray; // esi@2
        unsigned __int16 v5; // ax@2
        unsigned __int16 next_handle; // cx@3
        int handleArray_1; // esi@9
        int v9; // eax@9
        unsigned __int16 v10; // ax@10
 
        materialHandle_local = material;
        materialInterface_240h_local = this->address + 0x240;
        if (material == invalid_material()) {
            next_handle = invalid_material();
        } else {
            handleArray = process.read<DWORD>(this->address + 0x240 + 4);// +0x244
            v5 = process.read<WORD>(handleArray + 16 * (unsigned __int16)material + 2);
            if (v5 != invalid_material()) {
                do {
                    next_handle = v5;
                    if (v5 == invalid_material())
                        break;
                    v5 = process.read<WORD>(handleArray + 16 * (unsigned __int16)v5);
                } while (v5 != invalid_material());
                return next_handle;
            }
            next_handle = process.read<WORD>(handleArray + 16 * (unsigned __int16)material + 4);
        }
        while (1) {
            if (materialHandle_local == invalid_material()
                || (handleArray_1 = process.read<DWORD>(materialInterface_240h_local + 4),
                    v9 = process.read<WORD>(handleArray_1 + 16 * (unsigned __int16)materialHandle_local + 4),
                    (WORD)v9 == invalid_material()))
                v10 = invalid_material();
            else
                v10 = process.read<WORD>(handleArray_1 + 16 * v9 + 2);
            if (v10 != materialHandle_local)
                break;
            materialHandle_local = next_handle;
            if (next_handle == invalid_material())
                break;
            next_handle = process.read<WORD>(process.read<DWORD>(materialInterface_240h_local + 4) + 16 * (unsigned __int16)next_handle + 4);
        }
        return next_handle;
    }
 
    material_handle invalid_material() {
        return 0xFFFF;
    }
 
    c_material get_material(material_handle material) {
        return c_material(process.read<DWORD>(process.read<uint32_t>(this->address + 145 * 4) + 16 * material + 8));
    }
};

material_global_var_thing = process.read<uint32_t>(process.read<uint32_t>(utils::find_pattern(process, "materialsystem.dll", "80 3D ? ? ? ? ? 66") + 2) + 4);
Example of using:

C++:
for (auto handle = interfaces::material_system.first_material();
    handle != interfaces::material_system.invalid_material();
    handle = interfaces::material_system.next_material(handle)) {
 
    auto material = interfaces::material_system.get_material(handle);
    const auto texture_group_name = material.get_texture_group_name();
}
 
Top