2022CTF培训(七)逆向专项练习

news2024/11/24 6:53:48

附件下载链接

babyre

首先是一个迷宫,由于答案不唯一,因此到 dfs 求出所有路径。

#include <bits/stdc++.h>

constexpr char s[] = "**************.****.**s..*..******.****.***********..***..**..#*..***..***.********************.**..*******..**...*..*.*.**.*";

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int n = std::strlen(s);

    int p = -1;
    for (int i = 0; i < n; i++) {
        if (s[i] == '#') {
            p = i;
            break;
        }
    }

    std::queue<int> q;
    std::vector<int> vis(n);
    std::string ans;
    std::function<void(int)> dfs = [&](int x) {
        if (x == p) {
            std::cout << ans << std::endl;
            return;
        }
        
        for (auto[d, c]:{std::make_pair(-5, 'w'), {5, 's'}, {1, 'd'}, {-1, 'a'}, {25, 'x'}, {-25, 'y'}}) {
            int y = x + d;
            if (y < 0 || y >= n || s[y] == '*' || vis[y]) {
                continue;
            }
            vis[y] = true;
            ans.push_back(c);
            dfs(y);
            ans.pop_back();
            vis[y] = false;
        }
    };
    
    vis[22] = true;
    dfs(22);
    
    return 0;
}

求得路径如下:

saxssd
saxsds
saxdss
saxdsasd
sxss
sxsasd
sxassd
sxasds
ddwwxxssxaxwwwasasasyywwdwwdss
ddwwxxssxaxwwwasasasyywwdwwydxss
ddwwxxssxaxwwwasasasyywwdwds
ddwwxxssxaxwwwasasasyywwdd
ddwwxxssxaxwwaasasyywwdwwdss
ddwwxxssxaxwwaasasyywwdwwydxss
ddwwxxssxaxwwaasasyywwdwds
ddwwxxssxaxwwaasasyywwdd
ddwwxxsdwwdwwdss
ddwwxxsdwwdwwydxss
ddwwxxsdwwdwds
ddwwxxsdwwdd
ddwwxxdwdwwdss
ddwwxxdwdwwydxss
ddwwxxdwdwds
ddwwxxdwdd

第二部分加密函数前半段没用后面每次取 4 次 6 比特转成 3 个 8 比特存在 a2 中,猜测是 base64 。

  while ( v11 > 0 )
  {
    v7 -= v14[*v13] == '@';
    v6 = v14[*v13] & 0x3F | (v6 << 6);
    if ( ++v8 == 4 )
    {
      v8 = 0;
      if ( v7 )
      {
        v2 = v10++;
        a2[v2] = BYTE2(v6);
      }
      if ( v7 > 1 )
      {
        v3 = v10++;
        a2[v3] = BYTE1(v6);
      }
      if ( v7 > 2 )
      {
        v4 = v10++;
        a2[v4] = v6;
      }
    }
    ++v13;
    --v11;
  }

观察 v14 发现是 base64 码表的反向映射,确认是 base64 。因此该部分输入为 c2N0Zl85MTAy
在这里插入图片描述
第三部分求逆,解得答案为 g4lf_si_u_0s!y1g

#include <bits/stdc++.h>
#include <wsdxml.h>

