MFC逆向之CrackMe Level3 过反调试 + 写注册机

今天我来分享一下,过反调试的方法以及使用IDA还原代码 + 写注册机的过程

由于内容太多,我准备分为两个帖子写,这个帖子主要是写IDA还原代码,下一个帖子是写反调试的分析以及过反调试和异常

这个CrackMe Level3是一个朋友发我的,我也不知道他在哪里弄的,我感觉挺好玩的,对反调试 异常 以及代码还原的学习有一些帮助

调试器:X64和OD

反编译工具:IDA

PE工具:Detect It Easy

反调试插件:OD的StrongOD和虫子的ScyllaHide

ARK工具:Pchunter

MFC工具:MfcSpy

初步分析

第一步先看看PE文件 工具说:软件是使用2008的MFC写的

上面得知是MFC写的软件,我们可以利用MFC的RTTI(动态类型识别)获取信息,如果不是MFC写的,我们可以运行一下软件看看,有没有报错信息

当然这个软件,输入注册码点击注册没有任何提示

 

打开调试器附加看看字符串,结果软件会闪退,无法附加,估计是有反调试,遇到这种情况我有三种方式可以解决

第一种:静态分析解决反调试

第二种:使用ARK工具把软件暂停,然后在用调试器附加

第三种:直接使用调试器打开程序,让软件断到入口或者系统断点

我们先使用第二种吧,因为X32调试器对中文字符串的支持不是很好,我没有装插件,所以先用OD看看字符串吧

验证函数中有一个异常 OD的反汇编已经出现了BUG,可以使用删除分析,我这里就不删除了 直接打开IDA F5吧 

 

虽然不能F5 但是我们可以很清晰的看到,两个GetWindowText 估计一个是获取用户名 一个是获取密码

至于为什么不能F5 是因为有一个jmp [ebx + 0xXXX] 这样的代码 IDA在解析代码的时候 它不知道跳到那里去 导致无法解析

我们直接把这个Jmp [ebp + var_8A8] 给nop掉就好了 然后删除这个函数的分析 接着在把这个函数分析为代码即可

我们可以向上看,在OD反汇编的时候也是到这个位置 反汇编失败了

下面是IDA F5后的代码 很明显 这IDA还原出来的根本不能用,这是需要我们进行修理变量的,另外我们给它重新命名一下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

int __thiscall sub_401810(CWnd *this)

