HITCON2022--ctf驱动逆向题

news2024/11/19 3:37:41

作者:selph

HITCON CTF 2022 Writeup-checker

挺有意思的一道题,这里的关键函数是使用的动态生成执行操作,按照特定参数序列进行解密才能正常执行,否则一定会报错异常

checker

一共给了两个文件:checker.exe和checker_drv.sys

是一道驱动逆向的题,查壳,无壳,有签名的Windows 10 x64驱动

先看用户程序checker.exe:

 

逻辑很简单,就是打开符号链接发送IRP请求,控制码是0x222080,没有输入参数,接收1个字节的输出

接下来看驱动程序checker_drv.sys:

DriverEntry里面就这么一个函数,进来后,可以看到,先是创建驱动对象和符号链接,然后填充IRP处理函数

接下来往全局变量里填充了映射的内存地址,

•qword_140013170:里的是dword_140003000函数地址

•addr_140003030_qword:里的是dword_140003000+48数组地址

•qword_140013188:里的是sub_140001430函数地址

•qword_140013180:里的是sub_140001B30函数地址

最后就是一系列异或操作:

 

对qword_140013180里头的前16字节异或了两轮,使用的是qword_140013188里的前32字节的内容

qword_140013180地址的内容:

 

qword_140013188地址的内容:

 

可以看到这两个地址都是函数,这里用一个函数去异或另一个函数emmm

这大概是某种保护手段,阻碍静态分析,真正的函数是运行中动态生成的(实测,异或这两轮的结果并不是可执行的代码)

之前用户程序里看到,传入给驱动了一个控制码,这里到驱动里去看看这个控制码的作用:

 

 

除了这个控制码,上面还有8个控制码,等会再看

当用户传入0x222080的时候,驱动进入这个分支,如果数组byte_140013190里的8个值均为1,则会跳转到LABEL_21,很显然,这里验证的内容是dword_140003000的开头是否是hitcon,这说明这里会出现flag

byte_140013190的值是在哪里改变的呢?往上看:

 

上面的其他8个控制码分支,分别修改该数组的每一位为1,同时也会执行一个相同的处理函数(参数不同)

随便点进去一个看看:

首先是进行了对刚刚那个函数的又一轮异或操作,异或的值取决于函数的参数

然后对qword_140013170地址,也就是dword_140003000数组里的值进行修改,一共修改48个字节,修改方式是调用sub_140001B30函数(被异或了好几轮的那个)

 

 

最后再次异或一轮

整理一下思路:

•flag的生成,是在函数中通过调用一个奇怪的东西sub_140001B30生成出来的

•flag是否完成生产的判定是,是否走完了其他8个控制码的处理分支

那么是不是只需要依次把这8个函数都调用一遍,生成出来的内容就是flag了呢?经测试,根本执行不了,直接报错地址异常,应该是函数异或出来的东西就不是可执行的内容,在Windows 10 x64虚拟机上安装驱动实测则会蓝屏崩溃

这里我卡住了,感觉很接近了,但就是总差一点

休息了一下突然意识到,有没有可能是这8次函数调用的顺序问题?如果程序一定能执行成功的话,就一定能一个一个把8个函数执行出结果

于是经过一番倒腾测试,发现执行一个函数,只有最后一个函数能执行下去,能行,一定是顺序问题,经过又一番测试,得到最终测试顺序,

flag生成:

#include

#include

#define _BYTE BYTE

// qword_140013180 = sub_140001B30

unsigned char* pFunc;

DWORD oldprotect;

typedef BYTE(_cdecl* g_pFunc)(BYTE a);

g_pFunc sub_140001B30;

unsigned char* qword_140013180;

// qword_140013170 = dword_140003000