int dword_55B52EE01940[280] = {
        214, 144, 233, 254, 204, 225, 61, 183, 22, 182, 20, 194, 40, 251, 44, 5, 43, 103, 154, 118, 42, 190, 4, 195, 170, 68, 19, 38, 73, 134, 6, 153, 156, 66, 80, 244, 145, 239, 152, 122, 51, 84, 11, 67, 237, 207, 172, 98, 228, 179, 28, 169, 201, 8, 232, 149, 128, 223, 148, 250, 117, 143, 63, 166, 71, 7, 167, 252, 243, 115, 23, 186, 131, 89, 60, 25, 230, 133, 79, 168, 104, 107, 129, 178, 113, 100, 218, 139, 248, 235, 15, 75, 112, 86, 157, 53, 30, 36, 14, 94, 99, 88, 209, 162, 37, 34, 124, 59, 1, 33, 120, 135, 212, 0, 70, 87, 159, 211, 39, 82, 76, 54, 2, 231, 160, 196, 200, 158, 234, 191, 138, 210, 64, 199, 56, 181, 163, 247, 242, 206, 249, 97, 21, 161, 224, 174, 93, 164, 155, 52, 26, 85, 173, 147, 50, 48, 245, 140, 177, 227, 29, 246, 226, 46, 130, 102, 202, 96, 192, 41, 35, 171, 13, 83, 78, 111, 213, 219, 55, 69, 222, 253, 142, 47, 3, 255, 106, 114, 109, 108, 91, 81, 141, 27, 175, 146, 187, 221, 188, 127, 17, 217, 92, 65, 31, 16, 90, 216, 10, 193, 49, 136, 165, 205, 123, 189,
        45, 116, 208, 18, 184, 229, 180, 176, 137, 105, 151, 74, 12, 150, 119, 126, 101, 185, 241, 9, 197, 110, 198, 132, 24, 240, 125, 236, 58, 220, 77, 32, 121, 238, 95, 62, 215, 203, 57, 72, 198, 186, 177, 163, 80, 51, 170, 86, 151, 145, 125, 103, 220, 34, 112, 178, 0, 0, 0, 0, 0, 0, 0, 0
};


unsigned int __ROL4__(unsigned int x, int i) {
    return (x << i) | (x >> (32 - i));
}


unsigned int __ROR4__(unsigned int x, int i) {
    return (x >> i) | (x << (32 - i));
}

unsigned int sub_55B52EE01464(unsigned int a1) {
    int v2; // [rsp+18h] [rbp-498h]
    v2 = (dword_55B52EE01940[BYTE2(a1)] << 16) | dword_55B52EE01940[(unsigned __int8) a1] | (dword_55B52EE01940[BYTE1(a1)] << 8) | (dword_55B52EE01940[(a1 >> 24) & 0xFF] << 24);
    return __ROL4__(v2, 12) ^ (unsigned int) (__ROL4__(v2, 8) ^ __ROR4__(v2, 2)) ^ __ROR4__(v2, 6);
}

unsigned int sub_55B52EE0143B(unsigned int a1, unsigned int a2, unsigned int a3, unsigned int a4) {
    return a1 ^ (unsigned int) sub_55B52EE01464(a2 ^ a3 ^ a4);
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int v9[16];
    v9[0] = 190;
    v9[1] = 4;
    v9[2] = 6;
    v9[3] = 128;
    v9[4] = 197;
    v9[5] = 175;
    v9[6] = 118;
    v9[7] = 71;
    v9[8] = 159;
    v9[9] = 204;
    v9[10] = 64;
    v9[11] = 31;
    v9[12] = 216;
    v9[13] = 191;
    v9[14] = 146;
    v9[15] = 239;
    unsigned int v10[30];
    v10[29] = v9[15] | (v9[14] << 8) | (v9[13] << 16) | (v9[12] << 24);
    v10[28] = v9[11] | (v9[10] << 8) | (v9[9] << 16) | (v9[8] << 24);
    v10[27] = v9[7] | (v9[6] << 8) | (v9[5] << 16) | (v9[4] << 24);
    v10[26] = v9[3] | (v9[2] << 8) | (v9[1] << 16) | (v9[0] << 24);
    for (int i = 25; i >= 0; i--) {
        v10[i] = sub_55B52EE0143B(v10[i + 4], v10[i + 1], v10[i + 2], v10[i + 3]);
    }
    for (int i = 0; i < 4; i++) {
        _byteswap_ulong(v10[i]);
    }
    std::string s(16, 0);
    for (int i = 0, j = 0; i < 16; i += 4, j++) {
        s[i] = v10[j] >> 24 & 0xFF;
        s[i + 1] = v10[j] >> 16 & 0xFF;
        s[i + 2] = v10[j] >> 8 & 0xFF;
        s[i + 3] = v10[j] & 0xFF;
    }
    std::cout << s << std::endl;
    return 0;
}

