This commit is contained in:
Arsenii es3n1n 2022-05-15 22:32:16 +02:00
commit 09cca66301
14 changed files with 3271 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
build*/
.idea/
.vs/
cmake-build-*/
/CMakeSettings.json

74
CMakeLists.txt Normal file
View File

@ -0,0 +1,74 @@
# This file is automatically generated from cmake.toml - DO NOT EDIT
# See https://github.com/build-cpp/cmkr for more information
cmake_minimum_required(VERSION 3.15)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR "In-tree builds are not supported. Run CMake from a separate directory: cmake -B build")
endif()
# Regenerate CMakeLists.txt automatically in the root project
set(CMKR_ROOT_PROJECT OFF)
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(CMKR_ROOT_PROJECT ON)
# Bootstrap cmkr
include("cmake/cmkr.cmake" OPTIONAL RESULT_VARIABLE CMKR_INCLUDE_RESULT)
if(CMKR_INCLUDE_RESULT)
cmkr()
endif()
# Enable folder support
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
endif()
# Create a configure-time dependency on cmake.toml to improve IDE support
if(CMKR_ROOT_PROJECT)
configure_file(cmake.toml cmake.toml COPYONLY)
endif()
# Set up a more familiar Visual Studio configuration
# Override these options with -DCMAKE_OPTION=Value
#
# See: https://cmake.org/cmake/help/latest/command/set.html#set-cache-entry
set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/DEBUG:FULL /INCREMENTAL:NO" CACHE STRING "")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "/DEBUG:FULL /INCREMENTAL:NO" CACHE STRING "")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE STRING "")
project(BetterRVA)
include("cmake/CPM.cmake")
include("cmake/x64dbg.cmake")
# Target BetterRVA
set(CMKR_TARGET BetterRVA)
set(BetterRVA_SOURCES "")
list(APPEND BetterRVA_SOURCES
"src/plugin.cpp"
"src/pluginmain.cpp"
"src/icons.h"
"src/plugin.h"
"src/pluginmain.h"
)
list(APPEND BetterRVA_SOURCES
cmake.toml
)
set(CMKR_SOURCES ${BetterRVA_SOURCES})
add_library(BetterRVA SHARED)
if(BetterRVA_SOURCES)
target_sources(BetterRVA PRIVATE ${BetterRVA_SOURCES})
endif()
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${BetterRVA_SOURCES})
x64dbg_plugin(${CMKR_TARGET})
unset(CMKR_TARGET)
unset(CMKR_SOURCES)

10
README.md Normal file
View File

