diff --git a/libreborn/include/libreborn/patch.h b/libreborn/include/libreborn/patch.h index 06e5403..a4587a1 100644 --- a/libreborn/include/libreborn/patch.h +++ b/libreborn/include/libreborn/patch.h @@ -14,6 +14,9 @@ void _overwrite_call(const char *file, int line, void *start, void *target); void _overwrite_calls(const char *file, int line, void *start, void *target); #define overwrite_calls(start, target) _overwrite_calls(__FILE__, __LINE__, start, target); +void _overwrite_calls_within(const char *file, int line, void *from, void *to, void *start, void *target); +#define overwrite_calls_within(from, to, start, target) _overwrite_calls(__FILE__, __LINE__, from, to, start, target); + void *extract_from_bl_instruction(unsigned char *from); void _overwrite(const char *file, int line, void *start, void *target); diff --git a/libreborn/src/patch/patch.c b/libreborn/src/patch/patch.c index 21093da..3e5654c 100644 --- a/libreborn/src/patch/patch.c +++ b/libreborn/src/patch/patch.c @@ -40,6 +40,26 @@ static uint32_t generate_bl_instruction(void *from, void *to, int use_b_instruct } // Run For Every .text Section +static int _overwrite_calls_within_internal(const char *file, int line, void *from, void *to, void *target, void *replacement) { + int found = 0; + for (uint32_t i = (uint32_t) from; i < (uint32_t) to; i = i + 4) { + unsigned char *addr = (unsigned char *) i; + int use_b_instruction = addr[3] == B_INSTRUCTION; + // Check If Instruction is B Or BL + if (addr[3] == BL_INSTRUCTION || use_b_instruction) { + uint32_t check_instruction = generate_bl_instruction(addr, target, use_b_instruction); + unsigned char *check_instruction_array = (unsigned char *) &check_instruction; + // Check If Instruction Calls Target + if (addr[0] == check_instruction_array[0] && addr[1] == check_instruction_array[1] && addr[2] == check_instruction_array[2]) { + // Patch Instruction + uint32_t new_instruction = generate_bl_instruction(addr, replacement, use_b_instruction); + _patch(file, line, addr, (unsigned char *) &new_instruction); + found++; + } + } + } + return found; +} struct overwrite_data { const char *file; int line; @@ -50,23 +70,7 @@ struct overwrite_data { static void overwrite_calls_callback(ElfW(Addr) section_addr, ElfW(Word) size, void *data) { struct overwrite_data *args = (struct overwrite_data *) data; void *section = (void *) section_addr; - - for (uint32_t i = 0; i < size; i = i + 4) { - unsigned char *addr = ((unsigned char *) section) + i; - int use_b_instruction = addr[3] == B_INSTRUCTION; - // Check If Instruction is B Or BL - if (addr[3] == BL_INSTRUCTION || use_b_instruction) { - uint32_t check_instruction = generate_bl_instruction(addr, args->target, use_b_instruction); - unsigned char *check_instruction_array = (unsigned char *) &check_instruction; - // Check If Instruction Calls Target - if (addr[0] == check_instruction_array[0] && addr[1] == check_instruction_array[1] && addr[2] == check_instruction_array[2]) { - // Patch Instruction - uint32_t new_instruction = generate_bl_instruction(addr, args->replacement, use_b_instruction); - _patch(args->file, args->line, addr, (unsigned char *) &new_instruction); - args->found++; - } - } - } + args->found += _overwrite_calls_within_internal(args->file, args->line, section, (void *) (section_addr + size), args->target, args->replacement); } // Limit To 512 overwrite_calls() Uses @@ -139,6 +143,20 @@ void _overwrite_calls(const char *file, int line, void *start, void *target) { ERR("(%s:%i) Unable To Find Callsites For 0x%08x", file, line, (uint32_t) start); } } +void _overwrite_calls_within(const char *file, int line, void *from, void *to, void *target, void *replacement) { + // Add New Target To Code Block + update_code_block(replacement); + + // Patch + int found = _overwrite_calls_within_internal(file, line, from, to, target, code_block); + // Check + if (found < 1) { + ERR("(%s:%i) Unable To Find Callsites For 0x%08x", file, line, (uint32_t) target); + } + + // Increment Code Block Position + increment_code_block(); +} // Extract Target Address From B(L) Instruction void *extract_from_bl_instruction(unsigned char *from) { diff --git a/media-layer/core/CMakeLists.txt b/media-layer/core/CMakeLists.txt index c53228f..6d66d9b 100644 --- a/media-layer/core/CMakeLists.txt +++ b/media-layer/core/CMakeLists.txt @@ -1,7 +1,9 @@ project(media-layer-core) # OpenGL -add_subdirectory(gles) +if(NOT MCPI_HEADLESS_MODE) + add_subdirectory(gles) +endif() # Configuration set(CORE_SRC src/base.cpp src/media.c $) # SDL Re-Implementation Using GLFW @@ -21,10 +23,10 @@ endif() install(TARGETS media-layer-core-real DESTINATION "${MCPI_LIB_DIR}") # Link -target_link_libraries(media-layer-core-real PUBLIC media-layer-headers PUBLIC reborn-util PUBLIC GLESv1_CM PUBLIC dl) +target_link_libraries(media-layer-core-real PUBLIC media-layer-headers PUBLIC reborn-util PUBLIC dl) if(NOT MCPI_HEADLESS_MODE) # OpenAL find_library(OPENAL_LIBRARY NAMES openal REQUIRED) # Link - target_link_libraries(media-layer-core-real PRIVATE "${OPENAL_LIBRARY}" PRIVATE m PRIVATE glfw PRIVATE LIB_LIEF) + target_link_libraries(media-layer-core-real PRIVATE "${OPENAL_LIBRARY}" PRIVATE m PRIVATE glfw PUBLIC GLESv1_CM PRIVATE LIB_LIEF) endif() diff --git a/media-layer/core/gles/CMakeLists.txt b/media-layer/core/gles/CMakeLists.txt index 16ed214..2111a0a 100644 --- a/media-layer/core/gles/CMakeLists.txt +++ b/media-layer/core/gles/CMakeLists.txt @@ -1,11 +1,7 @@ project(media-layer-gles) # Build -if(MCPI_HEADLESS_MODE) - # Stubs For Headless Mode - add_library(GLESv1_CM OBJECT src/stubs.c) - target_link_libraries(GLESv1_CM PRIVATE media-layer-headers) -elseif(MCPI_USE_GLES1_COMPATIBILITY_LAYER) +if(MCPI_USE_GLES1_COMPATIBILITY_LAYER) # GLESv1_CM Compatibility Layer add_library(GLESv1_CM INTERFACE) target_link_libraries(GLESv1_CM INTERFACE gles-compatibility-layer) diff --git a/media-layer/core/gles/src/stubs.c b/media-layer/core/gles/src/stubs.c deleted file mode 100644 index ab3ffe5..0000000 --- a/media-layer/core/gles/src/stubs.c +++ /dev/null @@ -1,170 +0,0 @@ -#include - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" - -void glFogfv(GLenum pname, const GLfloat *params) { -} -void glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { -} -void glLineWidth(GLfloat width) { -} -void glBlendFunc(GLenum sfactor, GLenum dfactor) { -} -void glDrawArrays(GLenum mode, GLint first, GLsizei count) { -} -void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { -} -void glClear(GLbitfield mask) { -} -void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage) { -} -void glFogx(GLenum pname, GLfixed param) { -} -void glFogf(GLenum pname, GLfloat param) { -} -void glMatrixMode(GLenum mode) { -} -void glColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { -} -void glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { -} -void glTexParameteri(GLenum target, GLenum pname, GLint param) { -} -void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) { -} -void glEnable(GLenum cap) { -} -void glEnableClientState(GLenum array) { -} -void glPolygonOffset(GLfloat factor, GLfloat units) { -} -void glDisableClientState(GLenum array) { -} -void glDepthRangef(GLclampf near, GLclampf far) { -} -void glDepthFunc(GLenum func) { -} -static GLuint current_buffer = 0; -void glBindBuffer(GLenum target, GLuint buffer) { - if (target == GL_ARRAY_BUFFER) { - current_buffer = buffer; - } -} -void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { -} -void glPopMatrix() { -} -void glLoadIdentity() { -} -void glScalef(GLfloat x, GLfloat y, GLfloat z) { -} -void glPushMatrix() { -} -void glDepthMask(GLboolean flag) { -} -void glHint(GLenum target, GLenum mode) { -} -void glMultMatrixf(const GLfloat *m) { -} -void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) { -} -void glDeleteBuffers(GLsizei n, const GLuint *buffers) { -} -void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { -} -void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) { -} -void glGenTextures(GLsizei n, GLuint *textures) { - static int i = 1; - for (int j = 0; j < n; j++) { - textures[j] = i++; - } -} -void glDeleteTextures(GLsizei n, const GLuint *textures) { -} -void glAlphaFunc(GLenum func, GLclampf ref) { -} -void glGetFloatv(GLenum pname, GLfloat *params) { - switch (pname) { - case GL_MODELVIEW_MATRIX: - case GL_PROJECTION_MATRIX: { - params[0] = 1; - params[1] = 0; - params[2] = 0; - params[3] = 0; - params[4] = 0; - params[5] = 1; - params[6] = 0; - params[7] = 0; - params[8] = 0; - params[9] = 0; - params[10] = 1; - params[11] = 0; - params[12] = 0; - params[13] = 0; - params[14] = 0; - params[15] = 1; - break; - } - default: { - params[0] = 0; - break; - } - } -} -static GLuint current_texture = 0; -void glBindTexture(GLenum target, GLuint texture) { - if (target == GL_TEXTURE_2D) { - current_texture = texture; - } -} -void glTranslatef(GLfloat x, GLfloat y, GLfloat z) { -} -void glShadeModel(GLenum mode) { -} -void glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far) { -} -void glDisable(GLenum cap) { -} -void glCullFace(GLenum mode) { -} -void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { -} -void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { -} -void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) { -} -GLboolean glIsEnabled(GLenum cap) { - return GL_FALSE; -} -void glGetIntegerv(GLenum pname, GLint *data) { - switch (pname) { - case GL_TEXTURE_BINDING_2D: { - data[0] = current_texture; - break; - } - case GL_ARRAY_BUFFER_BINDING: { - data[0] = current_buffer; - break; - } - case GL_UNPACK_ALIGNMENT: { - data[0] = 1; - break; - } - default: { - data[0] = 0; - break; - } - } -} -void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data) { -} -void glGenBuffers(GLsizei n, GLuint *buffers) { - static int i = 1; - for (int j = 0; j < n; j++) { - buffers[j] = i++; - } -} - -#pragma GCC diagnostic pop diff --git a/mods/src/misc/misc.c b/mods/src/misc/misc.c index c738f6a..d4a5802 100644 --- a/mods/src/misc/misc.c +++ b/mods/src/misc/misc.c @@ -301,10 +301,12 @@ int32_t misc_get_real_selected_slot(unsigned char *player) { return selected_slot; } +#ifndef MCPI_HEADLESS_MODE // Properly Generate Buffers static void anGenBuffers_injection(int32_t count, uint32_t *buffers) { glGenBuffers(count, buffers); } +#endif // Fix Graphics Bug When Switching To First-Person While Sneaking static void HumanoidMobRenderer_render_injection(unsigned char *model_renderer, unsigned char *entity, float param_2, float param_3, float param_4, float param_5, float param_6) { @@ -554,6 +556,9 @@ void init_misc() { #ifdef MCPI_HEADLESS_MODE // Don't Render Game In Headless Mode overwrite_calls((void *) GameRenderer_render, (void *) nop); + overwrite_calls((void *) NinecraftApp_initGLStates, (void *) nop); + overwrite_calls((void *) Gui_onConfigChanged, (void *) nop); + overwrite_calls((void *) LevelRenderer_generateSky, (void *) nop); #else // Improved Cursor Rendering if (feature_has("Improved Cursor Rendering", server_disabled)) { @@ -580,8 +585,10 @@ void init_misc() { overwrite_calls((void *) sleepMs, (void *) nop); } +#ifndef MCPI_HEADLESS_MODE // Properly Generate Buffers overwrite((void *) anGenBuffers, (void *) anGenBuffers_injection); +#endif // Fix Graphics Bug When Switching To First-Person While Sneaking patch_address(PlayerRenderer_render_vtable_addr, (void *) HumanoidMobRenderer_render_injection); diff --git a/symbols/include/symbols/minecraft.h b/symbols/include/symbols/minecraft.h index 33637b7..7103464 100644 --- a/symbols/include/symbols/minecraft.h +++ b/symbols/include/symbols/minecraft.h @@ -170,6 +170,11 @@ static TileRenderer_tesselateBlockInWorld_t TileRenderer_tesselateBlockInWorld = typedef void (*GameMode_releaseUsingItem_t)(unsigned char *game_mode, unsigned char *player); static uint32_t GameMode_releaseUsingItem_vtable_offset = 0x5c; +// NinecraftApp + +typedef void (*NinecraftApp_initGLStates_t)(unsigned char *minecraft); +static NinecraftApp_initGLStates_t NinecraftApp_initGLStates = (NinecraftApp_initGLStates_t) 0x148c8; + // Minecraft typedef void (*Minecraft_init_t)(unsigned char *minecraft); @@ -506,6 +511,9 @@ static Gui_renderToolBar_t Gui_renderToolBar = (Gui_renderToolBar_t) 0x26c30; typedef void (*Gui_renderChatMessages_t)(unsigned char *gui, int32_t y_offset, uint32_t max_messages, bool disable_fading, unsigned char *font); static Gui_renderChatMessages_t Gui_renderChatMessages = (Gui_renderChatMessages_t) 0x273d8; +typedef void (*Gui_onConfigChanged_t)(unsigned char *gui, unsigned char *config); +static Gui_onConfigChanged_t Gui_onConfigChanged = (Gui_onConfigChanged_t) 0x255bc; + static uint32_t Gui_minecraft_property_offset = 0x9f4; // Minecraft * static uint32_t Gui_selected_item_text_timer_property_offset = 0x9fc; // float @@ -563,6 +571,9 @@ static LevelRenderer_render_t LevelRenderer_render = (LevelRenderer_render_t) 0x typedef void (*LevelRenderer_renderDebug_t)(unsigned char *level_renderer, struct AABB *aabb, float delta); static LevelRenderer_renderDebug_t LevelRenderer_renderDebug = (LevelRenderer_renderDebug_t) 0x4d310; +typedef void (*LevelRenderer_generateSky_t)(unsigned char *level_renderer); +static LevelRenderer_generateSky_t LevelRenderer_generateSky = (LevelRenderer_generateSky_t) 0x4d0d4; + static uint32_t LevelRenderer_minecraft_property_offset = 0x4; // Minecraft * // PerfRenderer