├── .github └── workflows │ └── objective-c-xcode.yml ├── README.md ├── kmem.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── rickmark.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── xcshareddata │ └── xcschemes │ │ ├── Build All.xcscheme │ │ ├── kmem.xcscheme │ │ └── kmemclient.xcscheme └── xcuserdata │ └── rickmark.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── kmem ├── IOKernelMemoryApeture.cpp ├── IOKernelMemoryApeture.hpp ├── IOKernelMemoryUserClient.cpp ├── IOKernelMemoryUserClient.hpp ├── Info.plist ├── kmem.c ├── kmem.h └── kmem_api.h └── kmemclient └── main.cpp /.github/workflows/objective-c-xcode.yml: -------------------------------------------------------------------------------- 1 | name: Xcode - Build and Analyze 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | jobs: 10 | build: 11 | name: Build and analyse default scheme using xcodebuild command 12 | runs-on: macos-latest 13 | 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v3 17 | - name: Set Default Scheme 18 | run: | 19 | scheme_list=$(xcodebuild -list -json | tr -d "\n") 20 | default=$(echo $scheme_list | ruby -e "require 'json'; puts JSON.parse(STDIN.gets)['project']['targets'][0]") 21 | echo $default | cat >default 22 | echo Using default scheme: $default 23 | - name: Build 24 | env: 25 | scheme: ${{ 'default' }} 26 | run: | 27 | if [ $scheme = default ]; then scheme=$(cat default); fi 28 | if [ "`ls -A | grep -i \\.xcworkspace\$`" ]; then filetype_parameter="workspace" && file_to_build="`ls -A | grep -i \\.xcworkspace\$`"; else filetype_parameter="project" && file_to_build="`ls -A | grep -i \\.xcodeproj\$`"; fi 29 | file_to_build=`echo $file_to_build | awk '{$1=$1;print}'` 30 | xcodebuild clean build analyze -scheme "$scheme" -"$filetype_parameter" "$file_to_build" | xcpretty && exit ${PIPESTATUS[0]} 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IOKernelMemoryApeture 2 | 3 | 4 | 5 | 6 | ## Credits 7 | 8 | * https://github.com/unbit/foohid for an example of a Kext + User mode client 9 | -------------------------------------------------------------------------------- /kmem.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C95E08862558AF2D007E6B1C /* kmem.h in Headers */ = {isa = PBXBuildFile; fileRef = C95E08852558AF2D007E6B1C /* kmem.h */; }; 11 | C95E088B2558AF53007E6B1C /* IOKernelMemoryUserClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C95E08892558AF53007E6B1C /* IOKernelMemoryUserClient.cpp */; }; 12 | C95E088C2558AF53007E6B1C /* IOKernelMemoryUserClient.hpp in Headers */ = {isa = PBXBuildFile; fileRef = C95E088A2558AF53007E6B1C /* IOKernelMemoryUserClient.hpp */; }; 13 | C95E08AF2558B994007E6B1C /* kmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C95E08AE2558B994007E6B1C /* kmem.c */; }; 14 | C971686D255898070087FAD6 /* IOKernelMemoryApeture.hpp in Headers */ = {isa = PBXBuildFile; fileRef = C971686C255898070087FAD6 /* IOKernelMemoryApeture.hpp */; }; 15 | C971686F255898070087FAD6 /* IOKernelMemoryApeture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C971686E255898070087FAD6 /* IOKernelMemoryApeture.cpp */; }; 16 | C9716880255898DC0087FAD6 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C971687F255898DC0087FAD6 /* main.cpp */; }; 17 | C971688725589B870087FAD6 /* kmem_api.h in Headers */ = {isa = PBXBuildFile; fileRef = C971688625589B870087FAD6 /* kmem_api.h */; }; 18 | C971688C2558A3000087FAD6 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C971688B2558A3000087FAD6 /* IOKit.framework */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXCopyFilesBuildPhase section */ 22 | C971687B255898DC0087FAD6 /* CopyFiles */ = { 23 | isa = PBXCopyFilesBuildPhase; 24 | buildActionMask = 2147483647; 25 | dstPath = /usr/share/man/man1/; 26 | dstSubfolderSpec = 0; 27 | files = ( 28 | ); 29 | runOnlyForDeploymentPostprocessing = 1; 30 | }; 31 | /* End PBXCopyFilesBuildPhase section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | C95E08852558AF2D007E6B1C /* kmem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = kmem.h; sourceTree = ""; }; 35 | C95E08892558AF53007E6B1C /* IOKernelMemoryUserClient.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = IOKernelMemoryUserClient.cpp; sourceTree = ""; }; 36 | C95E088A2558AF53007E6B1C /* IOKernelMemoryUserClient.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = IOKernelMemoryUserClient.hpp; sourceTree = ""; }; 37 | C95E08A92558B582007E6B1C /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 38 | C95E08AE2558B994007E6B1C /* kmem.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = kmem.c; sourceTree = ""; }; 39 | C9716869255898070087FAD6 /* kmem.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = kmem.kext; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | C971686C255898070087FAD6 /* IOKernelMemoryApeture.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = IOKernelMemoryApeture.hpp; sourceTree = ""; }; 41 | C971686E255898070087FAD6 /* IOKernelMemoryApeture.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = IOKernelMemoryApeture.cpp; sourceTree = ""; }; 42 | C9716870255898070087FAD6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43 | C9716878255898BA0087FAD6 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; 44 | C971687D255898DC0087FAD6 /* kmemclient */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = kmemclient; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | C971687F255898DC0087FAD6 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; 46 | C971688625589B870087FAD6 /* kmem_api.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = kmem_api.h; sourceTree = ""; }; 47 | C971688B2558A3000087FAD6 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; 48 | /* End PBXFileReference section */ 49 | 50 | /* Begin PBXFrameworksBuildPhase section */ 51 | C9716866255898070087FAD6 /* Frameworks */ = { 52 | isa = PBXFrameworksBuildPhase; 53 | buildActionMask = 2147483647; 54 | files = ( 55 | ); 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | C971687A255898DC0087FAD6 /* Frameworks */ = { 59 | isa = PBXFrameworksBuildPhase; 60 | buildActionMask = 2147483647; 61 | files = ( 62 | C971688C2558A3000087FAD6 /* IOKit.framework in Frameworks */, 63 | ); 64 | runOnlyForDeploymentPostprocessing = 0; 65 | }; 66 | /* End PBXFrameworksBuildPhase section */ 67 | 68 | /* Begin PBXGroup section */ 69 | C971685F255898070087FAD6 = { 70 | isa = PBXGroup; 71 | children = ( 72 | C95E08A92558B582007E6B1C /* README.md */, 73 | C9716877255898A40087FAD6 /* kmemclient */, 74 | C971686B255898070087FAD6 /* kmem */, 75 | C971687E255898DC0087FAD6 /* kmemclient */, 76 | C971686A255898070087FAD6 /* Products */, 77 | C971688A2558A3000087FAD6 /* Frameworks */, 78 | ); 79 | sourceTree = ""; 80 | }; 81 | C971686A255898070087FAD6 /* Products */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | C9716869255898070087FAD6 /* kmem.kext */, 85 | C971687D255898DC0087FAD6 /* kmemclient */, 86 | ); 87 | name = Products; 88 | sourceTree = ""; 89 | }; 90 | C971686B255898070087FAD6 /* kmem */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | C971686C255898070087FAD6 /* IOKernelMemoryApeture.hpp */, 94 | C971686E255898070087FAD6 /* IOKernelMemoryApeture.cpp */, 95 | C9716870255898070087FAD6 /* Info.plist */, 96 | C971688625589B870087FAD6 /* kmem_api.h */, 97 | C95E08852558AF2D007E6B1C /* kmem.h */, 98 | C95E08892558AF53007E6B1C /* IOKernelMemoryUserClient.cpp */, 99 | C95E088A2558AF53007E6B1C /* IOKernelMemoryUserClient.hpp */, 100 | C95E08AE2558B994007E6B1C /* kmem.c */, 101 | ); 102 | path = kmem; 103 | sourceTree = ""; 104 | }; 105 | C9716877255898A40087FAD6 /* kmemclient */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | C9716878255898BA0087FAD6 /* main.cpp */, 109 | ); 110 | path = kmemclient; 111 | sourceTree = ""; 112 | }; 113 | C971687E255898DC0087FAD6 /* kmemclient */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | C971687F255898DC0087FAD6 /* main.cpp */, 117 | ); 118 | path = kmemclient; 119 | sourceTree = ""; 120 | }; 121 | C971688A2558A3000087FAD6 /* Frameworks */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | C971688B2558A3000087FAD6 /* IOKit.framework */, 125 | ); 126 | name = Frameworks; 127 | sourceTree = ""; 128 | }; 129 | /* End PBXGroup section */ 130 | 131 | /* Begin PBXHeadersBuildPhase section */ 132 | C9716864255898070087FAD6 /* Headers */ = { 133 | isa = PBXHeadersBuildPhase; 134 | buildActionMask = 2147483647; 135 | files = ( 136 | C971686D255898070087FAD6 /* IOKernelMemoryApeture.hpp in Headers */, 137 | C95E08862558AF2D007E6B1C /* kmem.h in Headers */, 138 | C95E088C2558AF53007E6B1C /* IOKernelMemoryUserClient.hpp in Headers */, 139 | C971688725589B870087FAD6 /* kmem_api.h in Headers */, 140 | ); 141 | runOnlyForDeploymentPostprocessing = 0; 142 | }; 143 | /* End PBXHeadersBuildPhase section */ 144 | 145 | /* Begin PBXNativeTarget section */ 146 | C9716868255898070087FAD6 /* kmem */ = { 147 | isa = PBXNativeTarget; 148 | buildConfigurationList = C9716873255898070087FAD6 /* Build configuration list for PBXNativeTarget "kmem" */; 149 | buildPhases = ( 150 | C9716864255898070087FAD6 /* Headers */, 151 | C9716865255898070087FAD6 /* Sources */, 152 | C9716866255898070087FAD6 /* Frameworks */, 153 | C9716867255898070087FAD6 /* Resources */, 154 | ); 155 | buildRules = ( 156 | ); 157 | dependencies = ( 158 | ); 159 | name = kmem; 160 | productName = kmem; 161 | productReference = C9716869255898070087FAD6 /* kmem.kext */; 162 | productType = "com.apple.product-type.kernel-extension"; 163 | }; 164 | C971687C255898DC0087FAD6 /* kmemclient */ = { 165 | isa = PBXNativeTarget; 166 | buildConfigurationList = C9716881255898DC0087FAD6 /* Build configuration list for PBXNativeTarget "kmemclient" */; 167 | buildPhases = ( 168 | C9716879255898DC0087FAD6 /* Sources */, 169 | C971687A255898DC0087FAD6 /* Frameworks */, 170 | C971687B255898DC0087FAD6 /* CopyFiles */, 171 | ); 172 | buildRules = ( 173 | ); 174 | dependencies = ( 175 | ); 176 | name = kmemclient; 177 | productName = kmemclient; 178 | productReference = C971687D255898DC0087FAD6 /* kmemclient */; 179 | productType = "com.apple.product-type.tool"; 180 | }; 181 | /* End PBXNativeTarget section */ 182 | 183 | /* Begin PBXProject section */ 184 | C9716860255898070087FAD6 /* Project object */ = { 185 | isa = PBXProject; 186 | attributes = { 187 | LastUpgradeCheck = 1220; 188 | TargetAttributes = { 189 | C9716868255898070087FAD6 = { 190 | CreatedOnToolsVersion = 12.2; 191 | }; 192 | C971687C255898DC0087FAD6 = { 193 | CreatedOnToolsVersion = 12.2; 194 | }; 195 | }; 196 | }; 197 | buildConfigurationList = C9716863255898070087FAD6 /* Build configuration list for PBXProject "kmem" */; 198 | compatibilityVersion = "Xcode 9.3"; 199 | developmentRegion = en; 200 | hasScannedForEncodings = 0; 201 | knownRegions = ( 202 | en, 203 | Base, 204 | ); 205 | mainGroup = C971685F255898070087FAD6; 206 | productRefGroup = C971686A255898070087FAD6 /* Products */; 207 | projectDirPath = ""; 208 | projectRoot = ""; 209 | targets = ( 210 | C9716868255898070087FAD6 /* kmem */, 211 | C971687C255898DC0087FAD6 /* kmemclient */, 212 | ); 213 | }; 214 | /* End PBXProject section */ 215 | 216 | /* Begin PBXResourcesBuildPhase section */ 217 | C9716867255898070087FAD6 /* Resources */ = { 218 | isa = PBXResourcesBuildPhase; 219 | buildActionMask = 2147483647; 220 | files = ( 221 | ); 222 | runOnlyForDeploymentPostprocessing = 0; 223 | }; 224 | /* End PBXResourcesBuildPhase section */ 225 | 226 | /* Begin PBXSourcesBuildPhase section */ 227 | C9716865255898070087FAD6 /* Sources */ = { 228 | isa = PBXSourcesBuildPhase; 229 | buildActionMask = 2147483647; 230 | files = ( 231 | C95E08AF2558B994007E6B1C /* kmem.c in Sources */, 232 | C971686F255898070087FAD6 /* IOKernelMemoryApeture.cpp in Sources */, 233 | C95E088B2558AF53007E6B1C /* IOKernelMemoryUserClient.cpp in Sources */, 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | }; 237 | C9716879255898DC0087FAD6 /* Sources */ = { 238 | isa = PBXSourcesBuildPhase; 239 | buildActionMask = 2147483647; 240 | files = ( 241 | C9716880255898DC0087FAD6 /* main.cpp in Sources */, 242 | ); 243 | runOnlyForDeploymentPostprocessing = 0; 244 | }; 245 | /* End PBXSourcesBuildPhase section */ 246 | 247 | /* Begin XCBuildConfiguration section */ 248 | C9716871255898070087FAD6 /* Debug */ = { 249 | isa = XCBuildConfiguration; 250 | buildSettings = { 251 | ALWAYS_SEARCH_USER_PATHS = NO; 252 | CLANG_ANALYZER_NONNULL = YES; 253 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 254 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 255 | CLANG_CXX_LIBRARY = "libc++"; 256 | CLANG_ENABLE_MODULES = YES; 257 | CLANG_ENABLE_OBJC_ARC = YES; 258 | CLANG_ENABLE_OBJC_WEAK = YES; 259 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 260 | CLANG_WARN_BOOL_CONVERSION = YES; 261 | CLANG_WARN_COMMA = YES; 262 | CLANG_WARN_CONSTANT_CONVERSION = YES; 263 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 264 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 265 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 266 | CLANG_WARN_EMPTY_BODY = YES; 267 | CLANG_WARN_ENUM_CONVERSION = YES; 268 | CLANG_WARN_INFINITE_RECURSION = YES; 269 | CLANG_WARN_INT_CONVERSION = YES; 270 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 271 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 272 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 273 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 274 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 275 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 276 | CLANG_WARN_STRICT_PROTOTYPES = YES; 277 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 278 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 279 | CLANG_WARN_UNREACHABLE_CODE = YES; 280 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 281 | COPY_PHASE_STRIP = NO; 282 | DEBUG_INFORMATION_FORMAT = dwarf; 283 | ENABLE_STRICT_OBJC_MSGSEND = YES; 284 | ENABLE_TESTABILITY = YES; 285 | GCC_C_LANGUAGE_STANDARD = gnu11; 286 | GCC_DYNAMIC_NO_PIC = NO; 287 | GCC_NO_COMMON_BLOCKS = YES; 288 | GCC_OPTIMIZATION_LEVEL = 0; 289 | GCC_PREPROCESSOR_DEFINITIONS = ( 290 | "DEBUG=1", 291 | "$(inherited)", 292 | ); 293 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 294 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 295 | GCC_WARN_UNDECLARED_SELECTOR = YES; 296 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 297 | GCC_WARN_UNUSED_FUNCTION = YES; 298 | GCC_WARN_UNUSED_VARIABLE = YES; 299 | MACOSX_DEPLOYMENT_TARGET = 11.0; 300 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 301 | MTL_FAST_MATH = YES; 302 | ONLY_ACTIVE_ARCH = YES; 303 | SDKROOT = macosx; 304 | }; 305 | name = Debug; 306 | }; 307 | C9716872255898070087FAD6 /* Release */ = { 308 | isa = XCBuildConfiguration; 309 | buildSettings = { 310 | ALWAYS_SEARCH_USER_PATHS = NO; 311 | CLANG_ANALYZER_NONNULL = YES; 312 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 313 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 314 | CLANG_CXX_LIBRARY = "libc++"; 315 | CLANG_ENABLE_MODULES = YES; 316 | CLANG_ENABLE_OBJC_ARC = YES; 317 | CLANG_ENABLE_OBJC_WEAK = YES; 318 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 319 | CLANG_WARN_BOOL_CONVERSION = YES; 320 | CLANG_WARN_COMMA = YES; 321 | CLANG_WARN_CONSTANT_CONVERSION = YES; 322 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 323 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 324 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 325 | CLANG_WARN_EMPTY_BODY = YES; 326 | CLANG_WARN_ENUM_CONVERSION = YES; 327 | CLANG_WARN_INFINITE_RECURSION = YES; 328 | CLANG_WARN_INT_CONVERSION = YES; 329 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 330 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 331 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 333 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 334 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 335 | CLANG_WARN_STRICT_PROTOTYPES = YES; 336 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 337 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 338 | CLANG_WARN_UNREACHABLE_CODE = YES; 339 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 340 | COPY_PHASE_STRIP = NO; 341 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 342 | ENABLE_NS_ASSERTIONS = NO; 343 | ENABLE_STRICT_OBJC_MSGSEND = YES; 344 | GCC_C_LANGUAGE_STANDARD = gnu11; 345 | GCC_NO_COMMON_BLOCKS = YES; 346 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 347 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 348 | GCC_WARN_UNDECLARED_SELECTOR = YES; 349 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 350 | GCC_WARN_UNUSED_FUNCTION = YES; 351 | GCC_WARN_UNUSED_VARIABLE = YES; 352 | MACOSX_DEPLOYMENT_TARGET = 11.0; 353 | MTL_ENABLE_DEBUG_INFO = NO; 354 | MTL_FAST_MATH = YES; 355 | SDKROOT = macosx; 356 | }; 357 | name = Release; 358 | }; 359 | C9716874255898070087FAD6 /* Debug */ = { 360 | isa = XCBuildConfiguration; 361 | buildSettings = { 362 | ARCHS = "$(ARCHS_STANDARD)"; 363 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; 364 | CODE_SIGN_IDENTITY = "Apple Development"; 365 | "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; 366 | CODE_SIGN_STYLE = Automatic; 367 | COMBINE_HIDPI_IMAGES = YES; 368 | CURRENT_PROJECT_VERSION = 1.0.0d1; 369 | DEVELOPMENT_TEAM = ZK96P738ZR; 370 | INFOPLIST_FILE = kmem/Info.plist; 371 | INSTALL_GROUP = root; 372 | INSTALL_OWNER = root; 373 | MACOSX_DEPLOYMENT_TARGET = 11.0; 374 | MODULE_NAME = me.rickmark.kmem; 375 | MODULE_VERSION = 1.0.0d1; 376 | PRODUCT_BUNDLE_IDENTIFIER = me.rickmark.kmem; 377 | PRODUCT_NAME = "$(TARGET_NAME)"; 378 | PROVISIONING_PROFILE_SPECIFIER = ""; 379 | RUN_CLANG_STATIC_ANALYZER = YES; 380 | WRAPPER_EXTENSION = kext; 381 | }; 382 | name = Debug; 383 | }; 384 | C9716875255898070087FAD6 /* Release */ = { 385 | isa = XCBuildConfiguration; 386 | buildSettings = { 387 | ARCHS = "$(ARCHS_STANDARD)"; 388 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; 389 | CODE_SIGN_IDENTITY = "Apple Development"; 390 | "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; 391 | CODE_SIGN_STYLE = Automatic; 392 | COMBINE_HIDPI_IMAGES = YES; 393 | CURRENT_PROJECT_VERSION = 1.0.0d1; 394 | DEVELOPMENT_TEAM = ZK96P738ZR; 395 | INFOPLIST_FILE = kmem/Info.plist; 396 | INSTALL_GROUP = root; 397 | INSTALL_OWNER = root; 398 | MACOSX_DEPLOYMENT_TARGET = 11.0; 399 | MODULE_NAME = me.rickmark.kmem; 400 | MODULE_VERSION = 1.0.0d1; 401 | PRODUCT_BUNDLE_IDENTIFIER = me.rickmark.kmem; 402 | PRODUCT_NAME = "$(TARGET_NAME)"; 403 | PROVISIONING_PROFILE_SPECIFIER = ""; 404 | RUN_CLANG_STATIC_ANALYZER = YES; 405 | WRAPPER_EXTENSION = kext; 406 | }; 407 | name = Release; 408 | }; 409 | C9716882255898DC0087FAD6 /* Debug */ = { 410 | isa = XCBuildConfiguration; 411 | buildSettings = { 412 | CODE_SIGN_STYLE = Automatic; 413 | DEVELOPMENT_TEAM = ZK96P738ZR; 414 | ENABLE_HARDENED_RUNTIME = YES; 415 | PRODUCT_NAME = "$(TARGET_NAME)"; 416 | }; 417 | name = Debug; 418 | }; 419 | C9716883255898DC0087FAD6 /* Release */ = { 420 | isa = XCBuildConfiguration; 421 | buildSettings = { 422 | CODE_SIGN_STYLE = Automatic; 423 | DEVELOPMENT_TEAM = ZK96P738ZR; 424 | ENABLE_HARDENED_RUNTIME = YES; 425 | PRODUCT_NAME = "$(TARGET_NAME)"; 426 | }; 427 | name = Release; 428 | }; 429 | /* End XCBuildConfiguration section */ 430 | 431 | /* Begin XCConfigurationList section */ 432 | C9716863255898070087FAD6 /* Build configuration list for PBXProject "kmem" */ = { 433 | isa = XCConfigurationList; 434 | buildConfigurations = ( 435 | C9716871255898070087FAD6 /* Debug */, 436 | C9716872255898070087FAD6 /* Release */, 437 | ); 438 | defaultConfigurationIsVisible = 0; 439 | defaultConfigurationName = Release; 440 | }; 441 | C9716873255898070087FAD6 /* Build configuration list for PBXNativeTarget "kmem" */ = { 442 | isa = XCConfigurationList; 443 | buildConfigurations = ( 444 | C9716874255898070087FAD6 /* Debug */, 445 | C9716875255898070087FAD6 /* Release */, 446 | ); 447 | defaultConfigurationIsVisible = 0; 448 | defaultConfigurationName = Release; 449 | }; 450 | C9716881255898DC0087FAD6 /* Build configuration list for PBXNativeTarget "kmemclient" */ = { 451 | isa = XCConfigurationList; 452 | buildConfigurations = ( 453 | C9716882255898DC0087FAD6 /* Debug */, 454 | C9716883255898DC0087FAD6 /* Release */, 455 | ); 456 | defaultConfigurationIsVisible = 0; 457 | defaultConfigurationName = Release; 458 | }; 459 | /* End XCConfigurationList section */ 460 | }; 461 | rootObject = C9716860255898070087FAD6 /* Project object */; 462 | } 463 | -------------------------------------------------------------------------------- /kmem.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /kmem.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /kmem.xcodeproj/project.xcworkspace/xcuserdata/rickmark.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hack-different/kext-kmem/f89a31ce4fbaac98fd7df38380f7d798a992f720/kmem.xcodeproj/project.xcworkspace/xcuserdata/rickmark.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /kmem.xcodeproj/xcshareddata/xcschemes/Build All.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 46 | 47 | 57 | 58 | 64 | 65 | 71 | 72 | 73 | 74 | 76 | 77 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /kmem.xcodeproj/xcshareddata/xcschemes/kmem.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /kmem.xcodeproj/xcshareddata/xcschemes/kmemclient.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 57 | 58 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /kmem.xcodeproj/xcuserdata/rickmark.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /kmem.xcodeproj/xcuserdata/rickmark.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Build All.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 1 11 | 12 | kmem.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 2 16 | 17 | kmemclient.xcscheme_^#shared#^_ 18 | 19 | orderHint 20 | 0 21 | 22 | 23 | SuppressBuildableAutocreation 24 | 25 | C9716868255898070087FAD6 26 | 27 | primary 28 | 29 | 30 | C971687C255898DC0087FAD6 31 | 32 | primary 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /kmem/IOKernelMemoryApeture.cpp: -------------------------------------------------------------------------------- 1 | /* add your code here */ 2 | 3 | #include "IOKernelMemoryApeture.hpp" 4 | 5 | #define super IOService 6 | 7 | OSDefineMetaClassAndStructors(IOKernelMemoryApeture, IOService); 8 | 9 | 10 | bool IOKernelMemoryApeture::start(IOService *provider) { 11 | IOLog("kmem: Executing 'IOKernelMemoryApeture::start()'.\n"); 12 | 13 | bool superStart = super::start(provider); 14 | if (superStart) { 15 | IODebug("Calling 'IOKernelMemory:registerService()'."); 16 | registerService(); 17 | } 18 | 19 | return superStart; 20 | } 21 | 22 | 23 | void IOKernelMemoryApeture::stop(IOService *provider) { 24 | IODebug("Executing 'IOKernelMemoryApeture:stop()'."); 25 | 26 | super::stop(provider); 27 | } 28 | 29 | bool IOKernelMemoryApeture::init(OSDictionary *dictionary) { 30 | IODebug("Executing 'IOKernelMemoryApeture:init()'."); 31 | 32 | return super::init(dictionary); 33 | } 34 | 35 | void IOKernelMemoryApeture::free() { 36 | IODebug("Executing 'IOKernelMemoryApeture:free()'."); 37 | 38 | super::free(); 39 | } 40 | -------------------------------------------------------------------------------- /kmem/IOKernelMemoryApeture.hpp: -------------------------------------------------------------------------------- 1 | /* add your code here */ 2 | 3 | #ifndef IOKernelMemoryApeture_hpp 4 | #define IOKernelMemoryApeture_hpp 5 | 6 | #include 7 | #include 8 | #include "kmem.h" 9 | 10 | class IOKernelMemoryApeture : IOService { 11 | OSDeclareDefaultStructors(IOKernelMemoryApeture) 12 | 13 | public: 14 | virtual bool init(OSDictionary *dictionary = 0) override; 15 | virtual void free(void) override; 16 | 17 | virtual bool start(IOService *provider) override; 18 | virtual void stop(IOService *provider) override; 19 | 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /kmem/IOKernelMemoryUserClient.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // IOKernelMemoryUserClient.cpp 3 | // kmem 4 | // 5 | // Created by Rick Mark on 11/8/20. 6 | // 7 | 8 | #include "IOKernelMemoryUserClient.hpp" 9 | 10 | #if __LP64__ 11 | extern struct mach_header_64 __dso_handle; 12 | #else 13 | extern struct mach_header __dso_handle; 14 | #endif 15 | 16 | #define super IOUserClient 17 | 18 | 19 | OSDefineMetaClassAndStructors(IOKernelMemoryApetureUserClient, IOUserClient) 20 | 21 | const IOExternalMethodDispatch IOKernelMemoryApetureUserClient::s_methods[kIOKernelMemoryApetureMethodCount] = { 22 | {(IOExternalMethodAction)&IOKernelMemoryApetureUserClient::actionMethodReadVirtual, 3, 0, 8, 0}, 23 | {(IOExternalMethodAction)&IOKernelMemoryApetureUserClient::actionMethodReadPhysical, 3, 0, 0, 0}, 24 | {(IOExternalMethodAction)&IOKernelMemoryApetureUserClient::actionMethodHeaderAddress, 0, 0, 1, 0}, 25 | {(IOExternalMethodAction)&IOKernelMemoryApetureUserClient::actionMethodCodeAddress, 0, 0, 1, 0}, 26 | }; 27 | 28 | bool IOKernelMemoryApetureUserClient::initWithTask(task_t owningTask, void *securityToken, UInt32 type, OSDictionary *properties) { 29 | IOLog("kmem: Executing 'IOKernelMemoryApetureUserClient::initWithTask()'.\n"); 30 | 31 | 32 | if (!owningTask) { 33 | return false; 34 | } 35 | 36 | if (!super::initWithTask(owningTask, securityToken, type, properties)) { 37 | return false; 38 | } 39 | 40 | this->m_owner = owningTask; 41 | 42 | return true; 43 | } 44 | 45 | bool IOKernelMemoryApetureUserClient::start(IOService *provider) { 46 | IODebug("Executing 'IOKernelMemoryApetureUserClient::start()'."); 47 | 48 | if (!super::start(provider)) { 49 | return false; 50 | } 51 | 52 | this->m_apeture = OSDynamicCast(IOKernelMemoryApeture, provider); 53 | if (!this->m_apeture) { 54 | return false; 55 | } 56 | 57 | return true; 58 | } 59 | 60 | void IOKernelMemoryApetureUserClient::stop(IOService *provider) { 61 | IODebug("Executing 'IOKernelMemoryApetureUserClient::stop()'."); 62 | super::stop(provider); 63 | } 64 | 65 | IOReturn IOKernelMemoryApetureUserClient::clientClose() { 66 | if (this->m_apeture) { 67 | this->close((IOService*)this->m_apeture); 68 | this->m_apeture = nullptr; 69 | } 70 | 71 | if (this->m_owner) { 72 | this->m_owner = nullptr; 73 | } 74 | 75 | this->terminate(); 76 | 77 | return kIOReturnSuccess; 78 | } 79 | 80 | IOReturn IOKernelMemoryApetureUserClient::externalMethod(uint32_t selector, IOExternalMethodArguments *arguments, IOExternalMethodDispatch *dispatch, OSObject *target, void *reference) { 81 | 82 | if (selector >= kIOKernelMemoryApetureMethodCount) { 83 | return kIOReturnUnsupported; 84 | } 85 | 86 | dispatch = (IOExternalMethodDispatch*)&s_methods[selector]; 87 | target = this; 88 | reference = nullptr; 89 | 90 | return super::externalMethod(selector, arguments, dispatch, target, reference); 91 | } 92 | 93 | IOReturn IOKernelMemoryApetureUserClient::actionMethodReadVirtual(IOKernelMemoryApetureUserClient *target, void *reference, 94 | IOExternalMethodArguments *arguments) { 95 | return target->methodReadVirtual(arguments); 96 | } 97 | 98 | IOReturn IOKernelMemoryApetureUserClient::actionMethodReadPhysical(IOKernelMemoryApetureUserClient *target, void *reference, 99 | IOExternalMethodArguments *arguments) { 100 | return target->methodReadPhysical(arguments); 101 | } 102 | 103 | IOReturn IOKernelMemoryApetureUserClient::actionMethodHeaderAddress(IOKernelMemoryApetureUserClient *target, void *reference, 104 | IOExternalMethodArguments *arguments) { 105 | return target->methodHeaderAddress(arguments); 106 | } 107 | 108 | IOReturn IOKernelMemoryApetureUserClient::actionMethodCodeAddress(IOKernelMemoryApetureUserClient *target, void *reference, 109 | IOExternalMethodArguments *arguments) { 110 | return target->methodCodeAddress(arguments); 111 | } 112 | 113 | IOReturn IOKernelMemoryApetureUserClient::methodHeaderAddress(IOExternalMethodArguments *arguments) { 114 | IOLog("kmem: Executing 'IOKernelMemoryApetureUserClient::methodHeaderAddress()'.\n"); 115 | arguments->scalarOutput[0] = (uint64_t)&__dso_handle; 116 | return kIOReturnSuccess; 117 | } 118 | 119 | __attribute__((noinline)) 120 | static uint64_t get_code_addr(void) { 121 | return (uint64_t)__builtin_return_address(0); 122 | } 123 | 124 | IOReturn IOKernelMemoryApetureUserClient::methodCodeAddress(IOExternalMethodArguments *arguments) { 125 | IOLog("kmem: Executing 'IOKernelMemoryApetureUserClient::methodCodeAddress()'.\n"); 126 | arguments->scalarOutput[0] = get_code_addr(); 127 | return kIOReturnSuccess; 128 | } 129 | 130 | IOReturn IOKernelMemoryApetureUserClient::methodReadVirtual(IOExternalMethodArguments *arguments) { 131 | IOLog("kmem: Executing 'IOKernelMemoryApetureUserClient::methodReadVirtual()'.\n"); 132 | 133 | void* targetAddress = (void*)arguments->scalarInput[0]; 134 | size_t targetSize = (size_t)arguments->scalarInput[1]; 135 | mach_vm_address_t userMemoryBuffer = (mach_vm_address_t)arguments->scalarInput[2]; 136 | 137 | IOMemoryDescriptor* userBuffer = IOMemoryDescriptor::withAddressRange(userMemoryBuffer, targetSize, kIOMemoryDirectionOut, this->m_owner); 138 | 139 | kern_return_t prepareResult = userBuffer->prepare(kIOMemoryDirectionOut); 140 | if (prepareResult != KERN_SUCCESS) { 141 | OSSafeReleaseNULL(userBuffer); 142 | return prepareResult; 143 | } 144 | 145 | IOMemoryMap* kernelMapping = userBuffer->map(); 146 | if (kernelMapping == nullptr) { 147 | userBuffer->complete(); 148 | OSSafeReleaseNULL(userBuffer); 149 | return kIOReturnVMError; 150 | } 151 | 152 | // arguments->scalarOutput[0] = kernelMapping->getAddress(); 153 | arguments->scalarOutput[0] = 0xdeadbeef; 154 | arguments->scalarOutput[1] = (int64_t)targetAddress; 155 | arguments->scalarOutput[2] = userBuffer->getPhysicalAddress(); 156 | arguments->scalarOutput[3] = kernelMapping->getVirtualAddress(); 157 | arguments->scalarOutput[4] = kernelMapping->getSize(); 158 | // arguments->scalarOutput[5] = kernelMapping->getAddress(); 159 | arguments->scalarOutput[5] = 0xbaadc0de; 160 | memcpy(&arguments->scalarOutput[6], (void*)kernelMapping->getVirtualAddress(), sizeof(uint64_t)); 161 | arguments->scalarOutput[7] = kernelMapping->getPhysicalAddress(); 162 | 163 | 164 | // memset((void*)userBuffer->getVirtualAddress(), 0x41, targetSize); 165 | //memcpy((void*)kernelMapping->getVirtualAddress(), &markerValue, sizeof(uint64_t)); 166 | 167 | // userBuffer->writeBytes(0, targetAddress, targetSize); 168 | memcpy((void*)kernelMapping->getVirtualAddress(), targetAddress, targetSize); 169 | 170 | kernelMapping->unmap(); 171 | OSSafeReleaseNULL(kernelMapping); 172 | 173 | 174 | 175 | kern_return_t completeResult = userBuffer->complete(); 176 | 177 | if (completeResult != KERN_SUCCESS) { 178 | OSSafeReleaseNULL(userBuffer); 179 | return completeResult; 180 | } 181 | 182 | OSSafeReleaseNULL(userBuffer); 183 | return kIOReturnSuccess; 184 | } 185 | 186 | IOReturn IOKernelMemoryApetureUserClient::methodReadPhysical(IOExternalMethodArguments *arguments) { 187 | IOLog("kmem: Executing 'IOKernelMemoryApetureUserClient::methodReadPhysical()'.\n"); 188 | 189 | return kIOReturnSuccess; 190 | } 191 | -------------------------------------------------------------------------------- /kmem/IOKernelMemoryUserClient.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // IOKernelMemoryUserClient.hpp 3 | // kmem 4 | // 5 | // Created by Rick Mark on 11/8/20. 6 | // 7 | 8 | #ifndef IOKernelMemoryUserClient_hpp 9 | #define IOKernelMemoryUserClient_hpp 10 | 11 | 12 | #include 13 | #include 14 | #include "kmem.h" 15 | #include "IOKernelMemoryApeture.hpp" 16 | 17 | class IOKernelMemoryApetureUserClient : public IOUserClient { 18 | OSDeclareDefaultStructors(IOKernelMemoryApetureUserClient); 19 | 20 | public: 21 | virtual bool initWithTask(task_t owningTask, void *securityToken, 22 | UInt32 type, OSDictionary *properties) override; 23 | 24 | virtual bool start(IOService *provider) override; 25 | virtual void stop(IOService *provider) override; 26 | 27 | virtual IOReturn clientClose() override; 28 | 29 | virtual IOReturn externalMethod(uint32_t selector, 30 | IOExternalMethodArguments *arguments, 31 | IOExternalMethodDispatch *dispatch, 32 | OSObject *target, void *reference) override; 33 | protected: 34 | /** 35 | * The following methods unpack/handle the given arguments and 36 | * call the related driver method. 37 | */ 38 | virtual IOReturn methodReadVirtual(IOExternalMethodArguments *arguments); 39 | virtual IOReturn methodReadPhysical(IOExternalMethodArguments *arguments); 40 | 41 | static IOReturn actionMethodReadVirtual(IOKernelMemoryApetureUserClient *target, void *reference, IOExternalMethodArguments *arguments); 42 | static IOReturn actionMethodReadPhysical(IOKernelMemoryApetureUserClient *target, void *reference,IOExternalMethodArguments *arguments); 43 | 44 | virtual IOReturn methodHeaderAddress(IOExternalMethodArguments *arguments); 45 | virtual IOReturn methodCodeAddress(IOExternalMethodArguments *arguments); 46 | 47 | static IOReturn actionMethodHeaderAddress(IOKernelMemoryApetureUserClient *target, void *reference, IOExternalMethodArguments *arguments); 48 | static IOReturn actionMethodCodeAddress(IOKernelMemoryApetureUserClient *target, void *reference,IOExternalMethodArguments *arguments); 49 | private: 50 | /** 51 | * Method dispatch table. 52 | */ 53 | static const IOExternalMethodDispatch s_methods[kIOKernelMemoryApetureMethodCount]; 54 | 55 | /** 56 | * Driver provider. 57 | */ 58 | IOKernelMemoryApeture *m_apeture = nullptr; 59 | 60 | /** 61 | * Userland subscriber. 62 | */ 63 | OSAsyncReference64 *m_subscriber = nullptr; 64 | 65 | /** 66 | * Task owner. 67 | */ 68 | task_t m_owner; 69 | }; 70 | 71 | 72 | #endif /* IOKernelMemoryUserClient_hpp */ 73 | -------------------------------------------------------------------------------- /kmem/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | LSApplicationCategoryType 6 | 7 | CFBundleDevelopmentRegion 8 | $(DEVELOPMENT_LANGUAGE) 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | IOKitPersonalities 24 | 25 | IOKernelMemoryApeture 26 | 27 | IOProviderClass 28 | IOResources 29 | IOMatchCategory 30 | IOKernelMemoryApeture 31 | IOResourceMatch 32 | IOKit 33 | IOUserClientClass 34 | IOKernelMemoryApetureUserClient 35 | IOClass 36 | IOKernelMemoryApeture 37 | CFBundleIdentifier 38 | $(PRODUCT_BUNDLE_IDENTIFIER) 39 | 40 | 41 | CFBundleDisplayName 42 | 43 | OSBundleLibraries 44 | 45 | com.apple.kpi.mach 46 | 9.0.0 47 | com.apple.kpi.libkern 48 | 9.0.0 49 | com.apple.kpi.iokit 50 | 9.0.0 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /kmem/kmem.c: -------------------------------------------------------------------------------- 1 | // 2 | // kmem.c 3 | // kmem 4 | // 5 | // Created by Rick Mark on 11/8/20. 6 | // 7 | 8 | #include "kmem.h" 9 | 10 | const char* kIOKernelMemoryApeture = "IOKernelMemoryApeture"; 11 | const char* kIOKernelMemoryUserClient = "IOKernelMemoryUserClient"; 12 | 13 | const uint32_t kIOKernelMemoryApetureDefault = 0; 14 | 15 | -------------------------------------------------------------------------------- /kmem/kmem.h: -------------------------------------------------------------------------------- 1 | // 2 | // kmem.h 3 | // kmem 4 | // 5 | // Created by Rick Mark on 11/8/20. 6 | // 7 | 8 | #ifndef kmem_h 9 | #define kmem_h 10 | 11 | #include 12 | 13 | #include "kmem_api.h" 14 | 15 | #define IODebug(fmt, ...) IOLog(("kmem: " fmt "\n"), ##__VA_ARGS__) 16 | 17 | #endif /* kmem_h */ 18 | -------------------------------------------------------------------------------- /kmem/kmem_api.h: -------------------------------------------------------------------------------- 1 | // 2 | // kmem_api.h 3 | // kmem 4 | // 5 | // Created by Rick Mark on 11/8/20. 6 | // 7 | 8 | #ifndef kmem_api_h 9 | #define kmem_api_h 10 | 11 | extern const char* kIOKernelMemoryApeture; 12 | extern const char* kIOKernelMemoryUserClient; 13 | 14 | extern const uint32_t kIOKernelMemoryApetureDefault; 15 | 16 | 17 | enum { 18 | kIOKernelMemoryApetureMethodReadVirtual, 19 | kIOKernelMemoryApetureMethodReadPhysical, 20 | // kIOKernelMemoryApetureMethodWriteVirtual, 21 | // kIOKernelMemoryApetureMethodWritePhysical, 22 | kIOKernelMemoryApetureMethodGetKextHeaderAddress, 23 | kIOKernelMemoryApetureMethodGetKextCodeAddress, 24 | 25 | kIOKernelMemoryApetureMethodCount 26 | }; 27 | 28 | 29 | typedef struct { 30 | void* address; 31 | size_t size; 32 | } kmem_read_t; 33 | 34 | 35 | #endif /* kmem_api_h */ 36 | -------------------------------------------------------------------------------- /kmemclient/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // kmemclient 4 | // 5 | // Created by Rick Mark on 11/8/20. 6 | // 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "kmem_api.h" 13 | 14 | 15 | const char* kIOKernelMemoryApeture = "IOKernelMemoryApeture"; 16 | const char* kIOKernelMemoryUserClient = "IOKernelMemoryUserClient"; 17 | 18 | const uint32_t kIOKernelMemoryApetureDefault = 0; 19 | 20 | 21 | 22 | static const long hextable[] = { 23 | ['0'] = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // faster for most modern processors, 24 | ['A'] = 10, 11, 12, 13, 14, 15, // for the space conscious, reduce to 25 | ['a'] = 10, 11, 12, 13, 14, 15 // signed char. 26 | }; 27 | 28 | uint64_t parseHex(const char* input) { 29 | if (strlen(input) > 2 && input[0] == '0' && input[1] == 'x') { 30 | input += 2; 31 | uint64_t result = 0; 32 | while (*input && result >= 0) { 33 | result = (result << 4) | hextable[*input++]; 34 | } 35 | 36 | return result; 37 | } 38 | 39 | return atoi(input); 40 | } 41 | 42 | int main(int argc, const char * argv[]) { 43 | if (argc != 3) { 44 | std::cout << "Usage: kmemclient
\n"; 45 | return -1; 46 | } 47 | 48 | uint64_t targetAddress = parseHex(argv[1]); 49 | uint32_t targetSize = (uint32_t)parseHex(argv[2]); 50 | 51 | io_service_t service; 52 | io_connect_t connection; 53 | 54 | uint64_t input[3]; 55 | uint64_t output[8]; 56 | uint32_t outputCount = 8; 57 | 58 | input[0] = targetAddress; 59 | input[1] = targetSize; 60 | 61 | service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(kIOKernelMemoryApeture)); 62 | 63 | 64 | if (service == IO_OBJECT_NULL) { 65 | std::cerr << "Could not find the kernel side component IOKernelMemoryApeture\n"; 66 | return -2; 67 | } 68 | 69 | kern_return_t openResult = IOServiceOpen(service, mach_task_self(), kIOKernelMemoryApetureDefault, &connection); 70 | 71 | if (openResult != KERN_SUCCESS) { 72 | std::cerr << "Could not open the IOKernelMemoryApeture\n"; 73 | return -3; 74 | } 75 | 76 | outputCount = 1; 77 | kern_return_t hdrResult = IOConnectCallScalarMethod(connection, kIOKernelMemoryApetureMethodGetKextHeaderAddress, nullptr, 0, output, &outputCount); 78 | if (hdrResult != KERN_SUCCESS) { 79 | char hexError[16]; 80 | sprintf(hexError, "0x%X", hdrResult); 81 | std::cerr << "Unable to invoke hdr addr operation on the IOService: " << hexError << "\n"; 82 | return -5; 83 | } else { 84 | printf("kext header address: %p\n", (void*)output[0]); 85 | } 86 | 87 | outputCount = 1; 88 | kern_return_t codeResult = IOConnectCallScalarMethod(connection, kIOKernelMemoryApetureMethodGetKextCodeAddress, nullptr, 0, output, &outputCount); 89 | if (codeResult != KERN_SUCCESS) { 90 | char hexError[16]; 91 | sprintf(hexError, "0x%X", hdrResult); 92 | std::cerr << "Unable to invoke code addr operation on the IOService: " << hexError << "\n"; 93 | return -5; 94 | } else { 95 | printf("code header address: %p\n", (void*)output[0]); 96 | } 97 | 98 | #if 1 99 | 100 | outputCount = 8; 101 | void* outputBuffer = malloc(targetSize); 102 | if (!outputBuffer) { 103 | std::cerr << "Could not allocate user mode buffer with sufficant size.\n"; 104 | return -4; 105 | } 106 | 107 | memset(outputBuffer, 0x00, targetSize); 108 | fprintf(stderr, "user mode buffer: 0x%llX\n", (uint64_t)outputBuffer); 109 | 110 | input[2] = (uint64_t)outputBuffer; 111 | 112 | 113 | 114 | kern_return_t readResult = IOConnectCallScalarMethod(connection, kIOKernelMemoryApetureMethodReadVirtual, input, 3, output, &outputCount); 115 | 116 | if (readResult != KERN_SUCCESS) { 117 | char hexError[16]; 118 | sprintf(hexError, "0x%X", readResult); 119 | std::cerr << "Unable to invoke Read operation on the IOService: " << hexError << "\n"; 120 | return -5; 121 | } 122 | 123 | fprintf(stderr, "would have written %d bytes from 0x%llX -> 0x%llX\n", targetSize, output[1], output[0]); 124 | 125 | fprintf(stderr, "user buffer physical address: 0x%llX\n", output[2]); 126 | fprintf(stderr, "virtual address: 0x%llX\n", output[3]); 127 | fprintf(stderr, "size: %lld\n", output[4]); 128 | fprintf(stderr, "address: 0x%llX\n", output[5]); 129 | //fprintf(stderr, "physical address: %llX\n", output[6]); 130 | fprintf(stderr, "physical address: 0x%llX\n", output[7]); 131 | /* 132 | arguments->scalarOutput[2] = userBuffer->getPhysicalAddress(); 133 | arguments->scalarOutput[3] = kernelMapping->getVirtualAddress(); 134 | arguments->scalarOutput[4] = kernelMapping->getSize(); 135 | arguments->scalarOutput[5] = kernelMapping->getAddress(); 136 | arguments->scalarOutput[7] = kernelMapping->getPhysicalAddress(); 137 | */ 138 | // Output the bytes to STDOUT 139 | 140 | fwrite(outputBuffer, 1, targetSize, stdout); 141 | fflush(stdout); 142 | 143 | #endif 144 | 145 | return 0; 146 | } 147 | --------------------------------------------------------------------------------