unsigned char qword_140013170[304] = {

0x63, 0x60, 0xA5, 0xB9, 0xFF, 0xFC, 0x30, 0x0A, 0x48, 0xBB, 0xFE, 0xFE, 0x32, 0x2C, 0x0A, 0xD6,

0xE6, 0xFE, 0xFE, 0x32, 0x2C, 0x0A, 0xD6, 0xBB, 0x4A, 0x4A, 0x32, 0x2C, 0xFC, 0xFF, 0x0A, 0xFD,

0xBB, 0xFE, 0x2C, 0xB9, 0x63, 0xD6, 0xB9, 0x62, 0xD6, 0x0A, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00,

0x19, 0xBC, 0x8F, 0x82, 0xD0, 0x2C, 0x61, 0x34, 0xC0, 0x9F, 0xF6, 0x50, 0xD5, 0xFB, 0x0C, 0x6E,

0xD0, 0xEB, 0xE5, 0xE3, 0xCE, 0xB5, 0x4C, 0xCA, 0x45, 0xAA, 0x11, 0xB2, 0x3E, 0x62, 0x6F, 0x7D,

0xD0, 0xEB, 0xA9, 0xE3, 0xB2, 0x2F, 0x06, 0x47, 0x7C, 0x28, 0xC5, 0xDE, 0xDE, 0x1A, 0x4E, 0xD6,

0xD8, 0x2D, 0x93, 0x4F, 0x82, 0x65, 0x64, 0xFD, 0x08, 0x62, 0x4B, 0x87, 0x7E, 0x52, 0x47, 0x30,

0xB7, 0xBA, 0xD0, 0x39, 0x68, 0x53, 0x50, 0xAB, 0x20, 0xD5, 0xCA, 0x84, 0x26, 0x71, 0x6F, 0x91,

0x1B, 0x36, 0x46, 0x11, 0xA5, 0xF1, 0x4E, 0x58, 0x6C, 0x74, 0xD4, 0x9C, 0x15, 0xE2, 0x28, 0xD5,

0xD9, 0x0F, 0x3D, 0x83, 0xF3, 0xFC, 0xD1, 0x13, 0x1A, 0x62, 0x12, 0x40, 0xAA, 0xEA, 0xCD, 0xCB,

0xE1, 0xC6, 0x08, 0x81, 0x98, 0xF6, 0x68, 0x88, 0xBE, 0x23, 0xB5, 0x9E, 0x55, 0xB9, 0xE2, 0x7D,

0x5A, 0xDA, 0x39, 0x07, 0xF0, 0x2E, 0x32, 0x20, 0x59, 0x56, 0x4C, 0xB4, 0x8F, 0x3E, 0x07, 0x61,

0xD9, 0x0F, 0x2D, 0x61, 0xF1, 0x91, 0x33, 0x14, 0xCB, 0x49, 0x68, 0xFE, 0x1F, 0xD4, 0x8A, 0xFE,

0xE1, 0xC6, 0x18, 0x63, 0x9A, 0x9B, 0x8A, 0x8A, 0x7F, 0x08, 0xC3, 0xE8, 0xE1, 0xEC, 0x0B, 0x8F,

0x3B, 0x00, 0x94, 0xA5, 0x11, 0xE7, 0x47, 0x66, 0xC4, 0x9F, 0x98, 0x18, 0x70, 0xF0, 0x30, 0xF6,

0x94, 0x71, 0xB1, 0x95, 0xD1, 0xF0, 0x6F, 0xB7, 0xD9, 0x3D, 0x05, 0x9E, 0xC1, 0x53, 0x33, 0x76,

0x9B, 0x4B, 0x69, 0xCA, 0xDE, 0xFD, 0x7D, 0x67, 0xB8, 0x29, 0x2B, 0xC7, 0xC5, 0x84, 0x2C, 0xD1,

0x87, 0x87, 0xF1, 0x98, 0x97, 0x74, 0xAD, 0x4B, 0x32, 0xF0, 0x4A, 0x51, 0x72, 0xEA, 0x09, 0xF7,

0x38, 0xFD, 0x27, 0xBD, 0x1C, 0x52, 0x71, 0x43, 0x95, 0x9C, 0x1A, 0x86, 0xF2, 0xC0, 0xF9, 0xF8

};

