├── .gitignore ├── .idea ├── .gitignore ├── compiler.xml ├── gradle.xml ├── misc.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── shocker │ │ └── hwbpapp │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── cpp │ │ ├── CMakeLists.txt │ │ ├── HwBreakpointManager.h │ │ ├── Hwbp.h │ │ ├── log.h │ │ └── native-lib.cpp │ ├── java │ │ └── com │ │ │ └── shocker │ │ │ └── hwbpapp │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── values-night │ │ └── themes.xml │ │ ├── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── themes.xml │ │ └── xml │ │ ├── backup_rules.xml │ │ └── data_extraction_rules.xml │ └── test │ └── java │ └── com │ └── shocker │ └── hwbpapp │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── img ├── app.jpg └── hw.jpg └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Shocker 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HwBpApp 2 | hwBreakpoint Test App 3 | 4 | [Android使用硬件断点调试app](https://pshocker.github.io/2022/09/20/Android%E4%BD%BF%E7%94%A8%E7%A1%AC%E4%BB%B6%E6%96%AD%E7%82%B9%E8%B0%83%E8%AF%95app/) 5 | 6 | Releases: 7 | **https://github.com/PShocker/PShocker.github.io/releases/tag/HwBpApp** 8 | 9 | ![](img/app.jpg) 10 | 11 | ![](img/hw.jpg) -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | } 4 | 5 | android { 6 | compileSdk 32 7 | 8 | defaultConfig { 9 | applicationId "com.shocker.hwbpapp" 10 | minSdk 21 11 | targetSdk 32 12 | versionCode 1 13 | versionName "1.0" 14 | 15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 16 | externalNativeBuild { 17 | cmake { 18 | cppFlags '' 19 | } 20 | } 21 | } 22 | 23 | buildTypes { 24 | release { 25 | minifyEnabled false 26 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 27 | } 28 | } 29 | compileOptions { 30 | sourceCompatibility JavaVersion.VERSION_1_8 31 | targetCompatibility JavaVersion.VERSION_1_8 32 | } 33 | externalNativeBuild { 34 | cmake { 35 | path file('src/main/cpp/CMakeLists.txt') 36 | version '3.18.1' 37 | } 38 | } 39 | buildFeatures { 40 | viewBinding true 41 | } 42 | } 43 | 44 | dependencies { 45 | 46 | implementation 'androidx.appcompat:appcompat:1.3.0' 47 | implementation 'com.google.android.material:material:1.4.0' 48 | implementation 'androidx.constraintlayout:constraintlayout:2.0.4' 49 | testImplementation 'junit:junit:4.13.2' 50 | androidTestImplementation 'androidx.test.ext:junit:1.1.3' 51 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' 52 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/androidTest/java/com/shocker/hwbpapp/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.shocker.hwbpapp; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | assertEquals("com.shocker.hwbpapp", appContext.getPackageName()); 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # For more information about using CMake with Android Studio, read the 2 | # documentation: https://d.android.com/studio/projects/add-native-code.html 3 | 4 | # Sets the minimum version of CMake required to build the native library. 5 | 6 | cmake_minimum_required(VERSION 3.18.1) 7 | 8 | # Declares and names the project. 9 | 10 | project("hwbpapp") 11 | 12 | # Creates and names a library, sets it as either STATIC 13 | # or SHARED, and provides the relative paths to its source code. 14 | # You can define multiple libraries, and CMake builds them for you. 15 | # Gradle automatically packages shared libraries with your APK. 16 | 17 | add_library( # Sets the name of the library. 18 | hwbpapp 19 | 20 | # Sets the library as a shared library. 21 | SHARED 22 | 23 | # Provides a relative path to your source file(s). 24 | native-lib.cpp) 25 | 26 | # Searches for a specified prebuilt library and stores the path as a 27 | # variable. Because CMake includes system libraries in the search path by 28 | # default, you only need to specify the name of the public NDK library 29 | # you want to add. CMake verifies that the library exists before 30 | # completing its build. 31 | 32 | find_library( # Sets the name of the path variable. 33 | log-lib 34 | 35 | # Specifies the name of the NDK library that 36 | # you want CMake to locate. 37 | log) 38 | 39 | # Specifies libraries CMake should link to your target library. You 40 | # can link multiple libraries, such as libraries you define in this 41 | # build script, prebuilt third-party libraries, or system libraries. 42 | 43 | target_link_libraries( # Specifies the target library. 44 | hwbpapp 45 | 46 | # Links the target library to the log library 47 | # included in the NDK. 48 | ${log-lib}) -------------------------------------------------------------------------------- /app/src/main/cpp/HwBreakpointManager.h: -------------------------------------------------------------------------------- 1 | #ifndef HW_BREAKPOINT_MANAGER_H_ 2 | #define HW_BREAKPOINT_MANAGER_H_ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | //当前驱动版本号 16 | #define SYS_VERSION 01 17 | #define DEV_FILENAME "/dev/hwBreakpointProc1" 18 | 19 | #ifndef __cplusplus 20 | #define true 1 21 | #define false 0 22 | typedef int bool; 23 | #endif 24 | 25 | typedef int BOOL; 26 | #define TRUE 1 27 | #define FALSE 0 28 | 29 | enum 30 | { 31 | HW_BREAKPOINT_LEN_1 = 1, 32 | HW_BREAKPOINT_LEN_2 = 2, 33 | HW_BREAKPOINT_LEN_4 = 4, 34 | HW_BREAKPOINT_LEN_8 = 8, 35 | }; 36 | 37 | enum 38 | { 39 | HW_BREAKPOINT_EMPTY = 0, 40 | HW_BREAKPOINT_R = 1, 41 | HW_BREAKPOINT_W = 2, 42 | HW_BREAKPOINT_RW = HW_BREAKPOINT_R | HW_BREAKPOINT_W, 43 | HW_BREAKPOINT_X = 4, 44 | HW_BREAKPOINT_INVALID = HW_BREAKPOINT_RW | HW_BREAKPOINT_X, 45 | }; 46 | #pragma pack(1) 47 | struct my_user_pt_regs 48 | { 49 | uint64_t regs[31]; 50 | uint64_t sp; 51 | uint64_t pc; 52 | uint64_t pstate; 53 | uint64_t orig_x0; 54 | uint64_t syscallno; 55 | }; 56 | 57 | struct USER_HIT_INFO 58 | { 59 | size_t hit_addr; //命中地址 60 | size_t hit_count; //命中次数 61 | struct my_user_pt_regs regs; //最后一次命中的寄存器数据 62 | }; 63 | struct HIT_CONDITIONS 64 | { 65 | char enable_regs[31]; 66 | char enable_sp; 67 | char enable_pc; 68 | char enable_pstate; 69 | char enable_orig_x0; 70 | char enable_syscallno; 71 | struct my_user_pt_regs regs; 72 | }; 73 | #pragma pack() 74 | 75 | #define MAJOR_NUM 100 76 | #define IOCTL_OPEN_PROCESS _IOR(MAJOR_NUM, 1, char *) //打开进程 77 | #define IOCTL_CLOSE_HANDLE _IOR(MAJOR_NUM, 2, char *) //关闭进程 78 | #define IOCTL_GET_NUM_BRPS _IOR(MAJOR_NUM, 3, char *) //获取CPU支持硬件执行断点的数量 79 | #define IOCTL_GET_NUM_WRPS _IOR(MAJOR_NUM, 4, char *) //获取CPU支持硬件访问断点的数量 80 | #define IOCTL_SET_HWBP_HIT_CONDITIONS _IOR(MAJOR_NUM, 5, char *) //设置硬件断点命中记录条件 81 | #define IOCTL_ADD_PROCESS_HWBP _IOR(MAJOR_NUM, 6, char *) //设置进程硬件断点 82 | #define IOCTL_DEL_PROCESS_HWBP _IOR(MAJOR_NUM, 7, char *) //删除进程硬件断点 83 | #define IOCTL_GET_HWBP_HIT_ADDR_COUNT _IOR(MAJOR_NUM, 8, char *) //获取硬件断点命中地址数量 84 | 85 | //声明 86 | ////////////////////////////////////////////////////////////////////////// 87 | //C语言形式接口: 88 | ///////////////////////////////////////////////////////////////////////// 89 | 90 | //连接驱动,返回值:驱动连接句柄,>=0代表成功 91 | static int hwBreakpointProcDriver_Connect(); 92 | 93 | //断开驱动,返回值:TRUE成功,FALSE失败 94 | static BOOL hwBreakpointProcDriver_Disconnect(int nDriverLink); 95 | 96 | //驱动_打开进程(进程PID),返回值:进程句柄,0为失败 97 | static uint64_t hwBreakpointProcDriver_OpenProcess(int nDriverLink, uint64_t pid); 98 | 99 | //驱动_获取CPU支持硬件执行断点的数量,返回值:TRUE成功,FALSE失败 100 | static int hwBreakpointProcDriver_GetNumBRPS(int nDriverLink); 101 | 102 | //驱动_获取CPU支持硬件访问断点的数量,返回值:TRUE成功,FALSE失败 103 | static int hwBreakpointProcDriver_GetNumWRPS(int nDriverLink); 104 | 105 | //驱动_设置硬件断点命中记录条件,返回值:TRUE成功,FALSE失败 106 | static BOOL hwBreakpointProcDriver_SetHwBpHitConditions( 107 | int nDriverLink, 108 | HIT_CONDITIONS *hitConditions); 109 | 110 | //驱动_新增硬件断点,返回值:TRUE成功,FALSE失败 111 | static uint64_t hwBreakpointProcDriver_AddProcessHwBp( 112 | int nDriverLink, 113 | uint64_t hProcess, 114 | uint64_t lpBaseAddress, 115 | uint64_t hwBreakpointLen, 116 | unsigned int hwBreakpointType); 117 | 118 | //驱动_删除硬件断点,返回值:TRUE成功,FALSE失败 119 | static BOOL hwBreakpointProcDriver_DelProcessHwBp( 120 | int nDriverLink, 121 | uint64_t hHwBreakpointHandle); 122 | 123 | //驱动_读取硬件断点命中记录信息,返回值:TRUE成功,FALSE失败 124 | static BOOL hwBreakpointProcDriver_ReadHwBpInfo( 125 | int nDriverLink, 126 | uint64_t hHwBreakpointHandle, 127 | std::vector &vOutput); 128 | 129 | //驱动_清除硬件断点命中记录信息,返回值:TRUE成功,FALSE失败 130 | static BOOL hwBreakpointProcDriver_CleanHwBpInfo(int nDriverLink); 131 | 132 | //驱动_关闭进程,返回值:TRUE成功,FALSE失败 133 | static BOOL hwBreakpointProcDriver_CloseHandle(int nDriverLink, uint64_t handle); 134 | 135 | ////////////////////////////////////////////////////////////////////////// 136 | //C++语言形式接口: 137 | ///////////////////////////////////////////////////////////////////////// 138 | #ifdef __cplusplus 139 | #include 140 | #include 141 | class CHwBreakpointManager 142 | { 143 | public: 144 | CHwBreakpointManager() 145 | { 146 | } 147 | ~CHwBreakpointManager() 148 | { 149 | DisconnectDriver(); 150 | } 151 | 152 | //连接驱动(错误代码),返回值:驱动连接句柄,>=0代表成功 153 | BOOL ConnectDriver(int &err) 154 | { 155 | if (m_nDriverLink >= 0) 156 | { 157 | return TRUE; 158 | } 159 | m_nDriverLink = hwBreakpointProcDriver_Connect(); 160 | if (m_nDriverLink < 0) 161 | { 162 | err = m_nDriverLink; 163 | return FALSE; 164 | } 165 | else 166 | { 167 | err = 0; 168 | } 169 | return TRUE; 170 | } 171 | 172 | //断开驱动,返回值:TRUE成功,FALSE失败 173 | BOOL DisconnectDriver() 174 | { 175 | if (m_nDriverLink >= 0) 176 | { 177 | hwBreakpointProcDriver_Disconnect(m_nDriverLink); 178 | m_nDriverLink = -1; 179 | return TRUE; 180 | } 181 | return FALSE; 182 | } 183 | 184 | //驱动是否连接正常,返回值:TRUE已连接,FALSE未连接 185 | BOOL IsDriverConnected() 186 | { 187 | return m_nDriverLink >= 0 ? TRUE : FALSE; 188 | } 189 | 190 | //驱动_打开进程(进程PID),返回值:进程句柄,0为失败 191 | uint64_t OpenProcess(uint64_t pid) 192 | { 193 | return hwBreakpointProcDriver_OpenProcess(m_nDriverLink, pid); 194 | } 195 | 196 | //驱动_获取CPU支持硬件执行断点的数量,返回值:TRUE成功,FALSE失败 197 | int GetNumBRPS() 198 | { 199 | return hwBreakpointProcDriver_GetNumBRPS(m_nDriverLink); 200 | } 201 | //驱动_获取CPU支持硬件访问断点的数量,返回值:TRUE成功,FALSE失败 202 | int GetNumWRPS() 203 | { 204 | return hwBreakpointProcDriver_GetNumWRPS(m_nDriverLink); 205 | } 206 | 207 | //驱动_设置硬件断点命中记录条件,返回值:TRUE成功,FALSE失败 208 | BOOL SetHwBpHitConditions(HIT_CONDITIONS &hitConditions) 209 | { 210 | return hwBreakpointProcDriver_SetHwBpHitConditions(m_nDriverLink, &hitConditions); 211 | } 212 | 213 | //驱动_新增硬件断点,返回值:TRUE成功,FALSE失败 214 | uint64_t AddProcessHwBp( 215 | uint64_t hProcess, 216 | uint64_t lpBaseAddress, 217 | uint64_t hwBreakpointLen, 218 | unsigned int hwBreakpointType) 219 | { 220 | return hwBreakpointProcDriver_AddProcessHwBp(m_nDriverLink, hProcess, lpBaseAddress, hwBreakpointLen, hwBreakpointType); 221 | } 222 | 223 | //驱动_删除硬件断点,返回值:TRUE成功,FALSE失败 224 | BOOL DelProcessHwBp(uint64_t hHwBreakpointHandle) 225 | { 226 | return hwBreakpointProcDriver_DelProcessHwBp(m_nDriverLink, hHwBreakpointHandle); 227 | } 228 | 229 | //驱动_读取硬件断点命中记录信息,返回值:TRUE成功,FALSE失败 230 | BOOL ReadHwBpInfo(uint64_t hHwBreakpointHandle, std::vector &vOutput) 231 | { 232 | return hwBreakpointProcDriver_ReadHwBpInfo(m_nDriverLink, hHwBreakpointHandle, vOutput); 233 | } 234 | 235 | //驱动_清除硬件断点命中记录信息,返回值:TRUE成功,FALSE失败 236 | BOOL CleanHwBpInfo() 237 | { 238 | return hwBreakpointProcDriver_CleanHwBpInfo(m_nDriverLink); 239 | } 240 | 241 | //驱动_关闭进程,返回值:TRUE成功,FALSE失败 242 | BOOL CloseHandle(uint64_t handle) 243 | { 244 | return hwBreakpointProcDriver_CloseHandle(m_nDriverLink, handle); 245 | } 246 | 247 | private: 248 | int m_nDriverLink = -1; 249 | }; 250 | #endif 251 | 252 | //实现 253 | ////////////////////////////////////////////////////////////////////////// 254 | 255 | static int hwBreakpointProcDriver_Connect() 256 | { 257 | int nDriverLink = open(DEV_FILENAME, O_RDWR); 258 | if (nDriverLink < 0) 259 | { 260 | printf("open error():%s\n", strerror(errno)); 261 | } 262 | return nDriverLink; 263 | } 264 | 265 | static BOOL hwBreakpointProcDriver_Disconnect(int nDriverLink) 266 | { 267 | if (nDriverLink < 0) 268 | { 269 | return FALSE; 270 | } 271 | //�Ͽ��������� 272 | close(nDriverLink); 273 | return TRUE; 274 | } 275 | static uint64_t hwBreakpointProcDriver_OpenProcess(int nDriverLink, uint64_t pid) 276 | { 277 | if (nDriverLink < 0) 278 | { 279 | return 0; 280 | } 281 | char buf[8] = {0}; 282 | memcpy(buf, &pid, 8); 283 | 284 | int res = ioctl(nDriverLink, IOCTL_OPEN_PROCESS, &buf); 285 | if (res != 0) 286 | { 287 | printf("OpenProcess ioctl():%s\n", strerror(errno)); 288 | return 0; 289 | } 290 | uint64_t ptr = 0; 291 | memcpy(&ptr, &buf, 8); 292 | return ptr; 293 | } 294 | 295 | static int hwBreakpointProcDriver_GetNumBRPS(int nDriverLink) 296 | { 297 | if (nDriverLink < 0) 298 | { 299 | return 0; 300 | } 301 | int res = ioctl(nDriverLink, IOCTL_GET_NUM_BRPS, 0); 302 | return res; 303 | } 304 | static int hwBreakpointProcDriver_GetNumWRPS(int nDriverLink) 305 | { 306 | if (nDriverLink < 0) 307 | { 308 | return 0; 309 | } 310 | int res = ioctl(nDriverLink, IOCTL_GET_NUM_WRPS, 0); 311 | return res; 312 | } 313 | 314 | static BOOL hwBreakpointProcDriver_SetHwBpHitConditions( 315 | int nDriverLink, 316 | HIT_CONDITIONS *hitConditions) 317 | { 318 | if (nDriverLink < 0) 319 | { 320 | return FALSE; 321 | } 322 | int res = ioctl(nDriverLink, IOCTL_SET_HWBP_HIT_CONDITIONS, hitConditions); 323 | if (res != 0) 324 | { 325 | printf("SetHwBpHitConditions ioctl():%s\n", strerror(errno)); 326 | return FALSE; 327 | } 328 | return TRUE; 329 | } 330 | static uint64_t hwBreakpointProcDriver_AddProcessHwBp( 331 | int nDriverLink, 332 | uint64_t hProcess, 333 | uint64_t lpBaseAddress, 334 | uint64_t hwBreakpointLen, 335 | unsigned int hwBreakpointType) 336 | { 337 | if (nDriverLink < 0) 338 | { 339 | return 0; 340 | } 341 | 342 | unsigned char buf[28] = {0}; 343 | memcpy(buf, &hProcess, 28); 344 | memcpy((void *)((size_t)buf + (size_t)8), &lpBaseAddress, 8); 345 | memcpy((void *)((size_t)buf + (size_t)16), &hwBreakpointLen, 8); 346 | memcpy((void *)((size_t)buf + (size_t)24), &hwBreakpointType, 4); 347 | 348 | int res = ioctl(nDriverLink, IOCTL_ADD_PROCESS_HWBP, &buf); 349 | if (res != 0) 350 | { 351 | printf("AddProcessHwBp ioctl():%s\n", strerror(errno)); 352 | return 0; 353 | } 354 | uint64_t ptr = 0; 355 | memcpy(&ptr, &buf, 8); 356 | return ptr; 357 | } 358 | 359 | static BOOL hwBreakpointProcDriver_DelProcessHwBp( 360 | int nDriverLink, 361 | uint64_t hHwBreakpointHandle) 362 | { 363 | if (nDriverLink < 0) 364 | { 365 | return FALSE; 366 | } 367 | if (!hHwBreakpointHandle) 368 | { 369 | return FALSE; 370 | } 371 | 372 | char buf[8] = {0}; 373 | memcpy(buf, &hHwBreakpointHandle, 8); 374 | 375 | int res = ioctl(nDriverLink, IOCTL_DEL_PROCESS_HWBP, &buf); 376 | if (res != 0) 377 | { 378 | printf("DelProcessHwBp ioctl():%s\n", strerror(errno)); 379 | return FALSE; 380 | } 381 | return TRUE; 382 | } 383 | 384 | static BOOL hwBreakpointProcDriver_ReadHwBpInfo( 385 | int nDriverLink, 386 | uint64_t hHwBreakpointHandle, 387 | std::vector &vOutput) 388 | { 389 | if (nDriverLink < 0) 390 | { 391 | return FALSE; 392 | } 393 | if (!hHwBreakpointHandle) 394 | { 395 | return FALSE; 396 | } 397 | 398 | char buf[8] = {0}; 399 | memcpy(buf, &hHwBreakpointHandle, 8); 400 | int count = ioctl(nDriverLink, IOCTL_GET_HWBP_HIT_ADDR_COUNT, &buf); 401 | //printf("count %d\n", count); 402 | if (count <= 0) 403 | { 404 | //printf("ioctl():%s\n", strerror(errno)); 405 | return FALSE; 406 | } 407 | 408 | uint64_t big_buf_len = sizeof(struct USER_HIT_INFO) * count; 409 | char *big_buf = (char *)malloc(big_buf_len); 410 | memset(big_buf, 0, big_buf_len); 411 | memcpy(big_buf, &hHwBreakpointHandle, 8); 412 | 413 | int res = read(nDriverLink, big_buf, big_buf_len); 414 | //printf("res %d\n", res); 415 | if (res <= 0) 416 | { 417 | free(big_buf); 418 | return FALSE; 419 | } 420 | size_t copy_pos = (size_t)big_buf; 421 | 422 | for (; res > 0; res--) 423 | { 424 | struct USER_HIT_INFO hInfo = {0}; 425 | memcpy(&hInfo, (void *)copy_pos, sizeof(hInfo)); 426 | copy_pos += sizeof(hInfo); 427 | vOutput.push_back(hInfo); 428 | } 429 | free(big_buf); 430 | return TRUE; 431 | } 432 | 433 | static BOOL hwBreakpointProcDriver_CleanHwBpInfo(int nDriverLink) 434 | { 435 | if (nDriverLink < 0) 436 | { 437 | return FALSE; 438 | } 439 | int res = write(nDriverLink, (void *)1, 1); 440 | if (res == 0) 441 | { 442 | printf("CleanHwBpInfo write():%s\n", strerror(errno)); 443 | return FALSE; 444 | } 445 | return TRUE; 446 | } 447 | 448 | static BOOL hwBreakpointProcDriver_CloseHandle(int nDriverLink, uint64_t handle) 449 | { 450 | if (nDriverLink < 0) 451 | { 452 | return FALSE; 453 | } 454 | if (!handle) 455 | { 456 | return FALSE; 457 | } 458 | 459 | char buf[8] = {0}; 460 | memcpy(buf, &handle, 8); 461 | 462 | int res = ioctl(nDriverLink, IOCTL_CLOSE_HANDLE, &buf); 463 | if (res != 0) 464 | { 465 | printf("CloseHandle ioctl():%s\n", strerror(errno)); 466 | return FALSE; 467 | } 468 | return TRUE; 469 | } 470 | 471 | 472 | #endif /* HW_BREAKPOINT_MANAGER_H_ */ 473 | -------------------------------------------------------------------------------- /app/src/main/cpp/Hwbp.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Shocker on 2022/9/20. 3 | // 4 | 5 | #ifndef HWBPAPP_HWBP_H 6 | #define HWBPAPP_HWBP_H 7 | #include 8 | #include "HwBreakpointManager.h" 9 | #include "log.h" 10 | 11 | BOOL GetProcessTask(int pid, std::vector &vOutput) 12 | { 13 | DIR *dir = NULL; 14 | struct dirent *ptr = NULL; 15 | char szTaskPath[256] = {0}; 16 | sprintf(szTaskPath, "/proc/%d/task", pid); 17 | 18 | dir = opendir(szTaskPath); 19 | if (NULL != dir) 20 | { 21 | while ((ptr = readdir(dir)) != NULL) // 循环读取路径下的每一个文件/文件夹 22 | { 23 | // 如果读取到的是"."或者".."则跳过,读取到的不是文件夹名字也跳过 24 | if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) 25 | { 26 | continue; 27 | } 28 | else if (ptr->d_type != DT_DIR) 29 | { 30 | continue; 31 | } 32 | else if (strspn(ptr->d_name, "1234567890") != strlen(ptr->d_name)) 33 | { 34 | continue; 35 | } 36 | 37 | int task = atoi(ptr->d_name); 38 | vOutput.push_back(task); 39 | } 40 | closedir(dir); 41 | return TRUE; 42 | } 43 | return FALSE; 44 | } 45 | 46 | 47 | void *setHwBreakPoint(void *address) 48 | { 49 | CHwBreakpointManager driver; 50 | //连接驱动 51 | int err = 0; 52 | if (!driver.ConnectDriver(err)) 53 | { 54 | LOGD("连接驱动失败\n"); 55 | return nullptr; 56 | } 57 | 58 | //获取CPU支持硬件执行和访问断点的数量 59 | int bprsCount = driver.GetNumBRPS(); 60 | int wprsCount = driver.GetNumWRPS(); 61 | LOGD("驱动_获取CPU支持硬件执行断点的数量:%d\n", bprsCount); 62 | LOGD("驱动_获取CPU支持硬件访问断点的数量:%d\n", wprsCount); 63 | 64 | //获取当前进程所有的task 65 | std::vector vTask; 66 | GetProcessTask(getpid(), vTask); 67 | if (vTask.size() == 0) 68 | { 69 | LOGD("获取当前进程task失败\n"); 70 | return nullptr; 71 | } 72 | 73 | //设置进程硬件断点 74 | std::vector vHwBpHandle; 75 | 76 | for (int task : vTask) 77 | { 78 | //打开task 79 | uint64_t hProcess = driver.OpenProcess(task); 80 | // LOGD("调用驱动 OpenProcess(%d) 返回值:%lu", task, hProcess); 81 | if (!hProcess) 82 | { 83 | LOGD("调用驱动 OpenProcess 失败\n"); 84 | fflush(stdout); 85 | continue; 86 | } 87 | 88 | //设置进程硬件断点 89 | uint64_t hwBpHandle = driver.AddProcessHwBp(hProcess, (uint64_t)address, 90 | HW_BREAKPOINT_LEN_4, HW_BREAKPOINT_R); 91 | // LOGD("调用驱动 AddProcessHwBp(%lx) 返回值:%lu", address, hwBpHandle); 92 | 93 | if (hwBpHandle) 94 | { 95 | vHwBpHandle.push_back(hwBpHandle); 96 | } 97 | //关闭task 98 | driver.CloseHandle(hProcess); 99 | // LOGD("调用驱动 CloseHandle:%lu", hProcess); 100 | } 101 | LOGD("请等待2秒"); 102 | sleep(2); 103 | // printf("==========================================================================\n"); 104 | //删除进程硬件断点 105 | for (uint64_t hwBpHandle : vHwBpHandle) 106 | { 107 | driver.DelProcessHwBp(hwBpHandle); 108 | // printf("调用驱动 DelProcessHwBp(%" PRIu64 ")\n", hwBpHandle); 109 | } 110 | //读取硬件断点命中信息 111 | for (uint64_t hwBpHandle : vHwBpHandle) 112 | { 113 | std::vector vHit; 114 | BOOL b = driver.ReadHwBpInfo(hwBpHandle, vHit); 115 | // printf("==========================================================================\n"); 116 | // printf("调用驱动 ReadProcessHwBp(%" PRIu64 ") 返回值:%d\n", hwBpHandle, b); 117 | for (USER_HIT_INFO userhInfo : vHit) 118 | { 119 | LOGD("==========================================================================\n"); 120 | LOGD("硬件断点命中地址:%p,命中次数:%zu\n", userhInfo.hit_addr, userhInfo.hit_count); 121 | for (int r = 0; r < 30; r += 5) 122 | { 123 | LOGD("\tX%-2d=%-12llx X%-2d=%-12llx X%-2d=%-12llx X%-2d=%-12llx X%-2d=%-12llx\n", 124 | r, userhInfo.regs.regs[r], 125 | r + 1, userhInfo.regs.regs[r + 1], 126 | r + 2, userhInfo.regs.regs[r + 2], 127 | r + 3, userhInfo.regs.regs[r + 3], 128 | r + 4, userhInfo.regs.regs[r + 4]); 129 | } 130 | LOGD("\tLR=%-12llx SP=%-12llx PC=%-12llx\n", 131 | userhInfo.regs.regs[30], 132 | userhInfo.regs.sp, 133 | userhInfo.regs.pc); 134 | 135 | LOGD("\tprocess status:%-12llx orig_x0:%-12llx syscallno:%-12llx\n", 136 | userhInfo.regs.pstate, 137 | userhInfo.regs.orig_x0, 138 | userhInfo.regs.syscallno); 139 | LOGD("==========================================================================\n"); 140 | } 141 | } 142 | 143 | //清空硬件断点命中信息 144 | driver.CleanHwBpInfo(); 145 | LOGD("调用驱动 CleanHwBpInfo()\n"); 146 | return nullptr; 147 | } 148 | 149 | #endif //HWBPAPP_HWBP_H 150 | -------------------------------------------------------------------------------- /app/src/main/cpp/log.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LOG_H 3 | #define LOG_H 4 | 5 | #include 6 | 7 | #define LOG_TAG "Shocker" 8 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) 9 | #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) 10 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) 11 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /app/src/main/cpp/native-lib.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "log.h" 7 | #include "Hwbp.h" 8 | 9 | 10 | extern "C" 11 | JNIEXPORT void JNICALL 12 | Java_com_shocker_hwbpapp_MainActivity_testHwBp(JNIEnv *env, jobject thiz) { 13 | // TODO: implement testHwBp() 14 | 15 | int i=0; 16 | int ret; 17 | pthread_t ntid; 18 | LOGD("正在创建线程"); 19 | if ((ret =pthread_create(&ntid, nullptr, setHwBreakPoint, (void *)&i))) 20 | { 21 | LOGD("can't create thread: %s\n", strerror(ret)); 22 | } 23 | // LOGD("当前函数地址:%p",Java_com_shocker_hwbpapp_MainActivity_testHwBp); 24 | while (i<100){ 25 | i+=1; 26 | sleep(1); 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/shocker/hwbpapp/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.shocker.hwbpapp; 2 | 3 | import androidx.appcompat.app.AppCompatActivity; 4 | 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.TextView; 8 | import android.widget.Toast; 9 | 10 | import com.shocker.hwbpapp.databinding.ActivityMainBinding; 11 | 12 | public class MainActivity extends AppCompatActivity { 13 | 14 | // Used to load the 'hwbpapp' library on application startup. 15 | static { 16 | System.loadLibrary("hwbpapp"); 17 | } 18 | 19 | private ActivityMainBinding binding; 20 | 21 | private boolean isClick=false; 22 | 23 | 24 | @Override 25 | protected void onCreate(Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | binding = ActivityMainBinding.inflate(getLayoutInflater()); 28 | setContentView(binding.getRoot()); 29 | } 30 | 31 | //点击按钮执行的方法 32 | public void OnClickButton(View view) { 33 | if (!isClick) { 34 | new Thread(new Runnable() { 35 | @Override 36 | public void run() { 37 | isClick = true; 38 | testHwBp(); 39 | } 40 | }).start(); 41 | }else { 42 | Toast.makeText(getApplicationContext(),"您已经点击过测试按钮,请重新打开app",Toast.LENGTH_LONG).show(); 43 | } 44 | } 45 | 46 | /** 47 | * A native method that is implemented by the 'hwbpapp' native library, 48 | * which is packaged with this application. 49 | */ 50 | public native void testHwBp(); 51 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 |