把所有合法的 flag 交一遍,可得flag为sctf{ddwwxxssxaxwwaasasyywwdd-c2N0Zl85MTAy(fl4g_is_s0_ug1y!)}

Activity

盲猜 FlagActivity 类中的 onClick 方法是打印 flag 的。

public void onClick(View arg3) {
    ((TextView)this.findViewById(0x7F080181)).setText(Integer.toString(FlagActivity.access$004(FlagActivity.this)));  // id:textView2
    if(FlagActivity.this.cnt >= 10000) {
        Toast.makeText(FlagActivity.this, ((EditText)this.findViewById(0x7F080097)).getText().toString(), 0).show();  // id:editTextTextPersonName2
    }
}

将资源导出,搜索 0x7F080097 得资源名称
在这里插入图片描述
再搜索资源名称,text 属性即为 flag 。
在这里插入图片描述

R2c3

通过 ida 调试,将 shellcode 解密

__int64 __fastcall judge(char *a1)
{
  char v2[5]; // [rsp+8h] [rbp-20h] BYREF
  char v3[9]; // [rsp+Dh] [rbp-1Bh] BYREF
  int i; // [rsp+24h] [rbp-4h]

  qmemcpy(v2, "fmcd", 4);
  v2[4] = 127;
  qmemcpy(v3, "k7d;V`;np", sizeof(v3));
  for ( i = 0; i <= 13; ++i )
    a1[i] ^= i;
  for ( i = 0; i <= 13; ++i )
  {
    if ( a1[i] != v2[i] )
      return 0LL;
  }
  return 1LL;
}

解密得 flag 为 flag{n1c3_j0b}

#include <bits/stdc++.h>

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::string s;
    s = std::string("fmcd") + char(127) + "k7d;V`;np";
    for (int i = 0; i <= 13; i++) {
        s[i] ^= i;
    }
    std::cout << s << std::endl;
    return 0;
}

ezre

程序加壳。IDA 在壳代码末尾跳转处下断点然后动态调试运行到该处,此时搜索字符串即可定位到关键函数:

__int64 sub_7FF7B5681C70()
{
  char *v0; // rdi
  __int64 i; // rcx
  char v3[32]; // [rsp+0h] [rbp-20h] BYREF
  __int64 v4; // [rsp+20h] [rbp+0h] BYREF
  char input[228]; // [rsp+30h] [rbp+10h] BYREF
  int v6; // [rsp+114h] [rbp+F4h]
  __int64 v7; // [rsp+1E8h] [rbp+1C8h]

  v0 = v3;
  for ( i = 126i64; i; --i )
  {
    *(_DWORD *)v0 = -858993460;
    v0 += 4;
  }
  sub_7FF7B568108C(&unk_7FF7B5692008);
  printf("<<Input your flag: \n");
  scanf("%200s", input);
  if ( !(unsigned int)CheckLengthAndEnctypt(input) )
  {
    printf("Wrong.\n\n");
    exit(0);
  }
  v6 = AlwaysReturn0(&qword_7FF7B568D0C0[78], v3);
  if ( v6 )
  {
    if ( v6 == 1 )
    {
      printf("Wrong.\n\n");
      exit(0);
    }
    printf("Right!\n\n");
    exit(0);
  }
  EncryptAndCheckContext(input, 20i64);
  sub_7FF7B5681375((__int64)v3, (__int64)&unk_7FF7B568AE80);
  return sub_7FF7B56810E1((unsigned __int64)&v4 ^ v7);
}

首先在 CheckLengthAndEnctypt 函数逻辑如下:

__int64 __fastcall sub_7FF7B56817A0(char *input)
{
  _DWORD *v1; // rdi
  __int64 i; // rcx
  _BYTE v4[36]; // [rsp+0h] [rbp-20h] BYREF
  int v5; // [rsp+24h] [rbp+4h]

  v1 = v4;
  for ( i = 66i64; i; --i )
    *v1++ = -858993460;
  sub_7FF7B568108C(&unk_7FF7B5692008);
  v5 = AlwaysReturn0((__int64)&qword_7FF7B568D0C0[46], (__int64)v4);
  if ( v5 )
    return v5 == 20;
  else
    return sub_7FF7B5681230(input);
}