{

  CWnd *DlgItem; // eax

  CWnd *v2; // eax

  int result; // eax

  char *v4; // [esp+10h] [ebp-8C8h]

  CHAR *v5; // [esp+14h] [ebp-8C4h]

  unsigned int v6; // [esp+18h] [ebp-8C0h]

  unsigned __int8 v8; // [esp+21h] [ebp-8B7h]

  unsigned __int8 v9; // [esp+22h] [ebp-8B6h]

  unsigned __int8 v10; // [esp+23h] [ebp-8B5h]

  int k; // [esp+24h] [ebp-8B4h]

  int j; // [esp+28h] [ebp-8B0h]

  int i; // [esp+2Ch] [ebp-8ACh]

  int v14; // [esp+34h] [ebp-8A4h]

  int v15; // [esp+34h] [ebp-8A4h]

  char v16; // [esp+38h] [ebp-8A0h] BYREF

  int v17[6]; // [esp+39h] [ebp-89Fh] BYREF

  char v18; // [esp+51h] [ebp-887h]

  char v19; // [esp+53h] [ebp-885h]

  char v20; // [esp+54h] [ebp-884h]

  int v21; // [esp+55h] [ebp-883h]

  int v22[5]; // [esp+59h] [ebp-87Fh] BYREF

  char v23; // [esp+6Dh] [ebp-86Bh]

  int v24; // [esp+70h] [ebp-868h]

  char v25; // [esp+74h] [ebp-864h]

  int v26; // [esp+75h] [ebp-863h]

  int v27; // [esp+79h] [ebp-85Fh]

  int v28; // [esp+7Dh] [ebp-85Bh]

  int v29; // [esp+81h] [ebp-857h]

  int v30; // [esp+85h] [ebp-853h]

  int v31; // [esp+89h] [ebp-84Fh]

  char v32; // [esp+8Dh] [ebp-84Bh]

  char v33; // [esp+93h] [ebp-845h]

  char v34; // [esp+94h] [ebp-844h]

  int v35; // [esp+95h] [ebp-843h]

  int v36[5]; // [esp+99h] [ebp-83Fh] BYREF

  char v37; // [esp+ADh] [ebp-82Bh]

  CHAR String[1028]; // [esp+B0h] [ebp-828h] BYREF

  int v39; // [esp+4B4h] [ebp-424h]

  CHAR v40[1028]; // [esp+4B8h] [ebp-420h] BYREF

  CPPEH_RECORD ms_exc; // [esp+8C0h] [ebp-18h]

  MEMORY[0] = 6530;

  ms_exc.registration.TryLevel = -2;

  v33 = sub_402D60();

  v14 = sub_402C60(v33);

  sub_402750(v14);

  v26 = 0;

  v27 = 0;

  v28 = 0;

  v29 = 0;

  v30 = 0;

  v31 = 0;

  v32 = 0;

  v35 = 0;

  memset(v36, 0, sizeof(v36));

  v37 = 0;

  v21 = 0;

  memset(v22, 0, sizeof(v22));

  v23 = 0;

  v25 = 48;

  v34 = 66;

  v20 = 98;

  for ( i = 1; i < 26; ++i )

  {

    *(&v25 + i) = *((_BYTE *)&v24 + i + 3) + 1;

    *(&v34 + i) = *(&v33 + i) + 1;

    *(&v20 + i) = *(&v19 + i) + 1;

  }

  CWnd::UpdateData(this, 1);

  memset(String, 0, 1024);

  memset(v40, 0, 1024);

  ms_exc.registration.Next = (struct _EH3_EXCEPTION_REGISTRATION *)1024;

  ms_exc.exc_ptr = (EXCEPTION_POINTERS *)String;

  DlgItem = CWnd::GetDlgItem(this, 1000);

  CWnd::GetWindowTextA(DlgItem, (LPSTR)ms_exc.exc_ptr, (int)ms_exc.registration.Next);

  ms_exc.registration.Next = (struct _EH3_EXCEPTION_REGISTRATION *)1024;

  ms_exc.exc_ptr = (EXCEPTION_POINTERS *)v40;

  v2 = CWnd::GetDlgItem(this, 1001);

  result = CWnd::GetWindowTextA(v2, (LPSTR)ms_exc.exc_ptr, (int)ms_exc.registration.Next);

  if ( String[7] )

  {

    result = String[8];

    if ( !String[8] && v40[23] && !v40[24] )

    {

      v39 = 16;

      v24 = 32;

      for ( j = 0; j < 8; ++j )

      {

        String[j] ^= j;

        String[j] ^= *(_BYTE *)(j + v39);

        String[j] ^= *(_BYTE *)(j + v24);

      }

      v16 = 0;

      memset(v17, 0, sizeof(v17));

      v18 = 0;

      for ( k = 0; k < 8; ++k )

      {

        v10 = (unsigned __int8)(String[k] & 0xE0) / 32;

        v8 = (String[k] & 0x1C) / 4;

        v9 = String[k] & 3;

        if ( k % 3 == 2 )

        {

          *(&v16 + 3 * k) = *(&v25 + v9);

          *((_BYTE *)v17 + 3 * k) = *((_BYTE *)v36 + v10 + 3);

          *((_BYTE *)v17 + 3 * k + 1) = *((_BYTE *)&v22[2] + v8 + 3);

        }

        if ( k % 3 == 1 )

        {

          *(&v16 + 3 * k) = *((_BYTE *)&v36[2] + v10 + 3);

          *((_BYTE *)v17 + 3 * k) = *((_BYTE *)v22 + v8 + 3);

          *((_BYTE *)v17 + 3 * k + 1) = *(&v25 + v9);

        }

        if ( !(k % 3) )

        {

          *(&v16 + 3 * k) = *((_BYTE *)&v36[2] + v8 + 3);

          *((_BYTE *)v17 + 3 * k) = *((_BYTE *)v22 + v9 + 3);

          *((_BYTE *)v17 + 3 * k + 1) = *(&v25 + v10);

        }

      }

      sub_401790();

      v33 = sub_402D90();

      v15 = sub_402C60(v33);

      sub_4028A0(v15);

      v6 = 24;

      v5 = v40;

      v4 = &v16;

      while ( v6 >= 4 )

      {

        result = (int)v5;

        if ( *(_DWORD *)v4 != *(_DWORD *)v5 )

          return result;

        v6 -= 4;

        v5 += 4;

        v4 += 4;

      }

      return CWnd::MessageBoxA(this, &Text, 0, 0);

    }

  }

  return result;

}

1.根据循环可以知道对应数组大小和数组首地址