// addr_140003030_qword = dword_140003030

unsigned char* qword_140003030 = qword_140013170 + 48;

// qword_140013188 = sub_140001430

void init() {

unsigned char sub_140001B30_init[20] = {

 0x80, 0xE9, 0x22, 0x80, 0xF1, 0xAD, 0x0F, 0xB6, 0xC1, 0x6B, 0xC8, 0x11, 0xB8, 0x9E, 0x00, 0x00,

 0x00, 0x2A, 0xC1, 0xC3

};

unsigned char sub_140001430[88] = {

0x40, 0x53, 0x48, 0x83, 0xEC, 0x20, 0x48, 0x8B, 0x05, 0x3B, 0x0C, 0x00, 0x00, 0x48, 0x8B, 0xDA,

0x48, 0x8B, 0x4A, 0x10, 0x48, 0x39, 0x08, 0x75, 0x37, 0x48, 0x8B, 0x4A, 0x08, 0xFF, 0x15, 0x1D,

0x0C, 0x00, 0x00, 0x48, 0x8D, 0x0D, 0x16, 0x1D, 0x00, 0x00, 0x80, 0x3C, 0x08, 0x00, 0x74, 0x20,

0x8B, 0x03, 0x83, 0xF8, 0x01, 0x74, 0x05, 0x83, 0xF8, 0x02, 0x75, 0x14, 0x48, 0x8B, 0x4B, 0x20,

0x8B, 0x41, 0x04, 0x83, 0xE0, 0x01, 0x84, 0xC0, 0x74, 0x06, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00,

0x33, 0xC0, 0x48, 0x83, 0xC4, 0x20, 0x5B, 0xC3

};



pFunc = (unsigned char*)malloc(20);

VirtualProtect((LPVOID)pFunc, 20, PAGE_EXECUTE_READWRITE, &oldprotect);

memcpy(pFunc, sub_140001B30_init, 20);

sub_140001B30 = (g_pFunc)pFunc;

qword_140013180 = pFunc;

for (int i = 0, j = 0; i < 32; i++,j++)

{

    if (j == 16)j = 0;

    pFunc[j] ^= sub_140001430[i];

}

}

void __fastcall sub_1400014D0(unsigned int a1)