虽然不清楚 AlwaysReturn0 函数有什么作用,但通过分析汇编可知该函数无论参数如何始终返回 0 ,因此紧接着调用 sub_7FF7B5681230 函数。sub_7FF7B5681230 函数逻辑如下:

__int64 __fastcall sub_7FF7B5681840(char *input)
{
  __int64 *v1; // rdi
  __int64 i; // rcx
  __int64 v4; // [rsp+0h] [rbp-20h] BYREF
  unsigned int j; // [rsp+24h] [rbp+4h]

  v1 = &v4;
  for ( i = 66i64; i; --i )
  {
    *(_DWORD *)v1 = -858993460;
    v1 = (__int64 *)((char *)v1 + 4);
  }
  sub_7FF7B568108C(&unk_7FF7B5692008);
  j = strlen(input);
  if ( j != 20 )
    return CheckDebug(&qword_7FF7B568D0C0[46], j);
  for ( j = 0; (int)j < 36; ++j )
    input[j] ^= 0x66u;
  return CheckDebug(&qword_7FF7B568D0C0[46], 20i64);
}

这里叫做 CheckDebug 函数是因为单步跟进去程序会在执行到某一步时退出。
分析该函数逻辑发现,函数首先判断输入长度是否为 20 字节,根据实际调试发现,只有等于 20 字节的时候才不会在进入 CheckDebug 后直接退出。同时也可以发现输入被逐字节异或了 0x66 。

回到 sub_7FF7B5681C70 函数,如果输入长度正确则在执行完 CheckLengthAndEnctypt 函数后会执行 AlwaysReturn0 函数,因为该函数返回 0,因此接下来执行的是 EncryptAndCheckContext 函数,该函数逻辑如下:

__int64 __fastcall sub_7FF7B56819B0(char *input, int len)
{
  __int64 *v2; // rdi
  __int64 i; // rcx
  __int64 v5; // [rsp+0h] [rbp-20h] BYREF
  unsigned __int64 j; // [rsp+28h] [rbp+8h]

  v2 = &v5;
  for ( i = 66i64; i; --i )
  {
    *(_DWORD *)v2 = -858993460;
    v2 = (__int64 *)((char *)v2 + 4);
  }
  sub_7FF7B568108C(&unk_7FF7B5692008);
  for ( j = 0i64; j < len; ++j )
    check((unsigned int)j, (input[j] + 10) ^ 0x50u);
  return CheckDebug((__int64)&qword_7FF7B568D0C0[78], 2i64);
}

可以看出,该函数对输入逐字节加 10 并异或 0x50 ,然后调用 check 函数对其进行检查,check 函数逻辑如下:

__int64 __fastcall sub_7FF7B5681920(int index, int input_i)
{
  __int64 *v2; // rdi
  __int64 i; // rcx
  __int64 result; // rax
  __int64 v5; // [rsp+0h] [rbp-20h] BYREF

  v2 = &v5;
  for ( i = 58i64; i; --i )
  {
    *(_DWORD *)v2 = -858993460;
    v2 = (__int64 *)((char *)v2 + 4);
  }
  sub_7FF7B568108C(&unk_7FF7B5692008);
  result = index;
  if ( DATA[index] != input_i )
    return CheckDebug((__int64)&qword_7FF7B568D0C0[78], 1i64);
  return result;
}

通过调试可知,只要不满足 DATA[index] != input_i 则程序会立即退出。
根据上述分析可以编写解密程序如下:

#include <bits/stdc++.h>

constexpr unsigned char DATA[20] = {75, 72, 121, 19, 69, 48, 92, 73, 90, 121, 19, 112, 109, 120, 19, 111, 72, 93, 100, 100};

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::string flag(20, 0);
    for (int i = 0; i < 20; i++) {
        flag[i] = ((DATA[i] ^ 0x50) - 10) ^ 0x66;
    }
    std::cout << flag << std::endl;
    return 0;
}