2.根据MemSet也可以知道对应数组的大小和数组首地址

3.根据GetWindowsText也可以知道数组的大小

修正变量要结合代码怎么去操作这个变量的 根据它的逻辑来猜测大小

这是变量重命名后的汇编代码

经过修理后的IDA F5代码 可以看到基本上很清晰了 效果跟源代码应该很接近

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

int __thiscall sub_401810(CWnd *this)

{

  CWnd *DlgItem; // eax

  CWnd *v2; // eax

  int result; // eax

  char *pFinalKey_1; // [esp+10h] [ebp-8C8h]

  char *pGetWindowTextString1_1; // [esp+14h] [ebp-8C4h]

  unsigned int Var24_1; // [esp+18h] [ebp-8C0h]

  unsigned __int8 Var8_1; // [esp+21h] [ebp-8B7h]

  unsigned __int8 Var9_1; // [esp+22h] [ebp-8B6h]

  unsigned __int8 Var10_1; // [esp+23h] [ebp-8B5h]

  int K; // [esp+24h] [ebp-8B4h]

  int J; // [esp+28h] [ebp-8B0h]

  int I; // [esp+2Ch] [ebp-8ACh]

  int Unknown2_1; // [esp+34h] [ebp-8A4h]

  int unknown1; // [esp+34h] [ebp-8A4h]

  char FinalKey_1[26]; // [esp+38h] [ebp-8A0h] BYREF

  char SecretKey3[28]; // [esp+54h] [ebp-884h] BYREF

  int v19; // [esp+70h] [ebp-868h]

  char SecretKey1[31]; // [esp+74h] [ebp-864h] BYREF

  char Unknown3_1; // [esp+93h] [ebp-845h]

  char SecretKey2[28]; // [esp+94h] [ebp-844h] BYREF

  char GetWindowTextString2_1[1028]; // [esp+B0h] [ebp-828h] BYREF

  int v24; // [esp+4B4h] [ebp-424h]

  char GetWindowTextString1[1028]; // [esp+4B8h] [ebp-420h] BYREF

  CPPEH_RECORD ms_exc; // [esp+8C0h] [ebp-18h]

  MEMORY[0] = 6530;

  ms_exc.registration.TryLevel = -2;

  Unknown3_1 = sub_402D60();

  Unknown2_1 = sub_402C60(&dword_42FA04, Unknown3_1);

  sub_402750(Unknown2_1);

  memset(&SecretKey1[1], 0, 25);

  memset(&SecretKey2[1], 0, 25);

  memset(&SecretKey3[1], 0, 25);

  SecretKey1[0] = 48;

  SecretKey2[0] = 66;

  SecretKey3[0] = 98;

  for ( I = 1; I < 26; ++I )

  {

    SecretKey1[I] = SecretKey1[I - 1] + 1;

    SecretKey2[I] = SecretKey2[I - 1] + 1;

    SecretKey3[I] = SecretKey3[I - 1] + 1;

  }

  CWnd::UpdateData(this, 1);

  memset(GetWindowTextString2_1, 0, 1024);

  memset(GetWindowTextString1, 0, 1024);

  ms_exc.registration.Next = (struct _EH3_EXCEPTION_REGISTRATION *)1024;

  ms_exc.exc_ptr = (EXCEPTION_POINTERS *)GetWindowTextString2_1;

  DlgItem = CWnd::GetDlgItem(this, 1000);

  CWnd::GetWindowTextA(DlgItem, (LPSTR)ms_exc.exc_ptr, (int)ms_exc.registration.Next);

  ms_exc.registration.Next = (struct _EH3_EXCEPTION_REGISTRATION *)1024;

  ms_exc.exc_ptr = (EXCEPTION_POINTERS *)GetWindowTextString1;

  v2 = CWnd::GetDlgItem(this, 1001);

  result = CWnd::GetWindowTextA(v2, (LPSTR)ms_exc.exc_ptr, (int)ms_exc.registration.Next);

  if ( GetWindowTextString2_1[7] )

  {

    result = GetWindowTextString2_1[8];

    if ( !GetWindowTextString2_1[8] && GetWindowTextString1[23] && !GetWindowTextString1[24] )

    {

      v24 = 16;

      v19 = 32;

      for ( J = 0; J < 8; ++J )

      {

        GetWindowTextString2_1[J] ^= J;

        GetWindowTextString2_1[J] ^= *(_BYTE *)(J + v24);

        GetWindowTextString2_1[J] ^= *(_BYTE *)(J + v19);

      }

      memset(FinalKey_1, 0, sizeof(FinalKey_1));

      for ( K = 0; K < 8; ++K )

      {

        Var10_1 = (unsigned __int8)(GetWindowTextString2_1[K] & 0xE0) / 32;

        Var8_1 = (GetWindowTextString2_1[K] & 0x1C) / 4;

        Var9_1 = GetWindowTextString2_1[K] & 3;

        if ( K % 3 == 2 )

        {

          FinalKey_1[3 * K] = SecretKey1[Var9_1];

          FinalKey_1[3 * K + 1] = SecretKey2[Var10_1 + 8];

          FinalKey_1[3 * K + 2] = SecretKey3[Var8_1 + 16];

        }

        if ( K % 3 == 1 )

        {

          FinalKey_1[3 * K] = SecretKey2[Var10_1 + 16];

          FinalKey_1[3 * K + 1] = SecretKey3[Var8_1 + 8];

          FinalKey_1[3 * K + 2] = SecretKey1[Var9_1];

        }

        if ( !(K % 3) )

        {

          FinalKey_1[3 * K] = SecretKey2[Var8_1 + 16];

          FinalKey_1[3 * K + 1] = SecretKey3[Var9_1 + 8];

          FinalKey_1[3 * K + 2] = SecretKey1[Var10_1];

        }

      }

      sub_401790();

      Unknown3_1 = sub_402D90();

      unknown1 = sub_402C60(&dword_42FA04, Unknown3_1);

      sub_4028A0(unknown1);

      Var24_1 = 24;

      pGetWindowTextString1_1 = GetWindowTextString1;

      pFinalKey_1 = FinalKey_1;

      while ( Var24_1 >= 4 )

      {

        result = (int)pGetWindowTextString1_1;

        if ( *(_DWORD *)pFinalKey_1 != *(_DWORD *)pGetWindowTextString1_1 )

          return result;

        Var24_1 -= 4;

        pGetWindowTextString1_1 += 4;

        pFinalKey_1 += 4;

      }

      return CWnd::MessageBoxA(this, &Text, 0, 0);

    }

  }

  return result;

}