{

__int64 v1; // rdi

char* v3; // rbx

unsigned char * v4; // rbx

unsigned char * v5; // rbx

unsigned char * v6; // rbx

unsigned char * v7; // rbx

unsigned char * v8; // rbx

unsigned char * v9; // rbx

unsigned char * v10; // rbx

unsigned char * v11; // rbx

unsigned char * v12; // rbx

unsigned char * v13; // rbx

unsigned char * v14; // rbx

unsigned char * v15; // rbx

unsigned char * v16; // rbx

unsigned char * v17; // rbx

unsigned char * v18; // rbx

unsigned char * v19; // rbx

unsigned char * v20; // rbx

unsigned char * v21; // rbx

unsigned char * v22; // rbx

unsigned char * v23; // rbx

unsigned char * v24; // rbx

unsigned char * v25; // rbx

unsigned char * v26; // rbx

unsigned char * v27; // rbx

unsigned char * v28; // rbx

unsigned char * v29; // rbx

unsigned char * v30; // rbx

unsigned char * v31; // rbx

unsigned char * v32; // rbx

unsigned char * v33; // rbx

unsigned char * v34; // rbx

unsigned char * v35; // rbx

unsigned char * v36; // rbx

unsigned char * v37; // rbx

unsigned char * v38; // rbx

unsigned char * v39; // rbx

unsigned char * v40; // rbx

unsigned char * v41; // rbx

unsigned char * v42; // rbx

unsigned char * v43; // rbx

unsigned char * v44; // rbx

unsigned char * v45; // rbx



v1 = a1;

*(_BYTE*)qword_140013180 ^= *(_BYTE*)(v1 + qword_140003030);// 修改这16个值,dword_140003000+48

*(_BYTE*)(qword_140013180 + 1) ^= *(_BYTE*)((unsigned int)(v1 + 1) + qword_140003030);

*(_BYTE*)(qword_140013180 + 2) ^= *(_BYTE*)((unsigned int)(v1 + 2) + qword_140003030);

*(_BYTE*)(qword_140013180 + 3) ^= *(_BYTE*)((unsigned int)(v1 + 3) + qword_140003030);

*(_BYTE*)(qword_140013180 + 4) ^= *(_BYTE*)((unsigned int)(v1 + 4) + qword_140003030);

*(_BYTE*)(qword_140013180 + 5) ^= *(_BYTE*)((unsigned int)(v1 + 5) + qword_140003030);

*(_BYTE*)(qword_140013180 + 6) ^= *(_BYTE*)((unsigned int)(v1 + 6) + qword_140003030);

*(_BYTE*)(qword_140013180 + 7) ^= *(_BYTE*)((unsigned int)(v1 + 7) + qword_140003030);

*(_BYTE*)(qword_140013180 + 8) ^= *(_BYTE*)((unsigned int)(v1 + 8) + qword_140003030);

*(_BYTE*)(qword_140013180 + 9) ^= *(_BYTE*)((unsigned int)(v1 + 9) + qword_140003030);

*(_BYTE*)(qword_140013180 + 10) ^= *(_BYTE*)((unsigned int)(v1 + 10) + qword_140003030);

*(_BYTE*)(qword_140013180 + 11) ^= *(_BYTE*)((unsigned int)(v1 + 11) + qword_140003030);

*(_BYTE*)(qword_140013180 + 12) ^= *(_BYTE*)((unsigned int)(v1 + 12) + qword_140003030);

*(_BYTE*)(qword_140013180 + 13) ^= *(_BYTE*)((unsigned int)(v1 + 13) + qword_140003030);

*(_BYTE*)(qword_140013180 + 14) ^= *(_BYTE*)((unsigned int)(v1 + 14) + qword_140003030);

*(_BYTE*)(qword_140013180 + 15) ^= *(_BYTE*)((unsigned int)(v1 + 15) + qword_140003030);

v3 = (char*)qword_140013170;                 // 修改这43字节,通过函数1B30(1B30是被篡改过的函数)

*v3 = sub_140001B30(*(_BYTE*)qword_140013170);

v4 = qword_140013170;

*(_BYTE*)(v4 + 1) = sub_140001B30(*(_BYTE*)(qword_140013170 + 1));

v5 = qword_140013170;

*(_BYTE*)(v5 + 2) = sub_140001B30(*(_BYTE*)(qword_140013170 + 2));

v6 = qword_140013170;

*(_BYTE*)(v6 + 3) = sub_140001B30(*(_BYTE*)(qword_140013170 + 3));

v7 = qword_140013170;

*(_BYTE*)(v7 + 4) = sub_140001B30(*(_BYTE*)(qword_140013170 + 4));

v8 = qword_140013170;

*(_BYTE*)(v8 + 5) = sub_140001B30(*(_BYTE*)(qword_140013170 + 5));

v9 = qword_140013170;

*(_BYTE*)(v9 + 6) = sub_140001B30(*(_BYTE*)(qword_140013170 + 6));

v10 = qword_140013170;

*(_BYTE*)(v10 + 7) = sub_140001B30(*(_BYTE*)(qword_140013170 + 7));

v11 = qword_140013170;

*(_BYTE*)(v11 + 8) = sub_140001B30(*(_BYTE*)(qword_140013170 + 8));

v12 = qword_140013170;

*(_BYTE*)(v12 + 9) = sub_140001B30(*(_BYTE*)(qword_140013170 + 9));

v13 = qword_140013170;

*(_BYTE*)(v13 + 10) = sub_140001B30(*(_BYTE*)(qword_140013170 + 10));

v14 = qword_140013170;

*(_BYTE*)(v14 + 11) = sub_140001B30(*(_BYTE*)(qword_140013170 + 11));

v15 = qword_140013170;

*(_BYTE*)(v15 + 12) = sub_140001B30(*(_BYTE*)(qword_140013170 + 12));

v16 = qword_140013170;

*(_BYTE*)(v16 + 13) = sub_140001B30(*(_BYTE*)(qword_140013170 + 13));

v17 = qword_140013170;

*(_BYTE*)(v17 + 14) = sub_140001B30(*(_BYTE*)(qword_140013170 + 14));

v18 = qword_140013170;

*(_BYTE*)(v18 + 15) = sub_140001B30(*(_BYTE*)(qword_140013170 + 15));

v19 = qword_140013170;

*(_BYTE*)(v19 + 16) = sub_140001B30(*(_BYTE*)(qword_140013170 + 16));

v20 = qword_140013170;

*(_BYTE*)(v20 + 17) = sub_140001B30(*(_BYTE*)(qword_140013170 + 17));

v21 = qword_140013170;

*(_BYTE*)(v21 + 18) = sub_140001B30(*(_BYTE*)(qword_140013170 + 18));

v22 = qword_140013170;

*(_BYTE*)(v22 + 19) = sub_140001B30(*(_BYTE*)(qword_140013170 + 19));

v23 = qword_140013170;

*(_BYTE*)(v23 + 20) = sub_140001B30(*(_BYTE*)(qword_140013170 + 20));

v24 = qword_140013170;

*(_BYTE*)(v24 + 21) = sub_140001B30(*(_BYTE*)(qword_140013170 + 21));

v25 = qword_140013170;

*(_BYTE*)(v25 + 22) = sub_140001B30(*(_BYTE*)(qword_140013170 + 22));

v26 = qword_140013170;

*(_BYTE*)(v26 + 23) = sub_140001B30(*(_BYTE*)(qword_140013170 + 23));

v27 = qword_140013170;

*(_BYTE*)(v27 + 24) = sub_140001B30(*(_BYTE*)(qword_140013170 + 24));

v28 = qword_140013170;

*(_BYTE*)(v28 + 25) = sub_140001B30(*(_BYTE*)(qword_140013170 + 25));

v29 = qword_140013170;

*(_BYTE*)(v29 + 26) = sub_140001B30(*(_BYTE*)(qword_140013170 + 26));

v30 = qword_140013170;

*(_BYTE*)(v30 + 27) = sub_140001B30(*(_BYTE*)(qword_140013170 + 27));

v31 = qword_140013170;

*(_BYTE*)(v31 + 28) = sub_140001B30(*(_BYTE*)(qword_140013170 + 28));

v32 = qword_140013170;

*(_BYTE*)(v32 + 29) = sub_140001B30(*(_BYTE*)(qword_140013170 + 29));

v33 = qword_140013170;

*(_BYTE*)(v33 + 30) = sub_140001B30(*(_BYTE*)(qword_140013170 + 30));

v34 = qword_140013170;

*(_BYTE*)(v34 + 31) = sub_140001B30(*(_BYTE*)(qword_140013170 + 31));

v35 = qword_140013170;

*(_BYTE*)(v35 + 32) = sub_140001B30(*(_BYTE*)(qword_140013170 + 32));

v36 = qword_140013170;

*(_BYTE*)(v36 + 33) = sub_140001B30(*(_BYTE*)(qword_140013170 + 33));

v37 = qword_140013170;

*(_BYTE*)(v37 + 34) = sub_140001B30(*(_BYTE*)(qword_140013170 + 34));

v38 = qword_140013170;

*(_BYTE*)(v38 + 35) = sub_140001B30(*(_BYTE*)(qword_140013170 + 35));

v39 = qword_140013170;

*(_BYTE*)(v39 + 36) = sub_140001B30(*(_BYTE*)(qword_140013170 + 36));

v40 = qword_140013170;

*(_BYTE*)(v40 + 37) = sub_140001B30(*(_BYTE*)(qword_140013170 + 37));

v41 = qword_140013170;

*(_BYTE*)(v41 + 38) = sub_140001B30(*(_BYTE*)(qword_140013170 + 38));

v42 = qword_140013170;

*(_BYTE*)(v42 + 39) = sub_140001B30(*(_BYTE*)(qword_140013170 + 39));

v43 = qword_140013170;

*(_BYTE*)(v43 + 40) = sub_140001B30(*(_BYTE*)(qword_140013170 + 40));

v44 = qword_140013170;

*(_BYTE*)(v44 + 41) = sub_140001B30(*(_BYTE*)(qword_140013170 + 41));

v45 = qword_140013170;

*(_BYTE*)(v45 + 42) = sub_140001B30(*(_BYTE*)(qword_140013170 + 42));

*(_BYTE*)qword_140013180 ^= *(_BYTE*)((unsigned int)(v1 + 16) + qword_140003030);// 然后再次修改这16个值

*(_BYTE*)(qword_140013180 + 1) ^= *(_BYTE*)((unsigned int)(v1 + 17) + qword_140003030);

*(_BYTE*)(qword_140013180 + 2) ^= *(_BYTE*)((unsigned int)(v1 + 18) + qword_140003030);

*(_BYTE*)(qword_140013180 + 3) ^= *(_BYTE*)((unsigned int)(v1 + 19) + qword_140003030);

*(_BYTE*)(qword_140013180 + 4) ^= *(_BYTE*)((unsigned int)(v1 + 20) + qword_140003030);

*(_BYTE*)(qword_140013180 + 5) ^= *(_BYTE*)((unsigned int)(v1 + 21) + qword_140003030);

*(_BYTE*)(qword_140013180 + 6) ^= *(_BYTE*)((unsigned int)(v1 + 22) + qword_140003030);

*(_BYTE*)(qword_140013180 + 7) ^= *(_BYTE*)((unsigned int)(v1 + 23) + qword_140003030);

*(_BYTE*)(qword_140013180 + 8) ^= *(_BYTE*)((unsigned int)(v1 + 24) + qword_140003030);

*(_BYTE*)(qword_140013180 + 9) ^= *(_BYTE*)((unsigned int)(v1 + 25) + qword_140003030);

*(_BYTE*)(qword_140013180 + 10) ^= *(_BYTE*)((unsigned int)(v1 + 26) + qword_140003030);

*(_BYTE*)(qword_140013180 + 11) ^= *(_BYTE*)((unsigned int)(v1 + 27) + qword_140003030);

*(_BYTE*)(qword_140013180 + 12) ^= *(_BYTE*)((unsigned int)(v1 + 28) + qword_140003030);

*(_BYTE*)(qword_140013180 + 13) ^= *(_BYTE*)((unsigned int)(v1 + 29) + qword_140003030);

*(_BYTE*)(qword_140013180 + 14) ^= *(_BYTE*)((unsigned int)(v1 + 30) + qword_140003030);

*(_BYTE*)(qword_140013180 + 15) ^= *(_BYTE*)((unsigned int)(v1 + 31) + qword_140003030);

}

