Radare2 框架介绍及使用
Radare2 框架介绍及使用
欢迎入群交流
radare2
这是整个框架的核心工具,它具有debugger和Hexeditor的核心功能,使您能够像打开普通的文件一样,打开许多输入/输出源,包括磁盘、网络连接、内核驱动和处于调试中的进程等。
它实现了一个高级的命令行界面,可用于在文件内部活动和浏览,分析数据,反编译,打补丁,比较数据,搜索,替换和可视化。您可以用多种编程语言编写radare2的脚本,包括Python, Ruby, JavaScript, Lua, 和 Perl。
rabin2
该程序用于从可执行文件中提取信息,例如ELF, PE, Java CLASS, Mach-O, 以及各种r2引擎所支持的二进制文件格式。r2核心使用rabin2获取数据,例如导出的符号,导入的函数和DLL等,文件的元信息,交叉引用(xrefs),依赖库以及文件区段信息。
rahash2
基于块的哈希工具,无论是一段短小的字符串,还是巨大的磁盘文件,rahash2都支持多种算法进行hash,包括MD4, MD5, CRC16, CRC32, SHA1, SHA256以及其他种种。 rahash2可用于完整性检查,或是追踪大文件、内存转储或磁盘上的变化。
rahash2 fineagent.jar
fineagent.jar: 0x00000000-0x00008a54 sha1: db077a2a9da66e9437c0d8e4cc6035a6ccda1a37
rahash2 -a sha256 fineagent.jar
fineagent.jar: 0x00000000-0x00008a54 sha256: 6c32e36008a8dd0a0cd196f16630d7cb6b1bb12a70dc50826656e047e648ef4b
radiff2
一个二进制差异比较工具, 实现了多种算法。它支持二进制文件的字节级比较以及差分比较, 以及支持代码差异比较,用于发现在Radare2分析工作中代码块发生的更改。
rafind2
用于在文件中根据pattern找到对应的字节串。
下载radare2
https://github.com/radareorg/radare2
cd radare2
./sys/install.sh
卸载radare2
make uninstall
make purge
使用radare2
radare2 -h
Usage: r2 [-ACdfLMnNqStuvwzX] [-P patch] [-p prj] [-a arch] [-b bits] [-i file][-s addr] [-B baddr] [-m maddr] [-c cmd] [-e k=v] file|pid|-|--|=-- run radare2 without opening any file- same as 'r2 malloc://512'= read file from stdin (use -i and -c to run cmds)-= perform !=! command to run all commands remotely-0 print \x00 after init and every command-2 close stderr file descriptor (silent warning messages)-a [arch] set asm.arch-A run 'aaa' command to analyze all referenced code-b [bits] set asm.bits-B [baddr] set base address for PIE binaries-c 'cmd..' execute radare command-C file is host:port (alias for -c+=http://%s/cmd/)-d debug the executable 'file' or running process 'pid'-D [backend] enable debug mode (e cfg.debug=true)-e k=v evaluate config var-f block size = file size-F [binplug] force to use that rbin plugin-h, -hh show help message, -hh for long-H ([var]) display variable-i [file] run script file-I [file] run script file before the file is opened-j use json for -v, -L and maybe others-k [OS/kern] set asm.os (linux, macos, w32, netbsd, ...)-l [lib] load plugin file-L, -LL list supported IO plugins (-LL list core plugins)-m [addr] map file at given address (loadaddr)-M do not demangle symbol names-n, -nn do not load RBin info (-nn only load bin structures)-N do not load user settings and scripts-NN do not load any script or plugin-q quiet mode (no prompt) and quit after -i-qq quit after running all -c and -i-Q quiet mode (no prompt) and quit faster (quickLeak=true)-p [prj] use project, list if no arg, load if no file-P [file] apply rapatch file and quit-r [rarun2] specify rarun2 profile to load (same as -e dbg.profile=X)-R [rr2rule] specify custom rarun2 directive-s [addr] initial seek-S start r2 in sandbox mode-t load rabin2 info in thread-u set bin.filter=false to get raw sym/sec/cls names-v, -V show radare2 version (-V show lib versions)-w open file in write mode-x open without exec-flag (asm.emu will not work), See io.exec-X same as -e bin.usextr=false (useful for dyldcache)-z, -zz do not load strings or load them even in raw
交互式命令行
要分析的文件名 test
radare2 test
iI
获取基本信息
[0x0007e1fe]> iIarch arm
baddr 0x100000000
binsz 26965216
bintype mach0
bits 64
canary true
class MACH064
compiler clang
crypto false
endian little
havecode true
intrp /usr/lib/dyld
laddr 0x0
lang swift
linenum false
lsyms false
machine all
nx false
os ios
pic true
relocs true
sanitize false
static false
stripped true
subsys darwin
va true
il
library
[0x0007e1fe]> il[Linked libraries]
/usr/lib/libc++.1.dylib
/System/Library/Frameworks/CFNetwork.framework/CFNetwork
/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation3 libraries
ii
获取所有导入的库
[0x0007e1fe]> ii[Imports]
nth vaddr bind type lib name
――――――――――――――――――――――――――――――――――――――――――――
0 0x00ecf074 NONE FUNC ABAddressBookGetAuthorizationStatus
1 0x00000000 NONE FUNC ALAssetPropertyType
2 0x00000000 NONE FUNC ALAssetTypeVideo
3 0x00000000 NONE FUNC AVAssetExportPresetHighestQuality
4 0x00000000 NONE FUNC AVAssetExportPresetLowQuality
5 0x00000000 NONE FUNC AVAssetExportPresetMediumQuality
6 0x00000000 NONE FUNC AVAssetExportPresetPassthrough
7 0x00000000 NONE FUNC AVAssetImageGeneratorApertureModeProductionAperture
8 0x00000000 NONE FUNC AVAudioSessionCategoryPlayAndRecord
9 0x00000000 NONE FUNC AVAudioSessionCategoryPlayback
10 0x00000000 NONE FUNC AVAudioSessionInterruptionNotification
11 0x00000000 NONE FUNC AVAudioSessionInterruptionTypeKey
12 0x00000000 NONE FUNC AVAudioSessionInterruptionWasSuspendedKey
13 0x00000000 NONE FUNC AVAudioSessionMediaServicesWereLostNotification
14 0x00000000 NONE FUNC AVAudioSessionMediaServicesWereResetNotification
15 0x00000000 NONE FUNC AVAudioSessionModeDefault
16 0x00000000 NONE FUNC AVAudioSessionModeVoiceChat
17 0x00000000 NONE FUNC AVAudioSessionPortBluetoothA2DP
iE
二进制也可以有自己的符号、函数或数据。这些函数通常显示在
Exports
[0x0007e1fe]> iE[Exports]nth paddr vaddr bind type size lib name
――――――――――――――――――――――――――――――――――――――――――――――――――――
0 0x013ef640 0x013ef640 GLOBAL FUNC 0 _OBJC_EHTYPE_$_NSError
1 0x001c57ea 0x001c57ea GLOBAL FUNC 0 _RCTFBQuickPerformanceLoggerConfigureHooks
2 0x00984f78 0x00984f78 GLOBAL FUNC 0 I0I1(OiIi, OiIi)
3 0x00980300 0x00980300 GLOBAL FUNC 0 I1I0(loO0, loO0)
4 0x00984886 0x00984886 GLOBAL FUNC 0 Ili1(oI1o, oI1o)
5 0x009833c0 0x009833c0 GLOBAL FUNC 0 O0o1(o00l, o00l)
6 0x0097eccc 0x0097eccc GLOBAL FUNC 0 OlO0(loO0, loO0)
7 0x00981e48 0x00981e48 GLOBAL FUNC 0 ilO1(o00l, o00l)
8 0x009854a4 0x009854a4 GLOBAL FUNC 0 l0I1(OiIi, OiIi)
9 0x0098c456 0x0098c456 GLOBAL FUNC 0 OIiOo(OiIi, OiIi)
10 0x00988a68 0x00988a68 GLOBAL FUNC 0 oOOOo(lI1o, lI1o)
11 0x013f0ec8 0x013f0ec8 GLOBAL FUNC 0 guard variable for CTXDataReportBase::GetInstance()::instance
12 0x013ed3e0 0x013ed3e0 GLOBAL FUNC 0 guard variable for folly::usingJEMalloc()::result
13 0x013ed3d8 0x013ed3d8 GLOBAL FUNC 0 guard variable for folly::detail::str_to_floating<double>(folly::Range<char const*>*)::conv
ie
程序入口
[0x100006784]> ie[Entrypoints]
vaddr=0x100006784 paddr=0x00006784 haddr=0x000008c0 type=program
iz
列出数据段里的字符串
[0x10008287c]> iz[Strings]
nth paddr vaddr len size section type string
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
0 0x00e1d7cc 0x100e1d7cc 17 18 3.__TEXT.__objc_methname ascii sharedApplication
1 0x00e1d7de 0x100e1d7de 9 10 3.__TEXT.__objc_methname ascii keyWindow
2 0x00e1d7e8 0x100e1d7e8 8 9 3.__TEXT.__objc_methname ascii subviews
3 0x00e1d7f1 0x100e1d7f1 11 12 3.__TEXT.__objc_methname ascii firstObject
4 0x00e1d7fd 0x100e1d7fd 16 17 3.__TEXT.__objc_methname ascii parentController
5 0x00e1d80e 0x100e1d80e 5 6 3.__TEXT.__objc_methname ascii class
6 0x00e1d814 0x100e1d814 14 15 3.__TEXT.__objc_methname ascii isKindOfClass:
izz
列出整个二进制文件中字符串
[0x0007e1fe]> izz[Strings]
nth paddr vaddr len size section type string
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
0 0x00000028 0x00000028 10 11 ascii __PAGEZERO
1 0x00000070 0x00000070 6 7 ascii __TEXT
qc
执行结果后退出
r2 -qc ii test > ./Desktop/info.txt
s
定位
a
analyze all (fcns + bbs)
aa
analyze all (fcns + bbs)
INFO: Analyze all flags starting with sym. and entry0 (aa)
WARN: Analysis of 0x00d39470 stopped at 0x00d3abd2, use a higher anal.depth to continue
WARN: Analysis of 0x00d39470 stopped at 0x00d3a63c, use a higher anal.depth to continue
INFO: Analyze all functions arguments/locals (afva@@@F)
afl
分析函数列表(Analyze Functions List),执行aa后再执行
[0x0007e1fe]> afl0x0007e1fe 1 92 main
0x00ed36c4 1 12 sym.imp.objc_autoreleasePoolPush
0x00ed3844 1 12 sym.imp.objc_msgSend
0x00ed36b4 1 12 sym.imp.objc_autoreleasePoolPop
0x001c57ea 1 2 sym._RCTFBQuickPerformanceLoggerConfigureHooks
0x009833c0 1 14 sym.O0o1_o00l__o00l_
0x0097eccc 1 24 sym.OlO0_loO0__loO0_
0x00981e48 1 12 sym.ilO1_o00l__o00l_
ax
列出所有方法,执行aa后再执行
[0x0007e1fe]> axsection.0.__TEXT.__text+34 0xb8c2 > CALL:--x > 0xed3844 sym.imp.objc_msgSend
section.0.__TEXT.__text+40 0xb8c8 > CALL:--x > 0xed38e4 sym.imp.objc_retainAutoreleasedReturnValue
fs
所有的信息和特定的名字绑定在一起,比如区段、函数、符号、字符串,这些都被称作 ‘flags’, flags 被整合进 ,一个 flag 是所有类似特征的集合,展示所有的 flag
[0x10008287c]> fs38483 . classes2090 . format93 . functions4354 * imports0 . imports f37 . registers2316 . relocs34 . sections4 . segments
80840 . strings
63511 . symbols
可以使用 ‘fs ’ 加 ‘f’ 来打印出 这个 flags 下面包含的信息,使用分号来间隔多条命令(‘cmd1;cmd2;cmd3;…’)
[0x100006784]> fs imports; f0x1000067fc 0 sym.imp.CC_SHA1
0x100006808 0 sym.imp.NSLog
0x1000068bc 0 sym.imp.strlen
反汇编(Disassembling)
s main 指令定位到main函数入口处
[0x10008287c]> s main[0x10008287c]> pdf;-- entry0:;-- func.10008287c:;-- pc:
┌ 128: int main (int argc, char **argv);
│ ; arg int argc @ x0
│ ; arg char **argv @ x1
│ ; var int64_t var_10h @ sp+0x10
│ ; var int64_t var_20h @ sp+0x20
│ 0x10008287c f657bda9 stp x22, x21, [sp, -0x30]!
│ 0x100082880 f44f01a9 stp x20, x19, [sp, 0x10]
│ 0x100082884 fd7b02a9 stp x29, x30, [sp, 0x20]
│ 0x100082888 fd830091 add x29, var_20h
│ 0x10008288c f30301aa mov x19, x1 ; argv
│ 0x100082890 f40300aa mov x20, x0 ; argc
│ 0x100082894 f0583694 bl sym.imp.objc_autoreleasePoolPush
│ 0x100082898 f50300aa mov x21, x0
│ 0x10008289c 689d00d0 adrp x8, 0x101430000
│ 0x1000828a0 005d44f9 ldr x0, [x8, 0x8b8] ; 0xcf ; 207
│ 0x1000828a4 489c00d0 adrp x8, 0x10140c000
│ 0x1000828a8 01cd41f9 ldr x1, [x8, 0x398] ; 0xcf ; 207
│ 0x1000828ac 23593694 bl sym.imp.objc_msgSend ; void *objc_msgSend(void *instance, char *selector)
│ 0x1000828b0 f3513694 bl sym.imp.NSStringFromClass
│ 0x1000828b4 fd031daa mov x29, x29
│ 0x1000828b8 38593694 bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
│ 0x1000828bc f60300aa mov x22, x0
│ 0x1000828c0 e00314aa mov x0, x20
│ 0x1000828c4 e10313aa mov x1, x19
│ 0x1000828c8 020080d2 movz x2, 0
│ 0x1000828cc e30316aa mov x3, x22
│ 0x1000828d0 9f523694 bl sym.imp.UIApplicationMain
│ 0x1000828d4 f30300aa mov x19, x0
│ 0x1000828d8 e00316aa mov x0, x22
│ 0x1000828dc 20593694 bl sym.imp.objc_release ; void objc_release(void *instance)
│ 0x1000828e0 e00315aa mov x0, x21
│ 0x1000828e4 d9583694 bl sym.imp.objc_autoreleasePoolPop
│ 0x1000828e8 e00313aa mov x0, x19
│ 0x1000828ec fd7b42a9 ldp x29, x30, [var_20h]
│ 0x1000828f0 f44f41a9 ldp x20, x19, [var_10h]
│ 0x1000828f4 f657c3a8 ldp x22, x21, [sp], 0x30
└ 0x1000828f8 c0035fd6 ret
视图模式 & 图形模式(Visual Mode & Graph Mode)
按 V 键将开启视图模式,按 p/P 可以在不同的模式之间切换,在屏幕的顶部是输入的命令
h / j / k / l 分别表示 左 / 下 / 上 / 右 ,输入 g来跳转到你想去的函数地址
按 q 返回到 r2 的 shell操作界面
结合代码使用
/*** ** CSDN:http://blog.csdn.net/yin13753884368/article* Github:https://github.com/taxiao213*/
@Log4j2
public class Radare2Job5 {private Process process;private final String R2_EXIT = "exit";private LinkedBlockingQueue<String> linkedBlockingQueue;StringBuilder stringBuilder;private String path;private final long TIME = 1000 * 60 * 1;private boolean isClose = false;public Radare2Job5(String filePath) {linkedBlockingQueue = new LinkedBlockingQueue<>();stringBuilder = new StringBuilder();path = filePath;}public void startRadare2() {initRadareProcess(path);Thread threadRead = new Thread(this::readCmd);threadRead.setName("readCmdRs");threadRead.start();Thread threadError = new Thread(this::readErrorCmd);threadError.setName("readErrorCmd");threadError.start();Thread threadWrite = new Thread(this::writeCmd);threadWrite.setName("writeCmd");threadWrite.start();Thread threadClose = new Thread(this::closeProcess);threadClose.setName("closeProcess");threadClose.start();Thread threadPut = new Thread(this::putCmd);threadPut.setName("putCmd");threadPut.start();try {process.waitFor();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("main thread stop");}public void inputCmd(String cmd) {try {if (linkedBlockingQueue != null) {linkedBlockingQueue.put(cmd);linkedBlockingQueue.put(R2_EXIT);}} catch (Exception e) {e.printStackTrace();}}public void inputCmd(String... cmd) {try {if (linkedBlockingQueue != null) {for (String st : cmd) {linkedBlockingQueue.put(st);}linkedBlockingQueue.put(R2_EXIT);}} catch (Exception e) {e.printStackTrace();}}public String getRadare2Result() {if (stringBuilder != null) {return stringBuilder.toString();}return "";}public void writeCmd() {BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));try {while (true) {try {String cmdSt = linkedBlockingQueue.take();log.debug("writeCmd cmdSt: {} ", cmdSt);System.out.println("writeCmd: " + cmdSt);bw.write(cmdSt);bw.newLine();bw.flush();if (cmdSt.equals("exit")) {log.debug("writeCmd r2 stop ");System.out.println("r2 stop ");break;}Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();log.error("writeCmd Exception : {} ", e.getMessage());}}} finally {try {bw.close();} catch (IOException e) {e.printStackTrace();log.error("writeCmd BufferedWriter Exception : {} ", e.getMessage());}System.out.println(Thread.currentThread().getName() + "writeCmd stop");log.debug("Thread.name:{} , writeCmd r2 stop ", Thread.currentThread().getName());}}private void readCmd() {InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream(), Charset.forName("GBK"));try {//用缓冲器读行BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String line = null;//结果输出流 直到读完为止System.out.println("start");log.debug("readCmd start ");while ((line = bufferedReader.readLine()) != null) {System.out.println(line);log.debug("print: {} ", line);if (!line.startsWith("[0x") && !line.contains("[0x")) {stringBuilder.append(line);}}System.out.println("end");log.debug("readCmd end ");} catch (Exception e) {e.printStackTrace();log.error("readCmd : {} ", e.getMessage());} finally {try {inputStreamReader.close();} catch (IOException e) {e.printStackTrace();}log.debug("Thread.name:{} , readCmd finally end ", Thread.currentThread().getName());System.out.println("结束");isClose = true;}}private void readErrorCmd() {InputStreamReader inputStreamReader = new InputStreamReader(process.getErrorStream(), Charset.forName("GBK"));try {//用缓冲器读行BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String line = null;//结果输出流 直到读完为止System.out.println("readErrorCmd start");log.debug("readErrorCmd start ");while ((line = bufferedReader.readLine()) != null) {System.out.println(line);log.debug("print: {} ", line);}System.out.println("readErrorCmd end");log.debug("readErrorCmd end ");} catch (Exception e) {e.printStackTrace();log.error("readErrorCmd Exception : {} ", e.getMessage());} finally {try {inputStreamReader.close();} catch (IOException e) {e.printStackTrace();}log.debug("Thread.name:{} , readErrorCmd finally end ", Thread.currentThread().getName());System.out.println("结束");isClose = true;}}public void putCmd() {Scanner scanner = new Scanner(System.in);while (true) {System.out.println("please input your cmd:");String cmd = scanner.next();try {if (linkedBlockingQueue != null) {linkedBlockingQueue.put(cmd);log.debug("putCmd cmdSt: {} ", cmd);}if (cmd.equals("exit")) {System.out.println("now, input cmd stop yet");break;}} catch (Exception e) {e.printStackTrace();}}}/*** 初始化 radare2 进程*/private void initRadareProcess(String filePath) {String cmd = "r2 ";try {log.debug("initRadareProcess filePath: {} ", filePath);process = Runtime.getRuntime().exec(cmd + filePath);} catch (Exception e) {e.printStackTrace();log.error("initRadareProcess Exception : {} ", e.getMessage());}}public void closeProcess() {long startTime = System.currentTimeMillis();while (true) {try {Thread.sleep(1000 * 1);} catch (InterruptedException e) {e.printStackTrace();}if (isClose) {break;}if (System.currentTimeMillis() - startTime > TIME) {break;}}if (process != null) {BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));try {bw.write("exit");bw.newLine();bw.flush();} catch (IOException e) {e.printStackTrace();}try {ProcessHandle processHandle = process.toHandle();if (processHandle != null) {processHandle.destroy();processHandle.descendants().forEach(ProcessHandle::destroy);}} catch (Exception e) {e.printStackTrace();log.error("closeProcess Exception : {} ", e.getMessage());}process.destroy();log.debug("Thread.name:{} , closeProcess ", Thread.currentThread().getName());}}
}
微信公众号(他晓),关注并转发,谢谢
Radare2 框架介绍及使用相关推荐
- python爬虫scrapy框架教程_Python爬虫教程-30-Scrapy 爬虫框架介绍
从本篇开始学习 Scrapy 爬虫框架 Python爬虫教程-30-Scrapy 爬虫框架介绍 框架:框架就是对于相同的相似的部分,代码做到不出错,而我们就可以将注意力放到我们自己的部分了 常见爬虫框 ...
- 2019年上半年收集到的人工智能开源框架介绍文章
2019年上半年收集到的人工智能开源框架介绍文章 TensorFlow基本使用 TensorFlow.js:让你在浏览器中也能玩转机器学习 人工智能学习框架TensorFlow渐近分析 TensorF ...
- ESFramework网络通信框架介绍之(2)――网络通信消息NetMessage
ESFramework网络通信框架与元数据 较之C++而言,.NET是一个更加"动态"的平台,其动态能力建立在反射机制之上,而反射的基础是"元数据". 上文已经 ...
- dommel mysql_.Net Core AA.FrameWork应用框架介绍
开发多年,一直在从社区获取开源的便利,也深感社区力量的重要性,今天开源一个应用基础框架AA.FrameWork,也算是回馈社区,做出一点点贡献,希望能够帮助类似当年入行的我. AA.FrameWork ...
- Foundation框架介绍
Foundation框架介绍 前言 在开发初期,个人发现开发主要涉及到这几个方面:语言语法使用.UIKit.Foundation, 语言是开发基础,UIkit主要负责用户界面设计,其他最常用的就是Fo ...
- 【Django】创建项目及框架介绍,学习笔记(一)
[学习教程] 1.Django基础教程:https://code.ziqiangxuetang.com/django/django-tutorial.html 2.Django博客:http://ww ...
- 流行的9个Java框架介绍: 优点、缺点等等
流行的9个Java框架介绍: 优点.缺点等等 在 2018年,Java仍然是世界上最流行的编程语言.它拥有一个巨大的生态系统,在全世界有超过900万Java开发人员.虽然Java不是最直接的语言,但是 ...
- iOS流媒体直播整个框架介绍(HLS、RTSP)
iOS流媒体直播整个框架介绍(HLS.RTSP) 目录技术文章2016年7月17日 一.HTTP(WebService) 基于HTTP的渐进下载Progressive Download流媒体播放仅是在 ...
- fitnesse - 框架介绍
fitnesse - 框架介绍 2017-09-29 目录: 1 fitnesse是什么? 2 框架介绍 3 与junit.testng比较,fitnesse教其他框架有什么优势 1 fitnesse ...
最新文章
- 20天持续压测,告诉你云存储性能哪家更强?
- [BZOJ 1112] [POI2008] 砖块Klo 【区间K大】
- windows7未能启动怎么修复计算机,win7系统提示windows无法启动这个硬件设备怎么办...
- TensorFlow 教程 --进阶指南--3.8使用GPU
- 解决Tomcat乱码
- UKEY开发,vue+websocket实现用户登录UKEY认证
- 小功能--扫描二维码自动连接WiFi
- 佛系程序员之歌 - 和我一起减减压
- linux系统无线网卡驱动安装,在linux上怎么安装无线网卡驱动?
- 创建签名文件jks 乱码
- 英特尔AVX指令集解析
- 成为一名合格的算法工程师需要掌握哪些技能?
- 学习JAVA.day05
- Unity 在Mac上打包,执行python报Win32Exception的解决方案
- 如何删除本地和远程的 Git 分支
- mongoshake2.2 Oplog Tailer initialize failed
- Java程序GUI与JDBC的应用
- 网吧带宽控制技术发展之三步曲
- Java程序验证五子棋先手必胜_五子棋在无禁手中,理论上是“先手必胜”,实际下棋中如何实现“先手必胜”?...
- mac外置硬盘安装linux,Mac外置硬盘上安装Linux图文教程
热门文章
- mysql对单引号的模糊查询_SQL语句中的单引号处理以及模糊查询
- Win10样式管理与夜间模式
- Win11终端管理员打不开解决方法
- 自然语言处理数据集-20个
- texstudio设置暗黑主题
- html表格标题标签_HTML标题标签
- github用户followers分析
- 工业农业消防自动检测及报警云方案
- Mac Navicat连接MySQL8.0.11出错:2003 - Can't connect to MySQL server on ……(61 Connection refused)
- 静态化freemarker,分布式文件系统minIO