运行得 flag:why_m0dify_pUx_SheLL

oldRE

程序加壳,调试得关键函数如下:

int sub_401000()
{
  void (__cdecl *printf)(char *); // esi
  int v2; // eax
  char input[52]; // [esp+4h] [ebp-38h] BYREF

  memset(input, 0, 50);
  printf = (void (__cdecl *)(char *))::printf;
  ::printf(aPleaseInputFla);
  gets_s(input, 44);
  if ( strlen(input) == 42 )
  {
    v2 = 0;
    while ( (input[v2] ^ KEY[v2 % 16]) == DATA[v2] )
    {
      if ( ++v2 >= 42 )
      {
        printf(aRight);
        return 0;
      }
    }
    printf(aError);
    return 0;
  }
  else
  {
    printf(aError);
    return -1;
  }
}

写出对应的解密程序可得 flag 为 flag{59b8ed8f-af22-11e7-bb4a-3cf862d1ee75}

#include <bits/stdc++.h>

constexpr unsigned int DATA[42] = {18, 4, 8, 20, 36, 92, 74, 61, 86, 10, 16, 103, 0, 65, 0, 1, 70, 90, 68, 66, 110, 12, 68, 114, 12, 13, 64, 62, 75, 95, 2, 1, 76, 94, 91, 23, 110, 12, 22, 104, 91, 18};
constexpr unsigned char KEY[16] = {0x74, 0x68, 0x69, 0x73, 0x5F, 0x69, 0x73, 0x5F, 0x6E, 0x6F, 0x74, 0x5F, 0x66, 0x6C, 0x61, 0x67};

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::string flag(42, 0);
    for (int i = 0; i < 42; i++) {
        flag[i] = DATA[i] ^ KEY[i % 16];
    }
    std::cout << flag << std::endl;
    return 0;
}

codeRE

0x080487BF 地址有一处花指令:
在这里插入图片描述
0x080487F3 地址有一处花指令:
在这里插入图片描述
0x08048812 地址有一处花指令,不过不能简单的把跳过的字节修改成 nop ,因为后面会用到这里的数据。
在这里插入图片描述
0x08048851 地址有一处花指令。
在这里插入图片描述
花指令跳转之后会变成一个死循环
在这里插入图片描述
通过在 OD 中模拟这部分花指令也可以确定,这部分花指令确实是一个死循环。
在这里插入图片描述
最终还原出的关键函数逻辑如下:

unsigned int sub_80487C4()
{
  size_t len; // eax
  size_t v1; // eax
  unsigned __int8 *md5; // [esp+14h] [ebp-74h]
  char s[20]; // [esp+18h] [ebp-70h] BYREF
  unsigned int v5; // [esp+7Ch] [ebp-Ch]

  v5 = __readgsdword(0x14u);
  memset(s, 0, sizeof(s));
  read(0, s, 0x14u);
  if ( !strncmp(s, "F1@gA", 5u) )
  {
    puts("You are very close! Now patch me~");
    if ( true )
    {
      while ( 1 )
        ;
    }
    len = strlen(s);
    md5 = MD5(&s[1], len, 0);
    dump(md5, 0x10u);
  }
  else
  {
    v1 = strlen(s);
    dump((unsigned __int8 *)s, v1 - 1);
  }
  fflush(stdout);
  return __readgsdword(0x14u) ^ v5;
}

根据程序中的提示(玄学)应当将死循环 patch 掉然后输入 F1@gA 即可输出 flag 内容。
运行时可能会缺少 libcrypto.so.1.0.0 。由于是 32 位程序,因此该库的路径应为 /usr/lib/i386-linux-gnu/libcrypto.so.1.0.0 。如果没有则考虑安装该库:

sudo apt install libssl1.0.0:i386

或者 ldd 查看该文件依赖的库路径是否正确,如果不正确则使用 patchelf 更改依赖库的路径。
运行结果如下:
在这里插入图片描述