int main()

{

// 得到修改后的函数,可能是干扰动态调试的

init();

// 顺序问题!!按照特定顺序执行才能运行成功

sub_1400014D0(0xE0);    // 1

sub_1400014D0(0x40);    // 2

sub_1400014D0(0xC0);    // 3

sub_1400014D0(0x00);    // 4

sub_1400014D0(0x20);    // 5



sub_1400014D0(0x80);    // 6

sub_1400014D0(0x60);    // 



sub_1400014D0(0xA0);    // 



printf("%s", qword_140013170);

}

运行结果:hitcon{r3ally_re4lly_rea11y_normal_checker}

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

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

相关文章

VR数字政务:多功能一体化,政务服务更便民

越来越多的政务单位都是通过网络等线上信息化渠道&#xff0c;进行政务的推进以及落实、查询等功能的实施&#xff0c;在实际的政务应用中&#xff0c;VR技术可以打造集实景导航、窗口查询、在线申报等多功能为一体&#xff0c;实现数据多跑腿、群众少跑腿&#xff0c;有效提高…

Nginx 01篇——Nginx详细安装步骤以及Nginx各种启动方式

Nginx 01篇——Nginx详细安装步骤以及Nginx各种启动方式1. 前言2. 下载安装2.1 下载安装包2.2 安装2.2.1 离线安装2.2.1.1 安装步骤2.2.1.2 安装问题2.2.2 先安装所需依赖2.2.3 直接 yum 安装2.2.4 指定安装目录安装3. nginx 启动4. 启动后访问5. Nginx 启动等简单命令5.1 启动…