@ -0,0 +1,10 @@
## BetterRVA
### What is this?
Since the button in x64dbg `Copy RVA` copies RVA only when the current address is in the module \
I decided to make my own _very-useless_ plugin and now you can copy RVA not only from modules but \
from unknown memory pages too. \
![memebox](https://i.imgur.com/Bbms4HT.png)
### Screenshot:
![img](https://i.imgur.com/VLRbB1A.png)

6
build.bat Normal file
View File

@ -0,0 +1,6 @@
call "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\vsdevcmd.bat"
cmake -B build64 -A x64
cmake -B build32 -A Win32
cmake --build build64 --config Release
cmake --build build32 --config Release
pause

31
cmake.toml Normal file
View File

@ -0,0 +1,31 @@
[cmake]
version = "3.15"
cmkr-include = "cmake/cmkr.cmake"
[project]
cmake-before = """
# Set up a more familiar Visual Studio configuration
# Override these options with -DCMAKE_OPTION=Value
#
# See: https://cmake.org/cmake/help/latest/command/set.html#set-cache-entry
set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/DEBUG:FULL /INCREMENTAL:NO" CACHE STRING "")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "/DEBUG:FULL /INCREMENTAL:NO" CACHE STRING "")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE STRING "")
"""
name = "BetterRVA"
include-after = [
"cmake/CPM.cmake",
"cmake/x64dbg.cmake",
]
[target.BetterRVA]
type = "shared"
sources = [
"src/*.cpp",
"src/*.h",
]
cmake-after = """
x64dbg_plugin(${CMKR_TARGET})
"""

507
cmake/CPM.cmake Normal file
View File

@ -0,0 +1,507 @@
# CPM.cmake - CMake's missing package manager
# ===========================================
# See https://github.com/TheLartians/CPM.cmake for usage and update instructions.
#
# MIT License
# -----------
#[[
Copyright (c) 2019 Lars Melchior
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
set(CURRENT_CPM_VERSION 0.27.5)
if(CPM_DIRECTORY)
if(NOT CPM_DIRECTORY STREQUAL CMAKE_CURRENT_LIST_DIR)
if (CPM_VERSION VERSION_LESS CURRENT_CPM_VERSION)
message(AUTHOR_WARNING "${CPM_INDENT} \
A dependency is using a more recent CPM version (${CURRENT_CPM_VERSION}) than the current project (${CPM_VERSION}). \
It is recommended to upgrade CPM to the most recent version. \
See https://github.com/TheLartians/CPM.cmake for more information."
)
endif()
return()
endif()
get_property(CPM_INITIALIZED GLOBAL "" PROPERTY CPM_INITIALIZED SET)
if (CPM_INITIALIZED)
return()
endif()
endif()
set_property(GLOBAL PROPERTY CPM_INITIALIZED true)
option(CPM_USE_LOCAL_PACKAGES "Always try to use `find_package` to get dependencies" $ENV{CPM_USE_LOCAL_PACKAGES})
option(CPM_LOCAL_PACKAGES_ONLY "Only use `find_package` to get dependencies" $ENV{CPM_LOCAL_PACKAGES_ONLY})
option(CPM_DOWNLOAD_ALL "Always download dependencies from source" $ENV{CPM_DOWNLOAD_ALL})
option(CPM_DONT_UPDATE_MODULE_PATH "Don't update the module path to allow using find_package" $ENV{CPM_DONT_UPDATE_MODULE_PATH})
option(CPM_DONT_CREATE_PACKAGE_LOCK "Don't create a package lock file in the binary path" $ENV{CPM_DONT_CREATE_PACKAGE_LOCK})
option(CPM_INCLUDE_ALL_IN_PACKAGE_LOCK "Add all packages added through CPM.cmake to the package lock" $ENV{CPM_INCLUDE_ALL_IN_PACKAGE_LOCK})
set(CPM_VERSION ${CURRENT_CPM_VERSION} CACHE INTERNAL "")
set(CPM_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} CACHE INTERNAL "")
set(CPM_FILE ${CMAKE_CURRENT_LIST_FILE} CACHE INTERNAL "")
set(CPM_PACKAGES "" CACHE INTERNAL "")
set(CPM_DRY_RUN OFF CACHE INTERNAL "Don't download or configure dependencies (for testing)")
if(DEFINED ENV{CPM_SOURCE_CACHE})
set(CPM_SOURCE_CACHE_DEFAULT $ENV{CPM_SOURCE_CACHE})
else()
set(CPM_SOURCE_CACHE_DEFAULT OFF)
endif()
set(CPM_SOURCE_CACHE ${CPM_SOURCE_CACHE_DEFAULT} CACHE PATH "Directory to downlaod CPM dependencies")
if (NOT CPM_DONT_UPDATE_MODULE_PATH)
set(CPM_MODULE_PATH "${CMAKE_BINARY_DIR}/CPM_modules" CACHE INTERNAL "")
# remove old modules
FILE(REMOVE_RECURSE ${CPM_MODULE_PATH})
file(MAKE_DIRECTORY ${CPM_MODULE_PATH})
# locally added CPM modules should override global packages
set(CMAKE_MODULE_PATH "${CPM_MODULE_PATH};${CMAKE_MODULE_PATH}")
endif()
if (NOT CPM_DONT_CREATE_PACKAGE_LOCK)
set(CPM_PACKAGE_LOCK_FILE "${CMAKE_BINARY_DIR}/cpm-package-lock.cmake" CACHE INTERNAL "")
file(WRITE ${CPM_PACKAGE_LOCK_FILE} "# CPM Package Lock\n# This file should be committed to version control\n\n")
endif()
include(FetchContent)
include(CMakeParseArguments)
# Initialize logging prefix
if(NOT CPM_INDENT)
set(CPM_INDENT "CPM:")
endif()
function(cpm_find_package NAME VERSION)
string(REPLACE " " ";" EXTRA_ARGS "${ARGN}")
find_package(${NAME} ${VERSION} ${EXTRA_ARGS} QUIET)
if(${CPM_ARGS_NAME}_FOUND)
message(STATUS "${CPM_INDENT} using local package ${CPM_ARGS_NAME}@${VERSION}")
CPMRegisterPackage(${CPM_ARGS_NAME} "${VERSION}")
set(CPM_PACKAGE_FOUND YES PARENT_SCOPE)
else()
set(CPM_PACKAGE_FOUND NO PARENT_SCOPE)
endif()
endfunction()
# Create a custom FindXXX.cmake module for a CPM package
# This prevents `find_package(NAME)` from finding the system library
function(CPMCreateModuleFile Name)
if (NOT CPM_DONT_UPDATE_MODULE_PATH)
# erase any previous modules
FILE(WRITE ${CPM_MODULE_PATH}/Find${Name}.cmake "include(${CPM_FILE})\n${ARGN}\nset(${Name}_FOUND TRUE)")
endif()
endfunction()
# Find a package locally or fallback to CPMAddPackage
function(CPMFindPackage)
set(oneValueArgs
NAME
VERSION
GIT_TAG
FIND_PACKAGE_ARGUMENTS
)
cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "" ${ARGN})
if (NOT DEFINED CPM_ARGS_VERSION)
if (DEFINED CPM_ARGS_GIT_TAG)
cpm_get_version_from_git_tag("${CPM_ARGS_GIT_TAG}" CPM_ARGS_VERSION)
endif()
endif()
if (CPM_DOWNLOAD_ALL)
CPMAddPackage(${ARGN})
cpm_export_variables(${CPM_ARGS_NAME})
return()
endif()
CPMCheckIfPackageAlreadyAdded(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}" "${CPM_ARGS_OPTIONS}")
if (CPM_PACKAGE_ALREADY_ADDED)
cpm_export_variables(${CPM_ARGS_NAME})
return()
endif()
cpm_find_package(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}" ${CPM_ARGS_FIND_PACKAGE_ARGUMENTS})
if(NOT CPM_PACKAGE_FOUND)
CPMAddPackage(${ARGN})
cpm_export_variables(${CPM_ARGS_NAME})
endif()
endfunction()
# checks if a package has been added before
function(CPMCheckIfPackageAlreadyAdded CPM_ARGS_NAME CPM_ARGS_VERSION CPM_ARGS_OPTIONS)
if ("${CPM_ARGS_NAME}" IN_LIST CPM_PACKAGES)
CPMGetPackageVersion(${CPM_ARGS_NAME} CPM_PACKAGE_VERSION)
if("${CPM_PACKAGE_VERSION}" VERSION_LESS "${CPM_ARGS_VERSION}")
message(WARNING "${CPM_INDENT} requires a newer version of ${CPM_ARGS_NAME} (${CPM_ARGS_VERSION}) than currently included (${CPM_PACKAGE_VERSION}).")
endif()
if (CPM_ARGS_OPTIONS)
foreach(OPTION ${CPM_ARGS_OPTIONS})
cpm_parse_option(${OPTION})
if(NOT "${${OPTION_KEY}}" STREQUAL "${OPTION_VALUE}")
message(WARNING "${CPM_INDENT} ignoring package option for ${CPM_ARGS_NAME}: ${OPTION_KEY} = ${OPTION_VALUE} (${${OPTION_KEY}})")
endif()
endforeach()
endif()
cpm_get_fetch_properties(${CPM_ARGS_NAME})
SET(${CPM_ARGS_NAME}_ADDED NO)
SET(CPM_PACKAGE_ALREADY_ADDED YES PARENT_SCOPE)
cpm_export_variables(${CPM_ARGS_NAME})
else()
SET(CPM_PACKAGE_ALREADY_ADDED NO PARENT_SCOPE)
endif()
endfunction()
# Download and add a package from source
function(CPMAddPackage)
set(oneValueArgs
NAME
FORCE
VERSION
GIT_TAG
DOWNLOAD_ONLY
GITHUB_REPOSITORY
GITLAB_REPOSITORY
GIT_REPOSITORY
SOURCE_DIR
DOWNLOAD_COMMAND
FIND_PACKAGE_ARGUMENTS
NO_CACHE
GIT_SHALLOW
)
set(multiValueArgs
OPTIONS
)
cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}")
# Set default values for arguments
if (NOT DEFINED CPM_ARGS_VERSION)
if (DEFINED CPM_ARGS_GIT_TAG)
cpm_get_version_from_git_tag("${CPM_ARGS_GIT_TAG}" CPM_ARGS_VERSION)
endif()
endif()
if(CPM_ARGS_DOWNLOAD_ONLY)
set(DOWNLOAD_ONLY ${CPM_ARGS_DOWNLOAD_ONLY})
else()
set(DOWNLOAD_ONLY NO)
endif()
if (DEFINED CPM_ARGS_GITHUB_REPOSITORY)
set(CPM_ARGS_GIT_REPOSITORY "https://github.com/${CPM_ARGS_GITHUB_REPOSITORY}.git")
endif()
if (DEFINED CPM_ARGS_GITLAB_REPOSITORY)
set(CPM_ARGS_GIT_REPOSITORY "https://gitlab.com/${CPM_ARGS_GITLAB_REPOSITORY}.git")
endif()
if (DEFINED CPM_ARGS_GIT_REPOSITORY)
list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS GIT_REPOSITORY ${CPM_ARGS_GIT_REPOSITORY})
if (NOT DEFINED CPM_ARGS_GIT_TAG)
set(CPM_ARGS_GIT_TAG v${CPM_ARGS_VERSION})
endif()
endif()
if (DEFINED CPM_ARGS_GIT_TAG)
list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS GIT_TAG ${CPM_ARGS_GIT_TAG})
# If GIT_SHALLOW is explicitly specified, honor the value.
if (DEFINED CPM_ARGS_GIT_SHALLOW)
list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS GIT_SHALLOW ${CPM_ARGS_GIT_SHALLOW})
endif()
endif()
# Check if package has been added before
CPMCheckIfPackageAlreadyAdded(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}" "${CPM_ARGS_OPTIONS}")
if (CPM_PACKAGE_ALREADY_ADDED)
cpm_export_variables(${CPM_ARGS_NAME})
return()
endif()
# Check for manual overrides
if (NOT CPM_ARGS_FORCE AND NOT "${CPM_${CPM_ARGS_NAME}_SOURCE}" STREQUAL "")
set(PACKAGE_SOURCE ${CPM_${CPM_ARGS_NAME}_SOURCE})
set(CPM_${CPM_ARGS_NAME}_SOURCE "")
CPMAddPackage(
NAME ${CPM_ARGS_NAME}
SOURCE_DIR ${PACKAGE_SOURCE}
FORCE True
OPTIONS ${CPM_ARGS_OPTIONS}
)
cpm_export_variables(${CPM_ARGS_NAME})
return()
endif()
# Check for available declaration
if (NOT CPM_ARGS_FORCE AND NOT "${CPM_DECLARATION_${CPM_ARGS_NAME}}" STREQUAL "")
set(declaration ${CPM_DECLARATION_${CPM_ARGS_NAME}})
set(CPM_DECLARATION_${CPM_ARGS_NAME} "")
CPMAddPackage(${declaration})
cpm_export_variables(${CPM_ARGS_NAME})
# checking again to ensure version and option compatibility
CPMCheckIfPackageAlreadyAdded(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}" "${CPM_ARGS_OPTIONS}")
return()
endif()
if(CPM_USE_LOCAL_PACKAGES OR CPM_LOCAL_PACKAGES_ONLY)
cpm_find_package(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}" ${CPM_ARGS_FIND_PACKAGE_ARGUMENTS})
if(CPM_PACKAGE_FOUND)
cpm_export_variables(${CPM_ARGS_NAME})
return()
endif()
if(CPM_LOCAL_PACKAGES_ONLY)
message(SEND_ERROR "CPM: ${CPM_ARGS_NAME} not found via find_package(${CPM_ARGS_NAME} ${CPM_ARGS_VERSION})")
endif()
endif()
CPMRegisterPackage("${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}")
if (CPM_ARGS_OPTIONS)
foreach(OPTION ${CPM_ARGS_OPTIONS})
cpm_parse_option(${OPTION})
set(${OPTION_KEY} ${OPTION_VALUE} CACHE INTERNAL "")
endforeach()
endif()
if (DEFINED CPM_ARGS_GIT_TAG)
set(PACKAGE_INFO "${CPM_ARGS_GIT_TAG}")
elseif (DEFINED CPM_ARGS_SOURCE_DIR)
set(PACKAGE_INFO "${CPM_ARGS_SOURCE_DIR}")
else()
set(PACKAGE_INFO "${CPM_ARGS_VERSION}")
endif()
if (DEFINED CPM_ARGS_DOWNLOAD_COMMAND)
list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS DOWNLOAD_COMMAND ${CPM_ARGS_DOWNLOAD_COMMAND})
elseif (DEFINED CPM_ARGS_SOURCE_DIR)
list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS SOURCE_DIR ${CPM_ARGS_SOURCE_DIR})
elseif (CPM_SOURCE_CACHE AND NOT CPM_ARGS_NO_CACHE)
string(TOLOWER ${CPM_ARGS_NAME} lower_case_name)
set(origin_parameters ${CPM_ARGS_UNPARSED_ARGUMENTS})
list(SORT origin_parameters)
string(SHA1 origin_hash "${origin_parameters}")
set(download_directory ${CPM_SOURCE_CACHE}/${lower_case_name}/${origin_hash})
list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS SOURCE_DIR ${download_directory})
if (EXISTS ${download_directory})
# disable the download command to allow offline builds
list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS DOWNLOAD_COMMAND "${CMAKE_COMMAND}")
set(PACKAGE_INFO "${download_directory}")
else()
# Enable shallow clone when GIT_TAG is not a commit hash.
# Our guess may not be accurate, but it should guarantee no commit hash get mis-detected.
if (NOT DEFINED CPM_ARGS_GIT_SHALLOW)
cpm_is_git_tag_commit_hash("${CPM_ARGS_GIT_TAG}" IS_HASH)
if (NOT ${IS_HASH})
list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS GIT_SHALLOW TRUE)
endif()
endif()
# remove timestamps so CMake will re-download the dependency
file(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/_deps/${lower_case_name}-subbuild)
set(PACKAGE_INFO "${PACKAGE_INFO} -> ${download_directory}")
endif()
endif()
CPMCreateModuleFile(${CPM_ARGS_NAME} "CPMAddPackage(${ARGN})")
if (CPM_PACKAGE_LOCK_ENABLED)
if ((CPM_ARGS_VERSION AND NOT CPM_ARGS_SOURCE_DIR) OR CPM_INCLUDE_ALL_IN_PACKAGE_LOCK)
cpm_add_to_package_lock(${CPM_ARGS_NAME} "${ARGN}")
elseif(CPM_ARGS_SOURCE_DIR)
cpm_add_comment_to_package_lock(${CPM_ARGS_NAME} "local directory")
else()
cpm_add_comment_to_package_lock(${CPM_ARGS_NAME} "${ARGN}")
endif()
endif()
cpm_declare_fetch("${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}" "${PACKAGE_INFO}" "${CPM_ARGS_UNPARSED_ARGUMENTS}")
cpm_fetch_package("${CPM_ARGS_NAME}" "${DOWNLOAD_ONLY}")
cpm_get_fetch_properties("${CPM_ARGS_NAME}")
SET(${CPM_ARGS_NAME}_ADDED YES)
cpm_export_variables("${CPM_ARGS_NAME}")
endfunction()
# Fetch a previously declared package
macro(CPMGetPackage Name)
if (DEFINED "CPM_DECLARATION_${Name}")
CPMAddPackage(
NAME ${Name}
)
else()
message(SEND_ERROR "Cannot retrieve package ${Name}: no declaration available")
endif()
endmacro()
# export variables available to the caller to the parent scope
# expects ${CPM_ARGS_NAME} to be set
macro(cpm_export_variables name)
SET(${name}_SOURCE_DIR "${${name}_SOURCE_DIR}" PARENT_SCOPE)
SET(${name}_BINARY_DIR "${${name}_BINARY_DIR}" PARENT_SCOPE)
SET(${name}_ADDED "${${name}_ADDED}" PARENT_SCOPE)
endmacro()
# declares a package, so that any call to CPMAddPackage for the
# package name will use these arguments instead.
# Previous declarations will not be overriden.
macro(CPMDeclarePackage Name)
if (NOT DEFINED "CPM_DECLARATION_${Name}")
set("CPM_DECLARATION_${Name}" "${ARGN}")
endif()
endmacro()
function(cpm_add_to_package_lock Name)
if (NOT CPM_DONT_CREATE_PACKAGE_LOCK)
file(APPEND ${CPM_PACKAGE_LOCK_FILE} "# ${Name}\nCPMDeclarePackage(${Name} \"${ARGN}\")\n")
endif()
endfunction()
function(cpm_add_comment_to_package_lock Name)
if (NOT CPM_DONT_CREATE_PACKAGE_LOCK)
file(APPEND ${CPM_PACKAGE_LOCK_FILE} "# ${Name} (unversioned)\n# CPMDeclarePackage(${Name} \"${ARGN}\")\n")
endif()
endfunction()
# includes the package lock file if it exists and creates a target
# `cpm-write-package-lock` to update it
macro(CPMUsePackageLock file)
if (NOT CPM_DONT_CREATE_PACKAGE_LOCK)
get_filename_component(CPM_ABSOLUTE_PACKAGE_LOCK_PATH ${file} ABSOLUTE)
if(EXISTS ${CPM_ABSOLUTE_PACKAGE_LOCK_PATH})
include(${CPM_ABSOLUTE_PACKAGE_LOCK_PATH})
endif()
if (NOT TARGET cpm-update-package-lock)
add_custom_target(cpm-update-package-lock COMMAND ${CMAKE_COMMAND} -E copy ${CPM_PACKAGE_LOCK_FILE} ${CPM_ABSOLUTE_PACKAGE_LOCK_PATH})
endif()
set(CPM_PACKAGE_LOCK_ENABLED true)
endif()
endmacro()
# registers a package that has been added to CPM
function(CPMRegisterPackage PACKAGE VERSION)
list(APPEND CPM_PACKAGES ${PACKAGE})
set(CPM_PACKAGES ${CPM_PACKAGES} CACHE INTERNAL "")
set("CPM_PACKAGE_${PACKAGE}_VERSION" ${VERSION} CACHE INTERNAL "")
endfunction()
# retrieve the current version of the package to ${OUTPUT}
function(CPMGetPackageVersion PACKAGE OUTPUT)
set(${OUTPUT} "${CPM_PACKAGE_${PACKAGE}_VERSION}" PARENT_SCOPE)
endfunction()
# declares a package in FetchContent_Declare
function (cpm_declare_fetch PACKAGE VERSION INFO)
message(STATUS "${CPM_INDENT} adding package ${PACKAGE}@${VERSION} (${INFO})")
if (${CPM_DRY_RUN})
message(STATUS "${CPM_INDENT} package not declared (dry run)")
return()
endif()
FetchContent_Declare(${PACKAGE}
${ARGN}
)
endfunction()
# returns properties for a package previously defined by cpm_declare_fetch
function (cpm_get_fetch_properties PACKAGE)
if (${CPM_DRY_RUN})
return()
endif()
FetchContent_GetProperties(${PACKAGE})
string(TOLOWER ${PACKAGE} lpackage)
SET(${PACKAGE}_SOURCE_DIR "${${lpackage}_SOURCE_DIR}" PARENT_SCOPE)
SET(${PACKAGE}_BINARY_DIR "${${lpackage}_BINARY_DIR}" PARENT_SCOPE)
endfunction()
# downloads a previously declared package via FetchContent
function (cpm_fetch_package PACKAGE DOWNLOAD_ONLY)
if (${CPM_DRY_RUN})
message(STATUS "${CPM_INDENT} package ${PACKAGE} not fetched (dry run)")
return()
endif()
if(DOWNLOAD_ONLY)
FetchContent_GetProperties(${PACKAGE})
if(NOT ${PACKAGE}_POPULATED)
FetchContent_Populate(${PACKAGE})
endif()
else()
set(CPM_OLD_INDENT "${CPM_INDENT}")
set(CPM_INDENT "${CPM_INDENT} ${PACKAGE}:")
FetchContent_MakeAvailable(${PACKAGE})
set(CPM_INDENT "${CPM_OLD_INDENT}")
endif()
endfunction()
# splits a package option
function(cpm_parse_option OPTION)
string(REGEX MATCH "^[^ ]+" OPTION_KEY ${OPTION})
string(LENGTH ${OPTION} OPTION_LENGTH)
string(LENGTH ${OPTION_KEY} OPTION_KEY_LENGTH)
if (OPTION_KEY_LENGTH STREQUAL OPTION_LENGTH)
# no value for key provided, assume user wants to set option to "ON"
set(OPTION_VALUE "ON")
else()
math(EXPR OPTION_KEY_LENGTH "${OPTION_KEY_LENGTH}+1")
string(SUBSTRING ${OPTION} "${OPTION_KEY_LENGTH}" "-1" OPTION_VALUE)
endif()
set(OPTION_KEY "${OPTION_KEY}" PARENT_SCOPE)
set(OPTION_VALUE "${OPTION_VALUE}" PARENT_SCOPE)
endfunction()
# guesses the package version from a git tag
function(cpm_get_version_from_git_tag GIT_TAG RESULT)
string(LENGTH ${GIT_TAG} length)
if (length EQUAL 40)
# GIT_TAG is probably a git hash
SET(${RESULT} 0 PARENT_SCOPE)
else()
string(REGEX MATCH "v?([0123456789.]*).*" _ ${GIT_TAG})
SET(${RESULT} ${CMAKE_MATCH_1} PARENT_SCOPE)
endif()
endfunction()
# guesses if the git tag is a commit hash or an actual tag or a branch nane.
function(cpm_is_git_tag_commit_hash GIT_TAG RESULT)
string(LENGTH "${GIT_TAG}" length)
# full hash has 40 characters, and short hash has at least 7 characters.
if (length LESS 7 OR length GREATER 40)
SET(${RESULT} 0 PARENT_SCOPE)
else()
if (${GIT_TAG} MATCHES "^[a-fA-F0-9]+$")
SET(${RESULT} 1 PARENT_SCOPE)
else()
SET(${RESULT} 0 PARENT_SCOPE)
endif()
endif()
endfunction()