babyAndroid

关键函数为 CheckString

public void onClick(View v) {
    if(cyberpeace.CheckString(((EditText)MainActivity.this.findViewById(0x7F070031)).getText().toString()) == 1) {  // id:editText
        Toast.makeText(MainActivity.this, "验证通过!", 1).show();
        return;
    }

    Toast.makeText(MainActivity.this, "验证失败!", 1).show();
}

该函数位于 libcyberpeace.so 中,内容如下:

_BOOL4 __cdecl Java_com_testjava_jack_pingan2_cyberpeace_CheckString(int a1, int a2, int a3)
{
  size_t len; // edi
  char *input; // esi
  size_t cur; // edi
  char v6; // al
  char v7; // al
  size_t v8; // edi
  char v9; // al
  const char *v11; // [esp+18h] [ebp-14h]

  v11 = (const char *)(*(int (__cdecl **)(int, int, _DWORD))(*(_DWORD *)a1 + 676))(a1, a3, 0);
  len = strlen(v11);
  input = (char *)malloc(len + 1);
  memset(&input[len], 0, len != -1);
  memcpy(input, v11, len);
  if ( strlen(input) >= 2 )
  {
    cur = 0;
    do
    {
      v6 = input[cur];
      input[cur] = input[cur + 16];
      input[cur++ + 16] = v6;
    }
    while ( cur < strlen(input) >> 1 );
  }
  v7 = *input;
  if ( *input )
  {
    *input = input[1];
    input[1] = v7;
    if ( strlen(input) >= 3 )
    {
      v8 = 2;
      do
      {
        v9 = input[v8];
        input[v8] = input[v8 + 1];
        input[v8 + 1] = v9;
        v8 += 2;
      }
      while ( v8 < strlen(input) );
    }
  }
  return strcmp(input, "f72c5a36569418a20907b55be5bf95ad") == 0;
}

写出对应的解密函数:

#include <bits/stdc++.h>

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::string s = "f72c5a36569418a20907b55be5bf95ad";
    for (int i = 0; i < s.size(); i += 2) {
        std::swap(s[i], s[i + 1]);
    }
    for (int i = 0; i < s.size() / 2; i++) {
        std::swap(s[i], s[i + 16]);
    }
    std::cout << s << std::endl;
    return 0;
}

ezAndroid

类 b 中的 a 方法这两句反编译反了,原本应该是模拟类似循环移位的操作。
在这里插入图片描述
根据代码逻辑分析可知,每个字节的生成都仅与输入的前缀有关,且输入前缀越长生成的序列也越长。
因此可以把反编译后的代码复制下来,然后逐字节爆破。部分代码如下,具体见附件。


public class MainActivity {
    private static char a(String f, b tb, a ta) {
        return ta.a(tb.a(f));
    }

    static int a(String arg1) {
        return MainActivity.b(arg1);
    }

    private static int b(String arg8) {
        arg8 = "flag{" + arg8 + "}";
        int v0 = 0;
        String flag = arg8.substring(5, arg8.length() - 1);
        b tb = new b(2);
        a ta = new a(3);
        StringBuilder v3 = new StringBuilder();
        int v1 = 0;
        while (v0 < flag.length()) {
            v3.append(MainActivity.a(flag.charAt(v0) + "", tb, ta));
            if (tb.b() / 25 > v1 && tb.b() / 25 >= 1) {
                ++v1;
            }
            ++v0;
        }
        String ss = v3.toString();
        String tt = "wigwrkaugala";
        for (int i = 0; i < Math.min(ss.length(), tt.length()); i++) {
            if (ss.charAt(i) != tt.charAt(i)) {
                return i;
            }
        }
        return Math.min(ss.length(), tt.length());
    }

//    static String charSet = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";

    static String charSet="abcdefghijklmnopqrstuvwxyz";

    private static void dfs(String s, int l) {
        if (l == 12) {
            System.out.println("flag{" + s + "}");
        }
        for (int i = 0; i < charSet.length(); i++) {
            String t = s + charSet.charAt(i);
            int nl = a(t);
            if (nl > l) {
                dfs(t, nl);
            }
        }
    }

