├── .github └── workflows │ └── build_release.yml ├── .gitignore ├── CMakeLists.txt ├── CMakePresets.json ├── CODE_OF_ETHICS.md ├── LICENSE ├── README.md ├── build_debug.bat ├── build_release.bat ├── config.hpp ├── funchook ├── include │ ├── distorm.h │ ├── funchook.h │ └── mnemonics.h └── src │ ├── config.h │ ├── decoder.c │ ├── decoder.h │ ├── disasm.h │ ├── disasm_distorm.c │ ├── distorm.c │ ├── funchook.c │ ├── funchook_internal.h │ ├── funchook_unix.c │ ├── funchook_x86.c │ ├── funchook_x86.h │ ├── instructions.c │ ├── instructions.h │ ├── insts.c │ ├── insts.h │ ├── mnemonics.c │ ├── operands.c │ ├── operands.h │ ├── prefix.c │ ├── prefix.h │ ├── textdefs.c │ ├── textdefs.h │ ├── wstring.h │ └── x86defs.h ├── init.cpp ├── init.hpp ├── main.cpp ├── media ├── showcase.png └── showcase_linux.png ├── memscan ├── .clang-format ├── .gitattributes ├── .gitignore ├── README.md ├── memscan.cmake └── src │ ├── memscan │ ├── memscan.c │ ├── memscan.h │ └── util │ │ ├── util.c │ │ └── util.h │ ├── test.c │ └── test.cpp ├── minhook ├── AUTHORS.txt ├── LICENSE.txt ├── README.md ├── include │ └── MinHook.h └── src │ ├── 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 ├── project.4coder ├── scaleform ├── alerts.js ├── alpha.js ├── base.js ├── buyzone.js ├── color.js ├── data.hpp ├── deathnotices.js ├── healthammo.js ├── sanitary_macros.hpp ├── scaleform.cpp ├── scaleform.hpp ├── spectating.js ├── teamcount_avatar.js ├── weapon_select.js └── winpanel.js └── sdk.hpp /.github/workflows/build_release.yml: -------------------------------------------------------------------------------- 1 | name: BuildRelease 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | env: 10 | # Path to the solution file relative to the root of the project. 11 | SOLUTION_FILE_PATH: . 12 | 13 | permissions: 14 | contents: read 15 | 16 | jobs: 17 | build: 18 | runs-on: windows-latest 19 | 20 | steps: 21 | - name: Enable Developer Command Prompt 22 | uses: ilammy/msvc-dev-cmd@v1.10.0 23 | with: 24 | arch: win32 25 | 26 | - uses: actions/checkout@v3 27 | 28 | - name: Build 29 | working-directory: ${{env.GITHUB_WORKSPACE}} 30 | run: ./build_release.bat 31 | 32 | - name: Upload Artifacts 33 | uses: actions/upload-artifact@v3 34 | with: 35 | name: ReleaseBuild 36 | path: ./out/build/x86-release/TeamSCALEFORM.dll 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out/ 2 | .vscode/ -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.21) 2 | project(TeamSCALEFORM) 3 | 4 | file(GLOB_RECURSE SRC 5 | "memscan/src/memscan/util/util.c" 6 | "memscan/src/memscan/memscan.c" 7 | 8 | "scaleform/scaleform.cpp" 9 | 10 | "init.cpp" 11 | "main.cpp" 12 | ) 13 | 14 | include("memscan/memscan.cmake") 15 | 16 | set_option(MEMSCAN_UNSAFE_OPTIMIZATIONS "Remove memscan safety checks" OFF) 17 | set_option(UTIL_UNSAFE_OPTIMIZATIONS "Remove util safety checks" OFF) 18 | 19 | if (UNIX) 20 | 21 | # DEBUG or RELEASE 22 | set(CMAKE_BUILD_TYPE DEBUG) 23 | 24 | set(CMAKE_C_FLAGS "-march=native --no-gnu-unique") 25 | set(CMAKE_C_FLAGS_DEBUG "-g3") 26 | set(CMAKE_C_FLAGS_RELEASE "-O3 -s -fvisibility=hidden -DNDEBUG") 27 | 28 | set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -fpermissive") 29 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") 30 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") 31 | 32 | # These are for funchook 33 | add_compile_definitions(DISASM_DISTORM) 34 | add_compile_definitions(_GNU_SOURCE) 35 | add_compile_definitions(_DEBUG) 36 | 37 | file(GLOB_RECURSE FUNCHOOK_SOURCES "${CMAKE_SOURCE_DIR}/funchook/src/*.c") 38 | 39 | find_package(SDL2 REQUIRED) 40 | 41 | include_directories(${SDL2_INCLUDE_DIRS}) 42 | 43 | add_library("${CMAKE_PROJECT_NAME}" SHARED ${SRC} ${FUNCHOOK_SOURCES}) 44 | 45 | target_link_options("${CMAKE_PROJECT_NAME}" PRIVATE LINKER:--no-undefined) 46 | target_link_libraries("${CMAKE_PROJECT_NAME}" PRIVATE ${SDL2_LIBRARIES}) 47 | target_include_directories("${CMAKE_PROJECT_NAME}" PRIVATE 48 | "${CMAKE_SOURCE_DIR}/funchook/include" 49 | ) 50 | 51 | else() 52 | 53 | set(CMAKE_SYSTEM_PROCESSOR "i686") 54 | set(ARCH "x86") 55 | 56 | add_definitions(/bigobj /Oi /Ot /Zi /GL /MP) 57 | 58 | file(GLOB_RECURSE MINHOOK 59 | "minhook/src/hde/hde32.c" 60 | "minhook/src/buffer.c" 61 | "minhook/src/hook.c" 62 | "minhook/src/trampoline.c" 63 | ) 64 | 65 | add_library(${PROJECT_NAME} SHARED ${MINHOOK} ${SRC}) 66 | set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20) 67 | set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) 68 | 69 | set(CMAKE_CXX_EXTENSIONS OFF) 70 | add_definitions(/GR- /EHsc) 71 | add_definitions(-D_HAS_EXCEPTIONS=0) #for STL 72 | add_definitions(/MP) #multi-processor compilation 73 | 74 | target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/minhook/include") 75 | 76 | endif() -------------------------------------------------------------------------------- /CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "configurePresets": [ 4 | { 5 | "name": "windows-base", 6 | "description": "Target Windows with the Visual Studio development environment.", 7 | "hidden": true, 8 | "generator": "Ninja", 9 | "binaryDir": "${sourceDir}/out/build/${presetName}", 10 | "installDir": "${sourceDir}/out/install/${presetName}", 11 | "cacheVariables": { 12 | "CMAKE_C_COMPILER": "cl.exe", 13 | "CMAKE_CXX_COMPILER": "cl.exe" 14 | }, 15 | "condition": { 16 | "type": "equals", 17 | "lhs": "${hostSystemName}", 18 | "rhs": "Windows" 19 | } 20 | }, 21 | { 22 | "name": "x86-debug", 23 | "displayName": "x86 Debug", 24 | "description": "Target Windows (32-bit) with the Visual Studio development environment. (Debug)", 25 | "inherits": "windows-base", 26 | "architecture": { 27 | "value": "x86", 28 | "strategy": "external" 29 | }, 30 | "cacheVariables": { 31 | "CMAKE_BUILD_TYPE": "Debug" 32 | } 33 | }, 34 | { 35 | "name": "x86-release", 36 | "displayName": "x86 Release", 37 | "description": "Target Windows (32-bit) with the Visual Studio development environment. (Release)", 38 | "inherits": "x86-debug", 39 | "cacheVariables": { 40 | "CMAKE_BUILD_TYPE": "Release" 41 | } 42 | } 43 | ] 44 | } -------------------------------------------------------------------------------- /CODE_OF_ETHICS.md: -------------------------------------------------------------------------------- 1 | # The Rule 2 | 3 | 1. First of all, love the Lord God with your whole heart, your whole soul, and your whole strength. 4 | 2. Then, love your neighbor as yourself. 5 | 3. Do not murder. 6 | 4. Do not commit adultery. 7 | 5. Do not steal. 8 | 6. Do not covet. 9 | 7. Do not bear false witness. 10 | 8. Honor all people. 11 | 9. Do not do to another what you would not have done to yourself. 12 | 10. Deny oneself in order to follow Christ. 13 | 11. Chastise the body. 14 | 12. Do not become attached to pleasures. 15 | 13. Love fasting. 16 | 14. Relieve the poor. 17 | 15. Clothe the naked. 18 | 16. Visit the sick. 19 | 17. Bury the dead. 20 | 18. Be a help in times of trouble. 21 | 19. Console the sorrowing. 22 | 20. Be a stranger to the world's ways. 23 | 21. Prefer nothing more than the love of Christ. 24 | 22. Do not give way to anger. 25 | 23. Do not nurse a grudge. 26 | 24. Do not entertain deceit in your heart. 27 | 25. Do not give a false peace. 28 | 26. Do not forsake charity. 29 | 27. Do not swear, for fear of perjuring yourself. 30 | 28. Utter only truth from heart and mouth. 31 | 29. Do not return evil for evil. 32 | 30. Do no wrong to anyone, and bear patiently wrongs done to yourself. 33 | 31. Love your enemies. 34 | 32. Do not curse those who curse you, but rather bless them. 35 | 33. Bear persecution for justice's sake. 36 | 34. Be not proud. 37 | 35. Be not addicted to wine. 38 | 36. Be not a great eater. 39 | 37. Be not drowsy. 40 | 38. Be not lazy. 41 | 39. Be not a grumbler. 42 | 40. Be not a detractor. 43 | 41. Put your hope in God. 44 | 42. Attribute to God, and not to self, whatever good you see in yourself. 45 | 43. Recognize always that evil is your own doing, and to impute it to yourself. 46 | 44. Fear the Day of Judgment. 47 | 45. Be in dread of hell. 48 | 46. Desire eternal life with all the passion of the spirit. 49 | 47. Keep death daily before your eyes. 50 | 48. Keep constant guard over the actions of your life. 51 | 49. Know for certain that God sees you everywhere. 52 | 50. When wrongful thoughts come into your heart, dash them against Christ immediately. 53 | 51. Disclose wrongful thoughts to your spiritual mentor. 54 | 52. Guard your tongue against evil and depraved speech. 55 | 53. Do not love much talking. 56 | 54. Speak no useless words or words that move to laughter. 57 | 55. Do not love much or boisterous laughter. 58 | 56. Listen willingly to holy reading. 59 | 57. Devote yourself frequently to prayer. 60 | 58. Daily in your prayers, with tears and sighs, confess your past sins to God, and amend them for the future. 61 | 59. Fulfill not the desires of the flesh; hate your own will. 62 | 60. Obey in all things the commands of those whom God has placed in authority over you even though they (which God forbid) should act otherwise, mindful of the Lord's precept, "Do what they say, but not what they do." 63 | 61. Do not wish to be called holy before one is holy; but first to be holy, that you may be truly so called. 64 | 62. Fulfill God's commandments daily in your deeds. 65 | 63. Love chastity. 66 | 64. Hate no one. 67 | 65. Be not jealous, nor harbor envy. 68 | 66. Do not love quarreling. 69 | 67. Shun arrogance. 70 | 68. Respect your seniors. 71 | 69. Love your juniors. 72 | 70. Pray for your enemies in the love of Christ. 73 | 71. Make peace with your adversary before the sun sets. 74 | 72. Never despair of God's mercy. 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | aventum discord
3 | tsf discord
4 | Join us on Discord! 5 | banner 6 | banner 7 | # scaleform 8 | A hackable and future-proof reimplementation of In-Game Scaleform HUD in CS:GO using Panorama. Written using C, C++ and JS. 9 | 10 | showcase 11 | showcase 12 | 13 | # Disclaimer 14 | We're not responsible for any potential VAC bans from using our project. Do not use this on any account you care about, unless you use `-insecure`, or respectively `sv_lan 1` on local servers. 15 | 16 | # Features 17 | - **NEW: Cross-platform support!**; 18 | - JavaScript loader (load changes at run-time, on bind); 19 | - Toggle Scaleform at run-time, without restarting game (on keybind - you're currently required to disconnect after toggling off, not when toggling on); 20 | - Hot-swappable Win Panels (on keybind); 21 | - Toggle Weapon Selection "show rarity" on/off (on keybind); 22 | - Fully supports (almost) every HUD command (including `cl_hud_color`, `cl_hud_background_alpha`, `cl_hud_healthammo_style`, etc...); 23 | - `-insecure` is not enforced; 24 | - No performance drawbacks (unlike with HLAE+MIGI); 25 | - Fully standalone (you only have to inject one DLL); 26 | - Future proof (does not require to be updated for code.pbin updates - unless it breaks any of the JavaScript itself); 27 | - Customizable (you can modify the CSS to your desires, and you can change keybinds and default states in `config.hpp`). 28 | 29 | # Known Issues 30 | Check the [Issues](https://github.com/TeamSCALEFORM/scaleform/issues) tab. 31 | 32 | # Main Menu 33 | If there's interest, and support, we're willing to kickstart progress towards replicating the Scaleform main-menu(s). Anyhow, before we divert any attention to that, there's much work left on the In-Game HUD. 34 | 35 | # Contributing 36 | Even if you don't know C++, you can write your changes in JavaScript (relating to the schema itself), and we will help implement the necessary boiler-plate for your change. If you're interested in doing such things, please join our Discord and see the `#contributing` channel. Thank you for your interest! 37 | 38 | NOTE: Once you open your game, you'll be told where your custom JavaScript file is expected. If it is not found, and you press the Load JavaScript keybind, you'll be announced in the console. 39 | 40 | # Building - Windows 41 | To build this project, you must install `CMake (>=3.21)`, `Ninja` and `Visual Studio 2022 Developer Tools`, then, open up `Developer Command Prompt for Visual Studio 2022`, go to the respective directory where your clone of this project is located (quick-tip: if your clone is located on a disk other than your start disk, you can modify the Developer Command Prompt 'Start In' flag, in properties), then write: 42 | 43 | `./build_release.bat` for release builds, or; 44 | 45 | `./build_debug.bat` for debug builds (includes Debug logs). 46 | 47 | Then, a build should start, and when it's done, your command prompt will be moved to the output directory, which should contain a `TeamSCALEFORM.dll` binary. 48 | 49 | # Ports 50 | We support ports of the boilerplate to software's APIs. If you developed a port of the scaleform boilerplate, open a pull request that links your repository under this comment. 51 | 52 | 53 | # Alternatives 54 | If you're a movie-maker, and you want something better suited for that purpose, please refer [to this](https://www.youtube.com/watch?v=FVtBAll3xjw). 55 | 56 | # Licensing 57 | This project is licensed under the [AGPL-3.0 license](https://github.com/TeamSCALEFORM/scaleform/blob/main/LICENSE). For a TLDR, refer to [this](https://tldrlegal.com/license/gnu-affero-general-public-license-v3-(agpl-3.0)). Please respect this. 58 | 59 | # Scams 60 | If some are blind to the "Licensing" section, they're going to be 'advertised' here, so you know who to avoid. We encourage people to make pull requests, if they ever notice a project using this against our firm licensing terms, which name and link said project. 61 | 62 | -------------------------------------------------------------------------------- /build_debug.bat: -------------------------------------------------------------------------------- 1 | set PATH=%PATH%;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\bin\Hostx86\x86\ 2 | 3 | cmake.exe --preset x86-debug 4 | cd out/build/x86-debug/ 5 | ninja -v -------------------------------------------------------------------------------- /build_release.bat: -------------------------------------------------------------------------------- 1 | set PATH=%PATH%;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\bin\Hostx86\x86\ 2 | 3 | cmake.exe --preset x86-release 4 | cd out/build/x86-release/ 5 | ninja -v -------------------------------------------------------------------------------- /config.hpp: -------------------------------------------------------------------------------- 1 | #include "sdk.hpp" 2 | 3 | #ifdef __linux__ 4 | #include 5 | #include 6 | #endif 7 | 8 | #define ON true 9 | #define OFF false 10 | 11 | #define OLD true 12 | #define NEW false 13 | 14 | // refer to https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes 15 | // for keybinds 16 | 17 | #define SCALEFORM_TOGGLE_KEY WIN32_LINUX_LITERAL(VK_F11, SDL_SCANCODE_F11) 18 | #define SCALEFORM_DEFAULT ON 19 | #define SCALEFORM_WINPANEL_TOGGLE_KEY WIN32_LINUX_LITERAL(VK_F10, SDL_SCANCODE_F10) 20 | #define SCALEFORM_WINPANEL_DEFAULT OLD 21 | #define SCALEFORM_JAVASCRIPT_LOADER_KEY WIN32_LINUX_LITERAL(VK_F7, SDL_SCANCODE_F7) 22 | #define SCALEFORM_WEAPON_SELECTION_RARITY_DEFAULT OFF 23 | #define SCALEFORM_WEAPON_SELECTION_RARITY_TOGGLE_KEY WIN32_LINUX_LITERAL(VK_F6, SDL_SCANCODE_F6) 24 | 25 | #ifdef WIN32 26 | #define GET_ASYNC_KEY_STATE(x) GetAsyncKeyState(x) 27 | #else 28 | #define GET_ASYNC_KEY_STATE(x) state ? state[x] : 0 29 | #endif -------------------------------------------------------------------------------- /funchook/include/funchook.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Funchook. 3 | * https://github.com/kubo/funchook 4 | * 5 | * Funchook is free software: you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License as published by the 7 | * Free Software Foundation, either version 2 of the License, or (at your 8 | * option) any later version. 9 | * 10 | * As a special exception, the copyright holders of this library give you 11 | * permission to link this library with independent modules to produce an 12 | * executable, regardless of the license terms of these independent 13 | * modules, and to copy and distribute the resulting executable under 14 | * terms of your choice, provided that you also meet, for each linked 15 | * independent module, the terms and conditions of the license of that 16 | * module. An independent module is a module which is not derived from or 17 | * based on this library. If you modify this library, you may extend this 18 | * exception to your version of the library, but you are not obliged to 19 | * do so. If you do not wish to do so, delete this exception statement 20 | * from your version. 21 | * 22 | * Funchook is distributed in the hope that it will be useful, but WITHOUT 23 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 24 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 25 | * for more details. 26 | * 27 | * You should have received a copy of the GNU General Public License 28 | * along with Funchook. If not, see . 29 | */ 30 | #ifndef FUNCHOOK_H 31 | #define FUNCHOOK_H 1 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* 38 | * Only functions with FUNCHOOK_EXPORT are visible from outside of funchook.dll 39 | * or libfunchook.so. Others are invisible. 40 | */ 41 | #ifdef FUNCHOOK_EXPORTS 42 | #if defined(WIN32) 43 | #define FUNCHOOK_EXPORT __declspec(dllexport) 44 | #elif defined(__GNUC__) 45 | #define FUNCHOOK_EXPORT __attribute__((visibility("default"))) 46 | #endif 47 | #endif /* FUNCHOOK_EXPORTS */ 48 | #ifndef FUNCHOOK_EXPORT 49 | #define FUNCHOOK_EXPORT 50 | #endif 51 | 52 | typedef struct funchook funchook_t; 53 | 54 | #define FUNCHOOK_ERROR_INTERNAL_ERROR -1 55 | #define FUNCHOOK_ERROR_SUCCESS 0 56 | #define FUNCHOOK_ERROR_OUT_OF_MEMORY 1 57 | #define FUNCHOOK_ERROR_ALREADY_INSTALLED 2 58 | #define FUNCHOOK_ERROR_DISASSEMBLY 3 59 | #define FUNCHOOK_ERROR_IP_RELATIVE_OFFSET 4 60 | #define FUNCHOOK_ERROR_CANNOT_FIX_IP_RELATIVE 5 61 | #define FUNCHOOK_ERROR_FOUND_BACK_JUMP 6 62 | #define FUNCHOOK_ERROR_TOO_SHORT_INSTRUCTIONS 7 63 | #define FUNCHOOK_ERROR_MEMORY_ALLOCATION 8 /* memory allocation error */ 64 | #define FUNCHOOK_ERROR_MEMORY_FUNCTION 9 /* other memory function errors */ 65 | #define FUNCHOOK_ERROR_NOT_INSTALLED 10 66 | #define FUNCHOOK_ERROR_NO_AVAILABLE_REGISTERS 11 67 | 68 | /** 69 | * Create a funchook handle 70 | * 71 | * @return allocated funchook handle. NULL when out-of-memory. 72 | */ 73 | FUNCHOOK_EXPORT funchook_t *funchook_create(void); 74 | 75 | /** 76 | * Prepare hooking 77 | * 78 | * @param funchook a funchook handle created by funchook_create() 79 | * @param target_func function pointer to be intercepted. The pointer to trampoline function is set on success. 80 | * @param hook_func function pointer which is called istead of target_func 81 | * @return error code. one of FUNCHOOK_ERROR_*. 82 | */ 83 | FUNCHOOK_EXPORT int funchook_prepare(funchook_t *funchook, void **target_func, void *hook_func); 84 | 85 | /** 86 | * Install hooks prepared by funchook_prepare(). 87 | * 88 | * @param funchook a funchook handle created by funchook_create() 89 | * @param flags reserved. Set zero. 90 | * @return error code. one of FUNCHOOK_ERROR_*. 91 | */ 92 | FUNCHOOK_EXPORT int funchook_install(funchook_t *funchook, int flags); 93 | 94 | /** 95 | * Uninstall hooks installed by funchook_install(). 96 | * 97 | * @param funchook a funchook handle created by funchook_create() 98 | * @param flags reserved. Set zero. 99 | * @return error code. one of FUNCHOOK_ERROR_*. 100 | */ 101 | FUNCHOOK_EXPORT int funchook_uninstall(funchook_t *funchook, int flags); 102 | 103 | /** 104 | * Destroy a funchook handle 105 | * 106 | * @param funchook a funchook handle created by funchook_create() 107 | * @return error code. one of FUNCHOOK_ERROR_*. 108 | */ 109 | FUNCHOOK_EXPORT int funchook_destroy(funchook_t *funchook); 110 | 111 | /** 112 | * Get error message 113 | * 114 | * @param funchook a funchook handle created by funchook_create() 115 | * @return pointer to buffer containing error message 116 | */ 117 | FUNCHOOK_EXPORT const char *funchook_error_message(const funchook_t *funchook); 118 | 119 | /** 120 | * Set log file name to debug funchook itself. 121 | * 122 | * @param name log file name 123 | * @return error code. one of FUNCHOOK_ERROR_*. 124 | */ 125 | FUNCHOOK_EXPORT int funchook_set_debug_file(const char *name); 126 | 127 | #ifdef __cplusplus 128 | } // extern "C" 129 | #endif 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /funchook/src/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | config.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2021 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #ifndef CONFIG_H 13 | #define CONFIG_H 14 | 15 | /* diStorm version number. */ 16 | #define __DISTORMV__ 0x030502 17 | 18 | #include /* memset, memcpy - can be easily self implemented for libc independency. */ 19 | 20 | #include "../include/distorm.h" 21 | 22 | 23 | /* 24 | * 64 bit offsets support: 25 | * This macro should be defined from compiler command line flags, e.g: -DSUPPORT_64BIT_OFFSET 26 | * Note: make sure that the caller (library user) defines it too! 27 | */ 28 | /* #define SUPPORT_64BIT_OFFSET */ 29 | 30 | /* 31 | * If you compile diStorm as a dynamic library (.dll or .so) file, make sure you uncomment the next line. 32 | * So the interface functions will be exported, otherwise they are useable only for static library. 33 | * For example, this macro is being set for compiling diStorm as a .dll for Python with CTypes. 34 | */ 35 | /* #define DISTORM_DYNAMIC */ 36 | 37 | /* 38 | * If DISTORM_LIGHT is defined, everything involved in formatting the instructions 39 | * as text will be excluded from compilation. 40 | * distorm_decode(..) and distorm_format(..) will not be available. 41 | * This will decrease the size of the executable and leave you with decomposition functionality only. 42 | * 43 | * Note: it should be either set in the preprocessor definitions manually or in command line -D switch. 44 | * #define DISTORM_LIGHT 45 | */ 46 | 47 | /* 48 | * diStorm now supports little/big endian CPU's. 49 | * It should detect the endianness according to predefined macro's of the compiler. 50 | * If you don't use GCC/MSVC you will have to define it on your own. 51 | */ 52 | 53 | /* These macros are used in order to make the code portable. */ 54 | #ifdef __GNUC__ 55 | 56 | #include 57 | 58 | #define _DLLEXPORT_ 59 | #define _FASTCALL_ 60 | /* Keep inline as static (arrrrg) as it would break linux on some flavors otherwise. */ 61 | #define _INLINE_ static 62 | /* GCC ignores this directive... */ 63 | /*#define _FASTCALL_ __attribute__((__fastcall__))*/ 64 | 65 | /* Set endianity (supposed to be LE though): */ 66 | #ifdef __BIG_ENDIAN__ 67 | #define BE_SYSTEM 68 | #endif 69 | 70 | /* End of __GCC__ */ 71 | 72 | #elif __WATCOMC__ 73 | 74 | #include 75 | 76 | #define _DLLEXPORT_ 77 | #define _FASTCALL_ 78 | #define _INLINE_ __inline 79 | 80 | /* End of __WATCOMC__ */ 81 | 82 | #elif __DMC__ 83 | 84 | #include 85 | 86 | #define _DLLEXPORT_ 87 | #define _FASTCALL_ 88 | #define _INLINE_ __inline 89 | 90 | /* End of __DMC__ */ 91 | 92 | #elif __TINYC__ 93 | 94 | #include 95 | 96 | #define _DLLEXPORT_ 97 | #define _FASTCALL_ 98 | #define _INLINE_ static 99 | 100 | /* End of __TINYC__ */ 101 | 102 | #elif _MSC_VER 103 | 104 | /* stdint alternative is defined in distorm.h */ 105 | 106 | #define _DLLEXPORT_ __declspec(dllexport) 107 | #define _FASTCALL_ __fastcall 108 | #define _INLINE_ __inline 109 | 110 | /* Set endianity (supposed to be LE though): */ 111 | #if !defined(_M_IX86) && !defined(_M_X64) 112 | #define BE_SYSTEM 113 | #endif 114 | 115 | #endif /* #elif _MSC_VER */ 116 | 117 | /* If the library isn't compiled as a dynamic library don't export any functions. */ 118 | #ifndef DISTORM_DYNAMIC 119 | #undef _DLLEXPORT_ 120 | #define _DLLEXPORT_ 121 | #endif 122 | 123 | #ifndef FALSE 124 | #define FALSE 0 125 | #endif 126 | #ifndef TRUE 127 | #define TRUE 1 128 | #endif 129 | 130 | /* Define stream read functions for big endian systems. */ 131 | #ifdef BE_SYSTEM 132 | 133 | /* Avoid defining 'static static' for GCC. */ 134 | #ifndef __GNUC__ 135 | #define STATIC_INLINE static _INLINE_ 136 | #else 137 | #define STATIC_INLINE static 138 | #endif 139 | 140 | /* 141 | * Assumption: These functions can read from the stream safely! 142 | * Swap endianity of input to little endian. 143 | */ 144 | STATIC_INLINE int16_t RSHORT(const uint8_t *s) 145 | { 146 | return s[0] | (s[1] << 8); 147 | } 148 | STATIC_INLINE uint16_t RUSHORT(const uint8_t *s) 149 | { 150 | return s[0] | (s[1] << 8); 151 | } 152 | STATIC_INLINE int32_t RLONG(const uint8_t *s) 153 | { 154 | return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24); 155 | } 156 | STATIC_INLINE uint32_t RULONG(const uint8_t *s) 157 | { 158 | return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24); 159 | } 160 | STATIC_INLINE int64_t RLLONG(const uint8_t *s) 161 | { 162 | return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24) | ((uint64_t)s[4] << 32) | ((uint64_t)s[5] << 40) | ((uint64_t)s[6] << 48) | ((uint64_t)s[7] << 56); 163 | } 164 | STATIC_INLINE uint64_t RULLONG(const uint8_t *s) 165 | { 166 | return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24) | ((uint64_t)s[4] << 32) | ((uint64_t)s[5] << 40) | ((uint64_t)s[6] << 48) | ((uint64_t)s[7] << 56); 167 | } 168 | 169 | #undef STATIC_INLINE 170 | 171 | #else 172 | /* Little endian macro's will just make the cast. */ 173 | #define RSHORT(x) *(int16_t *)x 174 | #define RUSHORT(x) *(uint16_t *)x 175 | #define RLONG(x) *(int32_t *)x 176 | #define RULONG(x) *(uint32_t *)x 177 | #define RLLONG(x) *(int64_t *)x 178 | #define RULLONG(x) *(uint64_t *)x 179 | #endif 180 | 181 | #endif /* CONFIG_H */ 182 | -------------------------------------------------------------------------------- /funchook/src/decoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | decoder.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2021 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #ifndef DECODER_H 13 | #define DECODER_H 14 | 15 | #include "config.h" 16 | 17 | typedef unsigned int _iflags; 18 | 19 | _DecodeResult decode_internal(_CodeInfo* _ci, int supportOldIntr, _DInst result[], unsigned int maxResultCount, unsigned int* usedInstructionsCount); 20 | 21 | #endif /* DECODER_H */ 22 | -------------------------------------------------------------------------------- /funchook/src/disasm.h: -------------------------------------------------------------------------------- 1 | /* -*- indent-tabs-mode: nil -*- 2 | * 3 | * This file is part of Funchook. 4 | * https://github.com/kubo/funchook 5 | * 6 | * Funchook is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by the 8 | * Free Software Foundation, either version 2 of the License, or (at your 9 | * option) any later version. 10 | * 11 | * As a special exception, the copyright holders of this library give you 12 | * permission to link this library with independent modules to produce an 13 | * executable, regardless of the license terms of these independent 14 | * modules, and to copy and distribute the resulting executable under 15 | * terms of your choice, provided that you also meet, for each linked 16 | * independent module, the terms and conditions of the license of that 17 | * module. An independent module is a module which is not derived from or 18 | * based on this library. If you modify this library, you may extend this 19 | * exception to your version of the library, but you are not obliged to 20 | * do so. If you do not wish to do so, delete this exception statement 21 | * from your version. 22 | * 23 | * Funchook is distributed in the hope that it will be useful, but WITHOUT 24 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 25 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 26 | * for more details. 27 | * 28 | * You should have received a copy of the GNU General Public License 29 | * along with Funchook. If not, see . 30 | */ 31 | #ifndef DISASM_H 32 | #define DISASM_H 1 33 | 34 | #ifdef DISASM_DISTORM 35 | #include 36 | #include 37 | 38 | typedef struct funchook_disasm { 39 | funchook_t *funchook; 40 | _CodeInfo ci; 41 | unsigned int idx; 42 | unsigned int cnt; 43 | _DInst dis[MAX_INSN_CHECK_SIZE]; 44 | } funchook_disasm_t; 45 | typedef _DInst funchook_insn_t; 46 | 47 | #define funchook_insn_size(insn) ((insn)->size) 48 | #define funchook_insn_address(insn) ((size_t)(insn)->addr) 49 | #define funchook_insn_branch_address(insn) ((size_t)INSTRUCTION_GET_TARGET(insn)) 50 | 51 | #endif 52 | 53 | #ifdef DISASM_CAPSTONE 54 | #include 55 | 56 | typedef struct funchook_disasm { 57 | funchook_t *funchook; 58 | csh handle; 59 | cs_insn *insns; 60 | size_t index; 61 | size_t count; 62 | } funchook_disasm_t; 63 | 64 | typedef cs_insn funchook_insn_t; 65 | 66 | #define funchook_insn_size(insn) ((insn)->size / sizeof(insn_t)) 67 | #define funchook_insn_address(insn) ((size_t)(insn)->address) 68 | #define funchook_insn_branch_address(insn) ((size_t)(insn)->detail->x86.operands[0].imm) 69 | #endif 70 | 71 | #ifdef DISASM_ZYDIS 72 | #include 73 | 74 | typedef struct { 75 | ZydisDecodedInstruction insn; 76 | size_t next_address; 77 | } funchook_insn_t; 78 | 79 | typedef struct funchook_disasm { 80 | funchook_t *funchook; 81 | ZydisDecoder decoder; 82 | ZydisFormatter formatter; 83 | funchook_insn_t insn; 84 | const uint8_t *code; 85 | const uint8_t *code_end; 86 | } funchook_disasm_t; 87 | 88 | #define funchook_insn_size(insn) ((insn)->insn.length) 89 | #define funchook_insn_address(insn) ((insn)->next_address - (insn)->insn.length) 90 | #define funchook_insn_branch_address(insn) ((insn)->next_address + (intptr_t)(insn)->insn.raw.imm[0].value.s) 91 | 92 | #endif 93 | 94 | #define FUNCHOOK_ERROR_END_OF_INSTRUCTION -2 95 | 96 | int funchook_disasm_init(funchook_disasm_t *disasm, funchook_t *funchook, const insn_t *code, size_t code_size, size_t address); 97 | void funchook_disasm_cleanup(funchook_disasm_t *disasm); 98 | int funchook_disasm_next(funchook_disasm_t *disasm, const funchook_insn_t **next_insn); 99 | void funchook_disasm_log_instruction(funchook_disasm_t *disasm, const funchook_insn_t *insn); 100 | 101 | #if defined(CPU_ARM64) 102 | funchook_insn_info_t funchook_disasm_arm64_insn_info(funchook_disasm_t *disasm, const funchook_insn_t *insn); 103 | #endif 104 | 105 | #if defined(CPU_X86) || defined(CPU_X86_64) 106 | /* RIP-relative address information */ 107 | typedef struct { 108 | insn_t *addr; /* absolute address */ 109 | intptr_t raddr; /* relative address */ 110 | int offset; 111 | int size; 112 | } rip_relative_t; 113 | 114 | void funchook_disasm_x86_rip_relative(funchook_disasm_t *disasm, const funchook_insn_t *insn, rip_relative_t *rel_disp, rip_relative_t *rel_imm); 115 | #endif 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /funchook/src/disasm_distorm.c: -------------------------------------------------------------------------------- 1 | /* -*- indent-tabs-mode: nil -*- 2 | * 3 | * This file is part of Funchook. 4 | * https://github.com/kubo/funchook 5 | * 6 | * Funchook is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by the 8 | * Free Software Foundation, either version 2 of the License, or (at your 9 | * option) any later version. 10 | * 11 | * As a special exception, the copyright holders of this library give you 12 | * permission to link this library with independent modules to produce an 13 | * executable, regardless of the license terms of these independent 14 | * modules, and to copy and distribute the resulting executable under 15 | * terms of your choice, provided that you also meet, for each linked 16 | * independent module, the terms and conditions of the license of that 17 | * module. An independent module is a module which is not derived from or 18 | * based on this library. If you modify this library, you may extend this 19 | * exception to your version of the library, but you are not obliged to 20 | * do so. If you do not wish to do so, delete this exception statement 21 | * from your version. 22 | * 23 | * Funchook is distributed in the hope that it will be useful, but WITHOUT 24 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 25 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 26 | * for more details. 27 | * 28 | * You should have received a copy of the GNU General Public License 29 | * along with Funchook. If not, see . 30 | */ 31 | #include "config.h" 32 | #include 33 | #include 34 | #include 35 | #include "funchook_internal.h" 36 | #include "disasm.h" 37 | 38 | int funchook_disasm_init(funchook_disasm_t *disasm, funchook_t *funchook, const uint8_t *code, size_t code_size, size_t address) 39 | { 40 | _DecodeResult decres; 41 | 42 | disasm->funchook = funchook; 43 | disasm->ci.codeOffset = address; 44 | disasm->ci.code = code; 45 | disasm->ci.codeLen = (int)code_size; 46 | #ifdef CPU_X86_64 47 | disasm->ci.dt = Decode64Bits; 48 | #else 49 | disasm->ci.dt = Decode32Bits; 50 | #endif 51 | disasm->ci.features = DF_STOP_ON_RET; 52 | disasm->idx = 0; 53 | decres = distorm_decompose64(&disasm->ci, disasm->dis, MAX_INSN_CHECK_SIZE, &disasm->cnt); 54 | if (decres != DECRES_SUCCESS) { 55 | funchook_set_error_message(funchook, "Disassemble Error: %d", decres); 56 | return FUNCHOOK_ERROR_DISASSEMBLY; 57 | } 58 | return 0; 59 | } 60 | 61 | void funchook_disasm_cleanup(funchook_disasm_t *disasm) 62 | { 63 | /* no need to free resources */ 64 | } 65 | 66 | int funchook_disasm_next(funchook_disasm_t *disasm, const funchook_insn_t **next_insn) 67 | { 68 | if (disasm->idx < disasm->cnt) { 69 | *next_insn = &disasm->dis[disasm->idx++]; 70 | return 0; 71 | } else { 72 | return FUNCHOOK_ERROR_END_OF_INSTRUCTION; 73 | } 74 | } 75 | 76 | void funchook_disasm_log_instruction(funchook_disasm_t *disasm, const funchook_insn_t *insn) 77 | { 78 | _DecodedInst dec; 79 | distorm_format64(&disasm->ci, insn, &dec); 80 | funchook_log(disasm->funchook, " "ADDR_FMT" (%02d) %-24s %s%s%s\n", 81 | (size_t)dec.offset, dec.size, (char*)dec.instructionHex.p, 82 | (char*)dec.mnemonic.p, dec.operands.length != 0 ? " " : "", (char*)dec.operands.p); 83 | } 84 | 85 | void funchook_disasm_x86_rip_relative(funchook_disasm_t *disasm, const funchook_insn_t *insn, rip_relative_t *rel_disp, rip_relative_t *rel_imm) 86 | { 87 | int opsiz = 0; 88 | int disp_offset = 0; 89 | int imm_offset = 0; 90 | int i; 91 | 92 | memset(rel_disp, 0, sizeof(rip_relative_t)); 93 | memset(rel_imm, 0, sizeof(rip_relative_t)); 94 | 95 | /* 96 | * Estimate total operand size and RIP-relative address offsets. 97 | */ 98 | for (i = 0; i < OPERANDS_NO && insn->ops[i].type != O_NONE; i++) { 99 | const _Operand *op = &insn->ops[i]; 100 | switch (op->type) { 101 | case O_IMM: 102 | opsiz += op->size / 8; 103 | break; 104 | case O_PC: 105 | rel_imm->addr = (uint8_t*)(size_t)(insn->addr + insn->size + insn->imm.addr); 106 | rel_imm->raddr = (intptr_t)insn->imm.addr; 107 | rel_imm->size = op->size; 108 | imm_offset = opsiz; 109 | opsiz += op->size / 8; 110 | break; 111 | case O_SMEM: 112 | if (insn->dispSize != 0 && op->index == R_RIP) { 113 | rel_disp->addr = (uint8_t*)(size_t)(insn->addr + insn->size + insn->disp); 114 | rel_disp->raddr = (intptr_t)insn->disp; 115 | rel_disp->size = insn->dispSize; 116 | disp_offset = opsiz; 117 | } 118 | opsiz += insn->dispSize / 8; 119 | break; 120 | case O_MEM: 121 | case O_DISP: 122 | opsiz += insn->dispSize / 8; 123 | break; 124 | } 125 | } 126 | switch (insn->opcode) { 127 | /* CMPSD */ 128 | case I_CMPEQSD: 129 | case I_CMPLTSD: 130 | case I_CMPLESD: 131 | case I_CMPUNORDSD: 132 | case I_CMPNEQSD: 133 | case I_CMPNLTSD: 134 | case I_CMPNLESD: 135 | case I_CMPORDSD: 136 | case I_VCMPEQSD: 137 | case I_VCMPLTSD: 138 | case I_VCMPLESD: 139 | case I_VCMPUNORDSD: 140 | case I_VCMPNEQSD: 141 | case I_VCMPNLTSD: 142 | case I_VCMPNLESD: 143 | case I_VCMPORDSD: 144 | case I_VCMPEQ_UQSD: 145 | case I_VCMPNGESD: 146 | case I_VCMPNGTSD: 147 | case I_VCMPFALSESD: 148 | case I_VCMPNEQ_OQSD: 149 | case I_VCMPGESD: 150 | case I_VCMPGTSD: 151 | case I_VCMPTRUESD: 152 | case I_VCMPEQ_OSSD: 153 | case I_VCMPLT_OQSD: 154 | case I_VCMPLE_OQSD: 155 | case I_VCMPUNORD_SSD: 156 | case I_VCMPNEQ_USSD: 157 | case I_VCMPNLT_UQSD: 158 | case I_VCMPNLE_UQSD: 159 | case I_VCMPORD_SSD: 160 | case I_VCMPEQ_USSD: 161 | case I_VCMPNGE_UQSD: 162 | case I_VCMPNGT_UQSD: 163 | case I_VCMPFALSE_OSSD: 164 | case I_VCMPNEQ_OSSD: 165 | case I_VCMPGE_OQSD: 166 | case I_VCMPGT_OQSD: 167 | /* CMPSS */ 168 | case I_CMPEQSS: 169 | case I_CMPLTSS: 170 | case I_CMPLESS: 171 | case I_CMPUNORDSS: 172 | case I_CMPNEQSS: 173 | case I_CMPNLTSS: 174 | case I_CMPNLESS: 175 | case I_CMPORDSS: 176 | case I_VCMPEQSS: 177 | case I_VCMPLTSS: 178 | case I_VCMPLESS: 179 | case I_VCMPUNORDSS: 180 | case I_VCMPNEQSS: 181 | case I_VCMPNLTSS: 182 | case I_VCMPNLESS: 183 | case I_VCMPORDSS: 184 | case I_VCMPEQ_UQSS: 185 | case I_VCMPNGESS: 186 | case I_VCMPNGTSS: 187 | case I_VCMPFALSESS: 188 | case I_VCMPNEQ_OQSS: 189 | case I_VCMPGESS: 190 | case I_VCMPGTSS: 191 | case I_VCMPTRUESS: 192 | case I_VCMPEQ_OSSS: 193 | case I_VCMPLT_OQSS: 194 | case I_VCMPLE_OQSS: 195 | case I_VCMPUNORD_SSS: 196 | case I_VCMPNEQ_USSS: 197 | case I_VCMPNLT_UQSS: 198 | case I_VCMPNLE_UQSS: 199 | case I_VCMPORD_SSS: 200 | case I_VCMPEQ_USSS: 201 | case I_VCMPNGE_UQSS: 202 | case I_VCMPNGT_UQSS: 203 | case I_VCMPFALSE_OSSS: 204 | case I_VCMPNEQ_OSSS: 205 | case I_VCMPGE_OQSS: 206 | case I_VCMPGT_OQSS: 207 | /* CMPPD */ 208 | case I_CMPEQPD: 209 | case I_CMPLTPD: 210 | case I_CMPLEPD: 211 | case I_CMPUNORDPD: 212 | case I_CMPNEQPD: 213 | case I_CMPNLTPD: 214 | case I_CMPNLEPD: 215 | case I_CMPORDPD: 216 | case I_VCMPEQPD: 217 | case I_VCMPLTPD: 218 | case I_VCMPLEPD: 219 | case I_VCMPUNORDPD: 220 | case I_VCMPNEQPD: 221 | case I_VCMPNLTPD: 222 | case I_VCMPNLEPD: 223 | case I_VCMPORDPD: 224 | case I_VCMPEQ_UQPD: 225 | case I_VCMPNGEPD: 226 | case I_VCMPNGTPD: 227 | case I_VCMPFALSEPD: 228 | case I_VCMPNEQ_OQPD: 229 | case I_VCMPGEPD: 230 | case I_VCMPGTPD: 231 | case I_VCMPTRUEPD: 232 | case I_VCMPEQ_OSPD: 233 | case I_VCMPLT_OQPD: 234 | case I_VCMPLE_OQPD: 235 | case I_VCMPUNORD_SPD: 236 | case I_VCMPNEQ_USPD: 237 | case I_VCMPNLT_UQPD: 238 | case I_VCMPNLE_UQPD: 239 | case I_VCMPORD_SPD: 240 | case I_VCMPEQ_USPD: 241 | case I_VCMPNGE_UQPD: 242 | case I_VCMPNGT_UQPD: 243 | case I_VCMPFALSE_OSPD: 244 | case I_VCMPNEQ_OSPD: 245 | case I_VCMPGE_OQPD: 246 | case I_VCMPGT_OQPD: 247 | case I_VCMPTRUE_USPD: 248 | /* CMPPS */ 249 | case I_CMPEQPS: 250 | case I_CMPLTPS: 251 | case I_CMPLEPS: 252 | case I_CMPUNORDPS: 253 | case I_CMPNEQPS: 254 | case I_CMPNLTPS: 255 | case I_CMPNLEPS: 256 | case I_CMPORDPS: 257 | case I_VCMPEQPS: 258 | case I_VCMPLTPS: 259 | case I_VCMPLEPS: 260 | case I_VCMPUNORDPS: 261 | case I_VCMPNEQPS: 262 | case I_VCMPNLTPS: 263 | case I_VCMPNLEPS: 264 | case I_VCMPORDPS: 265 | case I_VCMPEQ_UQPS: 266 | case I_VCMPNGEPS: 267 | case I_VCMPNGTPS: 268 | case I_VCMPFALSEPS: 269 | case I_VCMPNEQ_OQPS: 270 | case I_VCMPGEPS: 271 | case I_VCMPGTPS: 272 | case I_VCMPTRUEPS: 273 | case I_VCMPEQ_OSPS: 274 | case I_VCMPLT_OQPS: 275 | case I_VCMPLE_OQPS: 276 | case I_VCMPUNORD_SPS: 277 | case I_VCMPNEQ_USPS: 278 | case I_VCMPNLT_UQPS: 279 | case I_VCMPNLE_UQPS: 280 | case I_VCMPORD_SPS: 281 | case I_VCMPEQ_USPS: 282 | case I_VCMPNGE_UQPS: 283 | case I_VCMPNGT_UQPS: 284 | case I_VCMPFALSE_OSPS: 285 | case I_VCMPNEQ_OSPS: 286 | case I_VCMPGE_OQPS: 287 | case I_VCMPGT_OQPS: 288 | case I_VCMPTRUE_USPS: 289 | /* ohters */ 290 | case I_PI2FD: 291 | case I_PI2FW: 292 | case I_PF2IW: 293 | case I_PF2ID: 294 | case I_PSWAPD: 295 | case I_VPBLENDVB: 296 | case I_PFNACC: 297 | opsiz++; 298 | } 299 | 300 | if (rel_disp->size > 0) { 301 | rel_disp->offset = insn->size - opsiz + disp_offset; 302 | funchook_log(disasm->funchook, " ip-relative %08x, absolute address= "ADDR_FMT", offset=%d, size=%d\n", 303 | (uint32_t)rel_disp->raddr, (size_t)rel_disp->addr, rel_disp->offset, rel_disp->size); 304 | } 305 | if (rel_imm->size > 0) { 306 | rel_imm->offset = insn->size - opsiz + imm_offset; 307 | funchook_log(disasm->funchook, " ip-relative %08x, absolute address= "ADDR_FMT", offset=%d, size=%d\n", 308 | (uint32_t)rel_imm->raddr, (size_t)rel_imm->addr, rel_imm->offset, rel_imm->size); 309 | } 310 | } 311 | -------------------------------------------------------------------------------- /funchook/src/funchook_internal.h: -------------------------------------------------------------------------------- 1 | /* -*- indent-tabs-mode: nil -*- 2 | * 3 | * This file is part of Funchook. 4 | * https://github.com/kubo/funchook 5 | * 6 | * Funchook is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by the 8 | * Free Software Foundation, either version 2 of the License, or (at your 9 | * option) any later version. 10 | * 11 | * As a special exception, the copyright holders of this library give you 12 | * permission to link this library with independent modules to produce an 13 | * executable, regardless of the license terms of these independent 14 | * modules, and to copy and distribute the resulting executable under 15 | * terms of your choice, provided that you also meet, for each linked 16 | * independent module, the terms and conditions of the license of that 17 | * module. An independent module is a module which is not derived from or 18 | * based on this library. If you modify this library, you may extend this 19 | * exception to your version of the library, but you are not obliged to 20 | * do so. If you do not wish to do so, delete this exception statement 21 | * from your version. 22 | * 23 | * Funchook is distributed in the hope that it will be useful, but WITHOUT 24 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 25 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 26 | * for more details. 27 | * 28 | * You should have received a copy of the GNU General Public License 29 | * along with Funchook. If not, see . 30 | */ 31 | #ifndef FUNCHOOK_INTERNAL_H 32 | #define FUNCHOOK_INTERNAL_H 1 33 | #include "funchook.h" 34 | #ifdef WIN32 35 | #include 36 | #endif 37 | 38 | #if defined(_MSC_VER) && _MSC_VER < 1700 39 | #ifdef _WIN64 40 | #define PRIxPTR "I64" 41 | #else 42 | #define PRIxPTR "" 43 | #endif 44 | #else 45 | #include 46 | #endif 47 | 48 | #ifndef MIN 49 | #define MIN(a, b) (((a) < (b)) ? (a) : (b)) 50 | #endif 51 | 52 | #ifndef MAX 53 | #define MAX(a, b) (((a) > (b)) ? (a) : (b)) 54 | #endif 55 | 56 | #ifndef __GNUC__ 57 | #define __attribute__(arg) 58 | #endif 59 | 60 | #define ROUND_DOWN(num, unit) ((num) & ~((unit) - 1)) 61 | #define ROUND_UP(num, unit) (((num) + (unit) - 1) & ~((unit) - 1)) 62 | 63 | #if SIZEOF_VOID_P == 8 64 | #define ADDR_FMT "%016" PRIxPTR 65 | #else 66 | #define ADDR_FMT "%08" PRIxPTR 67 | #endif 68 | 69 | #if defined __aarch64__ 70 | #define CPU_ARM64 71 | #define CPU_64BIT 72 | #endif 73 | 74 | #if defined _M_AMD64 || defined __x86_64__ 75 | #define CPU_X86_64 76 | #define CPU_64BIT 77 | #endif 78 | 79 | #if defined _M_IX86 || defined __i686__ || defined __i386__ 80 | #define CPU_X86 81 | #endif 82 | 83 | #if defined(CPU_ARM64) 84 | #include "funchook_arm64.h" 85 | #endif 86 | #if defined(CPU_X86) || defined(CPU_X86_64) 87 | #include "funchook_x86.h" 88 | #endif 89 | 90 | #define JUMP32_BYTE_SIZE (JUMP32_SIZE * sizeof(insn_t)) 91 | #define TRAMPOLINE_BYTE_SIZE (TRAMPOLINE_SIZE * sizeof(insn_t)) 92 | 93 | /* This must be same with sysconf(_SC_PAGE_SIZE) on Unix 94 | * or the dwPageSize member of the SYSTEM_INFO structure on Windows. 95 | */ 96 | #undef PAGE_SIZE 97 | #define PAGE_SIZE 0x1000 /* 4k */ 98 | 99 | /* This must be same with the dwAllocationGranularity 100 | * member of the SYSTEM_INFO structure on Windows. 101 | */ 102 | #define ALLOCATION_UNIT 0x10000 /* 64k */ 103 | 104 | typedef struct { 105 | void *addr; 106 | size_t size; 107 | #ifdef WIN32 108 | DWORD protect; 109 | #endif 110 | } mem_state_t; 111 | 112 | typedef struct funchook_page { 113 | #ifdef FUNCHOOK_ENTRY_AT_PAGE_BOUNDARY 114 | funchook_entry_t entries[1]; /* This contains at most one. */ 115 | #endif 116 | struct funchook_page *next; 117 | uint16_t used; 118 | #ifndef FUNCHOOK_ENTRY_AT_PAGE_BOUNDARY 119 | funchook_entry_t entries[1]; /* This contains zero or more. */ 120 | #endif 121 | } funchook_page_t; 122 | 123 | /* Functions in funchook.c */ 124 | extern const size_t funchook_size; 125 | extern char funchook_debug_file[]; 126 | void funchook_log(funchook_t *funchook, const char *fmt, ...) __attribute__((__format__ (__printf__, 2, 3))); 127 | void funchook_set_error_message(funchook_t *funchook, const char *fmt, ...) __attribute__((__format__ (__printf__, 2, 3))); 128 | 129 | /* Functions in funchook_linux.c & funchook_windows.c */ 130 | extern const size_t page_size; 131 | extern const size_t allocation_unit; /* windows only */ 132 | 133 | funchook_t *funchook_alloc(void); 134 | int funchook_free(funchook_t *funchook); 135 | 136 | int funchook_page_alloc(funchook_t *funchook, funchook_page_t **page_out, uint8_t *func, ip_displacement_t *disp); 137 | int funchook_page_free(funchook_t *funchook, funchook_page_t *page); 138 | int funchook_page_protect(funchook_t *funchook, funchook_page_t *page); 139 | int funchook_page_unprotect(funchook_t *funchook, funchook_page_t *page); 140 | 141 | int funchook_unprotect_begin(funchook_t *funchook, mem_state_t *mstate, void *addr, size_t len); 142 | int funchook_unprotect_end(funchook_t *funchook, const mem_state_t *mstate); 143 | 144 | void *funchook_resolve_func(funchook_t *funchook, void *func); 145 | 146 | /* Functions in funchook_{CPU_NAME}.c */ 147 | int funchook_make_trampoline(funchook_t *funchook, ip_displacement_t *disp, const insn_t *func, insn_t *trampoline, size_t *trampoline_size); 148 | int funchook_fix_code(funchook_t *funchook, funchook_entry_t *entry, const ip_displacement_t *disp, const void *func, const void *hook_func); 149 | #ifdef CPU_X86_64 150 | int funchook_page_avail(funchook_t *funchook, funchook_page_t *page, int idx, uint8_t *addr, ip_displacement_t *disp); 151 | #else 152 | #define funchook_page_avail(funchook, page, idx, addr, disp) (1) 153 | #endif 154 | 155 | #endif 156 | -------------------------------------------------------------------------------- /funchook/src/funchook_x86.h: -------------------------------------------------------------------------------- 1 | /* -*- indent-tabs-mode: nil -*- 2 | * 3 | * This file is part of Funchook. 4 | * https://github.com/kubo/funchook 5 | * 6 | * Funchook is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by the 8 | * Free Software Foundation, either version 2 of the License, or (at your 9 | * option) any later version. 10 | * 11 | * As a special exception, the copyright holders of this library give you 12 | * permission to link this library with independent modules to produce an 13 | * executable, regardless of the license terms of these independent 14 | * modules, and to copy and distribute the resulting executable under 15 | * terms of your choice, provided that you also meet, for each linked 16 | * independent module, the terms and conditions of the license of that 17 | * module. An independent module is a module which is not derived from or 18 | * based on this library. If you modify this library, you may extend this 19 | * exception to your version of the library, but you are not obliged to 20 | * do so. If you do not wish to do so, delete this exception statement 21 | * from your version. 22 | * 23 | * Funchook is distributed in the hope that it will be useful, but WITHOUT 24 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 25 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 26 | * for more details. 27 | * 28 | * You should have received a copy of the GNU General Public License 29 | * along with Funchook. If not, see . 30 | */ 31 | #ifndef FUNCHOOK_X86_H 32 | #define FUNCHOOK_X86_H 1 33 | 34 | #define MAX_INSN_LEN 16 35 | #define MAX_INSN_CHECK_SIZE 256 36 | 37 | #define JUMP32_SIZE 5 38 | #ifdef CPU_X86_64 39 | #define JUMP64_SIZE 14 40 | #endif 41 | 42 | #define TRAMPOLINE_SIZE (JUMP32_SIZE + (MAX_INSN_LEN - 1) + JUMP32_SIZE) 43 | 44 | typedef uint8_t insn_t; 45 | 46 | typedef struct funchook_entry { 47 | void *target_func; 48 | void *hook_func; 49 | uint8_t trampoline[TRAMPOLINE_SIZE]; 50 | uint8_t old_code[JUMP32_SIZE]; 51 | uint8_t new_code[JUMP32_SIZE]; 52 | #ifdef CPU_X86_64 53 | uint8_t transit[JUMP64_SIZE]; 54 | #endif 55 | } funchook_entry_t; 56 | 57 | typedef struct { 58 | const insn_t *dst_addr; 59 | intptr_t src_addr_offset; 60 | intptr_t pos_offset; 61 | } ip_displacement_entry_t; 62 | 63 | typedef struct { 64 | ip_displacement_entry_t disp[2]; 65 | } ip_displacement_t; 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /funchook/src/insts.h: -------------------------------------------------------------------------------- 1 | /* 2 | insts.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2021 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #ifndef INSTS_H 13 | #define INSTS_H 14 | 15 | #include "instructions.h" 16 | 17 | 18 | /* Flags Table */ 19 | extern _iflags FlagsTable[]; 20 | 21 | /* Root Trie DB */ 22 | extern _InstSharedInfo InstSharedInfoTable[]; 23 | extern _InstInfo InstInfos[]; 24 | extern _InstInfoEx InstInfosEx[]; 25 | extern _InstNode InstructionsTree[]; 26 | 27 | /* 3DNow! Trie DB */ 28 | extern _InstNode Table_0F_0F; 29 | /* AVX related: */ 30 | extern _InstNode Table_0F, Table_0F_38, Table_0F_3A; 31 | 32 | /* 33 | * The inst_lookup will return on of these two instructions according to the specified decoding mode. 34 | * ARPL or MOVSXD on 64 bits is one byte instruction at index 0x63. 35 | */ 36 | extern _InstInfo II_MOVSXD; 37 | 38 | /* 39 | * The NOP instruction can be prefixed by REX in 64bits, therefore we have to decide in runtime whether it's an XCHG or NOP instruction. 40 | * If 0x90 is prefixed by a usable REX it will become XCHG, otherwise it will become a NOP. 41 | * Also note that if it's prefixed by 0xf3, it becomes a Pause. 42 | */ 43 | extern _InstInfo II_NOP; 44 | extern _InstInfo II_PAUSE; 45 | 46 | /* 47 | * RDRAND and VMPTRLD share same 2.3 bytes opcode, and then alternates on the MOD bits, 48 | * RDRAND is OT_FULL_REG while VMPTRLD is OT_MEM, and there's no such mixed type. 49 | * So a hack into the inst_lookup was added for this decision, the DB isn't flexible enough. :( 50 | */ 51 | extern _InstInfo II_RDRAND; 52 | 53 | /* 54 | * Used for letting the extract operand know the type of operands without knowing the 55 | * instruction itself yet, because of the way those instructions work. 56 | * See function instructions.c!inst_lookup_3dnow. 57 | */ 58 | extern _InstInfo II_3DNOW; 59 | 60 | /* Helper tables for pseudo compare mnemonics. */ 61 | extern uint16_t CmpMnemonicOffsets[8]; /* SSE */ 62 | extern uint16_t VCmpMnemonicOffsets[32]; /* AVX */ 63 | 64 | #endif /* INSTS_H */ 65 | -------------------------------------------------------------------------------- /funchook/src/operands.h: -------------------------------------------------------------------------------- 1 | /* 2 | operands.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2021 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #ifndef OPERANDS_H 13 | #define OPERANDS_H 14 | 15 | #include "config.h" 16 | #include "decoder.h" 17 | #include "prefix.h" 18 | #include "instructions.h" 19 | 20 | int operands_extract(_CodeInfo* ci, _DInst* di, _InstInfo* ii, 21 | _iflags instFlags, _OpType type, 22 | unsigned int modrm, _PrefixState* ps, _DecodeType effOpSz, 23 | _DecodeType effAdrSz, _Operand* op); 24 | 25 | #endif /* OPERANDS_H */ 26 | -------------------------------------------------------------------------------- /funchook/src/prefix.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamSCALEFORM/scaleform/f5e051c035a8d860d4f5412448f6049b53fbd626/funchook/src/prefix.c -------------------------------------------------------------------------------- /funchook/src/prefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | prefix.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2021 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #ifndef PREFIX_H 13 | #define PREFIX_H 14 | 15 | #include "config.h" 16 | #include "decoder.h" 17 | 18 | 19 | /* Specifies the type of the extension prefix, such as: REX, 2 bytes VEX, 3 bytes VEX. */ 20 | typedef enum {PET_NONE = 0, PET_REX, PET_VEX2BYTES, PET_VEX3BYTES} _PrefixExtType; 21 | 22 | /* Specifies an index into a table of prefixes by their type. */ 23 | typedef enum {PFXIDX_NONE = -1, PFXIDX_REX, PFXIDX_LOREP, PFXIDX_SEG, PFXIDX_OP_SIZE, PFXIDX_ADRS, PFXIDX_MAX} _PrefixIndexer; 24 | 25 | /* 26 | * This holds the prefixes state for the current instruction we decode. 27 | * decodedPrefixes includes all specific prefixes that the instruction got. 28 | * start is a pointer to the first prefix to take into account. 29 | * last is a pointer to the last byte we scanned. 30 | * Other pointers are used to keep track of prefixes positions and help us know if they appeared already and where. 31 | */ 32 | typedef struct { 33 | _iflags decodedPrefixes, usedPrefixes; 34 | /* Number of prefixes scanned for current instruction, including VEX! */ 35 | unsigned int count; 36 | uint16_t unusedPrefixesMask; 37 | /* Holds the offset to the prefix byte by its type. */ 38 | uint16_t pfxIndexer[PFXIDX_MAX]; 39 | _PrefixExtType prefixExtType; 40 | /* Indicates whether the operand size prefix (0x66) was used as a mandatory prefix. */ 41 | int isOpSizeMandatory; 42 | /* If VEX prefix is used, store the VEX.vvvv field. */ 43 | unsigned int vexV; 44 | /* The fields B/X/R/W/L of REX and VEX are stored together in this byte. */ 45 | unsigned int vrex; 46 | const uint8_t* vexPos; 47 | } _PrefixState; 48 | 49 | /* 50 | * Intel supports 6 types of prefixes, whereas AMD supports 5 types (lock is seperated from rep/nz). 51 | * REX is the fifth prefix type, this time I'm based on AMD64. 52 | * VEX is the 6th, though it can't be repeated. 53 | */ 54 | #define MAX_PREFIXES (5) 55 | 56 | extern int PrefixTables[256 * 2]; 57 | 58 | _INLINE_ int prefixes_is_valid(unsigned char ch, _DecodeType dt) 59 | { 60 | /* The predicate selects (branchlessly) second half table for 64 bits otherwise selects first half. */ 61 | return PrefixTables[ch + ((dt >> 1) << 8)]; 62 | } 63 | 64 | /* Ignore a specific prefix type. */ 65 | _INLINE_ void prefixes_ignore(_PrefixState* ps, _PrefixIndexer pi) 66 | { 67 | /* 68 | * If that type of prefix appeared already, set the bit of that *former* prefix. 69 | * Anyway, set the new index of that prefix type to the current index, so next time we know its position. 70 | */ 71 | ps->unusedPrefixesMask |= ps->pfxIndexer[pi]; 72 | } 73 | 74 | void prefixes_ignore_all(_PrefixState* ps); 75 | uint16_t prefixes_set_unused_mask(_PrefixState* ps); 76 | void prefixes_decode(_CodeInfo* ci, _PrefixState* ps); 77 | void prefixes_use_segment(_iflags defaultSeg, _PrefixState* ps, _DecodeType dt, _DInst* di); 78 | 79 | #endif /* PREFIX_H */ 80 | -------------------------------------------------------------------------------- /funchook/src/textdefs.c: -------------------------------------------------------------------------------- 1 | /* 2 | textdefs.c 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2021 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #include "textdefs.h" 13 | 14 | #ifndef DISTORM_LIGHT 15 | 16 | static uint8_t Nibble2ChrTable[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 17 | #define NIBBLE_TO_CHR Nibble2ChrTable[t] 18 | 19 | void str_hex(_WString* s, const uint8_t* buf, unsigned int len) 20 | { 21 | /* 256 * 2 : 2 chars per byte value. */ 22 | static const char* TextBTable = 23 | "000102030405060708090a0b0c0d0e0f" \ 24 | "101112131415161718191a1b1c1d1e1f" \ 25 | "202122232425262728292a2b2c2d2e2f" \ 26 | "303132333435363738393a3b3c3d3e3f" \ 27 | "404142434445464748494a4b4c4d4e4f" \ 28 | "505152535455565758595a5b5c5d5e5f" \ 29 | "606162636465666768696a6b6c6d6e6f" \ 30 | "707172737475767778797a7b7c7d7e7f" \ 31 | "808182838485868788898a8b8c8d8e8f" \ 32 | "909192939495969798999a9b9c9d9e9f" \ 33 | "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" \ 34 | "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" \ 35 | "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" \ 36 | "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" \ 37 | "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" \ 38 | "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; 39 | 40 | unsigned int i = 0; 41 | /* Length is at least 1, enter loop. */ 42 | s->length = len * 2; 43 | s->p[len * 2] = 0; 44 | do { 45 | RSHORT(&s->p[i]) = RSHORT(&TextBTable[(*buf) * 2]); 46 | buf++; 47 | i += 2; 48 | } while (i < len * 2); 49 | } 50 | 51 | #ifdef SUPPORT_64BIT_OFFSET 52 | 53 | void str_int_impl(unsigned char** s, uint64_t x) 54 | { 55 | int8_t* buf; 56 | int shift = 0; 57 | OFFSET_INTEGER t = x; 58 | 59 | buf = (int8_t*)*s; 60 | 61 | *buf++ = '0'; 62 | *buf++ = 'x'; 63 | 64 | if (x == 0) { 65 | *buf = '0'; 66 | *s += 3; 67 | return; 68 | } 69 | 70 | do { 71 | t >>= 4; 72 | shift += 4; 73 | } while (t); 74 | 75 | do { 76 | shift -= 4; 77 | t = (x >> shift) & 0xf; 78 | *buf++ = NIBBLE_TO_CHR; 79 | } while (shift > 0); 80 | 81 | *s = (unsigned char*)buf; 82 | } 83 | 84 | #else 85 | 86 | void str_int_impl(unsigned char** s, uint8_t src[8]) 87 | { 88 | int8_t* buf; 89 | int i = 0, shift = 0; 90 | uint32_t x = RULONG(&src[sizeof(int32_t)]); 91 | int t; 92 | 93 | buf = (int8_t*)*s; 94 | buf[0] = '0'; 95 | buf[1] = 'x'; 96 | buf += 2; 97 | 98 | for (shift = 28; shift != -4; shift -= 4) { 99 | t = (x >> shift) & 0xf; 100 | if (i | t) buf[i++] = NIBBLE_TO_CHR; 101 | } 102 | 103 | x = RULONG(src); 104 | for (shift = 28; shift != 0; shift -= 4) { 105 | t = (x >> shift) & 0xf; 106 | if (i | t) buf[i++] = NIBBLE_TO_CHR; 107 | } 108 | t = x & 0xf; 109 | buf[i++] = NIBBLE_TO_CHR; 110 | 111 | *s += (size_t)(i + 2); 112 | } 113 | 114 | #endif /* SUPPORT_64BIT_OFFSET */ 115 | 116 | #endif /* DISTORM_LIGHT */ 117 | -------------------------------------------------------------------------------- /funchook/src/textdefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | textdefs.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2021 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #ifndef TEXTDEFS_H 13 | #define TEXTDEFS_H 14 | 15 | #include "config.h" 16 | #include "wstring.h" 17 | 18 | #ifndef DISTORM_LIGHT 19 | 20 | #define PLUS_DISP_CHR '+' 21 | #define MINUS_DISP_CHR '-' 22 | #define OPEN_CHR '[' 23 | #define CLOSE_CHR ']' 24 | #define SP_CHR ' ' 25 | #define SEG_OFF_CHR ':' 26 | 27 | /* 28 | Naming Convention: 29 | 30 | * get - returns a pointer to a string. 31 | * str - concatenates to string. 32 | 33 | * hex - means the function is used for hex dump (number is padded to required size) - Little Endian output. 34 | * code - means the function is used for disassembled instruction - Big Endian output. 35 | * off - means the function is used for 64bit offset - Big Endian output. 36 | 37 | * h - '0x' in front of the string. 38 | 39 | * b - byte 40 | * dw - double word (can be used for word also) 41 | * qw - quad word 42 | 43 | * all numbers are in HEX. 44 | */ 45 | 46 | void str_hex(_WString* s, const uint8_t* buf, unsigned int len); 47 | 48 | #ifdef SUPPORT_64BIT_OFFSET 49 | #define str_int(s, x) str_int_impl((s), (x)) 50 | void str_int_impl(unsigned char** s, uint64_t x); 51 | #else 52 | #define str_int(s, x) str_int_impl((s), (uint8_t*)&(x)) 53 | void str_int_impl(unsigned char** s, uint8_t src[8]); 54 | #endif 55 | 56 | #endif /* DISTORM_LIGHT */ 57 | 58 | #endif /* TEXTDEFS_H */ 59 | -------------------------------------------------------------------------------- /funchook/src/wstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | wstring.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2021 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #ifndef WSTRING_H 13 | #define WSTRING_H 14 | 15 | #include "config.h" 16 | #include "../include/mnemonics.h" 17 | 18 | #ifndef DISTORM_LIGHT 19 | 20 | _INLINE_ void strcat_WSR(unsigned char** str, const _WRegister* reg) 21 | { 22 | /* 23 | * Longest register name is YMM15 - 5 characters, 24 | * Copy 8 so compiler can do a QWORD move. 25 | * We copy nul termination and fix the length, so it's okay to copy more to the output buffer. 26 | * There's a sentinel register to make sure we don't read past the end of the registers table. 27 | */ 28 | memcpy((int8_t*)*str, (const int8_t*)reg->p, 8); 29 | *str += reg->length; 30 | } 31 | 32 | #define strfinalize_WS(s, end) do { *end = 0; s.length = (unsigned int)((size_t)end - (size_t)s.p); } while (0) 33 | #define chrcat_WS(s, ch) do { *s = ch; s += 1; } while (0) 34 | #define strcat_WS(s, buf, copylen, advancelen) do { memcpy((int8_t*)s, buf, copylen); s += advancelen; } while(0) 35 | 36 | #endif /* DISTORM_LIGHT */ 37 | 38 | #endif /* WSTRING_H */ 39 | -------------------------------------------------------------------------------- /funchook/src/x86defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | x86defs.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2021 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #ifndef X86DEFS_H 13 | #define X86DEFS_H 14 | 15 | 16 | #define SEG_REGS_MAX (6) 17 | #define CREGS_MAX (9) 18 | #define DREGS_MAX (8) 19 | 20 | /* Maximum instruction size, including prefixes */ 21 | #define INST_MAXIMUM_SIZE (15) 22 | 23 | /* Maximum range of imm8 (comparison type) of special SSE CMP instructions. */ 24 | #define INST_CMP_MAX_RANGE (8) 25 | 26 | /* Maximum range of imm8 (comparison type) of special AVX VCMP instructions. */ 27 | #define INST_VCMP_MAX_RANGE (32) 28 | 29 | /* Wait instruction byte code. */ 30 | #define INST_WAIT_INDEX (0x9b) 31 | 32 | /* Lea instruction byte code. */ 33 | #define INST_LEA_INDEX (0x8d) 34 | 35 | /* NOP/XCHG instruction byte code. */ 36 | #define INST_NOP_INDEX (0x90) 37 | 38 | /* ARPL/MOVSXD instruction byte code. */ 39 | #define INST_ARPL_INDEX (0x63) 40 | 41 | /* 42 | * Minimal MODR/M value of divided instructions. 43 | * It's 0xc0, two MSBs set, which indicates a general purpose register is used too. 44 | */ 45 | #define INST_DIVIDED_MODRM (0xc0) 46 | 47 | /* This is the escape byte value used for 3DNow! instructions. */ 48 | #define _3DNOW_ESCAPE_BYTE (0x0f) 49 | 50 | #define PREFIX_LOCK (0xf0) 51 | #define PREFIX_REPNZ (0xf2) 52 | #define PREFIX_REP (0xf3) 53 | #define PREFIX_CS (0x2e) 54 | #define PREFIX_SS (0x36) 55 | #define PREFIX_DS (0x3e) 56 | #define PREFIX_ES (0x26) 57 | #define PREFIX_FS (0x64) 58 | #define PREFIX_GS (0x65) 59 | #define PREFIX_OP_SIZE (0x66) 60 | #define PREFIX_ADDR_SIZE (0x67) 61 | #define PREFIX_VEX2b (0xc5) 62 | #define PREFIX_VEX3b (0xc4) 63 | 64 | /* REX prefix value range, 64 bits mode decoding only. */ 65 | #define PREFIX_REX_LOW (0x40) 66 | #define PREFIX_REX_HI (0x4f) 67 | /* In order to use the extended GPR's we have to add 8 to the Modr/M info values. */ 68 | #define EX_GPR_BASE (8) 69 | 70 | /* Mask for REX and VEX features: */ 71 | /* Base */ 72 | #define PREFIX_EX_B (1) 73 | /* Index */ 74 | #define PREFIX_EX_X (2) 75 | /* Register */ 76 | #define PREFIX_EX_R (4) 77 | /* Operand Width */ 78 | #define PREFIX_EX_W (8) 79 | /* Vector Lengh */ 80 | #define PREFIX_EX_L (0x10) 81 | 82 | #endif /* X86DEFS_H */ 83 | -------------------------------------------------------------------------------- /init.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN 4 | #include "memscan/src/memscan/memscan.h" 5 | 6 | #include "sdk.hpp" 7 | 8 | #ifdef WIN32 9 | #include 10 | #endif 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #define LOG(...) (void)(printf("TeamScaleform/ "), printf(__VA_ARGS__)) 17 | 18 | #ifdef _DEBUG 19 | #define DEBUG(...) (void)(printf("TeamScaleform/ DEBUG: "), printf(__VA_ARGS__)) 20 | #else 21 | #define DEBUG(...) 22 | #endif 23 | 24 | namespace tsf 25 | { 26 | struct panorama_t; 27 | struct cvar_t; 28 | struct cvars_t; 29 | } 30 | 31 | struct context_t { 32 | context_t() = default; 33 | 34 | memscan::mapped_region_t client; 35 | memscan::mapped_region_t engine; 36 | memscan::mapped_region_t panorama; 37 | 38 | struct interfaces_t 39 | { 40 | tsf::panorama_t *panorama; 41 | tsf::cvars_t *cvars; 42 | } i; 43 | struct functions_t 44 | { 45 | char *(CDECL* compare_extension)(const char *lhs, const char *rhs); 46 | } f; 47 | struct cvars_t 48 | { 49 | tsf::cvar_t *cl_hud_color; 50 | tsf::cvar_t *cl_hud_background_alpha; 51 | tsf::cvar_t *cl_hud_healthammo_style; 52 | } c; 53 | struct globals_t 54 | { 55 | bool scf_on; 56 | bool old_wp; 57 | bool show_rarity; 58 | bool is_vulkan; 59 | } g; 60 | } inline ctx; 61 | 62 | void init(); -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | // Built by Cristei Gabriel-Marian (cristeigabriel) 2 | // (cristei g772 gmail com) 3 | // 4 | // ~TeamSCALEFORM~ 5 | 6 | #include 7 | #include 8 | #include "init.hpp" 9 | 10 | static void run_init() 11 | { 12 | LOG("Created by cristeigabriel, with the help of:\n" 13 | "isak, jo and other public contributors\n" 14 | "cristeigabriel: reverse engineering, boilerplate, original JS,\n" 15 | "making TeamSCALEFORM its own project\n" 16 | "isak: new JS, design\n" 17 | "jo: 2013 winpanel\n" 18 | "bruhmoment21: Linux port\n" 19 | "~~~~~~~~~~~~\n" 20 | "Refer to config.hpp for help\n" 21 | "NOTE: TeamSCALEFORM currently requires you disconnect\n" 22 | "for Scaleform Toggle Off to take effect\n" 23 | "(Toggle On will immediately take effect.)\n" 24 | "JavaScript to load on bind must be located at %s\\base.js\n" 25 | "~~~~~~~~~~~~\n" 26 | "This software is licensed under AGPL-3.0, if it\n" 27 | "wasn't shipped with the source code, you can download it at\n" 28 | "https://github.com/TeamSCALEFORM/scaleform\n" 29 | "~~~~~~~~~~~~\n", 30 | std::filesystem::current_path().string().c_str()); 31 | 32 | ::init(); 33 | } 34 | 35 | #ifdef WIN32 36 | BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) 37 | { 38 | if (reason != DLL_PROCESS_ATTACH) 39 | return FALSE; 40 | (void)(reserved); 41 | 42 | AllocConsole(); 43 | freopen_s((FILE**)stdout, "CONOUT$", "w", stdout); 44 | 45 | run_init(); 46 | return TRUE; 47 | } 48 | #else 49 | static void __attribute__((constructor)) attach() 50 | { 51 | std::thread _{run_init}; 52 | _.detach(); 53 | } 54 | #endif -------------------------------------------------------------------------------- /media/showcase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamSCALEFORM/scaleform/f5e051c035a8d860d4f5412448f6049b53fbd626/media/showcase.png -------------------------------------------------------------------------------- /media/showcase_linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamSCALEFORM/scaleform/f5e051c035a8d860d4f5412448f6049b53fbd626/media/showcase_linux.png -------------------------------------------------------------------------------- /memscan/.clang-format: -------------------------------------------------------------------------------- 1 | AccessModifierOffset: -4 2 | AlignAfterOpenBracket: Align 3 | AlignConsecutiveAssignments: true 4 | AlignConsecutiveDeclarations: true 5 | AlignEscapedNewlines: Right 6 | AlignOperands: true 7 | AlignTrailingComments: true 8 | AllowAllParametersOfDeclarationOnNextLine: true 9 | AllowShortBlocksOnASingleLine: false 10 | AllowShortCaseLabelsOnASingleLine: false 11 | AllowShortFunctionsOnASingleLine: All 12 | AllowShortIfStatementsOnASingleLine: false 13 | AllowShortLoopsOnASingleLine: false 14 | AlwaysBreakAfterDefinitionReturnType: TopLevel 15 | AlwaysBreakAfterReturnType: TopLevel 16 | AlwaysBreakBeforeMultilineStrings: false 17 | AlwaysBreakTemplateDeclarations: true # false 18 | BinPackArguments: true 19 | BinPackParameters: true 20 | BraceWrapping: 21 | AfterClass: true # false 22 | AfterControlStatement: true # false 23 | AfterEnum: true # false 24 | AfterFunction: true # false 25 | AfterNamespace: true # false 26 | AfterObjCDeclaration: true # false 27 | AfterStruct: true # false 28 | AfterUnion: true # false 29 | AfterExternBlock: true # false 30 | BeforeCatch: true # false 31 | BeforeElse: true # false 32 | IndentBraces: true # false 33 | SplitEmptyFunction: true 34 | SplitEmptyRecord: true 35 | SplitEmptyNamespace: true 36 | BreakBeforeBinaryOperators: None 37 | BreakBeforeBraces: Linux 38 | BreakBeforeInheritanceComma: false 39 | BreakBeforeTernaryOperators: true 40 | BreakConstructorInitializersBeforeComma: false 41 | BreakConstructorInitializers: BeforeColon 42 | BreakAfterJavaFieldAnnotations: false 43 | BreakStringLiterals: true 44 | ColumnLimit: 80 45 | CommentPragmas: '^ IWYU pragma:' 46 | CompactNamespaces: false 47 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 48 | ConstructorInitializerIndentWidth: 4 49 | ContinuationIndentWidth: 4 50 | Cpp11BracedListStyle: true 51 | DerivePointerAlignment: false 52 | DisableFormat: false 53 | ExperimentalAutoDetectBinPacking: false 54 | FixNamespaceComments: true 55 | IncludeBlocks: Preserve 56 | IndentCaseLabels: true # false 57 | IndentPPDirectives: None 58 | IndentWidth: 4 #2 59 | IndentWrappedFunctionNames: false 60 | JavaScriptQuotes: Leave 61 | JavaScriptWrapImports: true 62 | KeepEmptyLinesAtTheStartOfBlocks: true 63 | MacroBlockBegin: '' 64 | MacroBlockEnd: '' 65 | MaxEmptyLinesToKeep: 1 66 | NamespaceIndentation: None 67 | ObjCBlockIndentWidth: 2 68 | ObjCSpaceAfterProperty: false 69 | ObjCSpaceBeforeProtocolList: true 70 | PenaltyBreakAssignment: 2 71 | PenaltyBreakBeforeFirstCallParameter: 19 72 | PenaltyBreakComment: 300 73 | PenaltyBreakFirstLessLess: 120 74 | PenaltyBreakString: 1000 75 | PenaltyExcessCharacter: 1000000 76 | PenaltyReturnTypeOnItsOwnLine: 60 77 | PointerAlignment: Left 78 | ReflowComments: true 79 | SortIncludes: true 80 | SortUsingDeclarations: true 81 | SpaceAfterCStyleCast: false 82 | SpaceAfterTemplateKeyword: true 83 | SpaceBeforeAssignmentOperators: true 84 | SpaceBeforeParens: ControlStatements 85 | SpaceInEmptyParentheses: false 86 | SpacesBeforeTrailingComments: 1 87 | SpacesInAngles: false 88 | SpacesInContainerLiterals: true 89 | SpacesInCStyleCastParentheses: false 90 | SpacesInParentheses: false 91 | SpacesInSquareBrackets: false 92 | Standard: Cpp03 93 | TabWidth: 8 94 | UseTab: Never -------------------------------------------------------------------------------- /memscan/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | *.h linguist-language=C 5 | -------------------------------------------------------------------------------- /memscan/.gitignore: -------------------------------------------------------------------------------- 1 | checks.json 2 | build 3 | .vscode -------------------------------------------------------------------------------- /memscan/README.md: -------------------------------------------------------------------------------- 1 | # memscan 2 | **Feature-rich** **C99** library for memory scanning purposes, designed for **Windows** running machines, meant to work on both **32-bit** and **64-bit** portable executables. 3 | 4 | **memscan** has a **modern C++** wrapper which abstracts the **C** contents in an user-friendly way. To look at the **C** example, press [here](./src/test.c), and, for the **C++** example, press [here](./src/test.cpp). 5 | 6 | ### ✔ Features 7 | - 🚶 Follow system 8 |
9 | 10 | - - - 11 | It is an internal concept which is exposed to every of the following memscan **features**. 12 | - - - 13 | 14 | - It expects a base address, bounds and a find sequence. 15 | - Find sequences can be made of: 16 | - A bytecode-style string: 17 | - Example: ``"AA BB CC DD EE FF"`` 18 | - This is converted back to a byte array with a size at run-time. 19 | - **OR**, byte array and it's size 20 | - Example: ``{0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, 6`` 21 | - And, universally: 22 | - N-th match: 23 | - Sequences may repeat within the specified range, so you can choose which match you want to select, 24 | - Matches start at 0, implying the first match. 25 | - Direction: 26 | - You can go either backwards, or forwards, within the specified bounds, starting from the base address. 27 | - Invalid inputs will be reflected in the return with the status variable. This carries to the user-level return. 28 | 29 |
30 | 31 | - 🔎 Multi-paradigm pattern-scanning 32 |
33 | 34 | - It expects bounds, a pattern sequence and, optionally, a find sequence. 35 | - Pattern sequences can be made of: 36 | - A bytecode-style string: 37 | - Example: `"AA BB CC DD EE FF"` 38 | - **OR**, a byte array and it's size 39 | - Example: ``{0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, 6`` 40 | - Both of the aforementioned can contain a preset symbol to signal that a mismatch at said position is allowed. It is set [here](./src/memscan/memscan.h). 41 | - And, universally: 42 | - N-th match: 43 | - Sequences may repeat within the specified range, so you can choose which match you want to select, 44 | - Matches start at 0, implying the first match. 45 | - Refer to **Follow system** to see find sequences. 46 | - Every combination of the aforementioned is possible in the user-level API. 47 | - The result of this process carries an address depending on the success of the process and a status. For documentation on the status, refer to [this](./src/memscan/memscan.h) file. 48 | 49 |
50 | 51 | - ❌ Cross-reference resolver 52 |
53 | 54 | - It expects bounds, either a base address or content, prompt to whether there should be an endianness swap, N-th match, based on which method you choose and, optionally, a find sequence. 55 | - Refer to **Follow system** to see find sequences. 56 | - Can resolve references from a given input, or, resolve references at the address where they're represented: 57 | - An example for resolving references from a given input is inputting the following: ``0xAABBCCDD``. 58 | - We assume this is a pointer which we can resolve. When represented in memory, it'll have it's endianness swapped, so it'll look like ``0xDDCCBBAA``, therefore, we will ask for an endianness swap, 59 | - Then, for some reason, want to find the first instance where the contents at the pointer is referenced, so, we will input ``0`` for the N-th match. 60 | - We can also input the address where a pointer is referenced by choosing the right method: 61 | - If the contents at our address look like this sequence: ``8B 4D ? ? ? ?``: 62 | - We'll have to add '`2'` to the address (to skip over the ``8B 4D`` bytes), 63 | - Then, we'll have to prompt an endianness swap, 64 | - Then, for some reason, want to find the first instance where the contents at the address' pointer is referenced so, we will input ``0`` for the N-th match. 65 | - Refer to **Follow system** to see find sequences. 66 | - The result of this process carries an address depending on the success of the process and a status. For documentation on the status, refer to [this](./src/memscan/memscan.h) file. 67 | 68 |
69 | 70 | - 🗒️ String resolver 71 |
72 | 73 | - - - 74 | This component was built off the cross-reference resolver system. 75 | - - - 76 | 77 | - It expects bounds, a (compile-time) string, it's size, N-th match and, optionally, a find sequence. 78 | - Refer to **Follow system** to see find sequences. 79 | - The result of this process carries an address depending on the success of the process and a status. For documentation on the status, refer to [this](./src/memscan/memscan.h) file. 80 | - If the process was succesful, the address will be a pointer to the N-th match of the string. 81 | 82 |
83 | 84 | - 🤷 Scalable 85 |
86 | 87 | - This project is designed to operate under any reasonable circumstance. This can be used alongside DLL-injection, or on copied memory buffers. 88 | 89 |
90 | 91 | ### 📚 Internal documentation 92 | - The user-level API has up-to-date, Doxygen-compliant documentation, which, in most IDEs, should be displayed on hover. 93 | - There's also implementation documentation which you can see [here](./src/memscan/memscan.c). 94 | 95 | ### 📈 Progression 96 | - To do: 97 | - [x] ⚔️ C++ wrapper 98 | - [ ] 🦾 CMake package 99 | - [ ] 🧪 Standard tests 100 | - [ ] 🤝 Multi-platform support 101 | 102 | ### ⚖️ License 103 | I couldn't care less. 104 | -------------------------------------------------------------------------------- /memscan/memscan.cmake: -------------------------------------------------------------------------------- 1 | # verify platform 2 | if (NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") 3 | message("${PROJECT_NAME}: Your platform is not officially supported.") 4 | endif() 5 | 6 | # verify compiler 7 | if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") 8 | message("${PROJECT_NAME}: Your compiler is not officially supported. Issues or build errors may occur.") 9 | endif() 10 | 11 | # options 12 | macro(set_option option help value) 13 | option(${option} ${help} ${value}) 14 | if(${option}) 15 | message(STATUS "${PROJECT_NAME}: ${option}: ON") 16 | target_compile_definitions(${PROJECT_NAME} PUBLIC ${option}) 17 | else() 18 | message(STATUS "${PROJECT_NAME}: ${option}: OFF") 19 | endif() 20 | endmacro() -------------------------------------------------------------------------------- /memscan/src/memscan/util/util.c: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include 3 | #include 4 | 5 | ms_pattern_t 6 | util_build_pattern(const char* data, const ms_usize_t data_size) 7 | { 8 | ms_pattern_t result = {0}; 9 | 10 | result.m_data = NULL; 11 | result.m_size = 0; 12 | 13 | #if !UTIL_UNSAFE_OPTIMIZATIONS 14 | if (data == NULL) { 15 | result.m_status = MS_BUILD_STATUS_NO_DATA; 16 | 17 | goto leave; 18 | } 19 | #endif 20 | 21 | size_t len = data_size; 22 | 23 | #if !UTIL_UNSAFE_OPTIMIZATIONS 24 | if (len == 0) { 25 | result.m_status = MS_BUILD_STATUS_SHORT_DATA; 26 | goto leave; 27 | } 28 | #endif 29 | 30 | /* data */ 31 | 32 | char* start = (char*)data; 33 | char* end = (char*)(data + len); 34 | 35 | /* precompute allocation size */ 36 | 37 | ms_usize_t size = 0; 38 | 39 | for (char* current = start; current < end; ++current) 40 | ++size; 41 | 42 | ms_ubyte_t* bytes = (ms_ubyte_t*)malloc(size * sizeof *bytes); 43 | 44 | /* prefetched */ 45 | 46 | ms_usize_t indice = 0; 47 | 48 | for (char* current = start; current < end; ++current) { 49 | /* hex substring conversion */ 50 | 51 | bytes[indice++] = (ms_ubyte_t)strtoul(current, ¤t, 16); 52 | } 53 | 54 | result.m_data = bytes; 55 | result.m_size = indice; 56 | result.m_status = MS_BUILD_STATUS_OK; 57 | 58 | leave: 59 | return result; 60 | } 61 | 62 | /* */ 63 | 64 | ms_free_t 65 | util_free_pattern(ms_pattern_t* pattern) 66 | { 67 | #if !UTIL_UNSAFE_OPTIMIZATIONS 68 | if (pattern == NULL) { 69 | return MS_FREE_NO; 70 | } 71 | #endif 72 | 73 | ms_free_t result = MS_FREE_NO; 74 | 75 | if (pattern->m_status == MS_BUILD_STATUS_OK) { 76 | free(pattern->m_data); 77 | pattern->m_data = NULL; 78 | 79 | result = MS_FREE_YES; 80 | } 81 | 82 | pattern->m_size = 0; 83 | 84 | return result; 85 | } 86 | 87 | ms_ubyte_t* 88 | util_ptr_to_byteset(const ms_uptr_t num, bool swap_endianness) 89 | { 90 | /* data */ 91 | 92 | static ms_ubyte_t bytes[MEMSCAN_BYTESET_SIZE] = {0}; 93 | 94 | for (ms_usize_t i = 0; i < MEMSCAN_BYTESET_SIZE; ++i) { 95 | /* shift formation to get current indice */ 96 | 97 | bytes[swap_endianness ? i : MEMSCAN_BYTESET_SIZE - i - 1] = 98 | (ms_ubyte_t)(num >> (i * CHAR_BIT)); 99 | } 100 | 101 | return bytes; 102 | } -------------------------------------------------------------------------------- /memscan/src/memscan/util/util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* Includes */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | /* Types */ 10 | 11 | typedef uint8_t ms_ubyte_t; 12 | typedef uintptr_t ms_uptr_t; 13 | typedef uint32_t ms_usize_t; 14 | 15 | /* Extern */ 16 | 17 | #if __cplusplus 18 | #define MEMSCAN_EXTERN extern "C" 19 | #else 20 | #define MEMSCAN_EXTERN extern 21 | #endif 22 | 23 | typedef enum { 24 | /* nothing to free, or there's a condition preventing the process */ 25 | MS_FREE_NO = 0, 26 | 27 | /* the data was found present and then freed */ 28 | MS_FREE_YES 29 | } ms_free_t; 30 | 31 | typedef enum { 32 | /* won't be reached unless UTIL_UNSAFE_OPTIMIZATIONS is off */ 33 | 34 | /* passed data was NULL */ 35 | MS_BUILD_STATUS_NO_DATA = 0, 36 | 37 | /* data len was 0 */ 38 | MS_BUILD_STATUS_SHORT_DATA, 39 | 40 | /* */ 41 | 42 | /* generation has succeeded, status was set to OK */ 43 | MS_BUILD_STATUS_OK 44 | } ms_build_status_t; 45 | 46 | typedef struct { 47 | ms_ubyte_t* m_data; 48 | ms_usize_t m_size; 49 | ms_build_status_t m_status; 50 | } ms_pattern_t; 51 | 52 | /* Methods */ 53 | 54 | /** 55 | * @brief Generate byte code array from byte-code style string 56 | * 57 | * @param data Example: "AA BB CC DD EE FF", equivalent to 58 | * (ms_ubyte_t*)"\xAA\xBB\xCC\xDD\xEE\xFF" 59 | * @param data_size Size of 'data' 60 | * @return Refer to ms_pattern_t for documentation 61 | */ 62 | MEMSCAN_EXTERN ms_pattern_t 63 | util_build_pattern(const char* data, const ms_usize_t data_size); 64 | 65 | /** 66 | * @brief Deallocate pattern array after usage 67 | * 68 | * @param pattern Reference to the pattern construct 69 | * @return Refer to ms_free_t for documentation 70 | */ 71 | MEMSCAN_EXTERN ms_free_t 72 | util_free_pattern(ms_pattern_t* pattern); 73 | 74 | /** 75 | * @brief Convert pointer in numerical form to byteset of MEMSCAN_BYTESET_SIZE 76 | * bytes 77 | * 78 | * @param num Value to convert 79 | * @param swap_endianness Whether to swap endianness or not 80 | * @return Value as a MEMSCAN_BYTESET_SIZE bytes array 81 | */ 82 | MEMSCAN_EXTERN ms_ubyte_t* 83 | util_ptr_to_byteset(const ms_uptr_t num, bool swap_endianness); 84 | 85 | /* Constants */ 86 | 87 | #define MEMSCAN_BYTESET_SIZE (sizeof(ms_uptr_t) / sizeof(ms_ubyte_t)) 88 | #define MEMSCAN_POINTER_BITS (sizeof(ms_uptr_t) * CHAR_BIT) -------------------------------------------------------------------------------- /memscan/src/test.c: -------------------------------------------------------------------------------- 1 | #include "memscan/memscan.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | BOOL WINAPI 8 | DllMain(HINSTANCE hinstDLL, // handle to DLL module 9 | DWORD fdwReason, // reason for calling function 10 | LPVOID lpReserved) // reserved 11 | { 12 | (void)hinstDLL; 13 | (void)lpReserved; 14 | 15 | if (fdwReason != DLL_PROCESS_ATTACH) 16 | return FALSE; 17 | 18 | /* open IO and console */ 19 | 20 | AllocConsole(); 21 | freopen_s((FILE**)stdout, "CONOUT$", "w", stdout); 22 | 23 | clock_t begin = clock(); 24 | 25 | /* current tests are temporary and not guaranteed to work outside of the 26 | * repository owner's machine */ 27 | 28 | /* get guaranteed module in csgo.exe */ 29 | 30 | ms_uptr_t client = (ms_uptr_t)GetModuleHandleA("client.dll"); 31 | 32 | /* pattern finding */ 33 | 34 | #define MAGIC_VALUE 0x40000000 35 | #define GLOBAL_RANGE client, client + MAGIC_VALUE 36 | 37 | const ms_ubyte_t* address = (const ms_ubyte_t*)"\x55\x8B\xEC"; 38 | ms_result_t test_1 = 39 | memscan_find_pattern_nfb(GLOBAL_RANGE, address, 3, MEMSCAN_FIRST_MATCH); 40 | 41 | if (test_1.m_status == MS_RESULT_STATUS_FOUND) { 42 | printf("test1: %x\n", test_1.m_address); 43 | 44 | /* the fact that we're here implies that the following is be guaranteed 45 | * to work */ 46 | 47 | ms_result_t test_2 = memscan_find_pattern_nfs(GLOBAL_RANGE, "55 8B EC", 48 | MEMSCAN_FIRST_MATCH); 49 | 50 | printf("test2: %d %x\n", test_2.m_status, test_2.m_address); 51 | 52 | /* assert that the second test variable has a status of found and that 53 | * it equals the first test variable's status as they're equivalent */ 54 | 55 | assert(test_2.m_status == MS_RESULT_STATUS_FOUND && 56 | test_1.m_address == test_2.m_address); 57 | } 58 | 59 | /* find first occurence of "8B 4D" from the first occurence of "55 8B EC" 60 | * without using a standard follow routine */ 61 | 62 | ms_result_t test_3 = 63 | memscan_find_pattern_nfs(test_1.m_address, test_1.m_address + 0x3000, 64 | "8B 4D", MEMSCAN_FIRST_MATCH); 65 | 66 | if (test_3.m_status == MS_RESULT_STATUS_FOUND) { 67 | printf("test3: %x\n", test_3.m_address); 68 | 69 | ms_result_t test_4 = memscan_find_pattern_ss( 70 | GLOBAL_RANGE, "55 8B EC", MEMSCAN_FIRST_MATCH, "8B 4D", 71 | MEMSCAN_FIRST_MATCH, MS_FOLLOW_DIRECTION_FORWARDS); 72 | 73 | printf("test4: %d %x\n", test_4.m_status, test_4.m_address); 74 | 75 | assert(test_4.m_status == MS_RESULT_STATUS_FOUND && 76 | test_3.m_address == test_4.m_address); 77 | 78 | ms_result_t test_5 = memscan_find_xref_at_nf( 79 | test_1.m_address, test_1.m_address + 0x3000, test_3.m_address + 2, 80 | MEMSCAN_FIRST_MATCH, true); 81 | 82 | printf("test5: %d %x\n", test_5.m_status, test_5.m_address); 83 | 84 | assert(test_5.m_status == MS_RESULT_STATUS_FOUND && 85 | test_5.m_address == (test_3.m_address + 2) && 86 | (*(ms_uptr_t*)test_5.m_address == 87 | *(ms_uptr_t*)(test_3.m_address + 2))); 88 | 89 | printf("test5 2: %x %x\n", *(ms_uptr_t*)test_5.m_address, 90 | *(ms_uptr_t*)(test_3.m_address + 2)); 91 | } 92 | 93 | /* resolve first reference of "NullRNG" string */ 94 | 95 | const char NullRNG[] = "NullRNG"; 96 | 97 | ms_result_t test_6 = memscan_find_string_nf( 98 | GLOBAL_RANGE, NullRNG, sizeof(NullRNG), MEMSCAN_FIRST_MATCH); 99 | 100 | if (test_6.m_status == MS_RESULT_STATUS_FOUND) 101 | printf("test6: %x %s\n", test_6.m_address, 102 | *(const char**)test_6.m_address); 103 | 104 | printf("time: %lf\n", (double)(clock() - begin) / CLOCKS_PER_SEC); 105 | 106 | return TRUE; // Successful DLL_PROCESS_ATTACH. 107 | } -------------------------------------------------------------------------------- /memscan/src/test.cpp: -------------------------------------------------------------------------------- 1 | #include "memscan/memscan.h" 2 | #include 3 | #include 4 | #include 5 | 6 | #undef NDEBUG 7 | #define NDEBUG 0 8 | 9 | BOOL WINAPI 10 | DllMain(HINSTANCE hinstDLL, // handle to DLL module 11 | DWORD fdwReason, // reason for calling function 12 | LPVOID lpReserved) // reserved 13 | { 14 | (void)hinstDLL; 15 | (void)lpReserved; 16 | 17 | if (fdwReason != DLL_PROCESS_ATTACH) 18 | return FALSE; 19 | 20 | /* open IO and console */ 21 | 22 | AllocConsole(); 23 | freopen_s(reinterpret_cast(stdout), "CONOUT$", "w", stdout); 24 | 25 | clock_t begin = clock(); 26 | 27 | /* create range */ 28 | 29 | /* can also take start and end in numeric form */ 30 | 31 | memscan::mapped_region_t client(GetModuleHandleA("client.dll")); 32 | 33 | /* the following are just injections into the context, you can also access 34 | * the functions by doing memscan::mapped_region_t::* but that'll require 35 | * bounds */ 36 | 37 | auto test_1 = client.find_pattern({0x55, 0x8B, 0xEC}); 38 | 39 | if (test_1.has_value()) { 40 | printf("test1: %x\n", test_1.value()); 41 | 42 | /* the fact that we're here implies that the following is be guaranteed 43 | * to work */ 44 | 45 | auto test_2 = client.find_pattern("55 8B EC"); 46 | 47 | if (test_2.has_value()) { 48 | printf("test2: %x\n", test_2.value()); 49 | 50 | /* assert that the second test variable has a status of found and 51 | * that it equals the first test variable's status as they're 52 | * equivalent */ 53 | 54 | assert(test_1.value() == test_2.value()); 55 | } 56 | } 57 | 58 | auto test_3 = memscan::mapped_region_t::find_pattern( 59 | test_1.value(), test_1.value() + 0x3000, "8B 4D"); 60 | 61 | if (test_3.has_value()) { 62 | printf("test3: %x\n", test_3.value()); 63 | 64 | auto test_4 = client.find_pattern( 65 | "55 8B EC", MEMSCAN_FIRST_MATCH, "8B 4D", MEMSCAN_FIRST_MATCH, 66 | MS_FOLLOW_DIRECTION_FORWARDS); 67 | 68 | printf("test4: %x\n", test_4.value()); 69 | 70 | assert(test_3.value() == test_4.value()); 71 | 72 | auto test_5 = memscan::mapped_region_t::find_xref_at( 73 | test_1.value(), test_1.value() + 0x3000, test_3.value() + 2, 74 | MEMSCAN_FIRST_MATCH, true); 75 | 76 | printf("test5: %x\n", test_5.value()); 77 | 78 | assert(test_5.value() == (test_3.value() + 2) && 79 | (*reinterpret_cast(test_5.value()) == 80 | *reinterpret_cast(test_3.value() + 2))); 81 | 82 | printf("test5 2: %x %x\n", 83 | *reinterpret_cast(test_5.value()), 84 | *reinterpret_cast(test_3.value() + 2)); 85 | } 86 | 87 | /* find NulLRNG string */ 88 | 89 | auto test_6 = client.find_string("NullRNG", MEMSCAN_FIRST_MATCH); 90 | 91 | if (test_6.has_value()) 92 | printf("test6: %x %s\n", test_6.value(), 93 | *reinterpret_cast(test_6.value())); 94 | 95 | printf("time: %lf\n", 96 | static_cast(clock() - begin) / CLOCKS_PER_SEC); 97 | 98 | return TRUE; // Successful DLL_PROCESS_ATTACH. 99 | } 100 | -------------------------------------------------------------------------------- /minhook/AUTHORS.txt: -------------------------------------------------------------------------------- 1 | Tsuda Kageyu 2 | Creator, maintainer 3 | 4 | Michael Maltsev 5 | Added "Queue" functions. A lot of bug fixes. 6 | 7 | Andrey Unis 8 | Rewrote the hook engine in plain C. 9 | -------------------------------------------------------------------------------- /minhook/LICENSE.txt: -------------------------------------------------------------------------------- 1 | MinHook - The Minimalistic API Hooking Library for x64/x86 2 | Copyright (C) 2009-2017 Tsuda Kageyu. 3 | 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 COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 18 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 19 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | ================================================================================ 28 | Portions of this software are Copyright (c) 2008-2009, Vyacheslav Patkov. 29 | ================================================================================ 30 | Hacker Disassembler Engine 32 C 31 | Copyright (c) 2008-2009, Vyacheslav Patkov. 32 | All rights reserved. 33 | 34 | Redistribution and use in source and binary forms, with or without 35 | modification, are permitted provided that the following conditions 36 | are met: 37 | 38 | 1. Redistributions of source code must retain the above copyright 39 | notice, this list of conditions and the following disclaimer. 40 | 2. Redistributions in binary form must reproduce the above copyright 41 | notice, this list of conditions and the following disclaimer in the 42 | documentation and/or other materials provided with the distribution. 43 | 44 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 45 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 46 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 47 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 48 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 49 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 50 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 51 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 52 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 53 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 54 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55 | 56 | ------------------------------------------------------------------------------- 57 | Hacker Disassembler Engine 64 C 58 | Copyright (c) 2008-2009, Vyacheslav Patkov. 59 | All rights reserved. 60 | 61 | Redistribution and use in source and binary forms, with or without 62 | modification, are permitted provided that the following conditions 63 | are met: 64 | 65 | 1. Redistributions of source code must retain the above copyright 66 | notice, this list of conditions and the following disclaimer. 67 | 2. Redistributions in binary form must reproduce the above copyright 68 | notice, this list of conditions and the following disclaimer in the 69 | documentation and/or other materials provided with the distribution. 70 | 71 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 72 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 73 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 74 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 75 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 76 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 77 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 78 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 79 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 80 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 81 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 82 | -------------------------------------------------------------------------------- /minhook/README.md: -------------------------------------------------------------------------------- 1 | # MinHook 2 | 3 | [![License](https://img.shields.io/badge/License-BSD%202--Clause-orange.svg)](https://opensource.org/licenses/BSD-2-Clause) 4 | 5 | The Minimalistic x86/x64 API Hooking Library for Windows 6 | 7 | http://www.codeproject.com/KB/winsdk/LibMinHook.aspx 8 | 9 | ### Version history 10 | 11 | - **v1.3.3 - 8 Jan 2017** 12 | * Added a helper function ```MH_CreateHookApiEx```. (Thanks to asm256) 13 | * Support Visual Studio 2017 RC. 14 | 15 | - **v1.3.2.1 - 9 Nov 2015** (Nuget package only) 16 | * Fixed an insufficient support for Visual Studio 2015. 17 | 18 | - **v1.3.2 - 1 Nov 2015** 19 | * Support Visual Studio 2015. 20 | * Support MinGW. 21 | 22 | - **v1.3.2-beta3 - 21 Jul 2015** (Nuget package only) 23 | * Support MinGW. (Experimental) 24 | 25 | - **v1.3.2-beta2 - 18 May 2015** 26 | * Fixed some subtle bugs. (Thanks to RaMMicHaeL) 27 | * Added a helper function ```MH_StatusToString```. (Thanks to Jan Klass) 28 | 29 | - **v1.3.2-beta - 12 May 2015** 30 | * Fixed a possible thread deadlock in x64 mode. (Thanks to Aleh Kazakevich) 31 | * Reduced the footprint a little more. 32 | * Support Visual Studio 2015 RC. (Experimental) 33 | 34 | - **v1.3.1.1 - 7 Apr 2015** (Nuget package only) 35 | * Support for WDK8.0 and 8.1. 36 | 37 | - **v1.3.1 - 19 Mar 2015** 38 | * No major changes from v1.3.1-beta. 39 | 40 | - **v1.3.1-beta - 11 Mar 2015** 41 | * Added a helper function ```MH_CreateHookApi```. (Thanks to uniskz). 42 | * Fixed a false memory leak reported by some tools. 43 | * Fixed a degradated compatibility issue. 44 | 45 | - **v1.3 - 13 Sep 2014** 46 | * No major changes from v1.3-beta3. 47 | 48 | - **v1.3-beta3 - 31 Jul 2014** 49 | * Fixed some small bugs. 50 | * Improved the memory management. 51 | 52 | - **v1.3-beta2 - 21 Jul 2014** 53 | * Changed the parameters to Windows-friendly types. (void* to LPVOID) 54 | * Fixed some small bugs. 55 | * Reorganized the source files. 56 | * Reduced the footprint a little more. 57 | 58 | - **v1.3-beta - 17 Jul 2014** 59 | * Rewrote in plain C to reduce the footprint and memory usage. (suggested by Andrey Unis) 60 | * Simplified the overall code base to make it more readable and maintainable. 61 | * Changed the license from 3-clause to 2-clause BSD License. 62 | 63 | - **v1.2 - 28 Sep 2013** 64 | * Removed boost dependency ([jarredholman](https://github.com/jarredholman/minhook)). 65 | * Fixed a small bug in the GetRelativeBranchDestination function ([pillbug99](http://www.codeproject.com/Messages/4058892/Small-Bug-Found.aspx)). 66 | * Added the ```MH_RemoveHook``` function, which removes a hook created with the ```MH_CreateHook``` function. 67 | * Added the following functions to enable or disable multiple hooks in one go: ```MH_QueueEnableHook```, ```MH_QueueDisableHook```, ```MH_ApplyQueued```. This is the preferred way of handling multiple hooks as every call to `MH_EnableHook` or `MH_DisableHook` suspends and resumes all threads. 68 | * Made the functions ```MH_EnableHook``` and ```MH_DisableHook``` enable/disable all created hooks when the ```MH_ALL_HOOKS``` parameter is passed. This, too, is an efficient way of handling multiple hooks. 69 | * If the target function is too small to be patched with a jump, MinHook tries to place the jump above the function. If that fails as well, the ```MH_CreateHook``` function returns ```MH_ERROR_UNSUPPORTED_FUNCTION```. This fixes an issue of hooking the LoadLibraryExW function on Windows 7 x64 ([reported by Obble](http://www.codeproject.com/Messages/4578613/Re-Bug-LoadLibraryExW-hook-fails-on-windows-2008-r.aspx)). 70 | 71 | - **v1.1 - 26 Nov 2009** 72 | * Changed the interface to create a hook and a trampoline function in one go to prevent the detour function from being called before the trampoline function is created. ([reported by xliqz](http://www.codeproject.com/Messages/3280374/Unsafe.aspx)) 73 | * Shortened the function names from ```MinHook_*``` to ```MH_*``` to make them handier. 74 | 75 | - **v1.0 - 22 Nov 2009** 76 | * Initial release. 77 | 78 | ### Building MinHook - Using vcpkg 79 | 80 | You can download and install MinHook using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager: 81 | 82 | git clone https://github.com/microsoft/vcpkg 83 | .\vcpkg\bootstrap-vcpkg.bat 84 | .\vcpkg\vcpkg integrate install 85 | .\vcpkg\vcpkg install minhook 86 | 87 | The MinHook port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. 88 | -------------------------------------------------------------------------------- /minhook/include/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 | // pszProcName [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 | // pszProcName [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 | -------------------------------------------------------------------------------- /minhook/src/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(MEMORY_SLOT)); 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 | -------------------------------------------------------------------------------- /minhook/src/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 | -------------------------------------------------------------------------------- /minhook/src/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 11 | #include "hde32.h" 12 | #include "table32.h" 13 | 14 | unsigned int hde32_disasm(const void *code, hde32s *hs) 15 | { 16 | uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; 17 | uint8_t *ht = hde32_table, m_mod, m_reg, m_rm, disp_size = 0; 18 | 19 | memset(hs, 0, sizeof(hde32s)); 20 | 21 | for (x = 16; x; x--) 22 | switch (c = *p++) { 23 | case 0xf3: 24 | hs->p_rep = c; 25 | pref |= PRE_F3; 26 | break; 27 | case 0xf2: 28 | hs->p_rep = c; 29 | pref |= PRE_F2; 30 | break; 31 | case 0xf0: 32 | hs->p_lock = c; 33 | pref |= PRE_LOCK; 34 | break; 35 | case 0x26: case 0x2e: case 0x36: 36 | case 0x3e: case 0x64: case 0x65: 37 | hs->p_seg = c; 38 | pref |= PRE_SEG; 39 | break; 40 | case 0x66: 41 | hs->p_66 = c; 42 | pref |= PRE_66; 43 | break; 44 | case 0x67: 45 | hs->p_67 = c; 46 | pref |= PRE_67; 47 | break; 48 | default: 49 | goto pref_done; 50 | } 51 | pref_done: 52 | 53 | hs->flags = (uint32_t)pref << 23; 54 | 55 | if (!pref) 56 | pref |= PRE_NONE; 57 | 58 | if ((hs->opcode = c) == 0x0f) { 59 | hs->opcode2 = c = *p++; 60 | ht += DELTA_OPCODES; 61 | } else if (c >= 0xa0 && c <= 0xa3) { 62 | if (pref & PRE_67) 63 | pref |= PRE_66; 64 | else 65 | pref &= ~PRE_66; 66 | } 67 | 68 | opcode = c; 69 | cflags = ht[ht[opcode / 4] + (opcode % 4)]; 70 | 71 | if (cflags == C_ERROR) { 72 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 73 | cflags = 0; 74 | if ((opcode & -3) == 0x24) 75 | cflags++; 76 | } 77 | 78 | x = 0; 79 | if (cflags & C_GROUP) { 80 | uint16_t t; 81 | t = *(uint16_t *)(ht + (cflags & 0x7f)); 82 | cflags = (uint8_t)t; 83 | x = (uint8_t)(t >> 8); 84 | } 85 | 86 | if (hs->opcode2) { 87 | ht = hde32_table + DELTA_PREFIXES; 88 | if (ht[ht[opcode / 4] + (opcode % 4)] & pref) 89 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 90 | } 91 | 92 | if (cflags & C_MODRM) { 93 | hs->flags |= F_MODRM; 94 | hs->modrm = c = *p++; 95 | hs->modrm_mod = m_mod = c >> 6; 96 | hs->modrm_rm = m_rm = c & 7; 97 | hs->modrm_reg = m_reg = (c & 0x3f) >> 3; 98 | 99 | if (x && ((x << m_reg) & 0x80)) 100 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 101 | 102 | if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { 103 | uint8_t t = opcode - 0xd9; 104 | if (m_mod == 3) { 105 | ht = hde32_table + DELTA_FPU_MODRM + t*8; 106 | t = ht[m_reg] << m_rm; 107 | } else { 108 | ht = hde32_table + DELTA_FPU_REG; 109 | t = ht[t] << m_reg; 110 | } 111 | if (t & 0x80) 112 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 113 | } 114 | 115 | if (pref & PRE_LOCK) { 116 | if (m_mod == 3) { 117 | hs->flags |= F_ERROR | F_ERROR_LOCK; 118 | } else { 119 | uint8_t *table_end, op = opcode; 120 | if (hs->opcode2) { 121 | ht = hde32_table + DELTA_OP2_LOCK_OK; 122 | table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; 123 | } else { 124 | ht = hde32_table + DELTA_OP_LOCK_OK; 125 | table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; 126 | op &= -2; 127 | } 128 | for (; ht != table_end; ht++) 129 | if (*ht++ == op) { 130 | if (!((*ht << m_reg) & 0x80)) 131 | goto no_lock_error; 132 | else 133 | break; 134 | } 135 | hs->flags |= F_ERROR | F_ERROR_LOCK; 136 | no_lock_error: 137 | ; 138 | } 139 | } 140 | 141 | if (hs->opcode2) { 142 | switch (opcode) { 143 | case 0x20: case 0x22: 144 | m_mod = 3; 145 | if (m_reg > 4 || m_reg == 1) 146 | goto error_operand; 147 | else 148 | goto no_error_operand; 149 | case 0x21: case 0x23: 150 | m_mod = 3; 151 | if (m_reg == 4 || m_reg == 5) 152 | goto error_operand; 153 | else 154 | goto no_error_operand; 155 | } 156 | } else { 157 | switch (opcode) { 158 | case 0x8c: 159 | if (m_reg > 5) 160 | goto error_operand; 161 | else 162 | goto no_error_operand; 163 | case 0x8e: 164 | if (m_reg == 1 || m_reg > 5) 165 | goto error_operand; 166 | else 167 | goto no_error_operand; 168 | } 169 | } 170 | 171 | if (m_mod == 3) { 172 | uint8_t *table_end; 173 | if (hs->opcode2) { 174 | ht = hde32_table + DELTA_OP2_ONLY_MEM; 175 | table_end = ht + sizeof(hde32_table) - DELTA_OP2_ONLY_MEM; 176 | } else { 177 | ht = hde32_table + DELTA_OP_ONLY_MEM; 178 | table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; 179 | } 180 | for (; ht != table_end; ht += 2) 181 | if (*ht++ == opcode) { 182 | if ((*ht++ & pref) && !((*ht << m_reg) & 0x80)) 183 | goto error_operand; 184 | else 185 | break; 186 | } 187 | goto no_error_operand; 188 | } else if (hs->opcode2) { 189 | switch (opcode) { 190 | case 0x50: case 0xd7: case 0xf7: 191 | if (pref & (PRE_NONE | PRE_66)) 192 | goto error_operand; 193 | break; 194 | case 0xd6: 195 | if (pref & (PRE_F2 | PRE_F3)) 196 | goto error_operand; 197 | break; 198 | case 0xc5: 199 | goto error_operand; 200 | } 201 | goto no_error_operand; 202 | } else 203 | goto no_error_operand; 204 | 205 | error_operand: 206 | hs->flags |= F_ERROR | F_ERROR_OPERAND; 207 | no_error_operand: 208 | 209 | c = *p++; 210 | if (m_reg <= 1) { 211 | if (opcode == 0xf6) 212 | cflags |= C_IMM8; 213 | else if (opcode == 0xf7) 214 | cflags |= C_IMM_P66; 215 | } 216 | 217 | switch (m_mod) { 218 | case 0: 219 | if (pref & PRE_67) { 220 | if (m_rm == 6) 221 | disp_size = 2; 222 | } else 223 | if (m_rm == 5) 224 | disp_size = 4; 225 | break; 226 | case 1: 227 | disp_size = 1; 228 | break; 229 | case 2: 230 | disp_size = 2; 231 | if (!(pref & PRE_67)) 232 | disp_size <<= 1; 233 | break; 234 | } 235 | 236 | if (m_mod != 3 && m_rm == 4 && !(pref & PRE_67)) { 237 | hs->flags |= F_SIB; 238 | p++; 239 | hs->sib = c; 240 | hs->sib_scale = c >> 6; 241 | hs->sib_index = (c & 0x3f) >> 3; 242 | if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) 243 | disp_size = 4; 244 | } 245 | 246 | p--; 247 | switch (disp_size) { 248 | case 1: 249 | hs->flags |= F_DISP8; 250 | hs->disp.disp8 = *p; 251 | break; 252 | case 2: 253 | hs->flags |= F_DISP16; 254 | hs->disp.disp16 = *(uint16_t *)p; 255 | break; 256 | case 4: 257 | hs->flags |= F_DISP32; 258 | hs->disp.disp32 = *(uint32_t *)p; 259 | break; 260 | } 261 | p += disp_size; 262 | } else if (pref & PRE_LOCK) 263 | hs->flags |= F_ERROR | F_ERROR_LOCK; 264 | 265 | if (cflags & C_IMM_P66) { 266 | if (cflags & C_REL32) { 267 | if (pref & PRE_66) { 268 | hs->flags |= F_IMM16 | F_RELATIVE; 269 | hs->imm.imm16 = *(uint16_t *)p; 270 | p += 2; 271 | goto disasm_done; 272 | } 273 | goto rel32_ok; 274 | } 275 | if (pref & PRE_66) { 276 | hs->flags |= F_IMM16; 277 | hs->imm.imm16 = *(uint16_t *)p; 278 | p += 2; 279 | } else { 280 | hs->flags |= F_IMM32; 281 | hs->imm.imm32 = *(uint32_t *)p; 282 | p += 4; 283 | } 284 | } 285 | 286 | if (cflags & C_IMM16) { 287 | if (hs->flags & F_IMM32) { 288 | hs->flags |= F_IMM16; 289 | hs->disp.disp16 = *(uint16_t *)p; 290 | } else if (hs->flags & F_IMM16) { 291 | hs->flags |= F_2IMM16; 292 | hs->disp.disp16 = *(uint16_t *)p; 293 | } else { 294 | hs->flags |= F_IMM16; 295 | hs->imm.imm16 = *(uint16_t *)p; 296 | } 297 | p += 2; 298 | } 299 | if (cflags & C_IMM8) { 300 | hs->flags |= F_IMM8; 301 | hs->imm.imm8 = *p++; 302 | } 303 | 304 | if (cflags & C_REL32) { 305 | rel32_ok: 306 | hs->flags |= F_IMM32 | F_RELATIVE; 307 | hs->imm.imm32 = *(uint32_t *)p; 308 | p += 4; 309 | } else if (cflags & C_REL8) { 310 | hs->flags |= F_IMM8 | F_RELATIVE; 311 | hs->imm.imm8 = *p++; 312 | } 313 | 314 | disasm_done: 315 | 316 | if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) { 317 | hs->flags |= F_ERROR | F_ERROR_LENGTH; 318 | hs->len = 15; 319 | } 320 | 321 | return (unsigned int)hs->len; 322 | } 323 | 324 | #endif // defined(_M_IX86) || defined(__i386__) 325 | -------------------------------------------------------------------------------- /minhook/src/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 | -------------------------------------------------------------------------------- /minhook/src/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 11 | #include "hde64.h" 12 | #include "table64.h" 13 | 14 | unsigned int hde64_disasm(const void *code, hde64s *hs) 15 | { 16 | uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; 17 | uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0; 18 | uint8_t op64 = 0; 19 | 20 | memset(hs, 0, sizeof(hde64s)); 21 | 22 | for (x = 16; x; x--) 23 | switch (c = *p++) { 24 | case 0xf3: 25 | hs->p_rep = c; 26 | pref |= PRE_F3; 27 | break; 28 | case 0xf2: 29 | hs->p_rep = c; 30 | pref |= PRE_F2; 31 | break; 32 | case 0xf0: 33 | hs->p_lock = c; 34 | pref |= PRE_LOCK; 35 | break; 36 | case 0x26: case 0x2e: case 0x36: 37 | case 0x3e: case 0x64: case 0x65: 38 | hs->p_seg = c; 39 | pref |= PRE_SEG; 40 | break; 41 | case 0x66: 42 | hs->p_66 = c; 43 | pref |= PRE_66; 44 | break; 45 | case 0x67: 46 | hs->p_67 = c; 47 | pref |= PRE_67; 48 | break; 49 | default: 50 | goto pref_done; 51 | } 52 | pref_done: 53 | 54 | hs->flags = (uint32_t)pref << 23; 55 | 56 | if (!pref) 57 | pref |= PRE_NONE; 58 | 59 | if ((c & 0xf0) == 0x40) { 60 | hs->flags |= F_PREFIX_REX; 61 | if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8) 62 | op64++; 63 | hs->rex_r = (c & 7) >> 2; 64 | hs->rex_x = (c & 3) >> 1; 65 | hs->rex_b = c & 1; 66 | if (((c = *p++) & 0xf0) == 0x40) { 67 | opcode = c; 68 | goto error_opcode; 69 | } 70 | } 71 | 72 | if ((hs->opcode = c) == 0x0f) { 73 | hs->opcode2 = c = *p++; 74 | ht += DELTA_OPCODES; 75 | } else if (c >= 0xa0 && c <= 0xa3) { 76 | op64++; 77 | if (pref & PRE_67) 78 | pref |= PRE_66; 79 | else 80 | pref &= ~PRE_66; 81 | } 82 | 83 | opcode = c; 84 | cflags = ht[ht[opcode / 4] + (opcode % 4)]; 85 | 86 | if (cflags == C_ERROR) { 87 | error_opcode: 88 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 89 | cflags = 0; 90 | if ((opcode & -3) == 0x24) 91 | cflags++; 92 | } 93 | 94 | x = 0; 95 | if (cflags & C_GROUP) { 96 | uint16_t t; 97 | t = *(uint16_t *)(ht + (cflags & 0x7f)); 98 | cflags = (uint8_t)t; 99 | x = (uint8_t)(t >> 8); 100 | } 101 | 102 | if (hs->opcode2) { 103 | ht = hde64_table + DELTA_PREFIXES; 104 | if (ht[ht[opcode / 4] + (opcode % 4)] & pref) 105 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 106 | } 107 | 108 | if (cflags & C_MODRM) { 109 | hs->flags |= F_MODRM; 110 | hs->modrm = c = *p++; 111 | hs->modrm_mod = m_mod = c >> 6; 112 | hs->modrm_rm = m_rm = c & 7; 113 | hs->modrm_reg = m_reg = (c & 0x3f) >> 3; 114 | 115 | if (x && ((x << m_reg) & 0x80)) 116 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 117 | 118 | if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { 119 | uint8_t t = opcode - 0xd9; 120 | if (m_mod == 3) { 121 | ht = hde64_table + DELTA_FPU_MODRM + t*8; 122 | t = ht[m_reg] << m_rm; 123 | } else { 124 | ht = hde64_table + DELTA_FPU_REG; 125 | t = ht[t] << m_reg; 126 | } 127 | if (t & 0x80) 128 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 129 | } 130 | 131 | if (pref & PRE_LOCK) { 132 | if (m_mod == 3) { 133 | hs->flags |= F_ERROR | F_ERROR_LOCK; 134 | } else { 135 | uint8_t *table_end, op = opcode; 136 | if (hs->opcode2) { 137 | ht = hde64_table + DELTA_OP2_LOCK_OK; 138 | table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; 139 | } else { 140 | ht = hde64_table + DELTA_OP_LOCK_OK; 141 | table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; 142 | op &= -2; 143 | } 144 | for (; ht != table_end; ht++) 145 | if (*ht++ == op) { 146 | if (!((*ht << m_reg) & 0x80)) 147 | goto no_lock_error; 148 | else 149 | break; 150 | } 151 | hs->flags |= F_ERROR | F_ERROR_LOCK; 152 | no_lock_error: 153 | ; 154 | } 155 | } 156 | 157 | if (hs->opcode2) { 158 | switch (opcode) { 159 | case 0x20: case 0x22: 160 | m_mod = 3; 161 | if (m_reg > 4 || m_reg == 1) 162 | goto error_operand; 163 | else 164 | goto no_error_operand; 165 | case 0x21: case 0x23: 166 | m_mod = 3; 167 | if (m_reg == 4 || m_reg == 5) 168 | goto error_operand; 169 | else 170 | goto no_error_operand; 171 | } 172 | } else { 173 | switch (opcode) { 174 | case 0x8c: 175 | if (m_reg > 5) 176 | goto error_operand; 177 | else 178 | goto no_error_operand; 179 | case 0x8e: 180 | if (m_reg == 1 || m_reg > 5) 181 | goto error_operand; 182 | else 183 | goto no_error_operand; 184 | } 185 | } 186 | 187 | if (m_mod == 3) { 188 | uint8_t *table_end; 189 | if (hs->opcode2) { 190 | ht = hde64_table + DELTA_OP2_ONLY_MEM; 191 | table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM; 192 | } else { 193 | ht = hde64_table + DELTA_OP_ONLY_MEM; 194 | table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; 195 | } 196 | for (; ht != table_end; ht += 2) 197 | if (*ht++ == opcode) { 198 | if (*ht++ & pref && !((*ht << m_reg) & 0x80)) 199 | goto error_operand; 200 | else 201 | break; 202 | } 203 | goto no_error_operand; 204 | } else if (hs->opcode2) { 205 | switch (opcode) { 206 | case 0x50: case 0xd7: case 0xf7: 207 | if (pref & (PRE_NONE | PRE_66)) 208 | goto error_operand; 209 | break; 210 | case 0xd6: 211 | if (pref & (PRE_F2 | PRE_F3)) 212 | goto error_operand; 213 | break; 214 | case 0xc5: 215 | goto error_operand; 216 | } 217 | goto no_error_operand; 218 | } else 219 | goto no_error_operand; 220 | 221 | error_operand: 222 | hs->flags |= F_ERROR | F_ERROR_OPERAND; 223 | no_error_operand: 224 | 225 | c = *p++; 226 | if (m_reg <= 1) { 227 | if (opcode == 0xf6) 228 | cflags |= C_IMM8; 229 | else if (opcode == 0xf7) 230 | cflags |= C_IMM_P66; 231 | } 232 | 233 | switch (m_mod) { 234 | case 0: 235 | if (pref & PRE_67) { 236 | if (m_rm == 6) 237 | disp_size = 2; 238 | } else 239 | if (m_rm == 5) 240 | disp_size = 4; 241 | break; 242 | case 1: 243 | disp_size = 1; 244 | break; 245 | case 2: 246 | disp_size = 2; 247 | if (!(pref & PRE_67)) 248 | disp_size <<= 1; 249 | } 250 | 251 | if (m_mod != 3 && m_rm == 4) { 252 | hs->flags |= F_SIB; 253 | p++; 254 | hs->sib = c; 255 | hs->sib_scale = c >> 6; 256 | hs->sib_index = (c & 0x3f) >> 3; 257 | if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) 258 | disp_size = 4; 259 | } 260 | 261 | p--; 262 | switch (disp_size) { 263 | case 1: 264 | hs->flags |= F_DISP8; 265 | hs->disp.disp8 = *p; 266 | break; 267 | case 2: 268 | hs->flags |= F_DISP16; 269 | hs->disp.disp16 = *(uint16_t *)p; 270 | break; 271 | case 4: 272 | hs->flags |= F_DISP32; 273 | hs->disp.disp32 = *(uint32_t *)p; 274 | } 275 | p += disp_size; 276 | } else if (pref & PRE_LOCK) 277 | hs->flags |= F_ERROR | F_ERROR_LOCK; 278 | 279 | if (cflags & C_IMM_P66) { 280 | if (cflags & C_REL32) { 281 | if (pref & PRE_66) { 282 | hs->flags |= F_IMM16 | F_RELATIVE; 283 | hs->imm.imm16 = *(uint16_t *)p; 284 | p += 2; 285 | goto disasm_done; 286 | } 287 | goto rel32_ok; 288 | } 289 | if (op64) { 290 | hs->flags |= F_IMM64; 291 | hs->imm.imm64 = *(uint64_t *)p; 292 | p += 8; 293 | } else if (!(pref & PRE_66)) { 294 | hs->flags |= F_IMM32; 295 | hs->imm.imm32 = *(uint32_t *)p; 296 | p += 4; 297 | } else 298 | goto imm16_ok; 299 | } 300 | 301 | 302 | if (cflags & C_IMM16) { 303 | imm16_ok: 304 | hs->flags |= F_IMM16; 305 | hs->imm.imm16 = *(uint16_t *)p; 306 | p += 2; 307 | } 308 | if (cflags & C_IMM8) { 309 | hs->flags |= F_IMM8; 310 | hs->imm.imm8 = *p++; 311 | } 312 | 313 | if (cflags & C_REL32) { 314 | rel32_ok: 315 | hs->flags |= F_IMM32 | F_RELATIVE; 316 | hs->imm.imm32 = *(uint32_t *)p; 317 | p += 4; 318 | } else if (cflags & C_REL8) { 319 | hs->flags |= F_IMM8 | F_RELATIVE; 320 | hs->imm.imm8 = *p++; 321 | } 322 | 323 | disasm_done: 324 | 325 | if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) { 326 | hs->flags |= F_ERROR | F_ERROR_LENGTH; 327 | hs->len = 15; 328 | } 329 | 330 | return (unsigned int)hs->len; 331 | } 332 | 333 | #endif // defined(_M_X64) || defined(__x86_64__) 334 | -------------------------------------------------------------------------------- /minhook/src/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 | -------------------------------------------------------------------------------- /minhook/src/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 | -------------------------------------------------------------------------------- /minhook/src/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 | -------------------------------------------------------------------------------- /minhook/src/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 | -------------------------------------------------------------------------------- /minhook/src/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 | -------------------------------------------------------------------------------- /project.4coder: -------------------------------------------------------------------------------- 1 | project_name = "TeamSCALEFORM"; 2 | 3 | patterns = { 4 | "*.c", 5 | "*.h", 6 | "*.cc", 7 | "*.hh", 8 | "*.cpp", 9 | "*.hpp", 10 | "*.cxx", 11 | "*.hxx", 12 | "*.txt", 13 | "*.md", 14 | "*.js", 15 | "*.cmake" 16 | }; 17 | 18 | load_paths = { 19 | { 20 | { {"."}, .recursive = true, .relative = true }, 21 | .os = "win" 22 | }, 23 | }; 24 | 25 | command_list = { 26 | { 27 | .name = "build_debug", 28 | .out = "*compilation*", 29 | .footer_panel = true, 30 | .cursor_at_end = true, 31 | .save_dirty_files = true, 32 | .cmd = { 33 | { "build_debug.bat", .os = "win" }, 34 | }, 35 | }, 36 | { 37 | .name = "build_release", 38 | .out = "*compilation*", 39 | .footer_panel = true, 40 | .cursor_at_end = true, 41 | .save_dirty_files = true, 42 | .cmd = { 43 | { "build_release.bat", .os = "win" }, 44 | }, 45 | }, 46 | { 47 | .name = "kill_compilation", 48 | .footer_panel = false, 49 | .cmd = { 50 | { "taskkill /F /IM ninja.exe", .os = "win" }, 51 | }, 52 | } 53 | }; 54 | 55 | fkey_command[1] = "build_debug"; 56 | fkey_command[3] = "build_release"; 57 | fkey_command[4] = "kill_compilation"; -------------------------------------------------------------------------------- /scaleform/alerts.js: -------------------------------------------------------------------------------- 1 | R"alert( 2 | var contextPanel = $.GetContextPanel(); 3 | var joinPanelCTBG = "https://cdn.discordapp.com/attachments/808866622701830186/977922886042026015/Group_69.png"; 4 | var joinPanelTBG = "https://cdn.discordapp.com/attachments/808866622701830186/977919617194418195/Group_66.png"; 5 | var joinPanelBotBG = "https://images2.imgbox.com/3c/af/3j6BFAy9_o.png"; 6 | 7 | for(var hudHint of contextPanel.FindChildrenWithClassTraverse('hud-hint')) 8 | { 9 | hudHint.style.backgroundImage = "url('https://images2.imgbox.com/f1/60/1bTBT9qY_o.png')"; 10 | hudHint.style.backgroundColor = '#00000000'; 11 | hudHint.style.width = '450px'; 12 | hudHint.style.height = '109px'; 13 | hudHint.style.backgroundSize = '100% 100%'; 14 | hudHint.style.overflow = 'noclip'; 15 | hudHint.style.backgroundRepeat = 'no-repeat'; 16 | hudHint.style.transform = 'translateY(-100px)'; 17 | 18 | } 19 | 20 | for(var hudHintIcon of contextPanel.FindChildrenWithClassTraverse('hud-hint_icon')) 21 | { 22 | hudHintIcon.style.visibility = 'collapse'; // removal 23 | } 24 | for(var hint of contextPanel.FindChildrenWithClassTraverse('hud-hint__icon')) 25 | { 26 | hint.style.visibility = 'collapse'; // removal 27 | } 28 | 29 | 30 | for(var hudHintText of contextPanel.FindChildrenWithClassTraverse('hud-hint__text')) 31 | { 32 | hudHintText.style.width = '75%'; 33 | hudHintText.style.horizontalAlign = 'right'; 34 | hudHintText.style.textAlign = 'left'; 35 | hudHintText.style.height = '100%'; 36 | hudHintText.style.verticalAlign = 'top'; 37 | hudHintText.style.textOverflow = 'noclip'; 38 | 39 | } 40 | for(var hudHintPriorityLabel of contextPanel.FindChildrenWithClassTraverse('hud-hint__priority-label')) 41 | { 42 | hudHintPriorityLabel.style.horizontalAlign = 'left'; 43 | hudHintPriorityLabel.style.x = '0px'; 44 | hudHintPriorityLabel.style.width = '250px'; 45 | hudHintPriorityLabel.style.overflow = 'noclip'; 46 | hudHintPriorityLabel.style.fontSize = '20px'; 47 | hudHintPriorityLabel.style.fontFamily = 'Stratum2'; 48 | hudHintPriorityLabel.style.color = '#EA7861'; 49 | hudHintPriorityLabel.style.opacity = '0.9'; 50 | hudHintPriorityLabel.style.textAlign = 'left'; 51 | hudHintPriorityLabel.style.textOverflow = 'noclip'; 52 | hudHintPriorityLabel.style.letterSpacing = '0px'; 53 | hudHintPriorityLabel.style.marginTop = '5px'; 54 | 55 | } 56 | for(var hudHintLabel of contextPanel.FindChildrenWithClassTraverse('hud-hint__label')) 57 | { 58 | hudHintLabel.style.horizontalAlign = 'left'; 59 | hudHintLabel.style.height = '90px'; 60 | hudHintLabel.style.verticalAlign = 'top'; 61 | hudHintLabel.style.textOverflow = 'noclip'; 62 | hudHintLabel.style.fontSize = '16px'; 63 | hudHintLabel.style.opacity = '0.9' 64 | } 65 | 66 | var hudTeamCounter = contextPanel.FindChildTraverse('HudTeamCounter'); 67 | for (var hrTop of hudTeamCounter.FindChildrenWithClassTraverse('hrTop')) { 68 | hrTop.style.visibility = 'collapse'; // removal 69 | } 70 | 71 | 72 | var joinPanelCT = hudTeamCounter.FindChildTraverse('JoinPanelCT'); 73 | joinPanelCT.style.width = '630px'; 74 | joinPanelCT.style.height = '56px'; 75 | joinPanelCT.style.horizontalAlign = 'center'; 76 | joinPanelCT.style.flowChildren = 'none'; 77 | joinPanelCT.style.backgroundImage = `url(${joinPanelCTBG})`; 78 | joinPanelCT.style.backgroundSize = '100% 100%'; 79 | 80 | var joinPanelT = hudTeamCounter.FindChildTraverse('JoinPanelT'); 81 | joinPanelT.style.width = '630px'; 82 | joinPanelT.style.height = '56px'; 83 | joinPanelT.style.horizontalAlign = 'center'; 84 | joinPanelT.style.flowChildren = 'none'; 85 | joinPanelT.style.backgroundImage = `url(${joinPanelTBG})`; 86 | joinPanelT.style.backgroundSize = '100% 100%'; 87 | 88 | var joinPanelBot = hudTeamCounter.FindChildTraverse('JoinPanelBot'); 89 | joinPanelBot.style.width = '630px'; 90 | joinPanelBot.style.height = '56px'; 91 | joinPanelBot.style.horizontalAlign = 'center'; 92 | joinPanelBot.style.flowChildren = 'none'; 93 | joinPanelBot.style.backgroundImage = `url(${joinPanelBotBG})`; 94 | joinPanelBot.style.backgroundSize = '100% 100%'; 95 | 96 | var entryTextCt = hudTeamCounter.FindChildTraverse('JoinTextCT'); 97 | entryTextCt.style.fontSize = '26px'; 98 | entryTextCt.style.fontWeight = 'black'; 99 | entryTextCt.style.horizontalAlign = 'center'; 100 | entryTextCt.style.verticalAlign = 'top'; 101 | entryTextCt.style.letterSpacing = '0px'; 102 | entryTextCt.style.marginTop = '12px'; 103 | entryTextCt.style.opacity = '0.85'; 104 | entryTextCt.style.backgroundColor = 'none'; 105 | entryTextCt.style.backgroundImage = 'none'; 106 | entryTextCt.style.backgroundSize = '100% 100%'; 107 | entryTextCt.style.overflow = 'noclip'; 108 | entryTextCt.style.backgroundRepeat = 'no-repeat'; 109 | entryTextCt.style.backgroundPosition = '40px -5px'; 110 | entryTextCt.style.marginLeft = '0%'; 111 | 112 | var entryTextT = hudTeamCounter.FindChildTraverse('JoinTextT'); 113 | entryTextT.style.fontSize = '26px'; 114 | entryTextT.style.fontWeight = 'black'; 115 | entryTextT.style.horizontalAlign = 'center'; 116 | entryTextT.style.verticalAlign = 'top'; 117 | entryTextT.style.letterSpacing = '0px'; 118 | entryTextT.style.marginTop = '12px'; 119 | entryTextT.style.opacity = '0.85'; 120 | entryTextT.style.backgroundColor = 'none'; 121 | entryTextT.style.backgroundImage = 'none'; 122 | entryTextT.style.backgroundSize = '100% 100%'; 123 | entryTextT.style.overflow = 'noclip'; 124 | entryTextT.style.backgroundRepeat = 'no-repeat'; 125 | entryTextT.style.backgroundPosition = '40px -5px'; 126 | var entryTextBot = hudTeamCounter.FindChildTraverse('JoinTextBot'); 127 | entryTextBot.style.fontSize = '26px'; 128 | entryTextBot.style.fontWeight = 'black'; 129 | entryTextBot.style.horizontalAlign = 'center'; 130 | entryTextBot.style.verticalAlign = 'top'; 131 | entryTextBot.style.letterSpacing = '0px'; 132 | entryTextBot.style.marginTop = '12px'; 133 | entryTextBot.style.opacity = '0.85'; 134 | entryTextBot.style.backgroundColor = 'none'; 135 | entryTextBot.style.backgroundImage = 'none'; 136 | entryTextBot.style.backgroundSize = '100% 100%'; 137 | entryTextBot.style.overflow = 'noclip'; 138 | entryTextBot.style.backgroundRepeat = 'no-repeat'; 139 | entryTextBot.style.backgroundPosition = '40px -5px'; 140 | entryTextBot.style.marginLeft = '0%'; 141 | 142 | // Top alerts (warmup, start etc) 143 | 144 | var hal = contextPanel.FindChildTraverse('HudAlerts'); 145 | hal.style.width = '883px'; 146 | hal.style.height = '44px'; 147 | hal.style.marginTop = '-40px'; 148 | 149 | for (var hrbot of hal.FindChildrenWithClassTraverse('hrBot')) {hrbot.style.visibility = 'collapse';} 150 | for (var hrtop of hal.FindChildrenWithClassTraverse('hrTop')) {hrtop.style.visibility = 'collapse';} 151 | 152 | var hal = contextPanel.FindChildTraverse('HudAlerts'); 153 | hal.style.width = '883px'; 154 | hal.style.height = '44px'; 155 | hal.style.marginTop = '-40px'; 156 | for (var hrbot of hal.FindChildrenWithClassTraverse('hrBot')) {hrbot.style.visibility = 'collapse';} 157 | for (var hrtop of hal.FindChildrenWithClassTraverse('hrTop')) {hrtop.style.visibility = 'collapse';} 158 | 159 | var alertText = contextPanel.FindChildTraverse('AlertText'); 160 | alertText.style.opacity = '1'; 161 | alertText.style.fontSize = '30px'; 162 | alertText.style.fontWeight = 'bold'; 163 | alertText.style.verticalAlign = 'center'; 164 | alertText.style.fontFamily = 'Stratum2'; 165 | alertText.style.letterSpacing = '0px'; 166 | alertText.style.marginTop = '5px'; 167 | 168 | var alertBg = contextPanel.FindChildTraverse('AlertBg'); 169 | alertBg.style.opacity = '1'; 170 | alertBg.style.height = '44px'; 171 | alertBg.style.backgroundImage = 'url("https://images2.imgbox.com/e4/eb/FdasPVKZ_o.png")'; 172 | alertBg.style.backgroundImgOpacity = '0.95'; 173 | alertBg.style.backgroundSize = '100% 100%'; 174 | alertBg.style.backgroundRepeat = 'no-repeat'; 175 | alertBg.style.backgroundColor = '#00000000'; 176 | )alert" -------------------------------------------------------------------------------- /scaleform/alpha.js: -------------------------------------------------------------------------------- 1 | R"( 2 | var contextPanel = $.GetContextPanel(); 3 | var hudRadar = contextPanel.FindChildTraverse('HudRadar'); 4 | 5 | var dashboardLabel = hudRadar.FindChildTraverse('DashboardLabel'); 6 | dashboardLabel.style.backgroundImgOpacity = '${alpha}'; 7 | )" -------------------------------------------------------------------------------- /scaleform/base.js: -------------------------------------------------------------------------------- 1 | R"( 2 | var contextPanel = $.GetContextPanel(); 3 | 4 | var hudBottomRightImg = "https://images2.imgbox.com/ac/02/og3P1Xvp_o.png" 5 | var moneyBgImg = "https://images2.imgbox.com/a9/2f/lt6Pj1Mc_o.png" 6 | var dashboardLabelImg = "https://images2.imgbox.com/62/17/y3tvD95I_o.png" 7 | var hudTeamCountBgT = "https://images2.imgbox.com/0f/d5/fpNsbsSC_o.png"; 8 | var hudTeamCountBgCT = "https://images2.imgbox.com/05/8f/f32nMOYd_o.png"; 9 | 10 | var hudBottomRight = contextPanel.FindChildTraverse('HudWeaponPanel').FindChildTraverse('WeaponPanelBottomBG'); 11 | hudBottomRight.style.backgroundImage = `url(${hudBottomRightImg})`; 12 | hudBottomRight.style.backgroundColor = '#00000000'; 13 | hudBottomRight.style.backgroundSize = 'cover'; 14 | hudBottomRight.style.width = '325px'; 15 | hudBottomRight.style.height = '54px'; 16 | hudBottomRight.style.marginLeft = '37px'; 17 | hudBottomRight.style.marginTop = '0px'; 18 | hudBottomRight.style.overflow = 'squish'; 19 | hudBottomRight.style.backgroundImgOpacity = '0.95'; 20 | 21 | var hudMoney = contextPanel.FindChildTraverse('HudMoney'); 22 | // Background position is 0% by default which doesn't show 23 | // our own buy cart. This is handled in {buyzone.js} 24 | var moneyBg = hudMoney.FindChildTraverse('MoneyBG'); 25 | moneyBg.style.width = '291px'; 26 | moneyBg.style.height = '44px'; 27 | moneyBg.style.horizontalAlign = 'center'; 28 | moneyBg.style.verticalAlign = 'center'; 29 | moneyBg.style.marginLeft = '0px'; 30 | moneyBg.style.backgroundImage = `url(${moneyBgImg})`; 31 | moneyBg.style.backgroundColor = '#00000000'; 32 | moneyBg.style.backgroundSize = '200% 100%'; 33 | moneyBg.style.backgroundRepeat = 'no-repeat'; 34 | moneyBg.style.backgroundImgOpacity = '0.95'; 35 | 36 | for (var moneyText of hudMoney.FindChildrenWithClassTraverse('money-text')) { 37 | moneyText.style.horizontalAlign = 'left'; 38 | moneyText.style.flowChildren = 'right'; 39 | moneyText.style.verticalAlign = 'middle'; 40 | moneyText.style.marginLeft = '0px'; 41 | } 42 | 43 | for (var moneyLabel of hudMoney.FindChildrenWithClassTraverse('money-text-label')) { 44 | moneyLabel.style.marginTop = '3px'; 45 | moneyLabel.style.marginLeft = '65px'; 46 | moneyLabel.style.transform = 'translateX(0px)'; 47 | } 48 | 49 | // Fully remove this, as due to layouting rules we have to replace this with 50 | // a dynamically UV-mapped image 51 | for (var buyIcon of hudMoney.FindChildrenWithClassTraverse('money-text-buy-icon')) { 52 | buyIcon.style.visibility = 'collapse'; 53 | } 54 | 55 | // Reposition and change the color of animations 56 | var moneyAdd = hudMoney.FindChildTraverse('Money-Add'); 57 | moneyAdd.style.color = '#7CC213'; 58 | moneyAdd.style.marginLeft = '25px'; 59 | var moneyAddFlash = hudMoney.FindChildTraverse('Money-AddFlash'); 60 | moneyAddFlash.style.color = '#D3E798'; 61 | var moneyRemove = hudMoney.FindChildTraverse('Money-Remove'); 62 | moneyRemove.style.marginLeft = '30px'; 63 | moneyRemove.style.color = '#FD2424'; 64 | 65 | // Radar 66 | var hudRadar = contextPanel.FindChildTraverse('HudRadar'); 67 | 68 | // Alpha is handled in {alpha.js} 69 | var dashboardLabel = contextPanel.FindChildTraverse('DashboardLabel'); 70 | dashboardLabel.style.horizontalAlign = 'center'; 71 | dashboardLabel.style.verticalAlign = 'center'; 72 | dashboardLabel.style.marginLeft = '0px'; 73 | dashboardLabel.style.marginTop = '-14px'; 74 | dashboardLabel.style.paddingTop = '10px'; 75 | dashboardLabel.style.width = '280px'; 76 | dashboardLabel.style.height = '51px'; 77 | dashboardLabel.style.paddingLeft = '12px'; 78 | dashboardLabel.style.backgroundImage = `url(${dashboardLabelImg})`; 79 | dashboardLabel.style.backgroundColor = '#00000000'; 80 | dashboardLabel.style.backgroundSize = '100% 100%'; 81 | dashboardLabel.style.fontFamily = 'Stratum2'; 82 | dashboardLabel.style.fontWeight = 'bold'; 83 | dashboardLabel.style.fontSize = '26px'; 84 | dashboardLabel.style.letterSpacing = '-0.3px'; 85 | 86 | // Teamcount (only score style) 87 | var hudTeamCounter = contextPanel.FindChildTraverse('HudTeamCounter'); 88 | hudTeamCounter.style.height = '100%'; 89 | var aliveTextT = hudTeamCounter.FindChildTraverse('AliveTextT'); 90 | var aliveTextCT = hudTeamCounter.FindChildTraverse('AliveTextCT'); 91 | aliveTextT.style.fontSize = '13px'; 92 | aliveTextT.style.fontWeight ='normal'; 93 | aliveTextCT.style.fontWeight = 'normal'; 94 | aliveTextCT.style.fontSize = '13px'; 95 | aliveTextCT.style.letterSpacing = '0px'; 96 | aliveTextT.style.letterSpacing = '0px'; 97 | aliveTextCT.style.marginBottom = '-2px'; 98 | aliveTextT.style.marginBottom = '-2px'; 99 | aliveTextT.style.textShadow = '2px 1px 1px 0.0 #000000'; 100 | aliveTextCT.style.textShadow = '2px 1px 1px 0.0 #000000'; 101 | aliveTextT.style.fontFamily = 'Stratum2'; 102 | aliveTextCT.style.fontFamily = 'Stratum2'; 103 | aliveTextT.style.color = '#e6e6e680'; 104 | aliveTextCT.style.color = '#e6e6e680'; 105 | var winsT = hudTeamCounter.FindChildTraverse('ScoreT'); 106 | var winsCT = hudTeamCounter.FindChildTraverse('ScoreCT'); 107 | winsT.style.fontFamily = 'Stratum2 Bold Monodigit'; 108 | winsCT.style.fontFamily = 'Stratum2 Bold Monodigit'; 109 | winsT.style.color = '#A38B60C8'; 110 | winsCT.style.color = '#5C7F8AC8'; 111 | var timer = hudTeamCounter.FindChildTraverse('TimerText'); 112 | timer.style.fontFamily = 'Stratum2 Bold Monodigit'; 113 | timer.style.marginTop = '-2px'; 114 | timer.style.fontSize = '28px'; 115 | for (var tAlive of contextPanel.FindChildTraverse('HudTeamCounter').FindChildrenWithClassTraverse('TeamCounter__AliveT')){ 116 | tAlive.style.backgroundImage = `url(${hudTeamCountBgT})`; 117 | } 118 | for (var ctAlive of contextPanel.FindChildTraverse('HudTeamCounter').FindChildrenWithClassTraverse('TeamCounter__AliveCT')) 119 | { 120 | ctAlive.style.backgroundImage = `url(${hudTeamCountBgCT})`; 121 | } 122 | for (var scoreText of contextPanel.FindChildTraverse('HudTeamCounter').FindChildrenWithClassTraverse('TeamCounter__AliveCount')) 123 | { 124 | scoreText.style.color = '#ffffff'; 125 | } 126 | 127 | var historyText = contextPanel.FindChildTraverse('HudChat').FindChildTraverse('ChatHistoryText'); 128 | historyText.style.fontFamily = 'Stratum2'; 129 | historyText.style.fontSize = '18px'; 130 | historyText.style.fontWeight = 'lighter'; 131 | historyText.style.letterSpacing = '0px'; 132 | historyText.style.backgroundColor = '#000000CC'; 133 | 134 | var textEntry = contextPanel.FindChildTraverse('HudChat').FindChildTraverse('ChatTextEntryBox'); 135 | textEntry.style.fontFamily = 'Stratum2'; 136 | textEntry.style.fontSize = '18px'; 137 | textEntry.style.fontWeight = 'lighter'; 138 | textEntry.style.letterSpacing = '0px'; 139 | 140 | var sendChat = contextPanel.FindChildTraverse('HudChat').FindChildTraverse('ChatSendButton'); 141 | sendChat.style.fontFamily = 'Stratum2'; 142 | sendChat.style.fontSize = '18px'; 143 | sendChat.style.fontWeight = 'lighter'; 144 | sendChat.style.letterSpacing = '0px'; 145 | 146 | for(var sentChat of contextPanel.FindChildrenWithClassTraverse('AlertText')) 147 | { 148 | sentChat.style.backgroundColor = 'gradient( linear, 100% 0%, 0% 0%, from( #00000000 ), color-stop( 0.7, #00000077 ), to( #00000077 ) )'; 149 | sentChat.style.textShadow = '1px 1px 2px #00000055'; 150 | sentChat.style.fontFamily = 'Stratum2'; 151 | sentChat.style.fontWeight = 'normal'; 152 | sentChat.style.fontSize = '21.5px'; 153 | sentChat.style.letterSpacing = '.43px'; 154 | sentChat.style.paddingLeft = '28px'; 155 | sentChat.style.paddingBottom = '0px'; 156 | } 157 | 158 | )" -------------------------------------------------------------------------------- /scaleform/buyzone.js: -------------------------------------------------------------------------------- 1 | R"( 2 | var contextPanel = $.GetContextPanel(); 3 | var hudMoney = contextPanel.FindChildTraverse('HudMoney'); 4 | var moneyBg = hudMoney.FindChildTraverse('MoneyBG'); 5 | moneyBg.style.backgroundPosition = '${buyZone}'; 6 | )" -------------------------------------------------------------------------------- /scaleform/color.js: -------------------------------------------------------------------------------- 1 | R"( 2 | var contextPanel = $.GetContextPanel(); 3 | var hudRadar = contextPanel.FindChildTraverse('HudRadar'); 4 | 5 | var roundBorder = hudRadar.FindChildTraverse('Radar__Round--Border'); 6 | roundBorder.style.borderRadius = '50% / 50%'; 7 | roundBorder.style.borderWidth = '2px'; 8 | roundBorder.style.borderStyle = 'solid'; 9 | roundBorder.style.borderColor = `${radarColor}`; 10 | roundBorder.style.opacity = '0.50'; 11 | 12 | var squareBorder = hudRadar.FindChildTraverse('Radar__Square--Border'); 13 | squareBorder.style.borderRadius = '0'; 14 | squareBorder.style.borderWidth = '2px'; 15 | squareBorder.style.borderStyle = 'solid'; 16 | squareBorder.style.borderColor = `${radarColor}`; 17 | squareBorder.style.opacity = '0.50'; 18 | 19 | var dashboardLabel = hudRadar.FindChildTraverse('DashboardLabel'); 20 | dashboardLabel.style.color = `${dashboardLabelColor}`; 21 | )" -------------------------------------------------------------------------------- /scaleform/deathnotices.js: -------------------------------------------------------------------------------- 1 | R"( 2 | var contextPanel = $.GetContextPanel(); 3 | 4 | for (var dnBackground of contextPanel.FindChildrenWithClassTraverse('DeathNoticeBGBorder')) 5 | { 6 | 7 | dnBackground.style.border = '0px solid #00000000'; 8 | dnBackground.style.boxShadow = 'inset #00000000 0px 0px 0px 0px;'; 9 | dnBackground.style.borderRadius = '0px'; 10 | } 11 | 12 | for (var dnBackgroundg of contextPanel.FindChildrenWithClassTraverse('DeathNoticeBG')) 13 | { 14 | dnBackgroundg.style.backgroundImage = 'url("https://images2.imgbox.com/49/45/mrwub2K0_o.png")'; 15 | dnBackgroundg.style.backgroundSize = '100% 100%'; 16 | dnBackgroundg.style.backgroundColor = '#00000000'; 17 | } 18 | 19 | for (var dnIcon of contextPanel.FindChildrenWithClassTraverse('DeathNoticeIcon')) 20 | { 21 | if (dnIcon.id === "Weapon") 22 | { 23 | dnIcon.style.verticalAlign = 'top'; 24 | dnIcon.style.transform = 'translateY(5px)'; 25 | dnIcon.style.uiScale = "51%"; 26 | } else 27 | { 28 | dnIcon.style.height = '20px'; 29 | dnIcon.style.verticalAlign = 'top'; 30 | dnIcon.style.transform = 'translateY(0px) scaleY(.8) scaleX(.8)'; 31 | dnIcon.style.uiScale = "100%"; 32 | } 33 | } 34 | 35 | for (var dnT of contextPanel.FindChildrenWithClassTraverse('DeathNoticeTColor')) 36 | { 37 | dnT.style.color = '#e8c56f'; 38 | 39 | } 40 | for (var dnCt of contextPanel.FindChildrenWithClassTraverse('DeathNoticeCTColor')) 41 | { 42 | dnCt.style.color = '#83a5de'; 43 | 44 | } 45 | 46 | for (var deathnotice of contextPanel.FindChildrenWithClassTraverse('DeathNotice')) 47 | { 48 | // ---------------- ICON REMOVALS ---------------- 49 | deathnotice.FindChildTraverse('NoScopeIcon').style.visibility = 'collapse'; 50 | deathnotice.FindChildTraverse('ThroughSmokeIcon').style.visibility = 'collapse'; 51 | deathnotice.FindChildTraverse('AttackerBlindIcon').style.visibility = 'collapse'; 52 | deathnotice.FindChildTraverse('Domination').style.visibility = 'collapse'; 53 | // ---------------- REMOVALS ---------------- 54 | deathnotice.style.margin = '0px'; 55 | if(deathnotice.BHasClass('DeathNotice_Killer')) 56 | { 57 | for (var killer of contextPanel.FindChildTraverse('HudDeathNotice').FindChildrenWithClassTraverse('DeathNotice_Killer')) 58 | { 59 | for(var content of killer.FindChildrenWithClassTraverse('DeathNoticeBG')) 60 | { 61 | content.style.border = '2px solid #8a121b'; 62 | content.style.borderRadius = '3px'; 63 | content.style.backgroundColor = '#000000ff'; 64 | content.style.opacity = '0.9'; 65 | } 66 | } 67 | } 68 | if(deathnotice.BHasClass('DeathNotice_Victim')) 69 | { 70 | for (var victim of contextPanel.FindChildTraverse('HudDeathNotice').FindChildrenWithClassTraverse('DeathNotice_Victim')) 71 | { 72 | for(var content of victim.FindChildrenWithClassTraverse('DeathNoticeBG')) 73 | { 74 | 75 | content.style.backgroundColor = '#0e0e0eB3'; 76 | content.style.borderRadius = '3px'; 77 | content.style.boxShadow = 'inset #e10000e6 0px 0px 1px;'; 78 | content.style.opacity = '0.9'; 79 | } 80 | } 81 | } 82 | } 83 | )" -------------------------------------------------------------------------------- /scaleform/healthammo.js: -------------------------------------------------------------------------------- 1 | R"( 2 | var contextPanel = $.GetContextPanel(); 3 | contextPanel.FindChildTraverse('HudHealthArmor').style.marginLeft = '0px'; 4 | var hudHa = contextPanel.FindChildTraverse('HudHealthArmor'); 5 | /* <---- REMOVALS ----> */ 6 | hudHa.FindChildTraverse('HudHealthBG').style.backgroundColor = '#00000000'; 7 | hudHa.FindChildTraverse('HudArmorBG').style.backgroundColor = '#00000000'; 8 | /* <--------> */ 9 | for(var hud_container of hudHa.FindChildrenWithClassTraverse('hud-HA-icon-container')) 10 | { 11 | hud_container.style.x = '10px'; 12 | hud_container.style.y = '3px'; 13 | hud_container.style.width = '30px'; 14 | hud_container.style.height = '100%'; 15 | hud_container.style.opacity = '1.0'; 16 | hud_container.style.marginTop = '-1px'; 17 | } 18 | 19 | for(var hudHaArmor of hudHa.FindChildrenWithClassTraverse('hud-HA-armor1')) 20 | { 21 | hudHaArmor.style.x = '38px'; 22 | hudHaArmor.style.y = '3px'; 23 | hudHaArmor.style.width = '70px'; 24 | hudHaArmor.style.fontSize = '42px'; 25 | hudHaArmor.style.fontWeight = 'bold'; 26 | hudHaArmor.style.color = '#ffffff'; 27 | hudHaArmor.style.letterSpacing = '0px'; 28 | hudHaArmor.style.horizontalAlign = 'left'; 29 | hudHaArmor.style.opacity = '0.95'; 30 | hudHaArmor.style.textShadow = '0px 0px 3px 0.0 #000000DD'; 31 | hudHaArmor.style.marginLeft = '5px'; 32 | hudHaArmor.style.textOverflow = 'shrink'; 33 | } 34 | 35 | for(var hudHaHealth of hudHa.FindChildrenWithClassTraverse('hud-HA-health1')) 36 | { 37 | hudHaHealth.style.x = '38px'; 38 | hudHaHealth.style.y = '3px'; 39 | hudHaHealth.style.width = '70px'; 40 | hudHaHealth.style.fontSize = '42px'; 41 | hudHaHealth.style.fontWeight = 'bold'; 42 | hudHaHealth.style.color = '#ffffff'; 43 | hudHaHealth.style.letterSpacing = '0px'; 44 | hudHaHealth.style.horizontalAlign = 'center'; 45 | hudHaHealth.style.opacity = '0.95'; 46 | hudHaHealth.style.textShadow = '0px 0px 3px 0.0 #000000DD'; 47 | hudHaHealth.style.marginLeft = '5px'; 48 | hudHaHealth.style.textOverflow = 'shrink'; 49 | } 50 | 51 | for(var hudHaText of hudHa.FindChildrenWithClassTraverse('hud-HA-text')) 52 | { 53 | hudHaText.style.x = '42px'; 54 | hudHaText.style.y = '4px'; 55 | } 56 | 57 | for(var hudHaBar of hudHa.FindChildrenWithClassTraverse('hud-HA-bar')) 58 | { 59 | hudHaBar.style.x = '108px'; 60 | hudHaBar.style.y = '34px'; 61 | hudHaBar.style.backgroundColor = '#03030399'; 62 | } 63 | for(var hudHaGeneric of hudHa.FindChildrenWithClassTraverse('hud-HA')) 64 | { 65 | hudHaGeneric.style.width = '465px'; 66 | hudHaGeneric.style.height = '55px'; 67 | hudHaGeneric.style.verticalAlign = 'bottom'; 68 | hudHaGeneric.style.opacity = '0.0'; 69 | hudHaGeneric.style.transitionProperty = 'opacity'; 70 | hudHaGeneric.style.transitionTimingFunction = 'ease-in-out'; 71 | hudHaGeneric.style.transitionDuration = '0.3s'; 72 | hudHaGeneric.style.marginLeft = '0px'; 73 | 74 | if(hudHaGeneric.BHasClass('hud-HA--active')) 75 | { 76 | for(var hudHaGeneric_active of hudHa.FindChildrenWithClassTraverse('hud-HA--active')) 77 | { 78 | hudHaGeneric_active.style.opacity = '1.0'; 79 | } 80 | } 81 | } 82 | 83 | for(var survival of hudHa.FindChildrenWithClassTraverse('survival')) 84 | { 85 | for(var inner of survival.FindChildrenWithClassTraverse('hud-HA')) 86 | { 87 | inner.style.width = '550px'; 88 | } 89 | } 90 | 91 | for(var hudHaBg of hudHa.FindChildrenWithClassTraverse('hud-HA-bg')) 92 | { 93 | hudHaBg.style.flowChildren = 'right'; 94 | hudHaBg.style.width = '100%'; 95 | hudHaBg.style.height = '100%'; 96 | hudHaBg.style.opacity = '1.0'; 97 | } 98 | 99 | for(var hudHaBgH of hudHa.FindChildrenWithClassTraverse('hud-HA-bg-h')) 100 | { 101 | hudHaBgH.style.backgroundImage = 'url("https://images2.imgbox.com/3b/5c/knQ8o3GI_o.png")'; // HP.png 102 | hudHaBgH.style.backgroundSize = '107% 100%'; 103 | hudHaBgH.style.backgroundImgOpacity = '0.95'; 104 | hudHaBgH.style.width = '200px'; 105 | hudHaBgH.style.height = '100%'; 106 | hudHaBgH.style.horizontalAlign = 'left'; 107 | } 108 | 109 | for(var hudHaBgA of hudHa.FindChildrenWithClassTraverse('hud-HA-bg-a')) 110 | { 111 | hudHaBgA.style.backgroundImage = 'url("https://images2.imgbox.com/81/02/IrFgHYQq_o.png")'; // Armor.png 112 | hudHaBgA.style.backgroundSize = '100% 100%'; 113 | hudHaBgA.style.backgroundImgOpacity = '1.0'; 114 | hudHaBgA.style.width = ${isShort} ? '210px' : '55px'; 115 | hudHaBgA.style.height = '100%'; 116 | hudHaBgA.style.opacity = '0.95'; 117 | hudHaBgA.style.horizontalAlign = 'left'; 118 | hudHaBgA.style.overflow = 'noclip'; 119 | } 120 | 121 | for(var onDmg of hudHa.FindChildrenWithClassTraverse('hud-HA--on-damage')) 122 | { 123 | for(var dmg of onDmg.FindChildrenWithClassTraverse('hud-HA-text')) 124 | { 125 | dmg.style.washColor = '#ff0000'; 126 | } 127 | } 128 | 129 | for(var oncrit of hudHa.FindChildrenWithClassTraverse('hud-HA--critical')) 130 | { 131 | for(var hudHaBg of oncrit.FindChildTraverse('HudHealthArmor').FindChildrenWithClassTraverse('hud-HA-bg-h')) 132 | { 133 | hudHaBg.style.backgroundImage = 'url("https://images2.imgbox.com/7b/d1/XeL3b9D9_o.png")'; 134 | hudHaBg.style.backgroundImgOpacity = '0.92'; 135 | } 136 | } 137 | 138 | for (var health of contextPanel.FindChildTraverse('HudHealthArmor').FindChildrenWithClassTraverse('hud-HA-icon--health')) 139 | { 140 | 141 | health.SetImage('https://images2.imgbox.com/3f/ad/nTYzLRen_o.png'); 142 | health.style.marginTop = '0px'; 143 | health.style.overflow = 'noclip'; 144 | health.style.backgroundColor = '#00000000'; 145 | } 146 | 147 | for (var shield of contextPanel.FindChildTraverse('HudHealthArmor').FindChildrenWithClassTraverse('hud-HA-icon--armor')) 148 | { 149 | shield.SetImage('https://images2.imgbox.com/74/48/0CfxlpEt_o.png'); 150 | shield.style.marginTop = '0px'; 151 | shield.style.overflow = 'noclip'; 152 | shield.style.backgroundColor = '#00000000'; 153 | } 154 | )" -------------------------------------------------------------------------------- /scaleform/sanitary_macros.hpp: -------------------------------------------------------------------------------- 1 | #define JAVASCRIPT constexpr const char * 2 | #define HEX_COLOR constexpr const char * 3 | #define CSGO_HUD_SCHEMA "panorama/layout/hud/hud.xml" 4 | 5 | #define UPDATING_VAR(old, goal_name, goal, on_update) \ 6 | { \ 7 | decltype(old) goal_name = goal; \ 8 | if (old != goal_name) \ 9 | { \ 10 | on_update; \ 11 | old = goal_name; \ 12 | } \ 13 | } -------------------------------------------------------------------------------- /scaleform/scaleform.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace tsf 6 | { 7 | struct ui_panel_t; 8 | struct player_t; 9 | struct event_t; 10 | } 11 | 12 | struct scaleform_t 13 | { 14 | // game panel 15 | tsf::ui_panel_t *root; 16 | // weap sel 17 | tsf::ui_panel_t *weap_sel; 18 | // weap pan bg 19 | tsf::ui_panel_t *weap_pan_bg; 20 | // reset on shutdown, whether scaleform was initialized 21 | // (for toggle) 22 | bool inited; 23 | // old color cvar value 24 | int old_color; 25 | // old alpha cvar value 26 | float old_alpha; 27 | // old healthammo style cvar value 28 | int old_healthammo_style; 29 | // old in buyzone value 30 | int old_in_buyzone; 31 | // verify if we received mvp event 32 | bool pending_mvp; 33 | // old weapon selection rows count 34 | int old_weap_rows_count; 35 | } inline scf; 36 | 37 | void scaleform_init(); 38 | void scaleform_install(); 39 | void scaleform_tick(tsf::player_t *); 40 | void scaleform_on_event(tsf::event_t *); 41 | void scaleform_after_event(const char *); 42 | void scaleform_dump_icons(const char *, const uint8_t *, size_t, const char *); 43 | bool scaleform_get_replacement_icon(const char *, const uint8_t *&, size_t &, int &, int &); -------------------------------------------------------------------------------- /scaleform/spectating.js: -------------------------------------------------------------------------------- 1 | R"( 2 | var contextPanel = $.GetContextPanel(); 3 | 4 | for(var spec_parent of contextPanel.FindChildrenWithClassTraverse('HudSpecplayerParentContainer')) 5 | { 6 | spec_parent.style.height = '260px'; 7 | spec_parent.style.width = '642px'; 8 | } 9 | for(var spec_bg of contextPanel.FindChildrenWithClassTraverse('HudSpecplayerBG')) 10 | { 11 | spec_bg.style.backgroundColor = '#0000004D'; 12 | spec_bg.style.height = '100px'; 13 | spec_bg.style.verticalAlign = 'top'; 14 | spec_bg.style.overflow = 'noclip' 15 | } 16 | 17 | for(var spec_bgb of contextPanel.FindChildrenWithClassTraverse('HudSpecplayerBG__Border')) 18 | { 19 | spec_bgb.style.backgroundColor = '#0000004D'; 20 | } 21 | 22 | for(var spec_def_logo of contextPanel.FindChildrenWithClassTraverse('HudSpecplayerBG__DefaultLogo')) 23 | { 24 | spec_def_logo.style.visibility = 'collapse'; 25 | } 26 | 27 | for(var spec_top_strip of contextPanel.FindChildrenWithClassTraverse('HudSpecplayerBG__TopStrip')) 28 | { 29 | spec_top_strip.style.visibility = 'collapse'; 30 | } 31 | 32 | for(var spec_bottom_strip of contextPanel.FindChildrenWithClassTraverse('HudSpecplayerBG__BottomStrip')) 33 | { 34 | spec_bottom_strip.style.backgroundColor = '#0000004D'; 35 | spec_bottom_strip.style.height = '24px'; 36 | spec_bottom_strip.style.transform = 'translateY(0px)'; 37 | } 38 | 39 | for(var fix of contextPanel.FindChildrenWithClassTraverse('HudSpecplayer__ItemContainer')) 40 | { 41 | fix.style.overflow = 'noclip' 42 | } 43 | 44 | function updateText() 45 | { 46 | for (var row of contextPanel.FindChildrenWithClassTraverse('weapon-row')) { 47 | if (row.BHasClass('weapon-row--selected')) { 48 | for(var x of row.FindChildrenWithClassTraverse('weapon-selection-item-name-text')) 49 | { 50 | for(var txt of contextPanel.FindChildrenWithClassTraverse('HudSpecplayer__ItemName')) 51 | { 52 | txt.text = x.text; 53 | txt.style.visibility = 'visible'; 54 | txt.style.height = 'fit-children'; 55 | txt.style.verticalAlign = 'bottom'; 56 | txt.style.backgroundColor = '#00000000'; 57 | txt.style.transform = 'translateY(13px) translateX(-5px)'; 58 | txt.style.fontSize = '16px'; 59 | txt.style.fontWeight = 'light' 60 | } 61 | } 62 | } 63 | } 64 | } 65 | 66 | for(var spec_player_name of contextPanel.FindChildrenWithClassTraverse('HudSpecplayer__player-name')) 67 | { 68 | spec_player_name.style.verticalAlign = 'center'; 69 | spec_player_name.style.transform = 'translateY(0px)' 70 | spec_player_name.style.fontSize = '36px'; 71 | spec_player_name.style.fontWeight = 'bold'; 72 | spec_player_name.style.fontFamily = 'Stratum2'; 73 | spec_player_name.style.letterSpacing = '-1px'; 74 | spec_player_name.style.textShadow = '0px 0px 0px 0.0 #000000'; 75 | } 76 | 77 | for(var spec_root_avatar of contextPanel.FindChildrenWithClassTraverse('HudSpecplayerRoot__avatar')) 78 | { 79 | spec_root_avatar.style.height = '76px'; 80 | spec_root_avatar.style.width = '76px'; 81 | spec_root_avatar.style.marginTop = '-3px'; 82 | spec_root_avatar.style.border = '0px solid #ff0000'; 83 | spec_root_avatar.style.backgroundColor = 'gradient( linear, 0% 0%, 0% 100%, from( #838383 ), to( #303030 ) )'; 84 | spec_root_avatar.style.padding = '3px' 85 | } 86 | for(var spec_k_hints of contextPanel.FindChildrenWithClassTraverse('HudSpecplayer__key-hints-text')) 87 | { 88 | spec_k_hints.style.opacity = '1'; 89 | spec_k_hints.style.verticalAlign = 'bottom'; 90 | spec_k_hints.style.transform = 'translateY(63%) translateX(-10px)'; 91 | spec_k_hints.style.fontSize = '17px'; 92 | spec_k_hints.style.fontWeight = 'light'; 93 | spec_k_hints.style.horizontalAlign = 'left'; 94 | spec_k_hints.style.backgroundColor = '#00000000'; 95 | } 96 | for(var spec_root_t of contextPanel.FindChildrenWithClassTraverse('HudSpecplayerRoot--TeamT')) 97 | { 98 | for(var names of spec_root_t.FindChildrenWithClassTraverse('HudSpecplayer__player-name')) 99 | { 100 | names.style.color = '#F7F4CB' 101 | } 102 | } 103 | for(var spec_root_ct of contextPanel.FindChildrenWithClassTraverse('HudSpecplayerRoot--TeamCT')) 104 | { 105 | for(var names of spec_root_ct.FindChildrenWithClassTraverse('HudSpecplayer__player-name')) 106 | { 107 | names.style.color = '#E5F8FF' 108 | } 109 | } 110 | 111 | $.Schedule(0.05, updateText); 112 | )" -------------------------------------------------------------------------------- /scaleform/teamcount_avatar.js: -------------------------------------------------------------------------------- 1 | R"( 2 | function runner() { 3 | var hudTeamCounter = $.GetContextPanel().FindChildTraverse('HudTeamCounter'); 4 | 5 | 6 | for (var avatarBackground of hudTeamCounter.FindChildrenWithClassTraverse('AvatarL__Default--CT')) { 7 | avatarBackground.style.backgroundSize = '92% 86%'; 8 | avatarBackground.style.backgroundPosition = '50% 25%'; 9 | avatarBackground.style.backgroundRepeat = 'no-repeat'; 10 | } 11 | for (var avatarBackground of hudTeamCounter.FindChildrenWithClassTraverse('AvatarL__Default--T')) { 12 | avatarBackground.style.backgroundSize = '92% 86%'; 13 | avatarBackground.style.backgroundPosition = '50% 25%'; 14 | avatarBackground.style.backgroundRepeat = 'no-repeat'; 15 | 16 | } 17 | 18 | for (var avatarClr of hudTeamCounter.FindChildrenWithClassTraverse('AvatarL__PlayerColor')) { 19 | avatarClr.style.y = '-2px'; 20 | avatarClr.style.width = '24px'; 21 | avatarClr.style.height = '12px'; 22 | avatarClr.style.marginLeft = '0px'; 23 | avatarClr.style.horizontalAlign = 'center'; 24 | avatarClr.style.imgShadow = '0px 0px 1px 1.0 #000000CC'; 25 | } 26 | 27 | for (avatarL of hudTeamCounter.FindChildrenWithClassTraverse('AvatarL__Internal')) { 28 | avatarL.style.height = '59px'; 29 | avatarL.style.width = '85%'; 30 | avatarL.style.horizontalAlign = 'center'; 31 | avatarL.style.verticalAlign = 'top'; 32 | avatarL.style.backgroundColor = '#7f7f7f'; 33 | } 34 | 35 | for (var avatarL of hudTeamCounter.FindChildrenWithClassTraverse('AvatarL_HealthBarBG')) { 36 | avatarL.style.verticalAlign = 'bottom'; 37 | avatarL.style.marginBottom = '1.5px'; 38 | avatarL.style.marginRight = '1.5px'; 39 | avatarL.style.marginLeft = '1.5px'; 40 | avatarL.style.height = '4.55px'; 41 | avatarL.style.backgroundColor = '#00000040'; 42 | avatarL.style.position = 'absolute'; 43 | } 44 | 45 | for (var avbg of hudTeamCounter.FindChildrenWithClassTraverse('AvatarL__ImageBG')) { 46 | avbg.style.width = '85%'; 47 | avbg.style.height = '59px'; 48 | } 49 | 50 | for (var avatarL of hudTeamCounter.FindChildrenWithClassTraverse('AvatarL')) { 51 | avatarL.style.width = '58px'; 52 | avatarL.style.height = '100px'; 53 | avatarL.style.overflow = 'noclip'; 54 | } 55 | 56 | for (var avatarS of hudTeamCounter.FindChildrenWithClassTraverse('AvatarS')) { 57 | avatarS.style.width = '40px'; 58 | } 59 | 60 | for (var avatarS of hudTeamCounter.FindChildrenWithClassTraverse('AvatarS__Internal')) { 61 | avatarS.style.opacity = '1'; 62 | avatarS.style.width = '25px'; 63 | avatarS.style.height = '28.6px'; 64 | avatarS.style.backgroundColor = '#7f7f7f'; 65 | avatarS.style.verticalAlign = 'top'; 66 | } 67 | 68 | for (var avatarS of hudTeamCounter.FindChildrenWithClassTraverse('AvatarS__PlayerImage')) { 69 | avatarS.style.backgroundColor = 'black'; 70 | avatarS.style.width = '100%'; 71 | avatarS.style.height = '100%'; 72 | avatarS.style.verticalAlign = 'middle'; 73 | } 74 | 75 | 76 | for (var avatarS of hudTeamCounter.FindChildrenWithClassTraverse('AvatarS__HealthBar')) { 77 | avatarS.style.height = '3px'; 78 | avatarS.style.verticalAlign = 'bottom'; 79 | } 80 | 81 | for (var avatarS of hudTeamCounter.FindChildrenWithClassTraverse('AvatarS__Default--CT')) { 82 | avatarS.style.backgroundSize = '100% 180%'; 83 | avatarS.style.backgroundPosition = 'center'; 84 | avatarS.style.height = '100%' 85 | } 86 | 87 | for (var avatarS of hudTeamCounter.FindChildrenWithClassTraverse('AvatarS__Default--T')) { 88 | avatarS.style.backgroundSize = '100% 180%'; 89 | avatarS.style.backgroundPosition = 'center'; 90 | avatarS.style.height = '100%'; 91 | } 92 | 93 | 94 | for (var internalColor of hudTeamCounter.FindChildrenWithClassTraverse('AvatarImageT__Color')) { 95 | internalColor.style.backgroundColor = '#87663e'; 96 | internalColor.style.border = '2px solid #8a6a41'; 97 | } 98 | 99 | for (var internalColor of hudTeamCounter.FindChildrenWithClassTraverse('AvatarImageT__InternalColor')) { 100 | internalColor.style.backgroundColor = '#FFFFFF'; 101 | } 102 | 103 | 104 | for (var internalColor of hudTeamCounter.FindChildrenWithClassTraverse('AvatarImageCT__Color')) { 105 | internalColor.style.backgroundColor = '#72859d'; 106 | internalColor.style.border = '2px solid #72859d'; 107 | } 108 | 109 | for (var internalColor of hudTeamCounter.FindChildrenWithClassTraverse('AvatarImageCT__InternalColor')) { 110 | internalColor.style.backgroundColor = '#FFFFFF'; 111 | } 112 | 113 | for (var noOutline of hudTeamCounter.FindChildrenWithClassTraverse('Avatar__PlayerOutline--None')) { 114 | noOutline.style.border = '0px solid #0000000'; 115 | } 116 | 117 | for (var avatarOutline of hudTeamCounter.FindChildrenWithClassTraverse('Avatar__PlayerOutline--White')) { 118 | avatarOutline.style.border = '4px solid white'; 119 | } 120 | 121 | 122 | for (var avatarOutline of hudTeamCounter.FindChildrenWithClassTraverse('Avatar__PlayerOutline--T')) { 123 | avatarOutline.style.backgroundColor = '#756337'; 124 | avatarOutline.style.border = '2px solid #87663e'; 125 | } 126 | 127 | for (var avatarOutline of hudTeamCounter.FindChildrenWithClassTraverse('Avatar__PlayerOutline--CT')) { 128 | avatarOutline.style.backgroundColor = '#7C858F'; 129 | avatarOutline.style.border = '2px solid #4F5D6D'; 130 | } 131 | 132 | for (var av of hudTeamCounter.FindChildrenWithClassTraverse('Avatar__HealthBar--Normal')) { 133 | av.style.backgroundColor = '#99ae91'; 134 | } 135 | } 136 | 137 | $.Schedule(0.3, runner); 138 | //runner(); 139 | )" -------------------------------------------------------------------------------- /scaleform/weapon_select.js: -------------------------------------------------------------------------------- 1 | R"( 2 | 3 | var hws = contextPanel.FindChildTraverse('HudWeaponSelection'); 4 | hws.style.transform = 'translateY(-10px)'; 5 | for (select of hws.FindChildrenWithClassTraverse("weapon-selection-item")) { 6 | select.style.transform = 'translateY(0px)'; 7 | select.style.marginTop = '0px'; 8 | select.style.overflow = 'noclip'; 9 | select.style.verticalAlign = 'center'; 10 | for (text of select.FindChildrenWithClassTraverse('weapon-selection-item-name-text')) { 11 | text.style.fontSize = '17px'; 12 | text.style.letterSpacing = '-0.4px'; 13 | text.style.opacity = '0.95'; 14 | text.style.marginTop = '1px'; 15 | text.style.fontFamily = 'Stratum2'; 16 | text.style.transform = 'translateY(-4px) translateX(5px)'; 17 | text.style.fontWeight = 'bold'; 18 | } 19 | for (icon of select.FindChildrenWithClassTraverse('weapon-selection-item-icon-main')) { 20 | icon.style.marginRight = '8px'; 21 | icon.style.marginLeft = '12px'; 22 | icon.style.padding = '5px'; 23 | icon.style.opacity = '0.98'; 24 | icon.style.transform = 'scaleX(-1)'; 25 | } 26 | } 27 | 28 | for (row of hws.FindChildrenWithClassTraverse('weapon-row')) { 29 | // if (row.BHasClass('weapon-row--selected')) 30 | { 31 | for(test of row.FindChildrenWithClassTraverse('weapon-row-background')) 32 | { 33 | test.style.backgroundImage = 'url("https://cdn.discordapp.com/attachments/808866622701830186/1001890355169476669/weapon_row_bg.png")'; 34 | test.style.backgroundRepeat = 'no-repeat' 35 | test.style.backgroundPosition = 'right'; 36 | test.style.backgroundSize = '221px 73px' 37 | test.style.horizontalAlign = 'right'; 38 | test.style.backgroundImgOpacity = '0.65'; 39 | } 40 | } 41 | } 42 | for (rowNumber of hws.FindChildrenWithClassTraverse('weapon-row-number')) { 43 | rowNumber.style.fontSize = '16px'; 44 | rowNumber.style.fontWeight = 'bold'; 45 | rowNumber.style.transform = 'translateY(-5px)'; 46 | } 47 | 48 | )" -------------------------------------------------------------------------------- /scaleform/winpanel.js: -------------------------------------------------------------------------------- 1 | R"( 2 | var contextPanel = $.GetContextPanel(); 3 | var textColor = ${isCt} ? '#B4BBBE' : '#D6C8B5'; 4 | 5 | var winPanelFg = contextPanel.FindChildrenWithClassTraverse('WinPanelTeam')[0].FindChildrenWithClassTraverse('TeamFG')[0]; 6 | winPanelFg.backgroundColor = '#ffffff00'; 7 | 8 | var mvpStar = 'https://cdn.discordapp.com/attachments/954389817536421908/957676079642980392/star.svg'; 9 | var winpanelBackground = ${isCt} ? 'https://images2.imgbox.com/dd/a0/NGbPjmfs_o.png' : ${isT} ? 'https://images2.imgbox.com/2c/64/OQBzyOLT_o.png' : 'https://images2.imgbox.com/dd/a0/NGbPjmfs_o.png'; 10 | if (${is2013}) 11 | winpanelBackground = ${isCt} ? 'https://images2.imgbox.com/77/d5/T79ImP9g_o.png' : ${isT} ? 'https://images2.imgbox.com/26/56/eEUIVB7m_o.png' : 'https://images2.imgbox.com/77/d5/T79ImP9g_o.png'; 12 | 13 | if(!${pendingMvp} && !${is2013}) 14 | { 15 | winpanelBackground = ${isCt} ? 'https://images2.imgbox.com/aa/19/PZCGWu3Y_o.png' : ${isT} ? 'https://images2.imgbox.com/a8/41/vccaTYzS_o.png' : 'https://images2.imgbox.com/aa/19/PZCGWu3Y_o.png'; 16 | } 17 | for (var mvp of contextPanel.FindChildTraverse('HudWinPanel').FindChildrenWithClassTraverse('MVP')) 18 | { 19 | if (${pendingMvp}) 20 | { 21 | mvp.style.visibility = 'visible'; 22 | mvp.style.width = '815px'; 23 | } else 24 | { 25 | mvp.style.visibility = 'collapse'; 26 | } 27 | } 28 | for (var winPanelBg of contextPanel.FindChildTraverse('HudWinPanel').FindChildrenWithClassTraverse('TeamBG__MainBG')) { 29 | winPanelBg.style.marginTop = '-42px'; 30 | winPanelBg.style.width = '815px'; 31 | winPanelBg.style.height = '155px'; 32 | winPanelFg.style.marginTop = '-42px'; 33 | winPanelFg.style.width = '815px'; 34 | winPanelFg.style.height = '155px'; 35 | winPanelFg.style.marginLeft = '105px'; 36 | winPanelBg.style.backgroundImage = `url(${winpanelBackground})`; 37 | winPanelBg.style.backgroundSize = 'cover'; 38 | winPanelBg.style.marginLeft = '105px'; 39 | winPanelBg.style.transitionProperty = 'brightness'; 40 | } 41 | for (var teamTitle of contextPanel.FindChildTraverse('HudWinPanel').FindChildrenWithClassTraverse('TeamFG__Title')) 42 | { 43 | teamTitle.style.visibility = ${is2013} ? 'collapse' : 'visible'; 44 | teamTitle.style.marginTop = '-45px'; 45 | teamTitle.style.color = textColor; 46 | teamTitle.style.fontSize = '40px'; 47 | } 48 | for (var star of contextPanel.FindChildTraverse('HudWinPanel').FindChildrenWithClassTraverse('MVP__WinnerStar')) { 49 | if (${pendingMvp}) 50 | { 51 | star.style.visibility = ${is2013} ?'collapse' : 'visible'; 52 | star.style.marginTop = "25%"; 53 | star.style.marginLeft = "-2px"; 54 | star.SetImage(mvpStar); 55 | star.style.transform = 'translateY(5px)'; 56 | } else 57 | { 58 | star.style.visibility = 'collapse'; 59 | } 60 | } 61 | for (var playerName of contextPanel.FindChildTraverse('HudWinPanel').FindChildrenWithClassTraverse('MVP__WinnerName')){ 62 | if (${pendingMvp}) 63 | { 64 | playerName.style.visibility = 'visible'; 65 | playerName.style.marginTop = ${is2013} ?"15px" : "20px"; 66 | playerName.style.color = ${isCt} ?"#717377" : "#8A7E6C"; 67 | playerName.style.marginLeft = ${is2013} ?"-4px" : "2px"; 68 | playerName.style.fontSize = ${is2013} ?"22px" : "17px"; 69 | playerName.style.fontWeight = ${is2013} ?'light' : 'bold'; 70 | playerName.style.transform = 'translateY(5px)'; 71 | } else 72 | { 73 | playerName.style.visibility = 'collapse'; 74 | } 75 | } 76 | for (var profileImg of contextPanel.FindChildTraverse('HudWinPanel').FindChildrenWithClassTraverse('MVP__Avatar')) 77 | { 78 | if (${pendingMvp}) 79 | { 80 | if (${is2013}) 81 | { 82 | profileImg.style.visibility = 'visible'; 83 | profileImg.style.zIndex = "500"; 84 | profileImg.style.height = "59px"; 85 | profileImg.style.width = "59px"; 86 | profileImg.style.marginTop = "19px"; 87 | profileImg.style.padding = '0px'; 88 | profileImg.style.paddingTop = '2px'; 89 | profileImg.style.backgroundSize = '50%'; 90 | profileImg.style.marginLeft = "25px"; 91 | profileImg.style.backgroundColor = 'gradient( linear, 0% 0%, 0% 100%, from( #7d7d7d ), to( #202020) )'; 92 | for (var imgPadding of contextPanel.FindChildTraverse('HudWinPanel').FindChildrenWithClassTraverse('AvatarImage')) { 93 | imgPadding.style.padding = '0px'; 94 | } 95 | } else 96 | { 97 | profileImg.style.visibility = 'visible'; 98 | profileImg.style.zIndex = "1000"; 99 | profileImg.style.height = "60px"; 100 | profileImg.style.width = "60px"; 101 | profileImg.style.backgroundColor = "#00000000"; 102 | profileImg.style.marginTop = "19px"; 103 | profileImg.style.paddingLeft = "0px"; 104 | profileImg.style.marginLeft = "25px"; 105 | } 106 | } else 107 | { 108 | profileImg.style.visibility = 'collapse'; 109 | } 110 | } 111 | var count = 60 112 | var start = 5 + count 113 | var funFact = contextPanel.FindChildTraverse('FunFactText'); 114 | if (!${is2013}) 115 | { 116 | funFact.style.width = '813px'; 117 | funFact.style.height = '35px'; 118 | funFact.style.x = '107px'; 119 | funFact.style.marginTop = `${start}px`; 120 | funFact.style.backgroundColor = '#000000CC'; 121 | funFact.style.verticalAlign = 'center'; 122 | funFact.style.textAlign = 'center'; 123 | funFact.style.paddingTop = '10px'; 124 | funFact.style.paddingLeft = '0px'; 125 | funFact.style.fontWeight = 'normal'; 126 | funFact.style.fontSize = '16px'; 127 | } 128 | else 129 | { 130 | funFact.style.width = '813px'; 131 | funFact.style.height = '40px'; 132 | funFact.style.x = '107px'; 133 | funFact.style.marginTop = `${start}px`; 134 | funFact.style.backgroundColor = '#000000CC'; 135 | funFact.style.textAlign = 'left'; 136 | funFact.style.fontSize = '19px'; 137 | funFact.style.fontWeight = 'light'; 138 | funFact.style.verticalAlign = 'center'; 139 | funFact.style.paddingTop = '10px'; 140 | funFact.style.paddingLeft = '25px'; 141 | } 142 | 143 | // is this horrible? yes. 144 | // does it work? yes. 145 | // you win some, 146 | // you lose some. 147 | var time = 0.20 148 | var funfactTime = 1.0 149 | $.Schedule(funfactTime, function() { 150 | for (var z = 0; z <= 60; ++z) 151 | { 152 | $.Schedule(time * (z/60), function() { 153 | if (count >= 0) { 154 | var e = 5 + count 155 | funFact.style.marginTop = `${e}px` 156 | count -= 1 157 | } 158 | }) 159 | } 160 | }) 161 | /* <--------- REMOVALS ---------->*/ 162 | for (var h of contextPanel.FindChildTraverse('HudWinPanel').FindChildrenWithClassTraverse('TeamBG__hrTop')) {h.style.x = '0';h.style.y = '0';h.style.width = '0';h.style.height = '0';} 163 | for (var h of contextPanel.FindChildTraverse('HudWinPanel').FindChildrenWithClassTraverse('TeamBG__hrMid')) {h.style.x = '0';h.style.y = '0';h.style.width = '0';h.style.height = '0';} 164 | for (var h of contextPanel.FindChildTraverse('HudWinPanel').FindChildrenWithClassTraverse('TeamBG__hrBot')) {h.style.x = '0';h.style.y = '0';h.style.width = '0';h.style.height = '0';} 165 | for (var hideTeamIcon of contextPanel.FindChildTraverse('HudWinPanel').FindChildrenWithClassTraverse('TeamBG__DefaultLogo')){hideTeamIcon.style.visibility ='collapse'; hideTeamIcon.style.opacity = '0';} 166 | 167 | 168 | /* <--------- FLASHING ----------> */ 169 | 170 | function firstFlash() { 171 | for (var star of contextPanel.FindChildTraverse('HudWinPanel').FindChildrenWithClassTraverse('MVP__WinnerStar')) { 172 | star.style.transition = 'wash-color 0.15s linear 0.0s'; 173 | star.style.washColor = '#FFFFFF'; 174 | } 175 | 176 | winPanelFg.style.transition = 'background-color 0.15s linear 0.0s'; 177 | winPanelFg.style.backgroundColor = '#FFFFFF'; 178 | } 179 | 180 | function secondFlash() { 181 | for (var star of contextPanel.FindChildTraverse('HudWinPanel').FindChildrenWithClassTraverse('MVP__WinnerStar')) { 182 | star.style.transition = 'wash-color 0.30s linear 0.0s'; 183 | star.style.washColor = '#FFD856'; 184 | } 185 | 186 | winPanelFg.style.transition = 'background-color 0.30s linear 0.0s'; 187 | winPanelFg.style.backgroundColor = 'transparent'; 188 | } 189 | 190 | $.Schedule(0.2, firstFlash); 191 | $.Schedule(0.35, secondFlash); 192 | 193 | )" -------------------------------------------------------------------------------- /sdk.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | // NOTE(para): minwindef.h 6 | #ifdef CDECL 7 | #undef CDECL 8 | #endif 9 | 10 | #ifdef WIN32 11 | #define LINUX false 12 | 13 | #define WIN32_LINUX_LITERAL(x, y) x 14 | #define THISCALL __thiscall 15 | #define STDCALL __stdcall 16 | #define FASTCALL __fastcall 17 | #define CDECL __cdecl 18 | #define GET_MODULE_HANDLE(x) GetModuleHandleA(x) 19 | #define FASTCALL_ARGS void *self, void *edx 20 | #define FASTCALL_CALL self, edx 21 | #else 22 | #define LINUX true 23 | 24 | #define WIN32_LINUX_LITERAL(x, y) y 25 | #define THISCALL 26 | #define STDCALL 27 | #define FASTCALL 28 | #define CDECL 29 | #define GET_MODULE_HANDLE(x) x 30 | #define FASTCALL_ARGS void *self 31 | #define FASTCALL_CALL self 32 | #define OPENGL_VULKAN(x, y) !ctx.g.is_vulkan ? x : y 33 | #endif 34 | 35 | #define CLIENT_DLL WIN32_LINUX_LITERAL("client.dll", "csgo/bin/linux64/client_client.so") 36 | #define ENGINE_DLL WIN32_LINUX_LITERAL("engine.dll", "engine_client.so") 37 | #define PANORAMA_DLL WIN32_LINUX_LITERAL("panorama.dll", OPENGL_VULKAN("panorama_gl_client.so", "panorama_client.so")) 38 | 39 | template 40 | inline auto rel_to_abs(uintptr_t address) 41 | { 42 | return (T)(address + 4 + *reinterpret_cast(address)); 43 | } 44 | 45 | template 46 | constexpr auto WIN32_LINUX(T&& lhs, T&& rhs) 47 | { 48 | return LINUX ? rhs : lhs; 49 | } 50 | 51 | namespace tsf 52 | { 53 | template 54 | struct utl_vector_t 55 | { 56 | T *mem; 57 | int alloc_count; 58 | int grow_size; 59 | int size; 60 | T *els; 61 | }; 62 | 63 | struct ui_panel_t 64 | { 65 | const char *get_id() 66 | { 67 | return ((const char *(THISCALL *)(ui_panel_t *))((*(uintptr_t **)(this))[WIN32_LINUX(9, 10)]))(this); 68 | } 69 | 70 | ui_panel_t* get_parent() 71 | { 72 | return ((ui_panel_t *(THISCALL *)(ui_panel_t *))((*(uintptr_t **)(this))[WIN32_LINUX(25, 26)]))(this); 73 | } 74 | 75 | void set_visible(bool to) 76 | { 77 | return ((void(THISCALL *)(ui_panel_t *, bool))((*(uintptr_t **)(this))[WIN32_LINUX(27, 28)]))(this, to); 78 | } 79 | 80 | ui_panel_t *find_child_traverse(const char *name) 81 | { 82 | return ((ui_panel_t *(THISCALL *)(ui_panel_t *, const char *))((*(uintptr_t **)(this))[WIN32_LINUX(40, 41)]))(this, name); 83 | } 84 | 85 | void find_children_with_class_traverse(const char *class_name, utl_vector_t *out) 86 | { 87 | return ((void(THISCALL *)(ui_panel_t *, const char *, utl_vector_t *))((*(uintptr_t **)(this))[302]))(this, class_name, out); 88 | } 89 | }; 90 | 91 | struct ui_engine_t 92 | { 93 | bool is_valid_panel_pointer(ui_panel_t const *panel) 94 | { 95 | return ((bool(THISCALL *)(ui_engine_t *, ui_panel_t const *))((*(uintptr_t **)(this))[WIN32_LINUX(36, 37)]))(this, panel); 96 | } 97 | 98 | ui_panel_t *get_last_dispatched_event_target_panel() 99 | { 100 | return ((ui_panel_t *(THISCALL *)(ui_engine_t *))((*(uintptr_t **)(this))[WIN32_LINUX(56, 57)]))(this); 101 | } 102 | 103 | 104 | void run_script(ui_panel_t *panel, const char *js, const char *schema_path, int a5 = 8, int a6 = 10, bool a7 = false, bool a8 = false) 105 | { 106 | return ((void(THISCALL *)(ui_engine_t *, ui_panel_t *, const char *, const char *, int, int, bool, bool))((*(uintptr_t **)(this))[WIN32_LINUX(113, 114)]))(this, panel, js, schema_path, a5, a6, a7, a8); 107 | } 108 | }; 109 | 110 | struct panorama_t 111 | { 112 | ui_engine_t *access_ui_engine() 113 | { 114 | return ((ui_engine_t *(THISCALL *)(panorama_t *))((*(uintptr_t **)(this))[11]))(this); 115 | } 116 | }; 117 | 118 | struct player_t 119 | { 120 | bool in_buyzone() 121 | { 122 | return *(bool*)((uintptr_t)this + WIN32_LINUX(0x99B5, 0xA2A9)); 123 | } 124 | }; 125 | 126 | struct user_cmd_t 127 | { 128 | void* vtable; 129 | int command_number; 130 | int tick_count; 131 | }; 132 | 133 | struct cvar_t 134 | { 135 | float get_float() 136 | { 137 | return ((float(THISCALL *)(cvar_t *))((*(uintptr_t **)(this))[WIN32_LINUX(12, 15)]))(this); 138 | } 139 | 140 | int get_int() 141 | { 142 | return ((int(THISCALL *)(cvar_t *))((*(uintptr_t **)(this))[WIN32_LINUX(13, 16)]))(this); 143 | } 144 | }; 145 | 146 | struct cvars_t 147 | { 148 | cvar_t *get_var(const char *name) 149 | { 150 | return ((cvar_t *(THISCALL *)(cvars_t *, const char *))((*(uintptr_t **)(this))[16]))(this, name); 151 | } 152 | }; 153 | 154 | struct event_t 155 | { 156 | const char *get_name() 157 | { 158 | return ((const char *(THISCALL *)(event_t *))((*(uintptr_t **)(this))[WIN32_LINUX(1, 2)]))(this); 159 | } 160 | 161 | int get_int(const char *key, int def = 0) 162 | { 163 | return ((int(THISCALL *)(event_t *, const char *, int))((*(uintptr_t **)(this))[WIN32_LINUX(6, 7)]))(this, key, def); 164 | } 165 | }; 166 | } --------------------------------------------------------------------------------