我们可以看到上面的代码中还是有两个变量的值是错误的 一个是V24 一个是V19 为什么是错误的呢?

我们可以结合下面的循环代码,下面代码中用到V24 是*(BYTE*)(J+V24);    用到V19 是*(BYTE*)(J+V19);

这很明显是一个数组 大小是8个字节

看下面代码中 V19和V24是来源于AbnormalVariable这个变量的值 + 16和+32的位置的

这也就是下面代码中V19和V24数组的值的来源

最终的C代码 算法还原完成

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

int main()

{

    char SecretKey1[28];

    char SecretKey2[28];

    char SecretKey3[28];

    memset(SecretKey1,0,sizeof(SecretKey1));

    memset(SecretKey2,0,sizeof(SecretKey2));

    memset(SecretKey3,0,sizeof(SecretKey3));

    SecretKey1[0] = 48;

    SecretKey2[0] = 66;

    SecretKey3[0] = 98;

    for (int I = 1; I < 26; ++I)

    {

        SecretKey1[I] = SecretKey1[I - 1] + 1;

        SecretKey2[I] = SecretKey2[I - 1] + 1;

        SecretKey3[I] = SecretKey3[I - 1] + 1;

    }

    char GetWindowTextString1[1024];

    char GetWindowTextString2_1[1024];

    memset(GetWindowTextString1,0,1024);

    memset(GetWindowTextString2_1, 0, 1024);

    strcpy(GetWindowTextString2_1,"12345678");

    char v24[24] = { 0x00,0x00,0x88,0x85,0xBB,0xF7,0xFF,0xFF,0x0F,0xB6,0x8D,0xBB,0xF7,0xFF,0xFF,0xB8,0x04,0xFA,0x42,0x00,0xE8,0xAD };

    char v19[24] = { 0xB8,0x04,0xFA,0x42,0x00,0xE8,0xAD,0x13,0x00,0x00,0x89,0x85,0x5C,0xF7,0xFF,0xFF,0x8B,0x95,0x5C,0xF7,0xFF,0xFF };

    for (int J = 0; J < 8; ++J)

    {

        GetWindowTextString2_1[J] ^= J;

        GetWindowTextString2_1[J] ^= v24[J];

        GetWindowTextString2_1[J] ^= v19[J];

    }

    char FinalKey_1[26];

    memset(FinalKey_1,0,sizeof(FinalKey_1));

    for (int K = 0; K < 8; ++K)

    {

        char Var10_1 = (unsigned __int8)(GetWindowTextString2_1[K] & 0xE0) / 32;

        char Var8_1 = (GetWindowTextString2_1[K] & 0x1C) / 4;

        char Var9_1 = GetWindowTextString2_1[K] & 3;

        if (K % 3 == 2)

        {

            FinalKey_1[3 * K] = SecretKey1[Var9_1];

            FinalKey_1[3 * K + 1] = SecretKey2[Var10_1 + 8];

            FinalKey_1[3 * K + 2] = SecretKey3[Var8_1 + 16];

        }

        if (K % 3 == 1)

        {

            FinalKey_1[3 * K] = SecretKey2[Var10_1 + 16];

            FinalKey_1[3 * K + 1] = SecretKey3[Var8_1 + 8];

            FinalKey_1[3 * K + 2] = SecretKey1[Var9_1];

        }

        if (!(K % 3))

        {

            FinalKey_1[3 * K] = SecretKey2[Var8_1 + 16];

            FinalKey_1[3 * K + 1] = SecretKey3[Var9_1 + 8];

            FinalKey_1[3 * K + 2] = SecretKey1[Var10_1];

        }

    }

    //FinalKey_1 = 0x00aff3f8 "Tk4So33LrVj7Vl20KuRm3Xn3"

    system("pause");

    return 0;

}