    public static void main(String[] args) {
        dfs("", 0);
    }
}

如果仅枚举小写字母则合法的 flag 如下:

flag{veniviaivici}
flag{veniviaivicr}
flag{veniviaivkci}
flag{veniviaivkcr}
flag{venividivici}
flag{venividivicr}
flag{venividivkci}
flag{venividivkcr}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springMVC01,springMVC的执行流程【第一个springMVC例子(XML配置版本):HelloWorld】

springMVC01,springMVC的执行流程【第一个springMVC项目&#xff1a;HelloWorld】springMVC的简介springMVC的执行流程第一个springMVC项目&#xff08;XML配置版本&#xff09;1.创建项目1.1 新建maven项目&#xff1a;1.2 添加web支持1.3 在pom.xml中导入依赖1.4 配置tomcat2…

【云享·人物】华为云AI高级专家白小龙:AI如何释放应用生产力,向AI工程化前行?

摘要&#xff1a;AI技术发展&#xff0c;正由应用落地阶段向效率化生产阶段演进&#xff0c;AI工程化能力将会不断深入业务&#xff0c;释放企业生产力。本文分享自华为云社区《【云享人物】华为云AI高级专家白小龙&#xff1a;AI如何释放应用生产力&#xff0c;向AI工程化前行…

[附源码]Python计算机毕业设计Django飞越青少儿兴趣培训机构管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

旅游景区地图导览系统,传统导览智慧新升级

地图在景区导览中一直扮演着重要角色。 从传统导览的纸质地图&#xff0c;再到智慧导览的电子地图&#xff0c;游客都可以从景区地图上了解到景点名称、游玩路线、服务设施等内容&#xff0c;帮助游客更好地游览景区。 相比传统的纸质地图导览&#xff0c;电子地图导览系统有哪…

计算机组成原理习题课第四章-4(唐朔飞)

计算机组成原理习题课第四章-4&#xff08;唐朔飞&#xff09; ✨欢迎关注&#x1f5b1;点赞&#x1f380;收藏⭐留言✒ &#x1f52e;本文由京与旧铺原创&#xff0c;csdn首发&#xff01; &#x1f618;系列专栏&#xff1a;java学习 &#x1f4bb;首发时间&#xff1a;&…

TIA博途中通用函数库指令FIFO先入先出的具体使用方法

TIA博途中通用函数库指令FIFO先入先出的具体使用方法 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 如下图所示,在TIA博途中添加通用函数库指令,然后在库指令中找到FIFO,鼠标直接拖拽到程序段中,系统会自动生成一…

【毕业设计】10-基于单片机的车站安检门_磁性霍尔传感器系统设计(原理图+源码+仿真工程+答辩论文)

【毕业设计】10-基于单片机的车站安检门/磁性霍尔传感器系统设计&#xff08;原理图源码仿真工程答辩论文&#xff09; 文章目录【毕业设计】10-基于单片机的车站安检门/磁性霍尔传感器系统设计&#xff08;原理图源码仿真工程答辩论文&#xff09;任务书设计说明书摘要设计框架…

https加密解密过程二、名词解析及文件生成

https加密解密过程二、名词解析及文件生成 密钥仓库keystore文件 Keytool是一个Java数据证书的管理工具 &#xff0c;Keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中 keystore文件的内容其实就是把私钥、公钥以及公钥对应的地址等信息输出为json格式的…

git的基础操作

git的基础操作 一、Git理论 &#xff08;一&#xff09;工作区域 基本概念&#xff1a; 工作区&#xff1a;平时存放项目代码的地方。 暂存区(Stage/Index)&#xff1a;暂存区&#xff0c;用于临时存放你的改动&#xff0c;事实上它只是一个文件&#xff0c;保存即将提交到…

(四)DepthAI-python相关接口:OAK Messages

