├── .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 | 
3 | 
4 | Join us on Discord!
5 |
6 |
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 |
11 |
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 | [](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 | }
--------------------------------------------------------------------------------