1

2

用户名:12345678

注册码:Tk4So33LrVj7Vl20KuRm3Xn3

 

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

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

相关文章

VMP泄露编译的一些注意事项

VMP编译教程 鉴于VMP已经在GitHub上被大佬强制开源&#xff0c;特此出一期编译教程。各位熟悉的可以略过&#xff0c;不熟悉的可以参考一下。 环境&#xff08;软件&#xff09; Visual Studio 2015 - 2022 &#xff08;建议使用VS2019&#xff0c;Qt插件只有这个版本及以上…

vscode的文件和文件夹的警告标志如何消去

由于平时用vscode写一些java的小demo, 但是这个vscode的警告和错误管理很奇怪, 这个警告信息会显示在这个侧边的文件和文件夹中, 我上网上找能不能把这个给去掉的办法, 找了半天没找到。 于是我就自己去查了一下这个vscode的设置, 真让我找到了这方面的开关, 把下面的这个关闭…

Linux学习笔记-Ubuntu下ssh服务器连接异常Connection reset

文章目录 一、问题问题现象1.1 连接重置无法访问的的问题1.2 查看服务器连接状态1.3 使用调试模式查看的信息 二、临时解决方法三、从根源解决问题3.1 问题分析3.2 服务器的ssh日志3.3 修改ssh配置禁止root登录3.4 配置允许所有ip访问3.5 修改认证方法 角色&#xff1a;百世经纶…

selenium+xpath爬取二手房标题

贝壳找房标题爬取需要注意的是&#xff0c;在页面中间有一个小广告 而他就在ul的li下面&#xff0c;当我们进行title所以输出时&#xff0c;会报错。 所以在进行页面解析之前必须把广告叉掉&#xff0c;不然也把广告那一部分的li给爬取下来了 所以&#xff0c;我们&#xff0…

软件测试职业规划

软件测试人员的发展误区【4】 公司开发的产品专业性较强&#xff0c;软件测试人员需要有很强的专业知识&#xff0c;现在软件测试人员发展出现了一种测试管理者不愿意看到的景象&#xff1a; 1、开发技术较强的软件测试人员转向了软件开发(非测试工具开发)&#xff1b; 2、业务…

蓝桥杯专题-真题版含答案-【古代赌局】【古堡算式】【微生物增殖】【密码发生器】

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

C++报错:error C2238: 意外的标记位于“;”之前

报错信息如下&#xff1a; 编译遇见这样的错误信息主要有一下几种&#xff1a; 情况一&#xff1a; 多数情况下出现这种问题的原因是因为头文件重复包含&#xff1a;即头文件A包含了B&#xff0c;头文件B又包含了A&#xff0c;导致编译器在加载头文件时陷入死循环。 解决办法…

力扣题:数字与字符串间转换-12.16

力扣题-12.16 [力扣刷题攻略] Re&#xff1a;从零开始的力扣刷题生活 力扣题1&#xff1a;640. 求解方程 解题思想&#xff1a;首先将方程按照“”进行划分&#xff0c;然后分别记录x的因数和常数项&#xff0c;最后进行返回的判断即可 class Solution(object):def solveEqu…

