├── README.md ├── entry └── main.cpp ├── gasper-cpp.vcxproj ├── gasper-cpp.vcxproj.filters ├── gasper-cpp.vcxproj.user ├── main ├── cheats │ ├── cheat.cpp │ ├── cheat.h │ └── impl │ │ ├── headers │ │ ├── aimbot.h │ │ ├── impl.h │ │ ├── reach.h │ │ └── strafe.h │ │ └── src │ │ ├── aimbot.cpp │ │ ├── reach.cpp │ │ └── strafe.cpp ├── gasper.cpp ├── gasper.h └── hooks │ ├── swap_buffers.cpp │ └── wndproc.cpp └── sdk ├── hook ├── MinHook.h ├── buffer.c ├── buffer.h ├── hde │ ├── hde32.c │ ├── hde32.h │ ├── hde64.c │ ├── hde64.h │ ├── pstdint.h │ ├── table32.h │ └── table64.h ├── hook.c ├── trampoline.c └── trampoline.h ├── includes.h ├── libraries ├── imgui │ ├── imconfig.h │ ├── imgui.cpp │ ├── imgui.h │ ├── imgui_draw.cpp │ ├── imgui_impl_opengl2.cpp │ ├── imgui_impl_opengl2.h │ ├── imgui_impl_win32.cpp │ ├── imgui_impl_win32.h │ ├── imgui_internal.h │ ├── imgui_widgets.cpp │ ├── imstb_rectpack.h │ ├── imstb_textedit.h │ └── imstb_truetype.h └── xorstr.h ├── mapper └── mapper.h ├── minecraft ├── axisaligned │ ├── axisalignedbb.cpp │ └── axisalignedbb.h ├── minecraft.cpp ├── minecraft.h ├── player │ ├── player.cpp │ └── player.h └── world │ ├── world.cpp │ └── world.h ├── utils ├── timer │ ├── timer.cpp │ └── timer.h └── utils.h └── wrapper └── wrapper.h /README.md: -------------------------------------------------------------------------------- 1 | # gasper-cpp 2 | A Forge 'ghost client' written in C++ 3 | 4 | # Wagwan 5 | Wagwan guys, now is time to combine all your knowledge I've spoonfed you last month. Have fun buddies :) 6 | 7 | # Compiling 8 | Don't forget to link opengl32.dll or else it wont compile. 9 | *NOTE: If you're not compiling for Badlion Client, go to the includes header-file and disable the poorly defined BADLION_CLIENT variable.* 10 | 11 | # Features 12 | * Aimbot 13 | * Reach 14 | * Strafe (anti-paste) 15 | * Menu 16 | -------------------------------------------------------------------------------- /entry/main.cpp: -------------------------------------------------------------------------------- 1 | #include "../sdk/includes.h" 2 | #include "../main/gasper.h" 3 | 4 | void start_gasper_thread(); 5 | 6 | /// Note: this DLL is manually mapped, there's literally NO reason to handle any other call than DLL_PROCESS_ATTACH 7 | /// thread calls are also non-existant, so no reason to use DisableThreadLibraryCalls 8 | int __stdcall DllMain( 9 | HINSTANCE hinstDLL, 10 | unsigned long fdwReason, 11 | void* lpvReserved 12 | ) { 13 | 14 | if (fdwReason != DLL_PROCESS_ATTACH) 15 | return false; 16 | 17 | /// Not necessary to handle the handle to the thread because, no second call I guess. 18 | wrapper::spawn_thread(reinterpret_cast(start_gasper_thread)); 19 | 20 | return true; 21 | } 22 | 23 | void start_gasper_thread() { 24 | 25 | std::this_thread::sleep_for(std::chrono::seconds(5)); 26 | 27 | /// "Bro you know when the object is destroyed" true. 28 | gasper::instance = std::make_unique(); 29 | 30 | /// Try to attach, if we fail the attach function will be sure to drop an error message 31 | if (!gasper::instance->attach()) 32 | std::exit(0); 33 | 34 | /// Let's get this started 35 | gasper::instance->run(); 36 | 37 | /// Wait a second actually 38 | std::this_thread::sleep_for(std::chrono::seconds(1)); 39 | 40 | /// Ok now dispose of our shit 41 | gasper::instance->dispose(); 42 | } -------------------------------------------------------------------------------- /gasper-cpp.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {0F49A3C8-151C-466C-98E5-43E8EFC24D41} 24 | gaspercpp 25 | 10.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v142 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v142 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v142 45 | Unicode 46 | 47 | 48 | DynamicLibrary 49 | false 50 | v142 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | C:\Program Files\Java\jdk1.8.0_231\include\win32;C:\Program Files\Java\jdk1.8.0_231\include;$(IncludePath) 84 | C:\Program Files\Java\jdk1.8.0_231\lib;$(LibraryPath) 85 | 86 | 87 | 88 | Level3 89 | true 90 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 91 | true 92 | 93 | 94 | Console 95 | true 96 | 97 | 98 | 99 | 100 | Level3 101 | true 102 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 103 | true 104 | 105 | 106 | Console 107 | true 108 | 109 | 110 | 111 | 112 | Level3 113 | true 114 | true 115 | true 116 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 117 | true 118 | 119 | 120 | Console 121 | true 122 | true 123 | true 124 | 125 | 126 | 127 | 128 | Level3 129 | true 130 | true 131 | true 132 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 133 | true 134 | stdcpp17 135 | 136 | 137 | Console 138 | true 139 | true 140 | true 141 | opengl32.lib;%(AdditionalDependencies) 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /gasper-cpp.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | Source Files 53 | 54 | 55 | Source Files 56 | 57 | 58 | Source Files 59 | 60 | 61 | Source Files 62 | 63 | 64 | Source Files 65 | 66 | 67 | Source Files 68 | 69 | 70 | Source Files 71 | 72 | 73 | Source Files 74 | 75 | 76 | Source Files 77 | 78 | 79 | Source Files 80 | 81 | 82 | Source Files 83 | 84 | 85 | Source Files 86 | 87 | 88 | 89 | 90 | Header Files 91 | 92 | 93 | Header Files 94 | 95 | 96 | Header Files 97 | 98 | 99 | Header Files 100 | 101 | 102 | Header Files 103 | 104 | 105 | Header Files 106 | 107 | 108 | Header Files 109 | 110 | 111 | Header Files 112 | 113 | 114 | Header Files 115 | 116 | 117 | Header Files 118 | 119 | 120 | Header Files 121 | 122 | 123 | Header Files 124 | 125 | 126 | Header Files 127 | 128 | 129 | Header Files 130 | 131 | 132 | Header Files 133 | 134 | 135 | Header Files 136 | 137 | 138 | Header Files 139 | 140 | 141 | Header Files 142 | 143 | 144 | Header Files 145 | 146 | 147 | Header Files 148 | 149 | 150 | Header Files 151 | 152 | 153 | Header Files 154 | 155 | 156 | Header Files 157 | 158 | 159 | Header Files 160 | 161 | 162 | Header Files 163 | 164 | 165 | Header Files 166 | 167 | 168 | Header Files 169 | 170 | 171 | Header Files 172 | 173 | 174 | Header Files 175 | 176 | 177 | Header Files 178 | 179 | 180 | Header Files 181 | 182 | 183 | Header Files 184 | 185 | 186 | -------------------------------------------------------------------------------- /gasper-cpp.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | -------------------------------------------------------------------------------- /main/cheats/cheat.cpp: -------------------------------------------------------------------------------- 1 | #include "cheat.h" 2 | 3 | #include "../../sdk/minecraft/player/player.h" 4 | #include "../../sdk/minecraft/world/world.h" 5 | 6 | cheats::c_cheats::~c_cheats() 7 | { 8 | _functions.clear(); 9 | } 10 | 11 | void cheats::c_cheats::register_function(std::function)> fn) 12 | { 13 | _functions.push_back(fn); 14 | } 15 | 16 | void cheats::c_cheats::invoke(std::shared_ptr ctx) 17 | { 18 | for (auto fn : _functions) 19 | fn(ctx); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /main/cheats/cheat.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../sdk/includes.h" 4 | class c_player; 5 | class c_world; 6 | 7 | class c_context { 8 | public: 9 | std::shared_ptr local; 10 | std::shared_ptr world; 11 | bool hovering; 12 | bool ingame; 13 | 14 | c_context(std::shared_ptr plr, std::shared_ptr wld, bool ingam, bool hoverig) 15 | { 16 | local = plr; 17 | world = wld; 18 | ingame = ingam; 19 | hovering = hoverig; 20 | } 21 | }; 22 | 23 | namespace cheats { 24 | 25 | class c_cheats { 26 | private: 27 | std::vector)>> _functions; 28 | public: 29 | 30 | ~c_cheats(); 31 | 32 | void register_function(std::function)> fn); 33 | void invoke(std::shared_ptr ctx); 34 | 35 | }; 36 | inline std::unique_ptr instance = nullptr; 37 | } -------------------------------------------------------------------------------- /main/cheats/impl/headers/aimbot.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "impl.h" 4 | 5 | namespace aimbot { 6 | void invoke(std::shared_ptr); 7 | 8 | inline auto m_enabled = false; 9 | inline auto m_speed = 10.0f; 10 | inline auto m_speed_body = 2.0f; 11 | inline auto m_fov = 30.0f; 12 | } -------------------------------------------------------------------------------- /main/cheats/impl/headers/impl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../cheat.h" 4 | 5 | #include "../../../gasper.h" 6 | #include "../../../../sdk/minecraft/player/player.h" 7 | #include "../../../../sdk/minecraft/world/world.h" 8 | #include "../../../../sdk/minecraft/axisaligned/axisalignedbb.h" -------------------------------------------------------------------------------- /main/cheats/impl/headers/reach.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "impl.h" 4 | 5 | namespace reach { 6 | void invoke(std::shared_ptr); 7 | 8 | inline auto m_enabled = false; 9 | inline auto m_reach = 0.5f; 10 | } -------------------------------------------------------------------------------- /main/cheats/impl/headers/strafe.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "impl.h" 4 | 5 | namespace strafe { 6 | void invoke(std::shared_ptr ctx); 7 | 8 | inline bool m_enabled = false; 9 | } -------------------------------------------------------------------------------- /main/cheats/impl/src/aimbot.cpp: -------------------------------------------------------------------------------- 1 | #include "../headers/aimbot.h" 2 | 3 | void aimbot::invoke(std::shared_ptr ctx) 4 | { 5 | /// Keep a timer 6 | static std::shared_ptr timer = std::make_shared(); 7 | 8 | /// Returns true when the local player object and the world object aren't null 9 | const auto is_sane = [&]() { 10 | return (ctx->local->get_object() && ctx->world->get_object()); 11 | }; 12 | 13 | /// Get closest player to local player (distance wise) 14 | const auto get_closest_player = [&]() { 15 | /// If you still use some random number you're stupid 16 | double dist = (std::numeric_limits::max)(); 17 | /// Target :O 18 | std::shared_ptr target = nullptr; 19 | 20 | /// Iterate over all player objects in the world 21 | /// note: c_world#get_players actually iterates the playerlist so if you want to iterate the entity list instead 22 | /// you should actually change the field 23 | for (const auto& player : ctx->world->get_players()) 24 | { 25 | /// Compare the object to our local player to make sure we aren't going to be aiming at ourselves 26 | if (gasper::instance->get_env()->IsSameObject(ctx->local->get_object(), player->get_object())) 27 | continue; 28 | 29 | /// Not ded? 30 | if (!player->get_health() > 0) 31 | continue; 32 | 33 | /// Not invisible? 34 | if (player->is_invisible()) 35 | continue; 36 | 37 | /// Basic stuff 38 | if (ctx->local->get_distance_to(player) <= dist) 39 | { 40 | dist = ctx->local->get_distance_to(player); 41 | target = player; 42 | } 43 | } 44 | 45 | return target; 46 | }; 47 | 48 | if (!is_sane() || !aimbot::m_enabled || !ctx->ingame) 49 | return; 50 | 51 | auto target = get_closest_player(); 52 | 53 | if (target && timer->has_passed(30) ) 54 | { 55 | auto angles = sdk::util::get_angles(ctx->local->get_position(), target->get_position()); 56 | 57 | auto difference = sdk::util::wrap_to_180(-(ctx->local->get_yaw() - angles.first)); 58 | 59 | /// difference might be negative so yknow 60 | if (abs(difference) <= aimbot::m_fov) { 61 | auto current_yaw = ctx->local->get_yaw(); 62 | current_yaw += (difference / (20 / aimbot::m_speed)); 63 | 64 | ctx->local->set_yaw(current_yaw); 65 | } 66 | 67 | timer->reset(); 68 | } 69 | } -------------------------------------------------------------------------------- /main/cheats/impl/src/reach.cpp: -------------------------------------------------------------------------------- 1 | #include "../headers/reach.h" 2 | 3 | void reach::invoke(std::shared_ptr ctx) 4 | { 5 | /// Keep a timer 6 | static std::shared_ptr timer = std::make_shared(); 7 | 8 | /// Returns true when the local player object and the world object aren't null 9 | const auto is_sane = [&]() { 10 | return (ctx->local->get_object() && ctx->world->get_object()); 11 | }; 12 | /// Santity check and only run 20 times a second because that's what MC does as well, no need to overkill atm 13 | if (is_sane() && timer->has_passed(25) && reach::m_enabled) 14 | { 15 | auto distance = reach::m_reach; 16 | 17 | auto position = ctx->local->get_position(); 18 | 19 | for (const auto& entity : ctx->world->get_players()) 20 | { 21 | if (gasper::instance->get_env()->IsSameObject(ctx->local->get_object(), entity->get_object())) 22 | continue; 23 | 24 | if (!entity->get_health() > 0.0f) 25 | continue; 26 | 27 | /// Position of entity 28 | auto entity_position = entity->get_position(); 29 | 30 | /// Get the hyp 31 | auto hypothenuse_distance = hypot(position.x - entity_position.x, position.z - entity_position.z); 32 | 33 | /// Check if the distance is greater than the vertical dist 34 | if (distance > hypothenuse_distance) 35 | distance -= hypothenuse_distance; 36 | 37 | /// Get angles to player 38 | auto angles = sdk::util::get_angles(position, entity_position); 39 | 40 | /// Distance between angles 41 | auto difference = sdk::util::wrap_to_180(-(ctx->local->get_yaw() - angles.first)); 42 | 43 | /// Check if player isn't on screen 44 | if (std::abs(difference) > 180.0f) 45 | continue; 46 | 47 | /// ye ye 48 | auto cos = std::cos(sdk::util::deg_to_radiants(angles.first + 90.0f)); 49 | auto sin = std::sin(sdk::util::deg_to_radiants(angles.first + 90.0f)); 50 | 51 | /// Move accordingly 52 | auto x = entity_position.x, z = entity_position.z; 53 | x -= (cos * distance); 54 | z -= (sin * distance); 55 | 56 | /// At this point what we've done, we've calculated the position of the entity where he would be if we moved him, considering we can't set his position without 57 | /// glitching out, we'll have to move the bounding box instead luckily for us, minecraft explains what we need to do for us :) 58 | /// the values we get is entity_width = 0.6f and entity_height = 1.8f but we'll keep the y-axis of the boundingbox the same 59 | auto entity_width = 0.6f; 60 | 61 | /// Width from left to middle 62 | auto bb_width = entity_width / 2.0f; 63 | 64 | /// To see what original is :) 65 | auto current_boundingbox = entity->get_bounding_box()->get_native_boundingbox(); 66 | 67 | /// Set the values for min 68 | s_axisalignedbb bb{}; 69 | bb.minX = x - bb_width; 70 | bb.minY = current_boundingbox.minY; 71 | bb.minZ = z - bb_width; 72 | 73 | /// And max ofcourse 74 | bb.maxX = x + bb_width; 75 | bb.maxY = current_boundingbox.maxY; 76 | bb.maxZ = z + bb_width; 77 | 78 | /// Now set the entity's BB 79 | /// NOTE: There's no reason to allocate a new boundingbox, this will save us processing power 80 | entity->get_bounding_box()->set_native_boundingbox(bb); 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /main/cheats/impl/src/strafe.cpp: -------------------------------------------------------------------------------- 1 | #include "..\headers\strafe.h" 2 | 3 | /// Get directional float 4 | float get_direction(std::shared_ptr ctx); 5 | 6 | /// Get calculated speed 7 | float get_speed(std::shared_ptr ctx); 8 | 9 | /// Set speed 10 | void set_speed(std::shared_ptr ctx, const float speed); 11 | 12 | /// Fun fact: I had originally written this feature in some old client me and Koupah were making (but eventually dropped) 13 | /// later he adapted that feature and made it a public module and since then we've seen it pretty much in ever cheat since (lulw) 14 | /// so just wanted to tell you I made this shit as can be seen in my commit log of the git we kept this feature has been present in the git 15 | /// since June 2018 but I had implemented it in other cheats as well so let's say begin 2018? 16 | /// epic right? 17 | void strafe::invoke(std::shared_ptr ctx) 18 | { 19 | /// Keep a timer 20 | static std::shared_ptr timer = std::make_shared(); 21 | 22 | /// Returns true when the local player object and the world object aren't null 23 | const auto is_sane = [&]() { 24 | return (ctx->local->get_object() && ctx->world->get_object()); 25 | }; 26 | 27 | if (!strafe::m_enabled || !is_sane()) 28 | return; 29 | 30 | /// Here we go, 20 times a second again (doesn't necessarily have to be synced as well) 31 | if (!timer->has_passed(50)) 32 | return; 33 | 34 | /// If we're not being hit 35 | /// We're on the ground 36 | /// And we're moving 37 | if (ctx->local->get_hurt_time() == 0 38 | && (ctx->local->get_moveforward() != .0f 39 | || ctx->local->get_movestrafe() != .0f)) 40 | /// Set the speed :) 41 | set_speed(ctx, get_speed(ctx)); 42 | 43 | timer->reset(); 44 | } 45 | 46 | float get_direction(std::shared_ptr ctx) 47 | { 48 | float yaw = ctx->local->get_yaw(); 49 | float move_forward = ctx->local->get_moveforward(); 50 | float move_strafe = ctx->local->get_movestrafe(); 51 | 52 | /// See if we're moving in a different direction (backwards) 53 | if (move_forward < 0.0f) 54 | yaw += 180.0f; 55 | 56 | float forward; 57 | 58 | /// Do some directional calculations for forwards and backwards 59 | if (move_forward < 0.0f) 60 | forward = -.5f; 61 | else if (move_forward > 0.0f) 62 | forward = .5f; 63 | else 64 | forward = 1.0f; 65 | 66 | /// Then accomodate for strafing as well 67 | if (move_strafe > 0.0f) 68 | yaw -= 90.0f * forward; 69 | else if (move_strafe < 0.0f) 70 | yaw += 90.0f * forward; 71 | 72 | yaw *= .017453292f; 73 | return yaw; 74 | } 75 | 76 | float get_speed(std::shared_ptr ctx) 77 | { 78 | auto velocity_vector = ctx->local->get_motion_vector(); 79 | 80 | return sqrt(velocity_vector.x * velocity_vector.x + velocity_vector.z * velocity_vector.z); 81 | } 82 | 83 | void set_speed(std::shared_ptr ctx, const float speed) 84 | { 85 | auto direction = get_direction(ctx); 86 | auto velocity_vector = ctx->local->get_motion_vector(); 87 | 88 | velocity_vector.x = -(sin(direction) * speed); 89 | velocity_vector.z = cos(direction) * speed; 90 | } 91 | -------------------------------------------------------------------------------- /main/gasper.cpp: -------------------------------------------------------------------------------- 1 | #include "gasper.h" 2 | 3 | #include "../sdk/minecraft/minecraft.h" 4 | #include "../sdk/minecraft/player/player.h" 5 | #include "../sdk/minecraft/world/world.h" 6 | 7 | #include "cheats/cheat.h" 8 | 9 | #include "cheats/impl/headers/aimbot.h" 10 | #include "cheats/impl/headers/reach.h" 11 | #include "cheats/impl/headers/strafe.h" 12 | 13 | 14 | jvmtiEnv* jvmti_env; 15 | 16 | /// Attach to the JVM 17 | bool gasper::c_gasper::attach() 18 | { 19 | auto jvm_dll = wrapper::get_module_handle(xorstr_("jvm.dll")); 20 | 21 | auto created_java_vms = reinterpret_cast(wrapper::get_proc_address(xorstr_("JNI_GetCreatedJavaVMs"), jvm_dll)); 22 | 23 | auto ret = created_java_vms(&vm, 1, nullptr); 24 | 25 | if (ret != JNI_OK) 26 | return false; 27 | 28 | ret = get_vm()->AttachCurrentThread(reinterpret_cast(&env), nullptr); 29 | 30 | if (ret != JNI_OK) 31 | return false; 32 | 33 | get_vm()->GetEnv(reinterpret_cast(&jvmti_env), JVMTI_VERSION_1_1); 34 | 35 | if (!jvmti_env) 36 | return false; 37 | 38 | /// Get the launchwrapper instance so that we can use findClass 39 | get_launchwrapper(); 40 | 41 | /// Hook our shizzle 42 | hook(); 43 | 44 | /// Now we can begin business 45 | b_running = true; 46 | 47 | return true; 48 | } 49 | 50 | void gasper::c_gasper::run() 51 | { 52 | /// Spawn an instance of our "SDK" 53 | sdk::instance = std::make_unique(); 54 | 55 | /// Spawn an instance of our "cheats" 56 | cheats::instance = std::make_unique(); 57 | 58 | /// Register all our cheats 59 | cheats::instance->register_function(aimbot::invoke); 60 | cheats::instance->register_function(reach::invoke); 61 | cheats::instance->register_function(strafe::invoke); 62 | 63 | //Give it a console for debugging purposes 64 | AllocConsole(); 65 | //Allow you to close the console without the host process closing too 66 | SetConsoleCtrlHandler(NULL, true); 67 | //Assign console in and out to pass to the create console rather than minecraft's 68 | FILE* fIn; 69 | FILE* fOut; 70 | freopen_s(&fIn, "conin$", "r", stdin); 71 | freopen_s(&fOut, "conout$", "w", stdout); 72 | freopen_s(&fOut, "conout$", "w", stderr); 73 | 74 | /// We better be running 75 | while (b_running) 76 | { 77 | /// "Self-destruct" button 78 | if (wrapper::get_async_keystate(VK_HOME)) 79 | b_running = false; 80 | 81 | /// Le epic flag for le epic modern C++ 82 | static std::once_flag flag; 83 | 84 | /// Keep references simple so that we can easily dispose of them later (they're all localref btw) 85 | /// but they last for one cycle of this thread so we shouldn't worry about them being accidentally destroyed suddenly 86 | auto minecraft_inst = sdk::instance->get_minecraft(); 87 | 88 | /// Notify of injection (this is for testing) 89 | /// Note to self: release mode currently contains pretty much the same debug info as debug config 90 | /// so if you want to sell this piece of shit you better change that or else you'll get crackalacked in a minute 91 | std::call_once(flag, [&]() { wrapper::show_message(xorstr_("Injected.")); }); 92 | 93 | /// NOTE: the player and world class already dispose of the references themselves 94 | auto local = std::make_shared(sdk::instance->get_player(minecraft_inst)); 95 | auto world = std::make_shared(sdk::instance->get_world(minecraft_inst)); 96 | 97 | cheats::instance->invoke(std::make_shared(local, world, !sdk::instance->get_current_screen(minecraft_inst), false)); 98 | 99 | /// Delete the reference 100 | get_env()->DeleteLocalRef(minecraft_inst); 101 | 102 | /// Let's save the CPU some processing powerz 103 | std::this_thread::sleep_for(std::chrono::milliseconds(5)); 104 | } 105 | } 106 | 107 | /// This is called when we're supposed to dispose of our mineman hackery 108 | void gasper::c_gasper::dispose() 109 | { 110 | get_env()->DeleteGlobalRef(classloader_obj); 111 | get_vm()->DetachCurrentThread(); 112 | 113 | ImGui_ImplOpenGL2_Shutdown(); 114 | wglDeleteContext(hooks::gl_context->m_glrenderctx); 115 | ImGui::DestroyContext(); 116 | ImGui_ImplWin32_Shutdown(); 117 | 118 | MH_DisableHook(MH_ALL_HOOKS); 119 | MH_Uninitialize(); 120 | 121 | SetWindowLongPtrA(wrapper::find_window(xorstr_("Minecraft 1.7.10")), GWLP_WNDPROC, (LONG_PTR)hooks::original_wndproc); 122 | 123 | env = nullptr; 124 | hooks::gl_context = nullptr; 125 | vm = nullptr; 126 | } 127 | 128 | void gasper::c_gasper::get_launchwrapper() 129 | { 130 | jclass launchwrapper_cls = get_env()->FindClass(xorstr_("net/minecraft/launchwrapper/LaunchClassLoader")); 131 | jclass launch_cls = get_env()->FindClass(xorstr_("net/minecraft/launchwrapper/Launch")); 132 | 133 | if (wrapper::handle_issue(xorstr_("launchwrapper"), launchwrapper_cls) || 134 | wrapper::handle_issue(xorstr_("launch_cls"), launch_cls)) 135 | std::exit(0); 136 | 137 | auto classloader_fid = get_env()->GetStaticFieldID(launch_cls, xorstr_("classLoader"), xorstr_("Lnet/minecraft/launchwrapper/LaunchClassLoader;")); 138 | 139 | findclass_md = get_env()->GetMethodID(launchwrapper_cls, xorstr_("findClass"), xorstr_("(Ljava/lang/String;)Ljava/lang/Class;")); 140 | classloader_obj = get_env()->NewGlobalRef(get_env()->GetStaticObjectField(launch_cls, classloader_fid)); 141 | 142 | get_env()->DeleteLocalRef(launchwrapper_cls); 143 | get_env()->DeleteLocalRef(launch_cls); 144 | } 145 | 146 | void gasper::c_gasper::hook() 147 | { 148 | MH_Initialize(); 149 | 150 | auto swap_buffers_ptr = wrapper::get_proc_address(xorstr_("SwapBuffers"), wrapper::get_module_handle(xorstr_("Gdi32.dll"))); 151 | 152 | MH_CreateHook(swap_buffers_ptr, hooks::swap_buffers_hk, reinterpret_cast(&hooks::oswap_buffers)); 153 | MH_EnableHook(MH_ALL_HOOKS); 154 | 155 | /// Set the WndProc 156 | hooks::original_wndproc = reinterpret_cast(SetWindowLongPtrA(wrapper::find_window (xorstr_("Minecraft 1.7.10")), GWLP_WNDPROC, reinterpret_cast(hooks::wndproc_hk))); 157 | } 158 | 159 | 160 | std::unique_ptr gasper::instance; -------------------------------------------------------------------------------- /main/gasper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../sdk/includes.h" 4 | 5 | namespace gasper { 6 | class c_gasper { 7 | private: 8 | JNIEnv* env; 9 | JavaVM* vm; 10 | 11 | jmethodID findclass_md; 12 | jobject classloader_obj; 13 | public: 14 | /// If we're still running 15 | bool b_running; 16 | 17 | /// If the menu is open 18 | bool b_open; 19 | 20 | /// Function to try and attach to the JVM 21 | bool attach(); 22 | 23 | /// Run the cheat 24 | void run(); 25 | 26 | /// Dispose of cheat 27 | void dispose(); 28 | 29 | /// Get the launchwrapper for forge support 30 | void get_launchwrapper(); 31 | 32 | /// Hook necessary functions 33 | void hook(); 34 | 35 | const auto get_env() { 36 | return env; 37 | } 38 | 39 | const auto get_vm() { 40 | return vm; 41 | } 42 | 43 | /// Inline function to get class 44 | inline jclass find_class(const char* name) { 45 | jstring jname = get_env()->NewStringUTF(name); 46 | 47 | jclass cls = reinterpret_cast(get_env()->CallObjectMethod(classloader_obj, findclass_md, jname)); 48 | 49 | get_env()->DeleteLocalRef(jname); 50 | 51 | wrapper::handle_issue(name, cls); 52 | 53 | return cls; 54 | } 55 | }; 56 | 57 | namespace hooks { 58 | /// Function template of SwapBuffers 59 | using swap_buffers_fn = int(__stdcall*)(HDC); 60 | 61 | /// Store pointer to the original SwapBuffers function 62 | inline swap_buffers_fn oswap_buffers = nullptr; 63 | 64 | /// Simple glcontext wrapper to make life easy 65 | extern std::shared_ptr gl_context; 66 | 67 | /// The actual hook 68 | int __stdcall swap_buffers_hk(HDC); 69 | 70 | /// Original WndProc of the Window we're hooking 71 | inline WNDPROC original_wndproc = nullptr; 72 | 73 | /// Actual "hook", this really isn't a hook but it's whatever 74 | long __stdcall wndproc_hk(const HWND hwnd, unsigned int usermsg, uintptr_t wparam, long lparam); 75 | } 76 | 77 | extern std::unique_ptr instance; 78 | } 79 | -------------------------------------------------------------------------------- /main/hooks/swap_buffers.cpp: -------------------------------------------------------------------------------- 1 | #include "../gasper.h" 2 | 3 | /// Include cheats for settings 4 | #include "../cheats/impl/headers/reach.h" 5 | #include "../cheats/impl/headers/aimbot.h" 6 | #include "../cheats/impl/headers/strafe.h" 7 | 8 | /// Context 9 | std::shared_ptr gasper::hooks::gl_context = nullptr; 10 | 11 | /// Flag for initializing ImGui 12 | std::once_flag flag; 13 | 14 | /// Set our colors 15 | void set_colors(); 16 | 17 | /// Our le epic swap_buffers hook :) 18 | /// NOTE: This is "stream" proof, but flickers. You can fix this by modifying the buffer. 19 | int __stdcall gasper::hooks::swap_buffers_hk(HDC hdc) { 20 | 21 | /// Le retardation has arrived 22 | static auto mc_window = wrapper::find_window(xorstr_("Minecraft 1.7.10")); 23 | auto window_rect = wrapper::get_window_rect(xorstr_("Minecraft 1.7.10")); 24 | 25 | /// std::call_once because we're hip 26 | std::call_once(flag, [&]() { 27 | gl_context = wrapper::create_gl_context(); 28 | ImGui::CreateContext(); 29 | set_colors(); 30 | ImGui_ImplWin32_Init(mc_window); 31 | ImGui_ImplOpenGL2_Init(); 32 | return gasper::hooks::oswap_buffers(hdc); 33 | }); 34 | 35 | /// if for some reason our instance is nullptr'd or we aren't running anymore but this hook still is 36 | /// make sure to dip 37 | if (!gasper::instance || !gasper::instance->b_running) 38 | return gasper::hooks::oswap_buffers(hdc); 39 | 40 | /// Switch to our context 41 | wglMakeCurrent(gl_context->m_hdc_devicectx, gl_context->m_glrenderctx); 42 | 43 | /// If our menu is open why don't we draw 44 | /// NOTE: If it's according to phage, a 0fps dip when rendering the menu is too compromising 45 | /// which is frankly the funniest shit I've read in a while. 46 | if (gasper::instance->b_open) 47 | { 48 | ImGuiIO& io = ImGui::GetIO(); 49 | io.MouseDrawCursor = true; 50 | 51 | ImGui_ImplOpenGL2_NewFrame(); 52 | ImGui_ImplWin32_NewFrame(); 53 | ImGui::NewFrame(); 54 | 55 | ImGui::Begin(xorstr_("Gasper C++"), nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize); 56 | 57 | ImGui::Checkbox(xorstr_("Reach enabled"), &reach::m_enabled); 58 | ImGui::SliderFloat(xorstr_("Distance"), &reach::m_reach, 0.0f, 1.5f, xorstr_("%.1f")); 59 | ImGui::Checkbox(xorstr_("AimAssist enabled"), &aimbot::m_enabled); 60 | ImGui::SliderFloat(xorstr_("Speed"), &aimbot::m_speed, 1.0f, 10.0f, xorstr_("%.1f")); 61 | ImGui::SliderFloat(xorstr_("Speed on Body"), &aimbot::m_speed_body, 1.0f, 10.0f, xorstr_("%.1f")); 62 | ImGui::SliderFloat(xorstr_("FOV"), &aimbot::m_fov, 10.0f, 90.0f, xorstr_("%.1f")); 63 | ImGui::Checkbox(xorstr_("Strafe"), &strafe::m_enabled); 64 | 65 | ImGui::End(); 66 | 67 | ImGui::Render(); 68 | glViewport(0, 0, window_rect.right, window_rect.top); 69 | ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()); 70 | } 71 | 72 | ImGuiIO& io = ImGui::GetIO(); 73 | io.MouseDrawCursor = false; 74 | 75 | /// Switch back 76 | wglMakeCurrent(gl_context->m_hdc_devicectx, gl_context->m_oglrenderctx); 77 | 78 | /// Call original and dip 79 | return gasper::hooks::oswap_buffers(hdc); 80 | } 81 | 82 | void set_colors() 83 | { 84 | ImColor mainColor = ImColor(int(15), int(135), int(105), 255); 85 | ImColor bodyColor = ImColor(int(24), int(24), int(24), 255); 86 | ImColor fontColor = ImColor(int(255), int(255), int(255), 255); 87 | 88 | ImGuiStyle& style = ImGui::GetStyle(); 89 | 90 | ImVec4 mainColorHovered = ImVec4(mainColor.Value.x + 0.1f, mainColor.Value.y + 0.1f, mainColor.Value.z + 0.1f, mainColor.Value.w); 91 | ImVec4 mainColorActive = ImVec4(mainColor.Value.x + 0.2f, mainColor.Value.y + 0.2f, mainColor.Value.z + 0.2f, mainColor.Value.w); 92 | ImVec4 menubarColor = ImVec4(bodyColor.Value.x, bodyColor.Value.y, bodyColor.Value.z, bodyColor.Value.w - 0.8f); 93 | ImVec4 frameBgColor = ImVec4(bodyColor.Value.x + 0.1f, bodyColor.Value.y + 0.1f, bodyColor.Value.z + 0.1f, bodyColor.Value.w + .1f); 94 | ImVec4 tooltipBgColor = ImVec4(bodyColor.Value.x, bodyColor.Value.y, bodyColor.Value.z, bodyColor.Value.w + .05f); 95 | 96 | style.Alpha = 1.0f; 97 | style.WindowPadding = ImVec2(8, 8); 98 | style.WindowMinSize = ImVec2(32, 32); 99 | style.WindowRounding = 0.0f; 100 | style.WindowTitleAlign = ImVec2(0.5f, 0.5f); 101 | style.ChildRounding = 0.0f; 102 | style.FramePadding = ImVec2(4, 3); 103 | style.FrameRounding = 2.0f; 104 | style.ItemSpacing = ImVec2(4, 3); 105 | style.ItemInnerSpacing = ImVec2(4, 4); 106 | style.TouchExtraPadding = ImVec2(0, 0); 107 | style.IndentSpacing = 21.0f; 108 | style.ColumnsMinSpacing = 3.0f; 109 | style.ScrollbarSize = 8.f; 110 | style.ScrollbarRounding = 0.0f; 111 | style.GrabMinSize = 1.0f; 112 | style.GrabRounding = 0.0f; 113 | style.ButtonTextAlign = ImVec2(0.5f, 0.5f); 114 | style.DisplayWindowPadding = ImVec2(22, 22); 115 | style.DisplaySafeAreaPadding = ImVec2(4, 4); 116 | style.AntiAliasedLines = true; 117 | style.CurveTessellationTol = 1.25f; 118 | 119 | style.Colors[ImGuiCol_Text] = fontColor; 120 | 121 | style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.24f, 0.23f, 0.29f, 1.00f); 122 | style.Colors[ImGuiCol_WindowBg] = bodyColor; 123 | style.Colors[ImGuiCol_ChildBg] = ImVec4(.0f, .0f, .0f, .0f); 124 | style.Colors[ImGuiCol_PopupBg] = tooltipBgColor; 125 | style.Colors[ImGuiCol_Border] = ImColor(200, 200, 200, 220); 126 | style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.92f, 0.91f, 0.88f, 0.00f); 127 | style.Colors[ImGuiCol_FrameBg] = frameBgColor; 128 | style.Colors[ImGuiCol_FrameBgHovered] = mainColorHovered; 129 | style.Colors[ImGuiCol_FrameBgActive] = mainColorActive; 130 | style.Colors[ImGuiCol_TitleBg] = mainColor; 131 | style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 0.98f, 0.95f, 0.75f); 132 | style.Colors[ImGuiCol_TitleBgActive] = mainColor; 133 | style.Colors[ImGuiCol_MenuBarBg] = menubarColor; 134 | style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(frameBgColor.x + .05f, frameBgColor.y + .05f, frameBgColor.z + .05f, frameBgColor.w); 135 | style.Colors[ImGuiCol_ScrollbarGrab] = mainColor; 136 | style.Colors[ImGuiCol_ScrollbarGrabHovered] = mainColorHovered; 137 | style.Colors[ImGuiCol_ScrollbarGrabActive] = mainColorActive; 138 | style.Colors[ImGuiCol_CheckMark] = mainColor; 139 | style.Colors[ImGuiCol_SliderGrab] = mainColorHovered; 140 | style.Colors[ImGuiCol_SliderGrabActive] = mainColorActive; 141 | style.Colors[ImGuiCol_Button] = mainColor; 142 | style.Colors[ImGuiCol_ButtonHovered] = mainColorHovered; 143 | style.Colors[ImGuiCol_ButtonActive] = mainColorActive; 144 | style.Colors[ImGuiCol_Header] = mainColor; 145 | style.Colors[ImGuiCol_HeaderHovered] = mainColorHovered; 146 | style.Colors[ImGuiCol_HeaderActive] = mainColorActive; 147 | 148 | 149 | style.Colors[ImGuiCol_ResizeGrip] = mainColor; 150 | style.Colors[ImGuiCol_ResizeGripHovered] = mainColorHovered; 151 | style.Colors[ImGuiCol_ResizeGripActive] = mainColorActive; 152 | style.Colors[ImGuiCol_PlotLines] = mainColor; 153 | style.Colors[ImGuiCol_PlotLinesHovered] = mainColorHovered; 154 | style.Colors[ImGuiCol_PlotHistogram] = mainColor; 155 | style.Colors[ImGuiCol_PlotHistogramHovered] = mainColorHovered; 156 | style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.25f, 1.00f, 0.00f, 0.43f); 157 | style.Colors[ImGuiCol_ModalWindowDarkening] = ImVec4(1.00f, 0.98f, 0.95f, 0.73f); 158 | } 159 | -------------------------------------------------------------------------------- /main/hooks/wndproc.cpp: -------------------------------------------------------------------------------- 1 | #include "../gasper.h" 2 | 3 | /// Stole this one off of the DirectX example. 4 | LRESULT imgui_wndproc(HWND, UINT msg, WPARAM wParam, LPARAM lParam) 5 | { 6 | ImGuiIO& io = ImGui::GetIO(); 7 | switch (msg) { 8 | case WM_LBUTTONDOWN: 9 | io.MouseDown[0] = true; 10 | return true; 11 | case WM_LBUTTONUP: 12 | io.MouseDown[0] = false; 13 | return true; 14 | case WM_RBUTTONDOWN: 15 | io.MouseDown[1] = true; 16 | return true; 17 | case WM_RBUTTONUP: 18 | io.MouseDown[1] = false; 19 | return true; 20 | case WM_MBUTTONDOWN: 21 | io.MouseDown[2] = true; 22 | return true; 23 | case WM_MBUTTONUP: 24 | io.MouseDown[2] = false; 25 | return true; 26 | case WM_XBUTTONDOWN: 27 | if ((GET_KEYSTATE_WPARAM(wParam) & MK_XBUTTON1) == MK_XBUTTON1) 28 | io.MouseDown[3] = true; 29 | else if ((GET_KEYSTATE_WPARAM(wParam) & MK_XBUTTON2) == MK_XBUTTON2) 30 | io.MouseDown[4] = true; 31 | return true; 32 | case WM_XBUTTONUP: 33 | if ((GET_KEYSTATE_WPARAM(wParam) & MK_XBUTTON1) == MK_XBUTTON1) 34 | io.MouseDown[3] = false; 35 | else if ((GET_KEYSTATE_WPARAM(wParam) & MK_XBUTTON2) == MK_XBUTTON2) 36 | io.MouseDown[4] = false; 37 | return true; 38 | case WM_MOUSEWHEEL: 39 | io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; 40 | return true; 41 | case WM_MOUSEMOVE: 42 | io.MousePos.x = (signed short)(lParam); 43 | io.MousePos.y = (signed short)(lParam >> 16); 44 | return true; 45 | case WM_KEYDOWN: 46 | if (wParam < 256) 47 | io.KeysDown[wParam] = 1; 48 | return true; 49 | case WM_KEYUP: 50 | if (wParam < 256) 51 | io.KeysDown[wParam] = 0; 52 | return true; 53 | case WM_CHAR: 54 | if (wParam > 0 && wParam < 0x10000) 55 | io.AddInputCharacter((unsigned short)wParam); 56 | return true; 57 | } 58 | return 0; 59 | } 60 | 61 | long __stdcall gasper::hooks::wndproc_hk(const HWND hwnd, unsigned int usermsg, uintptr_t wparam, long lparam) 62 | { 63 | if (WM_KEYDOWN == usermsg) 64 | if (wparam == VK_UP) 65 | gasper::instance->b_open = !gasper::instance->b_open; 66 | 67 | if (gasper::instance->b_open && imgui_wndproc(hwnd, usermsg, wparam, lparam)) 68 | return 1l; 69 | 70 | return CallWindowProcA(hooks::original_wndproc, hwnd, usermsg, wparam, lparam); 71 | } 72 | -------------------------------------------------------------------------------- /sdk/hook/MinHook.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2017 Tsuda Kageyu. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 20 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__) 32 | #error MinHook supports only x86 and x64 systems. 33 | #endif 34 | 35 | #include 36 | 37 | // MinHook Error Codes. 38 | typedef enum MH_STATUS 39 | { 40 | // Unknown error. Should not be returned. 41 | MH_UNKNOWN = -1, 42 | 43 | // Successful. 44 | MH_OK = 0, 45 | 46 | // MinHook is already initialized. 47 | MH_ERROR_ALREADY_INITIALIZED, 48 | 49 | // MinHook is not initialized yet, or already uninitialized. 50 | MH_ERROR_NOT_INITIALIZED, 51 | 52 | // The hook for the specified target function is already created. 53 | MH_ERROR_ALREADY_CREATED, 54 | 55 | // The hook for the specified target function is not created yet. 56 | MH_ERROR_NOT_CREATED, 57 | 58 | // The hook for the specified target function is already enabled. 59 | MH_ERROR_ENABLED, 60 | 61 | // The hook for the specified target function is not enabled yet, or already 62 | // disabled. 63 | MH_ERROR_DISABLED, 64 | 65 | // The specified pointer is invalid. It points the address of non-allocated 66 | // and/or non-executable region. 67 | MH_ERROR_NOT_EXECUTABLE, 68 | 69 | // The specified target function cannot be hooked. 70 | MH_ERROR_UNSUPPORTED_FUNCTION, 71 | 72 | // Failed to allocate memory. 73 | MH_ERROR_MEMORY_ALLOC, 74 | 75 | // Failed to change the memory protection. 76 | MH_ERROR_MEMORY_PROTECT, 77 | 78 | // The specified module is not loaded. 79 | MH_ERROR_MODULE_NOT_FOUND, 80 | 81 | // The specified function is not found. 82 | MH_ERROR_FUNCTION_NOT_FOUND 83 | } 84 | MH_STATUS; 85 | 86 | // Can be passed as a parameter to MH_EnableHook, MH_DisableHook, 87 | // MH_QueueEnableHook or MH_QueueDisableHook. 88 | #define MH_ALL_HOOKS NULL 89 | 90 | #ifdef __cplusplus 91 | extern "C" { 92 | #endif 93 | 94 | // Initialize the MinHook library. You must call this function EXACTLY ONCE 95 | // at the beginning of your program. 96 | MH_STATUS WINAPI MH_Initialize(VOID); 97 | 98 | // Uninitialize the MinHook library. You must call this function EXACTLY 99 | // ONCE at the end of your program. 100 | MH_STATUS WINAPI MH_Uninitialize(VOID); 101 | 102 | // Creates a Hook for the specified target function, in disabled state. 103 | // Parameters: 104 | // pTarget [in] A pointer to the target function, which will be 105 | // overridden by the detour function. 106 | // pDetour [in] A pointer to the detour function, which will override 107 | // the target function. 108 | // ppOriginal [out] A pointer to the trampoline function, which will be 109 | // used to call the original target function. 110 | // This parameter can be NULL. 111 | MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal); 112 | 113 | // Creates a Hook for the specified API function, in disabled state. 114 | // Parameters: 115 | // pszModule [in] A pointer to the loaded module name which contains the 116 | // target function. 117 | // pszTarget [in] A pointer to the target function name, which will be 118 | // overridden by the detour function. 119 | // pDetour [in] A pointer to the detour function, which will override 120 | // the target function. 121 | // ppOriginal [out] A pointer to the trampoline function, which will be 122 | // used to call the original target function. 123 | // This parameter can be NULL. 124 | MH_STATUS WINAPI MH_CreateHookApi( 125 | LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal); 126 | 127 | // Creates a Hook for the specified API function, in disabled state. 128 | // Parameters: 129 | // pszModule [in] A pointer to the loaded module name which contains the 130 | // target function. 131 | // pszTarget [in] A pointer to the target function name, which will be 132 | // overridden by the detour function. 133 | // pDetour [in] A pointer to the detour function, which will override 134 | // the target function. 135 | // ppOriginal [out] A pointer to the trampoline function, which will be 136 | // used to call the original target function. 137 | // This parameter can be NULL. 138 | // ppTarget [out] A pointer to the target function, which will be used 139 | // with other functions. 140 | // This parameter can be NULL. 141 | MH_STATUS WINAPI MH_CreateHookApiEx( 142 | LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget); 143 | 144 | // Removes an already created hook. 145 | // Parameters: 146 | // pTarget [in] A pointer to the target function. 147 | MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget); 148 | 149 | // Enables an already created hook. 150 | // Parameters: 151 | // pTarget [in] A pointer to the target function. 152 | // If this parameter is MH_ALL_HOOKS, all created hooks are 153 | // enabled in one go. 154 | MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget); 155 | 156 | // Disables an already created hook. 157 | // Parameters: 158 | // pTarget [in] A pointer to the target function. 159 | // If this parameter is MH_ALL_HOOKS, all created hooks are 160 | // disabled in one go. 161 | MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget); 162 | 163 | // Queues to enable an already created hook. 164 | // Parameters: 165 | // pTarget [in] A pointer to the target function. 166 | // If this parameter is MH_ALL_HOOKS, all created hooks are 167 | // queued to be enabled. 168 | MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget); 169 | 170 | // Queues to disable an already created hook. 171 | // Parameters: 172 | // pTarget [in] A pointer to the target function. 173 | // If this parameter is MH_ALL_HOOKS, all created hooks are 174 | // queued to be disabled. 175 | MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget); 176 | 177 | // Applies all queued changes in one go. 178 | MH_STATUS WINAPI MH_ApplyQueued(VOID); 179 | 180 | // Translates the MH_STATUS to its name as a string. 181 | const char * WINAPI MH_StatusToString(MH_STATUS status); 182 | 183 | #ifdef __cplusplus 184 | } 185 | #endif 186 | 187 | -------------------------------------------------------------------------------- /sdk/hook/buffer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2017 Tsuda Kageyu. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 20 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | #include "buffer.h" 31 | 32 | // Size of each memory block. (= page size of VirtualAlloc) 33 | #define MEMORY_BLOCK_SIZE 0x1000 34 | 35 | // Max range for seeking a memory block. (= 1024MB) 36 | #define MAX_MEMORY_RANGE 0x40000000 37 | 38 | // Memory protection flags to check the executable address. 39 | #define PAGE_EXECUTE_FLAGS \ 40 | (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) 41 | 42 | // Memory slot. 43 | typedef struct _MEMORY_SLOT 44 | { 45 | union 46 | { 47 | struct _MEMORY_SLOT *pNext; 48 | UINT8 buffer[MEMORY_SLOT_SIZE]; 49 | }; 50 | } MEMORY_SLOT, *PMEMORY_SLOT; 51 | 52 | // Memory block info. Placed at the head of each block. 53 | typedef struct _MEMORY_BLOCK 54 | { 55 | struct _MEMORY_BLOCK *pNext; 56 | PMEMORY_SLOT pFree; // First element of the free slot list. 57 | UINT usedCount; 58 | } MEMORY_BLOCK, *PMEMORY_BLOCK; 59 | 60 | //------------------------------------------------------------------------- 61 | // Global Variables: 62 | //------------------------------------------------------------------------- 63 | 64 | // First element of the memory block list. 65 | PMEMORY_BLOCK g_pMemoryBlocks; 66 | 67 | //------------------------------------------------------------------------- 68 | VOID InitializeBuffer(VOID) 69 | { 70 | // Nothing to do for now. 71 | } 72 | 73 | //------------------------------------------------------------------------- 74 | VOID UninitializeBuffer(VOID) 75 | { 76 | PMEMORY_BLOCK pBlock = g_pMemoryBlocks; 77 | g_pMemoryBlocks = NULL; 78 | 79 | while (pBlock) 80 | { 81 | PMEMORY_BLOCK pNext = pBlock->pNext; 82 | VirtualFree(pBlock, 0, MEM_RELEASE); 83 | pBlock = pNext; 84 | } 85 | } 86 | 87 | //------------------------------------------------------------------------- 88 | #if defined(_M_X64) || defined(__x86_64__) 89 | static LPVOID FindPrevFreeRegion(LPVOID pAddress, LPVOID pMinAddr, DWORD dwAllocationGranularity) 90 | { 91 | ULONG_PTR tryAddr = (ULONG_PTR)pAddress; 92 | 93 | // Round down to the allocation granularity. 94 | tryAddr -= tryAddr % dwAllocationGranularity; 95 | 96 | // Start from the previous allocation granularity multiply. 97 | tryAddr -= dwAllocationGranularity; 98 | 99 | while (tryAddr >= (ULONG_PTR)pMinAddr) 100 | { 101 | MEMORY_BASIC_INFORMATION mbi; 102 | if (VirtualQuery((LPVOID)tryAddr, &mbi, sizeof(mbi)) == 0) 103 | break; 104 | 105 | if (mbi.State == MEM_FREE) 106 | return (LPVOID)tryAddr; 107 | 108 | if ((ULONG_PTR)mbi.AllocationBase < dwAllocationGranularity) 109 | break; 110 | 111 | tryAddr = (ULONG_PTR)mbi.AllocationBase - dwAllocationGranularity; 112 | } 113 | 114 | return NULL; 115 | } 116 | #endif 117 | 118 | //------------------------------------------------------------------------- 119 | #if defined(_M_X64) || defined(__x86_64__) 120 | static LPVOID FindNextFreeRegion(LPVOID pAddress, LPVOID pMaxAddr, DWORD dwAllocationGranularity) 121 | { 122 | ULONG_PTR tryAddr = (ULONG_PTR)pAddress; 123 | 124 | // Round down to the allocation granularity. 125 | tryAddr -= tryAddr % dwAllocationGranularity; 126 | 127 | // Start from the next allocation granularity multiply. 128 | tryAddr += dwAllocationGranularity; 129 | 130 | while (tryAddr <= (ULONG_PTR)pMaxAddr) 131 | { 132 | MEMORY_BASIC_INFORMATION mbi; 133 | if (VirtualQuery((LPVOID)tryAddr, &mbi, sizeof(mbi)) == 0) 134 | break; 135 | 136 | if (mbi.State == MEM_FREE) 137 | return (LPVOID)tryAddr; 138 | 139 | tryAddr = (ULONG_PTR)mbi.BaseAddress + mbi.RegionSize; 140 | 141 | // Round up to the next allocation granularity. 142 | tryAddr += dwAllocationGranularity - 1; 143 | tryAddr -= tryAddr % dwAllocationGranularity; 144 | } 145 | 146 | return NULL; 147 | } 148 | #endif 149 | 150 | //------------------------------------------------------------------------- 151 | static PMEMORY_BLOCK GetMemoryBlock(LPVOID pOrigin) 152 | { 153 | PMEMORY_BLOCK pBlock; 154 | #if defined(_M_X64) || defined(__x86_64__) 155 | ULONG_PTR minAddr; 156 | ULONG_PTR maxAddr; 157 | 158 | SYSTEM_INFO si; 159 | GetSystemInfo(&si); 160 | minAddr = (ULONG_PTR)si.lpMinimumApplicationAddress; 161 | maxAddr = (ULONG_PTR)si.lpMaximumApplicationAddress; 162 | 163 | // pOrigin ± 512MB 164 | if ((ULONG_PTR)pOrigin > MAX_MEMORY_RANGE && minAddr < (ULONG_PTR)pOrigin - MAX_MEMORY_RANGE) 165 | minAddr = (ULONG_PTR)pOrigin - MAX_MEMORY_RANGE; 166 | 167 | if (maxAddr > (ULONG_PTR)pOrigin + MAX_MEMORY_RANGE) 168 | maxAddr = (ULONG_PTR)pOrigin + MAX_MEMORY_RANGE; 169 | 170 | // Make room for MEMORY_BLOCK_SIZE bytes. 171 | maxAddr -= MEMORY_BLOCK_SIZE - 1; 172 | #endif 173 | 174 | // Look the registered blocks for a reachable one. 175 | for (pBlock = g_pMemoryBlocks; pBlock != NULL; pBlock = pBlock->pNext) 176 | { 177 | #if defined(_M_X64) || defined(__x86_64__) 178 | // Ignore the blocks too far. 179 | if ((ULONG_PTR)pBlock < minAddr || (ULONG_PTR)pBlock >= maxAddr) 180 | continue; 181 | #endif 182 | // The block has at least one unused slot. 183 | if (pBlock->pFree != NULL) 184 | return pBlock; 185 | } 186 | 187 | #if defined(_M_X64) || defined(__x86_64__) 188 | // Alloc a new block above if not found. 189 | { 190 | LPVOID pAlloc = pOrigin; 191 | while ((ULONG_PTR)pAlloc >= minAddr) 192 | { 193 | pAlloc = FindPrevFreeRegion(pAlloc, (LPVOID)minAddr, si.dwAllocationGranularity); 194 | if (pAlloc == NULL) 195 | break; 196 | 197 | pBlock = (PMEMORY_BLOCK)VirtualAlloc( 198 | pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 199 | if (pBlock != NULL) 200 | break; 201 | } 202 | } 203 | 204 | // Alloc a new block below if not found. 205 | if (pBlock == NULL) 206 | { 207 | LPVOID pAlloc = pOrigin; 208 | while ((ULONG_PTR)pAlloc <= maxAddr) 209 | { 210 | pAlloc = FindNextFreeRegion(pAlloc, (LPVOID)maxAddr, si.dwAllocationGranularity); 211 | if (pAlloc == NULL) 212 | break; 213 | 214 | pBlock = (PMEMORY_BLOCK)VirtualAlloc( 215 | pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 216 | if (pBlock != NULL) 217 | break; 218 | } 219 | } 220 | #else 221 | // In x86 mode, a memory block can be placed anywhere. 222 | pBlock = (PMEMORY_BLOCK)VirtualAlloc( 223 | NULL, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 224 | #endif 225 | 226 | if (pBlock != NULL) 227 | { 228 | // Build a linked list of all the slots. 229 | PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBlock + 1; 230 | pBlock->pFree = NULL; 231 | pBlock->usedCount = 0; 232 | do 233 | { 234 | pSlot->pNext = pBlock->pFree; 235 | pBlock->pFree = pSlot; 236 | pSlot++; 237 | } while ((ULONG_PTR)pSlot - (ULONG_PTR)pBlock <= MEMORY_BLOCK_SIZE - MEMORY_SLOT_SIZE); 238 | 239 | pBlock->pNext = g_pMemoryBlocks; 240 | g_pMemoryBlocks = pBlock; 241 | } 242 | 243 | return pBlock; 244 | } 245 | 246 | //------------------------------------------------------------------------- 247 | LPVOID AllocateBuffer(LPVOID pOrigin) 248 | { 249 | PMEMORY_SLOT pSlot; 250 | PMEMORY_BLOCK pBlock = GetMemoryBlock(pOrigin); 251 | if (pBlock == NULL) 252 | return NULL; 253 | 254 | // Remove an unused slot from the list. 255 | pSlot = pBlock->pFree; 256 | pBlock->pFree = pSlot->pNext; 257 | pBlock->usedCount++; 258 | #ifdef _DEBUG 259 | // Fill the slot with INT3 for debugging. 260 | memset(pSlot, 0xCC, sizeof(MEMORY_SLOT)); 261 | #endif 262 | return pSlot; 263 | } 264 | 265 | //------------------------------------------------------------------------- 266 | VOID FreeBuffer(LPVOID pBuffer) 267 | { 268 | PMEMORY_BLOCK pBlock = g_pMemoryBlocks; 269 | PMEMORY_BLOCK pPrev = NULL; 270 | ULONG_PTR pTargetBlock = ((ULONG_PTR)pBuffer / MEMORY_BLOCK_SIZE) * MEMORY_BLOCK_SIZE; 271 | 272 | while (pBlock != NULL) 273 | { 274 | if ((ULONG_PTR)pBlock == pTargetBlock) 275 | { 276 | PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBuffer; 277 | #ifdef _DEBUG 278 | // Clear the released slot for debugging. 279 | memset(pSlot, 0x00, sizeof(*pSlot)); 280 | #endif 281 | // Restore the released slot to the list. 282 | pSlot->pNext = pBlock->pFree; 283 | pBlock->pFree = pSlot; 284 | pBlock->usedCount--; 285 | 286 | // Free if unused. 287 | if (pBlock->usedCount == 0) 288 | { 289 | if (pPrev) 290 | pPrev->pNext = pBlock->pNext; 291 | else 292 | g_pMemoryBlocks = pBlock->pNext; 293 | 294 | VirtualFree(pBlock, 0, MEM_RELEASE); 295 | } 296 | 297 | break; 298 | } 299 | 300 | pPrev = pBlock; 301 | pBlock = pBlock->pNext; 302 | } 303 | } 304 | 305 | //------------------------------------------------------------------------- 306 | BOOL IsExecutableAddress(LPVOID pAddress) 307 | { 308 | MEMORY_BASIC_INFORMATION mi; 309 | VirtualQuery(pAddress, &mi, sizeof(mi)); 310 | 311 | return (mi.State == MEM_COMMIT && (mi.Protect & PAGE_EXECUTE_FLAGS)); 312 | } 313 | -------------------------------------------------------------------------------- /sdk/hook/buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2017 Tsuda Kageyu. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 20 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | // Size of each memory slot. 32 | #if defined(_M_X64) || defined(__x86_64__) 33 | #define MEMORY_SLOT_SIZE 64 34 | #else 35 | #define MEMORY_SLOT_SIZE 32 36 | #endif 37 | 38 | VOID InitializeBuffer(VOID); 39 | VOID UninitializeBuffer(VOID); 40 | LPVOID AllocateBuffer(LPVOID pOrigin); 41 | VOID FreeBuffer(LPVOID pBuffer); 42 | BOOL IsExecutableAddress(LPVOID pAddress); 43 | -------------------------------------------------------------------------------- /sdk/hook/hde/hde32.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 32 C 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | */ 7 | 8 | #if defined(_M_IX86) || defined(__i386__) 9 | 10 | #include "hde32.h" 11 | #include "table32.h" 12 | 13 | unsigned int hde32_disasm(const void *code, hde32s *hs) 14 | { 15 | uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; 16 | uint8_t *ht = hde32_table, m_mod, m_reg, m_rm, disp_size = 0; 17 | 18 | // Avoid using memset to reduce the footprint. 19 | #ifndef _MSC_VER 20 | memset((LPBYTE)hs, 0, sizeof(hde32s)); 21 | #else 22 | __stosb((LPBYTE)hs, 0, sizeof(hde32s)); 23 | #endif 24 | 25 | for (x = 16; x; x--) 26 | switch (c = *p++) { 27 | case 0xf3: 28 | hs->p_rep = c; 29 | pref |= PRE_F3; 30 | break; 31 | case 0xf2: 32 | hs->p_rep = c; 33 | pref |= PRE_F2; 34 | break; 35 | case 0xf0: 36 | hs->p_lock = c; 37 | pref |= PRE_LOCK; 38 | break; 39 | case 0x26: case 0x2e: case 0x36: 40 | case 0x3e: case 0x64: case 0x65: 41 | hs->p_seg = c; 42 | pref |= PRE_SEG; 43 | break; 44 | case 0x66: 45 | hs->p_66 = c; 46 | pref |= PRE_66; 47 | break; 48 | case 0x67: 49 | hs->p_67 = c; 50 | pref |= PRE_67; 51 | break; 52 | default: 53 | goto pref_done; 54 | } 55 | pref_done: 56 | 57 | hs->flags = (uint32_t)pref << 23; 58 | 59 | if (!pref) 60 | pref |= PRE_NONE; 61 | 62 | if ((hs->opcode = c) == 0x0f) { 63 | hs->opcode2 = c = *p++; 64 | ht += DELTA_OPCODES; 65 | } else if (c >= 0xa0 && c <= 0xa3) { 66 | if (pref & PRE_67) 67 | pref |= PRE_66; 68 | else 69 | pref &= ~PRE_66; 70 | } 71 | 72 | opcode = c; 73 | cflags = ht[ht[opcode / 4] + (opcode % 4)]; 74 | 75 | if (cflags == C_ERROR) { 76 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 77 | cflags = 0; 78 | if ((opcode & -3) == 0x24) 79 | cflags++; 80 | } 81 | 82 | x = 0; 83 | if (cflags & C_GROUP) { 84 | uint16_t t; 85 | t = *(uint16_t *)(ht + (cflags & 0x7f)); 86 | cflags = (uint8_t)t; 87 | x = (uint8_t)(t >> 8); 88 | } 89 | 90 | if (hs->opcode2) { 91 | ht = hde32_table + DELTA_PREFIXES; 92 | if (ht[ht[opcode / 4] + (opcode % 4)] & pref) 93 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 94 | } 95 | 96 | if (cflags & C_MODRM) { 97 | hs->flags |= F_MODRM; 98 | hs->modrm = c = *p++; 99 | hs->modrm_mod = m_mod = c >> 6; 100 | hs->modrm_rm = m_rm = c & 7; 101 | hs->modrm_reg = m_reg = (c & 0x3f) >> 3; 102 | 103 | if (x && ((x << m_reg) & 0x80)) 104 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 105 | 106 | if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { 107 | uint8_t t = opcode - 0xd9; 108 | if (m_mod == 3) { 109 | ht = hde32_table + DELTA_FPU_MODRM + t*8; 110 | t = ht[m_reg] << m_rm; 111 | } else { 112 | ht = hde32_table + DELTA_FPU_REG; 113 | t = ht[t] << m_reg; 114 | } 115 | if (t & 0x80) 116 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 117 | } 118 | 119 | if (pref & PRE_LOCK) { 120 | if (m_mod == 3) { 121 | hs->flags |= F_ERROR | F_ERROR_LOCK; 122 | } else { 123 | uint8_t *table_end, op = opcode; 124 | if (hs->opcode2) { 125 | ht = hde32_table + DELTA_OP2_LOCK_OK; 126 | table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; 127 | } else { 128 | ht = hde32_table + DELTA_OP_LOCK_OK; 129 | table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; 130 | op &= -2; 131 | } 132 | for (; ht != table_end; ht++) 133 | if (*ht++ == op) { 134 | if (!((*ht << m_reg) & 0x80)) 135 | goto no_lock_error; 136 | else 137 | break; 138 | } 139 | hs->flags |= F_ERROR | F_ERROR_LOCK; 140 | no_lock_error: 141 | ; 142 | } 143 | } 144 | 145 | if (hs->opcode2) { 146 | switch (opcode) { 147 | case 0x20: case 0x22: 148 | m_mod = 3; 149 | if (m_reg > 4 || m_reg == 1) 150 | goto error_operand; 151 | else 152 | goto no_error_operand; 153 | case 0x21: case 0x23: 154 | m_mod = 3; 155 | if (m_reg == 4 || m_reg == 5) 156 | goto error_operand; 157 | else 158 | goto no_error_operand; 159 | } 160 | } else { 161 | switch (opcode) { 162 | case 0x8c: 163 | if (m_reg > 5) 164 | goto error_operand; 165 | else 166 | goto no_error_operand; 167 | case 0x8e: 168 | if (m_reg == 1 || m_reg > 5) 169 | goto error_operand; 170 | else 171 | goto no_error_operand; 172 | } 173 | } 174 | 175 | if (m_mod == 3) { 176 | uint8_t *table_end; 177 | if (hs->opcode2) { 178 | ht = hde32_table + DELTA_OP2_ONLY_MEM; 179 | table_end = ht + sizeof(hde32_table) - DELTA_OP2_ONLY_MEM; 180 | } else { 181 | ht = hde32_table + DELTA_OP_ONLY_MEM; 182 | table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; 183 | } 184 | for (; ht != table_end; ht += 2) 185 | if (*ht++ == opcode) { 186 | if (*ht++ & pref && !((*ht << m_reg) & 0x80)) 187 | goto error_operand; 188 | else 189 | break; 190 | } 191 | goto no_error_operand; 192 | } else if (hs->opcode2) { 193 | switch (opcode) { 194 | case 0x50: case 0xd7: case 0xf7: 195 | if (pref & (PRE_NONE | PRE_66)) 196 | goto error_operand; 197 | break; 198 | case 0xd6: 199 | if (pref & (PRE_F2 | PRE_F3)) 200 | goto error_operand; 201 | break; 202 | case 0xc5: 203 | goto error_operand; 204 | } 205 | goto no_error_operand; 206 | } else 207 | goto no_error_operand; 208 | 209 | error_operand: 210 | hs->flags |= F_ERROR | F_ERROR_OPERAND; 211 | no_error_operand: 212 | 213 | c = *p++; 214 | if (m_reg <= 1) { 215 | if (opcode == 0xf6) 216 | cflags |= C_IMM8; 217 | else if (opcode == 0xf7) 218 | cflags |= C_IMM_P66; 219 | } 220 | 221 | switch (m_mod) { 222 | case 0: 223 | if (pref & PRE_67) { 224 | if (m_rm == 6) 225 | disp_size = 2; 226 | } else 227 | if (m_rm == 5) 228 | disp_size = 4; 229 | break; 230 | case 1: 231 | disp_size = 1; 232 | break; 233 | case 2: 234 | disp_size = 2; 235 | if (!(pref & PRE_67)) 236 | disp_size <<= 1; 237 | } 238 | 239 | if (m_mod != 3 && m_rm == 4 && !(pref & PRE_67)) { 240 | hs->flags |= F_SIB; 241 | p++; 242 | hs->sib = c; 243 | hs->sib_scale = c >> 6; 244 | hs->sib_index = (c & 0x3f) >> 3; 245 | if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) 246 | disp_size = 4; 247 | } 248 | 249 | p--; 250 | switch (disp_size) { 251 | case 1: 252 | hs->flags |= F_DISP8; 253 | hs->disp.disp8 = *p; 254 | break; 255 | case 2: 256 | hs->flags |= F_DISP16; 257 | hs->disp.disp16 = *(uint16_t *)p; 258 | break; 259 | case 4: 260 | hs->flags |= F_DISP32; 261 | hs->disp.disp32 = *(uint32_t *)p; 262 | } 263 | p += disp_size; 264 | } else if (pref & PRE_LOCK) 265 | hs->flags |= F_ERROR | F_ERROR_LOCK; 266 | 267 | if (cflags & C_IMM_P66) { 268 | if (cflags & C_REL32) { 269 | if (pref & PRE_66) { 270 | hs->flags |= F_IMM16 | F_RELATIVE; 271 | hs->imm.imm16 = *(uint16_t *)p; 272 | p += 2; 273 | goto disasm_done; 274 | } 275 | goto rel32_ok; 276 | } 277 | if (pref & PRE_66) { 278 | hs->flags |= F_IMM16; 279 | hs->imm.imm16 = *(uint16_t *)p; 280 | p += 2; 281 | } else { 282 | hs->flags |= F_IMM32; 283 | hs->imm.imm32 = *(uint32_t *)p; 284 | p += 4; 285 | } 286 | } 287 | 288 | if (cflags & C_IMM16) { 289 | if (hs->flags & F_IMM32) { 290 | hs->flags |= F_IMM16; 291 | hs->disp.disp16 = *(uint16_t *)p; 292 | } else if (hs->flags & F_IMM16) { 293 | hs->flags |= F_2IMM16; 294 | hs->disp.disp16 = *(uint16_t *)p; 295 | } else { 296 | hs->flags |= F_IMM16; 297 | hs->imm.imm16 = *(uint16_t *)p; 298 | } 299 | p += 2; 300 | } 301 | if (cflags & C_IMM8) { 302 | hs->flags |= F_IMM8; 303 | hs->imm.imm8 = *p++; 304 | } 305 | 306 | if (cflags & C_REL32) { 307 | rel32_ok: 308 | hs->flags |= F_IMM32 | F_RELATIVE; 309 | hs->imm.imm32 = *(uint32_t *)p; 310 | p += 4; 311 | } else if (cflags & C_REL8) { 312 | hs->flags |= F_IMM8 | F_RELATIVE; 313 | hs->imm.imm8 = *p++; 314 | } 315 | 316 | disasm_done: 317 | 318 | if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) { 319 | hs->flags |= F_ERROR | F_ERROR_LENGTH; 320 | hs->len = 15; 321 | } 322 | 323 | return (unsigned int)hs->len; 324 | } 325 | 326 | #endif // defined(_M_IX86) || defined(__i386__) 327 | -------------------------------------------------------------------------------- /sdk/hook/hde/hde32.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 32 3 | * Copyright (c) 2006-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | * hde32.h: C/C++ header file 7 | * 8 | */ 9 | 10 | #ifndef _HDE32_H_ 11 | #define _HDE32_H_ 12 | 13 | /* stdint.h - C99 standard header 14 | * http://en.wikipedia.org/wiki/stdint.h 15 | * 16 | * if your compiler doesn't contain "stdint.h" header (for 17 | * example, Microsoft Visual C++), you can download file: 18 | * http://www.azillionmonkeys.com/qed/pstdint.h 19 | * and change next line to: 20 | * #include "pstdint.h" 21 | */ 22 | #include "pstdint.h" 23 | 24 | #define F_MODRM 0x00000001 25 | #define F_SIB 0x00000002 26 | #define F_IMM8 0x00000004 27 | #define F_IMM16 0x00000008 28 | #define F_IMM32 0x00000010 29 | #define F_DISP8 0x00000020 30 | #define F_DISP16 0x00000040 31 | #define F_DISP32 0x00000080 32 | #define F_RELATIVE 0x00000100 33 | #define F_2IMM16 0x00000800 34 | #define F_ERROR 0x00001000 35 | #define F_ERROR_OPCODE 0x00002000 36 | #define F_ERROR_LENGTH 0x00004000 37 | #define F_ERROR_LOCK 0x00008000 38 | #define F_ERROR_OPERAND 0x00010000 39 | #define F_PREFIX_REPNZ 0x01000000 40 | #define F_PREFIX_REPX 0x02000000 41 | #define F_PREFIX_REP 0x03000000 42 | #define F_PREFIX_66 0x04000000 43 | #define F_PREFIX_67 0x08000000 44 | #define F_PREFIX_LOCK 0x10000000 45 | #define F_PREFIX_SEG 0x20000000 46 | #define F_PREFIX_ANY 0x3f000000 47 | 48 | #define PREFIX_SEGMENT_CS 0x2e 49 | #define PREFIX_SEGMENT_SS 0x36 50 | #define PREFIX_SEGMENT_DS 0x3e 51 | #define PREFIX_SEGMENT_ES 0x26 52 | #define PREFIX_SEGMENT_FS 0x64 53 | #define PREFIX_SEGMENT_GS 0x65 54 | #define PREFIX_LOCK 0xf0 55 | #define PREFIX_REPNZ 0xf2 56 | #define PREFIX_REPX 0xf3 57 | #define PREFIX_OPERAND_SIZE 0x66 58 | #define PREFIX_ADDRESS_SIZE 0x67 59 | 60 | #pragma pack(push,1) 61 | 62 | typedef struct { 63 | uint8_t len; 64 | uint8_t p_rep; 65 | uint8_t p_lock; 66 | uint8_t p_seg; 67 | uint8_t p_66; 68 | uint8_t p_67; 69 | uint8_t opcode; 70 | uint8_t opcode2; 71 | uint8_t modrm; 72 | uint8_t modrm_mod; 73 | uint8_t modrm_reg; 74 | uint8_t modrm_rm; 75 | uint8_t sib; 76 | uint8_t sib_scale; 77 | uint8_t sib_index; 78 | uint8_t sib_base; 79 | union { 80 | uint8_t imm8; 81 | uint16_t imm16; 82 | uint32_t imm32; 83 | } imm; 84 | union { 85 | uint8_t disp8; 86 | uint16_t disp16; 87 | uint32_t disp32; 88 | } disp; 89 | uint32_t flags; 90 | } hde32s; 91 | 92 | #pragma pack(pop) 93 | 94 | #ifdef __cplusplus 95 | extern "C" { 96 | #endif 97 | 98 | /* __cdecl */ 99 | unsigned int hde32_disasm(const void *code, hde32s *hs); 100 | 101 | #ifdef __cplusplus 102 | } 103 | #endif 104 | 105 | #endif /* _HDE32_H_ */ 106 | -------------------------------------------------------------------------------- /sdk/hook/hde/hde64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 64 C 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | */ 7 | 8 | #if defined(_M_X64) || defined(__x86_64__) 9 | 10 | #include "hde64.h" 11 | #include "table64.h" 12 | 13 | unsigned int hde64_disasm(const void *code, hde64s *hs) 14 | { 15 | uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; 16 | uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0; 17 | uint8_t op64 = 0; 18 | 19 | // Avoid using memset to reduce the footprint. 20 | #ifndef _MSC_VER 21 | memset((LPBYTE)hs, 0, sizeof(hde64s)); 22 | #else 23 | __stosb((LPBYTE)hs, 0, sizeof(hde64s)); 24 | #endif 25 | 26 | for (x = 16; x; x--) 27 | switch (c = *p++) { 28 | case 0xf3: 29 | hs->p_rep = c; 30 | pref |= PRE_F3; 31 | break; 32 | case 0xf2: 33 | hs->p_rep = c; 34 | pref |= PRE_F2; 35 | break; 36 | case 0xf0: 37 | hs->p_lock = c; 38 | pref |= PRE_LOCK; 39 | break; 40 | case 0x26: case 0x2e: case 0x36: 41 | case 0x3e: case 0x64: case 0x65: 42 | hs->p_seg = c; 43 | pref |= PRE_SEG; 44 | break; 45 | case 0x66: 46 | hs->p_66 = c; 47 | pref |= PRE_66; 48 | break; 49 | case 0x67: 50 | hs->p_67 = c; 51 | pref |= PRE_67; 52 | break; 53 | default: 54 | goto pref_done; 55 | } 56 | pref_done: 57 | 58 | hs->flags = (uint32_t)pref << 23; 59 | 60 | if (!pref) 61 | pref |= PRE_NONE; 62 | 63 | if ((c & 0xf0) == 0x40) { 64 | hs->flags |= F_PREFIX_REX; 65 | if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8) 66 | op64++; 67 | hs->rex_r = (c & 7) >> 2; 68 | hs->rex_x = (c & 3) >> 1; 69 | hs->rex_b = c & 1; 70 | if (((c = *p++) & 0xf0) == 0x40) { 71 | opcode = c; 72 | goto error_opcode; 73 | } 74 | } 75 | 76 | if ((hs->opcode = c) == 0x0f) { 77 | hs->opcode2 = c = *p++; 78 | ht += DELTA_OPCODES; 79 | } else if (c >= 0xa0 && c <= 0xa3) { 80 | op64++; 81 | if (pref & PRE_67) 82 | pref |= PRE_66; 83 | else 84 | pref &= ~PRE_66; 85 | } 86 | 87 | opcode = c; 88 | cflags = ht[ht[opcode / 4] + (opcode % 4)]; 89 | 90 | if (cflags == C_ERROR) { 91 | error_opcode: 92 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 93 | cflags = 0; 94 | if ((opcode & -3) == 0x24) 95 | cflags++; 96 | } 97 | 98 | x = 0; 99 | if (cflags & C_GROUP) { 100 | uint16_t t; 101 | t = *(uint16_t *)(ht + (cflags & 0x7f)); 102 | cflags = (uint8_t)t; 103 | x = (uint8_t)(t >> 8); 104 | } 105 | 106 | if (hs->opcode2) { 107 | ht = hde64_table + DELTA_PREFIXES; 108 | if (ht[ht[opcode / 4] + (opcode % 4)] & pref) 109 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 110 | } 111 | 112 | if (cflags & C_MODRM) { 113 | hs->flags |= F_MODRM; 114 | hs->modrm = c = *p++; 115 | hs->modrm_mod = m_mod = c >> 6; 116 | hs->modrm_rm = m_rm = c & 7; 117 | hs->modrm_reg = m_reg = (c & 0x3f) >> 3; 118 | 119 | if (x && ((x << m_reg) & 0x80)) 120 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 121 | 122 | if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { 123 | uint8_t t = opcode - 0xd9; 124 | if (m_mod == 3) { 125 | ht = hde64_table + DELTA_FPU_MODRM + t*8; 126 | t = ht[m_reg] << m_rm; 127 | } else { 128 | ht = hde64_table + DELTA_FPU_REG; 129 | t = ht[t] << m_reg; 130 | } 131 | if (t & 0x80) 132 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 133 | } 134 | 135 | if (pref & PRE_LOCK) { 136 | if (m_mod == 3) { 137 | hs->flags |= F_ERROR | F_ERROR_LOCK; 138 | } else { 139 | uint8_t *table_end, op = opcode; 140 | if (hs->opcode2) { 141 | ht = hde64_table + DELTA_OP2_LOCK_OK; 142 | table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; 143 | } else { 144 | ht = hde64_table + DELTA_OP_LOCK_OK; 145 | table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; 146 | op &= -2; 147 | } 148 | for (; ht != table_end; ht++) 149 | if (*ht++ == op) { 150 | if (!((*ht << m_reg) & 0x80)) 151 | goto no_lock_error; 152 | else 153 | break; 154 | } 155 | hs->flags |= F_ERROR | F_ERROR_LOCK; 156 | no_lock_error: 157 | ; 158 | } 159 | } 160 | 161 | if (hs->opcode2) { 162 | switch (opcode) { 163 | case 0x20: case 0x22: 164 | m_mod = 3; 165 | if (m_reg > 4 || m_reg == 1) 166 | goto error_operand; 167 | else 168 | goto no_error_operand; 169 | case 0x21: case 0x23: 170 | m_mod = 3; 171 | if (m_reg == 4 || m_reg == 5) 172 | goto error_operand; 173 | else 174 | goto no_error_operand; 175 | } 176 | } else { 177 | switch (opcode) { 178 | case 0x8c: 179 | if (m_reg > 5) 180 | goto error_operand; 181 | else 182 | goto no_error_operand; 183 | case 0x8e: 184 | if (m_reg == 1 || m_reg > 5) 185 | goto error_operand; 186 | else 187 | goto no_error_operand; 188 | } 189 | } 190 | 191 | if (m_mod == 3) { 192 | uint8_t *table_end; 193 | if (hs->opcode2) { 194 | ht = hde64_table + DELTA_OP2_ONLY_MEM; 195 | table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM; 196 | } else { 197 | ht = hde64_table + DELTA_OP_ONLY_MEM; 198 | table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; 199 | } 200 | for (; ht != table_end; ht += 2) 201 | if (*ht++ == opcode) { 202 | if (*ht++ & pref && !((*ht << m_reg) & 0x80)) 203 | goto error_operand; 204 | else 205 | break; 206 | } 207 | goto no_error_operand; 208 | } else if (hs->opcode2) { 209 | switch (opcode) { 210 | case 0x50: case 0xd7: case 0xf7: 211 | if (pref & (PRE_NONE | PRE_66)) 212 | goto error_operand; 213 | break; 214 | case 0xd6: 215 | if (pref & (PRE_F2 | PRE_F3)) 216 | goto error_operand; 217 | break; 218 | case 0xc5: 219 | goto error_operand; 220 | } 221 | goto no_error_operand; 222 | } else 223 | goto no_error_operand; 224 | 225 | error_operand: 226 | hs->flags |= F_ERROR | F_ERROR_OPERAND; 227 | no_error_operand: 228 | 229 | c = *p++; 230 | if (m_reg <= 1) { 231 | if (opcode == 0xf6) 232 | cflags |= C_IMM8; 233 | else if (opcode == 0xf7) 234 | cflags |= C_IMM_P66; 235 | } 236 | 237 | switch (m_mod) { 238 | case 0: 239 | if (pref & PRE_67) { 240 | if (m_rm == 6) 241 | disp_size = 2; 242 | } else 243 | if (m_rm == 5) 244 | disp_size = 4; 245 | break; 246 | case 1: 247 | disp_size = 1; 248 | break; 249 | case 2: 250 | disp_size = 2; 251 | if (!(pref & PRE_67)) 252 | disp_size <<= 1; 253 | } 254 | 255 | if (m_mod != 3 && m_rm == 4) { 256 | hs->flags |= F_SIB; 257 | p++; 258 | hs->sib = c; 259 | hs->sib_scale = c >> 6; 260 | hs->sib_index = (c & 0x3f) >> 3; 261 | if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) 262 | disp_size = 4; 263 | } 264 | 265 | p--; 266 | switch (disp_size) { 267 | case 1: 268 | hs->flags |= F_DISP8; 269 | hs->disp.disp8 = *p; 270 | break; 271 | case 2: 272 | hs->flags |= F_DISP16; 273 | hs->disp.disp16 = *(uint16_t *)p; 274 | break; 275 | case 4: 276 | hs->flags |= F_DISP32; 277 | hs->disp.disp32 = *(uint32_t *)p; 278 | } 279 | p += disp_size; 280 | } else if (pref & PRE_LOCK) 281 | hs->flags |= F_ERROR | F_ERROR_LOCK; 282 | 283 | if (cflags & C_IMM_P66) { 284 | if (cflags & C_REL32) { 285 | if (pref & PRE_66) { 286 | hs->flags |= F_IMM16 | F_RELATIVE; 287 | hs->imm.imm16 = *(uint16_t *)p; 288 | p += 2; 289 | goto disasm_done; 290 | } 291 | goto rel32_ok; 292 | } 293 | if (op64) { 294 | hs->flags |= F_IMM64; 295 | hs->imm.imm64 = *(uint64_t *)p; 296 | p += 8; 297 | } else if (!(pref & PRE_66)) { 298 | hs->flags |= F_IMM32; 299 | hs->imm.imm32 = *(uint32_t *)p; 300 | p += 4; 301 | } else 302 | goto imm16_ok; 303 | } 304 | 305 | 306 | if (cflags & C_IMM16) { 307 | imm16_ok: 308 | hs->flags |= F_IMM16; 309 | hs->imm.imm16 = *(uint16_t *)p; 310 | p += 2; 311 | } 312 | if (cflags & C_IMM8) { 313 | hs->flags |= F_IMM8; 314 | hs->imm.imm8 = *p++; 315 | } 316 | 317 | if (cflags & C_REL32) { 318 | rel32_ok: 319 | hs->flags |= F_IMM32 | F_RELATIVE; 320 | hs->imm.imm32 = *(uint32_t *)p; 321 | p += 4; 322 | } else if (cflags & C_REL8) { 323 | hs->flags |= F_IMM8 | F_RELATIVE; 324 | hs->imm.imm8 = *p++; 325 | } 326 | 327 | disasm_done: 328 | 329 | if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) { 330 | hs->flags |= F_ERROR | F_ERROR_LENGTH; 331 | hs->len = 15; 332 | } 333 | 334 | return (unsigned int)hs->len; 335 | } 336 | 337 | #endif // defined(_M_X64) || defined(__x86_64__) 338 | -------------------------------------------------------------------------------- /sdk/hook/hde/hde64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 64 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | * hde64.h: C/C++ header file 7 | * 8 | */ 9 | 10 | #ifndef _HDE64_H_ 11 | #define _HDE64_H_ 12 | 13 | /* stdint.h - C99 standard header 14 | * http://en.wikipedia.org/wiki/stdint.h 15 | * 16 | * if your compiler doesn't contain "stdint.h" header (for 17 | * example, Microsoft Visual C++), you can download file: 18 | * http://www.azillionmonkeys.com/qed/pstdint.h 19 | * and change next line to: 20 | * #include "pstdint.h" 21 | */ 22 | #include "pstdint.h" 23 | 24 | #define F_MODRM 0x00000001 25 | #define F_SIB 0x00000002 26 | #define F_IMM8 0x00000004 27 | #define F_IMM16 0x00000008 28 | #define F_IMM32 0x00000010 29 | #define F_IMM64 0x00000020 30 | #define F_DISP8 0x00000040 31 | #define F_DISP16 0x00000080 32 | #define F_DISP32 0x00000100 33 | #define F_RELATIVE 0x00000200 34 | #define F_ERROR 0x00001000 35 | #define F_ERROR_OPCODE 0x00002000 36 | #define F_ERROR_LENGTH 0x00004000 37 | #define F_ERROR_LOCK 0x00008000 38 | #define F_ERROR_OPERAND 0x00010000 39 | #define F_PREFIX_REPNZ 0x01000000 40 | #define F_PREFIX_REPX 0x02000000 41 | #define F_PREFIX_REP 0x03000000 42 | #define F_PREFIX_66 0x04000000 43 | #define F_PREFIX_67 0x08000000 44 | #define F_PREFIX_LOCK 0x10000000 45 | #define F_PREFIX_SEG 0x20000000 46 | #define F_PREFIX_REX 0x40000000 47 | #define F_PREFIX_ANY 0x7f000000 48 | 49 | #define PREFIX_SEGMENT_CS 0x2e 50 | #define PREFIX_SEGMENT_SS 0x36 51 | #define PREFIX_SEGMENT_DS 0x3e 52 | #define PREFIX_SEGMENT_ES 0x26 53 | #define PREFIX_SEGMENT_FS 0x64 54 | #define PREFIX_SEGMENT_GS 0x65 55 | #define PREFIX_LOCK 0xf0 56 | #define PREFIX_REPNZ 0xf2 57 | #define PREFIX_REPX 0xf3 58 | #define PREFIX_OPERAND_SIZE 0x66 59 | #define PREFIX_ADDRESS_SIZE 0x67 60 | 61 | #pragma pack(push,1) 62 | 63 | typedef struct { 64 | uint8_t len; 65 | uint8_t p_rep; 66 | uint8_t p_lock; 67 | uint8_t p_seg; 68 | uint8_t p_66; 69 | uint8_t p_67; 70 | uint8_t rex; 71 | uint8_t rex_w; 72 | uint8_t rex_r; 73 | uint8_t rex_x; 74 | uint8_t rex_b; 75 | uint8_t opcode; 76 | uint8_t opcode2; 77 | uint8_t modrm; 78 | uint8_t modrm_mod; 79 | uint8_t modrm_reg; 80 | uint8_t modrm_rm; 81 | uint8_t sib; 82 | uint8_t sib_scale; 83 | uint8_t sib_index; 84 | uint8_t sib_base; 85 | union { 86 | uint8_t imm8; 87 | uint16_t imm16; 88 | uint32_t imm32; 89 | uint64_t imm64; 90 | } imm; 91 | union { 92 | uint8_t disp8; 93 | uint16_t disp16; 94 | uint32_t disp32; 95 | } disp; 96 | uint32_t flags; 97 | } hde64s; 98 | 99 | #pragma pack(pop) 100 | 101 | #ifdef __cplusplus 102 | extern "C" { 103 | #endif 104 | 105 | /* __cdecl */ 106 | unsigned int hde64_disasm(const void *code, hde64s *hs); 107 | 108 | #ifdef __cplusplus 109 | } 110 | #endif 111 | 112 | #endif /* _HDE64_H_ */ 113 | -------------------------------------------------------------------------------- /sdk/hook/hde/pstdint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #pragma once 28 | 29 | #include 30 | 31 | // Integer types for HDE. 32 | typedef INT8 int8_t; 33 | typedef INT16 int16_t; 34 | typedef INT32 int32_t; 35 | typedef INT64 int64_t; 36 | typedef UINT8 uint8_t; 37 | typedef UINT16 uint16_t; 38 | typedef UINT32 uint32_t; 39 | typedef UINT64 uint64_t; 40 | -------------------------------------------------------------------------------- /sdk/hook/hde/table32.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 32 C 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | */ 7 | 8 | #define C_NONE 0x00 9 | #define C_MODRM 0x01 10 | #define C_IMM8 0x02 11 | #define C_IMM16 0x04 12 | #define C_IMM_P66 0x10 13 | #define C_REL8 0x20 14 | #define C_REL32 0x40 15 | #define C_GROUP 0x80 16 | #define C_ERROR 0xff 17 | 18 | #define PRE_ANY 0x00 19 | #define PRE_NONE 0x01 20 | #define PRE_F2 0x02 21 | #define PRE_F3 0x04 22 | #define PRE_66 0x08 23 | #define PRE_67 0x10 24 | #define PRE_LOCK 0x20 25 | #define PRE_SEG 0x40 26 | #define PRE_ALL 0xff 27 | 28 | #define DELTA_OPCODES 0x4a 29 | #define DELTA_FPU_REG 0xf1 30 | #define DELTA_FPU_MODRM 0xf8 31 | #define DELTA_PREFIXES 0x130 32 | #define DELTA_OP_LOCK_OK 0x1a1 33 | #define DELTA_OP2_LOCK_OK 0x1b9 34 | #define DELTA_OP_ONLY_MEM 0x1cb 35 | #define DELTA_OP2_ONLY_MEM 0x1da 36 | 37 | unsigned char hde32_table[] = { 38 | 0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3, 39 | 0xa8,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xac,0xaa,0xb2,0xaa,0x9f,0x9f, 40 | 0x9f,0x9f,0xb5,0xa3,0xa3,0xa4,0xaa,0xaa,0xba,0xaa,0x96,0xaa,0xa8,0xaa,0xc3, 41 | 0xc3,0x96,0x96,0xb7,0xae,0xd6,0xbd,0xa3,0xc5,0xa3,0xa3,0x9f,0xc3,0x9c,0xaa, 42 | 0xaa,0xac,0xaa,0xbf,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0x90, 43 | 0x82,0x7d,0x97,0x59,0x59,0x59,0x59,0x59,0x7f,0x59,0x59,0x60,0x7d,0x7f,0x7f, 44 | 0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x9a,0x88,0x7d, 45 | 0x59,0x50,0x50,0x50,0x50,0x59,0x59,0x59,0x59,0x61,0x94,0x61,0x9e,0x59,0x59, 46 | 0x85,0x59,0x92,0xa3,0x60,0x60,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59, 47 | 0x59,0x59,0x9f,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xcc,0x01,0xbc,0x03,0xf0, 48 | 0x10,0x10,0x10,0x10,0x50,0x50,0x50,0x50,0x14,0x20,0x20,0x20,0x20,0x01,0x01, 49 | 0x01,0x01,0xc4,0x02,0x10,0x00,0x00,0x00,0x00,0x01,0x01,0xc0,0xc2,0x10,0x11, 50 | 0x02,0x03,0x11,0x03,0x03,0x04,0x00,0x00,0x14,0x00,0x02,0x00,0x00,0xc6,0xc8, 51 | 0x02,0x02,0x02,0x02,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xca, 52 | 0x01,0x01,0x01,0x00,0x06,0x00,0x04,0x00,0xc0,0xc2,0x01,0x01,0x03,0x01,0xff, 53 | 0xff,0x01,0x00,0x03,0xc4,0xc4,0xc6,0x03,0x01,0x01,0x01,0xff,0x03,0x03,0x03, 54 | 0xc8,0x40,0x00,0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00, 55 | 0x00,0x00,0x00,0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00, 56 | 0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 57 | 0x00,0xff,0xff,0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 58 | 0x7f,0x00,0x00,0xff,0x4a,0x4a,0x4a,0x4a,0x4b,0x52,0x4a,0x4a,0x4a,0x4a,0x4f, 59 | 0x4c,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x55,0x45,0x40,0x4a,0x4a,0x4a, 60 | 0x45,0x59,0x4d,0x46,0x4a,0x5d,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a, 61 | 0x4a,0x4a,0x4a,0x4a,0x4a,0x61,0x63,0x67,0x4e,0x4a,0x4a,0x6b,0x6d,0x4a,0x4a, 62 | 0x45,0x6d,0x4a,0x4a,0x44,0x45,0x4a,0x4a,0x00,0x00,0x00,0x02,0x0d,0x06,0x06, 63 | 0x06,0x06,0x0e,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x00,0x06,0x06,0x02,0x06, 64 | 0x00,0x0a,0x0a,0x07,0x07,0x06,0x02,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, 65 | 0x04,0x04,0x00,0x00,0x00,0x0e,0x05,0x06,0x06,0x06,0x01,0x06,0x00,0x00,0x08, 66 | 0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01, 67 | 0x86,0x00,0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba, 68 | 0xf8,0xbb,0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00, 69 | 0xc4,0xff,0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00, 70 | 0x13,0x09,0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07, 71 | 0xb2,0xff,0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf, 72 | 0xe7,0x08,0x00,0xf0,0x02,0x00 73 | }; 74 | -------------------------------------------------------------------------------- /sdk/hook/hde/table64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 64 C 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | */ 7 | 8 | #define C_NONE 0x00 9 | #define C_MODRM 0x01 10 | #define C_IMM8 0x02 11 | #define C_IMM16 0x04 12 | #define C_IMM_P66 0x10 13 | #define C_REL8 0x20 14 | #define C_REL32 0x40 15 | #define C_GROUP 0x80 16 | #define C_ERROR 0xff 17 | 18 | #define PRE_ANY 0x00 19 | #define PRE_NONE 0x01 20 | #define PRE_F2 0x02 21 | #define PRE_F3 0x04 22 | #define PRE_66 0x08 23 | #define PRE_67 0x10 24 | #define PRE_LOCK 0x20 25 | #define PRE_SEG 0x40 26 | #define PRE_ALL 0xff 27 | 28 | #define DELTA_OPCODES 0x4a 29 | #define DELTA_FPU_REG 0xfd 30 | #define DELTA_FPU_MODRM 0x104 31 | #define DELTA_PREFIXES 0x13c 32 | #define DELTA_OP_LOCK_OK 0x1ae 33 | #define DELTA_OP2_LOCK_OK 0x1c6 34 | #define DELTA_OP_ONLY_MEM 0x1d8 35 | #define DELTA_OP2_ONLY_MEM 0x1e7 36 | 37 | unsigned char hde64_table[] = { 38 | 0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5, 39 | 0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1, 40 | 0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea, 41 | 0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0, 42 | 0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab, 43 | 0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92, 44 | 0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90, 45 | 0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b, 46 | 0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b, 47 | 0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc, 48 | 0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20, 49 | 0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff, 50 | 0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00, 51 | 0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01, 52 | 0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10, 53 | 0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00, 54 | 0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00, 55 | 0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00, 56 | 0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00, 57 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, 58 | 0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00, 59 | 0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40, 60 | 0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43, 61 | 0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, 62 | 0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40, 63 | 0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06, 64 | 0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07, 65 | 0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, 66 | 0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10, 67 | 0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00, 68 | 0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb, 69 | 0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff, 70 | 0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09, 71 | 0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff, 72 | 0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08, 73 | 0x00,0xf0,0x02,0x00 74 | }; 75 | -------------------------------------------------------------------------------- /sdk/hook/trampoline.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2017 Tsuda Kageyu. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 20 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | 31 | #ifndef ARRAYSIZE 32 | #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) 33 | #endif 34 | 35 | #if defined(_M_X64) || defined(__x86_64__) 36 | #include "./hde/hde64.h" 37 | typedef hde64s HDE; 38 | #define HDE_DISASM(code, hs) hde64_disasm(code, hs) 39 | #else 40 | #include "./hde/hde32.h" 41 | typedef hde32s HDE; 42 | #define HDE_DISASM(code, hs) hde32_disasm(code, hs) 43 | #endif 44 | 45 | #include "trampoline.h" 46 | #include "buffer.h" 47 | 48 | // Maximum size of a trampoline function. 49 | #if defined(_M_X64) || defined(__x86_64__) 50 | #define TRAMPOLINE_MAX_SIZE (MEMORY_SLOT_SIZE - sizeof(JMP_ABS)) 51 | #else 52 | #define TRAMPOLINE_MAX_SIZE MEMORY_SLOT_SIZE 53 | #endif 54 | 55 | //------------------------------------------------------------------------- 56 | static BOOL IsCodePadding(LPBYTE pInst, UINT size) 57 | { 58 | UINT i; 59 | 60 | if (pInst[0] != 0x00 && pInst[0] != 0x90 && pInst[0] != 0xCC) 61 | return FALSE; 62 | 63 | for (i = 1; i < size; ++i) 64 | { 65 | if (pInst[i] != pInst[0]) 66 | return FALSE; 67 | } 68 | return TRUE; 69 | } 70 | 71 | //------------------------------------------------------------------------- 72 | BOOL CreateTrampolineFunction(PTRAMPOLINE ct) 73 | { 74 | #if defined(_M_X64) || defined(__x86_64__) 75 | CALL_ABS call = { 76 | 0xFF, 0x15, 0x00000002, // FF15 00000002: CALL [RIP+8] 77 | 0xEB, 0x08, // EB 08: JMP +10 78 | 0x0000000000000000ULL // Absolute destination address 79 | }; 80 | JMP_ABS jmp = { 81 | 0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6] 82 | 0x0000000000000000ULL // Absolute destination address 83 | }; 84 | JCC_ABS jcc = { 85 | 0x70, 0x0E, // 7* 0E: J** +16 86 | 0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6] 87 | 0x0000000000000000ULL // Absolute destination address 88 | }; 89 | #else 90 | CALL_REL call = { 91 | 0xE8, // E8 xxxxxxxx: CALL +5+xxxxxxxx 92 | 0x00000000 // Relative destination address 93 | }; 94 | JMP_REL jmp = { 95 | 0xE9, // E9 xxxxxxxx: JMP +5+xxxxxxxx 96 | 0x00000000 // Relative destination address 97 | }; 98 | JCC_REL jcc = { 99 | 0x0F, 0x80, // 0F8* xxxxxxxx: J** +6+xxxxxxxx 100 | 0x00000000 // Relative destination address 101 | }; 102 | #endif 103 | 104 | UINT8 oldPos = 0; 105 | UINT8 newPos = 0; 106 | ULONG_PTR jmpDest = 0; // Destination address of an internal jump. 107 | BOOL finished = FALSE; // Is the function completed? 108 | #if defined(_M_X64) || defined(__x86_64__) 109 | UINT8 instBuf[16]; 110 | #endif 111 | 112 | ct->patchAbove = FALSE; 113 | ct->nIP = 0; 114 | 115 | do 116 | { 117 | HDE hs; 118 | UINT copySize; 119 | LPVOID pCopySrc; 120 | ULONG_PTR pOldInst = (ULONG_PTR)ct->pTarget + oldPos; 121 | ULONG_PTR pNewInst = (ULONG_PTR)ct->pTrampoline + newPos; 122 | 123 | copySize = HDE_DISASM((LPVOID)pOldInst, &hs); 124 | if (hs.flags & F_ERROR) 125 | return FALSE; 126 | 127 | pCopySrc = (LPVOID)pOldInst; 128 | if (oldPos >= sizeof(JMP_REL)) 129 | { 130 | // The trampoline function is long enough. 131 | // Complete the function with the jump to the target function. 132 | #if defined(_M_X64) || defined(__x86_64__) 133 | jmp.address = pOldInst; 134 | #else 135 | jmp.operand = (UINT32)(pOldInst - (pNewInst + sizeof(jmp))); 136 | #endif 137 | pCopySrc = &jmp; 138 | copySize = sizeof(jmp); 139 | 140 | finished = TRUE; 141 | } 142 | #if defined(_M_X64) || defined(__x86_64__) 143 | else if ((hs.modrm & 0xC7) == 0x05) 144 | { 145 | // Instructions using RIP relative addressing. (ModR/M = 00???101B) 146 | 147 | // Modify the RIP relative address. 148 | PUINT32 pRelAddr; 149 | 150 | // Avoid using memcpy to reduce the footprint. 151 | #ifndef _MSC_VER 152 | memcpy(instBuf, (LPBYTE)pOldInst, copySize); 153 | #else 154 | __movsb(instBuf, (LPBYTE)pOldInst, copySize); 155 | #endif 156 | pCopySrc = instBuf; 157 | 158 | // Relative address is stored at (instruction length - immediate value length - 4). 159 | pRelAddr = (PUINT32)(instBuf + hs.len - ((hs.flags & 0x3C) >> 2) - 4); 160 | *pRelAddr 161 | = (UINT32)((pOldInst + hs.len + (INT32)hs.disp.disp32) - (pNewInst + hs.len)); 162 | 163 | // Complete the function if JMP (FF /4). 164 | if (hs.opcode == 0xFF && hs.modrm_reg == 4) 165 | finished = TRUE; 166 | } 167 | #endif 168 | else if (hs.opcode == 0xE8) 169 | { 170 | // Direct relative CALL 171 | ULONG_PTR dest = pOldInst + hs.len + (INT32)hs.imm.imm32; 172 | #if defined(_M_X64) || defined(__x86_64__) 173 | call.address = dest; 174 | #else 175 | call.operand = (UINT32)(dest - (pNewInst + sizeof(call))); 176 | #endif 177 | pCopySrc = &call; 178 | copySize = sizeof(call); 179 | } 180 | else if ((hs.opcode & 0xFD) == 0xE9) 181 | { 182 | // Direct relative JMP (EB or E9) 183 | ULONG_PTR dest = pOldInst + hs.len; 184 | 185 | if (hs.opcode == 0xEB) // isShort jmp 186 | dest += (INT8)hs.imm.imm8; 187 | else 188 | dest += (INT32)hs.imm.imm32; 189 | 190 | // Simply copy an internal jump. 191 | if ((ULONG_PTR)ct->pTarget <= dest 192 | && dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL))) 193 | { 194 | if (jmpDest < dest) 195 | jmpDest = dest; 196 | } 197 | else 198 | { 199 | #if defined(_M_X64) || defined(__x86_64__) 200 | jmp.address = dest; 201 | #else 202 | jmp.operand = (UINT32)(dest - (pNewInst + sizeof(jmp))); 203 | #endif 204 | pCopySrc = &jmp; 205 | copySize = sizeof(jmp); 206 | 207 | // Exit the function If it is not in the branch 208 | finished = (pOldInst >= jmpDest); 209 | } 210 | } 211 | else if ((hs.opcode & 0xF0) == 0x70 212 | || (hs.opcode & 0xFC) == 0xE0 213 | || (hs.opcode2 & 0xF0) == 0x80) 214 | { 215 | // Direct relative Jcc 216 | ULONG_PTR dest = pOldInst + hs.len; 217 | 218 | if ((hs.opcode & 0xF0) == 0x70 // Jcc 219 | || (hs.opcode & 0xFC) == 0xE0) // LOOPNZ/LOOPZ/LOOP/JECXZ 220 | dest += (INT8)hs.imm.imm8; 221 | else 222 | dest += (INT32)hs.imm.imm32; 223 | 224 | // Simply copy an internal jump. 225 | if ((ULONG_PTR)ct->pTarget <= dest 226 | && dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL))) 227 | { 228 | if (jmpDest < dest) 229 | jmpDest = dest; 230 | } 231 | else if ((hs.opcode & 0xFC) == 0xE0) 232 | { 233 | // LOOPNZ/LOOPZ/LOOP/JCXZ/JECXZ to the outside are not supported. 234 | return FALSE; 235 | } 236 | else 237 | { 238 | UINT8 cond = ((hs.opcode != 0x0F ? hs.opcode : hs.opcode2) & 0x0F); 239 | #if defined(_M_X64) || defined(__x86_64__) 240 | // Invert the condition in x64 mode to simplify the conditional jump logic. 241 | jcc.opcode = 0x71 ^ cond; 242 | jcc.address = dest; 243 | #else 244 | jcc.opcode1 = 0x80 | cond; 245 | jcc.operand = (UINT32)(dest - (pNewInst + sizeof(jcc))); 246 | #endif 247 | pCopySrc = &jcc; 248 | copySize = sizeof(jcc); 249 | } 250 | } 251 | else if ((hs.opcode & 0xFE) == 0xC2) 252 | { 253 | // RET (C2 or C3) 254 | 255 | // Complete the function if not in a branch. 256 | finished = (pOldInst >= jmpDest); 257 | } 258 | 259 | // Can't alter the instruction length in a branch. 260 | if (pOldInst < jmpDest && copySize != hs.len) 261 | return FALSE; 262 | 263 | // Trampoline function is too large. 264 | if ((newPos + copySize) > TRAMPOLINE_MAX_SIZE) 265 | return FALSE; 266 | 267 | // Trampoline function has too many instructions. 268 | if (ct->nIP >= ARRAYSIZE(ct->oldIPs)) 269 | return FALSE; 270 | 271 | ct->oldIPs[ct->nIP] = oldPos; 272 | ct->newIPs[ct->nIP] = newPos; 273 | ct->nIP++; 274 | 275 | // Avoid using memcpy to reduce the footprint. 276 | #ifndef _MSC_VER 277 | memcpy((LPBYTE)ct->pTrampoline + newPos, pCopySrc, copySize); 278 | #else 279 | __movsb((LPBYTE)ct->pTrampoline + newPos, pCopySrc, copySize); 280 | #endif 281 | newPos += copySize; 282 | oldPos += hs.len; 283 | } 284 | while (!finished); 285 | 286 | // Is there enough place for a long jump? 287 | if (oldPos < sizeof(JMP_REL) 288 | && !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL) - oldPos)) 289 | { 290 | // Is there enough place for a short jump? 291 | if (oldPos < sizeof(JMP_REL_SHORT) 292 | && !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL_SHORT) - oldPos)) 293 | { 294 | return FALSE; 295 | } 296 | 297 | // Can we place the long jump above the function? 298 | if (!IsExecutableAddress((LPBYTE)ct->pTarget - sizeof(JMP_REL))) 299 | return FALSE; 300 | 301 | if (!IsCodePadding((LPBYTE)ct->pTarget - sizeof(JMP_REL), sizeof(JMP_REL))) 302 | return FALSE; 303 | 304 | ct->patchAbove = TRUE; 305 | } 306 | 307 | #if defined(_M_X64) || defined(__x86_64__) 308 | // Create a relay function. 309 | jmp.address = (ULONG_PTR)ct->pDetour; 310 | 311 | ct->pRelay = (LPBYTE)ct->pTrampoline + newPos; 312 | memcpy(ct->pRelay, &jmp, sizeof(jmp)); 313 | #endif 314 | 315 | return TRUE; 316 | } 317 | -------------------------------------------------------------------------------- /sdk/hook/trampoline.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2017 Tsuda Kageyu. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 20 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #pragma pack(push, 1) 32 | 33 | // Structs for writing x86/x64 instructions. 34 | 35 | // 8-bit relative jump. 36 | typedef struct _JMP_REL_SHORT 37 | { 38 | UINT8 opcode; // EB xx: JMP +2+xx 39 | UINT8 operand; 40 | } JMP_REL_SHORT, *PJMP_REL_SHORT; 41 | 42 | // 32-bit direct relative jump/call. 43 | typedef struct _JMP_REL 44 | { 45 | UINT8 opcode; // E9/E8 xxxxxxxx: JMP/CALL +5+xxxxxxxx 46 | UINT32 operand; // Relative destination address 47 | } JMP_REL, *PJMP_REL, CALL_REL; 48 | 49 | // 64-bit indirect absolute jump. 50 | typedef struct _JMP_ABS 51 | { 52 | UINT8 opcode0; // FF25 00000000: JMP [+6] 53 | UINT8 opcode1; 54 | UINT32 dummy; 55 | UINT64 address; // Absolute destination address 56 | } JMP_ABS, *PJMP_ABS; 57 | 58 | // 64-bit indirect absolute call. 59 | typedef struct _CALL_ABS 60 | { 61 | UINT8 opcode0; // FF15 00000002: CALL [+6] 62 | UINT8 opcode1; 63 | UINT32 dummy0; 64 | UINT8 dummy1; // EB 08: JMP +10 65 | UINT8 dummy2; 66 | UINT64 address; // Absolute destination address 67 | } CALL_ABS; 68 | 69 | // 32-bit direct relative conditional jumps. 70 | typedef struct _JCC_REL 71 | { 72 | UINT8 opcode0; // 0F8* xxxxxxxx: J** +6+xxxxxxxx 73 | UINT8 opcode1; 74 | UINT32 operand; // Relative destination address 75 | } JCC_REL; 76 | 77 | // 64bit indirect absolute conditional jumps that x64 lacks. 78 | typedef struct _JCC_ABS 79 | { 80 | UINT8 opcode; // 7* 0E: J** +16 81 | UINT8 dummy0; 82 | UINT8 dummy1; // FF25 00000000: JMP [+6] 83 | UINT8 dummy2; 84 | UINT32 dummy3; 85 | UINT64 address; // Absolute destination address 86 | } JCC_ABS; 87 | 88 | #pragma pack(pop) 89 | 90 | typedef struct _TRAMPOLINE 91 | { 92 | LPVOID pTarget; // [In] Address of the target function. 93 | LPVOID pDetour; // [In] Address of the detour function. 94 | LPVOID pTrampoline; // [In] Buffer address for the trampoline and relay function. 95 | 96 | #if defined(_M_X64) || defined(__x86_64__) 97 | LPVOID pRelay; // [Out] Address of the relay function. 98 | #endif 99 | BOOL patchAbove; // [Out] Should use the hot patch area? 100 | UINT nIP; // [Out] Number of the instruction boundaries. 101 | UINT8 oldIPs[8]; // [Out] Instruction boundaries of the target function. 102 | UINT8 newIPs[8]; // [Out] Instruction boundaries of the trampoline function. 103 | } TRAMPOLINE, *PTRAMPOLINE; 104 | 105 | BOOL CreateTrampolineFunction(PTRAMPOLINE ct); 106 | -------------------------------------------------------------------------------- /sdk/includes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | Main includes for gasper-cpp, would be a pain to write this constantly wouldn't it? 5 | 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | #ifndef M_PI 25 | #define M_PI 3.14159265358979323846 26 | #endif 27 | 28 | inline constexpr auto BADLION_CLIENT = true; 29 | 30 | #include 31 | 32 | #include "hook/MinHook.h" 33 | 34 | #include "libraries/imgui/imgui.h" 35 | #include "libraries/imgui/imgui_impl_win32.h" 36 | #include "libraries/imgui/imgui_impl_opengl2.h" 37 | #include "libraries/imgui/imgui_internal.h" 38 | 39 | #include "libraries/xorstr.h" 40 | #include "wrapper/wrapper.h" 41 | #include "utils/utils.h" 42 | #include "mapper/mapper.h" 43 | #include "utils/timer/timer.h" -------------------------------------------------------------------------------- /sdk/libraries/imgui/imconfig.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // COMPILE-TIME OPTIONS FOR DEAR IMGUI 3 | // Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure. 4 | // You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions. 5 | //----------------------------------------------------------------------------- 6 | // A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/branch with your modifications to imconfig.h) 7 | // B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h" 8 | // If you do so you need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include 9 | // the imgui*.cpp files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures. 10 | // Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. 11 | // Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using. 12 | //----------------------------------------------------------------------------- 13 | 14 | #pragma once 15 | 16 | //---- Define assertion handler. Defaults to calling assert(). 17 | //#define IM_ASSERT(_EXPR) MyAssert(_EXPR) 18 | //#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts 19 | 20 | //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows 21 | // Using dear imgui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility. 22 | //#define IMGUI_API __declspec( dllexport ) 23 | //#define IMGUI_API __declspec( dllimport ) 24 | 25 | //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names. 26 | //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS 27 | 28 | //---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty) 29 | // It is very strongly recommended to NOT disable the demo windows during development. Please read the comments in imgui_demo.cpp. 30 | //#define IMGUI_DISABLE_DEMO_WINDOWS 31 | //#define IMGUI_DISABLE_METRICS_WINDOW 32 | 33 | //---- Don't implement some functions to reduce linkage requirements. 34 | //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. 35 | //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow. 36 | //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime). 37 | //#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default). 38 | //#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf) 39 | //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself. 40 | //#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function. 41 | //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). 42 | 43 | //---- Include imgui_user.h at the end of imgui.h as a convenience 44 | //#define IMGUI_INCLUDE_IMGUI_USER_H 45 | 46 | //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another) 47 | //#define IMGUI_USE_BGRA_PACKED_COLOR 48 | 49 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version 50 | // By default the embedded implementations are declared static and not available outside of imgui cpp files. 51 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" 52 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" 53 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION 54 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION 55 | 56 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. 57 | // This will be inlined as part of ImVec2 and ImVec4 class declarations. 58 | /* 59 | #define IM_VEC2_CLASS_EXTRA \ 60 | ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ 61 | operator MyVec2() const { return MyVec2(x,y); } 62 | 63 | #define IM_VEC4_CLASS_EXTRA \ 64 | ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ 65 | operator MyVec4() const { return MyVec4(x,y,z,w); } 66 | */ 67 | 68 | //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices. 69 | // Your renderer back-end will need to support it (most example renderer back-ends support both 16/32-bit indices). 70 | // Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer. 71 | // Read about ImGuiBackendFlags_RendererHasVtxOffset for details. 72 | //#define ImDrawIdx unsigned int 73 | 74 | //---- Override ImDrawCallback signature (will need to modify renderer back-ends accordingly) 75 | //struct ImDrawList; 76 | //struct ImDrawCmd; 77 | //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data); 78 | //#define ImDrawCallback MyImDrawCallback 79 | 80 | //---- Debug Tools: Macro to break in Debugger 81 | // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.) 82 | //#define IM_DEBUG_BREAK IM_ASSERT(0) 83 | //#define IM_DEBUG_BREAK __debugbreak() 84 | 85 | //---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(), 86 | // (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.) 87 | // This adds a small runtime cost which is why it is not enabled by default. 88 | //#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX 89 | 90 | //---- Debug Tools: Enable slower asserts 91 | //#define IMGUI_DEBUG_PARANOID 92 | 93 | //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. 94 | /* 95 | namespace ImGui 96 | { 97 | void MyFunction(const char* name, const MyMatrix44& v); 98 | } 99 | */ 100 | -------------------------------------------------------------------------------- /sdk/libraries/imgui/imgui_impl_opengl2.cpp: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer for OpenGL2 (legacy OpenGL, fixed pipeline) 2 | // This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..) 3 | 4 | // Implemented features: 5 | // [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID! 6 | 7 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 8 | // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. 9 | // https://github.com/ocornut/imgui 10 | 11 | // **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** 12 | // **Prefer using the code in imgui_impl_opengl3.cpp** 13 | // This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read. 14 | // If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more 15 | // complicated, will require your code to reset every single OpenGL attributes to their initial state, and might 16 | // confuse your GPU driver. 17 | // The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API. 18 | 19 | // CHANGELOG 20 | // (minor and older changes stripped away, please see git history for details) 21 | // 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. 22 | // 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display. 23 | // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. 24 | // 2018-08-03: OpenGL: Disabling/restoring GL_LIGHTING and GL_COLOR_MATERIAL to increase compatibility with legacy OpenGL applications. 25 | // 2018-06-08: Misc: Extracted imgui_impl_opengl2.cpp/.h away from the old combined GLFW/SDL+OpenGL2 examples. 26 | // 2018-06-08: OpenGL: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle. 27 | // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplOpenGL2_RenderDrawData() in the .h file so you can call it yourself. 28 | // 2017-09-01: OpenGL: Save and restore current polygon mode. 29 | // 2016-09-10: OpenGL: Uploading font texture as RGBA32 to increase compatibility with users shaders (not ideal). 30 | // 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle. 31 | 32 | #include "imgui.h" 33 | #include "imgui_impl_opengl2.h" 34 | #if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier 35 | #include // intptr_t 36 | #else 37 | #include // intptr_t 38 | #endif 39 | 40 | // Include OpenGL header (without an OpenGL loader) requires a bit of fiddling 41 | #if defined(_WIN32) && !defined(APIENTRY) 42 | #define APIENTRY __stdcall // It is customary to use APIENTRY for OpenGL function pointer declarations on all platforms. Additionally, the Windows OpenGL header needs APIENTRY. 43 | #endif 44 | #if defined(_WIN32) && !defined(WINGDIAPI) 45 | #define WINGDIAPI __declspec(dllimport) // Some Windows OpenGL headers need this 46 | #endif 47 | #if defined(__APPLE__) 48 | #define GL_SILENCE_DEPRECATION 49 | #include 50 | #else 51 | #include 52 | #endif 53 | 54 | // OpenGL Data 55 | static GLuint g_FontTexture = 0; 56 | 57 | // Functions 58 | bool ImGui_ImplOpenGL2_Init() 59 | { 60 | // Setup back-end capabilities flags 61 | ImGuiIO& io = ImGui::GetIO(); 62 | io.BackendRendererName = "imgui_impl_opengl2"; 63 | return true; 64 | } 65 | 66 | void ImGui_ImplOpenGL2_Shutdown() 67 | { 68 | ImGui_ImplOpenGL2_DestroyDeviceObjects(); 69 | } 70 | 71 | void ImGui_ImplOpenGL2_NewFrame() 72 | { 73 | if (!g_FontTexture) 74 | ImGui_ImplOpenGL2_CreateDeviceObjects(); 75 | } 76 | 77 | static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height) 78 | { 79 | // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill. 80 | glEnable(GL_BLEND); 81 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 82 | glDisable(GL_CULL_FACE); 83 | glDisable(GL_DEPTH_TEST); 84 | glDisable(GL_LIGHTING); 85 | glDisable(GL_COLOR_MATERIAL); 86 | glEnable(GL_SCISSOR_TEST); 87 | glEnableClientState(GL_VERTEX_ARRAY); 88 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); 89 | glEnableClientState(GL_COLOR_ARRAY); 90 | glEnable(GL_TEXTURE_2D); 91 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 92 | 93 | // If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!), 94 | // you may need to backup/reset/restore current shader using the lines below. DO NOT MODIFY THIS FILE! Add the code in your calling function: 95 | // GLint last_program; 96 | // glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); 97 | // glUseProgram(0); 98 | // ImGui_ImplOpenGL2_RenderDrawData(...); 99 | // glUseProgram(last_program) 100 | 101 | // Setup viewport, orthographic projection matrix 102 | // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. 103 | glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); 104 | glMatrixMode(GL_PROJECTION); 105 | glPushMatrix(); 106 | glLoadIdentity(); 107 | glOrtho(draw_data->DisplayPos.x, draw_data->DisplayPos.x + draw_data->DisplaySize.x, draw_data->DisplayPos.y + draw_data->DisplaySize.y, draw_data->DisplayPos.y, -1.0f, +1.0f); 108 | glMatrixMode(GL_MODELVIEW); 109 | glPushMatrix(); 110 | glLoadIdentity(); 111 | } 112 | 113 | // OpenGL2 Render function. 114 | // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) 115 | // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. 116 | void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data) 117 | { 118 | // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) 119 | int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); 120 | int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); 121 | if (fb_width == 0 || fb_height == 0) 122 | return; 123 | 124 | // Backup GL state 125 | GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); 126 | GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); 127 | GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); 128 | GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); 129 | glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); 130 | 131 | // Setup desired GL state 132 | ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height); 133 | 134 | // Will project scissor/clipping rectangles into framebuffer space 135 | ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports 136 | ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2) 137 | 138 | // Render command lists 139 | for (int n = 0; n < draw_data->CmdListsCount; n++) 140 | { 141 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 142 | const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; 143 | const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; 144 | glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos))); 145 | glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv))); 146 | glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col))); 147 | 148 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) 149 | { 150 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; 151 | if (pcmd->UserCallback) 152 | { 153 | // User callback, registered via ImDrawList::AddCallback() 154 | // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) 155 | if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) 156 | ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height); 157 | else 158 | pcmd->UserCallback(cmd_list, pcmd); 159 | } 160 | else 161 | { 162 | // Project scissor/clipping rectangles into framebuffer space 163 | ImVec4 clip_rect; 164 | clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x; 165 | clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y; 166 | clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x; 167 | clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y; 168 | 169 | if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) 170 | { 171 | // Apply scissor/clipping rectangle 172 | glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); 173 | 174 | // Bind texture, Draw 175 | glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); 176 | glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); 177 | } 178 | } 179 | idx_buffer += pcmd->ElemCount; 180 | } 181 | } 182 | 183 | // Restore modified GL state 184 | glDisableClientState(GL_COLOR_ARRAY); 185 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); 186 | glDisableClientState(GL_VERTEX_ARRAY); 187 | glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); 188 | glMatrixMode(GL_MODELVIEW); 189 | glPopMatrix(); 190 | glMatrixMode(GL_PROJECTION); 191 | glPopMatrix(); 192 | glPopAttrib(); 193 | glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]); 194 | glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); 195 | glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); 196 | } 197 | 198 | bool ImGui_ImplOpenGL2_CreateFontsTexture() 199 | { 200 | // Build texture atlas 201 | ImGuiIO& io = ImGui::GetIO(); 202 | unsigned char* pixels; 203 | int width, height; 204 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. 205 | 206 | // Upload texture to graphics system 207 | GLint last_texture; 208 | glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); 209 | glGenTextures(1, &g_FontTexture); 210 | glBindTexture(GL_TEXTURE_2D, g_FontTexture); 211 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 212 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 213 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 214 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 215 | 216 | // Store our identifier 217 | io.Fonts->TexID = (ImTextureID)(intptr_t)g_FontTexture; 218 | 219 | // Restore state 220 | glBindTexture(GL_TEXTURE_2D, last_texture); 221 | 222 | return true; 223 | } 224 | 225 | void ImGui_ImplOpenGL2_DestroyFontsTexture() 226 | { 227 | if (g_FontTexture) 228 | { 229 | ImGuiIO& io = ImGui::GetIO(); 230 | glDeleteTextures(1, &g_FontTexture); 231 | io.Fonts->TexID = 0; 232 | g_FontTexture = 0; 233 | } 234 | } 235 | 236 | bool ImGui_ImplOpenGL2_CreateDeviceObjects() 237 | { 238 | return ImGui_ImplOpenGL2_CreateFontsTexture(); 239 | } 240 | 241 | void ImGui_ImplOpenGL2_DestroyDeviceObjects() 242 | { 243 | ImGui_ImplOpenGL2_DestroyFontsTexture(); 244 | } 245 | -------------------------------------------------------------------------------- /sdk/libraries/imgui/imgui_impl_opengl2.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer for OpenGL2 (legacy OpenGL, fixed pipeline) 2 | // This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..) 3 | 4 | // Implemented features: 5 | // [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID! 6 | 7 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 8 | // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. 9 | // https://github.com/ocornut/imgui 10 | 11 | // **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** 12 | // **Prefer using the code in imgui_impl_opengl3.cpp** 13 | // This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read. 14 | // If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more 15 | // complicated, will require your code to reset every single OpenGL attributes to their initial state, and might 16 | // confuse your GPU driver. 17 | // The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API. 18 | 19 | #pragma once 20 | 21 | IMGUI_IMPL_API bool ImGui_ImplOpenGL2_Init(); 22 | IMGUI_IMPL_API void ImGui_ImplOpenGL2_Shutdown(); 23 | IMGUI_IMPL_API void ImGui_ImplOpenGL2_NewFrame(); 24 | IMGUI_IMPL_API void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data); 25 | 26 | // Called by Init/NewFrame/Shutdown 27 | IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateFontsTexture(); 28 | IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyFontsTexture(); 29 | IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateDeviceObjects(); 30 | IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyDeviceObjects(); 31 | -------------------------------------------------------------------------------- /sdk/libraries/imgui/imgui_impl_win32.cpp: -------------------------------------------------------------------------------- 1 | // dear imgui: Platform Binding for Windows (standard windows API for 32 and 64 bits applications) 2 | // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) 3 | 4 | // Implemented features: 5 | // [X] Platform: Clipboard support (for Win32 this is actually part of core imgui) 6 | // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 7 | // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). 8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 9 | 10 | #include "imgui.h" 11 | #include "imgui_impl_win32.h" 12 | #ifndef WIN32_LEAN_AND_MEAN 13 | #define WIN32_LEAN_AND_MEAN 14 | #endif 15 | #include 16 | #include 17 | #include 18 | 19 | // CHANGELOG 20 | // (minor and older changes stripped away, please see git history for details) 21 | // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. 22 | // 2019-05-11: Inputs: Don't filter value from WM_CHAR before calling AddInputCharacter(). 23 | // 2019-01-17: Misc: Using GetForegroundWindow()+IsChild() instead of GetActiveWindow() to be compatible with windows created in a different thread or parent. 24 | // 2019-01-17: Inputs: Added support for mouse buttons 4 and 5 via WM_XBUTTON* messages. 25 | // 2019-01-15: Inputs: Added support for XInput gamepads (if ImGuiConfigFlags_NavEnableGamepad is set by user application). 26 | // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. 27 | // 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. 28 | // 2018-06-10: Inputs: Fixed handling of mouse wheel messages to support fine position messages (typically sent by track-pads). 29 | // 2018-06-08: Misc: Extracted imgui_impl_win32.cpp/.h away from the old combined DX9/DX10/DX11/DX12 examples. 30 | // 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors and ImGuiBackendFlags_HasSetMousePos flags + honor ImGuiConfigFlags_NoMouseCursorChange flag. 31 | // 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). 32 | // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. 33 | // 2018-02-06: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set). 34 | // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 35 | // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. 36 | // 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert. 37 | // 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag. 38 | // 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read. 39 | // 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging. 40 | // 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCursor is set. 41 | 42 | // Win32 Data 43 | static HWND g_hWnd = 0; 44 | static INT64 g_Time = 0; 45 | static INT64 g_TicksPerSecond = 0; 46 | static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT; 47 | static bool g_HasGamepad = false; 48 | static bool g_WantUpdateHasGamepad = true; 49 | 50 | // Functions 51 | bool ImGui_ImplWin32_Init(void* hwnd) 52 | { 53 | if (!::QueryPerformanceFrequency((LARGE_INTEGER *)&g_TicksPerSecond)) 54 | return false; 55 | if (!::QueryPerformanceCounter((LARGE_INTEGER *)&g_Time)) 56 | return false; 57 | 58 | // Setup back-end capabilities flags 59 | g_hWnd = (HWND)hwnd; 60 | ImGuiIO& io = ImGui::GetIO(); 61 | io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) 62 | io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) 63 | io.BackendPlatformName = "imgui_impl_win32"; 64 | io.ImeWindowHandle = hwnd; 65 | 66 | // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime. 67 | io.KeyMap[ImGuiKey_Tab] = VK_TAB; 68 | io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; 69 | io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; 70 | io.KeyMap[ImGuiKey_UpArrow] = VK_UP; 71 | io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN; 72 | io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR; 73 | io.KeyMap[ImGuiKey_PageDown] = VK_NEXT; 74 | io.KeyMap[ImGuiKey_Home] = VK_HOME; 75 | io.KeyMap[ImGuiKey_End] = VK_END; 76 | io.KeyMap[ImGuiKey_Insert] = VK_INSERT; 77 | io.KeyMap[ImGuiKey_Delete] = VK_DELETE; 78 | io.KeyMap[ImGuiKey_Backspace] = VK_BACK; 79 | io.KeyMap[ImGuiKey_Space] = VK_SPACE; 80 | io.KeyMap[ImGuiKey_Enter] = VK_RETURN; 81 | io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE; 82 | io.KeyMap[ImGuiKey_KeyPadEnter] = VK_RETURN; 83 | io.KeyMap[ImGuiKey_A] = 'A'; 84 | io.KeyMap[ImGuiKey_C] = 'C'; 85 | io.KeyMap[ImGuiKey_V] = 'V'; 86 | io.KeyMap[ImGuiKey_X] = 'X'; 87 | io.KeyMap[ImGuiKey_Y] = 'Y'; 88 | io.KeyMap[ImGuiKey_Z] = 'Z'; 89 | 90 | return true; 91 | } 92 | 93 | void ImGui_ImplWin32_Shutdown() 94 | { 95 | g_hWnd = (HWND)0; 96 | } 97 | 98 | static bool ImGui_ImplWin32_UpdateMouseCursor() 99 | { 100 | ImGuiIO& io = ImGui::GetIO(); 101 | if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) 102 | return false; 103 | 104 | ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); 105 | if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor) 106 | { 107 | // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor 108 | ::SetCursor(NULL); 109 | } 110 | else 111 | { 112 | // Show OS mouse cursor 113 | LPTSTR win32_cursor = IDC_ARROW; 114 | switch (imgui_cursor) 115 | { 116 | case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break; 117 | case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break; 118 | case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break; 119 | case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break; 120 | case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break; 121 | case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break; 122 | case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break; 123 | case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break; 124 | case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break; 125 | } 126 | ::SetCursor(::LoadCursor(NULL, win32_cursor)); 127 | } 128 | return true; 129 | } 130 | 131 | static void ImGui_ImplWin32_UpdateMousePos() 132 | { 133 | ImGuiIO& io = ImGui::GetIO(); 134 | 135 | // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) 136 | if (io.WantSetMousePos) 137 | { 138 | POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; 139 | ::ClientToScreen(g_hWnd, &pos); 140 | ::SetCursorPos(pos.x, pos.y); 141 | } 142 | 143 | // Set mouse position 144 | io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); 145 | POINT pos; 146 | if (HWND active_window = ::GetForegroundWindow()) 147 | if (active_window == g_hWnd || ::IsChild(active_window, g_hWnd)) 148 | if (::GetCursorPos(&pos) && ::ScreenToClient(g_hWnd, &pos)) 149 | io.MousePos = ImVec2((float)pos.x, (float)pos.y); 150 | } 151 | 152 | #ifdef _MSC_VER 153 | #pragma comment(lib, "xinput") 154 | #endif 155 | 156 | // Gamepad navigation mapping 157 | static void ImGui_ImplWin32_UpdateGamepads() 158 | { 159 | ImGuiIO& io = ImGui::GetIO(); 160 | memset(io.NavInputs, 0, sizeof(io.NavInputs)); 161 | if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) 162 | return; 163 | 164 | // Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow. 165 | // Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE. 166 | if (g_WantUpdateHasGamepad) 167 | { 168 | XINPUT_CAPABILITIES caps; 169 | g_HasGamepad = (XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS); 170 | g_WantUpdateHasGamepad = false; 171 | } 172 | 173 | XINPUT_STATE xinput_state; 174 | io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; 175 | if (g_HasGamepad && XInputGetState(0, &xinput_state) == ERROR_SUCCESS) 176 | { 177 | const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad; 178 | io.BackendFlags |= ImGuiBackendFlags_HasGamepad; 179 | 180 | #define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; } 181 | #define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; } 182 | MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); // Cross / A 183 | MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); // Circle / B 184 | MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); // Square / X 185 | MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); // Triangle / Y 186 | MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); // D-Pad Left 187 | MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); // D-Pad Right 188 | MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); // D-Pad Up 189 | MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); // D-Pad Down 190 | MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB 191 | MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB 192 | MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB 193 | MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB 194 | MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768); 195 | MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); 196 | MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); 197 | MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767); 198 | #undef MAP_BUTTON 199 | #undef MAP_ANALOG 200 | } 201 | } 202 | 203 | void ImGui_ImplWin32_NewFrame() 204 | { 205 | ImGuiIO& io = ImGui::GetIO(); 206 | IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame()."); 207 | 208 | // Setup display size (every frame to accommodate for window resizing) 209 | RECT rect; 210 | ::GetClientRect(g_hWnd, &rect); 211 | io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); 212 | 213 | // Setup time step 214 | INT64 current_time; 215 | ::QueryPerformanceCounter((LARGE_INTEGER *)¤t_time); 216 | io.DeltaTime = (float)(current_time - g_Time) / g_TicksPerSecond; 217 | g_Time = current_time; 218 | 219 | // Read keyboard modifiers inputs 220 | io.KeyCtrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; 221 | io.KeyShift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; 222 | io.KeyAlt = (::GetKeyState(VK_MENU) & 0x8000) != 0; 223 | io.KeySuper = false; 224 | // io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below. 225 | 226 | // Update OS mouse position 227 | ImGui_ImplWin32_UpdateMousePos(); 228 | 229 | // Update OS mouse cursor with the cursor requested by imgui 230 | ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); 231 | if (g_LastMouseCursor != mouse_cursor) 232 | { 233 | g_LastMouseCursor = mouse_cursor; 234 | ImGui_ImplWin32_UpdateMouseCursor(); 235 | } 236 | 237 | // Update game controllers (if enabled and available) 238 | ImGui_ImplWin32_UpdateGamepads(); 239 | } 240 | 241 | // Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions. 242 | #ifndef WM_MOUSEHWHEEL 243 | #define WM_MOUSEHWHEEL 0x020E 244 | #endif 245 | #ifndef DBT_DEVNODES_CHANGED 246 | #define DBT_DEVNODES_CHANGED 0x0007 247 | #endif 248 | 249 | // Process Win32 mouse/keyboard inputs. 250 | // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. 251 | // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. 252 | // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. 253 | // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. 254 | // PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds. 255 | // PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. 256 | IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 257 | { 258 | if (ImGui::GetCurrentContext() == NULL) 259 | return 0; 260 | 261 | ImGuiIO& io = ImGui::GetIO(); 262 | switch (msg) 263 | { 264 | case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: 265 | case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: 266 | case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: 267 | case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: 268 | { 269 | int button = 0; 270 | if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; } 271 | if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; } 272 | if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; } 273 | if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } 274 | if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL) 275 | ::SetCapture(hwnd); 276 | io.MouseDown[button] = true; 277 | return 0; 278 | } 279 | case WM_LBUTTONUP: 280 | case WM_RBUTTONUP: 281 | case WM_MBUTTONUP: 282 | case WM_XBUTTONUP: 283 | { 284 | int button = 0; 285 | if (msg == WM_LBUTTONUP) { button = 0; } 286 | if (msg == WM_RBUTTONUP) { button = 1; } 287 | if (msg == WM_MBUTTONUP) { button = 2; } 288 | if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } 289 | io.MouseDown[button] = false; 290 | if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd) 291 | ::ReleaseCapture(); 292 | return 0; 293 | } 294 | case WM_MOUSEWHEEL: 295 | io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; 296 | return 0; 297 | case WM_MOUSEHWHEEL: 298 | io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; 299 | return 0; 300 | case WM_KEYDOWN: 301 | case WM_SYSKEYDOWN: 302 | if (wParam < 256) 303 | io.KeysDown[wParam] = 1; 304 | return 0; 305 | case WM_KEYUP: 306 | case WM_SYSKEYUP: 307 | if (wParam < 256) 308 | io.KeysDown[wParam] = 0; 309 | return 0; 310 | case WM_CHAR: 311 | // You can also use ToAscii()+GetKeyboardState() to retrieve characters. 312 | io.AddInputCharacter((unsigned int)wParam); 313 | return 0; 314 | case WM_SETCURSOR: 315 | if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor()) 316 | return 1; 317 | return 0; 318 | case WM_DEVICECHANGE: 319 | if ((UINT)wParam == DBT_DEVNODES_CHANGED) 320 | g_WantUpdateHasGamepad = true; 321 | return 0; 322 | } 323 | return 0; 324 | } 325 | 326 | -------------------------------------------------------------------------------- /sdk/libraries/imgui/imgui_impl_win32.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Platform Binding for Windows (standard windows API for 32 and 64 bits applications) 2 | // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) 3 | 4 | // Implemented features: 5 | // [X] Platform: Clipboard support (for Win32 this is actually part of core imgui) 6 | // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 7 | // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). 8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 9 | 10 | #pragma once 11 | 12 | IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd); 13 | IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown(); 14 | IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame(); 15 | 16 | // Handler for Win32 messages, update mouse/keyboard data. 17 | // You may or not need this for your implementation, but it can serve as reference for handling inputs. 18 | // Intentionally commented out to avoid dragging dependencies on types. You can COPY this line into your .cpp code instead. 19 | /* 20 | IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 21 | */ 22 | -------------------------------------------------------------------------------- /sdk/libraries/imgui/imstb_rectpack.h: -------------------------------------------------------------------------------- 1 | // [DEAR IMGUI] 2 | // This is a slightly modified version of stb_rect_pack.h 1.00. 3 | // Those changes would need to be pushed into nothings/stb: 4 | // - Added STBRP__CDECL 5 | // Grep for [DEAR IMGUI] to find the changes. 6 | 7 | // stb_rect_pack.h - v1.00 - public domain - rectangle packing 8 | // Sean Barrett 2014 9 | // 10 | // Useful for e.g. packing rectangular textures into an atlas. 11 | // Does not do rotation. 12 | // 13 | // Not necessarily the awesomest packing method, but better than 14 | // the totally naive one in stb_truetype (which is primarily what 15 | // this is meant to replace). 16 | // 17 | // Has only had a few tests run, may have issues. 18 | // 19 | // More docs to come. 20 | // 21 | // No memory allocations; uses qsort() and assert() from stdlib. 22 | // Can override those by defining STBRP_SORT and STBRP_ASSERT. 23 | // 24 | // This library currently uses the Skyline Bottom-Left algorithm. 25 | // 26 | // Please note: better rectangle packers are welcome! Please 27 | // implement them to the same API, but with a different init 28 | // function. 29 | // 30 | // Credits 31 | // 32 | // Library 33 | // Sean Barrett 34 | // Minor features 35 | // Martins Mozeiko 36 | // github:IntellectualKitty 37 | // 38 | // Bugfixes / warning fixes 39 | // Jeremy Jaussaud 40 | // Fabian Giesen 41 | // 42 | // Version history: 43 | // 44 | // 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles 45 | // 0.99 (2019-02-07) warning fixes 46 | // 0.11 (2017-03-03) return packing success/fail result 47 | // 0.10 (2016-10-25) remove cast-away-const to avoid warnings 48 | // 0.09 (2016-08-27) fix compiler warnings 49 | // 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0) 50 | // 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0) 51 | // 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort 52 | // 0.05: added STBRP_ASSERT to allow replacing assert 53 | // 0.04: fixed minor bug in STBRP_LARGE_RECTS support 54 | // 0.01: initial release 55 | // 56 | // LICENSE 57 | // 58 | // See end of file for license information. 59 | 60 | ////////////////////////////////////////////////////////////////////////////// 61 | // 62 | // INCLUDE SECTION 63 | // 64 | 65 | #ifndef STB_INCLUDE_STB_RECT_PACK_H 66 | #define STB_INCLUDE_STB_RECT_PACK_H 67 | 68 | #define STB_RECT_PACK_VERSION 1 69 | 70 | #ifdef STBRP_STATIC 71 | #define STBRP_DEF static 72 | #else 73 | #define STBRP_DEF extern 74 | #endif 75 | 76 | #ifdef __cplusplus 77 | extern "C" { 78 | #endif 79 | 80 | typedef struct stbrp_context stbrp_context; 81 | typedef struct stbrp_node stbrp_node; 82 | typedef struct stbrp_rect stbrp_rect; 83 | 84 | #ifdef STBRP_LARGE_RECTS 85 | typedef int stbrp_coord; 86 | #else 87 | typedef unsigned short stbrp_coord; 88 | #endif 89 | 90 | STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); 91 | // Assign packed locations to rectangles. The rectangles are of type 92 | // 'stbrp_rect' defined below, stored in the array 'rects', and there 93 | // are 'num_rects' many of them. 94 | // 95 | // Rectangles which are successfully packed have the 'was_packed' flag 96 | // set to a non-zero value and 'x' and 'y' store the minimum location 97 | // on each axis (i.e. bottom-left in cartesian coordinates, top-left 98 | // if you imagine y increasing downwards). Rectangles which do not fit 99 | // have the 'was_packed' flag set to 0. 100 | // 101 | // You should not try to access the 'rects' array from another thread 102 | // while this function is running, as the function temporarily reorders 103 | // the array while it executes. 104 | // 105 | // To pack into another rectangle, you need to call stbrp_init_target 106 | // again. To continue packing into the same rectangle, you can call 107 | // this function again. Calling this multiple times with multiple rect 108 | // arrays will probably produce worse packing results than calling it 109 | // a single time with the full rectangle array, but the option is 110 | // available. 111 | // 112 | // The function returns 1 if all of the rectangles were successfully 113 | // packed and 0 otherwise. 114 | 115 | struct stbrp_rect 116 | { 117 | // reserved for your use: 118 | int id; 119 | 120 | // input: 121 | stbrp_coord w, h; 122 | 123 | // output: 124 | stbrp_coord x, y; 125 | int was_packed; // non-zero if valid packing 126 | 127 | }; // 16 bytes, nominally 128 | 129 | 130 | STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes); 131 | // Initialize a rectangle packer to: 132 | // pack a rectangle that is 'width' by 'height' in dimensions 133 | // using temporary storage provided by the array 'nodes', which is 'num_nodes' long 134 | // 135 | // You must call this function every time you start packing into a new target. 136 | // 137 | // There is no "shutdown" function. The 'nodes' memory must stay valid for 138 | // the following stbrp_pack_rects() call (or calls), but can be freed after 139 | // the call (or calls) finish. 140 | // 141 | // Note: to guarantee best results, either: 142 | // 1. make sure 'num_nodes' >= 'width' 143 | // or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' 144 | // 145 | // If you don't do either of the above things, widths will be quantized to multiples 146 | // of small integers to guarantee the algorithm doesn't run out of temporary storage. 147 | // 148 | // If you do #2, then the non-quantized algorithm will be used, but the algorithm 149 | // may run out of temporary storage and be unable to pack some rectangles. 150 | 151 | STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem); 152 | // Optionally call this function after init but before doing any packing to 153 | // change the handling of the out-of-temp-memory scenario, described above. 154 | // If you call init again, this will be reset to the default (false). 155 | 156 | 157 | STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic); 158 | // Optionally select which packing heuristic the library should use. Different 159 | // heuristics will produce better/worse results for different data sets. 160 | // If you call init again, this will be reset to the default. 161 | 162 | enum 163 | { 164 | STBRP_HEURISTIC_Skyline_default=0, 165 | STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, 166 | STBRP_HEURISTIC_Skyline_BF_sortHeight 167 | }; 168 | 169 | 170 | ////////////////////////////////////////////////////////////////////////////// 171 | // 172 | // the details of the following structures don't matter to you, but they must 173 | // be visible so you can handle the memory allocations for them 174 | 175 | struct stbrp_node 176 | { 177 | stbrp_coord x,y; 178 | stbrp_node *next; 179 | }; 180 | 181 | struct stbrp_context 182 | { 183 | int width; 184 | int height; 185 | int align; 186 | int init_mode; 187 | int heuristic; 188 | int num_nodes; 189 | stbrp_node *active_head; 190 | stbrp_node *free_head; 191 | stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' 192 | }; 193 | 194 | #ifdef __cplusplus 195 | } 196 | #endif 197 | 198 | #endif 199 | 200 | ////////////////////////////////////////////////////////////////////////////// 201 | // 202 | // IMPLEMENTATION SECTION 203 | // 204 | 205 | #ifdef STB_RECT_PACK_IMPLEMENTATION 206 | #ifndef STBRP_SORT 207 | #include 208 | #define STBRP_SORT qsort 209 | #endif 210 | 211 | #ifndef STBRP_ASSERT 212 | #include 213 | #define STBRP_ASSERT assert 214 | #endif 215 | 216 | // [DEAR IMGUI] Added STBRP__CDECL 217 | #ifdef _MSC_VER 218 | #define STBRP__NOTUSED(v) (void)(v) 219 | #define STBRP__CDECL __cdecl 220 | #else 221 | #define STBRP__NOTUSED(v) (void)sizeof(v) 222 | #define STBRP__CDECL 223 | #endif 224 | 225 | enum 226 | { 227 | STBRP__INIT_skyline = 1 228 | }; 229 | 230 | STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic) 231 | { 232 | switch (context->init_mode) { 233 | case STBRP__INIT_skyline: 234 | STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight); 235 | context->heuristic = heuristic; 236 | break; 237 | default: 238 | STBRP_ASSERT(0); 239 | } 240 | } 241 | 242 | STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem) 243 | { 244 | if (allow_out_of_mem) 245 | // if it's ok to run out of memory, then don't bother aligning them; 246 | // this gives better packing, but may fail due to OOM (even though 247 | // the rectangles easily fit). @TODO a smarter approach would be to only 248 | // quantize once we've hit OOM, then we could get rid of this parameter. 249 | context->align = 1; 250 | else { 251 | // if it's not ok to run out of memory, then quantize the widths 252 | // so that num_nodes is always enough nodes. 253 | // 254 | // I.e. num_nodes * align >= width 255 | // align >= width / num_nodes 256 | // align = ceil(width/num_nodes) 257 | 258 | context->align = (context->width + context->num_nodes-1) / context->num_nodes; 259 | } 260 | } 261 | 262 | STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes) 263 | { 264 | int i; 265 | #ifndef STBRP_LARGE_RECTS 266 | STBRP_ASSERT(width <= 0xffff && height <= 0xffff); 267 | #endif 268 | 269 | for (i=0; i < num_nodes-1; ++i) 270 | nodes[i].next = &nodes[i+1]; 271 | nodes[i].next = NULL; 272 | context->init_mode = STBRP__INIT_skyline; 273 | context->heuristic = STBRP_HEURISTIC_Skyline_default; 274 | context->free_head = &nodes[0]; 275 | context->active_head = &context->extra[0]; 276 | context->width = width; 277 | context->height = height; 278 | context->num_nodes = num_nodes; 279 | stbrp_setup_allow_out_of_mem(context, 0); 280 | 281 | // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) 282 | context->extra[0].x = 0; 283 | context->extra[0].y = 0; 284 | context->extra[0].next = &context->extra[1]; 285 | context->extra[1].x = (stbrp_coord) width; 286 | #ifdef STBRP_LARGE_RECTS 287 | context->extra[1].y = (1<<30); 288 | #else 289 | context->extra[1].y = 65535; 290 | #endif 291 | context->extra[1].next = NULL; 292 | } 293 | 294 | // find minimum y position if it starts at x1 295 | static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste) 296 | { 297 | stbrp_node *node = first; 298 | int x1 = x0 + width; 299 | int min_y, visited_width, waste_area; 300 | 301 | STBRP__NOTUSED(c); 302 | 303 | STBRP_ASSERT(first->x <= x0); 304 | 305 | #if 0 306 | // skip in case we're past the node 307 | while (node->next->x <= x0) 308 | ++node; 309 | #else 310 | STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency 311 | #endif 312 | 313 | STBRP_ASSERT(node->x <= x0); 314 | 315 | min_y = 0; 316 | waste_area = 0; 317 | visited_width = 0; 318 | while (node->x < x1) { 319 | if (node->y > min_y) { 320 | // raise min_y higher. 321 | // we've accounted for all waste up to min_y, 322 | // but we'll now add more waste for everything we've visted 323 | waste_area += visited_width * (node->y - min_y); 324 | min_y = node->y; 325 | // the first time through, visited_width might be reduced 326 | if (node->x < x0) 327 | visited_width += node->next->x - x0; 328 | else 329 | visited_width += node->next->x - node->x; 330 | } else { 331 | // add waste area 332 | int under_width = node->next->x - node->x; 333 | if (under_width + visited_width > width) 334 | under_width = width - visited_width; 335 | waste_area += under_width * (min_y - node->y); 336 | visited_width += under_width; 337 | } 338 | node = node->next; 339 | } 340 | 341 | *pwaste = waste_area; 342 | return min_y; 343 | } 344 | 345 | typedef struct 346 | { 347 | int x,y; 348 | stbrp_node **prev_link; 349 | } stbrp__findresult; 350 | 351 | static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height) 352 | { 353 | int best_waste = (1<<30), best_x, best_y = (1 << 30); 354 | stbrp__findresult fr; 355 | stbrp_node **prev, *node, *tail, **best = NULL; 356 | 357 | // align to multiple of c->align 358 | width = (width + c->align - 1); 359 | width -= width % c->align; 360 | STBRP_ASSERT(width % c->align == 0); 361 | 362 | // if it can't possibly fit, bail immediately 363 | if (width > c->width || height > c->height) { 364 | fr.prev_link = NULL; 365 | fr.x = fr.y = 0; 366 | return fr; 367 | } 368 | 369 | node = c->active_head; 370 | prev = &c->active_head; 371 | while (node->x + width <= c->width) { 372 | int y,waste; 373 | y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste); 374 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL 375 | // bottom left 376 | if (y < best_y) { 377 | best_y = y; 378 | best = prev; 379 | } 380 | } else { 381 | // best-fit 382 | if (y + height <= c->height) { 383 | // can only use it if it first vertically 384 | if (y < best_y || (y == best_y && waste < best_waste)) { 385 | best_y = y; 386 | best_waste = waste; 387 | best = prev; 388 | } 389 | } 390 | } 391 | prev = &node->next; 392 | node = node->next; 393 | } 394 | 395 | best_x = (best == NULL) ? 0 : (*best)->x; 396 | 397 | // if doing best-fit (BF), we also have to try aligning right edge to each node position 398 | // 399 | // e.g, if fitting 400 | // 401 | // ____________________ 402 | // |____________________| 403 | // 404 | // into 405 | // 406 | // | | 407 | // | ____________| 408 | // |____________| 409 | // 410 | // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned 411 | // 412 | // This makes BF take about 2x the time 413 | 414 | if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) { 415 | tail = c->active_head; 416 | node = c->active_head; 417 | prev = &c->active_head; 418 | // find first node that's admissible 419 | while (tail->x < width) 420 | tail = tail->next; 421 | while (tail) { 422 | int xpos = tail->x - width; 423 | int y,waste; 424 | STBRP_ASSERT(xpos >= 0); 425 | // find the left position that matches this 426 | while (node->next->x <= xpos) { 427 | prev = &node->next; 428 | node = node->next; 429 | } 430 | STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); 431 | y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); 432 | if (y + height <= c->height) { 433 | if (y <= best_y) { 434 | if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) { 435 | best_x = xpos; 436 | STBRP_ASSERT(y <= best_y); 437 | best_y = y; 438 | best_waste = waste; 439 | best = prev; 440 | } 441 | } 442 | } 443 | tail = tail->next; 444 | } 445 | } 446 | 447 | fr.prev_link = best; 448 | fr.x = best_x; 449 | fr.y = best_y; 450 | return fr; 451 | } 452 | 453 | static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height) 454 | { 455 | // find best position according to heuristic 456 | stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); 457 | stbrp_node *node, *cur; 458 | 459 | // bail if: 460 | // 1. it failed 461 | // 2. the best node doesn't fit (we don't always check this) 462 | // 3. we're out of memory 463 | if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) { 464 | res.prev_link = NULL; 465 | return res; 466 | } 467 | 468 | // on success, create new node 469 | node = context->free_head; 470 | node->x = (stbrp_coord) res.x; 471 | node->y = (stbrp_coord) (res.y + height); 472 | 473 | context->free_head = node->next; 474 | 475 | // insert the new node into the right starting point, and 476 | // let 'cur' point to the remaining nodes needing to be 477 | // stiched back in 478 | 479 | cur = *res.prev_link; 480 | if (cur->x < res.x) { 481 | // preserve the existing one, so start testing with the next one 482 | stbrp_node *next = cur->next; 483 | cur->next = node; 484 | cur = next; 485 | } else { 486 | *res.prev_link = node; 487 | } 488 | 489 | // from here, traverse cur and free the nodes, until we get to one 490 | // that shouldn't be freed 491 | while (cur->next && cur->next->x <= res.x + width) { 492 | stbrp_node *next = cur->next; 493 | // move the current node to the free list 494 | cur->next = context->free_head; 495 | context->free_head = cur; 496 | cur = next; 497 | } 498 | 499 | // stitch the list back in 500 | node->next = cur; 501 | 502 | if (cur->x < res.x + width) 503 | cur->x = (stbrp_coord) (res.x + width); 504 | 505 | #ifdef _DEBUG 506 | cur = context->active_head; 507 | while (cur->x < context->width) { 508 | STBRP_ASSERT(cur->x < cur->next->x); 509 | cur = cur->next; 510 | } 511 | STBRP_ASSERT(cur->next == NULL); 512 | 513 | { 514 | int count=0; 515 | cur = context->active_head; 516 | while (cur) { 517 | cur = cur->next; 518 | ++count; 519 | } 520 | cur = context->free_head; 521 | while (cur) { 522 | cur = cur->next; 523 | ++count; 524 | } 525 | STBRP_ASSERT(count == context->num_nodes+2); 526 | } 527 | #endif 528 | 529 | return res; 530 | } 531 | 532 | // [DEAR IMGUI] Added STBRP__CDECL 533 | static int STBRP__CDECL rect_height_compare(const void *a, const void *b) 534 | { 535 | const stbrp_rect *p = (const stbrp_rect *) a; 536 | const stbrp_rect *q = (const stbrp_rect *) b; 537 | if (p->h > q->h) 538 | return -1; 539 | if (p->h < q->h) 540 | return 1; 541 | return (p->w > q->w) ? -1 : (p->w < q->w); 542 | } 543 | 544 | // [DEAR IMGUI] Added STBRP__CDECL 545 | static int STBRP__CDECL rect_original_order(const void *a, const void *b) 546 | { 547 | const stbrp_rect *p = (const stbrp_rect *) a; 548 | const stbrp_rect *q = (const stbrp_rect *) b; 549 | return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); 550 | } 551 | 552 | #ifdef STBRP_LARGE_RECTS 553 | #define STBRP__MAXVAL 0xffffffff 554 | #else 555 | #define STBRP__MAXVAL 0xffff 556 | #endif 557 | 558 | STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) 559 | { 560 | int i, all_rects_packed = 1; 561 | 562 | // we use the 'was_packed' field internally to allow sorting/unsorting 563 | for (i=0; i < num_rects; ++i) { 564 | rects[i].was_packed = i; 565 | } 566 | 567 | // sort according to heuristic 568 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare); 569 | 570 | for (i=0; i < num_rects; ++i) { 571 | if (rects[i].w == 0 || rects[i].h == 0) { 572 | rects[i].x = rects[i].y = 0; // empty rect needs no space 573 | } else { 574 | stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); 575 | if (fr.prev_link) { 576 | rects[i].x = (stbrp_coord) fr.x; 577 | rects[i].y = (stbrp_coord) fr.y; 578 | } else { 579 | rects[i].x = rects[i].y = STBRP__MAXVAL; 580 | } 581 | } 582 | } 583 | 584 | // unsort 585 | STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order); 586 | 587 | // set was_packed flags and all_rects_packed status 588 | for (i=0; i < num_rects; ++i) { 589 | rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); 590 | if (!rects[i].was_packed) 591 | all_rects_packed = 0; 592 | } 593 | 594 | // return the all_rects_packed status 595 | return all_rects_packed; 596 | } 597 | #endif 598 | 599 | /* 600 | ------------------------------------------------------------------------------ 601 | This software is available under 2 licenses -- choose whichever you prefer. 602 | ------------------------------------------------------------------------------ 603 | ALTERNATIVE A - MIT License 604 | Copyright (c) 2017 Sean Barrett 605 | Permission is hereby granted, free of charge, to any person obtaining a copy of 606 | this software and associated documentation files (the "Software"), to deal in 607 | the Software without restriction, including without limitation the rights to 608 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 609 | of the Software, and to permit persons to whom the Software is furnished to do 610 | so, subject to the following conditions: 611 | The above copyright notice and this permission notice shall be included in all 612 | copies or substantial portions of the Software. 613 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 614 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 615 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 616 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 617 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 618 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 619 | SOFTWARE. 620 | ------------------------------------------------------------------------------ 621 | ALTERNATIVE B - Public Domain (www.unlicense.org) 622 | This is free and unencumbered software released into the public domain. 623 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 624 | software, either in source code form or as a compiled binary, for any purpose, 625 | commercial or non-commercial, and by any means. 626 | In jurisdictions that recognize copyright laws, the author or authors of this 627 | software dedicate any and all copyright interest in the software to the public 628 | domain. We make this dedication for the benefit of the public at large and to 629 | the detriment of our heirs and successors. We intend this dedication to be an 630 | overt act of relinquishment in perpetuity of all present and future rights to 631 | this software under copyright law. 632 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 633 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 634 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 635 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 636 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 637 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 638 | ------------------------------------------------------------------------------ 639 | */ 640 | -------------------------------------------------------------------------------- /sdk/libraries/xorstr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 - 2018 Justas Masiulis 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef JM_XORSTR_HPP 18 | #define JM_XORSTR_HPP 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #define xorstr(str) \ 26 | ::jm::make_xorstr( \ 27 | []() { return str; }, \ 28 | std::make_index_sequence{}, \ 29 | std::make_index_sequence<::jm::detail::_buffer_size()>{}) 30 | #define xorstr_(str) xorstr(str).crypt_get() 31 | 32 | #ifdef _MSC_VER 33 | #define XORSTR_FORCEINLINE __forceinline 34 | #else 35 | #define XORSTR_FORCEINLINE __attribute__((always_inline)) 36 | #endif 37 | 38 | // you can define this macro to get possibly faster code on gcc/clang 39 | // at the expense of constants being put into data section. 40 | #if !defined(XORSTR_ALLOW_DATA) 41 | // MSVC - no volatile 42 | // GCC and clang - volatile everywhere 43 | #if defined(__clang__) || defined(__GNUC__) 44 | #define XORSTR_VOLATILE volatile 45 | #endif 46 | 47 | #endif 48 | #ifndef XORSTR_VOLATILE 49 | #define XORSTR_VOLATILE 50 | #endif 51 | 52 | namespace jm { 53 | 54 | namespace detail { 55 | 56 | template 57 | struct unsigned_; 58 | 59 | template<> 60 | struct unsigned_<1> { 61 | using type = std::uint8_t; 62 | }; 63 | template<> 64 | struct unsigned_<2> { 65 | using type = std::uint16_t; 66 | }; 67 | template<> 68 | struct unsigned_<4> { 69 | using type = std::uint32_t; 70 | }; 71 | 72 | template 73 | struct pack_value_type { 74 | using type = decltype(C); 75 | }; 76 | 77 | template 78 | constexpr std::size_t _buffer_size() 79 | { 80 | return ((Size / 16) + (Size % 16 != 0)) * 2; 81 | } 82 | 83 | template 84 | struct tstring_ { 85 | using value_type = typename pack_value_type::type; 86 | constexpr static std::size_t size = sizeof...(Cs); 87 | constexpr static value_type str[size] = { Cs... }; 88 | 89 | constexpr static std::size_t buffer_size = _buffer_size(); 90 | constexpr static std::size_t buffer_align = 91 | #ifndef JM_XORSTR_DISABLE_AVX_INTRINSICS 92 | ((sizeof(str) > 16) ? 32 : 16); 93 | #else 94 | 16; 95 | #endif 96 | }; 97 | 98 | template 99 | struct _ki { 100 | constexpr static std::size_t idx = I; 101 | constexpr static std::uint64_t key = K; 102 | }; 103 | 104 | template 105 | constexpr std::uint32_t key4() noexcept 106 | { 107 | std::uint32_t value = Seed; 108 | for (char c : __TIME__) 109 | value = static_cast((value ^ c) * 16777619ull); 110 | return value; 111 | } 112 | 113 | template 114 | constexpr std::uint64_t key8() 115 | { 116 | constexpr auto first_part = key4<2166136261 + S>(); 117 | constexpr auto second_part = key4(); 118 | return (static_cast(first_part) << 32) | second_part; 119 | } 120 | 121 | // clang and gcc try really hard to place the constants in data 122 | // sections. to counter that there was a need to create an intermediate 123 | // constexpr string and then copy it into a non constexpr container with 124 | // volatile storage so that the constants would be placed directly into 125 | // code. 126 | template 127 | struct string_storage { 128 | std::uint64_t storage[T::buffer_size]; 129 | 130 | XORSTR_FORCEINLINE constexpr string_storage() noexcept : storage{ Keys... } 131 | { 132 | using cast_type = 133 | typename unsigned_::type; 134 | constexpr auto value_size = sizeof(typename T::value_type); 135 | // puts the string into 64 bit integer blocks in a constexpr 136 | // fashion 137 | for (std::size_t i = 0; i < T::size; ++i) 138 | storage[i / (8 / value_size)] ^= 139 | (std::uint64_t{ static_cast(T::str[i]) } 140 | << ((i % (8 / value_size)) * 8 * value_size)); 141 | } 142 | }; 143 | 144 | } // namespace detail 145 | 146 | template 147 | class xor_string { 148 | alignas(T::buffer_align) std::uint64_t _storage[T::buffer_size]; 149 | 150 | // _single functions needed because MSVC crashes without them 151 | XORSTR_FORCEINLINE void _crypt_256_single(const std::uint64_t* keys, 152 | std::uint64_t* storage) noexcept 153 | 154 | { 155 | _mm256_store_si256( 156 | reinterpret_cast<__m256i*>(storage), 157 | _mm256_xor_si256( 158 | _mm256_load_si256(reinterpret_cast(storage)), 159 | _mm256_load_si256(reinterpret_cast(keys)))); 160 | } 161 | 162 | template 163 | XORSTR_FORCEINLINE void _crypt_256(const std::uint64_t* keys, 164 | std::index_sequence) noexcept 165 | { 166 | (_crypt_256_single(keys + Idxs * 4, _storage + Idxs * 4), ...); 167 | } 168 | 169 | XORSTR_FORCEINLINE void _crypt_128_single(const std::uint64_t* keys, 170 | std::uint64_t* storage) noexcept 171 | { 172 | _mm_store_si128( 173 | reinterpret_cast<__m128i*>(storage), 174 | _mm_xor_si128(_mm_load_si128(reinterpret_cast(storage)), 175 | _mm_load_si128(reinterpret_cast(keys)))); 176 | } 177 | 178 | template 179 | XORSTR_FORCEINLINE void _crypt_128(const std::uint64_t* keys, 180 | std::index_sequence) noexcept 181 | { 182 | (_crypt_128_single(keys + Idxs * 2, _storage + Idxs * 2), ...); 183 | } 184 | 185 | // loop generates vectorized code which places constants in data dir 186 | XORSTR_FORCEINLINE constexpr void _copy() noexcept 187 | { 188 | constexpr detail::string_storage storage; 189 | static_cast(std::initializer_list{ 190 | (const_cast(_storage))[Keys::idx] = 191 | storage.storage[Keys::idx]... }); 192 | } 193 | 194 | public: 195 | using value_type = typename T::value_type; 196 | using size_type = std::size_t; 197 | using pointer = value_type*; 198 | using const_pointer = const pointer; 199 | 200 | XORSTR_FORCEINLINE xor_string() noexcept { _copy(); } 201 | 202 | XORSTR_FORCEINLINE constexpr size_type size() const noexcept 203 | { 204 | return T::size - 1; 205 | } 206 | 207 | XORSTR_FORCEINLINE void crypt() noexcept 208 | { 209 | alignas(T::buffer_align) std::uint64_t keys[T::buffer_size]; 210 | static_cast(std::initializer_list{ 211 | (const_cast(keys))[Keys::idx] = 212 | Keys::key... }); 213 | 214 | _copy(); 215 | 216 | #ifndef JM_XORSTR_DISABLE_AVX_INTRINSICS 217 | _crypt_256(keys, std::make_index_sequence{}); 218 | if constexpr (T::buffer_size % 4 != 0) 219 | _crypt_128(keys, std::index_sequence{}); 220 | #else 221 | _crypt_128(keys, std::make_index_sequence{}); 222 | #endif 223 | } 224 | 225 | XORSTR_FORCEINLINE const_pointer get() const noexcept 226 | { 227 | return reinterpret_cast(_storage); 228 | } 229 | 230 | XORSTR_FORCEINLINE const_pointer crypt_get() noexcept 231 | { 232 | crypt(); 233 | return reinterpret_cast(_storage); 234 | } 235 | }; 236 | 237 | template 238 | XORSTR_FORCEINLINE constexpr auto 239 | make_xorstr(Tstr str_lambda, 240 | std::index_sequence, 241 | std::index_sequence) noexcept 242 | { 243 | return xor_string, 244 | detail::_ki()>...>{}; 245 | } 246 | 247 | } // namespace jm 248 | 249 | #endif // include guard -------------------------------------------------------------------------------- /sdk/mapper/mapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | namespace sdk { 5 | namespace mapper { 6 | 7 | namespace classes { 8 | 9 | class c_classentry { 10 | 11 | private: 12 | 13 | std::unordered_map objects; 14 | 15 | public: 16 | 17 | c_classentry(std::unordered_map entries) : objects(entries) {} 18 | }; 19 | 20 | } 21 | 22 | class c_mapper { 23 | public: 24 | std::unordered_map classes; 25 | 26 | 27 | c_mapper(); 28 | ~c_mapper(); 29 | 30 | 31 | }; 32 | 33 | extern std::shared_ptr instance; 34 | } 35 | } 36 | */ -------------------------------------------------------------------------------- /sdk/minecraft/axisaligned/axisalignedbb.cpp: -------------------------------------------------------------------------------- 1 | #include "axisalignedbb.h" 2 | 3 | #include "../../../main/gasper.h" 4 | 5 | c_axisalignedbb::c_axisalignedbb(jobject obj) 6 | { 7 | axis_aligned_obj = obj; 8 | } 9 | 10 | c_axisalignedbb::~c_axisalignedbb() 11 | { 12 | gasper::instance->get_env()->DeleteLocalRef(axis_aligned_obj); 13 | } 14 | 15 | s_axisalignedbb c_axisalignedbb::get_native_boundingbox() 16 | { 17 | auto this_clazz = gasper::instance->get_env()->GetObjectClass(axis_aligned_obj); 18 | 19 | auto minX_fid = gasper::instance->get_env()->GetFieldID(this_clazz, BADLION_CLIENT ? xorstr_("a") : xorstr_("field_72340_a"), xorstr_("D")), 20 | minY_fid = gasper::instance->get_env()->GetFieldID(this_clazz, BADLION_CLIENT ? xorstr_("b") : xorstr_("field_72338_b"), xorstr_("D")), 21 | minZ_fid = gasper::instance->get_env()->GetFieldID(this_clazz, BADLION_CLIENT ? xorstr_("c") : xorstr_("field_72339_c"), xorstr_("D")); 22 | 23 | auto maxX_fid = gasper::instance->get_env()->GetFieldID(this_clazz, BADLION_CLIENT ? xorstr_("d") : xorstr_("field_72336_d"), xorstr_("D")), 24 | maxY_fid = gasper::instance->get_env()->GetFieldID(this_clazz, BADLION_CLIENT ? xorstr_("e") : xorstr_("field_72337_e"), xorstr_("D")), 25 | maxZ_fid = gasper::instance->get_env()->GetFieldID(this_clazz, BADLION_CLIENT ? xorstr_("f") : xorstr_("field_72334_f"), xorstr_("D")); 26 | 27 | gasper::instance->get_env()->DeleteLocalRef(this_clazz); 28 | 29 | s_axisalignedbb bb{}; 30 | bb.minX = gasper::instance->get_env()->GetDoubleField(axis_aligned_obj, minX_fid); 31 | bb.minY = gasper::instance->get_env()->GetDoubleField(axis_aligned_obj, minY_fid); 32 | bb.minZ = gasper::instance->get_env()->GetDoubleField(axis_aligned_obj, minZ_fid); 33 | 34 | bb.maxX = gasper::instance->get_env()->GetDoubleField(axis_aligned_obj, maxX_fid); 35 | bb.maxY = gasper::instance->get_env()->GetDoubleField(axis_aligned_obj, maxY_fid); 36 | bb.maxZ = gasper::instance->get_env()->GetDoubleField(axis_aligned_obj, maxZ_fid); 37 | 38 | return bb; 39 | } 40 | 41 | void c_axisalignedbb::set_native_boundingbox(s_axisalignedbb target) 42 | { 43 | set(target.minX, target.minY, target.minZ, target.maxX, target.maxY, target.maxZ); 44 | } 45 | 46 | void c_axisalignedbb::set(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) 47 | { 48 | auto this_clazz = gasper::instance->get_env()->GetObjectClass(axis_aligned_obj); 49 | 50 | auto minX_fid = gasper::instance->get_env()->GetFieldID(this_clazz, BADLION_CLIENT ? xorstr_("a") : xorstr_("field_72340_a"), xorstr_("D")), 51 | minY_fid = gasper::instance->get_env()->GetFieldID(this_clazz, BADLION_CLIENT ? xorstr_("b") : xorstr_("field_72338_b"), xorstr_("D")), 52 | minZ_fid = gasper::instance->get_env()->GetFieldID(this_clazz, BADLION_CLIENT ? xorstr_("c") : xorstr_("field_72339_c"), xorstr_("D")); 53 | 54 | auto maxX_fid = gasper::instance->get_env()->GetFieldID(this_clazz, BADLION_CLIENT ? xorstr_("d") : xorstr_("field_72336_d"), xorstr_("D")), 55 | maxY_fid = gasper::instance->get_env()->GetFieldID(this_clazz, BADLION_CLIENT ? xorstr_("e") : xorstr_("field_72337_e"), xorstr_("D")), 56 | maxZ_fid = gasper::instance->get_env()->GetFieldID(this_clazz, BADLION_CLIENT ? xorstr_("f") : xorstr_("field_72334_f"), xorstr_("D")); 57 | 58 | gasper::instance->get_env()->DeleteLocalRef(this_clazz); 59 | 60 | gasper::instance->get_env()->SetDoubleField(axis_aligned_obj, minX_fid, minX); 61 | gasper::instance->get_env()->SetDoubleField(axis_aligned_obj, minY_fid, minY); 62 | gasper::instance->get_env()->SetDoubleField(axis_aligned_obj, minZ_fid, minZ); 63 | 64 | gasper::instance->get_env()->SetDoubleField(axis_aligned_obj, maxX_fid, maxX); 65 | gasper::instance->get_env()->SetDoubleField(axis_aligned_obj, maxY_fid, maxY); 66 | gasper::instance->get_env()->SetDoubleField(axis_aligned_obj, maxZ_fid, maxZ); 67 | 68 | } 69 | -------------------------------------------------------------------------------- /sdk/minecraft/axisaligned/axisalignedbb.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../minecraft.h" 4 | 5 | struct s_axisalignedbb { 6 | double minX, minY, minZ, 7 | maxX, maxY, maxZ; 8 | }; 9 | 10 | class c_axisalignedbb { 11 | private: 12 | jobject axis_aligned_obj; 13 | public: 14 | c_axisalignedbb(jobject); 15 | ~c_axisalignedbb(); 16 | 17 | s_axisalignedbb get_native_boundingbox(); 18 | void set_native_boundingbox(s_axisalignedbb target); 19 | 20 | void set(double minX, double minY, double minZ, double maxX, double maxY, double maxZ); 21 | }; -------------------------------------------------------------------------------- /sdk/minecraft/minecraft.cpp: -------------------------------------------------------------------------------- 1 | #include "minecraft.h" 2 | #include "../../main/gasper.h" 3 | 4 | std::unique_ptr sdk::instance; 5 | 6 | #pragma warning(disable:4996) 7 | 8 | jobject sdk::c_minecraft::get_minecraft() 9 | { 10 | jobject res; 11 | if (!BADLION_CLIENT) { 12 | auto cls = gasper::instance->find_class(xorstr_("net.minecraft.client.Minecraft")); 13 | auto mc_fid = gasper::instance->get_env()->GetStaticFieldID(cls, xorstr_("field_71432_P"), xorstr_("Lnet/minecraft/client/Minecraft;")); 14 | 15 | res = gasper::instance->get_env()->GetStaticObjectField(cls, mc_fid); 16 | 17 | gasper::instance->get_env()->DeleteLocalRef(cls); 18 | 19 | return res; 20 | } 21 | 22 | auto cls = gasper::instance->find_class(xorstr_("ave")); 23 | auto ave = gasper::instance->get_env()->GetStaticFieldID(cls, xorstr_("S"), xorstr_("Lave;")); 24 | 25 | res = gasper::instance->get_env()->GetStaticObjectField(cls, ave); 26 | 27 | gasper::instance->get_env()->DeleteLocalRef(cls); 28 | 29 | 30 | return res; 31 | } 32 | 33 | jobject sdk::c_minecraft::get_player(jobject mc) { 34 | jobject res; 35 | 36 | if (!BADLION_CLIENT) { 37 | auto cls = gasper::instance->find_class(xorstr_("net.minecraft.client.Minecraft")); 38 | auto player_fid = gasper::instance->get_env()->GetFieldID(cls, xorstr_("field_71439_g"), xorstr_("Lnet/minecraft/client/entity/EntityClientPlayerMP;")); 39 | 40 | res = gasper::instance->get_env()->GetObjectField(mc, player_fid); 41 | 42 | gasper::instance->get_env()->DeleteLocalRef(cls); 43 | return res; 44 | } 45 | 46 | auto cls = gasper::instance->find_class(xorstr_("ave")); 47 | auto player_fid = gasper::instance->get_env()->GetFieldID(cls, xorstr_("h"), xorstr_("Lbew;")); 48 | 49 | res = gasper::instance->get_env()->GetObjectField(mc, player_fid); 50 | 51 | gasper::instance->get_env()->DeleteLocalRef(cls); 52 | 53 | return res; 54 | } 55 | 56 | jobject sdk::c_minecraft::get_world(jobject mc) { 57 | jobject res; 58 | 59 | if (!BADLION_CLIENT) { 60 | auto cls = gasper::instance->find_class(xorstr_("net.minecraft.client.Minecraft")); 61 | auto world_fid = gasper::instance->get_env()->GetFieldID(cls, xorstr_("field_71441_e"), xorstr_("Lnet/minecraft/client/multiplayer/WorldClient;")); 62 | 63 | res = gasper::instance->get_env()->GetObjectField(mc, world_fid); 64 | 65 | gasper::instance->get_env()->DeleteLocalRef(cls); 66 | return res; 67 | } 68 | 69 | auto cls = gasper::instance->find_class(xorstr_("ave")); 70 | auto world_fid = gasper::instance->get_env()->GetFieldID(cls, xorstr_("f"), xorstr_("Lbdb;")); 71 | 72 | res = gasper::instance->get_env()->GetObjectField(mc, world_fid); 73 | 74 | gasper::instance->get_env()->DeleteLocalRef(cls); 75 | 76 | return res; 77 | } 78 | 79 | jobject sdk::c_minecraft::get_current_screen(jobject mc) { 80 | jobject res; 81 | 82 | if (!BADLION_CLIENT) { 83 | auto cls = gasper::instance->find_class(xorstr_("net.minecraft.client.Minecraft")); 84 | auto current_screen_fid = gasper::instance->get_env()->GetFieldID(cls, xorstr_("field_71462_r"), xorstr_("Lnet/minecraft/client/gui/GuiScreen;")); 85 | 86 | res = gasper::instance->get_env()->GetObjectField(mc, current_screen_fid); 87 | 88 | gasper::instance->get_env()->DeleteLocalRef(cls); 89 | return res; 90 | } 91 | 92 | auto cls = gasper::instance->find_class(xorstr_("ave")); 93 | auto current_screen_fid = gasper::instance->get_env()->GetFieldID(cls, xorstr_("m"), xorstr_("Laxu;")); 94 | 95 | res = gasper::instance->get_env()->GetObjectField(mc, current_screen_fid); 96 | 97 | gasper::instance->get_env()->DeleteLocalRef(cls); 98 | 99 | return res; 100 | } 101 | 102 | jobject sdk::c_minecraft::get_entity_over(jobject mc) { 103 | jobject res = nullptr; 104 | 105 | auto cls = gasper::instance->find_class(!BADLION_CLIENT ? xorstr_("net.minecraft.client.Minecraft") : xorstr_("ave")); 106 | 107 | auto object_mouse_over_fid = gasper::instance->get_env()->GetFieldID(cls, !BADLION_CLIENT ? xorstr_("field_71476_x") : xorstr_("s"), !BADLION_CLIENT ? xorstr_("Lnet/minecraft/util/MovingObjectPosition;") : xorstr_("Lauh;")); 108 | 109 | auto object_mouse_over = gasper::instance->get_env()->GetObjectField(mc, object_mouse_over_fid); 110 | 111 | if (!object_mouse_over) 112 | return res; 113 | 114 | auto mop_entityhit_cls = gasper::instance->get_env()->GetObjectClass(object_mouse_over); 115 | 116 | auto entity_hit_fid = gasper::instance->get_env()->GetFieldID(mop_entityhit_cls, !BADLION_CLIENT ? xorstr_("field_72308_g") : xorstr_("d"), !BADLION_CLIENT ? xorstr_("Lnet/minecraft/entity/Entity;") : xorstr_("Lpk;")); 117 | 118 | gasper::instance->get_env()->DeleteLocalRef(cls); 119 | gasper::instance->get_env()->DeleteLocalRef(mop_entityhit_cls); 120 | 121 | res = gasper::instance->get_env()->GetObjectField(object_mouse_over, entity_hit_fid); 122 | 123 | gasper::instance->get_env()->DeleteLocalRef(object_mouse_over); 124 | 125 | return res; 126 | } -------------------------------------------------------------------------------- /sdk/minecraft/minecraft.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../includes.h" 4 | 5 | namespace sdk { 6 | class c_minecraft { 7 | private: 8 | public: 9 | 10 | jobject get_minecraft(); 11 | 12 | jobject get_player(jobject); 13 | 14 | jobject get_world(jobject mc); 15 | 16 | jobject get_current_screen(jobject mc); 17 | 18 | jobject get_entity_over(jobject mc); 19 | 20 | }; 21 | 22 | extern std::unique_ptr instance; 23 | } -------------------------------------------------------------------------------- /sdk/minecraft/player/player.cpp: -------------------------------------------------------------------------------- 1 | #include "player.h" 2 | 3 | #include "../../../main/gasper.h" 4 | #include "../axisaligned/axisalignedbb.h" 5 | 6 | c_player::c_player(jobject obj) 7 | { 8 | player_obj = obj; 9 | } 10 | 11 | c_player::~c_player() 12 | { 13 | gasper::instance->get_env()->DeleteLocalRef(player_obj); 14 | } 15 | 16 | bool c_player::is_invisible() 17 | { 18 | jmethodID invisible_md = gasper::instance->get_env()->GetMethodID(gasper::instance->get_env()->GetObjectClass(player_obj), BADLION_CLIENT ? xorstr_("ax") : xorstr_("func_82150_aj"), xorstr_("()Z")); 19 | 20 | return gasper::instance->get_env()->CallBooleanMethod(player_obj, invisible_md); 21 | } 22 | 23 | float c_player::get_hurt_time() 24 | { 25 | jfieldID hurttime_fid = gasper::instance->get_env()->GetFieldID(gasper::instance->get_env()->GetObjectClass(player_obj), BADLION_CLIENT ? xorstr_("au") : xorstr_("field_70737_aN"), xorstr_("F")); 26 | 27 | return gasper::instance->get_env()->GetFloatField(player_obj, hurttime_fid); 28 | } 29 | 30 | float c_player::get_moveforward() 31 | { 32 | jfieldID hurttime_fid = gasper::instance->get_env()->GetFieldID(gasper::instance->get_env()->GetObjectClass(player_obj), BADLION_CLIENT ? xorstr_("ba") : xorstr_("field_70701_bs"), xorstr_("F")); 33 | 34 | return gasper::instance->get_env()->GetFloatField(player_obj, hurttime_fid); 35 | } 36 | 37 | float c_player::get_movestrafe() 38 | { 39 | jfieldID hurttime_fid = gasper::instance->get_env()->GetFieldID(gasper::instance->get_env()->GetObjectClass(player_obj), BADLION_CLIENT ? xorstr_("aZ") : xorstr_("field_70702_br"), xorstr_("F")); 40 | 41 | return gasper::instance->get_env()->GetFloatField(player_obj, hurttime_fid); 42 | } 43 | 44 | sdk::vec3d c_player::get_motion_vector() 45 | { 46 | auto mox_fid = gasper::instance->get_env()->GetFieldID(gasper::instance->get_env()->GetObjectClass(player_obj), BADLION_CLIENT ? xorstr_("v") : xorstr_("field_70159_w"), xorstr_("D")); 47 | auto moy_fid = gasper::instance->get_env()->GetFieldID(gasper::instance->get_env()->GetObjectClass(player_obj), BADLION_CLIENT ? xorstr_("w") : xorstr_("field_70181_x"), xorstr_("D")); 48 | auto moz_fid = gasper::instance->get_env()->GetFieldID(gasper::instance->get_env()->GetObjectClass(player_obj), BADLION_CLIENT ? xorstr_("x") : xorstr_("field_70179_y"), xorstr_("D")); 49 | 50 | return sdk::vec3d{ 51 | gasper::instance->get_env()->GetDoubleField(player_obj, mox_fid), 52 | gasper::instance->get_env()->GetDoubleField(player_obj, moy_fid), 53 | gasper::instance->get_env()->GetDoubleField(player_obj, moz_fid) 54 | }; 55 | } 56 | 57 | void c_player::get_motion_vector(sdk::vec3d vec) 58 | { 59 | auto mox_fid = gasper::instance->get_env()->GetFieldID(gasper::instance->get_env()->GetObjectClass(player_obj), BADLION_CLIENT ? xorstr_("v") : xorstr_("field_70159_w"), xorstr_("D")); 60 | auto moy_fid = gasper::instance->get_env()->GetFieldID(gasper::instance->get_env()->GetObjectClass(player_obj), BADLION_CLIENT ? xorstr_("w") : xorstr_("field_70181_x"), xorstr_("D")); 61 | auto moz_fid = gasper::instance->get_env()->GetFieldID(gasper::instance->get_env()->GetObjectClass(player_obj), BADLION_CLIENT ? xorstr_("x") : xorstr_("field_70179_y"), xorstr_("D")); 62 | 63 | gasper::instance->get_env()->SetDoubleField(player_obj, mox_fid, vec.x); 64 | gasper::instance->get_env()->SetDoubleField(player_obj, moy_fid, vec.y); 65 | gasper::instance->get_env()->SetDoubleField(player_obj, moz_fid, vec.z); 66 | } 67 | 68 | bool c_player::is_on_ground() 69 | { 70 | jfieldID onground_fid = gasper::instance->get_env()->GetFieldID(gasper::instance->get_env()->GetObjectClass(player_obj), BADLION_CLIENT ? xorstr_("C") : xorstr_("field_70122_E"), xorstr_("Z")); 71 | 72 | return gasper::instance->get_env()->GetBooleanField(player_obj, onground_fid); 73 | } 74 | 75 | float c_player::get_health() 76 | { 77 | jmethodID get_health_mid; 78 | if (!BADLION_CLIENT) 79 | get_health_mid = gasper::instance->get_env()->GetMethodID(gasper::instance->get_env()->GetObjectClass(player_obj), xorstr_("func_110143_aJ"), xorstr_("()F")); 80 | else 81 | get_health_mid = gasper::instance->get_env()->GetMethodID(gasper::instance->get_env()->GetObjectClass(player_obj), xorstr_("bn"), xorstr_("()F")); 82 | 83 | if (!get_health_mid) 84 | return 1337.f; 85 | 86 | return gasper::instance->get_env()->CallFloatMethod(player_obj, get_health_mid); 87 | } 88 | 89 | sdk::vec3d c_player::get_position() 90 | { 91 | auto player_class = gasper::instance->get_env()->GetObjectClass(player_obj); 92 | 93 | jfieldID pos_x_fid, pos_y_fid, pos_z_fid; 94 | 95 | if (!BADLION_CLIENT) { 96 | pos_x_fid = gasper::instance->get_env()->GetFieldID(player_class, xorstr_("field_70165_t"), xorstr_("D")); 97 | pos_y_fid = gasper::instance->get_env()->GetFieldID(player_class, xorstr_("field_70163_u"), xorstr_("D")); 98 | pos_z_fid = gasper::instance->get_env()->GetFieldID(player_class, xorstr_("field_70161_v"), xorstr_("D")); 99 | } 100 | else { 101 | pos_x_fid = gasper::instance->get_env()->GetFieldID(player_class, xorstr_("s"), xorstr_("D")); 102 | pos_y_fid = gasper::instance->get_env()->GetFieldID(player_class, xorstr_("t"), xorstr_("D")); 103 | pos_z_fid = gasper::instance->get_env()->GetFieldID(player_class, xorstr_("u"), xorstr_("D")); 104 | } 105 | 106 | gasper::instance->get_env()->DeleteLocalRef(player_class); 107 | 108 | return sdk::vec3d{ 109 | gasper::instance->get_env()->GetDoubleField(player_obj, pos_x_fid), 110 | gasper::instance->get_env()->GetDoubleField(player_obj, pos_y_fid), 111 | gasper::instance->get_env()->GetDoubleField(player_obj, pos_z_fid) 112 | }; 113 | } 114 | 115 | void c_player::set_yaw(float yaw) 116 | { 117 | auto player_class = gasper::instance->get_env()->GetObjectClass(player_obj); 118 | 119 | jfieldID yaw_fid; 120 | if (!BADLION_CLIENT) { 121 | yaw_fid = gasper::instance->get_env()->GetFieldID(player_class, xorstr_("field_70177_z"), xorstr_("F")); 122 | } 123 | else { 124 | yaw_fid = gasper::instance->get_env()->GetFieldID(player_class, xorstr_("y"), xorstr_("F")); 125 | } 126 | 127 | gasper::instance->get_env()->DeleteLocalRef(player_class); 128 | 129 | gasper::instance->get_env()->SetFloatField(player_obj, yaw_fid, yaw); 130 | } 131 | 132 | float c_player::get_yaw() 133 | { 134 | auto player_class = gasper::instance->get_env()->GetObjectClass(player_obj); 135 | 136 | jfieldID yaw_fid; 137 | if (!BADLION_CLIENT) { 138 | yaw_fid = gasper::instance->get_env()->GetFieldID(player_class, xorstr_("field_70177_z"), xorstr_("F")); 139 | } 140 | else { 141 | yaw_fid = gasper::instance->get_env()->GetFieldID(player_class, xorstr_("y"), xorstr_("F")); 142 | } 143 | 144 | gasper::instance->get_env()->DeleteLocalRef(player_class); 145 | 146 | return gasper::instance->get_env()->GetFloatField(player_obj, yaw_fid); 147 | } 148 | 149 | void c_player::set_pitch(float pitch) 150 | { 151 | auto player_class = gasper::instance->get_env()->GetObjectClass(player_obj); 152 | 153 | jfieldID pitch_fid; 154 | if (!BADLION_CLIENT) { 155 | pitch_fid = gasper::instance->get_env()->GetFieldID(player_class, xorstr_("field_70125_A"), xorstr_("F")); 156 | } 157 | else { 158 | pitch_fid = gasper::instance->get_env()->GetFieldID(player_class, xorstr_("z"), xorstr_("F")); 159 | } 160 | 161 | gasper::instance->get_env()->DeleteLocalRef(player_class); 162 | 163 | gasper::instance->get_env()->SetFloatField(player_obj, pitch_fid, pitch); 164 | } 165 | 166 | float c_player::get_pitch() 167 | { 168 | auto player_class = gasper::instance->get_env()->GetObjectClass(player_obj); 169 | 170 | jfieldID pitch_fid; 171 | if (!BADLION_CLIENT) { 172 | pitch_fid = gasper::instance->get_env()->GetFieldID(player_class, xorstr_("field_70125_A"), xorstr_("F")); 173 | } 174 | else { 175 | pitch_fid = gasper::instance->get_env()->GetFieldID(player_class, xorstr_("z"), xorstr_("F")); 176 | } 177 | 178 | gasper::instance->get_env()->DeleteLocalRef(player_class); 179 | 180 | return gasper::instance->get_env()->GetFloatField(player_obj, pitch_fid); 181 | } 182 | 183 | std::shared_ptr c_player::get_bounding_box() 184 | { 185 | auto player_class = gasper::instance->get_env()->GetObjectClass(player_obj); 186 | jfieldID boundingbox_fid; 187 | 188 | boundingbox_fid = BADLION_CLIENT ? gasper::instance->get_env()->GetFieldID(player_class, xorstr_("f"), xorstr_("Laug;")) : gasper::instance->get_env()->GetFieldID(player_class, xorstr_("field_70121_D"), xorstr_("Lnet/minecraft/util/AxisAlignedBB;")); 189 | 190 | gasper::instance->get_env()->DeleteLocalRef(player_class); 191 | 192 | return std::make_shared(gasper::instance->get_env()->GetObjectField(player_obj, boundingbox_fid)); 193 | } 194 | 195 | double c_player::get_distance_to(std::shared_ptr other) 196 | { 197 | auto pos = get_position(); 198 | auto entity_pos = other->get_position(); 199 | return sdk::util::distance(pos.x, pos.y, pos.z, entity_pos.x, entity_pos.y, entity_pos.z); 200 | } 201 | -------------------------------------------------------------------------------- /sdk/minecraft/player/player.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../minecraft.h" 4 | 5 | class c_axisalignedbb; 6 | 7 | class c_player { 8 | private: 9 | jobject player_obj; 10 | public: 11 | c_player(jobject obj); 12 | ~c_player(); 13 | 14 | bool is_invisible(); 15 | float get_hurt_time(); 16 | float get_moveforward(); 17 | float get_movestrafe(); 18 | sdk::vec3d get_motion_vector(); 19 | void get_motion_vector(sdk::vec3d vec); 20 | bool is_on_ground(); 21 | float get_health(); 22 | sdk::vec3d get_position(); 23 | void set_yaw(float yaw); 24 | float get_yaw(); 25 | void set_pitch(float pitch); 26 | float get_pitch(); 27 | std::shared_ptr get_bounding_box(); 28 | double get_distance_to(std::shared_ptr); 29 | 30 | const jobject get_object() 31 | { 32 | return player_obj; 33 | } 34 | }; -------------------------------------------------------------------------------- /sdk/minecraft/world/world.cpp: -------------------------------------------------------------------------------- 1 | #include "world.h" 2 | 3 | #include "../../../main/gasper.h" 4 | 5 | c_world::c_world(jobject obj) 6 | { 7 | world_obj = obj; 8 | } 9 | 10 | c_world::~c_world() 11 | { 12 | gasper::instance->get_env()->DeleteLocalRef(world_obj); 13 | } 14 | 15 | std::vector> c_world::get_players() 16 | { 17 | jfieldID player_entities; 18 | if (!BADLION_CLIENT) 19 | player_entities = gasper::instance->get_env()->GetFieldID(gasper::instance->get_env()->GetObjectClass(world_obj), xorstr_("field_73010_i"), xorstr_("Ljava/util/List;")); 20 | else 21 | player_entities = gasper::instance->get_env()->GetFieldID(gasper::instance->get_env()->GetObjectClass(world_obj), xorstr_("j"), xorstr_("Ljava/util/List;")); 22 | 23 | jclass list_cls = gasper::instance->get_env()->FindClass(xorstr_("java/util/List")); 24 | jmethodID to_array_md = gasper::instance->get_env()->GetMethodID(list_cls, xorstr_("toArray"), xorstr_("()[Ljava/lang/Object;")); 25 | 26 | gasper::instance->get_env()->DeleteLocalRef(list_cls); 27 | 28 | std::vector> res; 29 | 30 | jobject obj_player_entities = gasper::instance->get_env()->GetObjectField(world_obj, player_entities); 31 | 32 | if (!obj_player_entities) 33 | return res; 34 | 35 | jobjectArray array_player_list = reinterpret_cast(gasper::instance->get_env()->CallObjectMethod(obj_player_entities, to_array_md)); 36 | 37 | if (!array_player_list) 38 | return res; 39 | 40 | size_t len = gasper::instance->get_env()->GetArrayLength(array_player_list); 41 | 42 | for (int i = 0; i < len; ++i) 43 | { 44 | jobject player = gasper::instance->get_env()->GetObjectArrayElement(array_player_list, i); 45 | res.push_back(std::make_shared(player)); 46 | } 47 | 48 | gasper::instance->get_env()->DeleteLocalRef(obj_player_entities); 49 | gasper::instance->get_env()->DeleteLocalRef(array_player_list); 50 | 51 | return res; 52 | } 53 | 54 | 55 | -------------------------------------------------------------------------------- /sdk/minecraft/world/world.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../minecraft.h" 4 | #include "../player/player.h" 5 | 6 | class c_world { 7 | private: 8 | jobject world_obj; 9 | public: 10 | c_world(jobject obj); 11 | ~c_world(); 12 | 13 | const jobject get_object() 14 | { 15 | return world_obj; 16 | } 17 | 18 | std::vector> get_players(); 19 | }; -------------------------------------------------------------------------------- /sdk/utils/timer/timer.cpp: -------------------------------------------------------------------------------- 1 | #include "timer.h" 2 | 3 | #include "../../includes.h" 4 | 5 | c_timer::c_timer() 6 | { 7 | this->time = GetTickCount64(); 8 | } 9 | 10 | void c_timer::reset() 11 | { 12 | this->time = GetTickCount64(); 13 | } 14 | 15 | sdk::qword c_timer::get_time() 16 | { 17 | return this->time; 18 | } 19 | 20 | bool c_timer::has_passed(long ms) 21 | { 22 | return (GetTickCount64() - this->get_time() > ms); 23 | } 24 | -------------------------------------------------------------------------------- /sdk/utils/timer/timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class c_timer { 4 | private: 5 | unsigned long long time; 6 | public: 7 | c_timer(); 8 | c_timer(unsigned long long time) : time(time) {} 9 | 10 | void reset(); 11 | unsigned long long get_time(); 12 | bool has_passed(long ms); 13 | }; -------------------------------------------------------------------------------- /sdk/utils/utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace sdk { 4 | 5 | /// Simple struct to store positions 6 | struct vec3d { 7 | double x, y, z; 8 | }; 9 | 10 | using qword = unsigned long long; 11 | using t_createdvms = jint(__stdcall*)(JavaVM**, jsize, jsize*); 12 | 13 | /// NOTE: They're all inline LULW 14 | namespace util { 15 | inline float wrap_to_180(float value) 16 | { 17 | if (value >= 180.f) 18 | value -= 360.f; 19 | if (value < -180.f) 20 | value += 360.f; 21 | return value; 22 | } 23 | 24 | inline float radiants_to_deg(float x) 25 | { 26 | return x * 180.f / M_PI; 27 | } 28 | 29 | inline float deg_to_radiants(float r) 30 | { 31 | return r * M_PI / 180; 32 | } 33 | 34 | inline std::pair get_angles(sdk::vec3d pos, sdk::vec3d pos1) 35 | { 36 | double d_x = pos1.x - pos.x; 37 | double d_y = pos1.y - pos.y; 38 | double d_z = pos1.z - pos.z; 39 | 40 | double hypothenuse = sqrt(d_x * d_x + d_z * d_z); 41 | float yaw = radiants_to_deg(atan2(d_z, d_x)) - 90.f; 42 | float pitch = radiants_to_deg(-atan2(d_y, hypothenuse)); 43 | 44 | return std::make_pair(yaw, pitch); 45 | } 46 | 47 | inline static double distance(double x, double y) { 48 | return sqrt(pow(x, 2) + pow(y, 2)); 49 | } 50 | 51 | inline static double distance(double x1, double y1, double z1, double x2, double y2, double z2) { 52 | return distance(y1 - y2, distance(x1 - x2, z1 - z2)); 53 | } 54 | } 55 | }; -------------------------------------------------------------------------------- /sdk/wrapper/wrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /// Thought about wrapping certain WinAPI functions to keep syntax consistancy 4 | /// also handy when obfuscating these calls :) 5 | namespace wrapper { 6 | 7 | /// Simple wrapper for CreateThread 8 | inline HANDLE spawn_thread(LPTHREAD_START_ROUTINE routine) { 9 | return CreateThread(0, 0, routine, 0, 0, 0); 10 | } 11 | 12 | /// Simple wrapper to show MessageBox 13 | const inline void show_message(std::string msg) { 14 | MessageBoxA(nullptr, msg.c_str(), xorstr_("[dbg] gasper"), MB_OK); 15 | } 16 | 17 | /// Simple wrapper to handle issues 18 | const inline bool handle_issue(const char* name, void* ptr) 19 | { 20 | /// Constant formatting message 21 | const auto s_formatting = xorstr_("%s not intialized, value -> 0x%X"); 22 | 23 | /// Value isn't initialized 24 | if (!ptr) 25 | { 26 | size_t len = std::snprintf(nullptr, 0, s_formatting, name, ptr) + 1; /// Had issues with terminator 27 | 28 | if (len <= 0) 29 | show_message(xorstr_("Issue formatting issue_handler wrapper::#handle_issue#26")); 30 | 31 | /// Allocate buffer with lenght of message 32 | auto buffer = std::make_unique(len); 33 | 34 | /// Format the message to buffer 35 | std::snprintf(buffer.get(), len, s_formatting, name, ptr); 36 | 37 | /// Show the message 38 | show_message(std::string(buffer.get(), buffer.get() + len - 1)); 39 | 40 | /// Show that an issue occured 41 | return true; 42 | } 43 | 44 | /// Everything gucci 45 | return false; 46 | } 47 | 48 | /// Wrapper to get address of module 49 | inline void* get_module_handle(const char* name) { 50 | auto h_module = GetModuleHandleA(name); 51 | 52 | if (handle_issue(name, h_module)) 53 | std::exit(0); 54 | 55 | return h_module; 56 | } 57 | 58 | /// Wrapper to get window 59 | inline HWND find_window(const char* name) 60 | { 61 | auto res = BADLION_CLIENT ? FindWindowA("LWJGL", nullptr) : FindWindowA(nullptr, name); 62 | 63 | if (handle_issue(name, res)) 64 | std::exit(0); 65 | 66 | return res; 67 | } 68 | 69 | inline RECT get_window_rect(const char* name) 70 | { 71 | RECT res; 72 | GetWindowRect(find_window(name), &res); 73 | 74 | return res; 75 | } 76 | 77 | /// Wrapper to get procedure address 78 | inline void* get_proc_address(const char* name, void* handle) 79 | { 80 | auto p_procedure = GetProcAddress(reinterpret_cast(handle), name); 81 | 82 | if (handle_issue(name, p_procedure)) 83 | std::exit(0); 84 | 85 | return p_procedure; 86 | } 87 | 88 | /// Wrapper for GetAynscKeyState 89 | inline short get_async_keystate(int key) 90 | { 91 | return GetAsyncKeyState(key); 92 | } 93 | 94 | /// Wrapper class for OpenGL context 95 | struct c_context { 96 | HDC m_hdc_devicectx; 97 | HGLRC m_glrenderctx; 98 | HGLRC m_oglrenderctx; 99 | }; 100 | 101 | inline std::shared_ptr create_gl_context() 102 | { 103 | std::shared_ptr res = std::make_shared(); 104 | 105 | PIXELFORMATDESCRIPTOR pfd = 106 | { 107 | sizeof(PIXELFORMATDESCRIPTOR), 108 | 1, 109 | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //Flags 110 | PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette. 111 | 32, // Colordepth of the framebuffer. 112 | 0, 0, 0, 0, 0, 0, 113 | 0, 114 | 0, 115 | 0, 116 | 0, 0, 0, 0, 117 | 24, // Number of bits for the depthbuffer 118 | 8, // Number of bits for the stencilbuffer 119 | 0, // Number of Aux buffers in the framebuffer. 120 | PFD_MAIN_PLANE, 121 | 0, 122 | 0, 0, 0 123 | }; 124 | 125 | res->m_hdc_devicectx = GetDC(find_window(xorstr_("Minecraft 1.7.10"))); 126 | 127 | int pixel_format = ChoosePixelFormat(res->m_hdc_devicectx, &pfd); 128 | SetPixelFormat(res->m_hdc_devicectx, pixel_format, &pfd); 129 | 130 | res->m_oglrenderctx = wglGetCurrentContext(); 131 | res->m_glrenderctx = wglCreateContext(res->m_hdc_devicectx); 132 | return res; 133 | } 134 | } --------------------------------------------------------------------------------