├── model.cpp ├── assets ├── demo.png ├── 灵取证系统流程图.png ├── 1747996785328.png ├── qrcode_1747839744296.jpg ├── flow.puml └── logo.svg ├── .github ├── FUNDING.yml └── workflows │ └── c-cpp.yml ├── main.cpp ├── makefile ├── controller ├── controller.h └── controller.cpp ├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── view ├── view.h └── view.cpp ├── model ├── model.h └── model.cpp └── README.md /model.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctkqiang/LQZ/HEAD/assets/demo.png -------------------------------------------------------------------------------- /assets/灵取证系统流程图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctkqiang/LQZ/HEAD/assets/灵取证系统流程图.png -------------------------------------------------------------------------------- /assets/1747996785328.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctkqiang/LQZ/HEAD/assets/1747996785328.png -------------------------------------------------------------------------------- /assets/qrcode_1747839744296.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctkqiang/LQZ/HEAD/assets/qrcode_1747839744296.jpg -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [ctkqiang] 2 | patreon: ctkqiang 3 | ko_fi: ctkqiang 4 | custom: 5 | - https://donate.stripe.com/00gg2nefu6TK1LqeUY 6 | - https://qr.alipay.com/fkx19369scgxdrkv8mxso92 7 | - https://raw.githubusercontent.com/ctkqiang/ctkqiang/refs/heads/main/assets/IMG_9859.JPG 8 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "controller/controller.h" 10 | 11 | int main() { 12 | Controller App; 13 | App.Run(); 14 | 15 | return 0x0; 16 | } -------------------------------------------------------------------------------- /.github/workflows/c-cpp.yml: -------------------------------------------------------------------------------- 1 | name: C/C++ CI 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | - name: make 17 | run: make 18 | - name: make check 19 | run: make check 20 | - name: make distcheck 21 | run: make distcheck 22 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | CXX = g++ 2 | CXXFLAGS = -std=c++17 -Wall 3 | 4 | SRC = main.cpp model/model.cpp view/view.cpp controller/controller.cpp 5 | OBJ = $(SRC:.cpp=.o) 6 | EXEC = phone_forensic 7 | 8 | all: $(EXEC) 9 | 10 | $(EXEC): $(OBJ) 11 | $(CXX) $(CXXFLAGS) $^ -o $@ 12 | 13 | %.o: %.cpp 14 | $(CXX) $(CXXFLAGS) -c $< -o $@ 15 | 16 | clean: 17 | rm -f $(OBJ) $(EXEC) 18 | 19 | run: 20 | g++ -std=c++17 -Wall main.cpp model/model.cpp view/view.cpp controller/controller.cpp -o $(EXEC) && ./$(EXEC) -------------------------------------------------------------------------------- /controller/controller.h: -------------------------------------------------------------------------------- 1 | #ifndef CONTROLLER_H 2 | #define CONTROLLER_H 3 | 4 | #include "../model/model.h" 5 | #include "../view/view.h" 6 | 7 | // 哇哦~这里是控制器的魔法指挥中心呀 (๑•. •๑) 8 | // 所有可爱的操作指令都在这里汇聚,就像小仙子们在跳圆圈舞呢~ 9 | 10 | // 呀~这个 Controller 类就像是一个超级魔法管家呢 (✿◠‿◠) 11 | // 它会负责协调 Model 和 View 的互动,就像贴心的小女仆一样~ 12 | class Controller { 13 | // 小秘密:这里藏着数据模型小管家 Model 哟 (๑•ω•๑) 14 | Model model; 15 | // 小秘密:这里藏着视图小助手 View 哟 (๑•ω•๑) 16 | View view; 17 | 18 | public: 19 | // 小管家的魔法启动仪式来啦~ 20 | // 它会开启整个程序的魔法流程,让 Model 和 View 一起翩翩起舞哟 21 | void Run(); 22 | 23 | // 小管家的菜单魔法在此~ 24 | // 它会展示一个美美的功能菜单,就像递给用户一本魔法说明书哟 25 | void DisplayMenu(); 26 | }; 27 | 28 | #endif -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build directories 2 | build/ 3 | Debug/ 4 | Release/ 5 | x64/ 6 | [Bb]in/ 7 | [Oo]bj/ 8 | 9 | # Compiled files 10 | *.o 11 | *.obj 12 | *.exe 13 | *.out 14 | *.app 15 | *.dll 16 | *.dylib 17 | *.so 18 | 19 | # IDE specific files 20 | .vscode/ 21 | .idea/ 22 | *.sln 23 | *.vcxproj 24 | *.vcxproj.filters 25 | *.xcodeproj/ 26 | *.xcworkspace/ 27 | .DS_Store 28 | 29 | # CMake files 30 | CMakeCache.txt 31 | CMakeFiles/ 32 | cmake_install.cmake 33 | Makefile 34 | 35 | # Dependencies 36 | vendor/ 37 | lib/ 38 | libs/ 39 | 40 | # Generated data 41 | Datas/ 42 | *.ab 43 | *.db 44 | *.log 45 | 46 | # Temporary files 47 | *.swp 48 | *~ 49 | .*.sw? 50 | .~lock.* 51 | 52 | # Environment files 53 | .env 54 | .env.local 55 | 56 | # Debug files 57 | *.dSYM/ 58 | *.su 59 | *.idb 60 | *.pdb 61 | 62 | # Package files 63 | *.tar.gz 64 | *.zip 65 | *.7z 66 | *.rar 67 | 68 | # Project specific 69 | Phone_dump_sms.ab 70 | phone_forensic 71 | -------------------------------------------------------------------------------- /assets/flow.puml: -------------------------------------------------------------------------------- 1 | @startuml 灵取证系统流程图 2 | 3 | skinparam ParticipantPadding 20 4 | skinparam BoxPadding 10 5 | skinparam SequenceGroupBodyBackgroundColor transparent 6 | 7 | actor 用户 as User 8 | participant "视图层\n(View)" as View 9 | participant "控制器\n(Controller)" as Controller 10 | participant "模型层\n(Model)" as Model 11 | participant "Android设备" as Device 12 | database "数据存储" as Storage 13 | 14 | box "初始化阶段" #LightBlue 15 | User -> View: 启动程序 16 | View -> Controller: 初始化系统 17 | Controller -> Model: 检查ADB环境 18 | Model -> Model: CheckAdb() 19 | Model --> Controller: 返回ADB状态 20 | Controller -> Model: 检查设备连接 21 | Model -> Device: 尝试连接设备 22 | Model --> Controller: 返回设备状态 23 | Controller -> View: 显示设备信息 24 | end box 25 | 26 | box "操作选择阶段" #LightYellow 27 | User -> View: 输入命令 28 | View -> Controller: 处理命令 29 | Controller -> Controller: 验证命令有效性 30 | end box 31 | 32 | box "数据提取阶段" #LightGreen 33 | alt 通话记录导出 34 | Controller -> Model: DumpCallLogs() 35 | Model -> Device: 提取通话记录 36 | Model -> Storage: 保存数据 37 | else 短信导出 38 | Controller -> Model: DumpSMS() 39 | Model -> Device: 提取短信数据 40 | Model -> Storage: 保存数据 41 | else 照片导出 42 | Controller -> Model: DumpPhotos() 43 | Model -> Device: 提取照片文件 44 | Model -> Storage: 保存数据 45 | else 应用导出 46 | Controller -> Model: DumpApks() 47 | Model -> Device: 提取应用数据 48 | Model -> Storage: 保存数据 49 | end 50 | end box 51 | 52 | box "结果反馈阶段" #LightPink 53 | Model --> Controller: 返回操作结果 54 | Controller -> View: 显示执行状态 55 | View --> User: 展示操作结果 56 | end box 57 | 58 | box "错误处理" #LightGray 59 | Model -> Controller: 抛出异常 60 | Controller -> View: 显示错误信息 61 | View --> User: 展示错误提示 62 | end box 63 | 64 | box "程序终止" #LightCoral 65 | User -> View: 退出命令 66 | View -> Controller: 处理退出请求 67 | Controller -> Model: 清理资源 68 | Model -> Device: 断开连接 69 | Controller -> View: 确认退出 70 | View --> User: 程序终止 71 | end box 72 | 73 | @enduml -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "*.sqlbook": "sql", 4 | "*.ndjson": "jsonl", 5 | "*.dbclient-js": "javascript", 6 | "*.embeddedhtml": "html", 7 | "filesystem": "cpp", 8 | "iostream": "cpp", 9 | "__bit_reference": "cpp", 10 | "__hash_table": "cpp", 11 | "__locale": "cpp", 12 | "__node_handle": "cpp", 13 | "__split_buffer": "cpp", 14 | "__threading_support": "cpp", 15 | "__tree": "cpp", 16 | "__verbose_abort": "cpp", 17 | "array": "cpp", 18 | "bitset": "cpp", 19 | "cctype": "cpp", 20 | "clocale": "cpp", 21 | "cmath": "cpp", 22 | "complex": "cpp", 23 | "cstdarg": "cpp", 24 | "cstddef": "cpp", 25 | "cstdint": "cpp", 26 | "cstdio": "cpp", 27 | "cstdlib": "cpp", 28 | "cstring": "cpp", 29 | "ctime": "cpp", 30 | "cwchar": "cpp", 31 | "cwctype": "cpp", 32 | "deque": "cpp", 33 | "execution": "cpp", 34 | "memory": "cpp", 35 | "initializer_list": "cpp", 36 | "iomanip": "cpp", 37 | "ios": "cpp", 38 | "iosfwd": "cpp", 39 | "istream": "cpp", 40 | "limits": "cpp", 41 | "locale": "cpp", 42 | "map": "cpp", 43 | "mutex": "cpp", 44 | "new": "cpp", 45 | "optional": "cpp", 46 | "ostream": "cpp", 47 | "print": "cpp", 48 | "queue": "cpp", 49 | "ratio": "cpp", 50 | "regex": "cpp", 51 | "sstream": "cpp", 52 | "stack": "cpp", 53 | "stdexcept": "cpp", 54 | "streambuf": "cpp", 55 | "string": "cpp", 56 | "string_view": "cpp", 57 | "tuple": "cpp", 58 | "typeinfo": "cpp", 59 | "unordered_map": "cpp", 60 | "variant": "cpp", 61 | "vector": "cpp", 62 | "algorithm": "cpp", 63 | "charconv": "cpp", 64 | "forward_list": "cpp", 65 | "fstream": "cpp", 66 | "chrono": "cpp" 67 | } 68 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 木兰宽松许可证, 第2版 2 | 3 | 2020年1月 http://license.coscl.org.cn/MulanPSL2 4 | 5 | 您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束: 6 | 7 | 0. 定义 8 | 9 | “软件” 是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。 10 | 11 | “贡献” 是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。 12 | 13 | “贡献者” 是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。 14 | 15 | “法人实体” 是指提交贡献的机构及其“关联实体”。 16 | 17 | “关联实体” 是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。 18 | 19 | 1. 授予版权许可 20 | 21 | 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。 22 | 23 | 2. 授予专利许可 24 | 25 | 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。 26 | 27 | 3. 无商标许可 28 | 29 | “本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。 30 | 31 | 4. 分发限制 32 | 33 | 您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。 34 | 35 | 5. 免责声明与责任限制 36 | 37 | “软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。 38 | 39 | 6. 语言 40 | 41 | “本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。 42 | 43 | 条款结束 44 | 45 | 如何将木兰宽松许可证,第2版,应用到您的软件 46 | 47 | 如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步: 48 | 49 | 1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字; 50 | 51 | 2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中; 52 | 53 | 3, 请将如下声明文本放入每个源文件的头部注释中。 54 | 55 | Copyright (c) 2025 钟智强 56 | 灵取证 is licensed under Mulan PSL v2. 57 | You can use this software according to the terms and conditions of the Mulan PSL v2. 58 | You may obtain a copy of Mulan PSL v2 at: 59 | http://license.coscl.org.cn/MulanPSL2 60 | THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 61 | EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 62 | MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 63 | See the Mulan PSL v2 for more details. -------------------------------------------------------------------------------- /view/view.h: -------------------------------------------------------------------------------- 1 | #ifndef VIEW_H 2 | #define VIEW_H 3 | 4 | #include 5 | 6 | // 哇哦~这里是视图小助手的魔法舞台呀 (๑•. •๑) 7 | // 所有可爱的用户交互都在这里绽放光芒,就像小仙子在舞台上跳舞呢~ 8 | 9 | // 呀~这个 View 类就像是一个超级贴心的小司仪哟 (✿◠‿◠) 10 | // 它会负责和用户互动,用各种可爱的提示和反馈让操作变得超有趣哒~ 11 | class View { 12 | public: 13 | // 小草莓红:用来标记重要错误信息的颜色哟 14 | static const std::string RED; 15 | // 天空蓝:用来显示操作提示的清爽颜色哒 16 | static const std::string BLUE; 17 | // 薄荷绿:成功时闪烁的治愈系颜色呀 18 | static const std::string GREEN; 19 | // 柠檬黄:温馨提示的可爱颜色哟 20 | static const std::string YELLOW; 21 | // 云朵白:默认的干净纯洁颜色哒 22 | static const std::string WHITE; 23 | // 水晶蓝:系统信息展示的高级感颜色呀 24 | static const std::string CYAN; 25 | 26 | public: 27 | // 小司仪登场~展示欢迎标题页的魔法仪式哟 28 | // 会用闪烁的星星特效和可爱 ASCII 艺术欢迎用户哒 29 | void DisplayHeader(); 30 | 31 | // 小百科全书在此~展示所有可用命令的魔法手册哟 32 | // 会用彩虹色文字列出各种操作指令,超详细哒 33 | void DisplayHelp(); 34 | 35 | // 小雷达启动~显示设备连接状态的魔法看板哟 36 | // connected 参数是是否连接的小开关,model 是设备型号小标签 37 | void ShowDeviceStatus(bool connected, const std::string& model = ""); 38 | 39 | // 进度条小管家~显示操作进度的魔法仪表盘哟 40 | // operation 是当前操作的小名称,percentage 是完成度小数值 41 | void ShowProgress(const std::string& operation, int percentage); 42 | 43 | // 错误警报器~用红色闪烁文字报告错误的魔法喇叭哟 44 | // message 是要显示的错误小提示,会用可爱的语气读出来哒 45 | void ShowError(const std::string& message); 46 | 47 | // 成功小烟花~用绿色星星特效庆祝成功的魔法礼炮哟 48 | // message 是成功后的小庆祝语,会有 sparkles 音效哒 49 | void ShowSuccess(const std::string& message); 50 | 51 | // 彩色话痨模式~用指定颜色显示自定义信息的魔法泡泡哟 52 | // message 是要说的话,color 是选择的颜色魔法标记 53 | void ShowMessage(const std::string& message, const std::string& color); 54 | 55 | // 小话筒启动~获取用户输入的魔法吸管哟 56 | // prompt 是提示语小泡泡,input 是收集输入的小盒子 57 | void GetInput(const std::string& prompt, std::string& input); 58 | 59 | // 橡皮擦魔法~清空屏幕的神奇咒语哟 60 | // 会把屏幕擦得像新纸一样干净,还会有 "poof" 音效哒 61 | void ClearScreen(); 62 | 63 | private: 64 | // 小侦探技能~获取当前操作系统类型的魔法扫描仪哟 65 | // 会返回 "Windows"、"Mac" 或 "Linux" 等小标签 66 | std::string GetOSType(); 67 | }; 68 | 69 | #endif -------------------------------------------------------------------------------- /model/model.h: -------------------------------------------------------------------------------- 1 | #ifndef MODEL_H 2 | #define MODEL_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | // 哇哦~这里是数据模型类的小窝窝呀 (๑•. •๑) 所有可爱的数据操作都在这里诞生哟~ 9 | // 小仙子们正在这里翩翩起舞,守护着每一个重要的字节呢~ 10 | 11 | // 把文件系统命名空间简化成可爱的 fs 小昵称啦 12 | namespace fs = std::filesystem; 13 | 14 | // 呀~这个 Model 类就像是一个超级魔法管家呢 (✿◠‿◠) 15 | // 它能帮我们处理各种安卓设备的数据操作,就像贴心的小女仆一样~ 16 | class Model { 17 | // 小秘密:这里藏着设备型号信息哟 (๑•ω•๑) 18 | std::string deviceModel; 19 | 20 | // 小魔法师 executeCommand 在这里呢~ 21 | // 它能执行各种系统命令,还会把结果像小礼物一样包装好带回来哟 22 | std::string executeCommand(const std::string& cmd); 23 | 24 | public: 25 | // 小门卫 CheckDevice 来啦~ 26 | // 它会认真检查有没有连接安卓设备,如果有的话还会悄悄记住设备型号呢 27 | bool CheckDevice(); 28 | 29 | // 小医生 CheckAdb 在此~ 30 | // 它会仔细检查电脑里有没有安装 ADB 工具,如果没有的话还会帮忙安装哟 31 | void CheckAdb(); 32 | 33 | // 小管家 DumpSMS 出动~ 34 | // 它会把安卓设备里的短信都好好备份到小房间 Datas 里呢 35 | void DumpSMS(); 36 | 37 | // 小天使 DumpPhotos 来啦~ 38 | // 它会把设备里的照片都收集到 Datas 小相册里,就像收集星星一样哟 39 | void DumpPhotos(); 40 | 41 | // 小快递员 DumpDownloads 工作中~ 42 | // 它会把设备里下载的文件都送到 Datas 小包裹站,一个都不会漏掉哒 43 | void DumpDownloads(); 44 | 45 | // 小秘书 DumpContacts 在此~ 46 | // 它会把联系人信息和通话记录都整理到 Datas 小仓库里,超有条理哒 47 | void DumpContacts(); 48 | 49 | // 小邮差 DumpMessage 出发~ 50 | // 它会把短信数据库文件都安全地送到 Datas 小信箱里哟 51 | void DumpMessage(); 52 | 53 | // 小搬运工 Dumpfiles 上线~ 54 | // 它会把整个 SD 卡的内容都搬到 Datas/sdcard 大仓库里呢 55 | void Dumpfiles(); 56 | 57 | // 小使者 ConnectWirelessly 工作啦~ 58 | // 它会让我们输入设备 IP 地址,然后用无线魔法和设备牵起手手哟 59 | void ConnectWirelessly(); 60 | 61 | // 小秘书 Shell 在此待命~ 62 | // 我们把要执行的命令告诉它,它就会乖乖去执行并把结果报告给我们哟 63 | void Shell(std::string cmd); 64 | 65 | // 小侦探 GetDeviceModel 来啦~ 66 | // 调用它就能知道连接的设备是什么型号,超厉害哒 67 | std::string GetDeviceModel() const; 68 | 69 | // 小记录员 DumpCallLogs 工作中~ 70 | // 它会把通话记录都记到 Datas/CallLogs 小本子里,超详细哟 71 | void DumpCallLogs(); 72 | 73 | // 小影迷 DumpVideos 在此~ 74 | // 它会把设备里的视频都收集到 Datas 小电影院里,想看就看哟 75 | void DumpVideos(); 76 | 77 | // 小收藏家 DumpApks 出动~ 78 | // 它会把 APK 文件信息和文件都收集到 Datas/APKs 小软件库里呢 79 | void DumpApks(); 80 | 81 | // 小管理员 DumpDocuments 工作啦~ 82 | // 它会把文档文件都整理到 Datas/Documents 小文档室里,超整齐哒 83 | void DumpDocuments(); 84 | 85 | // 小侦探 ExtractSensitiveInfo 出动~ 86 | // 它会把敏感信息都收集到 Datas/Sensitive 小秘密基地里哟 87 | void ExtractSensitiveInfo(); 88 | 89 | // 小专家 GetWifiAddress 在此~ 90 | // 它会把 WiFi 地址和网络信息都研究清楚,记到 Datas/Network 小实验室里哟 91 | void GetWifiAddress(); 92 | 93 | // 小护士 DumpSystemInfo 工作中~ 94 | // 它会把设备的系统信息都记录到 Datas/System 小病房里呢 95 | void DumpSystemInfo(); 96 | 97 | // 小助手 ListPackages 在此~ 98 | // 它会把已安装应用的包名信息都列到 Datas/Packages 小清单本里哟 99 | void ListPackages(); 100 | 101 | // 小粉丝 ExtractWhatsApp 出动~ 102 | // 它会把 WhatsApp 数据都收集到 Datas/WhatsApp 小粉丝俱乐部里呢 103 | void ExtractWhatsApp(); 104 | 105 | // 小探险家 ExtractBrowserData 工作啦~ 106 | // 它会去浏览器里探险,把有用的数据都带回来放到 Datas/Browser 小基地里哟 107 | void ExtractBrowserData(); 108 | 109 | // 小使者 ExtractNotifications 在此~ 110 | // 它会把通知信息都收集到 Datas/Notifications 小通知站里哟 111 | void ExtractNotifications(); 112 | void DumpSysFromSpecificPackage(std::string PACKAGE_NAME); 113 | void RunPackageAs(); 114 | void RunApkTool(std::string APK_FILE); 115 | 116 | void Extract微信(); 117 | }; 118 | 119 | #endif -------------------------------------------------------------------------------- /assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 42 | 43 | 44 | 45 | 46 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 69 | ♥1010♥ 70 | 71 | 72 | 73 | 74 | 78 | ♥0101♥ 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 90 | 91 | 92 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /controller/controller.cpp: -------------------------------------------------------------------------------- 1 | #include "controller.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | // 哇哦~这里是控制器的魔法指挥中心呀 (๑•. •๑) 10 | // 所有可爱的操作指令都在这里汇聚,就像小仙子们在跳圆圈舞呢~ 11 | 12 | // 小管家 Controller 来啦~它会负责协调 Model 和 View 的互动哟 13 | void Controller::Run() { 14 | // 让 View 小助手先把屏幕擦得亮晶晶的~ 15 | view.ClearScreen(); 16 | // 展示一个美美的欢迎标题页,就像拉开魔法舞台的帷幕~ 17 | view.DisplayHeader(); 18 | 19 | try { 20 | // 让 Model 小医生去检查 ADB 工具有没有安装好哟~ 21 | model.CheckAdb(); 22 | } catch (const std::exception& e) { 23 | // 如果检查失败,View 小助手会用红色字体伤心地报告错误 24 | view.ShowError("ADB安装检查失败"); 25 | return; 26 | } 27 | 28 | // 让 Model 小门卫检查一下有没有连接安卓设备呢~ 29 | bool deviceConnected = model.CheckDevice(); 30 | // View 小助手会用可爱的图标显示设备连接状态和型号哟 31 | view.ShowDeviceStatus(deviceConnected, model.GetDeviceModel()); 32 | // 展示一个小帮助菜单,就像递给用户一本魔法说明书~ 33 | view.DisplayHelp(); 34 | 35 | // 如果没有检测到设备,View 小助手会用红色字体提醒我们哟 36 | if (!deviceConnected) { 37 | view.ShowError("未检测到手机设备"); 38 | return; 39 | } 40 | 41 | // 准备一个小本子,用来记录用户输入的命令哒 42 | std::string command; 43 | // 进入一个魔法循环,直到用户说退出哟 44 | while (true) { 45 | // View 小助手会用黄色字体提示用户输入命令哒 46 | view.GetInput("\n命令> ", command); 47 | 48 | try { 49 | // 如果输入的是 exit 或 0,就像小仙子要回家啦~ 50 | if (command == "exit" || command == "0") { 51 | view.ShowMessage("正在退出程序...", view.YELLOW); 52 | break; 53 | } 54 | 55 | // 如果输入 clear,View 小助手会把屏幕擦得像新的一样哟 56 | if (command == "clear") { 57 | view.ClearScreen(); 58 | continue; 59 | } 60 | 61 | // 如果输入 about,View 小助手会重新展示欢迎标题页哒 62 | if (command == "about") { 63 | view.DisplayHeader(); 64 | continue; 65 | } 66 | 67 | // 如果输入 help 或 ?,View 小助手会再次展示帮助菜单哟 68 | if (command == "help" || command == "?") { 69 | view.DisplayHelp(); 70 | continue; 71 | } 72 | 73 | // 命令 1:让 Model 小记录员去获取通话记录啦~ 74 | if (command == "1") { 75 | view.ShowMessage("正在获取通话记录...", view.BLUE); 76 | model.DumpCallLogs(); 77 | view.ShowSuccess("通话记录已导出"); 78 | } 79 | // 命令 2:让 Model 小管家去备份短信oyer~ 80 | else if (command == "2") { 81 | view.ShowMessage("正在导出短信...", view.BLUE); 82 | model.DumpSMS(); 83 | view.ShowSuccess("短信已导出"); 84 | } 85 | // 命令 3:让 Model 小天使去收集照片啦~ 86 | else if (command == "3") { 87 | view.ShowMessage("正在导出照片...", view.BLUE); 88 | model.DumpPhotos(); 89 | view.ShowSuccess("照片已导出"); 90 | } 91 | // 命令 4:让 Model 小影迷去收集视频哟~ 92 | else if (command == "4") { 93 | view.ShowMessage("正在导出视频...", view.BLUE); 94 | model.DumpVideos(); 95 | view.ShowSuccess("视频已导出"); 96 | } 97 | // 命令 5:让 Model 小收藏家去收集应用 APK 哟~ 98 | else if (command == "5") { 99 | view.ShowMessage("正在导出应用...", view.BLUE); 100 | model.DumpApks(); 101 | view.ShowSuccess("应用已导出"); 102 | } 103 | // 命令 6:让 Model 小管理员去整理文档哒~ 104 | else if (command == "6") { 105 | view.ShowMessage("正在导出文档...", view.BLUE); 106 | model.DumpDocuments(); 107 | view.ShowSuccess("文档已导出"); 108 | } 109 | // 命令 7:让 Model 小侦探去提取敏感信息哟~ 110 | else if (command == "7") { 111 | view.ShowMessage("正在提取敏感信息...", view.BLUE); 112 | model.ExtractSensitiveInfo(); 113 | view.ShowSuccess("信息提取完成"); 114 | } 115 | // 命令 8:让 Model 小使者去无线连接设备哒~ 116 | else if (command == "8") { 117 | model.ConnectWirelessly(); 118 | } 119 | // 命令 9/wifi:让 Model 小专家去获取网络信息哟~ 120 | else if (command == "9" || command == "wifi") { 121 | view.ShowMessage("正在获取网络信息...", view.BLUE); 122 | model.GetWifiAddress(); 123 | view.ShowSuccess("网络信息已导出"); 124 | } 125 | // 命令 10/sysinfo:让 Model 小护士去获取系统信息哒~ 126 | else if (command == "10" || command == "sysinfo") { 127 | view.ShowMessage("正在导出系统信息...", view.BLUE); 128 | model.DumpSystemInfo(); 129 | view.ShowSuccess("系统信息已导出"); 130 | } 131 | // 命令 11/packages:让 Model 小助手去获取应用列表哟~ 132 | else if (command == "11" || command == "packages") { 133 | view.ShowMessage("正在获取应用列表...", view.BLUE); 134 | model.ListPackages(); 135 | view.ShowSuccess("应用列表已导出"); 136 | } 137 | // 命令 12/whatsapp:让 Model 小粉丝去提取 WhatsApp 数据哒~ 138 | else if (command == "12" || command == "whatsapp") { 139 | view.ShowMessage("正在提取WhatsApp数据...", view.BLUE); 140 | model.ExtractWhatsApp(); 141 | view.ShowSuccess("WhatsApp数据已导出"); 142 | } 143 | // 命令 13/browser:让 Model 小探险家去提取浏览器数据哟~ 144 | else if (command == "13" || command == "browser") { 145 | view.ShowMessage("正在提取浏览器数据...", view.BLUE); 146 | model.ExtractBrowserData(); 147 | view.ShowSuccess("浏览器数据已导出"); 148 | } 149 | // 命令 14/notifications:让 Model 小使者去收集通知记录哒~ 150 | else if (command == "14" || command == "notifications") { 151 | view.ShowMessage("正在提取通知记录...", view.BLUE); 152 | model.ExtractNotifications(); 153 | view.ShowSuccess("通知记录已导出"); 154 | } 155 | 156 | else if (command == "15" || command == "dumpsys") { 157 | view.ShowMessage("正在提取微信数据...", view.BLUE); 158 | model.Extract微信(); 159 | view.ShowSuccess("微信数据已导出"); 160 | } 161 | 162 | // 如果输入了不认识的命令,View 小助手会用红色字体提醒哟 163 | else { 164 | view.ShowError("未知命令,输入 'help' 或 '?' 查看可用命令"); 165 | } 166 | 167 | // 检查一下设备连接状态,如果断开就结束魔法哟 168 | if (!model.CheckDevice()) { 169 | view.ShowError("设备连接已断开"); 170 | break; 171 | } 172 | 173 | } catch (const std::exception& e) { 174 | // 如果执行命令时出错,View 小助手会用红色字体报告错误信息哒 175 | view.ShowError(std::string("执行命令时出错: ") + e.what()); 176 | } 177 | } 178 | } -------------------------------------------------------------------------------- /view/view.cpp: -------------------------------------------------------------------------------- 1 | #include "view.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | // 定义各种可爱的颜色魔法~ 8 | const std::string View::RED = "\033[31m"; // 小草莓红色,用来提醒重要事项哟~ 9 | const std::string View::BLUE = "\033[34m"; // 天空蓝色,像清爽的海洋一样~ 10 | const std::string View::GREEN = "\033[32m"; // 嫩芽绿色,代表希望和成功呢~ 11 | const std::string View::YELLOW = "\033[33m"; // 向日葵黄色,温暖又活泼哒~ 12 | const std::string View::WHITE = "\033[0m"; // 纯净白色,像小棉花一样柔软~ 13 | const std::string View::CYAN = "\033[36m"; // 梦幻蓝色,充满神秘感呢~ 14 | 15 | // 欢迎界面的小仙女~用漂亮的ASCII艺术来装饰哟~ 16 | void View::DisplayHeader() { 17 | std::cout << BLUE << CYAN << R"( 18 | ✿ _______________ 19 | / ∗ ∗ \ 20 | / ⋆ ⋆ \ 21 | | ✧_______________✧ | 22 | | | ⋆ ⋆ | | 23 | | | \033[37m♡♡♡♡♡♡♡♡\033[36m | | 24 | | | \033[37m♡ \033[36mPHONE \033[37m♡\033[36m | | 25 | | | \033[37m♡♡♡♡♡♡♡♡\033[36m | | 26 | | | ⋆ ⋆ | | 27 | | |_______________| | 28 | | ✿[♡]✿ | 29 | \ ⋆ ⋆ / 30 | \_______________/ 31 | 32 | ╭══════════════════════════════════════════════════════════╮ 33 | │ ✧ Android 手机取证工具 v1.0.0 ✧ 34 | │ (安卓数据提取与分析系统) 35 | ╰──────────────────────────────────────────────────────────╯ 36 | ╭══════════════════════════════════════════════════════════╮ 37 | │ 法律依据 ♡ 38 | │ • 《中华人民共和国刑事诉讼法》第138条 39 | │ - 关于电子数据收集与使用的规定 40 | │ • 《中华人民共和国网络安全法》第50条 41 | │ - 网络运营者配合网络安全与信息内容管理 42 | │ • 《中华人民共和国公安机关办理刑事案件程序规定》第234条 43 | │ - 电子数据取证程序与要求 44 | │ • 《中华人民共和国电子签名法》第14条 45 | │ - 电子签名的法律效力 46 | │ • 《电子数据取证规范》GA/T 1070-2013 47 | │ - 移动设备取证技术标准 48 | │ • 《移动互联网应用程序信息安全管理规定》 49 | │ - APP数据安全与隐私保护要求 50 | ╰──────────────────────────────────────────────────────────╯ 51 | ╭══════════════════════════════════════════════════════════╮ 52 | │ 警告事项 ⚠ 53 | │ • 未经授权的数据提取可能构成违法行为 54 | │ - 可能违反《刑法》第285条 55 | │ - 可能违反《个人信息保护法》相关规定 56 | │ • 提取的数据可能涉及个人隐私,请依法处理 57 | │ - 需遵守数据保密原则 58 | │ - 确保数据存储安全 59 | │ • 建议在获得合法授权后再进行数据提取 60 | │ - 获取书面授权文件 61 | │ - 记录授权过程 62 | │ • 不当使用可能承担法律责任 63 | │ - 民事赔偿责任 64 | │ - 行政处罚责任 65 | │ - 刑事责任 66 | ╰──────────────────────────────────────────────────────────╯ 67 | ╭══════════════════════════════════════════════════════════╮ 68 | │ 免责声明 ♡ 69 | │ • 本工具仅供执法部门在法律框架内使用 70 | │ • 作者对任何非法使用或滥用概不负责 71 | │ • 使用本工具即表示同意遵守相关法律法规 72 | │ • 请确保在合法合规的前提下使用本工具 73 | ╰──────────────────────────────────────────────────────────╯ 74 | ╭══════════════════════════════════════════════════════════╮ 75 | │ 开发信息 ♡ 76 | │ 作者: 钟智强 77 | | 电邮:johnmelodymel@qq.com 78 | ╰──────────────────────────────────────────────────────────╯ 79 | )" << WHITE << std::endl; 80 | } 81 | 82 | // 小百科全书在此~展示所有可用命令的魔法手册哟~(๑•. •๑) 83 | // 会用彩虹色文字列出各种操作指令,超详细哒~ 84 | void View::DisplayHelp() { 85 | // 漂亮的菜单边框~ 86 | std::cout << CYAN << "\n╭────────── ♡ 功能菜单 Features ♡ ──────────╮" 87 | << WHITE << std::endl; 88 | 89 | // 数据提取功能区域~ 90 | std::cout << BLUE << "\n✧ 数据提取 Data Extraction ✧" << WHITE << std::endl; 91 | std::cout << BLUE << " [1] " << WHITE << "📱 Dump Call Logs 导出通话记录" 92 | << std::endl; 93 | std::cout << BLUE << " [2] " << WHITE << "💌 Dump SMS 导出短信" 94 | << std::endl; 95 | std::cout << BLUE << " [3] " << WHITE << "📸 Dump Photos 导出照片" 96 | << std::endl; 97 | std::cout << BLUE << " [4] " << WHITE << "🎥 Dump Videos 导出视频" 98 | << std::endl; 99 | std::cout << BLUE << " [5] " << WHITE << "📦 Dump APKs 导出应用" 100 | << std::endl; 101 | std::cout << BLUE << " [6] " << WHITE << "📤 Upload Files 上传文件" 102 | << std::endl; 103 | std::cout << BLUE << " [7] " << WHITE << "📑 Dump Documents 导出文档" 104 | << std::endl; 105 | std::cout << BLUE << " [8] " << WHITE << "🔍 Extract Info 提取敏感信息" 106 | << std::endl; 107 | 108 | // 系统信息功能区域~ 109 | std::cout << BLUE << "\n✧ 系统信息 System Info ✧" << WHITE << std::endl; 110 | std::cout << BLUE << " [9] " << WHITE << "📶 WiFi Info 获取WiFi信息" 111 | << std::endl; 112 | std::cout << BLUE << " [10] " << WHITE << "⚙️ System Info 系统信息" 113 | << std::endl; 114 | std::cout << BLUE << " [11] " << WHITE << "📱 List Packages 应用列表" 115 | << std::endl; 116 | std::cout << BLUE << " [12] " << WHITE << "💬 WhatsApp Data 提取WhatsApp" 117 | << std::endl; 118 | std::cout << BLUE << " [13] " << WHITE << "🌐 Browser Data 浏览器数据" 119 | << std::endl; 120 | std::cout << BLUE << " [14] " << WHITE << "🔔 Notifications 通知记录" 121 | << std::endl; 122 | std::cout << BLUE << " [15] " << WHITE << "💭 WeChat Data 提取微信数据" 123 | << std::endl; 124 | 125 | // 常用命令区域~ 126 | std::cout << GREEN << "\n✧ 常用命令 Commands ✧" << WHITE << std::endl; 127 | std::cout << YELLOW << " ⭐ " << WHITE 128 | << "1-15: Execute feature 执行对应功能" << std::endl; 129 | std::cout << YELLOW << " ⭐ " << WHITE << "help/?: Show help 显示帮助" 130 | << std::endl; 131 | std::cout << YELLOW << " ⭐ " << WHITE << "about: Show about 关于程序" 132 | << std::endl; 133 | std::cout << YELLOW << " ⭐ " << WHITE << "clear: Clear screen 清屏" 134 | << std::endl; 135 | std::cout << YELLOW << " ⭐ " << WHITE << "exit/0: Exit program 退出程序" 136 | << std::endl; 137 | 138 | // 底部装饰边框~ 139 | std::cout << CYAN << "\n╰─────────────────────────────────────────╯" 140 | << WHITE << std::endl; 141 | } 142 | 143 | // 设备状态小助手~随时汇报设备连接情况哟~ 144 | void View::ShowDeviceStatus(bool connected, const std::string& model) { 145 | std::cout << YELLOW << "\n[-] Connected Device/已连接设备:" << WHITE 146 | << std::endl; 147 | if (connected) { 148 | std::cout << GREEN << "[+] " << model << WHITE << std::endl; 149 | } else { 150 | std::cout << RED << "[!] No mobile phone detected/未检测到手机设备" 151 | << WHITE << std::endl; 152 | } 153 | // Decorative border for device status 154 | std::cout << CYAN << "\n╭──── Device Status 设备状态 ────╮" << WHITE 155 | << std::endl; 156 | if (connected) { 157 | std::cout << GREEN << " ✓ 设备已连接 Device Connected" << std::endl; 158 | std::cout << " 📱 型号 Model: " << model << WHITE << std::endl; 159 | } else { 160 | std::cout << RED << " ✗ 未检测到设备 No Device" << std::endl; 161 | std::cout << " 💡 请检查连接 Check Connection" << WHITE << std::endl; 162 | } 163 | std::cout << CYAN << "╰────────────────────────────╯" << WHITE << std::endl; 164 | } 165 | 166 | // 进度条小精灵~用可爱的方式显示任务进度呢~ 167 | void View::ShowProgress(const std::string& operation, int percentage) { 168 | std::cout << GREEN << "\r[*] " << operation << " ["; 169 | int pos = 50 * percentage / 100; 170 | for (int i = 0; i < 50; ++i) { 171 | if (i < pos) 172 | std::cout << "="; 173 | else if (i == pos) 174 | std::cout << ">"; 175 | else 176 | std::cout << " "; 177 | } 178 | std::cout << "] " << std::setw(3) << percentage << "%" << std::flush; 179 | if (percentage == 100) std::cout << std::endl; 180 | } 181 | 182 | // 错误提示小天使~用温柔的方式告诉用户出错啦~ 183 | void View::ShowError(const std::string& message) { 184 | std::cout << RED << "[!] Error/错误: " << message << WHITE << std::endl; 185 | } 186 | 187 | // 成功提示小仙子~开心地庆祝任务完成啦~ 188 | void View::ShowSuccess(const std::string& message) { 189 | std::cout << GREEN << "[+] Success/成功: " << message << WHITE << std::endl; 190 | } 191 | 192 | // 消息传递小精灵~用漂亮的颜色显示各种提示哟~ 193 | void View::ShowMessage(const std::string& message, const std::string& color) { 194 | std::cout << color << "[*] " << message << WHITE << std::endl; 195 | } 196 | 197 | // 用户输入小助手~温柔地等待用户的指令呢~ 198 | void View::GetInput(const std::string& prompt, std::string& input) { 199 | std::cout << YELLOW << prompt << WHITE; 200 | std::getline(std::cin, input); 201 | } 202 | 203 | // 清屏幕小魔法师~让界面保持整洁干净呢~ 204 | void View::ClearScreen() { 205 | #ifdef _WIN32 206 | system("cls"); // Windows系统下的清屏魔法~ 207 | #else 208 | system("clear"); // Unix系统下的清屏魔法~ 209 | #endif 210 | } 211 | 212 | // 系统检测小能手~帮忙识别当前运行的系统类型哟~ 213 | std::string View::GetOSType() { 214 | #ifdef _WIN32 215 | return "Windows"; // Windows系统就返回这个~ 216 | #elif __APPLE__ 217 | return "MacOS"; // 苹果系统就返回这个~ 218 | #elif __linux__ 219 | return "Linux"; // Linux系统就返回这个~ 220 | #elif __unix__ 221 | return "Unix"; // Unix系统就返回这个~ 222 | #else 223 | return "Unknown OS"; // 不认识的系统就这样说啦~ 224 | #endif 225 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 灵取证 Logo 3 |