消息快播&#xff1a;OpenCV众筹了一款ROS2机器人rae&#xff0c;开源、功能强、上手简单。来瞅瞅~ 编辑&#xff1a;OAK中国 首发&#xff1a;oakchina.cn 喜欢的话&#xff0c;请多多&#x1f44d;⭐️✍ 内容可能会不定期更新&#xff0c;官网内容都是最新的&#xff0c;请查…

mapstruct常见错误及解决方案

1 问题集合 mapstruct-jdk8 编译报错 我以前项目使用的是mapstruct-jdk8<1.3.1.Final &#xff0c;现在做改造升级&#xff0c;比如springboot升级等&#xff0c;但是报错了 我们去mvn仓库去看下&#xff1a; Deprecated MapStruct artifact containing annotations to …

Postman之CSV或JOSN文件实现数据驱动

目录 一、适用场景 二、接口信息 三、数据驱动实现 3.1.data.文件设置 3.1.1.data.csv文件设置 3.1.2.data.json文件设置 3.3.接口传参设置 3.4.断言设置 四、执行结果 4.1.data.csv执行脚本上传设置 4.2.data.json执行脚本上传设置​ 4.3.执行结果展示 一、适用场…

12 【操作mongodb数据库】

12 【操作mongodb数据库】 1.简介 1.Mongoose是一个让我们可以通过Node来操作MongoDB的模块。2.Mongoose是一个对象文档模型(ODM)库,它对Node原生的MongoDB模块进行了进一步的优化封装&#xff0c;并提供了更多的功能。在大多数情况下&#xff0c;它被用来把结构化的模式应用…

Stable Diffusion 关键词tag语法教程

Stable Diffusion 关键词tag语法教程 AI绘图在线体验 二次元绘图 在线体验地址:Stable Diffusion 模型包括&#xff1a; NovelAI&#xff0c;NovelAI的模型训练使用了数千个网站的数十亿张图片&#xff0c;包括 Pixiv、Twitter、DeviantArt、Tumblr等网站的作品。 Waifu&am…

Flink系列之大数据分布式计算引擎设计实现剖析

声明&#xff1a; 文章中代码及相关语句为自己根据相应理解编写&#xff0c;文章中出现的相关图片为自己实践中的截图和相关技术对应的图片&#xff0c;若有相关异议&#xff0c;请联系删除。感谢。转载请注明出处&#xff0c;感谢。 By luoyepiaoxue2014 B站&#xff…

MySQL基本语句操作

目录 一. MySQKL基本操作命令&#xff08;增&#xff0c;删&#xff0c;该&#xff0c;查&#xff09; 1.1 基本概述 1.2 查看当前服务器种的数据库 1.3 查看数据库结构​编辑 二.SQL语句 三. 创建及删除数据库和表 3.1 创建新的数据库 3.2 创建新的表 ​3.3 删除指…

c++随机数问题研究

1、问题背景 某项目中有个复杂的排序&#xff0c;先是各种规则依次排序&#xff0c;最后如果依然并列的话&#xff0c;那就随机位置&#xff0c;名次并列。测试中发现一个诡异现象&#xff0c;并列时随机排序但随机后2个case打印的顺序每次都一样&#xff0c;随机数没有起到任…

基于PHP+MySQL个人信息管理系统的设计与实现

随着现代工作的日趋繁忙,人们越来越意识到信息管理的重要性与必要性,而具有个性化特色的个人信息管理系统能够高速有效的管理个人信息,从而提升自己的工作效率。该系统的基本功能包括用户登录,个人信息管理,通信名录管理,日程备忘管理,财物管理,随手笔记管理,修改密码等功能。 …

html+css+javascript+jquery+bootstarp响应式旅行社旅游平台网站模板(14页)

&#x1f468;‍&#x1f393;学生HTML静态网页基础水平制作&#x1f469;‍&#x1f393;&#xff0c;页面排版干净简洁。使用HTMLCSS页面布局设计,web大学生网页设计作业源码&#xff0c;这是一个不错的旅游网页制作&#xff0c;画面精明&#xff0c;排版整洁&#xff0c;内容…

[附源码]Python计算机毕业设计SSM考试排考系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…