mirror of
https://github.com/CitrusIce/ksc4cpp
synced 2026-08-09 12:03:42 +00:00
init
This commit is contained in:
+353
@@ -0,0 +1,353 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
.vscode/
|
||||
build/
|
||||
@@ -0,0 +1,87 @@
|
||||
cmake_minimum_required(VERSION 3.25)
|
||||
project(ksc4cpp)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
|
||||
find_package(WDK REQUIRED)
|
||||
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/test")
|
||||
|
||||
|
||||
|
||||
# add include directories
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
|
||||
|
||||
|
||||
function(my_wdk_add_driver _target)
|
||||
cmake_parse_arguments(WDK "" "KMDF;WINVER;NTDDI_VERSION" "" ${ARGN})
|
||||
|
||||
add_executable(${_target} ${WDK_UNPARSED_ARGUMENTS})
|
||||
|
||||
set_target_properties(${_target} PROPERTIES SUFFIX ".sys")
|
||||
set_target_properties(${_target} PROPERTIES COMPILE_OPTIONS "${WDK_COMPILE_FLAGS}")
|
||||
set_target_properties(${_target} PROPERTIES COMPILE_DEFINITIONS
|
||||
"${WDK_COMPILE_DEFINITIONS};$<$<CONFIG:Debug>:${WDK_COMPILE_DEFINITIONS_DEBUG}>;_WIN32_WINNT=${WDK_WINVER}"
|
||||
)
|
||||
set_target_properties(${_target} PROPERTIES LINK_FLAGS "${WDK_LINK_FLAGS}")
|
||||
|
||||
if(WDK_NTDDI_VERSION)
|
||||
target_compile_definitions(${_target} PRIVATE NTDDI_VERSION=${WDK_NTDDI_VERSION})
|
||||
endif()
|
||||
|
||||
target_include_directories(${_target} SYSTEM PRIVATE
|
||||
"${WDK_ROOT}/Include/${WDK_INC_VERSION}/shared"
|
||||
"${WDK_ROOT}/Include/${WDK_INC_VERSION}/km"
|
||||
"${WDK_ROOT}/Include/${WDK_INC_VERSION}/km/crt"
|
||||
)
|
||||
|
||||
target_link_libraries(${_target} WDK::NTOSKRNL WDK::HAL WDK::WMILIB)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
target_link_libraries(${_target} WDK::MEMCMP)
|
||||
endif()
|
||||
|
||||
if(DEFINED WDK_KMDF)
|
||||
target_include_directories(${_target} SYSTEM PRIVATE "${WDK_ROOT}/Include/wdf/kmdf/${WDK_KMDF}")
|
||||
target_link_libraries(${_target}
|
||||
"${WDK_ROOT}/Lib/wdf/kmdf/${WDK_PLATFORM}/${WDK_KMDF}/WdfDriverEntry.lib"
|
||||
"${WDK_ROOT}/Lib/wdf/kmdf/${WDK_PLATFORM}/${WDK_KMDF}/WdfLdr.lib"
|
||||
)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:FxDriverEntry@8")
|
||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:FxDriverEntry")
|
||||
endif()
|
||||
else()
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:SCBegin")
|
||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:SCBegin")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
my_wdk_add_driver(ksc4cpp
|
||||
WINVER 0x0602
|
||||
src/main.cpp
|
||||
)
|
||||
set_target_properties(ksc4cpp
|
||||
PROPERTIES
|
||||
VS_PLATFORM_TOOLSET ClangCL)
|
||||
set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-imsvc")
|
||||
set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-imsvc")
|
||||
|
||||
set(COMPILE_FLAGS "/O2" "/Os" "/MT" "/GS-" "/Gs1048576" "-mno-sse" "-Wno-address-of-temporary")
|
||||
set_target_properties(ksc4cpp PROPERTIES COMPILE_OPTIONS "${COMPILE_FLAGS}")
|
||||
|
||||
# output compiler flags
|
||||
message(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}")
|
||||
message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
# output target ksc4cpp COMPILE_OPTIONS
|
||||
get_target_property(ksc4cpp_COMPILE_OPTIONS ksc4cpp COMPILE_OPTIONS)
|
||||
message(STATUS "ksc4cpp_COMPILE_OPTIONS: ${ksc4cpp_COMPILE_OPTIONS}")
|
||||
|
||||
# add custom command to sign the driver
|
||||
add_custom_command(TARGET ksc4cpp POST_BUILD
|
||||
COMMAND py -3 "${CMAKE_CURRENT_SOURCE_DIR}/tools/scextractor.py" $<TARGET_FILE:ksc4cpp>
|
||||
)
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 windpiaoxue
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,48 @@
|
||||
# ksc4cpp
|
||||
ksc4cpp is a shellcode framework for windows kernel based on C++
|
||||
|
||||
modified from sc4cpp
|
||||
|
||||
## Compiler
|
||||
Clang for Windows
|
||||
|
||||
## Compiler options
|
||||
```
|
||||
/O2 /Os /MT /GS- /Gs1048576 -mno-sse-Wno-address-of-temporary
|
||||
```
|
||||
## Build using Cmake
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
# do not using Debug mode
|
||||
cmake --build --config Release
|
||||
```
|
||||
|
||||
## Example
|
||||
```cpp
|
||||
#include <sc4cpp.h>
|
||||
|
||||
SC_NOINLINE
|
||||
SC_CODESEG_REORDERING
|
||||
DWORD WINAPI Func(PCSTR lpAnsiMsg) {
|
||||
SC_IMPORT_API_BATCH_BEGIN();
|
||||
SC_IMPORT_API_BATCH(DbgPrint);
|
||||
SC_IMPORT_API_BATCH_END();
|
||||
DbgPrint(lpAnsiMsg);
|
||||
return 0;
|
||||
}
|
||||
SC_MAIN_BEGIN()
|
||||
{
|
||||
Func(SC_PISTRINGA("Hello, world!"));
|
||||
}
|
||||
SC_MAIN_END();
|
||||
```
|
||||
|
||||
## Credit
|
||||
|
||||
[Windows x64 shellcode for locating the base address of ntoskrnl.exe](https://gist.github.com/Barakat/34e9924217ed81fd78c9c92d746ec9c6)
|
||||
|
||||
[[原创]X64 Kernel Shellcode获取Ntos Base-编程技术-看雪论坛-安全社区|安全招聘|bbs.pediy.com](https://bbs.pediy.com/thread-266744.htm)
|
||||
|
||||
[windpiaoxue/sc4cpp: sc4cpp is a shellcode framework based on C++](https://github.com/windpiaoxue/sc4cpp)
|
||||
@@ -0,0 +1,207 @@
|
||||
# Redistribution and use is allowed under the OSI-approved 3-clause BSD license.
|
||||
# Copyright (c) 2018 Sergey Podobry (sergey.podobry at gmail.com). All rights reserved.
|
||||
|
||||
#.rst:
|
||||
# FindWDK
|
||||
# ----------
|
||||
#
|
||||
# This module searches for the installed Windows Development Kit (WDK) and
|
||||
# exposes commands for creating kernel drivers and kernel libraries.
|
||||
#
|
||||
# Output variables:
|
||||
# - `WDK_FOUND` -- if false, do not try to use WDK
|
||||
# - `WDK_ROOT` -- where WDK is installed
|
||||
# - `WDK_VERSION` -- the version of the selected WDK
|
||||
# - `WDK_WINVER` -- the WINVER used for kernel drivers and libraries
|
||||
# (default value is `0x0601` and can be changed per target or globally)
|
||||
# - `WDK_NTDDI_VERSION` -- the NTDDI_VERSION used for kernel drivers and libraries,
|
||||
# if not set, the value will be automatically calculated by WINVER
|
||||
# (default value is left blank and can be changed per target or globally)
|
||||
#
|
||||
# Example usage:
|
||||
#
|
||||
# find_package(WDK REQUIRED)
|
||||
#
|
||||
# wdk_add_library(KmdfCppLib STATIC KMDF 1.15
|
||||
# KmdfCppLib.h
|
||||
# KmdfCppLib.cpp
|
||||
# )
|
||||
# target_include_directories(KmdfCppLib INTERFACE .)
|
||||
#
|
||||
# wdk_add_driver(KmdfCppDriver KMDF 1.15
|
||||
# Main.cpp
|
||||
# )
|
||||
# target_link_libraries(KmdfCppDriver KmdfCppLib)
|
||||
#
|
||||
|
||||
if(DEFINED ENV{WDKContentRoot})
|
||||
file(GLOB WDK_NTDDK_FILES
|
||||
"$ENV{WDKContentRoot}/Include/*/km/ntddk.h" # WDK 10
|
||||
"$ENV{WDKContentRoot}/Include/km/ntddk.h" # WDK 8.0, 8.1
|
||||
)
|
||||
else()
|
||||
file(GLOB WDK_NTDDK_FILES
|
||||
"C:/Program Files*/Windows Kits/*/Include/*/km/ntddk.h" # WDK 10
|
||||
"C:/Program Files*/Windows Kits/*/Include/km/ntddk.h" # WDK 8.0, 8.1
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WDK_NTDDK_FILES)
|
||||
if (NOT CMAKE_VERSION VERSION_LESS 3.18.0)
|
||||
list(SORT WDK_NTDDK_FILES COMPARE NATURAL) # sort to use the latest available WDK
|
||||
endif()
|
||||
list(GET WDK_NTDDK_FILES -1 WDK_LATEST_NTDDK_FILE)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(WDK REQUIRED_VARS WDK_LATEST_NTDDK_FILE)
|
||||
|
||||
if (NOT WDK_LATEST_NTDDK_FILE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_filename_component(WDK_ROOT ${WDK_LATEST_NTDDK_FILE} DIRECTORY)
|
||||
get_filename_component(WDK_ROOT ${WDK_ROOT} DIRECTORY)
|
||||
get_filename_component(WDK_VERSION ${WDK_ROOT} NAME)
|
||||
get_filename_component(WDK_ROOT ${WDK_ROOT} DIRECTORY)
|
||||
if (NOT WDK_ROOT MATCHES ".*/[0-9][0-9.]*$") # WDK 10 has a deeper nesting level
|
||||
get_filename_component(WDK_ROOT ${WDK_ROOT} DIRECTORY) # go up once more
|
||||
set(WDK_LIB_VERSION "${WDK_VERSION}")
|
||||
set(WDK_INC_VERSION "${WDK_VERSION}")
|
||||
else() # WDK 8.0, 8.1
|
||||
set(WDK_INC_VERSION "")
|
||||
foreach(VERSION winv6.3 win8 win7)
|
||||
if (EXISTS "${WDK_ROOT}/Lib/${VERSION}/")
|
||||
set(WDK_LIB_VERSION "${VERSION}")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
set(WDK_VERSION "${WDK_LIB_VERSION}")
|
||||
endif()
|
||||
|
||||
message(STATUS "WDK_ROOT: " ${WDK_ROOT})
|
||||
message(STATUS "WDK_VERSION: " ${WDK_VERSION})
|
||||
|
||||
set(WDK_WINVER "0x0601" CACHE STRING "Default WINVER for WDK targets")
|
||||
set(WDK_NTDDI_VERSION "" CACHE STRING "Specified NTDDI_VERSION for WDK targets if needed")
|
||||
|
||||
set(WDK_ADDITIONAL_FLAGS_FILE "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/wdkflags.h")
|
||||
file(WRITE ${WDK_ADDITIONAL_FLAGS_FILE} "#pragma runtime_checks(\"suc\", off)")
|
||||
|
||||
set(WDK_COMPILE_FLAGS
|
||||
"/Zp8" # set struct alignment
|
||||
"/GF" # enable string pooling
|
||||
"/GR-" # disable RTTI
|
||||
"/Gz" # __stdcall by default
|
||||
"/kernel" # create kernel mode binary
|
||||
"/FIwarning.h" # disable warnings in WDK headers
|
||||
"/FI${WDK_ADDITIONAL_FLAGS_FILE}" # include file to disable RTC
|
||||
)
|
||||
|
||||
set(WDK_COMPILE_DEFINITIONS "WINNT=1")
|
||||
set(WDK_COMPILE_DEFINITIONS_DEBUG "MSC_NOOPT;DEPRECATE_DDK_FUNCTIONS=1;DBG=1")
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
list(APPEND WDK_COMPILE_DEFINITIONS "_X86_=1;i386=1;STD_CALL")
|
||||
set(WDK_PLATFORM "x86")
|
||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
list(APPEND WDK_COMPILE_DEFINITIONS "_WIN64;_AMD64_;AMD64")
|
||||
set(WDK_PLATFORM "x64")
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported architecture")
|
||||
endif()
|
||||
|
||||
string(CONCAT WDK_LINK_FLAGS
|
||||
"/MANIFEST:NO " #
|
||||
"/DRIVER " #
|
||||
"/OPT:REF " #
|
||||
"/INCREMENTAL:NO " #
|
||||
"/OPT:ICF " #
|
||||
"/SUBSYSTEM:NATIVE " #
|
||||
"/MERGE:_TEXT=.text;_PAGE=PAGE " #
|
||||
"/NODEFAULTLIB " # do not link default CRT
|
||||
"/SECTION:INIT,d " #
|
||||
"/VERSION:10.0 " #
|
||||
)
|
||||
|
||||
# Generate imported targets for WDK lib files
|
||||
file(GLOB WDK_LIBRARIES "${WDK_ROOT}/Lib/${WDK_LIB_VERSION}/km/${WDK_PLATFORM}/*.lib")
|
||||
foreach(LIBRARY IN LISTS WDK_LIBRARIES)
|
||||
get_filename_component(LIBRARY_NAME ${LIBRARY} NAME_WE)
|
||||
string(TOUPPER ${LIBRARY_NAME} LIBRARY_NAME)
|
||||
add_library(WDK::${LIBRARY_NAME} INTERFACE IMPORTED)
|
||||
set_property(TARGET WDK::${LIBRARY_NAME} PROPERTY INTERFACE_LINK_LIBRARIES ${LIBRARY})
|
||||
endforeach(LIBRARY)
|
||||
unset(WDK_LIBRARIES)
|
||||
|
||||
function(wdk_add_driver _target)
|
||||
cmake_parse_arguments(WDK "" "KMDF;WINVER;NTDDI_VERSION" "" ${ARGN})
|
||||
|
||||
add_executable(${_target} ${WDK_UNPARSED_ARGUMENTS})
|
||||
|
||||
set_target_properties(${_target} PROPERTIES SUFFIX ".sys")
|
||||
set_target_properties(${_target} PROPERTIES COMPILE_OPTIONS "${WDK_COMPILE_FLAGS}")
|
||||
set_target_properties(${_target} PROPERTIES COMPILE_DEFINITIONS
|
||||
"${WDK_COMPILE_DEFINITIONS};$<$<CONFIG:Debug>:${WDK_COMPILE_DEFINITIONS_DEBUG}>;_WIN32_WINNT=${WDK_WINVER}"
|
||||
)
|
||||
set_target_properties(${_target} PROPERTIES LINK_FLAGS "${WDK_LINK_FLAGS}")
|
||||
if(WDK_NTDDI_VERSION)
|
||||
target_compile_definitions(${_target} PRIVATE NTDDI_VERSION=${WDK_NTDDI_VERSION})
|
||||
endif()
|
||||
|
||||
target_include_directories(${_target} SYSTEM PRIVATE
|
||||
"${WDK_ROOT}/Include/${WDK_INC_VERSION}/shared"
|
||||
"${WDK_ROOT}/Include/${WDK_INC_VERSION}/km"
|
||||
"${WDK_ROOT}/Include/${WDK_INC_VERSION}/km/crt"
|
||||
)
|
||||
|
||||
target_link_libraries(${_target} WDK::NTOSKRNL WDK::HAL WDK::BUFFEROVERFLOWK WDK::WMILIB)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
target_link_libraries(${_target} WDK::MEMCMP)
|
||||
endif()
|
||||
|
||||
if(DEFINED WDK_KMDF)
|
||||
target_include_directories(${_target} SYSTEM PRIVATE "${WDK_ROOT}/Include/wdf/kmdf/${WDK_KMDF}")
|
||||
target_link_libraries(${_target}
|
||||
"${WDK_ROOT}/Lib/wdf/kmdf/${WDK_PLATFORM}/${WDK_KMDF}/WdfDriverEntry.lib"
|
||||
"${WDK_ROOT}/Lib/wdf/kmdf/${WDK_PLATFORM}/${WDK_KMDF}/WdfLdr.lib"
|
||||
)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:FxDriverEntry@8")
|
||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:FxDriverEntry")
|
||||
endif()
|
||||
else()
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:GsDriverEntry@8")
|
||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS "/ENTRY:GsDriverEntry")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(wdk_add_library _target)
|
||||
cmake_parse_arguments(WDK "" "KMDF;WINVER;NTDDI_VERSION" "" ${ARGN})
|
||||
|
||||
add_library(${_target} ${WDK_UNPARSED_ARGUMENTS})
|
||||
|
||||
set_target_properties(${_target} PROPERTIES COMPILE_OPTIONS "${WDK_COMPILE_FLAGS}")
|
||||
set_target_properties(${_target} PROPERTIES COMPILE_DEFINITIONS
|
||||
"${WDK_COMPILE_DEFINITIONS};$<$<CONFIG:Debug>:${WDK_COMPILE_DEFINITIONS_DEBUG};>_WIN32_WINNT=${WDK_WINVER}"
|
||||
)
|
||||
if(WDK_NTDDI_VERSION)
|
||||
target_compile_definitions(${_target} PRIVATE NTDDI_VERSION=${WDK_NTDDI_VERSION})
|
||||
endif()
|
||||
|
||||
target_include_directories(${_target} SYSTEM PRIVATE
|
||||
"${WDK_ROOT}/Include/${WDK_INC_VERSION}/shared"
|
||||
"${WDK_ROOT}/Include/${WDK_INC_VERSION}/km"
|
||||
"${WDK_ROOT}/Include/${WDK_INC_VERSION}/km/crt"
|
||||
)
|
||||
|
||||
if(DEFINED WDK_KMDF)
|
||||
target_include_directories(${_target} SYSTEM PRIVATE "${WDK_ROOT}/Include/wdf/kmdf/${WDK_KMDF}")
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -0,0 +1,340 @@
|
||||
/**
|
||||
* Copyright (c) 2021 smh <windpiaoxue@foxmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if !defined(__clang__) || !defined(_WIN32)
|
||||
#error "sc4cpp only supports Clang on windows"
|
||||
#endif
|
||||
|
||||
#include <ntddk.h>
|
||||
#include <stdint.h>
|
||||
#include <minwindef.h>
|
||||
#include <ntimage.h>
|
||||
#define _countof(array) (sizeof(array) / sizeof(array[0]))
|
||||
#define _T(x) L##x
|
||||
// #include <type_traits>
|
||||
|
||||
// #include <utility>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define SC_DEBUG
|
||||
#endif // _DEBUG
|
||||
|
||||
#ifdef _WIN64
|
||||
#define SC_WIN64
|
||||
#endif // _WIN64
|
||||
|
||||
#define SC_CONSTEXPR constexpr
|
||||
#define SC_NOINLINE __declspec(noinline)
|
||||
#define SC_FORCEINLINE __forceinline
|
||||
|
||||
#define SC_EXTERN_C_BEGIN \
|
||||
extern "C" \
|
||||
{
|
||||
#define SC_DLL_IMPORT __declspec(dllimport)
|
||||
#define SC_DLL_EXPORT __declspec(dllexport)
|
||||
#define SC_EXTERN_C_END }
|
||||
|
||||
#define SC_NAKEDFUNC __declspec(naked)
|
||||
#define SC_ASM __asm
|
||||
#define SC_EMIT(c) __asm _emit(c)
|
||||
|
||||
#define SC_CODESEG(s) __declspec(code_seg(".code$" #s))
|
||||
|
||||
#define SC_CODESEG_START SC_CODESEG(CAA)
|
||||
#define SC_CODESEG_END SC_CODESEG(CZZ)
|
||||
#define SC_CODESEG_MAIN SC_CODESEG(CBA)
|
||||
|
||||
// Make sure it is between MAIN and END.
|
||||
#define SC_CODESEG_REORDERING SC_CODESEG(CXI)
|
||||
|
||||
namespace SC
|
||||
{
|
||||
// https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
template <typename Converter>
|
||||
SC_FORCEINLINE SC_CONSTEXPR DWORD Hash(PCSTR lpName)
|
||||
{
|
||||
DWORD dwHash = 2166136261u;
|
||||
for (; *lpName != '\0'; ++lpName)
|
||||
{
|
||||
dwHash = (dwHash ^ (BYTE)Converter()(*lpName)) * 16777619ull;
|
||||
}
|
||||
return dwHash;
|
||||
}
|
||||
SC_FORCEINLINE SC_CONSTEXPR DWORD Hash(PCSTR lpName)
|
||||
{
|
||||
struct Converter
|
||||
{
|
||||
SC_CONSTEXPR Converter() {}
|
||||
SC_CONSTEXPR CHAR operator()(CHAR c) const { return c; }
|
||||
};
|
||||
return Hash<Converter>(lpName);
|
||||
}
|
||||
SC_FORCEINLINE SC_CONSTEXPR DWORD HashI(PCSTR lpName)
|
||||
{
|
||||
struct Converter
|
||||
{
|
||||
SC_CONSTEXPR Converter() {}
|
||||
SC_CONSTEXPR CHAR operator()(CHAR c) const
|
||||
{
|
||||
return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c;
|
||||
}
|
||||
};
|
||||
return Hash<Converter>(lpName);
|
||||
}
|
||||
|
||||
SC_FORCEINLINE PVOID GetNtoskrnlBaseAddress()
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
UCHAR Padding[4];
|
||||
PVOID InterruptServiceRoutine;
|
||||
} IDT_ENTRY;
|
||||
#pragma pack(pop)
|
||||
|
||||
// Find the address of IdtBase using gs register.
|
||||
const auto idt_base = reinterpret_cast<IDT_ENTRY *>(__readgsqword(0x38));
|
||||
|
||||
// Find the address of the first (or any) interrupt service routine.
|
||||
const auto first_isr_address = idt_base[0].InterruptServiceRoutine;
|
||||
|
||||
// search this pattern "48 8D 1D ?? ?? ?? FF" backwards from the
|
||||
// first_isr_address
|
||||
auto ptr = reinterpret_cast<uintptr_t>(first_isr_address);
|
||||
while (1)
|
||||
{
|
||||
if (*(reinterpret_cast<uint8_t *>(ptr)) != 0x48 ||
|
||||
*(reinterpret_cast<uint8_t *>(ptr + 1)) != 0x8D ||
|
||||
*(reinterpret_cast<uint8_t *>(ptr + 2)) != 0x1D ||
|
||||
*(reinterpret_cast<uint8_t *>(ptr + 6)) != 0xFF)
|
||||
{
|
||||
ptr--;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we found the pattern, now we need to calculate the offset
|
||||
auto offset = *(reinterpret_cast<int32_t *>(ptr + 3));
|
||||
auto ntoskernl_base = ptr + 7 + offset;
|
||||
// check ntoskernel_base is page aligned
|
||||
if (ntoskernl_base % 0x1000 == 0)
|
||||
{
|
||||
return reinterpret_cast<void *>(ntoskernl_base);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SC_FORCEINLINE PIMAGE_NT_HEADERS GetNTHeaders(PVOID lpDLLBase)
|
||||
{
|
||||
PIMAGE_DOS_HEADER lpDOSHeader = (PIMAGE_DOS_HEADER)lpDLLBase;
|
||||
return (PIMAGE_NT_HEADERS)((PBYTE)lpDLLBase + lpDOSHeader->e_lfanew);
|
||||
}
|
||||
SC_FORCEINLINE PVOID MmGetSystemRoutineAddressByHash(DWORD dwProcHash)
|
||||
{
|
||||
auto lpNtBase = (PSTR)GetNtoskrnlBaseAddress();
|
||||
PIMAGE_NT_HEADERS lpNTHeaders = GetNTHeaders(lpNtBase);
|
||||
DWORD dwExportDirectoryRAV =
|
||||
lpNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
|
||||
.VirtualAddress;
|
||||
if (dwExportDirectoryRAV == 0)
|
||||
{
|
||||
}
|
||||
PIMAGE_EXPORT_DIRECTORY lpExportDirectory =
|
||||
(PIMAGE_EXPORT_DIRECTORY)(lpNtBase + dwExportDirectoryRAV);
|
||||
PDWORD lpNameRAVs = (PDWORD)(lpNtBase + lpExportDirectory->AddressOfNames);
|
||||
PWORD lpOrdinals =
|
||||
(PWORD)(lpNtBase + lpExportDirectory->AddressOfNameOrdinals);
|
||||
PDWORD lpProcRAVs =
|
||||
(PDWORD)(lpNtBase + lpExportDirectory->AddressOfFunctions);
|
||||
for (DWORD dwIdx = 0; dwIdx < lpExportDirectory->NumberOfNames; ++dwIdx)
|
||||
{
|
||||
if (Hash(lpNtBase + lpNameRAVs[dwIdx]) == dwProcHash)
|
||||
{
|
||||
return lpNtBase + lpProcRAVs[lpOrdinals[dwIdx]];
|
||||
}
|
||||
}
|
||||
__debugbreak();
|
||||
return NULL; // No return
|
||||
}
|
||||
// For Compile-time calculation
|
||||
template <DWORD dwProcHash>
|
||||
SC_FORCEINLINE PVOID MmGetSystemRoutineAddressByHash()
|
||||
{
|
||||
return MmGetSystemRoutineAddressByHash(dwProcHash);
|
||||
}
|
||||
|
||||
SC_FORCEINLINE PVOID GetProcAddressByHash(DWORD dwDLLHash, DWORD dwProcHash)
|
||||
{
|
||||
__debugbreak();
|
||||
LPSTR lpDLLBase = (LPSTR) nullptr;
|
||||
if (lpDLLBase == NULL)
|
||||
{
|
||||
}
|
||||
PIMAGE_NT_HEADERS lpNTHeaders = GetNTHeaders(lpDLLBase);
|
||||
DWORD dwExportDirectoryRAV =
|
||||
lpNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
|
||||
.VirtualAddress;
|
||||
if (dwExportDirectoryRAV == 0)
|
||||
{
|
||||
}
|
||||
PIMAGE_EXPORT_DIRECTORY lpExportDirectory =
|
||||
(PIMAGE_EXPORT_DIRECTORY)(lpDLLBase + dwExportDirectoryRAV);
|
||||
if (HashI(lpDLLBase + lpExportDirectory->Name) != dwDLLHash)
|
||||
{
|
||||
}
|
||||
PDWORD lpNameRAVs = (PDWORD)(lpDLLBase + lpExportDirectory->AddressOfNames);
|
||||
PWORD lpOrdinals =
|
||||
(PWORD)(lpDLLBase + lpExportDirectory->AddressOfNameOrdinals);
|
||||
PDWORD lpProcRAVs =
|
||||
(PDWORD)(lpDLLBase + lpExportDirectory->AddressOfFunctions);
|
||||
for (DWORD dwIdx = 0; dwIdx < lpExportDirectory->NumberOfNames; ++dwIdx)
|
||||
{
|
||||
if (Hash(lpDLLBase + lpNameRAVs[dwIdx]) == dwProcHash)
|
||||
{
|
||||
// FIXME: DLL Function Forwarding
|
||||
return lpDLLBase + lpProcRAVs[lpOrdinals[dwIdx]];
|
||||
}
|
||||
}
|
||||
__debugbreak();
|
||||
return NULL; // No return
|
||||
}
|
||||
|
||||
// For Compile-time calculation
|
||||
template <DWORD dwDLLHash, DWORD dwProcHash>
|
||||
SC_FORCEINLINE PVOID GetProcAddressByHash()
|
||||
{
|
||||
return GetProcAddressByHash(dwDLLHash, dwProcHash);
|
||||
}
|
||||
|
||||
template <class _Ty, _Ty... _Vals> struct integer_sequence
|
||||
{ // sequence of integer parameters
|
||||
|
||||
using value_type = _Ty;
|
||||
|
||||
_NODISCARD static constexpr size_t size() noexcept
|
||||
{
|
||||
return sizeof...(_Vals);
|
||||
}
|
||||
};
|
||||
// ALIAS TEMPLATE make_integer_sequence
|
||||
template <class _Ty, _Ty _Size>
|
||||
using make_integer_sequence = __make_integer_seq<integer_sequence, _Ty, _Size>;
|
||||
|
||||
template <size_t... _Vals>
|
||||
using index_sequence = integer_sequence<size_t, _Vals...>;
|
||||
|
||||
template <size_t _Size>
|
||||
using make_index_sequence = make_integer_sequence<size_t, _Size>;
|
||||
|
||||
template <class... _Types>
|
||||
using index_sequence_for = make_index_sequence<sizeof...(_Types)>;
|
||||
|
||||
// Position Independent String
|
||||
template <typename CharType, typename Indices> struct PIString;
|
||||
template <typename CharType, size_t... Indices>
|
||||
struct PIString<CharType, index_sequence<Indices...>>
|
||||
{
|
||||
CharType szBuffer_[sizeof...(Indices)];
|
||||
SC_FORCEINLINE SC_CONSTEXPR explicit PIString(
|
||||
const CharType (&szLiteral)[sizeof...(Indices)])
|
||||
: szBuffer_{(szLiteral[Indices])...}
|
||||
{
|
||||
}
|
||||
};
|
||||
} // namespace SC
|
||||
|
||||
#ifdef SC_WIN64
|
||||
#define SC_BEGIN_CODE \
|
||||
SC_DLL_EXPORT SC_CODESEG_START VOID SCBegin() { SCMain(NULL); }
|
||||
#else
|
||||
// clang-format off
|
||||
#define SC_BEGIN_CODE \
|
||||
SC_DLL_EXPORT SC_CODESEG_START SC_NAKEDFUNC VOID SCBegin() { \
|
||||
/* CALL $+5 */ \
|
||||
SC_EMIT(0xE8) SC_EMIT(0x00) SC_EMIT(0x00) SC_EMIT(0x00) SC_EMIT(0x00) \
|
||||
SC_ASM POP EAX \
|
||||
SC_ASM LEA EAX, [EAX - 5] \
|
||||
SC_ASM LEA ECX, [SCBegin] \
|
||||
SC_ASM NEG ECX \
|
||||
SC_ASM LEA EAX, [EAX + ECX + SCMain] \
|
||||
SC_ASM PUSH EAX \
|
||||
SC_ASM CALL EAX \
|
||||
SC_ASM RET \
|
||||
}
|
||||
// clang-format on
|
||||
#endif // SC_WIN64
|
||||
|
||||
#define SC_MAIN_BEGIN() \
|
||||
SC_EXTERN_C_BEGIN \
|
||||
SC_DLL_EXPORT VOID WINAPI SCMain(ULONG_PTR SCMainVA); \
|
||||
SC_BEGIN_CODE \
|
||||
SC_DLL_EXPORT SC_CODESEG_MAIN VOID WINAPI SCMain(ULONG_PTR SCMainVA)
|
||||
#define SC_MAIN_END() \
|
||||
SC_DLL_EXPORT SC_CODESEG_END VOID SCEnd() { __debugbreak(); } \
|
||||
SC_EXTERN_C_END
|
||||
|
||||
#define SC_PISTRINGA(szLiteralA) \
|
||||
(::SC::PIString<CHAR, ::SC::make_index_sequence<_countof(szLiteralA)>>( \
|
||||
szLiteralA) \
|
||||
.szBuffer_)
|
||||
#define SC_PISTRINGW(szLiteralW) \
|
||||
(::SC::PIString<WCHAR, ::SC::make_index_sequence<_countof(szLiteralW)>>( \
|
||||
szLiteralW) \
|
||||
.szBuffer_)
|
||||
#define SC_PISTRINGU(szLiteralW) \
|
||||
(&UNICODE_STRING{sizeof(szLiteralW) - sizeof(WCHAR), sizeof(szLiteralW), \
|
||||
SC_PISTRINGW(szLiteralW)})
|
||||
|
||||
#ifdef SC_WIN64
|
||||
#define SC_PIFUNCTION(fnReordered) ((decltype(fnReordered) *)fnReordered)
|
||||
#else
|
||||
// Must be invoked in SCMain.
|
||||
#define SC_PIFUNCTION(fnReordered) \
|
||||
((decltype(fnReordered) *)(((ULONG_PTR)(fnReordered) - \
|
||||
(ULONG_PTR)SCMain) + \
|
||||
SCMainVA))
|
||||
#endif // SC_WIN64
|
||||
|
||||
#define SC_GET_API_ADDRESS(szAPIName) \
|
||||
(::SC::MmGetSystemRoutineAddressByHash<::SC::Hash(szAPIName)>())
|
||||
|
||||
// #define SC_IMPORT_API_AS(fnVarName, szDLLName, fnAPIName) \
|
||||
// auto fnVarName = \
|
||||
// (decltype(::fnAPIName) *)SC_GET_API_ADDRESS(szDLLName, #fnAPIName)
|
||||
// #define SC_IMPORT_API(szDLLName, fnAPIName) \
|
||||
// SC_IMPORT_API_AS(fnAPIName, szDLLName, fnAPIName)
|
||||
#define SC_IMPORT_API_AS(fnVarName, fnAPIName) \
|
||||
auto fnVarName = (decltype(::fnAPIName) *)SC_GET_API_ADDRESS(#fnAPIName)
|
||||
#define SC_IMPORT_API(fnAPIName) SC_IMPORT_API_AS(fnAPIName, fnAPIName)
|
||||
|
||||
#define SC_IMPORT_API_BATCH_BEGIN() \
|
||||
SC_IMPORT_API_AS(fnSCGetFnAddress, MmGetSystemRoutineAddress)
|
||||
#define SC_IMPORT_API_BATCH(fnAPIName) \
|
||||
auto fnAPIName = \
|
||||
(decltype(::fnAPIName) *)(fnSCGetFnAddress(SC_PISTRINGU(_T(#fnAPIName))))
|
||||
#define SC_IMPORT_API_BATCH_END()
|
||||
@@ -0,0 +1,16 @@
|
||||
#include <sc4cpp.h>
|
||||
|
||||
SC_NOINLINE
|
||||
SC_CODESEG_REORDERING
|
||||
DWORD WINAPI Func(PCSTR lpAnsiMsg) {
|
||||
SC_IMPORT_API_BATCH_BEGIN();
|
||||
SC_IMPORT_API_BATCH(DbgPrint);
|
||||
SC_IMPORT_API_BATCH_END();
|
||||
DbgPrint(lpAnsiMsg);
|
||||
return 0;
|
||||
}
|
||||
SC_MAIN_BEGIN()
|
||||
{
|
||||
Func(SC_PISTRINGA("Hello, world!"));
|
||||
}
|
||||
SC_MAIN_END();
|
||||
@@ -0,0 +1,6 @@
|
||||
project(shellcodetester)
|
||||
wdk_add_driver(shellcodetester main.c)
|
||||
# add custom command to sign the driver
|
||||
add_custom_command(TARGET shellcodetester POST_BUILD
|
||||
COMMAND signtool sign /v /n WDKTestCert $<TARGET_FILE:shellcodetester>
|
||||
)
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
#include <ntddk.h>
|
||||
#include <wdm.h>
|
||||
#pragma comment(linker, "/merge:.data=.text")
|
||||
#pragma comment(linker, "/section:.text,RWE")
|
||||
|
||||
void DriverUnload(PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(DriverObject);
|
||||
}
|
||||
//------------------------------------------------------------
|
||||
//----------- Created with 010 Editor -----------
|
||||
//------ www.sweetscape.com/010editor/ ------
|
||||
//
|
||||
// File : D:\sec\code\ksc4cpp\build\Release\ksc4cpp.sc
|
||||
// Address : 0 (0x0)
|
||||
// Size : 330 (0x14A)
|
||||
//------------------------------------------------------------
|
||||
unsigned char hexData[330] = {
|
||||
0xE9, 0x00, 0x00, 0x00, 0x00, 0x48, 0x83, 0xEC, 0x38, 0x48, 0xB8, 0x48, 0x65, 0x6C, 0x6C, 0x6F,
|
||||
0x2C, 0x20, 0x77, 0x48, 0x8D, 0x4C, 0x24, 0x28, 0x48, 0x89, 0x01, 0xC7, 0x41, 0x08, 0x6F, 0x72,
|
||||
0x6C, 0x64, 0x66, 0xC7, 0x41, 0x0C, 0x21, 0x00, 0xE8, 0x06, 0x00, 0x00, 0x00, 0x90, 0x48, 0x83,
|
||||
0xC4, 0x38, 0xC3, 0x41, 0x56, 0x56, 0x57, 0x53, 0x48, 0x83, 0xEC, 0x48, 0x49, 0x89, 0xCE, 0x65,
|
||||
0x48, 0x8B, 0x04, 0x25, 0x38, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x48, 0x04, 0x80, 0x39, 0x48, 0x75,
|
||||
0x12, 0x80, 0x79, 0x01, 0x8D, 0x75, 0x0C, 0x80, 0x79, 0x02, 0x1D, 0x75, 0x06, 0x80, 0x79, 0x06,
|
||||
0xFF, 0x74, 0x05, 0x48, 0xFF, 0xC9, 0xEB, 0xE4, 0x48, 0x63, 0x41, 0x03, 0x48, 0x01, 0xC8, 0x48,
|
||||
0x83, 0xC0, 0x07, 0x31, 0xD2, 0xA9, 0xFF, 0x0F, 0x00, 0x00, 0x0F, 0x95, 0xC2, 0x48, 0x29, 0xD1,
|
||||
0xA9, 0xFF, 0x0F, 0x00, 0x00, 0x75, 0xC5, 0x48, 0x63, 0x48, 0x3C, 0x8B, 0x8C, 0x08, 0x88, 0x00,
|
||||
0x00, 0x00, 0x44, 0x8B, 0x5C, 0x08, 0x18, 0x4D, 0x85, 0xDB, 0x74, 0x53, 0x8B, 0x74, 0x08, 0x20,
|
||||
0x48, 0x01, 0xC6, 0x44, 0x8B, 0x44, 0x08, 0x24, 0x49, 0x01, 0xC0, 0x44, 0x8B, 0x4C, 0x08, 0x1C,
|
||||
0x49, 0x01, 0xC1, 0x4C, 0x8D, 0x50, 0x01, 0x31, 0xDB, 0x8B, 0x3C, 0x9E, 0x8A, 0x14, 0x38, 0x84,
|
||||
0xD2, 0x74, 0x24, 0x4C, 0x01, 0xD7, 0xB9, 0xC5, 0x9D, 0x1C, 0x81, 0x0F, 0xB6, 0xD2, 0x31, 0xCA,
|
||||
0x69, 0xCA, 0x93, 0x01, 0x00, 0x01, 0x8A, 0x17, 0x48, 0xFF, 0xC7, 0x84, 0xD2, 0x75, 0xEC, 0x81,
|
||||
0xF9, 0x98, 0x15, 0x70, 0x34, 0x74, 0x0D, 0x48, 0xFF, 0xC3, 0x4C, 0x39, 0xDB, 0x75, 0xCA, 0xCC,
|
||||
0x31, 0xC0, 0xEB, 0x0E, 0x89, 0xD9, 0x41, 0x0F, 0xB7, 0x0C, 0x48, 0x41, 0x8B, 0x0C, 0x89, 0x48,
|
||||
0x01, 0xC8, 0x48, 0x8D, 0x4C, 0x24, 0x20, 0xC7, 0x01, 0x10, 0x00, 0x12, 0x00, 0x48, 0xBA, 0x44,
|
||||
0x00, 0x62, 0x00, 0x67, 0x00, 0x50, 0x00, 0x48, 0x8D, 0x5C, 0x24, 0x30, 0x48, 0x89, 0x13, 0x48,
|
||||
0xBA, 0x72, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x48, 0x89, 0x53, 0x08, 0x66, 0xC7, 0x43,
|
||||
0x10, 0x00, 0x00, 0x48, 0x89, 0x59, 0x08, 0xFF, 0xD0, 0x4C, 0x89, 0xF1, 0xFF, 0xD0, 0x31, 0xC0,
|
||||
0x48, 0x83, 0xC4, 0x48, 0x5B, 0x5F, 0x5E, 0x41, 0x5E, 0xC3
|
||||
};
|
||||
|
||||
|
||||
|
||||
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,
|
||||
PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
|
||||
UNREFERENCED_PARAMETER(DriverObject);
|
||||
UNREFERENCED_PARAMETER(RegistryPath);
|
||||
((void(*)())hexData)();
|
||||
|
||||
// auto ntoskrnl_base = GetNtoskrnlBaseAddress();
|
||||
// // print the address of ntoskrnl.exe
|
||||
// DbgPrint("ntoskrnl.exe base address: %p", ntoskrnl_base);
|
||||
|
||||
// set driver unload function
|
||||
DriverObject->DriverUnload = DriverUnload;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import pefile
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def extract_shellcode(sc_path : Path) -> Path:
|
||||
image = pefile.PE(str(sc_path))
|
||||
if not image.is_exe() and not image.is_dll():
|
||||
raise Exception("The file is not a valid PE file.")
|
||||
|
||||
for symbol in image.DIRECTORY_ENTRY_EXPORT.symbols:
|
||||
if symbol.name.decode() == "SCBegin":
|
||||
sc_begin = symbol.address
|
||||
elif symbol.name.decode() == "SCEnd":
|
||||
sc_end = symbol.address
|
||||
if "sc_begin" not in locals().keys() or "sc_end" not in locals().keys():
|
||||
raise Exception("Not found shellcode in the PE file.")
|
||||
|
||||
sc_path = sc_path.parent.joinpath(sc_path.stem).with_suffix(".sc")
|
||||
sc_path.write_bytes(image.get_data(sc_begin, sc_end - sc_begin))
|
||||
return sc_path
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 2:
|
||||
raise Exception("Invalid parameters.")
|
||||
sc_path = Path(sys.argv[1])
|
||||
if not sc_path.is_file():
|
||||
raise Exception("Invalid parameters.")
|
||||
sc_path = extract_shellcode(sc_path)
|
||||
print(f"------ The shellcode extracted successfully and saved {sc_path} ------")
|
||||
Reference in New Issue
Block a user