SVN,Git与Helix Core,谁的数据管理基础设施更安全?

2022年2月底&#xff0c;全球知名的半导体芯片公司英伟达被爆遭到勒索软件攻击&#xff0c;不久后&#xff0c;英伟达公司官方证实遭到入侵&#xff0c;攻击者已开始在线泄露员工凭据和私密信息。勒索软件组织表示&#xff0c;如果英伟达拒绝支付高达100万美元的赎金&#xff0…

写在2022年的末尾

今年是我人生的第24个年头。 最近了解稚晖君&#xff0c;xinglu师兄&#xff0c;以及很多优秀的同辈人的事迹之后&#xff0c;感觉到自己还差了很远。 读研已经过半&#xff0c;研二已经到了第二个学期&#xff0c;而自己还什么成果都没有。甚至开题的事情到现在都还没有头绪。…

C++简介

C是一种计算机高级程序设计语言&#xff0c;由C语言扩展升级而产生 &#xff0c;最早于1979年由本贾尼斯特劳斯特卢普在AT&T贝尔工作室研发。 C既可以进行C语言的过程化程序设计&#xff0c;又可以进行以抽象数据类型为特点的基于对象的程序设计&#xff0c;还可以进行以…

计算机英文论文怎么做降重? - 易智编译EaseEditing