万户 OA OfficeServer.jsp 任意文件上传漏洞复现

0x01 产品简介 万户OA是面向政府组织及企事业单位的FlexOffice自主安全协同办公平台。 0x02 漏洞概述 万户OA OfficeServer.jsp接口存在任意文件上传漏洞,攻击者可通过该漏洞上传任意文件从而控制整个服务器。 0x03 复现环境 FOFA: (banner="OASESSIONID" &a…

算法基础概念之数据结构

邻接表 每个点作为头节点接一条链表 链表中元素均为该头节点指向的点 优先队列 参数: ①储存元素类型 ②底层使用的存储结构(一般为vector) ③比较方式(默认小于)

ffmpeg可以做什么

用途 FFmpeg是一个功能强大的多媒体处理工具&#xff0c;可以处理音频和视频文件。它是一个开源项目&#xff0c;可在各种操作系统上运行&#xff0c;包括Linux、Windows和Mac OS X等。以下是FFmpeg可以做的一些主要任务&#xff1a; 转换媒体格式&#xff1a;可将一个媒体格式…

0基础学习VR全景平台篇第128篇:720VR全景拍摄设备推荐

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 本篇教程&#xff0c;小编为大家推荐720VR全景拍摄所需要的设备器材。上节我们提到&#xff0c;理论上任意相机和镜头都能够拍摄全景&#xff0c;但为了标准化制作流程&#xff0…

CSS新手入门笔记整理:CSS常用属性表

字体样式 属性 属性值 说明 font-family 微软雅黑/苹方 字体类型 font-size 数值 字体大小 font-weight 数值/关键字 字体粗细&#xff08;字重&#xff09; font-style normal&#xff08;正常(默认值)&#xff09;italic&#xff08;斜体&#xff09;oblique&am…

云原生向量计算引擎 PieCloudVector:为大模型提供独特记忆

拓数派大模型数据计算系统&#xff08;PieDataComputingSystem&#xff0c;缩写&#xff1a;πDataCS&#xff09;在10月24日程序员节「大模型数据计算系统」2023拓数派年度技术论坛正式发布。πDataCS 以云原生技术重构数据存储和计算&#xff0c;「一份存储&#xff0c;多引擎…

我的NPI项目之Android 安全系列 -- 先认识一下ST33Jxxx

目前接触过的高通平台都没有集成单独的SE&#xff0c;安全运行环境都是高通自家的TEE&#xff0c;又言Trustzone。高通Keystore功能也是依赖TEE来实现的。那么&#xff0c;如果另外集成SE&#xff0c;那么高通的Keystore如何集成&#xff1f;TEE部分要如何配置&#xff1f; 最近…

Ubuntu Shutdown while other user logged on

1. sudo vim /etc/systemd/logind.conf 修改代码KillUserProcessesyes 2. sudo touch /etc/polkit-1/localauthority/50-local.d/multi-user-inhibit-shutdown-restart.pkla 3. 打开修改配置文件 sudo vim /etc/polkit-1/localauthority/50-local.d/multi-user-inhibit-shut…

TrustZone之总线请求

接下来&#xff0c;我们将查看系统中的总线请求者&#xff0c;如下图所示&#xff1a; 系统中的A型处理器具有TrustZone感知&#xff0c;并在每个总线访问中发送正确的安全状态。然而&#xff0c;大多数现代SoC还包含非处理器总线请求者&#xff0c;例如GPU和DMA控制器。 与完成…

MC-30A (32.768 kHz用于汽车应用的晶体单元)

MC-30A 32.768 kHz用于汽车应用的晶体&#xff0c;车规晶振中的热销型号之一。该款石英晶体谐振器&#xff0c;可以在-40 to 85 C的温度内稳定工作&#xff0c;能满足起动振动的要求。同时满足AEC-Q200无源元件质量标准认证&#xff0c;满足汽车仪表系统的所有要求。 频率范围…

蓝桥杯专题-真题版含答案-【基因牛的繁殖】【黄金分割数】【振兴中华】【圆周率与级数】

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

Apache Flume(4):日志文件监控

1 案例说明 企业中应用程序部署后会将日志写入到文件中&#xff0c;可以使用Flume从各个日志文件将日志收集到日志中心以便于查找和分析。 2 使用Exec Soucre Exec Source Exec Source通过指定命令监控文件的变化&#xff0c;加粗属性为必须设置的。 属性名默认值说明chan…