163
cmake/cmkr.cmake Normal file
View File

@ -0,0 +1,163 @@
include_guard()
# Change these defaults to point to your infrastructure if desired
set(CMKR_REPO "https://github.com/build-cpp/cmkr" CACHE STRING "cmkr git repository" FORCE)
set(CMKR_TAG "archive_7c7144b1" CACHE STRING "cmkr git tag (this needs to be available forever)" FORCE)
# Set these from the command line to customize for development/debugging purposes
set(CMKR_EXECUTABLE "" CACHE FILEPATH "cmkr executable")
set(CMKR_SKIP_GENERATION OFF CACHE BOOL "skip automatic cmkr generation")
# Disable cmkr if generation is disabled
if(DEFINED ENV{CI} OR CMKR_SKIP_GENERATION OR CMKR_BUILD_SKIP_GENERATION)
message(STATUS "[cmkr] Skipping automatic cmkr generation")
unset(CMKR_BUILD_SKIP_GENERATION CACHE)
macro(cmkr)
endmacro()
return()
endif()
# Disable cmkr if no cmake.toml file is found
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake.toml")
message(AUTHOR_WARNING "[cmkr] Not found: ${CMAKE_CURRENT_SOURCE_DIR}/cmake.toml")
macro(cmkr)
endmacro()
return()
endif()
# Convert a Windows native path to CMake path
if(CMKR_EXECUTABLE MATCHES "\\\\")
string(REPLACE "\\" "/" CMKR_EXECUTABLE_CMAKE "${CMKR_EXECUTABLE}")
set(CMKR_EXECUTABLE "${CMKR_EXECUTABLE_CMAKE}" CACHE FILEPATH "" FORCE)
unset(CMKR_EXECUTABLE_CMAKE)
endif()
# Helper macro to execute a process (COMMAND_ERROR_IS_FATAL ANY is 3.19 and higher)
function(cmkr_exec)
execute_process(COMMAND ${ARGV} RESULT_VARIABLE CMKR_EXEC_RESULT)
if(NOT CMKR_EXEC_RESULT EQUAL 0)
message(FATAL_ERROR "cmkr_exec(${ARGV}) failed (exit code ${CMKR_EXEC_RESULT})")
endif()
endfunction()
# Windows-specific hack (CMAKE_EXECUTABLE_PREFIX is not set at the moment)
if(WIN32)
set(CMKR_EXECUTABLE_NAME "cmkr.exe")
else()
set(CMKR_EXECUTABLE_NAME "cmkr")
endif()
# Use cached cmkr if found
set(CMKR_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/_cmkr_${CMKR_TAG}")
set(CMKR_CACHED_EXECUTABLE "${CMKR_DIRECTORY}/bin/${CMKR_EXECUTABLE_NAME}")
if(NOT CMKR_CACHED_EXECUTABLE STREQUAL CMKR_EXECUTABLE AND CMKR_EXECUTABLE MATCHES "^${CMAKE_CURRENT_BINARY_DIR}/_cmkr")
message(AUTHOR_WARNING "[cmkr] Upgrading '${CMKR_EXECUTABLE}' to '${CMKR_CACHED_EXECUTABLE}'")
unset(CMKR_EXECUTABLE CACHE)
endif()
if(CMKR_EXECUTABLE AND EXISTS "${CMKR_EXECUTABLE}")
message(VERBOSE "[cmkr] Found cmkr: '${CMKR_EXECUTABLE}'")
elseif(CMKR_EXECUTABLE AND NOT CMKR_EXECUTABLE STREQUAL CMKR_CACHED_EXECUTABLE)
message(FATAL_ERROR "[cmkr] '${CMKR_EXECUTABLE}' not found")
else()
set(CMKR_EXECUTABLE "${CMKR_CACHED_EXECUTABLE}" CACHE FILEPATH "Full path to cmkr executable" FORCE)
message(VERBOSE "[cmkr] Bootstrapping '${CMKR_EXECUTABLE}'")
message(STATUS "[cmkr] Fetching cmkr...")
if(EXISTS "${CMKR_DIRECTORY}")
cmkr_exec("${CMAKE_COMMAND}" -E rm -rf "${CMKR_DIRECTORY}")
endif()
find_package(Git QUIET REQUIRED)
cmkr_exec("${GIT_EXECUTABLE}"
clone
--config advice.detachedHead=false
--branch ${CMKR_TAG}
--depth 1
${CMKR_REPO}
"${CMKR_DIRECTORY}"
)
message(STATUS "[cmkr] Building cmkr...")
cmkr_exec("${CMAKE_COMMAND}"
--no-warn-unused-cli
"${CMKR_DIRECTORY}"
"-B${CMKR_DIRECTORY}/build"
"-DCMAKE_BUILD_TYPE=Release"
"-DCMAKE_INSTALL_PREFIX=${CMKR_DIRECTORY}"
"-DCMKR_GENERATE_DOCUMENTATION=OFF"
)
cmkr_exec("${CMAKE_COMMAND}"
--build "${CMKR_DIRECTORY}/build"
--config Release
--parallel
)
cmkr_exec("${CMAKE_COMMAND}"
--install "${CMKR_DIRECTORY}/build"
--config Release
--prefix "${CMKR_DIRECTORY}"
--component cmkr
)
if(NOT EXISTS ${CMKR_EXECUTABLE})
message(FATAL_ERROR "[cmkr] Failed to bootstrap '${CMKR_EXECUTABLE}'")
endif()
cmkr_exec("${CMKR_EXECUTABLE}" version)
message(STATUS "[cmkr] Bootstrapped ${CMKR_EXECUTABLE}")
endif()
execute_process(COMMAND "${CMKR_EXECUTABLE}" version
RESULT_VARIABLE CMKR_EXEC_RESULT
)
if(NOT CMKR_EXEC_RESULT EQUAL 0)
message(FATAL_ERROR "[cmkr] Failed to get version, try clearing the cache and rebuilding")
endif()
# This is the macro that contains black magic
macro(cmkr)
# When this macro is called from the generated file, fake some internal CMake variables
get_source_file_property(CMKR_CURRENT_LIST_FILE "${CMAKE_CURRENT_LIST_FILE}" CMKR_CURRENT_LIST_FILE)
if(CMKR_CURRENT_LIST_FILE)
set(CMAKE_CURRENT_LIST_FILE "${CMKR_CURRENT_LIST_FILE}")
get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
endif()
# File-based include guard (include_guard is not documented to work)
get_source_file_property(CMKR_INCLUDE_GUARD "${CMAKE_CURRENT_LIST_FILE}" CMKR_INCLUDE_GUARD)
if(NOT CMKR_INCLUDE_GUARD)
set_source_files_properties("${CMAKE_CURRENT_LIST_FILE}" PROPERTIES CMKR_INCLUDE_GUARD TRUE)
file(SHA256 "${CMAKE_CURRENT_LIST_FILE}" CMKR_LIST_FILE_SHA256_PRE)
# Generate CMakeLists.txt
cmkr_exec("${CMKR_EXECUTABLE}" gen
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
)
file(SHA256 "${CMAKE_CURRENT_LIST_FILE}" CMKR_LIST_FILE_SHA256_POST)
# Delete the temporary file if it was left for some reason
set(CMKR_TEMP_FILE "${CMAKE_CURRENT_SOURCE_DIR}/CMakerLists.txt")
if(EXISTS "${CMKR_TEMP_FILE}")
file(REMOVE "${CMKR_TEMP_FILE}")
endif()
if(NOT CMKR_LIST_FILE_SHA256_PRE STREQUAL CMKR_LIST_FILE_SHA256_POST)
# Copy the now-generated CMakeLists.txt to CMakerLists.txt
# This is done because you cannot include() a file you are currently in
configure_file(CMakeLists.txt "${CMKR_TEMP_FILE}" COPYONLY)
# Add the macro required for the hack at the start of the cmkr macro
set_source_files_properties("${CMKR_TEMP_FILE}" PROPERTIES
CMKR_CURRENT_LIST_FILE "${CMAKE_CURRENT_LIST_FILE}"
)
# 'Execute' the newly-generated CMakeLists.txt
include("${CMKR_TEMP_FILE}")
# Delete the generated file
file(REMOVE "${CMKR_TEMP_FILE}")
# Do not execute the rest of the original CMakeLists.txt
return()
endif()
# Resume executing the unmodified CMakeLists.txt
endif()
endmacro()

44
cmake/x64dbg.cmake Normal file
View File

@ -0,0 +1,44 @@
CPMAddPackage(
NAME x64dbg
URL https://downloads.sourceforge.net/project/x64dbg/snapshots/snapshot_2021-11-20_10-12.zip
URL_HASH SHA1=C75AC6BA7E7E5AB60632EED5648254E4BEF11465
DOWNLOAD_ONLY ON
)
if(x64dbg_ADDED)
if(NOT TARGET x64dbg)
file(GLOB_RECURSE HEADERS CONFIGURE_DEPENDS ${x64dbg_SOURCE_DIR}/pluginsdk/*.h)
add_custom_target(x64dbg-sdk SOURCES ${HEADERS})
source_group(TREE ${x64dbg_SOURCE_DIR} FILES ${HEADERS})
add_library(x64dbg INTERFACE)
target_include_directories(x64dbg INTERFACE ${x64dbg_SOURCE_DIR})
target_link_directories(x64dbg INTERFACE ${x64dbg_SOURCE_DIR})
endif()
function(x64dbg_plugin target)
if(NOT TARGET ${target})
# Add plugin dll
add_library(${target} SHARED ${ARGN})
# Group source files
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${ARGN})
endif()
# Change extension
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set_target_properties(${target} PROPERTIES SUFFIX ".dp64")
else()
set_target_properties(${target} PROPERTIES SUFFIX ".dp32")
endif()
# Link to the x64dbg SDK
target_link_libraries(${target} PRIVATE x64dbg)
# Set plugin name based on the target
target_compile_definitions(${target} PRIVATE "-DPLUGIN_NAME=\"${target}\"")
# Support PluginDevHelper
add_custom_command(TARGET ${target} PRE_LINK COMMAND if exist "\"$(SolutionDir)PluginDevBuildTool.exe\"" "(\"$(SolutionDir)PluginDevBuildTool.exe\"" unload "\"$(TargetPath)\")" else (echo Copy PluginDevTool.exe next to the .sln to automatically reload plugins when building))
add_custom_command(TARGET ${target} POST_BUILD COMMAND if exist "\"$(SolutionDir)PluginDevBuildTool.exe\"" ("\"$(SolutionDir)PluginDevBuildTool.exe\"" reload "\"$(TargetPath)\""))
endfunction()
endif()

2111
src/icons.h Normal file

File diff suppressed because it is too large Load Diff

171
src/plugin.cpp Normal file
View File

@ -0,0 +1,171 @@
#include "plugin.h"
namespace util {
// @note: @es3n1n: Get current window based on context menu item that was clicked on
//
GUISELECTIONTYPE get_window_for_ctx_item( const e_menu_ctx_item it ) {
if ( it >= e_menu_ctx_item::DISASM_BEGIN &&
it <= e_menu_ctx_item::DISASM_END )
return GUISELECTIONTYPE::GUI_DISASSEMBLY;
if ( it >= e_menu_ctx_item::DUMP_BEGIN &&
it <= e_menu_ctx_item::DUMP_END )
return GUISELECTIONTYPE::GUI_DUMP;
dprintf( "Error! Unknown ctx item %d\n", it );
return GUISELECTIONTYPE::GUI_DISASSEMBLY;
}
// @note: @es3n1n: Format and copy data to clipboard
//
void set_clipboard_data( const char* fmt, ... ) {
char buffer[ 1024 ];
va_list va;
va_start( va, fmt );
_vsnprintf_s( buffer, 1024, fmt, va );
va_end( va );
dprintf( "Copying '%s'\n", buffer );
auto txt_handle = GlobalAlloc( GHND | GMEM_DDESHARE, std::strlen( buffer ) );
if ( !txt_handle ) {
dprintf( "Error! Unable to allocate handle for text\n" );
return;
}
if ( !OpenClipboard( NULL ) ) {
dprintf( "Error! Unable to open clipboard\n" );
GlobalFree( txt_handle );
return;
}
SetClipboardData( CF_TEXT, txt_handle );
CloseClipboard( );
GlobalFree( txt_handle );
}
}
namespace core {
// @note: @es3n1n: Resolving region base address and current address
// using x64dbg script api
//
selected_addr_t get_selected_addr( const e_menu_ctx_item item ) {
if ( !DbgIsDebugging( ) )
return { false, 0, 0 };
SELECTIONDATA sel;
GuiSelectionGet( util::get_window_for_ctx_item( item ), &sel );
if ( !sel.start )
return { false, 0, 0 };
// @note: @es3n1n: If base address is inside of some loaded module
//
std::uintptr_t mod_base = Script::Module::BaseFromAddr( sel.start );
if ( mod_base )
return { true, mod_base, sel.start };
return { true, Script::Memory::GetBase( sel.start ), sel.start };
}
}
namespace handlers {
// @note: @es3n1n: Context menu "Copy RVA" handler
//
void copy_rva( const e_menu_ctx_item item ) {
auto result = core::get_selected_addr( item );
if ( !result.m_success ) {
dprintf( "Error! Address or base was invalid\n" );
return;
}
util::set_clipboard_data(
"0x%p",
reinterpret_cast< void* >( result.m_address - result.m_base )
);
}
// @note: @es3n1n: Context menu "Copy Base + RVA" handler
//
static void copy_base_plus_rva( const e_menu_ctx_item item ) {
auto result = core::get_selected_addr( item );
if ( !result.m_success ) {
dprintf( "Error! Address or base was invalid\n" );
return;
}
util::set_clipboard_data(
"0x%p + 0x%p",
reinterpret_cast< void* >( result.m_base ),
reinterpret_cast< void* >( result.m_address - result.m_base )
);
}
// @note: @es3n1n: Context menu "Copy VA - Base" handler
//
static void copy_va_minus_base( const e_menu_ctx_item item ) {
auto result = core::get_selected_addr( item );
if ( !result.m_success ) {
dprintf( "Error! Address or base was invalid\n" );
return;
}
util::set_clipboard_data(
"0x%p - 0x%p",
reinterpret_cast< void* >( result.m_address ),
reinterpret_cast< void* >( result.m_base )
);
}
}
namespace plugin {
// @note: @es3n1n: Init context menu buttons
//
void initial( ) {
ICONDATA clown_icon;
clown_icon.data = icons::clown;
clown_icon.size = sizeof( icons::clown );
_plugin_menuseticon( g::disasm_menu, &clown_icon );
_plugin_menuseticon( g::dump_menu, &clown_icon );
#define ADD_ENTRY( en, name ) _plugin_menuaddentry( g::disasm_menu, static_cast< std::uint32_t >( e_menu_ctx_item::##en##_disasm ), "&" name ); \
_plugin_menuaddentry( g::dump_menu, static_cast< std::uint32_t >( e_menu_ctx_item::##en##_dump ), "&" name );
ADD_ENTRY( copy_rva, "Copy RVA" );
ADD_ENTRY( copy_base_plus_rva, "Copy Base + RVA" );
ADD_ENTRY( copy_va_minus_base, "Copy VA - Base" );
#undef ADD_ENTRY
dprintf( "Initialized! Plugin version: %d. Author: https://github.com/es3n1n\n", PLUGIN_VERSION );
}
// @note: @es3n1n: Handle context menu button click
//
void menu_click( PLUG_CB_MENUENTRY* info ) {
const auto entry = static_cast< e_menu_ctx_item >( info->hEntry );
switch ( entry ) {
case e_menu_ctx_item::copy_rva_disasm:
case e_menu_ctx_item::copy_rva_dump:
return handlers::copy_rva( entry );
case e_menu_ctx_item::copy_base_plus_rva_disasm:
case e_menu_ctx_item::copy_base_plus_rva_dump:
return handlers::copy_base_plus_rva( entry );
case e_menu_ctx_item::copy_va_minus_base_disasm:
case e_menu_ctx_item::copy_va_minus_base_dump:
return handlers::copy_va_minus_base( entry );
}
}
}

47
src/plugin.h Normal file
View File

@ -0,0 +1,47 @@
#pragma once
#include "pluginmain.h"
#include "icons.h"
// @note: @es3n1n: Context item ids
// Still kinda sucks that we need to register each
// unique ctx item to each context menu, but whatever :shrug:
//
enum class e_menu_ctx_item : std::uint32_t {
DISASM_BEGIN = 0,
copy_rva_disasm,
copy_base_plus_rva_disasm,
copy_va_minus_base_disasm,
DISASM_END,
DUMP_BEGIN,
copy_rva_dump,
copy_base_plus_rva_dump,
copy_va_minus_base_dump,
DUMP_END,
};
namespace util {
GUISELECTIONTYPE get_window_for_ctx_item( const e_menu_ctx_item it );
void set_clipboard_data( const char* fmt, ... );
}
namespace core {
struct selected_addr_t {
public:
bool m_success = false;
std::uintptr_t m_base = 0x0;
std::uintptr_t m_address = 0x0;
};
selected_addr_t get_selected_addr( const e_menu_ctx_item item );
}
namespace handlers {
void copy_rva( const e_menu_ctx_item item );
void copy_base_plus_rva( const e_menu_ctx_item item );
void copy_va_minus_base( const e_menu_ctx_item item );
}
namespace plugin {
void initial( );
void menu_click( PLUG_CB_MENUENTRY* info );
}

35
src/pluginmain.cpp Normal file
View File

@ -0,0 +1,35 @@
#include "pluginmain.h"
#include "plugin.h"
namespace g {
int disasm_menu = 0;
int dump_menu = 0;
}
PLUGIN_EXPORT bool pluginit( PLUG_INITSTRUCT* initStruct ) {
initStruct->pluginVersion = PLUGIN_VERSION;
initStruct->sdkVersion = PLUG_SDKVERSION;
strncpy_s( initStruct->pluginName, PLUGIN_NAME, _TRUNCATE );
return true;
}
PLUGIN_EXPORT bool plugstop( ) {
_plugin_menuclear( g::disasm_menu );
_plugin_menuclear( g::dump_menu );
return true;
}
PLUGIN_EXPORT void plugsetup( PLUG_SETUPSTRUCT* setupStruct ) {
g::disasm_menu = setupStruct->hMenuDisasm;
g::dump_menu = setupStruct->hMenuDump;
plugin::initial( );
}
PLUGIN_EXPORT void CBMENUENTRY( CBTYPE cbType, PLUG_CB_MENUENTRY* info ) {
plugin::menu_click( info );
}

65
src/pluginmain.h Normal file
View File

@ -0,0 +1,65 @@
#pragma once
// Plugin information
#ifndef PLUGIN_NAME
#error You need to define PLUGIN_NAME
#endif // PLUGIN_NAME
#define PLUGIN_VERSION 1
#include "pluginsdk/bridgemain.h"
#include "pluginsdk/_plugins.h"
#include "pluginsdk/_scriptapi_argument.h"
#include "pluginsdk/_scriptapi_assembler.h"
#include "pluginsdk/_scriptapi_bookmark.h"
#include "pluginsdk/_scriptapi_comment.h"
#include "pluginsdk/_scriptapi_debug.h"
#include "pluginsdk/_scriptapi_flag.h"
#include "pluginsdk/_scriptapi_function.h"
#include "pluginsdk/_scriptapi_gui.h"
#include "pluginsdk/_scriptapi_label.h"
#include "pluginsdk/_scriptapi_memory.h"
#include "pluginsdk/_scriptapi_misc.h"
#include "pluginsdk/_scriptapi_module.h"
#include "pluginsdk/_scriptapi_pattern.h"
#include "pluginsdk/_scriptapi_register.h"
#include "pluginsdk/_scriptapi_stack.h"
#include "pluginsdk/_scriptapi_symbol.h"
#include "pluginsdk/DeviceNameResolver/DeviceNameResolver.h"
#include "pluginsdk/jansson/jansson.h"
#include "pluginsdk/lz4/lz4file.h"
#include "pluginsdk/TitanEngine/TitanEngine.h"
#include "pluginsdk/XEDParse/XEDParse.h"
#ifdef _WIN64
#pragma comment(lib, "pluginsdk/x64dbg.lib")
#pragma comment(lib, "pluginsdk/x64bridge.lib")
#pragma comment(lib, "pluginsdk/DeviceNameResolver/DeviceNameResolver_x64.lib")
#pragma comment(lib, "pluginsdk/jansson/jansson_x64.lib")
#pragma comment(lib, "pluginsdk/lz4/lz4_x64.lib")
#pragma comment(lib, "pluginsdk/TitanEngine/TitanEngine_x64.lib")
#pragma comment(lib, "pluginsdk/XEDParse/XEDParse_x64.lib")
#else
#pragma comment(lib, "pluginsdk/x32dbg.lib")
#pragma comment(lib, "pluginsdk/x32bridge.lib")
#pragma comment(lib, "pluginsdk/DeviceNameResolver/DeviceNameResolver_x86.lib")
#pragma comment(lib, "pluginsdk/jansson/jansson_x86.lib")
#pragma comment(lib, "pluginsdk/lz4/lz4_x86.lib")
#pragma comment(lib, "pluginsdk/TitanEngine/TitanEngine_x86.lib")
#pragma comment(lib, "pluginsdk/XEDParse/XEDParse_x86.lib")
#endif //_WIN64
#define dprintf( x, ... ) _plugin_logprintf( "[" PLUGIN_NAME "] " x, __VA_ARGS__ )
#define PLUGIN_EXPORT extern "C" __declspec( dllexport )
// @note: @es3n1n: Some global data that would be stored after initial process
//
namespace g {
extern int disasm_menu;
extern int dump_menu;
}