灵取证

4 |

专业的Android设备数据取证工具

5 |

6 | version 7 | license 8 | platform 9 | language 10 |

11 | 12 |

13 | 14 | language 15 | 16 | 17 | download 18 | 19 | 20 |

21 |
22 | 23 | ## 简介 24 | 25 | 灵取证是一款功能强大且专业的 Android 设备数据取证工具,专门为执法部门、司法机构和安全调查人员设计开发。本工具采用先进的取证技术,确保数据提取过程的完整性和准确性。 26 | 27 | 作为一款综合性取证解决方案,灵取证支持多维度的数据获取功能: 28 | 29 | - 通讯数据:包括通话记录、短信内容、即时通讯记录等(小邮差和小秘书的魔法组合哟~) 30 | - 多媒体文件:支持照片、视频、音频等各类媒体文件的提取(小天使和小影迷的宝藏收集呀~) 31 | - 应用数据:可提取已安装应用的数据、使用记录和缓存信息(小收藏家的魔法收纳箱哟~) 32 | - 系统信息:获取设备配置、系统日志、网络连接记录等(小专家的魔法实验室哒~) 33 | 34 | 本工具的开发和使用严格遵循相关法律法规框架,确保所有数据提取操作都在合法授权范围内进行。通过专业的数据处理流程,为执法调查工作提供可靠的电子证据支持(就像魔法部的合法巫师在工作哟~) 35 | 36 | ## 法律依据与合规性 37 | 38 | 本工具的开发和使用严格遵循以下法律法规: 39 | 40 | - 《中华人民共和国刑事诉讼法》第 138 条 41 | (法律小卫士在守护数据正义哟~) 42 | 43 | > 规定了电子数据的收集、固定、审查、判断程序 44 | 45 | - 电子数据是法定证据种类之一(亮晶晶的数据小星星 ✨) 46 | - 收集电子数据应当严格遵守法定程序(魔法咒语要念对顺序哒~) 47 | - 必须确保数据的完整性、真实性和合法性(数据小仙子不能受伤哟~) 48 | - 违反程序可能导致证据无效(魔法失效会被扣分哒~) 49 | - 非法获取数据将承担法律责任(黑暗魔法会被惩戒的哟~) 50 | 51 | - 《中华人民共和国网络安全法》第 50 条 52 | (网络小警察在维持秩序哟~) 53 | 54 | > 规定了网络运营者配合网络安全监督管理 55 | 56 | - 必须在法律授权范围内进行数据获取(要有魔法许可证才能行动哟~) 57 | - 禁止未经授权访问他人数据(私闯魔法城堡会被警告哒~) 58 | - 违反规定最高可处罚金 100 万元(金币会被没收的哟~) 59 | - 构成犯罪的将追究刑事责任(黑暗巫师会被关进魔法监狱哒~) 60 | - 可能导致运营许可证被吊销(魔法杖会被折断的哟~) 61 | 62 | - 《电子数据取证规范》GA/T 1070-2013 63 | (取证小百科全书在此哟~) 64 | 65 | > 规定了电子数据取证的标准操作规程 66 | 67 | - 取证过程必须遵循无损性原则(温柔对待每一个字节呀~) 68 | - 要求记录完整的取证过程(魔法日记要写清楚步骤哒~) 69 | - 必须保证数据的同一性(数据双胞胎要长得一模一样哟~) 70 | - 需建立完整的证据链(魔法锁链要环环相扣哒~) 71 | - 取证人员应具备相应资质(要有魔法学院毕业证书哟~) 72 | 73 | ### 法律后果警示 74 | 75 | 违反上述法律法规可能导致: 76 | 77 | - 刑事处罚:构成犯罪的,处 3 年以下有期徒刑或者拘役(魔法监狱的小黑屋哟~) 78 | - 行政处罚:最高可处 100 万元罚款(金币哗啦啦流走啦~) 79 | - 民事责任:赔偿受害方经济损失(要卖魔法书抵债啦~) 80 | - 职业风险:可能被吊销相关执业资格(魔法杖会被收回哒~) 81 | 82 | ## 免责声明 83 | 84 | - 本工具仅供执法部门在法律框架内使用(只有持证巫师才能使用哟~) 85 | - 作者对任何非法使用或滥用概不负责(黑魔法后果自负哟~) 86 | - 使用本工具即表示同意遵守相关法律法规(魔法契约要签字哒~) 87 | 88 | ## 使用演示 89 | 90 | ![灵取证使用演示](assets/demo.png) 91 | (小司仪在展示魔法流程哟~) 92 | 93 | ## 系统要求 94 | 95 | ### 硬件要求 96 | 97 | - CPU: 双核处理器及以上(小魔法师的大脑要够聪明哟~) 98 | - 内存: 4GB RAM 及以上(魔法背包要够大才能装下数据呀~) 99 | - 硬盘空间: 最少 1GB 可用空间(魔法仓库要留有余地哒~) 100 | - USB 端口: USB 2.0 或以上(魔法桥梁要够稳固哟~) 101 | 102 | ### 软件要求 103 | 104 | | 操作系统 | 最低版本要求 | 魔法适配版本 | 105 | | -------- | ---------------- | ------------------- | 106 | | Windows | Windows 7 64 位 | 魔法兼容性测试通过~ | 107 | | macOS | macOS 10.14 | 苹果魔法水晶球适配~ | 108 | | Linux | Ubuntu 18.04 LTS | 开源魔法石板适配~ | 109 | 110 | ## 安装步骤 111 | 112 | ### 环境要求 113 | 114 | #### 必需组件 115 | 116 | 1. C++ 开发环境 117 | 118 | - GCC/G++ 7.0 或更高版本(魔法编译器要够强大哟~) 119 | - CMake 3.10 或更高版本(魔法构建师在此哒~) 120 | - Make 工具(魔法锻造台要准备好哟~) 121 | 122 | 2. 数据库支持 123 | 124 | - SQLite 3.0 或更高版本(数据水晶球要亮晶晶哒~) 125 | 126 | 3. 版本控制 127 | 128 | - Git 2.0 或更高版本(魔法时间旅行器在此哟~) 129 | 130 | 4. Android 开发工具 131 | - Android SDK Platform Tools(安卓魔法工具箱~) 132 | - ADB (Android Debug Bridge)(安卓魔法桥接器~) 133 | 134 | ### Windows 安装 135 | 136 | 1. 安装 ADB 工具 137 | 138 | ```powershell 139 | winget install Google.PlatformTools 140 | ``` 141 | 142 | (小医生在给 Windows 系统打魔法补丁哟~) 143 | 144 | 2. 安装依赖项 145 | 146 | ```powershell 147 | winget install Python.Python.3.8 148 | ``` 149 | 150 | (小助手在安装魔法依赖包呀~) 151 | 152 | ### macOS 安装 153 | 154 | 1. 安装 Homebrew(如未安装) 155 | 156 | ```bash 157 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 158 | ``` 159 | 160 | (小园丁在种植魔法花园哟~) 161 | 162 | 2. 安装 ADB 工具 163 | 164 | ```bash 165 | brew install android-platform-tools 166 | ``` 167 | 168 | (小管家在配置魔法工具库哒~) 169 | 170 | ### Linux 安装 171 | 172 | ```bash 173 | sudo apt update 174 | sudo apt install adb android-tools-adb android-tools-fastboot 175 | ``` 176 | 177 | (小管家在安装安卓魔法组件哟~) 178 | 179 | ## 编译逻辑算法 180 | 181 | ![灵取证编译逻辑算法](assets/灵取证系统流程图.png) 182 | (魔法能量在流动的示意图哟~) 183 | 184 | ## 功能特性 185 | 186 | | 功能 | 描述 | 命令 | 魔法小助手 | 187 | | ------------- | -------------------------------------------- | ---- | ---------- | 188 | | 通话记录导出 | 提取设备所有通话记录,包括时间、号码、时长等 | `1` | 小记录员 | 189 | | 短信导出 | 导出设备中的短信记录,包括收发时间、内容等 | `2` | 小邮差 | 190 | | 照片导出 | 提取设备中的照片文件 | `3` | 小天使 | 191 | | 视频导出 | 提取设备中的视频文件 | `4` | 小影迷 | 192 | | 应用导出 | 导出已安装的应用程序 APK 文件 | `5` | 小收藏家 | 193 | | 文档导出 | 提取设备中的文档文件 | `6` | 小管理员 | 194 | | 敏感信息提取 | 提取设备中的敏感数据信息 | `7` | 小侦探 | 195 | | 无线连接 | 通过 WiFi 连接设备 | `8` | 小使者 | 196 | | WiFi 信息 | 获取设备的 WiFi 连接信息 | `9` | 小专家 | 197 | | 系统信息 | 导出设备系统信息 | `10` | 小护士 | 198 | | 应用列表 | 获取已安装应用列表 | `11` | 小助手 | 199 | | WhatsApp 数据 | 提取 WhatsApp 聊天记录和媒体文件 | `12` | 小粉丝 | 200 | | 浏览器数据 | 提取浏览器历史记录和缓存 | `13` | 小探险家 | 201 | | 通知记录 | 导出设备通知历史 | `14` | 小使者 | 202 | 203 | ## 运行方法 204 | 205 | ### 下载安装 206 | 207 | 1. 从 [GitHub Releases](https://github.com/ctkqiang/LQZ/releases/tag/1.0.0) 下载最新版本 208 | (小天使在分发魔法卷轴哟~) 209 | 2. 验证下载文件的 SHA-256 校验和,确保文件完整性 210 | (魔法封印要完好无损呀~) 211 | 3. 解压下载的压缩包到本地目录 212 | (魔法书要摊开才能使用哟~) 213 | 214 | ### 程序运行 215 | 216 | 1. 打开终端,进入程序目录: 217 | (魔法阵要摆放在正确位置哟~) 218 | 2. 赋予执行权限: 219 | 220 | ```bash 221 | chmod +x phone_forensic 222 | ``` 223 | 224 | (给魔法书赋予生命呀~) 3. 运行程序: 225 | 226 | ```bash 227 | ./phone_forensic 228 | ``` 229 | 230 | (念动启动咒语哒~) 4. 按照程序提示输入相应的命令号码(1-14)执行对应功能。 231 | (小司仪在等待你的指令哟~) 232 | 233 | 注意:首次运行时,请确保: 234 | 235 | - Android 设备已开启 USB 调试模式(安卓小门卫要放行哟~) 236 | - 设备已通过 USB 连接到电脑(魔法桥梁要搭建好呀~) 237 | - ADB 服务正常运行(魔法服务器要启动哒~) 238 | - 具有足够的存储空间(魔法仓库不能满仓哟~) 239 | 240 | ## 注意事项 241 | 242 | 1. 使用前请确保设备已开启 USB 调试模式(安卓小门卫要放行哟~) 243 | 2. 首次连接设备时需要在设备上确认授权(安卓小精灵要同意哟~) 244 | 3. 建议使用原装 USB 线缆连接设备(魔法桥梁要稳固哒~) 245 | 4. 数据提取过程中请勿断开设备连接(魔法仪式不能中断呀~) 246 | 5. 定期备份提取的数据(魔法存档要及时哟~) 247 | 248 | ### 🤝 加入技术交流群 249 | 250 | 欢迎加入我们的技术交流群,与其他安全研究者分享经验和知识! 251 | 252 |
253 | 254 | 255 | 262 | 269 | 270 |
256 | 257 |
258 | QQ交流群: 934810107 259 |
260 | (扫码加入,一起探讨安全技术) 261 |
263 | 264 |
265 | 钉钉交流群 266 |
267 | (扫码加入,一起探讨安全技术) 268 |
271 |
272 | 273 | 274 | 275 | ## 许可证 276 | 277 | 本项目采用 **木兰宽松许可证 (Mulan PSL)** 进行许可。 278 | 有关详细信息,请参阅 [LICENSE](LICENSE) 文件。 279 | (魔法契约要保管好哟~) 280 | 281 | [![License: Mulan PSL v2](https://img.shields.io/badge/License-Mulan%20PSL%202-blue.svg)](http://license.coscl.org.cn/MulanPSL2) 282 | 283 | ## 🌟 开源项目赞助计划 284 | 285 | ### 用捐赠助力发展 286 | 287 | 感谢您使用本项目!您的支持是开源持续发展的核心动力。 288 | 每一份捐赠都将直接用于: 289 | ✅ 服务器与基础设施维护(魔法城堡的维修费哟~) 290 | ✅ 新功能开发与版本迭代(魔法技能树要升级哒~) 291 | ✅ 文档优化与社区建设(魔法图书馆要扩建呀~) 292 | 293 | 点滴支持皆能汇聚成海,让我们共同打造更强大的开源工具! 294 | (小仙子们在向你比心哟~) 295 | 296 | --- 297 | 298 | ### 🌐 全球捐赠通道 299 | 300 | #### 国内用户 301 | 302 |
303 | 304 |
305 | 306 | 307 | 312 | 317 | 318 |
308 | 309 |
310 | 🔵 支付宝(小企鹅在收金币哟~) 311 |
313 | 314 |
315 | 🟢 微信支付(小绿龙在收金币哟~) 316 |
319 |
320 |
321 | 322 | #### 国际用户 323 | 324 |
325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 |
341 | 342 | --- 343 | 344 | ### 📌 开发者社交图谱 345 | 346 | #### 技术交流 347 | 348 |
349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 |
361 | 362 | #### 社交互动 363 | 364 |
365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 |
377 | 378 | --- 379 | 380 | 🙌 感谢您成为开源社区的重要一员! 381 | 💬 捐赠后欢迎通过社交平台与我联系,您的名字将出现在项目致谢列表! 382 | (小仙子们在向你撒花哟~) 383 | -------------------------------------------------------------------------------- /model/model.cpp: -------------------------------------------------------------------------------- 1 | // 哇哦~欢迎来到超可爱的数据模型类世界呀 (๑•. •๑) 2 | // 这里就像是一个充满魔法的数据小窝窝,每一行代码都像是小仙子在翩翩起舞呢,可一定要好好疼爱每一个字节哟~ 3 | #include "model.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | // 呐呐~这个 `ADB_CONNECT` 15 | // 呀,就像是一座神奇的桥梁,它能让我们的电脑和安卓设备手牵手呢 (✿◠‿◠) 16 | // 不过要记得把 换成设备真正的 IP 17 | // 地址哟,不然桥梁可就搭不起来啦~ 18 | const std::string ADB_CONNECT = "adb connect :5555"; 19 | // 哎呀呀,`ADB_DISCONNECT` 20 | // 呢,就像是一场短暂的分别,当我们不想和设备聊天啦,就用它来断开连接哒 (๑•ω•๑) 21 | // 同样也要把 填对哟~ 22 | const std::string ADB_DISCONNECT = "adb disconnect :5555"; 23 | // 嘿嘿,`ADB_PULL` 24 | // 可是个超厉害的小魔法师,它能把安卓设备里的宝贝文件都拉到我们电脑里来呢 (๑•. 25 | // •๑) 就是设备里文件藏着的地方, 26 | // 就是我们要把文件放到电脑的哪里哒~ 27 | const std::string ADB_PULL = "adb pull "; 28 | // 哟哟~`ADB_SHELL` 29 | // 就像是一把神奇的钥匙,有了它,我们就能打开安卓设备的小秘密盒子,在里面执行各种有趣的命令啦 30 | // (✿◠‿◠) 31 | const std::string ADB_SHELL = "adb shell "; 32 | // 哇塞~`ADB_BACKUP_SMS` 这个大宝贝,能把安卓设备里的短信都小心翼翼地备份到 33 | // `Datas/Phone_dump_sms.ab` 文件里哟,就像是给短信们找了个安全的小房子住呢 34 | // (๑•ω•๑) 35 | const char* ADB_BACKUP_SMS = 36 | "adb backup -noapk -f Datas/Phone_dump_sms.ab -nocompress " 37 | "com.android.providers.telephony"; 38 | 39 | // 呀~`MODEL_RED` 40 | // 就像是一个调皮的小精灵,它能让我们输出的文字变成超级显眼的红色呢,这样重要的信息就一下子跳出来啦 41 | // (๑•. •๑) 42 | const std::string MODEL_RED = "\033[31m"; 43 | // 嘿嘿,`MODEL_WHITE` 44 | // 则是一个温柔的小天使,它能让文字颜色乖乖地变回白色,让一切都恢复到原来的可爱模样哒 45 | // (✿◠‿◠) 46 | const std::string MODEL_WHITE = "\033[0m"; 47 | 48 | // 哇哦~这个 `GetDeviceModel` 49 | // 函数呀,就像是一个超级侦探,它能帮我们找出连接的安卓设备到底是什么型号哟 50 | // (๑•ω•๑) 调用它,就能揭开设备型号的神秘面纱啦~ 51 | std::string Model::GetDeviceModel() const { return deviceModel; } 52 | 53 | // 呐呐~`Shell` 函数就像是一个贴心的小秘书,我们把要执行的 ADB shell 54 | // 命令告诉它,它就会乖乖地去帮我们办好,还会把执行的结果打印出来给我们看呢 55 | // (✿◠‿◠) 56 | void Model::Shell(std::string command) { 57 | // 先让 `executeCommand` 这个小助手去执行 ADB_SHELL 58 | // 加上我们给的具体命令的组合 59 | std::string output = executeCommand(ADB_SHELL + command); 60 | // 然后把执行的结果美美的打印出来哟 61 | printf("%s\n", output.c_str()); 62 | } 63 | 64 | // 哎呀呀,`executeCommand` 65 | // 函数可是个超级能干的小魔法师呢,它能执行系统命令,还能把命令执行后的输出结果都收集起来给我们哟 66 | // (๑•. •๑) 67 | std::string Model::executeCommand(const std::string& cmd) { 68 | // 这个 `buffer` 就像是一个小口袋,用来暂时装一下命令输出的内容哒 69 | char buffer[128]; 70 | // `result` 71 | // 则是一个大箱子,把口袋里的内容都收集起来,最后变成完整的输出结果哟 72 | std::string result; 73 | // 打开一个神奇的管道,让命令能在里面运行呢 74 | FILE* pipe = popen(cmd.c_str(), "r"); 75 | 76 | // 如果管道打开失败了,就像魔法失灵啦,只能返回一个空空的箱子咯 77 | if (!pipe) return ""; 78 | 79 | // 从管道里把输出内容一点点地掏出来,放到大箱子里哟 80 | while (fgets(buffer, sizeof(buffer), pipe) != nullptr) { 81 | result += buffer; 82 | } 83 | 84 | // 用完管道后,要把它乖乖地关上哟 85 | pclose(pipe); 86 | 87 | // 最后把装满输出结果的大箱子交还给我们啦 88 | return result; 89 | } 90 | 91 | // 哇塞~`CheckDevice` 92 | // 函数就像是一个小门卫,它能帮我们看看有没有成功连接到安卓设备呢 (๑•ω•๑) 93 | // 如果连接上了,还会把设备型号偷偷记下来哟~ 94 | bool Model::CheckDevice() { 95 | // 先让 `executeCommand` 小助手去执行 `adb devices -l` 96 | // 命令,看看能得到什么信息 97 | std::string output = executeCommand("adb devices -l"); 98 | 99 | // 如果输出里找到了 "model" 这个小线索,说明可能已经连接到设备啦 100 | if (output.find("model") != std::string::npos) { 101 | // 用一个神奇的正则表达式魔法,把设备型号从输出里抓出来 102 | std::regex pattern("device:[a-z0-9]+"); 103 | // 这个 `match` 就像是一个小夹子,用来夹住抓到的设备型号 104 | std::smatch match; 105 | 106 | // 如果成功夹住了设备型号,就把它放到 `deviceModel` 107 | // 这个小盒子里保存起来,然后告诉我们连接成功啦 108 | if (std::regex_search(output, match, pattern)) { 109 | deviceModel = match.str(); 110 | return true; 111 | } 112 | } 113 | 114 | // 如果没有抓到设备型号,那就说明还没连接上设备哟 115 | return false; 116 | } 117 | 118 | // 哟哟~`DumpSMS` 函数就像是一个超级细心的小管家,它会先给我们创建一个 `Datas` 119 | // 小房间,然后把安卓设备里的短信都好好地备份起来呢 (✿◠‿◠) 120 | void Model::DumpSMS() { 121 | // 轻轻地创建一个 `Datas` 小房间,如果房间已经有啦,也没关系哒 122 | fs::create_directories("Datas"); 123 | 124 | // 用 `ADB_BACKUP_SMS` 这个大宝贝把短信备份好 125 | system(ADB_BACKUP_SMS); 126 | // 再用 `mvt - android` 127 | // 工具检查备份文件,把有用的数据提取出来,最后把备份文件这个小包袱扔掉哟 128 | system( 129 | "mvt-android check-backup Datas/Phone_dump_sms.ab -o Datas/ && rm " 130 | "Datas/Phone_dump_sms.ab"); 131 | } 132 | 133 | // 哇哦~`DumpPhotos` 函数就像是一个爱拍照的小天使,它会创建一个 `Datas` 134 | // 小相册,然后把安卓设备里的照片都拉到相册里来呢 (๑•ω•๑) 135 | void Model::DumpPhotos() { 136 | // 先创建一个美美的 `Datas` 小相册 137 | fs::create_directories("Datas"); 138 | // 把设备里 `/sdcard/Pictures` 这个照片小仓库里的照片都搬到相册里来哟 139 | system("adb pull /sdcard/Pictures Datas/"); 140 | } 141 | 142 | // 哎呀呀,`DumpDownloads` 函数就像是一个勤劳的小快递员,它会创建一个 `Datas` 143 | // 小包裹站,然后把安卓设备里下载的文件都送到包裹站里呢 (๑•. •๑) 144 | void Model::DumpDownloads() { 145 | // 建一个可爱的 `Datas` 小包裹站 146 | fs::create_directories("Datas"); 147 | // 把设备里 `/sdcard/Download` 这个下载小基地里的文件都拉到包裹站里哟 148 | system("adb pull /sdcard/Download Datas/"); 149 | } 150 | 151 | // 呐呐~`CheckAdb` 函数就像是一个小医生,它能帮我们检查一下电脑里有没有安装 ADB 152 | // 工具呢 (✿◠‿◠) 如果没有安装,还会根据不同的系统给我们想办法安装哟~ 153 | void Model::CheckAdb() { 154 | // 先让 `executeCommand` 小助手去执行 `adb version` 命令,看看能不能得到 ADB 155 | // 工具的版本信息 156 | std::string output = executeCommand("adb version"); 157 | 158 | // 如果输出是空的,就说明 ADB 工具还没安装呢 159 | if (output.empty()) { 160 | #ifdef _WIN32 161 | // 如果是 Windows 系统,就像小医生拿出了一个 Windows 162 | // 专属的小药方,提示我们正在安装 ADB 工具,然后用 `winget` 来安装 163 | std::cout << "ADB未安装,正在安装..." << std::endl; 164 | system("powershell -Command \"winget install Google.PlatformTools\""); 165 | 166 | // 找到用户的主目录,就像找到了小房子的地址 167 | std::string home = getenv("USERPROFILE"); 168 | // 再找到 ADB 工具安装的地方,就像找到了小宝贝藏在哪里 169 | std::string adbPath = 170 | home + "\\AppData\\Local\\Android\\Sdk\\platform-tools"; 171 | // 然后把 ADB 172 | // 工具的地址加到系统的环境变量里,就像给小宝贝在系统里留了个小纸条 173 | std::string cmd = "setx PATH \"%PATH%;" + adbPath + "\""; 174 | // 执行这个命令,把小纸条贴好 175 | system(cmd.c_str()); 176 | #elif __APPLE__ 177 | // 如果是 macOS 系统,小医生就拿出了 macOS 178 | // 专属的小药方,提示我们正在安装 ADB 工具,然后用 `brew` 来安装 179 | std::cout << "ADB未安装,正在安装..." << std::endl; 180 | system("brew install android-platform-tools"); 181 | #else 182 | // 如果是其他系统,小医生有点没办法啦,只能提示我们手动安装 ADB 183 | // 工具,然后伤心地退出程序咯 184 | std::cout << "请手动安装ADB工具" << std::endl; 185 | exit(1); 186 | #endif 187 | // 最后提醒我们重启终端,让环境变量这个小纸条生效哟 188 | std::cout << "请重启终端以使环境变量生效" << std::endl; 189 | exit(0); 190 | } 191 | } 192 | 193 | // 哇塞~`DumpContacts` 函数就像是一个超级记忆小能手,它会创建一个 `Datas` 194 | // 小仓库,然后把安卓设备里联系人的数据库文件都存到仓库里呢 (๑•ω•๑) 195 | void Model::DumpContacts() { 196 | // 建一个大大的 `Datas` 小仓库 197 | fs::create_directories("Datas"); 198 | // 把设备里联系人数据库文件 199 | // `/data/data/com.android.providers.contacts/databases/contacts2.db` 200 | // 搬到仓库里哟 201 | system( 202 | "adb pull " 203 | "/data/data/com.android.providers.contacts/databases/contacts2.db " 204 | "Datas/"); 205 | // 再把通话记录数据库文件 206 | // `/data/data/com.android.providers.contacts/databases/calllog.db` 207 | // 也搬到仓库里哟 208 | system( 209 | "adb pull " 210 | "/data/data/com.android.providers.contacts/databases/calllog.db " 211 | "Datas/"); 212 | } 213 | 214 | // 哟哟~`DumpMessage` 函数就像是一个贴心的小邮差,它会创建一个 `Datas` 215 | // 小信箱,然后把安卓设备里短信的数据库文件都放到信箱里呢 (✿◠‿◠) 216 | void Model::DumpMessage() { 217 | // 先建一个萌萌的 `Datas` 小信箱 218 | fs::create_directories("Datas"); 219 | // 把设备里短信数据库文件 220 | // `/data/data/com.android.providers.telephony/databases/mmssms.db` 221 | // 放到信箱里哟 222 | system( 223 | "adb pull " 224 | "/data/data/com.android.providers.telephony/databases/mmssms.db " 225 | "Datas/"); 226 | } 227 | 228 | // 哇哦~`Dumpfiles` 函数就像是一个超级大搬运工,它会创建一个 `Datas/sdcard` 229 | // 大仓库,然后把安卓设备里整个 SD 卡的内容都搬到仓库里呢 (๑•ω•๑) 230 | void Model::Dumpfiles() { 231 | // 建一个超级大的 `Datas` 大仓库 232 | fs::create_directories("Datas"); 233 | // 把设备里 SD 卡的所有东西都搬到仓库里哟 234 | system("adb pull /sdcard/ Datas/sdcard/"); 235 | } 236 | 237 | // 哎呀呀,`ConnectWirelessly` 238 | // 函数就像是一个浪漫的小使者,它会让我们输入安卓设备的 IP 239 | // 地址,然后尝试用无线的方式和设备牵起手来呢 (๑•. •๑) 240 | void Model::ConnectWirelessly() { 241 | // 准备一个小本子,用来记录我们输入的设备 IP 地址 242 | std::string ip; 243 | // 温柔地提示我们输入设备的 IP 地址哟 244 | std::cout << "请输入手机IP地址: "; 245 | // 把我们输入的 IP 地址记到小本子上 246 | std::getline(std::cin, ip); 247 | 248 | // 用 IP 地址和端口号组成一个神奇的连接咒语 249 | std::string connect_cmd = "adb connect " + ip + ":5555"; 250 | // 让 `executeCommand` 小助手去念这个咒语,看看能不能和设备连接上 251 | std::string output = executeCommand(connect_cmd); 252 | 253 | // 如果咒语生效啦,输出里找到了 "connected" 254 | // 这个小魔法词,就说明成功和设备连接上啦 255 | if (output.find("connected") != std::string::npos) { 256 | std::cout << "成功连接到设备 " << ip << std::endl; 257 | } else { 258 | // 如果咒语没生效,就温柔地告诉我们可能是哪里出了问题,让我们检查一下哟 259 | std::cout << "连接失败,请确保:" << std::endl; 260 | std::cout << "1. 手机和电脑在同一网络" << std::endl; 261 | std::cout << "2. 手机已启用USB调试和无线调试" << std::endl; 262 | std::cout << "3. IP地址正确" << std::endl; 263 | } 264 | } 265 | 266 | // 哇塞~`DumpCallLogs` 函数就像是一个超级记录员,它会创建一个 `Datas/CallLogs` 267 | // 小本子,然后把安卓设备里的通话记录都工工整整地记到本子里呢 (๑•ω•๑) 268 | void Model::DumpCallLogs() { 269 | // 先建一个可爱的 `Datas/CallLogs` 小本子 270 | fs::create_directories("Datas/CallLogs"); 271 | 272 | // 用命令把设备里的通话记录记到小本子里 273 | system( 274 | "adb shell content query --uri content://call_log/calls " 275 | "--projection date,number,duration,type " 276 | "> Datas/CallLogs/call_logs.log"); 277 | 278 | // 再用另一个命令把通话记录变成美美的格式,也记到小本子里哟 279 | system( 280 | "adb shell \"content query --uri content://call_log/calls " 281 | "--projection date,number,duration,type " 282 | "| awk '{print strftime(\\\"%Y-%m-%d %H:%M:%S\\\", substr(\\$1, " 283 | "2)/1000), \\$2, \\$3, \\$4}' " 284 | "\" > Datas/CallLogs/formatted_call_logs.log"); 285 | } 286 | 287 | // 哟哟~`DumpVideos` 函数就像是一个超级电影迷,它会创建一个 `Datas` 288 | // 小电影院,然后把安卓设备里的视频文件都搬到电影院里呢 (✿◠‿◠) 289 | void Model::DumpVideos() { 290 | // 建一个大大的 `Datas` 小电影院 291 | fs::create_directories("Datas"); 292 | // 把设备里相机拍摄的视频文件 `/sdcard/DCIM/Camera` 搬到电影院里哟 293 | system("adb pull /sdcard/DCIM/Camera Datas/Videos/"); 294 | // 再把设备里电影文件夹里的视频文件 `/sdcard/Movies` 也搬到电影院里哟 295 | system("adb pull /sdcard/Movies Datas/Videos/"); 296 | } 297 | 298 | // 哇哦~`DumpApks` 函数就像是一个超级软件收藏家,它会创建一个 `Datas/APKs` 299 | // 小软件库,然后把安卓设备里的 APK 文件信息和文件都收集到软件库里呢 (๑•ω•๑) 300 | void Model::DumpApks() { 301 | // 建一个美美的 `Datas/APKs` 小软件库 302 | fs::create_directories("Datas/APKs"); 303 | // 用命令把设备里已安装应用的包名信息记到软件库的一个小本子里 304 | system("adb shell pm list packages -f > Datas/APKs/installed_apps.log"); 305 | // 把设备里 `/data/app/` 这个软件小仓库里的 APK 文件都搬到软件库里哟 306 | system("adb pull /data/app/ Datas/APKs/"); 307 | } 308 | 309 | // 哎呀呀,`DumpDocuments` 函数就像是一个超级文档管理员,它会创建一个 310 | // `Datas/Documents` 小文档室,然后把安卓设备里的文档文件都整理到文档室里呢 (๑•. 311 | // •๑) 312 | void Model::DumpDocuments() { 313 | // 建一个整洁的 `Datas/Documents` 小文档室 314 | fs::create_directories("Datas/Documents"); 315 | // 把设备里文档文件夹 `/sdcard/Documents` 里的文档文件搬到文档室里哟 316 | system("adb pull /sdcard/Documents Datas/Documents/"); 317 | // 再把设备里下载文件夹 `/sdcard/Download` 里的文档文件也搬到文档室里哟 318 | system("adb pull /sdcard/Download Datas/Documents/"); 319 | } 320 | 321 | // 哇塞~`ExtractSensitiveInfo` 函数就像是一个超级小侦探,它会创建一个 322 | // `Datas/Sensitive` 323 | // 小秘密基地,然后把安卓设备里的敏感信息都偷偷地收集到基地里呢 (๑•ω•๑) 324 | void Model::ExtractSensitiveInfo() { 325 | // 建一个神秘的 `Datas/Sensitive` 小秘密基地 326 | fs::create_directories("Datas/Sensitive"); 327 | // 把设备里 SD 卡的所有内容都搬到秘密基地里哟 328 | system("adb pull /sdcard/ Datas/Sensitive/"); 329 | } 330 | 331 | // 哟哟~`GetWifiAddress` 函数就像是一个超级网络小专家,它会创建一个 332 | // `Datas/Network` 小网络实验室,然后把安卓设备的 WiFi 333 | // 地址和网络信息都好好地研究记录下来呢 (✿◠‿◠) 334 | void Model::GetWifiAddress() { 335 | // 建一个科技感满满的 `Datas/Network` 小网络实验室 336 | fs::create_directories("Datas/Network"); 337 | 338 | // 用命令获取设备的 WiFi 接口信息,就像给 WiFi 接口做个小检查 339 | std::string wifiInfo = executeCommand( 340 | "adb shell \"ip addr show wlan0 2>/dev/null || ip addr show wlan1\""); 341 | 342 | // 用命令获取设备当前的 WiFi 连接信息,看看它和哪个 WiFi 小天使牵手啦 343 | std::string wifiConnection = 344 | executeCommand("adb shell \"dumpsys wifi | grep 'mWifiInfo'\""); 345 | 346 | // 用命令获取设备所有的网络接口信息,就像把设备的网络小触角都摸一遍 347 | std::string allInterfaces = executeCommand("adb shell ip addr"); 348 | 349 | // 用命令获取设备的路由表信息,看看网络数据是怎么跑来跑去的 350 | std::string routingTable = executeCommand("adb shell ip route"); 351 | 352 | // 把这些网络信息都小心翼翼地写到一个文件里,就像写一本网络小日记 353 | try { 354 | // 获取当前的时间,给日记加上一个时间戳 355 | auto now = std::chrono::system_clock::now(); 356 | auto timeStamp = std::chrono::system_clock::to_time_t(now); 357 | 358 | // 打开一个文件,准备开始写日记啦 359 | std::ofstream file("Datas/Network/network_info.log"); 360 | // 如果文件打不开,就像日记的本子坏了,会伤心地抛出一个异常哟 361 | if (!file.is_open()) { 362 | throw std::runtime_error("Cannot create network info file"); 363 | } 364 | 365 | // 给日记写上一个大大的标题 366 | file << "=== Network Information Report ===" << std::endl; 367 | // 写上日记的生成时间 368 | file << "Generated: " << std::ctime(&timeStamp); 369 | // 写上设备的型号,就像给日记加上一个小标签 370 | file << "Device Model: " << deviceModel << std::endl << std::endl; 371 | 372 | // 写上 WiFi 接口的信息,如果没有找到接口,就说声小遗憾哟 373 | file << "=== WiFi Interface Information ===" << std::endl; 374 | file << (wifiInfo.empty() ? "No WiFi interface found" : wifiInfo) 375 | << std::endl; 376 | 377 | // 写上当前的 WiFi 连接信息,如果没有连接,就说声小寂寞哟 378 | file << "=== Current WiFi Connection ===" << std::endl; 379 | file << (wifiConnection.empty() ? "No active WiFi connection" 380 | : wifiConnection) 381 | << std::endl; 382 | 383 | // 写上所有的网络接口信息 384 | file << "=== All Network Interfaces ===" << std::endl; 385 | file << allInterfaces << std::endl; 386 | 387 | // 写上路由表信息 388 | file << "=== Routing Table ===" << std::endl; 389 | file << routingTable << std::endl; 390 | 391 | // 写完日记,把本子合上啦 392 | file.close(); 393 | 394 | // 用一个神奇的正则表达式魔法,从 WiFi 接口信息里找出 IP 地址 395 | std::regex ipPattern(R"(inet\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}))"); 396 | std::smatch match; 397 | // 如果成功找到了 IP 地址,就把它写到另一个小文件里,就像给 IP 398 | // 地址建个小档案 399 | if (std::regex_search(wifiInfo, match, ipPattern)) { 400 | std::string ip = match[1]; 401 | std::ofstream ipFile("Datas/Network/wireless_debug_ip.log"); 402 | // 如果小档案的本子打不开,也会伤心地抛出一个异常哟 403 | if (!ipFile.is_open()) { 404 | throw std::runtime_error( 405 | "Cannot create wireless debug IP file"); 406 | } 407 | // 给小档案写上一个标题 408 | ipFile << "=== ADB Wireless Debug Information ===" << std::endl; 409 | // 写上小档案的生成时间 410 | ipFile << "Generated: " << std::ctime(&timeStamp); 411 | // 写上 IP 地址 412 | ipFile << "IP Address: " << ip << std::endl; 413 | // 写上端口号 414 | ipFile << "Port: 5555" << std::endl; 415 | // 写上连接命令 416 | ipFile << "Connection Command: adb connect " << ip << ":5555" 417 | << std::endl; 418 | // 写完小档案,把本子合上啦 419 | ipFile.close(); 420 | } 421 | } catch (const std::exception& e) { 422 | // 如果写日记或者建小档案的时候出了问题,就用红色的字伤心地告诉我们哟 423 | std::cerr << MODEL_RED << "[!] Error: " << e.what() << MODEL_WHITE 424 | << std::endl; 425 | } 426 | } 427 | 428 | // 哇哦~`DumpSystemInfo` 函数就像是一个超级系统小护士,它会创建一个 429 | // `Datas/System` 小病房,然后把安卓设备的系统信息都好好地记录到病房的病历本里呢 430 | // (๑•ω•๑) 431 | void Model::DumpSystemInfo() { 432 | // 建一个温馨的 `Datas/System` 小病房 433 | fs::create_directories("Datas/System"); 434 | // 用命令把设备的系统信息写到病历本 `Datas/System/system_info.log` 里哟 435 | system("adb shell dumpsys > Datas/System/system_info.log"); 436 | } 437 | 438 | // 哎呀呀,`ListPackages` 函数就像是一个超级软件清单小助手,它会创建一个 439 | // `Datas/Packages` 440 | // 小清单本,然后把安卓设备里已安装应用的包名信息都记到清单本里呢 (๑•. •๑) 441 | void Model::ListPackages() { 442 | // 建一个整齐的 `Datas/Packages` 小清单本 443 | fs::create_directories("Datas/Packages"); 444 | // 用命令把设备里已安装应用的包名信息记到清单本 445 | // `Datas/Packages/installed_packages.log` 里哟 446 | system( 447 | "adb shell pm list packages > Datas/Packages/installed_packages.log"); 448 | } 449 | 450 | // 哇塞~`ExtractWhatsApp` 函数就像是一个超级 WhatsApp 小粉丝,它会创建一个 451 | // `Datas/WhatsApp` 小粉丝俱乐部,然后把安卓设备里的 WhatsApp 452 | // 数据都拉到俱乐部里呢 (๑•ω•๑) 453 | void Model::ExtractWhatsApp() { 454 | // 建一个热闹的 `Datas/WhatsApp` 小粉丝俱乐部 455 | fs::create_directories("Datas/WhatsApp"); 456 | // 把设备里 `/sdcard/Android/data/com.whatsapp/` 这个 WhatsApp 457 | // 小天地里的数据都拉到俱乐部里哟 458 | system("adb pull /sdcard/Android/data/com.whatsapp/ Datas/WhatsApp/"); 459 | } 460 | 461 | // 哟哟~`ExtractBrowserData` 函数就像是一个超级浏览器小探险家,它会创建一个 462 | // `Datas/Browser` 463 | // 小探险基地,然后去安卓设备的浏览器里探险,把有用的数据都带回来呢 (✿◠‿◠) 464 | void Model::ExtractBrowserData() { 465 | // 建一个充满冒险气息的 `Datas/Browser` 小探险基地 466 | fs::create_directories("Datas/Browser"); 467 | 468 | // 启用 Chrome 浏览器的无障碍服务,就像给探险队开了一个小绿灯 469 | system( 470 | "adb shell settings put secure enabled_accessibility_services " 471 | "com.android.chrome/" 472 | "com.android.chrome.accessibility.AccessibilityService"); 473 | 474 | // 从设备的 logcat 里找出 HTTPS URL 信息,就像在探险中发现了神秘的宝藏线索 475 | system("adb logcat -d | grep -i \"https\" > Datas/Browser/https_urls.log"); 476 | 477 | // 把 Chrome 浏览器的缓存文件拉到探险基地里,就像把宝藏的小碎片都收集起来 478 | system( 479 | "adb pull /sdcard/Android/data/com.android.chrome/cache/ " 480 | "Datas/Browser/chrome_cache/"); 481 | // 把 WebView 的缓存文件也拉到探险基地里,就像收集更多的宝藏碎片 482 | system( 483 | "adb pull /data/data/com.android.webview/cache/ " 484 | "Datas/Browser/webview_cache/"); 485 | 486 | // 设置一个代理,就像给探险队安排了一个小向导 487 | system("adb shell settings put global http_proxy 192.168.1.100:8080"); 488 | 489 | // 把 Chrome 浏览器的历史记录文件拉到探险基地里,就像打开了一本探险日记 490 | system( 491 | "adb pull /data/data/com.android.chrome/app_chrome/Default/History " 492 | "Datas/Browser/"); 493 | // 用 `sqlite3` 494 | // 工具从历史记录文件里找出有用的信息,就像从日记里读出精彩的故事 495 | system( 496 | "sqlite3 Datas/Browser/History \"SELECT * FROM urls;\" > " 497 | "Datas/Browser/browsing_history.log"); 498 | } 499 | 500 | // 哇哦~`ExtractNotifications` 函数就像是一个超级通知小使者,它会创建一个 501 | // `Datas/Notifications` 小通知站,然后把安卓设备里的通知信息都收集到通知站里呢 502 | // (๑•ω•๑) 503 | void Model::ExtractNotifications() { 504 | // 建一个明亮的 `Datas/Notifications` 小通知站 505 | fs::create_directories("Datas/Notifications"); 506 | // 用命令把设备里的通知信息收集到通知站的小本子 507 | // `Datas/Notifications/notifications.log` 里哟 508 | system( 509 | "adb shell dumpsys notification > " 510 | "Datas/Notifications/notifications.log"); 511 | } 512 | 513 | void Model::DumpSysFromSpecificPackage(std::string PACKAGE_NAME) { 514 | fs::create_directories("Datas/SysFromSpecificPackage"); 515 | 516 | system(("adb shell dumpsys package " + PACKAGE_NAME + 517 | "> Datas/SysFromSpecificPackage/" + PACKAGE_NAME + ".log") 518 | .c_str()); 519 | } 520 | 521 | void Model::RunApkTool(std::string APK_FILE) { 522 | std::string line; 523 | int line_num = 0; 524 | 525 | std::string decompiled_dir = APK_FILE.substr(0, APK_FILE.find_last_of(".")); 526 | std::string manifest_path = decompiled_dir + "/AndroidManifest.xml"; 527 | std::string strings_path = decompiled_dir + "/res/values/strings.xml"; 528 | std::string output_file = APK_FILE + "_敏感数据泄漏.log"; 529 | 530 | std::vector keywords = { 531 | "token", "key", "firebase", "secret", "public", 532 | "aws", "api", "tencent", "auth", 533 | }; 534 | 535 | std::cout << "🏗️ 正在解包 APK..." << std::endl; 536 | system(("apktool d -f " + APK_FILE + " -o " + decompiled_dir).c_str()); 537 | 538 | std::cout << "🔍 正在扫描敏感关键词..." << std::endl; 539 | 540 | std::ofstream out(output_file); 541 | if (!out.is_open()) { 542 | std::cerr << "❌ 无法打开输出文件: " << output_file << std::endl; 543 | return; 544 | } 545 | 546 | auto scan_file = [&](const std::string& path) { 547 | std::ifstream in(path); 548 | if (!in.is_open()) { 549 | std::cerr << "⚠️ 无法打开文件: " << path << std::endl; 550 | return; 551 | } 552 | 553 | while (std::getline(in, line)) { 554 | ++line_num; 555 | 556 | for (const auto& kw : keywords) { 557 | if (line.find(kw) != std::string::npos) { 558 | out << "[文件: " << path << "] 第 " << line_num 559 | << " 行包含 [" << kw << "]: " << line << "\n"; 560 | break; 561 | } 562 | } 563 | } 564 | 565 | in.close(); 566 | }; 567 | 568 | scan_file(manifest_path); 569 | scan_file(strings_path); 570 | 571 | out.close(); 572 | 573 | std::cout << "✅ 扫描完成,结果已写入: " << output_file << std::endl; 574 | } 575 | 576 | bool ContainsAny(const std::string& line, 577 | const std::vector& keywords) { 578 | for (const auto& keyword : keywords) { 579 | if (line.find(keyword) != std::string::npos) { 580 | return true; 581 | } 582 | } 583 | return false; 584 | } 585 | 586 | void Model::Extract微信() { 587 | const std::string outputDir = "Datas/微信"; 588 | fs::create_directories(outputDir); 589 | 590 | std::cout << "📱 检查设备连接状态..." << std::endl; 591 | if (system("adb get-state > nul 2>&1") != 0) { 592 | std::cerr << "❌ 设备未连接。" << std::endl; 593 | return; 594 | } 595 | 596 | std::cout << "📤 正在尝试提取 /sdcard 路径..." << std::endl; 597 | std::string pull_sdcard = 598 | "adb pull /sdcard/Android/data/com.tencent.mm/ \"" + outputDir + 599 | "/sdcard/\""; 600 | int result_sdcard = system(pull_sdcard.c_str()); 601 | 602 | if (result_sdcard == 0) { 603 | std::cout << "✅ 成功提取 /sdcard 目录。" << std::endl; 604 | return; 605 | } 606 | 607 | std::cout << "⚠️ /sdcard 不可访问,尝试 /data/data 路径(需要 root)..." 608 | << std::endl; 609 | std::string pull_data = 610 | "adb shell su -c 'cp -r /data/data/com.tencent.mm /sdcard/wechat_tmp " 611 | "&& chmod -R 777 /sdcard/wechat_tmp'"; 612 | int result_root = system(pull_data.c_str()); 613 | 614 | if (result_root != 0) { 615 | std::cerr << "❌ 无法访问 /data/data。需要 root 权限。" << std::endl; 616 | return; 617 | } 618 | 619 | std::string pull_tmp = 620 | "adb pull /sdcard/wechat_tmp \"" + outputDir + "/data_data/\""; 621 | if (system(pull_tmp.c_str()) == 0) { 622 | std::cout << "✅ 成功提取 /data/data 目录。" << std::endl; 623 | } else { 624 | std::cerr << "❌ 复制 /data/data 失败。" << std::endl; 625 | } 626 | } 627 | --------------------------------------------------------------------------------