人工降重一定要找靠谱的机构做。 降重是很耗费精力和时间的学术服务。 而那些没有口碑且不专业的商家&#xff0c;真的会花费那么多心思来仔细琢磨你的论文吗&#xff1f; 那些没有声誉的非专业商家给论文降重会产生很多弊端&#xff1a; &#xff08;1&#xff09;他们为了…

内网穿透你真的了解吗?

前言 内网穿透作为程序员常用的调试手段之一&#xff0c;我们可以通过在个人电脑上运行花生壳或者 frp 等方式&#xff0c;让他人访问我们本地启动的服务&#xff0c;而且这种访问可以不受局域网的限制&#xff0c;当我们使用ngrok,frp等开源框架时&#xff0c;你是否有好奇过…

力扣sql入门篇(一)

力扣sql入门篇(一) 1 大的国家 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 SELECT name,population,area FROM World WHERE area>3000000 OR population>250000001.3 运行截图 2 可回收且低碳的产品 2.1 题目内容 2.1.1 基本题目信息 2.…

c++使用icu国际化(i18n)

icu International Components for Unicode&#xff0c;https://github.com/unicode-org/icu.git https://icu.unicode.org/ 帮助文档&#xff1a; https://unicode-org.github.io/icu/userguide/icu/howtouseicu.html i18n&#xff0c;Internationalization (in/i18n) libra…

第五章:开机,重启和用户登录注销-[实操篇]

一&#xff1a;开机&重启命令 1.1基本介绍 shutdown shutdown -h now&#xff1a;表示立即关机 shutdown -h 1 : 表示1分钟后关机 shutdown -r now : 立即重启 halt 就是直接使用&#xff0c;效果等价于关机 reboot 就是直接使用&#xff0c;效果等价于关机 syn &…

uTools V3.3.0 效率工具集

前言 uTools是一款基于electron开发的工具集软件&#xff0c;通过快捷唤醒搜索&#xff0c;直接打开各种功能&#xff0c;非常方便。 uTools uTools是一个极简、插件化、跨平台的现代化桌面软件。通过自由选配丰富的插件&#xff0c;打造你得心应手的工具集合。 通过快捷键…

制作gltf动态夜景模型

kele 前言 要制作一个充满科技感的场景&#xff0c;离不开动画特效。众所周知&#xff0c;Unity软件可制作各种炫酷动画效果&#xff0c;如果将Unity中的动画添加到WebGL网页项目中&#xff0c;那一定会非常美妙吧~接下来小编将介绍如何通过Unity制作纹理动画&#xff0c;并导…

RISC-V IDE MRS使用笔记(七) :常用开发技巧汇总

RISC-V IDE MRS使用笔记(七) &#xff1a;常用开发技巧汇总 Q1: MRS调试时如何查看外设寄存器内容&#xff1f; A1: 在调试配置界面添加相应的.svd文件。 Q2: MRS如何调用数学库? A2: #include ”math.h”头文件,并在工程属性页面增加”m”参数。 Q3: 如何设置MRS调试前默认…

还在对比IT培训机构,行内人告诉你怎么比?

还在对比IT培训机构&#xff0c;行内人告诉你怎么比&#xff1f;因为身处IT培训行业6年多点时间 &#xff0c;从讲师到校区经营的成长履历中。见识过众多机构的运营和发展&#xff0c;当然也包含我所在的正厚软件。平时在知乎上看的多&#xff0c;自然推荐的关于机构对比的话题…

蓝牙无线运动耳机排行榜、口碑最好的运动蓝牙耳机推荐

越来越多的人开始喜欢蓝牙耳机的便携性&#xff0c;尤其对于运动的慢跑族&#xff0c;蓝牙耳机更为方便携带和佩戴&#xff0c;毕竟没有了线束的烦恼&#xff0c;目前蓝牙耳机市场很大&#xff0c;用户人群很多&#xff0c;我体验过的这类产品比较多&#xff0c;如何挑选一款满…

MySQL5.7安装配置教程-Windows(企业常用版)超详细

引言 MySQL 5.7 为公司、企业常用的MySQL版本。 正在学习或正在工作的小伙伴推荐相关教程按照5.7的版本来学习、操作。 1. 下载MySQL 阿里云盘不限速高速下载地址&#xff1a; https://www.aliyundrive.com/s/YTMa5LfSFB2 因为阿里云盘不支持zip压缩包的分享&#xff0c;我用…

【财务】FMS财务管理系统---应付结算

本篇文章中&#xff0c;笔者对应付结算各个部分进行了梳理和分析&#xff0c;与大家分享。 前面相继介绍了财务系统的组成、财务数据流转、应收管理、质保金、预付款、费用管理以及合同管理。 我个人觉得应付结算管理部分的逻辑是整个FMS财务管理系统中较为复杂的一部分&#…

APP测试面试题汇总

一、基础篇 1、请介绍一下&#xff0c;APP测试流程&#xff1f; APP测试流程与web测试流程类似&#xff0c;分为如下七个阶段&#xff1a; 1.根据需求说明书编写测试计划&#xff1b; 2.制定测试方案&#xff0c;主要是测试任务、测试人员和测试时间的分配&#xff1b; 3.…

Vue3 Composition API: 对比ref和reactive

Vue2 回顾 首先回顾一下在Vue2中我们是如何创建一个响应式数据 (reactive data)的&#xff1a; Vue3新特性 ref的使用 而在Vue3中&#xff0c;我们可以用Composition API: ref 来改写上述代码&#xff1a; ref 的作用就是将一个原始数据类型&#xff08;primitive data t…

NPM 2FA双重认证的设置方法

NPM在使用用户名和密码登录后&#xff0c;他觉得还不是很安全&#xff0c;需要用一个手机软件来生成一个随机验证码&#xff0c;两者同步&#xff0c;来做二次验证。类似于手机银行的优盾或者验证码验证。 双重验证&#xff1a;标准验证方法&#xff0c;其中一个因素是密码。 …