背景介绍
FASTDNS作者是张慧星,该软件能很好地测试dns并自动设置系统,一直以来都在用却不知道原理,这2天我做了逆向分析,并打算将delphi的移植为vc++的源码,如果有可能以后会兼容ipv6 dns。
提前声明:手动标注是逆向分析的重要步骤,下面代码中有些是API名,其余大部分有名称的都是分析了函数以后手动做的命名,为分析结构方便,以下汇集了我3天的成果,目的就是为了用VC++完成同样的功能,并期盼以后可以改进,比如兼容Ipv6和结合代理软件。
开始分析
看到设置界面发现可以设置多线程的,因此从这里入手,bp CreateThread,发现断不下来,于是bm !CreateThread,断到这里:
ecx=param0
edx=dwStackSize
eax=lpThreadAttributes
param1=lpThreadId
param2=dwCreationFlags
param3
0043D348 push ebp
0043D349 mov ebp, esp
0043D34B push ebx
0043D34C push esi
0043D34D push edi
0043D34E mov edi, ecx//edi=param1
0043D350 mov esi, edx//esi=dwStackSize
0043D352 mov ebx, eax//ebx=lpThreadAttributes
0043D354 mov eax, 8//DWORD[2]
0043D359 call sub_43B5C0
0043D35E mov [eax], edi//DWORD[0]=param0;FARPROC
0043D360 mov edx, [ebp+arg_8]
0043D363 mov [eax+4], edx//DWORD[1]=param3;PARAM
0043D366 mov byte_4B9C2D, 1
0043D36D mov edx, [ebp+dwCreationFlags_1]
0043D370 push edx ; lpThreadId
0043D371 mov edx, [ebp+dwCreationFlags]
0043D374 push edx ; dwCreationFlags
0043D375 push eax ; lpParameter
0043D376 mov eax, offset SpeedTest
0043D37B push eax ; lpStartAddress
0043D37C push esi ; dwStackSize
0043D37D push ebx ; lpThreadAttributes
0043D37E call CreateThread
0043D383 pop edi
0043D384 pop esi
0043D385 pop ebx
0043D386 pop ebp
0043D387 retn 0Ch
可以看到实际只执行了参数中的函数指针部分,现在我们来找CreateThread的StartAddress和Param部分,往上层找到StartAddress的值为Classes::_17197
004254A4 @Classes@TThread@$bctr$qqro proc near ; CODE XREF: sub_40E908+33 p
04254E6 push esi ; param3
004254E7 push 4 ; dwCreationFlags
004254E9 lea eax, [esi+8]
004254EC push eax ; lpThreadId
004254ED mov ecx, offset @Classes@_17197 ; a3
004254F2 xor edx, edx ; dwStackSize
004254F4 xor eax, eax ; lpThreadAttributes
004254F6 call @BeginThread
00425404 @Classes@_17197 proc near ; DATA XREF: Classes::TThread::TThread(bool)+49 o
00425404
00425404 var_4= dword ptr -4
00425404
00425404 push ebp
00425405 mov ebp, esp
00425407 push ecx
00425408 push ebx
00425409 push esi
0042540A push edi
0042540B mov [ebp+var_4], eax
0042540E xor eax, eax
00425410 push ebp
00425411 push offset j_@@HandleFinally_0 ; __linkproc__ HandleFinally
00425416 push dword ptr fs:[eax]
00425419 mov fs:[eax], esp
0042541C mov eax, [ebp+var_4]
0042541F cmp byte ptr [eax+0Dh], 0
00425423 jnz short loc_42545A
00425425 xor eax, eax
00425427 push ebp
00425428 push offset loc_425445
0042542D push dword ptr fs:[eax]
00425430 mov fs:[eax], esp
00425433 mov eax, [ebp+var_4]
00425436 mov edx, [eax]
00425438 call dword ptr [edx+4]
0042543B xor eax, eax
0042543D pop edx
0042543E pop ecx
0042543F pop ecx
00425440 mov fs:[eax], edx
00425443 jmp short loc_42545A
00425445 ; ---------------------------------------------------------------------------
00425445
00425445 loc_425445: ; DATA XREF: Classes::_17197+24 o
00425445 jmp @@HandleAnyException ; __linkproc__ HandleAnyException
0042544A ; ---------------------------------------------------------------------------
0042544A call @AcquireExceptionObject
0042544F mov edx, [ebp+var_4]
00425452 mov [edx+2Ch], eax
00425455 call @@DoneExcept ; __linkproc__ DoneExcept
0042545A
0042545A loc_42545A: ; CODE XREF: Classes::_17197+1F j
0042545A ; Classes::_17197+3F j
0042545A xor eax, eax
0042545C pop edx
0042545D pop ecx
0042545E pop ecx
0042545F mov fs:[eax], edx
00425462 push offset unk_42549C
00425467
00425467 loc_425467: ; CODE XREF: .text:0042549A j
00425467 mov eax, [ebp+var_4]
0042546A mov bl, [eax+0Fh]
0042546D mov eax, [ebp+var_4]
00425470 mov esi, [eax+14h]
00425473 mov eax, [ebp+var_4]
00425476 mov byte ptr [eax+10h], 1
0042547A mov eax, [ebp+var_4]
0042547D mov edx, [eax]
0042547F call dword ptr [edx]
00425481 test bl, bl
00425483 jz short loc_42548D
00425485 mov eax, [ebp+var_4]
00425488 call @TObject@Free ; TObject::Free
0042548D
0042548D loc_42548D: ; CODE XREF: Classes::_17197+7F j
0042548D mov eax, esi ; dwExitCode
0042548F call @EndThread
实际执行的又是参数中的函数指针;先执行*(param+4)(param) 在执行*(param(param),(感觉delphi的这个结构构造的很巧妙,传入CreateThread的param之前在堆上分配,而进了startaddress后自动释放,param里面也是StartAddress+Param的结构^_^可以无限这么套下去),而param的值需要再往上找。
004254A4 @Classes@TThread@$bctr$qqro proc near ; CODE XREF: sub_40E908+33 p
004254A4
004254A4 var_10= dword ptr -10h
004254A4 var_C= dword ptr -0Ch
004254A4 var_8= byte ptr -8
004254A4 var_1= byte ptr -1
004254A4
004254A4 push ebp
004254A5 mov ebp, esp
004254A7 add esp, 0FFFFFFF0h
004254AA push ebx
004254AB push esi
004254AC xor ebx, ebx
004254AE mov [ebp+var_10], ebx
004254B1 test dl, dl
004254B3 jz short loc_4254BD
004254B5 add esp, 0FFFFFFF0h
004254B8 call @@ClassCreate ; __linkproc__ ClassCreate
004254BD
004254BD loc_4254BD: ; CODE XREF: Classes::TThread::TThread(bool)+F j
004254BD mov ebx, ecx
004254BF mov [ebp+var_1], dl
004254C2 mov esi, eax
004254C4 xor eax, eax
004254C6 push ebp
004254C7 push offset loc_42554E
004254CC push dword ptr fs:[eax] ; lpThreadIda
004254CF mov fs:[eax], esp
004254D2 xor edx, edx
004254D4 mov eax, esi
004254D6 call @TObject@$bctr_0 ; TObject::`...'
004254DB call sub_42522C
004254E0 mov [esi+0Eh], bl
004254E3 mov [esi+0Ch], bl
004254E6 push esi ; param3
004254E7 push 4 ; dwCreationFlags
004254E9 lea eax, [esi+8]
004254EC push eax ; lpThreadId
004254ED mov ecx, offset @Classes@_17197 ; a3
004254F2 xor edx, edx ; dwStackSize
004254F4 xor eax, eax ; lpThreadAttributes
004254F6 call @BeginThread
看到004254E6处push的第一个参数位esi,往上看到004254C2处eax做了赋值,往前再没给eax赋值的,因此eax是传入参数,还要往调用者找,(delphi程序喜欢用ecx eax edx传值,不过这样的话在调用系统api前后,要做栈<–>寄存器参数变换)
0040E908 sub_40E908 proc near ; CODE XREF: sub_4094B4+46 p
0040E908 push ebp
0040E909 mov ebp, esp
0040E90B add esp, 0FFFFFFD4h
0040E90E mov [ebp+var_8], dl
0040E911 test dl, dl
0040E913 jle short loc_40E91A
0040E915 call __ClassCreate
0040E91A
0040E91A loc_40E91A: ; CODE XREF: sub_40E908+B j
0040E91A mov [ebp+var_2A], cl
0040E91D mov [ebp+var_29], dl
0040E920 mov [ebp+var_4], eax
0040E923 mov eax, offset unk_4B3C0C
0040E928 call @__InitExceptBlockLDTC
0040E92D mov [ebp+var_18], 8
0040E933 mov cl, [ebp+var_2A]
0040E936 xor edx, edx
0040E938 mov eax, [ebp+var_4]
0040E93B call @Classes@TThread@$bctr$qqro ; Classes::TThread::TThread(bool)
看到0040E938处var_4对eax赋值,而往上0040E920处eax又赋值给var_4,之前eax再没有赋值行为,同样eax也是该函数参数,继续往调用者走
004094B4 push ebp
004094B5 mov ebp, esp
004094B7 add esp, 0FFFFFFD4h
004094BA push ebx
004094BB push esi
004094BC push edi
004094BD mov [ebp+var_8], dl
004094C0 test dl, dl
004094C2 jle short loc_4094C9
004094C4 call __ClassCreate
004094C9
004094C9 loc_4094C9: ; CODE XREF: sub_4094B4+E j
004094C9 mov ebx, ecx
004094CB mov [ebp+var_29], dl
004094CE mov [ebp+var_4], eax
004094D1 mov eax, offset unk_4B24D0
004094D6 call @__InitExceptBlockLDTC
004094DB mov [ebp+var_18], 8
004094E1 mov edx, [ebp+arg_10]
004094E4 mov ecx, ebx
004094E6 push edx
004094E7 push [ebp+arg_C]
004094EA push [ebp+arg_8]
004094ED mov eax, [ebp+arg_4]
004094F0 push eax
004094F1 mov edx, [ebp+arg_0]
004094F4 push edx
004094F5 xor edx, edx
004094F7 mov eax, [ebp+var_4]
004094FA call sub_40E908
00402748 push ebp
00402749 mov ebp, esp
0040274B add esp, 0FFFFFF98h
0040274E mov eax, offset unk_4A2608
00402753 push ebx
00402754 push esi
00402755 push edi
00402756 mov esi, [ebp+arg_0]
00402759 call @__InitExceptBlockLDTC
0040275E mov ebx, [ebp+arg_4]
00402761 cmp byte ptr [ebx+10h], 1
00402765 jnz loc_4028A0
0040276B mov [ebp+var_34], 8
00402771 push ebx
00402772 lea eax, [ebp+var_4C]
00402775 mov [ebp+var_4C], offset sub_402990
0040277C mov [ebp+var_48], esi
0040277F mov dl, 1
00402781 push dword ptr [eax+4]
00402784 push dword ptr [eax]
00402786 mov ecx, [esi+3ECh]
0040278C push ecx
0040278D mov cl, 1
0040278F mov eax, [esi+3F0h]
00402795 push eax
00402796 mov eax, off_4B2618
0040279B call sub_4094B4
最后找到这里,发现eax是4B2618,来看该处2个函数指针(应该说是虚函数表,从后面可以看到param其实是个类):
.data:004B2618 off_4B2618 dd offset _cls_DNSSpending_TDNSSpending//虚表
。。。。。。。。。。。//类成员
.data:004B2664 _cls_DNSSpending_TDNSSpending dd offset @TThread@DoTerminate
.data:004B2664 ; DATA XREF: .text:00409906 o
.data:004B2664 ; .dataff_4B2618 o
.data:004B2664 ; TThread:oTerminate
.data:004B2668 dd offset sub_40EA3C
.data:004B266C dd offset sub_40970C
再往上走可以看到程序按照分的线程数创建线程:
00402940 sub_402940 proc near ; CODE XREF: showstatus+43 p
00402940 ; _TfrmFastDNS_actTestSpendingExecute+138 p
00402940
00402940 var_8 = dword ptr -8
00402940 var_4 = dword ptr -4
00402940 arg_0 = dword ptr 8
00402940 arg_4 = dword ptr 0Ch
00402940
00402940 push ebp
00402941 mov ebp, esp
00402943 add esp, 0FFFFFFF8h
00402946 push ebx
00402947 push esi
00402948 push edi
00402949 mov edi, [ebp+arg_4]
0040294C mov ebx, [ebp+arg_0]
0040294F cmp dword ptr [ebx+400h], 0
00402956 jz short loc_402988
00402958 xor esi, esi
0040295A cmp edi, esi
0040295C jle short loc_402988
0040295E
0040295E loc_40295E: ; CODE XREF: sub_402940+46 j
0040295E push 0
00402960 push 0
00402962 mov [ebp+var_8], offset sub_402748
00402969 mov [ebp+var_4], ebx
0040296C lea eax, [ebp+var_8]
0040296F push dword ptr [eax+4]
00402972 push dword ptr [eax]
00402974 mov ecx, [ebx+400h]
0040297A push ecx
0040297B call sub_40C400
00402980 add esp, 14h
00402983 inc esi
00402984 cmp edi, esi
00402986 jg short loc_40295E
00402988
00402988 loc_402988: ; CODE XREF: sub_402940+16 j
00402988 ; sub_402940+1C j
00402988 pop edi
00402989 pop esi
0040298A pop ebx
0040298B pop ecx
0040298C pop ecx
0040298D pop ebp
0040298E retn
0040298E sub_402940 endp
再往上走就是TfrmFastDNS_actTestSpendingExecute,也就是点击了测试按钮之后的回调函数
004033D4 _TfrmFastDNS_actTestSpendingExecute proc near
004033D4 ; DATA XREF: .data:fastdns___CPPdebugHook+13E3 o
004033D4
004033D4 var_38 = dword ptr -38h
004033D4 var_34 = dword ptr -34h
004033D4 var_30 = dword ptr -30h
004033D4 var_20 = word ptr -20h
004033D4 var_14 = dword ptr -14h
004033D4 var_C = byte ptr -0Ch
004033D4 var_8 = byte ptr -8
004033D4 var_4 = byte ptr -4
004033D4
004033D4 push ebp
004033D5 mov ebp, esp
004033D7 add esp, 0FFFFFFC8h
004033DA push ebx
004033DB mov ebx, eax
004033DD mov eax, offset unk_4A2954
004033E2 call @__InitExceptBlockLDTC
004033E7 xor edx, edx
004033E9 mov eax, [ebx+304h]
004033EF call sub_443028
004033F4 xor edx, edx
004033F6 mov eax, [ebx+364h]
004033FC call sub_443028
00403401 mov byte ptr [ebx+404h], 0
00403408 call @GetCurrentTime
0040340D mov [ebx+3E8h], eax
00403413 mov edx, 8000000Fh
00403418 mov eax, [ebx+350h]
0040341E call @TControl@SetColor ; TControl::SetColor
00403423 mov [ebp+var_20], 8
00403429 mov edx, offset unk_4A22AA
0040342E lea eax, [ebp+var_4]
00403431 call @System@AnsiString@$bctr$qqrpxc ; System::AnsiString::AnsiString(char *)
00403436 inc [ebp+var_14]
00403439 mov edx, [eax]
0040343B mov eax, [ebx+350h]
00403441 call @TControl@SetText ; TControl::SetText
00403446 dec [ebp+var_14]
00403449 lea eax, [ebp+var_4]
0040344C mov edx, 2
00403451 call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
00403456 mov dl, 1
00403458 mov eax, [ebx+35Ch]
0040345E call unknown_libname_1860 ; Delphi2006/BDS2006 Visual Component Library
0040345E ; BDS 4.0 RTL and VCL
00403463 mov [ebp+var_20], 14h
00403469 mov edx, offset unk_4A22AB
0040346E lea eax, [ebp+var_8]
00403471 call @System@AnsiString@$bctr$qqrpxc ; System::AnsiString::AnsiString(char *)
00403476 inc [ebp+var_14]
00403479 mov edx, [eax]
0040347B mov eax, [ebx+34Ch]
00403481 call @TControl@SetText ; TControl::SetText
00403486 dec [ebp+var_14]
00403489 lea eax, [ebp+var_8]
0040348C mov edx, 2
00403491 call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
00403496 xor edx, edx
00403498 mov eax, [ebx+30Ch]
0040349E call sub_443028
004034A3 mov eax, [ebx+400h]
004034A9 test eax, eax
004034AB jz short loc_4034CC
004034AD push 0
004034AF push 0
004034B1 mov [ebp+var_38], offset sub_4033B0
004034B8 mov [ebp+var_34], ebx
004034BB lea edx, [ebp+var_38]
004034BE push dword ptr [edx+4]
004034C1 push dword ptr [edx]
004034C3 push eax
004034C4 call sub_40C400
004034C9 add esp, 14h
004034CC
004034CC loc_4034CC: ; CODE XREF: _TfrmFastDNS_actTestSpendingExecute+D7 j
004034CC xor eax, eax
004034CE xor edx, edx
004034D0 mov [ebx+37Ch], eax
004034D6 lea eax, [ebp+var_C]
004034D9 mov [ebp+var_20], 20h
004034DF call unknown_libname_1523 ; CBuilder 4 and Delphi 4 VCL
004034DF ; CBuilder 5 runtime
004034E4 inc [ebp+var_14]
004034E7 mov edx, [eax]
004034E9 mov eax, [ebx+358h]
004034EF call @TControl@SetText ; TControl::SetText
004034F4 dec [ebp+var_14]
004034F7 lea eax, [ebp+var_C]
004034FA mov edx, 2
004034FF call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
00403504 mov ecx, [ebx+3F4h]
0040350A push ecx
0040350B push ebx
0040350C call sub_402940
00403511 add esp, 8
00403514 mov eax, [ebp+var_30]
00403517 mov large fs:0, eax
0040351D pop ebx
0040351E mov esp, ebp
00403520 pop ebp
00403521 retn
00403521 _TfrmFastDNS_actTestSpendingExecute endp
00403521
可知以下3个函数为关键函数,下断点:
- bp 425690 =>STOP
- bp 40ea3c =>FUNC1
- bp 40970c =>FUNC2
发现正如上面分析那样,调用顺序为FUNC1 -> FUNC2 -> STOP FUNC2通过调用堆栈可以得知是在FUNC1中调用的。先来分析三个函数类型:前面425404已经得知第一个和第二个,先断在425690,看调用栈,通过在上层函数中查看当前函数调用之前的状况粗略分析类型:
0:001> k
ChildEBP RetAddr
WARNING: Stack unwind information not available. Following frames may be wrong.
0273ff74 0043d33a FastDNS!Rtflabelinitialization$qqrv+0xd7d8
0273ff88 76b2919f FastDNS!Rtflabelinitialization$qqrv+0x25482
0273ff94 7745b5af KERNEL32!BaseThreadInitThunk+0xe
0273ffdc 7745b57a ntdll!__RtlUserThreadStart+0x2f
0273ffec 00000000 ntdll!_RtlUserThreadStart+0x1b
0043D311 mov ebp, esp
0043D313 call @System@_16542 ; System::_16542
0043D318 push ebp
0043D319 xor ecx, ecx
0043D31B push offset @System@_16754 ; System::_16754
0043D320 mov edx, fs:[ecx]
0043D323 push edx
0043D324 mov fs:[ecx], esp
0043D327 mov eax, [ebp+arg_0]
0043D32A mov ecx, [eax+4]
0043D32D mov edx, [eax]
0043D32F push ecx
0043D330 push edx
0043D331 call sub_43B5E0
0043D336 pop edx
0043D337 pop eax
0043D338 call edx
0043D33A xor edx, edx
0043D33C pop ecx
0043D33D mov fs:[edx], ecx
0043D340 pop ecx
0043D341 pop ebp
0043D342 pop ebp
0043D343 retn 4
根据栈平衡,同时call edx处可能传递的参数应该在当前call之前,上个call之后,加上调用者代码可以推断使用了eax,没有用到栈参数,其他2函数同理,再到STOP中看:(显然这是终止线程之类的收尾工作,所以这里我取名STOP)
.text:00425690 ; TThread:oTerminate
.text:00425690 @TThread@DoTerminate proc near ; DATA XREF: .text:_cls_Classes_TThread o
.text:00425690 ; .data:_cls_CalcSpendingThread_TCalcSpendingThread o
.text:00425690 cmp word ptr [eax+1Ah], 0
.text:00425695 jz short locret_4256A2
.text:00425697 push eax
.text:00425698 push offset @Controls@TSizeConstraints@Change$qqrv ; Delphi 5 Visual Component Library
.text:00425698 ; Delphi2006/BDS2006 Visual Component Library
.text:0042569D call terminate
.text:004256A2
.text:004256A2 locret_4256A2: ; CODE XREF: TThread:oTerminate+5 j
.text:004256A2 retn
0040EA3C sub_40EA3C proc near ; DATA XREF: .data:fastdns___CPPdebugHook+105D0 o
0040EA3C ; .data:fastdns___CPPdebugHook+11C3C o
0040EA3C
0040EA3C var_14 = dword ptr -14h
0040EA3C var_10 = dword ptr -10h
0040EA3C pertime = dword ptr -0Ch
0040EA3C var_8 = dword ptr -8
0040EA3C a1 = dword ptr -4
0040EA3C
0040EA3C push ebp
0040EA3D mov ebp, esp
0040EA3F add esp, 0FFFFFFECh
0040EA42 mov [ebp+a1], eax
0040EA45 mov eax, [ebp+a1]
0040EA48 mov byte ptr [eax+0Fh], 1
0040EA4C lea edx, [ebp+pertime]
0040EA4F push edx
0040EA50 mov ecx, [ebp+a1]
0040EA53 push dword ptr [ecx+30h]
0040EA56 push [ebp+a1]
0040EA59 call sub_40EAE0
0040EA5E add esp, 0Ch
0040EA61 test al, al
0040EA63 jz short loc_40EA8B
0040EA65 push [ebp+var_8]
0040EA68 push [ebp+pertime]
0040EA6B mov edx, [ebp+a1]
0040EA6E push dword ptr [edx+30h]
0040EA71 call sub_40EABC
0040EA76 add esp, 0Ch
0040EA79 push 0
0040EA7B mov ecx, [ebp+a1]
0040EA7E push dword ptr [ecx+30h]
0040EA81 call sub_40EAD0
0040EA86 add esp, 8
0040EA89 jmp short loc_40EA9B
0040EA8B ; ---------------------------------------------------------------------------
0040EA8B
0040EA8B loc_40EA8B: ; CODE XREF: sub_40EA3C+27 j
0040EA8B push 3
0040EA8D mov eax, [ebp+a1]
0040EA90 push dword ptr [eax+30h]
0040EA93 call sub_40EAD0
0040EA98 add esp, 8
0040EA9B
0040EA9B loc_40EA9B: ; CODE XREF: sub_40EA3C+4D j
0040EA9B mov [ebp+var_14], offset sub_40EA10
0040EAA2 mov edx, [ebp+a1]
0040EAA5 mov [ebp+var_10], edx
0040EAA8 lea ecx, [ebp+var_14]
0040EAAB push dword ptr [ecx+4] ; a5
0040EAAE push dword ptr [ecx] ; a4
0040EAB0 mov eax, [ebp+a1] ; a1
0040EAB3 call terminate
0040EAB8 mov esp, ebp
0040EABA pop ebp
0040EABB retn
0040EAE0 sub_40EAE0 proc near ; CODE XREF: sub_40EA3C+1D p
0040EAE0
0040EAE0 var_40 = qword ptr -40h
0040EAE0 var_38 = dword ptr -38h
0040EAE0 usedtime = qword ptr -34h
0040EAE0 totoaltime = dword ptr -2Ch
0040EAE0 var_28 = dword ptr -28h
0040EAE0 var_18 = word ptr -18h
0040EAE0 var_C = dword ptr -0Ch
0040EAE0 var_4 = byte ptr -4
0040EAE0 arg_0 = dword ptr 8
0040EAE0 arg_4 = dword ptr 0Ch
0040EAE0 arg_8 = dword ptr 10h
0040EAE0
0040EAE0 push ebp
0040EAE1 mov ebp, esp
0040EAE3 add esp, 0FFFFFFC0h
0040EAE6 mov eax, offset unk_4B3C64
0040EAEB call @__InitExceptBlockLDTC
0040EAF0 mov edx, [ebp+arg_0]
0040EAF3 push dword ptr [edx+40h]
0040EAF6 push [ebp+arg_4]
0040EAF9 call unknown_libname_1142 ; CBuilder 5 runtime
0040EAFE add esp, 8
0040EB01 mov [ebp+var_18], 8
0040EB07 lea eax, [ebp+var_4]
0040EB0A call unknown_libname_1128 ; CBuilder 5 runtime
0040EB0F inc [ebp+var_C]
0040EB12 mov [ebp+var_18], 14h
0040EB18 xor edx, edx
0040EB1A mov [ebp+totoaltime], edx
0040EB1D xor ecx, ecx
0040EB1F mov dword ptr [ebp+usedtime+4], ecx
0040EB22 jmp short loc_40EB61
0040EB24 ; ---------------------------------------------------------------------------
0040EB24
0040EB24 loc_40EB24: ; CODE XREF: sub_40EAE0+8A j
0040EB24 lea eax, [ebp+usedtime]
0040EB27 push eax
0040EB28 mov edx, [ebp+arg_0]
0040EB2B push edx
0040EB2C mov ecx, [edx]
0040EB2E call dword ptr [ecx+8]
0040EB31 add esp, 8
0040EB34 test al, al
0040EB36 jz short loc_40EB54
0040EB38 mov eax, dword ptr [ebp+usedtime]
0040EB3B add [ebp+totoaltime], eax
0040EB3E push [ebp+arg_4]
0040EB41 call @AspHlpr@TMTSASPObject@getObjectContext$qv_4 ; CBuilder 5 runtime
0040EB41 ; BCC v4.x/5.x class library 32 bit
0040EB46 pop ecx
0040EB47 dec eax
0040EB48 push eax
0040EB49 push [ebp+arg_4]
0040EB4C call unknown_libname_1142 ; CBuilder 5 runtime
0040EB51 add esp, 8
0040EB54
0040EB54 loc_40EB54: ; CODE XREF: sub_40EAE0+56 j
0040EB54 mov eax, 64h ; dwMilliseconds
0040EB59 call @Sleep
0040EB5E inc dword ptr [ebp+usedtime+4]
0040EB61
0040EB61 loc_40EB61: ; CODE XREF: sub_40EAE0+42 j
0040EB61 mov edx, dword ptr [ebp+usedtime+4]
0040EB64 mov ecx, [ebp+arg_0]
0040EB67 cmp edx, [ecx+40h]
0040EB6A jl short loc_40EB24
0040EB6C push [ebp+arg_4]
0040EB6F call @AspHlpr@TMTSASPObject@getObjectContext$qv_4 ; CBuilder 5 runtime
0040EB6F ; BCC v4.x/5.x class library 32 bit
0040EB74 pop ecx
0040EB75 mov edx, [ebp+arg_0]
0040EB78 cmp eax, [edx+40h]
0040EB7B jz short loc_40EBC9
0040EB7D push [ebp+arg_4]
0040EB80 call @AspHlpr@TMTSASPObject@getObjectContext$qv_4 ; CBuilder 5 runtime
0040EB80 ; BCC v4.x/5.x class library 32 bit
0040EB85 pop ecx
0040EB86 mov ecx, [ebp+arg_0]
0040EB89 mov edx, [ecx+40h]
0040EB8C sub edx, eax
0040EB8E mov [ebp+var_38], edx
0040EB91 fild [ebp+var_38]
0040EB94 mov eax, [ebp+totoaltime]
0040EB97 mov dword ptr [ebp+var_40], eax
0040EB9A xor ecx, ecx
0040EB9C mov dword ptr [ebp+var_40+4], ecx
0040EB9F fild [ebp+var_40]
0040EBA2 fdivrp st(1), st
0040EBA4 mov eax, [ebp+arg_8]
0040EBA7 fstp qword ptr [eax]
0040EBA9 mov al, 1
0040EBAB push eax
0040EBAC dec [ebp+var_C]
0040EBAF lea eax, [ebp+var_4]
0040EBB2 mov edx, 2
0040EBB7 call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
0040EBBC pop eax
0040EBBD mov edx, [ebp+var_28]
0040EBC0 mov large fs:0, edx
0040EBC7 jmp short loc_40EBE7
0040EBC9 ; ---------------------------------------------------------------------------
0040EBC9
0040EBC9 loc_40EBC9: ; CODE XREF: sub_40EAE0+9B j
0040EBC9 xor eax, eax
0040EBCB push eax
0040EBCC dec [ebp+var_C]
0040EBCF lea eax, [ebp+var_4]
0040EBD2 mov edx, 2
0040EBD7 call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
0040EBDC pop eax
0040EBDD mov edx, [ebp+var_28]
0040EBE0 mov large fs:0, edx
0040EBE7
0040EBE7 loc_40EBE7: ; CODE XREF: sub_40EAE0+E7 j
0040EBE7 mov esp, ebp
0040EBE9 pop ebp
0040EBEA retn
0040EBEA sub_40EAE0 endp
可以得知该函数循环执行指定次数的dns连接,使用的时间累加到totaltime中,后面使用该时间计算平均用时,整个程序精华在于
(unsigned __int8)(*(int (__cdecl **)(int, int *))(*(_DWORD *)a1 + 8))(a1, &usedtime)
这个call,实际上是FUNC2,而sub_40EA3C中可以解释为:
0040EA3C sub_40EA3C proc near ; DATA XREF: .data:fastdns___CPPdebugHook+105D0 o
0040EA3C ; .data:fastdns___CPPdebugHook+11C3C o
0040EA3C
0040EA3C var_14 = dword ptr -14h
0040EA3C var_10 = dword ptr -10h
0040EA3C pertime = dword ptr -0Ch
0040EA3C var_8 = dword ptr -8
0040EA3C a1 = dword ptr -4
0040EA3C
0040EA3C push ebp
0040EA3D mov ebp, esp
0040EA3F add esp, 0FFFFFFECh
0040EA42 mov [ebp+a1], eax
0040EA45 mov eax, [ebp+a1]
0040EA48 mov byte ptr [eax+0Fh], 1
0040EA4C lea edx, [ebp+pertime]
0040EA4F push edx
0040EA50 mov ecx, [ebp+a1]
0040EA53 push dword ptr [ecx+30h]
0040EA56 push [ebp+a1]
0040EA59 call sub_40EAE0
0040EA5E add esp, 0Ch
0040EA61 test al, al
0040EA63 jz short loc_40EA8B
0040EA65 push [ebp+var_8]
0040EA68 push [ebp+pertime]
0040EA6B mov edx, [ebp+a1]
0040EA6E push dword ptr [edx+30h]
0040EA71 call sub_40EABC
0040EA76 add esp, 0Ch
0040EA79 push 0
0040EA7B mov ecx, [ebp+a1]
0040EA7E push dword ptr [ecx+30h]
0040EA81 call sub_40EAD0
0040EA86 add esp, 8
0040EA89 jmp short loc_40EA9B
0040EA8B ; ---------------------------------------------------------------------------
0040EA8B
0040EA8B loc_40EA8B: ; CODE XREF: sub_40EA3C+27 j
0040EA8B push 3
0040EA8D mov eax, [ebp+a1]
0040EA90 push dword ptr [eax+30h]
0040EA93 call sub_40EAD0
0040EA98 add esp, 8
0040EA9B
0040EA9B loc_40EA9B: ; CODE XREF: sub_40EA3C+4D j
0040EA9B mov [ebp+var_14], offset sub_40EA10
0040EAA2 mov edx, [ebp+a1]
0040EAA5 mov [ebp+var_10], edx
0040EAA8 lea ecx, [ebp+var_14]
0040EAAB push dword ptr [ecx+4] ; a5
0040EAAE push dword ptr [ecx] ; a4
0040EAB0 mov eax, [ebp+a1] ; a1
0040EAB3 call terminate
0040EAB8 mov esp, ebp
0040EABA pop ebp
0040EABB retn
现在同时推测param类结构,可知
+00h virtualtable
+0 STOP
+4 FUNC1
+8 FUNC2
+04h HANDLE hthread ??
+0Fh bool Initaled ??
+10h
+18h FARPROC func0
+1Ch LPVOID param0
+20h FARPROC func1//OnIdle处理函数
+24h LPVOID param1
+28h BOOL IsMainthread??
+30h struct*
+00h int leftTime//剩余次数
+08h double pertime//平均消耗时间
+10h flag statu //成功0 失败3
+38h FARPROC func2
+3Ch DWORD param2
+40h int repeatTime//取样次数
+44h int timeout//超时
得到设置DNS逻辑
通过字符串搜索,可以定位到TfrmSetDNS_btnConfirmClick函数为点击了设置dns窗口的“设置”按钮后回调函数
__int32 *__fastcall TfrmSetDNS_btnConfirmClick(int a1, int a2)
{
v32 = a2;
v33 = a1;
__InitExceptBlockLDTC();
v31 = &v48;
v52 = 0;
v53 = 0;
v54 = 0;
v36 += 4;
v35 = 8;
for ( i = 0; i < (*(int (**)(void))(**(_DWORD **)(*(_DWORD *)(v33 + 772) + 536) + 20))(); ++i )// 0044a604 GetCount 选中DNS地址个数
{
v35 = 44;
v3 = *(_DWORD *)(v33 + 0x304);
addrstring = 0;
++v36;
(*(void (__fastcall **)(_DWORD, int, int *))(**(_DWORD **)(v3 + 0x218)
+ 12))(// 0044a620 getaddrstring 获取地址文本串
*(_DWORD *)(v3 + 0x218),
i,
&addrstring);
if ( v53 == v54 )
{
sub_403C34((int)&v52, v53, (int)&addrstring, (int)&v30, 1u, 1);
}
else
{
v46 = v53;
if ( v53 )
{
v35 = 56;
System::AnsiString::AnsiString(v46, &addrstring);
v35 = 44;
}
v53 += 4;
}
--v36;
System::AnsiString::~AnsiString(&addrstring, 2);
}
++v36;
v29 = &v45;
v49 = 0;
v50 = 0;
++v36;
v51 = 0;
++v36;
++v36;
++v36;
--v36;
v35 = 8;
for ( j = 0; j < (*(int (**)(void))(**(_DWORD **)(*(_DWORD *)(v33 + 768) + 536) + 20))(); ++j )// 对于网卡列表中的每一项
{
if ( (unsigned __int8)TCheckListBox::GetChecked(*(_DWORD *)(v33 + 768), j) )// 如果复选框选中
{
v35 = 92;
v5 = *(_DWORD *)(v33 + 768);
v44 = 0;
++v36;
(*(void (__fastcall **)(_DWORD, int, int *))(**(_DWORD **)(v5 + 536) + 12))(*(_DWORD *)(v5 + 536), j, &v44);// 获取网卡名称
if ( v50 == v51 )
{
sub_403C34((int)&v49, v50, (int)&v44, (int)&v28, 1u, 1);
}
else
{
v43 = v50;
if ( v50 )
{
v35 = 104;
System::AnsiString::AnsiString(v43, &v44);
v35 = 92;
}
v50 += 4;
}
--v36;
System::AnsiString::~AnsiString(&v44, 2);
}
}
if ( (unsigned int)((v53 - v52) / 4) <= 50 ) // 如果选中dns地址小于50个
{
if ( (v50 - v49) / 4 ) // 如果选中了网卡
{
v35 = 284;
v10 = sub_407DCC((int)off_4A4404, 1, v33);
sub_407F6C(v10, (int)&v49, (int)&v52);
(*(void (**)(void))(*(_DWORD *)v10 + 0xE8))();// 004670dc showmodel and setsetting 设置dns并显示进度
*(_BYTE *)(v33 + 776) = (unsigned int)*(_BYTE *)(v10 + 776) < 1;
v35 = 8;
v37 = v10;
if ( v10 )
{
v38 = *(_DWORD *)v10;
v35 = 308;
(*(void (__fastcall **)(int, signed int))(*(_DWORD *)v37 - 4))(v37, 3);
v35 = 296;
}
sub_466E84(v33);
--v36;
sub_403254(v49, v50);
v35 = 8;
--v36;
v9 = (v51 - v49) / 4;
if ( v49 )
{
v8 = 4 * v9;
if ( (unsigned int)(4 * v9) <= 0x80 )
sub_4A0CA4(v49, v8);
else
_rtl_close(v49);
}
--v36;
--v36;
--v36;
sub_403254(v52, v53);
--v36;
result = (__int32 *)v52;
v7 = (v54 - v52) / 4;
if ( v52 )
{
if ( (unsigned int)(4 * v7) <= 0x80 )
result = sub_4A0CA4(v52, 4 * v7);
else
result = (__int32 *)_rtl_close(v52);
}
}
else
{
v35 = 200;
++v36;
FormatString(&v39, (char *)"请至少选择一个连接。");
v36 += 4;
MessageBox((int)&v39);
--v36;
v35 = 8;
--v36;
v19 = v40 - v39;
if ( v39 )
{
if ( (unsigned int)v19 <= 0x80 )
sub_4A0CA4(v39, v19);
else
_rtl_close(v39);
}
--v36;
--v36;
--v36;
(*(void (**)(void))(**(_DWORD **)(v33 + 768) + 192))();
--v36;
v18 = v50;
v17 = v49;
sub_403254(v49, v50);
--v36;
v16 = (v51 - v49) / 4;
if ( v49 )
{
v15 = 4 * v16;
if ( (unsigned int)(4 * v16) <= 0x80 )
sub_4A0CA4(v49, v15);
else
_rtl_close(v49);
}
--v36;
--v36;
--v36;
v14 = v53;
v13 = v52;
sub_403254(v52, v53);
--v36;
v12 = (v54 - v52) / 4;
if ( v52 )
{
v11 = 4 * v12;
if ( (unsigned int)(4 * v12) <= 0x80 )
sub_4A0CA4(v52, v11);
else
_rtl_close(v52);
}
--v36;
--v36;
result = v34;
}
}
else
{
v35 = 116;
++v36;
FormatString(&handle, "选中的DNS地址数量过多。\n只允许选择不超过50个的DNS地址。");
v36 += 4;
MessageBox((int)&handle);
--v36;
v35 = 8;
--v36;
v27 = v42 - handle;
if ( handle )
{
if ( (unsigned int)v27 <= 0x80 )
sub_4A0CA4(handle, v27);
else
_rtl_close(handle);
}
--v36;
--v36;
--v36;
(*(void (**)(void))(**(_DWORD **)(v33 + 764) + 192))();
--v36;
v26 = v50;
v25 = v49;
sub_403254(v49, v50);
--v36;
v24 = (v51 - v49) / 4;
if ( v49 )
{
if ( (unsigned int)(4 * v24) <= 0x80 )
sub_4A0CA4(v49, 4 * v24);
else
_rtl_close(v49);
}
--v36;
--v36;
--v36;
v23 = v53;
v22 = v52;
result = (__int32 *)sub_403254(v52, v53);
--v36;
v21 = (v54 - v52) / 4;
if ( v52 )
{
v20 = 4 * v21;
if ( (unsigned int)(4 * v21) <= 0x80 )
result = sub_4A0CA4(v52, v20);
else
result = (__int32 *)_rtl_close(v52);
}
--v36;
--v36;
}
return result;
}
(*(void (**)(void))(*(_DWORD *)v10 + 0xE8))()
通过消息机制最终调用了_TfrmSetDNSProccess_tmrStartTimer
,该函数真正执行设置dns:
对于每个网卡接口
00407F88先清除dns
netsh interface ip set dns name="??网" source=static addr=none
对于每个dns地址
004082F4逐个添加dns
netsh interface ip add dns name="??网" addr=??.??.??.??
int __fastcall TfrmSetDNSProccess_tmrStartTimer(int a1)
{
int v1; // ebx@1
int i; // edi@1
int v3; // ST0C_4@2
int *v4; // eax@2
int v5; // esi@4
int v6; // ST0C_4@5
int v7; // ST08_4@5
int *v8; // eax@5
int v10; // [sp+Ch] [bp-30h]@4
int v11; // [sp+34h] [bp-8h]@5
int v12; // [sp+38h] [bp-4h]@2
v1 = a1;
__InitExceptBlockLDTC();
unknown_libname_1860(*(_DWORD *)(v1 + 760), 0);
sub_486B60(*(_DWORD *)(v1 + 752), 1);
sub_486B6C(
*(_DWORD *)(v1 + 752),
((*(_DWORD *)(*(_DWORD *)(v1 + 768) + 4) - **(_DWORD **)(v1 + 768)) / 4 + 1)
* ((*(_DWORD *)(*(_DWORD *)(v1 + 764) + 4) - **(_DWORD **)(v1 + 764))
/ 4));
for ( i = **(_DWORD **)(v1 + 764); i != *(_DWORD *)(*(_DWORD *)(v1 + 764) + 4); i += 4 )
{
v3 = *(_DWORD *)i;
v12 = 0;
v4 = (int *)System::AnsiString::sprintf(&v12, (const char *)&unk_4A40BB, v3);
TControl::SetText(*(_DWORD *)(v1 + 756), *v4);// 显示清除原有设置
System::AnsiString::~AnsiString(&v12, 2);
TApplication::ProcessMessages(*off_4B9450[0]);
if ( !cleardns(v1, i) )
{
*(_BYTE *)(v1 + 776) = 1;
return sub_466E84(v1);
}
TProgressBar::StepBy(*(_DWORD *)(v1 + 752), 1);// 更新进度条
v5 = **(_DWORD **)(v1 + 768);
v10 = 1;
while ( v5 != *(_DWORD *)(*(_DWORD *)(v1 + 768) + 4) )
{
v6 = *(_DWORD *)v5;
v7 = *(_DWORD *)i;
v11 = 0;
v8 = (int *)System::AnsiString::sprintf(&v11, (const char *)&unk_4A40D9, v7, v6);
TControl::SetText(*(_DWORD *)(v1 + 756), *v8);// 显示正在写入dns
System::AnsiString::~AnsiString(&v11, 2);
TApplication::ProcessMessages(*off_4B9450[0]);
if ( adddns(v1, i, v5, v10) )
++v10;
TProgressBar::StepBy(*(_DWORD *)(v1 + 752), 1);
v5 += 4;
}
}
return sub_466E84(v1);
}
bool __cdecl cleardns(int a1, int a2)
{
__InitExceptBlockLDTC();
qmemcpy(&v17, &unk_4A3F18, 0x40u);
do
{
v15 = 2;
ExitCode = -1;
v10 = *(_DWORD *)(a1 + 772);
v18 = 8;
++v19;
v9 = *(_DWORD *)a2;
v32 = 0;
++v19;
sub_40CA68((int)&v32, (int)&v17, 64);
if ( v32 )
v2 = v32;
else
v2 = (const char *)&unk_4A3F8E;
v31 = 0;
++v19;
v14 = (char **)System::AnsiString::sprintf(&v31, v2, v9);// 构造netsh命令
if ( *v14 )
v3 = *v14;
else
v3 = (char *)&unk_4A3F8F;
FormatString(&v29, v3);
v19 += 4;
++v19;
v28 = 0;
++v19;
unknown_libname_1857(*off_4B9450[0], &v28);
s = 0;
++v19;
ExtractFilePath(v28, &s);
if ( s )
v4 = s;
else
v4 = (char *)&unk_4A3F8D;
FormatString(&handle, v4);
v19 += 4;
v11 = (unsigned __int8)sub_40E30C((int)&handle, (int)&v29, v10, &ExitCode) < 1u;// CreateProcess netsh程序
--v19;
--v19;
v13 = v26 - handle;
if ( handle )
{
if ( (unsigned int)v13 <= 0x80 )
sub_4A0CA4(handle, v13);
else
_rtl_close(handle);
}
--v19;
--v19;
--v19;
--v19;
System::AnsiString::~AnsiString(&s, 2);
--v19;
System::AnsiString::~AnsiString(&v28, 2);
--v19;
--v19;
v12 = v30 - v29;
if ( v29 )
{
if ( (unsigned int)v12 <= 0x80 )
sub_4A0CA4(v29, v12);
else
_rtl_close(v29);
}
--v19;
--v19;
--v19;
--v19;
System::AnsiString::~AnsiString(&v32, 2);
--v19;
System::AnsiString::~AnsiString(&v31, 2);
if ( v11 )
{
v18 = 68;
v5 = System::AnsiString::AnsiString(&v24, &unk_4A3F90);// 调用的动态库不存在。
++v19;
(*(void (__fastcall **)(_DWORD, _DWORD))(**(_DWORD **)(a1 + 772) + 44))(*(_DWORD *)(a1 + 772), *(_DWORD *)v5);
--v19;
System::AnsiString::~AnsiString(&v24, 2);
ExitCode = 9999;
}
if ( ExitCode )
{
v18 = 80;
++v19;
v23 = 0; // 设置中遇到问题。设置停止。.若不能解决问题,测试结果仍然有效,可据此在网络属性中手工设置DNS。
++v19;
(*(void (__fastcall **)(_DWORD, int *))(**(_DWORD **)(a1 + 772) + 28))(*(_DWORD *)(a1 + 772), &v23);
v22 = 0;
++v19;
v6 = (char **)System::AnsiString::sprintf(&v22, (const char *)&unk_4A3FA5, v23);
if ( *v6 )
v7 = *v6;
else
v7 = (char *)&unk_4A40AA;
FormatString(&v20, v7);
v19 += 4;
v15 = sub_40E26C((int)&v20, 64, 5, 0, 0);
--v19;
--v19;
if ( v20 )
{
if ( (unsigned int)(v21 - v20) <= 0x80 )
sub_4A0CA4(v20, v21 - v20);
else
_rtl_close(v20);
}
--v19;
--v19;
--v19;
--v19;
System::AnsiString::~AnsiString(&v23, 2);
--v19;
System::AnsiString::~AnsiString(&v22, 2);
}
}
while ( v15 == 4 );
return ExitCode == 0;
}
adddns可类似分析,这里不再赘述
FASTDNS如何列出网卡的?
开始以为是找注册表,但是procmon无结果,后来还是根据字符串找到了下面的函数,该函数为设置dns的回调:
text:00403524 _TfrmFastDNS_actSetDNSExecute proc near ; DATA XREF: .data:fastdns___CPPdebugHook+1400 o
text:00403524 var_58 = dword ptr -58h
text:00403524 var_54 = dword ptr -54h
text:00403524 var_44 = word ptr -44h
text:00403524 var_38 = dword ptr -38h
text:00403524 var_30 = dword ptr -30h
text:00403524 var_2C = dword ptr -2Ch
text:00403524 handle = dword ptr -28h
text:00403524 var_18 = dword ptr -18h
text:00403524 var_10 = byte ptr -10h
text:00403524 var_8 = byte ptr -8
text:00403524 var_4 = byte ptr -4
text:00403524
text:00403524 push ebp
text:00403525 mov ebp, esp
text:00403527 add esp, 0FFFFFFA8h
text:0040352A push ebx
text:0040352B push esi
text:0040352C push edi
text:0040352D mov ebx, eax
text:0040352F mov eax, offset unk_4A29EC
text:00403534 call @__InitExceptBlockLDTC
text:00403539 mov [ebp+var_44], 8
text:0040353F mov edx, offset unk_4A22C4
text:00403544 lea eax, [ebp+var_4]
text:00403547 call @System@AnsiString@$bctr$qqrpxc ; System::AnsiString::AnsiString(char *)
text:0040354C inc [ebp+var_38]
text:0040354F mov edx, [eax]
text:00403551 mov eax, [ebx+34Ch]
text:00403557 call @TControl@SetText ; TControl::SetText
text:0040355C dec [ebp+var_38]
text:0040355F lea eax, [ebp+var_4]
text:00403562 mov edx, 2
text:00403567 call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
text:0040356C xor ecx, ecx
text:0040356E mov dl, 1
text:00403570 mov [ebp+var_58], ecx
text:00403573 mov ecx, ebx
text:00403575 mov [ebp+var_44], 14h
text:0040357B mov eax, off_4A3D2C
text:00403580 call sub_40738C
text:00403585 mov [ebp+var_58], eax
text:00403588 mov eax, [ebx+340h]
text:0040358E call @TCustomListView@GetSelection ; TCustomListView::GetSelection
text:00403593 test eax, eax
text:00403595 jz loc_403642
text:0040359B mov edx, [ebp+var_58]
text:0040359E mov eax, [edx+304h]
text:004035A4 mov edx, [eax]
text:004035A6 call dword ptr [edx+0D4h]
text:004035AC mov [ebp+var_44], 14h
text:004035B2 xor esi, esi
text:004035B4 jmp short loc_403629
text:004035B6 ; ---------------------------------------------------------------------------
text:004035B6
text:004035B6 loc_4035B6: ; CODE XREF: _TfrmFastDNS_actSetDNSExecute+118 j
text:004035B6 mov eax, [ebx+340h]
text:004035BC mov edx, esi
text:004035BE mov eax, [eax+22Ch]
text:004035C4 call sub_48A1E4
text:004035C9 mov edx, 3
text:004035CE call @TListItem@GetState ; TListItem::GetState
text:004035D3 test al, al
text:004035D5 jz short loc_403628
text:004035D7 mov eax, [ebp+var_58]
text:004035DA mov edx, esi
text:004035DC mov edi, [eax+304h]
text:004035E2 mov [ebp+var_44], 20h
text:004035E8 mov eax, [ebx+340h]
text:004035EE add edi, 218h
text:004035F4 mov eax, [eax+22Ch]
text:004035FA call sub_48A1E4
text:004035FF mov edx, eax
text:00403601 lea eax, [ebp+var_8]
text:00403604 add edx, 24h
text:00403607 call @System@AnsiString@$bctr$qqrrx17System@AnsiString ; System::AnsiString::AnsiString(System::AnsiString &)
text:0040360C inc [ebp+var_38]
text:0040360F mov edx, [eax]
text:00403611 mov eax, [edi]
text:00403613 mov ecx, [eax]
text:00403615 call dword ptr [ecx+38h]
text:00403618 dec [ebp+var_38]
text:0040361B lea eax, [ebp+var_8]
text:0040361E mov edx, 2
text:00403623 call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
text:00403628
text:00403628 loc_403628: ; CODE XREF: _TfrmFastDNS_actSetDNSExecute+B1 j
text:00403628 inc esi
text:00403629
text:00403629 loc_403629: ; CODE XREF: _TfrmFastDNS_actSetDNSExecute+90 j
text:00403629 mov ecx, [ebx+340h]
text:0040362F mov eax, [ecx+22Ch]
text:00403635 call @TListItems@GetCount ; TListItems::GetCount
text:0040363A cmp esi, eax
text:0040363C jl loc_4035B6
text:00403642
text:00403642 loc_403642: ; CODE XREF: _TfrmFastDNS_actSetDNSExecute+71 j
text:00403642 mov eax, [ebp+var_58]
text:00403645 mov edx, [eax]
text:00403647 call dword ptr [edx+0E8h]
text:0040364D mov ecx, [ebp+var_58]
text:00403650 cmp byte ptr [ecx+308h], 0
text:00403657 jz short loc_4036C3
text:00403659 mov [ebp+var_44], 2Ch
text:0040365F lea eax, [ebp+var_10]
text:00403662 lea edx, [ebp+handle]
text:00403665 push eax
text:00403666 inc [ebp+var_38]
text:00403669 push offset aSDnsBg ; "设置DNS完成。"
text:0040366E push edx ; _DWORD
text:0040366F call FormatString
text:00403674 add esp, 0Ch
text:00403677 lea ecx, [ebp+handle]
text:0040367A add [ebp+var_38], 4
text:0040367E push ecx
text:0040367F call MessageBox
text:00403684 pop ecx
text:00403685 dec [ebp+var_38]
text:00403688 mov [ebp+var_44], 14h
text:0040368E dec [ebp+var_38]
text:00403691 mov esi, [ebp+var_18]
text:00403694 mov eax, [ebp+handle]
text:00403697 sub esi, eax
text:00403699 mov ebx, eax
text:0040369B test ebx, ebx
text:0040369D jz short loc_4036BA
text:0040369F cmp esi, 80h
text:004036A5 jbe short loc_4036B0
text:004036A7 push ebx ; handle
text:004036A8 call __rtl_close
text:004036AD pop ecx
text:004036AE jmp short loc_4036BA
text:004036B0 ; ---------------------------------------------------------------------------
text:004036B0
text:004036B0 loc_4036B0: ; CODE XREF: _TfrmFastDNS_actSetDNSExecute+181 j
text:004036B0 push esi
text:004036B1 push ebx
text:004036B2 call sub_4A0CA4
text:004036B7 add esp, 8
text:004036BA
text:004036BA loc_4036BA: ; CODE XREF: _TfrmFastDNS_actSetDNSExecute+179 j
text:004036BA ; _TfrmFastDNS_actSetDNSExecute+18A j
text:004036BA dec [ebp+var_38]
text:004036BD dec [ebp+var_38]
text:004036C0 dec [ebp+var_38]
text:004036C3
text:004036C3 loc_4036C3: ; CODE XREF: _TfrmFastDNS_actSetDNSExecute+133 j
text:004036C3 mov [ebp+var_44], 0
text:004036C9 jmp short loc_4036D6
text:004036CB ; ---------------------------------------------------------------------------
text:004036CB
text:004036CB loc_4036CB: ; DATA XREF: .data:fastdns___CPPdebugHook+8F0 o
text:004036CB mov [ebp+var_44], 1Ch
text:004036D1 call @_CatchCleanup$qv ; _CatchCleanup(void)
text:004036D6
text:004036D6 loc_4036D6: ; CODE XREF: _TfrmFastDNS_actSetDNSExecute+1A5 j
text:004036D6 mov ebx, [ebp+var_58]
text:004036D9 mov [ebp+var_30], ebx
text:004036DC test ebx, ebx
text:004036DE jz short loc_4036FE
text:004036E0 mov eax, [ebx]
text:004036E2 mov [ebp+var_2C], eax
text:004036E5 mov [ebp+var_44], 5Ch
text:004036EB mov edx, 3
text:004036F0 mov eax, [ebp+var_30]
text:004036F3 mov ecx, [eax]
text:004036F5 call dword ptr [ecx-4]
text:004036F8 mov [ebp+var_44], 50h
text:004036FE
text:004036FE loc_4036FE: ; CODE XREF: _TfrmFastDNS_actSetDNSExecute+1BA j
text:004036FE mov edx, [ebp+var_54]
text:00403701 mov large fs:0, edx
text:00403708 pop edi
text:00403709 pop esi
text:0040370A pop ebx
text:0040370B mov esp, ebp
text:0040370D pop ebp
text:0040370E retn
text:0040370E _TfrmFastDNS_actSetDNSExecute endp
t
text:0040738C sub_40738C proc near ; CODE XREF: _TfrmFastDNS_actSetDNSExecute+5C p
text:0040738C ; DATA XREF: .data:fastdns___CPPdebugHook+1D0C o
text:0040738C
text:0040738C var_54 = byte ptr -54h
text:0040738C var_49 = byte ptr -49h
text:0040738C var_48 = dword ptr -48h
text:0040738C var_38 = word ptr -38h
text:0040738C var_2C = dword ptr -2Ch
text:0040738C var_28 = byte ptr -28h
text:0040738C var_1C = byte ptr -1Ch
text:0040738C var_4 = dword ptr -4
text:0040738C
text:0040738C push ebp
text:0040738D mov ebp, esp
text:0040738F add esp, 0FFFFFFACh
text:00407392 push ebx
text:00407393 push esi
text:00407394 push edi
text:00407395 mov [ebp+var_28], dl
text:00407398 test dl, dl
text:0040739A jle short loc_4073A1
text:0040739C call __ClassCreate
text:004073A1
text:004073A1 loc_4073A1: ; CODE XREF: sub_40738C+E j
text:004073A1 mov ebx, ecx
text:004073A3 mov [ebp+var_49], dl
text:004073A6 mov [ebp+var_4], eax
text:004073A9 lea esi, [ebp+var_1C]
text:004073AC mov eax, offset unk_4A3A70
text:004073B1 call @__InitExceptBlockLDTC
text:004073B6 mov [ebp+var_38], 8
text:004073BC mov ecx, ebx
text:004073BE xor edx, edx
text:004073C0 mov eax, [ebp+var_4]
text:004073C3 call sub_401EFC
text:004073C8 add [ebp+var_2C], 10h
text:004073CC mov edx, [ebp+var_4]
text:004073CF xor ecx, ecx
text:004073D1 xor eax, eax
text:004073D3 mov byte ptr [edx+308h], 0
text:004073DA mov [ebp+var_38], 20h
text:004073E0 inc [ebp+var_2C]
text:004073E3 mov [esi], ecx
text:004073E5 mov [esi+4], eax
text:004073E8 xor edx, edx
text:004073EA inc [ebp+var_2C]
text:004073ED mov [esi+10h], edx
text:004073F0 inc [ebp+var_2C]
text:004073F3 inc [ebp+var_2C]
text:004073F6 inc [ebp+var_2C]
text:004073F9 dec [ebp+var_2C]
text:004073FC mov [ebp+var_38], 14h
text:00407402 push esi
text:00407403 call sub_4071FC
text:00407408 pop ecx
text:00407409 mov ebx, [esi]
text:0040740B jmp short loc_407427
text:0040740D ; ---------------------------------------------------------------------------
text:0040740D
text:0040740D loc_40740D: ; CODE XREF: sub_40738C+9E j
text:0040740D mov eax, [ebp+var_4]
text:00407410 mov eax, [eax+300h]
text:00407416 add eax, 218h
text:0040741B mov edx, [ebx]
text:0040741D mov eax, [eax]
text:0040741F mov ecx, [eax]
text:00407421 call dword ptr [ecx+38h]
text:00407424 add ebx, 4
text:00407427
text:00407427 loc_407427: ; CODE XREF: sub_40738C+7F j
text:00407427 cmp ebx, [esi+4]
text:0040742A jnz short loc_40740D
text:0040742C dec [ebp+var_2C]
text:0040742F lea ecx, [ebp+var_54]
text:00407432 mov eax, [esi+4]
text:00407435 mov edx, [esi]
text:00407437 push ecx
text:00407438 push eax
text:00407439 push edx
text:0040743A call sub_403254
text:0040743F mov [ebp+var_38], 14h
text:00407445 dec [ebp+var_2C]
text:00407448 add esp, 0Ch
text:0040744B mov edi, [esi+10h]
text:0040744E mov eax, [esi]
text:00407450 sub edi, eax
text:00407452 test edi, edi
text:00407454 jns short loc_407459
text:00407456 add edi, 3
text:00407459
text:00407459 loc_407459: ; CODE XREF: sub_40738C+C8 j
text:00407459 sar edi, 2
text:0040745C mov ebx, eax
text:0040745E test ebx, ebx
text:00407460 jz short loc_407482
text:00407462 mov esi, edi
text:00407464 shl esi, 2
text:00407467 cmp esi, 80h
text:0040746D jbe short loc_407478
text:0040746F push ebx ; handle
text:00407470 call __rtl_close
text:00407475 pop ecx
text:00407476 jmp short loc_407482
text:00407478 ; ---------------------------------------------------------------------------
text:00407478
text:00407478 loc_407478: ; CODE XREF: sub_40738C+E1 j
text:00407478 push esi
text:00407479 push ebx
text:0040747A call sub_4A0CA4
text:0040747F add esp, 8
text:00407482
text:00407482 loc_407482: ; CODE XREF: sub_40738C+D4 j
text:00407482 ; sub_40738C+EA j
text:00407482 dec [ebp+var_2C]
text:00407485 dec [ebp+var_2C]
text:00407488 mov [ebp+var_38], 8
text:0040748E mov eax, [ebp+var_48]
text:00407491 mov large fs:0, eax
text:00407497 mov eax, [ebp+var_4]
text:0040749A cmp [ebp+var_49], 0
text:0040749E jz short loc_4074A5
text:004074A0 call @@AfterConstruction ; __AfterConstruction
text:004074A5
text:004074A5 loc_4074A5: ; CODE XREF: sub_40738C+112 j
text:004074A5 pop edi
text:004074A6 pop esi
text:004074A7 pop ebx
text:004074A8 mov esp, ebp
text:004074AA pop ebp
text:004074AB retn
text:004074AB sub_40738C endp
text:004074AB
text:004071FC sub_4071FC proc near ; CODE XREF: showstatus+374 p
text:004071FC ; sub_40738C+77 p
text:004071FC
text:004071FC var_54 = byte ptr -54h
text:004071FC var_4C = dword ptr -4Ch
text:004071FC SizePointer = dword ptr -48h
text:004071FC var_44 = byte ptr -44h
text:004071FC var_3C = byte ptr -3Ch
text:004071FC var_34 = dword ptr -34h
text:004071FC var_30 = dword ptr -30h
text:004071FC var_20 = word ptr -20h
text:004071FC var_14 = dword ptr -14h
text:004071FC var_C = dword ptr -0Ch
text:004071FC var_8 = byte ptr -8
text:004071FC var_4 = dword ptr -4
text:004071FC arg_0 = dword ptr 8
text:004071FC
text:004071FC push ebp
text:004071FD mov ebp, esp
text:004071FF add esp, 0FFFFFFACh
text:00407202 mov eax, offset unk_4A39F0
text:00407207 push ebx
text:00407208 push esi
text:00407209 push edi
text:0040720A mov ebx, [ebp+arg_0]
text:0040720D call @__InitExceptBlockLDTC
text:00407212 mov edi, [ebx+4]
text:00407215 mov esi, [ebx]
text:00407217 mov eax, [ebx+4]
text:0040721A lea edx, [ebp+var_3C]
text:0040721D mov [ebp+var_34], eax
text:00407220 push 0
text:00407222 push edx
text:00407223 push esi
text:00407224 mov ecx, [ebp+var_34]
text:00407227 push ecx
text:00407228 push edi
text:00407229 call sub_403BF8
text:0040722E add esp, 14h
text:00407231 mov edi, eax
text:00407233 mov eax, [ebx+4]
text:00407236 mov edx, edi
text:00407238 lea ecx, [ebp+var_44]
text:0040723B push ecx
text:0040723C push eax
text:0040723D push edx
text:0040723E call sub_403254
text:00407243 add esp, 0Ch
text:00407246 mov [ebx+4], edi
text:00407249 mov [ebp+var_20], 8
text:0040724F push 280h
text:00407254 call @$bnwa$qui ; operator new[](uint)
text:00407259 pop ecx
text:0040725A mov edi, eax
text:0040725C mov [ebp+SizePointer], 280h
text:00407263 mov [ebp+var_20], 8
text:00407269 lea eax, [ebp+SizePointer]
text:0040726C push eax ; SizePointer
text:0040726D push edi ; AdapterInfo
text:0040726E call GetAdaptersInfo
text:00407273 cmp eax, 6Fh
text:00407276 jnz short loc_40728B
text:00407278 push edi ; handle
text:00407279 call __close
text:0040727E pop ecx
text:0040727F mov edx, [ebp+SizePointer]
text:00407282 push edx
text:00407283 call @$bnwa$qui ; operator new[](uint)
text:00407288 pop ecx
text:00407289 mov edi, eax
text:0040728B
text:0040728B loc_40728B: ; CODE XREF: sub_4071FC+7A j
text:0040728B lea eax, [ebp+SizePointer]
text:0040728E push eax ; SizePointer
text:0040728F push edi ; AdapterInfo
text:00407290 call GetAdaptersInfo
text:00407295 test eax, eax
text:00407297 jnz loc_40735D
text:0040729D mov esi, edi
text:0040729F test esi, esi
text:004072A1 jz loc_40735D
text:004072A7
text:004072A7 loc_4072A7: ; CODE XREF: sub_4071FC+15B j
text:004072A7 mov [ebp+var_20], 20h
text:004072AD lea edx, [esi+8]
text:004072B0 lea eax, [ebp+var_8]
text:004072B3 call @System@AnsiString@$bctr$qqrpxc ; System::AnsiString::AnsiString(char *)
text:004072B8 inc [ebp+var_14]
text:004072BB lea ecx, [ebp+var_8]
text:004072BE push ecx
text:004072BF xor eax, eax
text:004072C1 mov [ebp+var_4], eax
text:004072C4 lea edx, [ebp+var_4]
text:004072C7 push edx
text:004072C8 inc [ebp+var_14]
text:004072CB call sub_406FD8
text:004072D0 add esp, 8
text:004072D3 dec [ebp+var_14]
text:004072D6 lea eax, [ebp+var_8]
text:004072D9 mov edx, 2
text:004072DE call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
text:004072E3 mov [ebp+var_20], 14h
text:004072E9 cmp [ebp+var_4], 0
text:004072ED jz short loc_40733D
text:004072EF mov ecx, [ebx+4]
text:004072F2 cmp ecx, [ebx+10h]
text:004072F5 jz short loc_407324
text:004072F7 mov eax, [ebx+4]
text:004072FA mov [ebp+var_4C], eax
text:004072FD mov edx, [ebp+var_4C]
text:00407300 mov [ebp+var_C], edx
text:00407303 test edx, edx
text:00407305 jz short loc_40731E
text:00407307 mov [ebp+var_20], 38h
text:0040730D lea edx, [ebp+var_4]
text:00407310 mov eax, [ebp+var_C]
text:00407313 call @System@AnsiString@$bctr$qqrrx17System@AnsiString ; System::AnsiString::AnsiString(System::AnsiString &)
text:00407318 mov [ebp+var_20], 2Ch
text:0040731E
text:0040731E loc_40731E: ; CODE XREF: sub_4071FC+109 j
text:0040731E add dword ptr [ebx+4], 4
text:00407322 jmp short loc_40733D
text:00407324 ; ---------------------------------------------------------------------------
text:00407324
text:00407324 loc_407324: ; CODE XREF: sub_4071FC+F9 j
text:00407324 push 1
text:00407326 push 1
text:00407328 lea ecx, [ebp+var_54]
text:0040732B push ecx
text:0040732C lea eax, [ebp+var_4]
text:0040732F push eax
text:00407330 mov edx, [ebx+4]
text:00407333 push edx
text:00407334 push ebx
text:00407335 call sub_403C34
text:0040733A add esp, 18h
text:0040733D
text:0040733D loc_40733D: ; CODE XREF: sub_4071FC+F1 j
text:0040733D ; sub_4071FC+126 j
text:0040733D mov esi, [esi]
text:0040733F dec [ebp+var_14]
text:00407342 lea eax, [ebp+var_4]
text:00407345 mov edx, 2
text:0040734A call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
text:0040734F mov [ebp+var_20], 8
text:00407355 test esi, esi
text:00407357 jnz loc_4072A7
text:0040735D
text:0040735D loc_40735D: ; CODE XREF: sub_4071FC+9B j
text:0040735D ; sub_4071FC+A5 j
text:0040735D mov [ebp+var_20], 0
text:00407363 jmp short loc_407372
text:00407365 ; ---------------------------------------------------------------------------
text:00407365
text:00407365 loc_407365: ; DATA XREF: .data:fastdns___CPPdebugHook+1904 o
text:00407365 xor edi, edi
text:00407367 mov [ebp+var_20], 10h
text:0040736D call @_CatchCleanup$qv ; _CatchCleanup(void)
text:00407372
text:00407372 loc_407372: ; CODE XREF: sub_4071FC+167 j
text:00407372 push edi ; handle
text:00407373 call __close
text:00407378 pop ecx
text:00407379 mov eax, [ebp+var_30]
text:0040737C mov large fs:0, eax
text:00407382 pop edi
text:00407383 pop esi
text:00407384 pop ebx
text:00407385 mov esp, ebp
text:00407387 pop ebp
text:00407388 retn
这里可以看到是用GetAdapterInfo得到的,得到的每个AdapterName再送到sub_406FDB中检查:
int __cdecl sub_406FD8(int a1, int a2)
{
__InitExceptBlockLDTC();
v15 = 0;
v7 = TRegistry::`...'(dword_427AA0, 1, 131097);
TRegistry::SetRootKey(v7, -2147483646);
v2 = System::AnsiString::AnsiString(
&v14,
"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
v13 = 0;
System::AnsiString::operator+(v2, a2, &v13);
System::AnsiString::AnsiString(&v12, "\\Connection\\");
v11 = 0;
System::AnsiString::operator+(&v13, &v12, &v11);
v3 = TRegistry::OpenKey(v7, v11, 0);
System::AnsiString::~AnsiString(&v11, 2);
System::AnsiString::~AnsiString(&v12, 2);
System::AnsiString::~AnsiString(&v13, 2);
System::AnsiString::~AnsiString(&v14, 2);
if ( v3 )
{
v4 = *(_DWORD *)System::AnsiString::AnsiString(&v10, "Name");
v9 = 0;
TRegistry::ReadString(v7, v4);
sub_4A0484(&v15, &v9);
System::AnsiString::~AnsiString(&v9, 2);
System::AnsiString::~AnsiString(&v10, 2);
}
else
{
System::AnsiString::AnsiString(&v8, &unk_4A37E9);
sub_4A0484(&v15, &v8);
System::AnsiString::~AnsiString(&v8, 2);
}
if ( v7 )
{
v5 = *(_DWORD *)v7;
(*(void (__fastcall **)(int, signed int))(*(_DWORD *)v7 - 4))(v7, 3);
}
sub_4A0484(a1, &v15);
System::AnsiString::~AnsiString(&v15, 2);
return a1;
}
做一些字符串操作然后查注册表中存储的网卡信息,取得name并存储
FASTDNS如何初始化那些DNS串的,存储在哪里?
熟悉windows消息机制的会清楚,ListView显示条目用的是SendMessage LVM_SETITEXT或类似机制,而绝不是自己设置,那么我们只需要在启动时加载程序并拦截该函数,看看数目和ip数目吻合程度就知道了。由于结果较多只贴出循环节:
hwnd=812a0 msg=4103
hwnd=812a0 msg=4101
hwnd=812a0 msg=4109
hwnd=812a0 msg=4142
此时可以用spy++查下hwnd是不是ListView,然后看看消息代码,可知分别对应:LVM_GETITEMA LVM_INSERTITEMA LVM_FINDITEMA LVM_SETITEMTEXTA
,第二个和第四个正是我们处理多column的ListView所用的操作,没想到Delphi程序也是这么做的(只不过可能经过层层封装)。下条件断点,进入后发现LVITEM.pszText为-1(LPSTR_TEXTCALLBACK,该消息是说显示到哪再加载那里的数据,较为灵活,对分析造成了困难),也就是说并未再此时赋值,因此使用该方法寻找dns地址根源是失败的,那么我们再次想到字符串,用WinHex搜索地址串,并下数据断点,等移动ListView的滚动条时,程序自动断下,进入.text:0048C33C ; TCustomListView::CNNotify
else
{
v4 = v3 + 308;
if ( v4 )
{
v5 = v4 - 151;
if ( v5 )
{
v6 = v5 - 5;
if ( v6 )
{
if ( v6 == 2 ) // LVN_GETDISPINFOA
{
v64 = TCustomListView::GetItem(v106, (const void *)(v2 + 12));
v65 = *(_DWORD *)(v105 + 8);
v66 = v65 + 12;
if ( *(_BYTE *)(v65 + 12) & 1 )
{
v67 = *(_DWORD *)(v65 + 20);
if ( v67 )
{
v96 = *(_DWORD *)(v64 + 8);
if ( v67 > (*(int (__cdecl **)(unsigned int, _UNKNOWN *, int *))(*(_DWORD *)v96 + 20))(v87, v88, v89) )
{
**(_BYTE **)(v66 + 20) = 0;
}
else
{
(*(void (__fastcall **)(int, int, int *))(*(_DWORD *)v96 + 12))(v96, *(_DWORD *)(v66 + 8) - 1, &v91);
StrPLCopy(*(void **)(v66 + 20), v91, *(_DWORD *)(v66 + 24) - 1);
}
}
else
{
StrPLCopy(*(void **)(v65 + 32), *(char **)(v64 + 0x24), *(_DWORD *)(v65 + 36) - 1);
}
}
可以看到这里正是我们需要的LVN_GETDISPINFOA,程序通过该回调设置真正的列表数据,程序经过最后面这个StrPLCopy,因此我们的重点是看谁改了v64,向上发现源头在TCustomListView::GetItem
,跟进,发现最终源头为SendMessageA(hWnd, LVM_GETITEM, 0, &lvitem);
得到的*(char*)(lvitem->lparam+0x24)
。最终结果。那么谁设置了lparam呢?继续追寻
-100 -101 -102 -150
LVN_ITEMCHANGING FFFFFF9C
LVN_ITEMCHANGED FFFFFF9B
LVN_INSERTITEM FFFFFF9A
LVN_GETDISPINFOA FFFFFF6A
如果下消息断点,并不能发现LVM_SETITEM消息,可能是对delphi不了解吧,这时还要采用最古老的方法,既然显示给我们了,那么内存里已经有字符串,并且一定是解密的,winhex找到位置后,下硬件断点,到了这里:
FastDNS!DnslistFinalize+0x555:
0040ba8d 3a4d14 cmp cl,byte ptr [ebp+14h] ss:002b:0018fbf4=2c
向上层回溯,看看拿到dns地址的根源在什么地方:
text:0040A258 sub_40A258 proc near ; CODE XREF: sub_402474+81 p
text:0040A258
text:0040A258 push ebp
text:0040A259 mov ebp, esp
text:0040A25B add esp, 0FFFFFE80h
text:0040A261 push ebx
text:0040A262 push esi
text:0040A263 push edi
text:0040A264 lea ebx, [ebp+var_114]
text:0040A26A mov eax, offset unk_4B2A5C
text:0040A26F call @__InitExceptBlockLDTC
text:0040A274 mov edx, [ebp+arg_0]
text:0040A277 push edx
text:0040A278 call sub_40C368
text:0040A27D pop ecx
text:0040A27E xor eax, eax
text:0040A280 mov word ptr [ebx+10h], 14h
text:0040A286 inc dword ptr [ebx+1Ch]
text:0040A289 lea ecx, [ebp-38h]
text:0040A28C mov [ebp+var_118], ecx
text:0040A292 mov [ebp+var_18], eax
text:0040A295 xor edx, edx
text:0040A297 xor ecx, ecx
text:0040A299 mov [ebp+var_18+4], edx
text:0040A29C lea eax, [ebp-40h]
text:0040A29F inc dword ptr [ebx+1Ch]
text:0040A2A2 mov [ebp+var_18+10h], ecx
text:0040A2A5 inc dword ptr [ebx+1Ch]
text:0040A2A8 inc dword ptr [ebx+1Ch]
text:0040A2AB inc dword ptr [ebx+1Ch]
text:0040A2AE dec dword ptr [ebx+1Ch]
text:0040A2B1 lea edx, [ebp+handle]
text:0040A2B4 mov word ptr [ebx+10h], 8
text:0040A2BA mov word ptr [ebx+10h], 2Ch
text:0040A2C0 push eax
text:0040A2C1 inc dword ptr [ebx+1Ch]
text:0040A2C4 push offset asc_4B2712 ; "\r\n"
text:0040A2C9 push edx ; _DWORD
text:0040A2CA call FormatString
text:0040A2CF add dword ptr [ebx+1Ch], 4
text:0040A2D3 mov ecx, [ebp+var_18+4]
text:0040A2D6 add esp, 0Ch
text:0040A2D9 cmp ecx, [ebp+var_18+10h]
text:0040A2DC jz short loc_40A316
text:0040A2DE mov eax, [ebp+var_18+4]
text:0040A2E1 mov [ebp+var_11C], eax
text:0040A2E7 mov edx, [ebp+var_11C]
text:0040A2ED mov [ebp-5Ch], edx
text:0040A2F0 test edx, edx
text:0040A2F2 jz short loc_40A310
text:0040A2F4 mov word ptr [ebx+10h], 38h
text:0040A2FA lea eax, [ebp+handle]
text:0040A2FD push eax
text:0040A2FE mov ecx, [ebp-5Ch]
text:0040A301 push ecx
text:0040A302 call sub_40AD98
text:0040A307 mov word ptr [ebx+10h], 2Ch
text:0040A30D add esp, 8
text:0040A310
text:0040A310 loc_40A310: ; CODE XREF: sub_40A258+9A j
text:0040A310 add [ebp+var_18+4], 18h
text:0040A314 jmp short loc_40A335
text:0040A316 ; ---------------------------------------------------------------------------
text:0040A316
text:0040A316 loc_40A316: ; CODE XREF: sub_40A258+84 j
text:0040A316 push 1
text:0040A318 push 1
text:0040A31A lea eax, [ebp+var_124]
text:0040A320 push eax
text:0040A321 lea edx, [ebp+handle]
text:0040A324 push edx
text:0040A325 mov ecx, [ebp+var_18+4]
text:0040A328 push ecx
text:0040A329 lea eax, [ebp+var_18]
text:0040A32C push eax
text:0040A32D call sub_40A968
text:0040A332 add esp, 18h
text:0040A335
text:0040A335 loc_40A335: ; CODE XREF: sub_40A258+BC j
text:0040A335 dec dword ptr [ebx+1Ch]
text:0040A338 mov word ptr [ebx+10h], 8
text:0040A33E dec dword ptr [ebx+1Ch]
text:0040A341 mov edi, [ebp+handle+10h]
text:0040A344 sub edi, [ebp+handle]
text:0040A347 mov esi, [ebp+handle]
text:0040A34A test esi, esi
text:0040A34C jz short loc_40A369
text:0040A34E cmp edi, 80h
text:0040A354 jbe short loc_40A35F
text:0040A356 push esi ; handle
text:0040A357 call __rtl_close
text:0040A35C pop ecx
text:0040A35D jmp short loc_40A369
text:0040A35F ; ---------------------------------------------------------------------------
text:0040A35F
text:0040A35F loc_40A35F: ; CODE XREF: sub_40A258+FC j
text:0040A35F push edi
text:0040A360 push esi
text:0040A361 call sub_4A0CA4
text:0040A366 add esp, 8
text:0040A369
text:0040A369 loc_40A369: ; CODE XREF: sub_40A258+F4 j
text:0040A369 ; sub_40A258+105 j
text:0040A369 dec dword ptr [ebx+1Ch]
text:0040A36C dec dword ptr [ebx+1Ch]
text:0040A36F dec dword ptr [ebx+1Ch]
text:0040A372 lea eax, [ebp-64h]
text:0040A375 mov word ptr [ebx+10h], 5Ch
text:0040A37B push eax
text:0040A37C lea edx, [ebp+var_7C]
text:0040A37F inc dword ptr [ebx+1Ch]
text:0040A382 push offset asc_4B2715 ; "\r"
text:0040A387 push edx ; _DWORD
text:0040A388 call FormatString
text:0040A38D add dword ptr [ebx+1Ch], 4
text:0040A391 mov ecx, [ebp+var_18+4]
text:0040A394 add esp, 0Ch
text:0040A397 cmp ecx, [ebp+var_18+10h]
text:0040A39A jz short loc_40A3D4
text:0040A39C mov eax, [ebp+var_18+4]
text:0040A39F mov [ebp+var_128], eax
text:0040A3A5 mov edx, [ebp+var_128]
text:0040A3AB mov [ebp-80h], edx
text:0040A3AE test edx, edx
text:0040A3B0 jz short loc_40A3CE
text:0040A3B2 mov word ptr [ebx+10h], 68h
text:0040A3B8 lea eax, [ebp+var_7C]
text:0040A3BB push eax
text:0040A3BC mov ecx, [ebp-80h]
text:0040A3BF push ecx
text:0040A3C0 call sub_40AD98
text:0040A3C5 mov word ptr [ebx+10h], 5Ch
text:0040A3CB add esp, 8
text:0040A3CE
text:0040A3CE loc_40A3CE: ; CODE XREF: sub_40A258+158 j
text:0040A3CE add [ebp+var_18+4], 18h
text:0040A3D2 jmp short loc_40A3F3
text:0040A3D4 ; ---------------------------------------------------------------------------
text:0040A3D4
text:0040A3D4 loc_40A3D4: ; CODE XREF: sub_40A258+142 j
text:0040A3D4 push 1
text:0040A3D6 push 1
text:0040A3D8 lea eax, [ebp+var_130]
text:0040A3DE push eax
text:0040A3DF lea edx, [ebp+var_7C]
text:0040A3E2 push edx
text:0040A3E3 mov ecx, [ebp+var_18+4]
text:0040A3E6 push ecx
text:0040A3E7 lea eax, [ebp+var_18]
text:0040A3EA push eax
text:0040A3EB call sub_40A968
text:0040A3F0 add esp, 18h
text:0040A3F3
text:0040A3F3 loc_40A3F3: ; CODE XREF: sub_40A258+17A j
text:0040A3F3 dec dword ptr [ebx+1Ch]
text:0040A3F6 mov word ptr [ebx+10h], 8
text:0040A3FC dec dword ptr [ebx+1Ch]
text:0040A3FF mov edi, [ebp+var_7C+10h]
text:0040A402 sub edi, [ebp+var_7C]
text:0040A405 mov esi, [ebp+var_7C]
text:0040A408 test esi, esi
text:0040A40A jz short loc_40A427
text:0040A40C cmp edi, 80h
text:0040A412 jbe short loc_40A41D
text:0040A414 push esi ; handle
text:0040A415 call __rtl_close
text:0040A41A pop ecx
text:0040A41B jmp short loc_40A427
text:0040A41D ; ---------------------------------------------------------------------------
text:0040A41D
text:0040A41D loc_40A41D: ; CODE XREF: sub_40A258+1BA j
text:0040A41D push edi
text:0040A41E push esi
text:0040A41F call sub_4A0CA4
text:0040A424 add esp, 8
text:0040A427
text:0040A427 loc_40A427: ; CODE XREF: sub_40A258+1B2 j
text:0040A427 ; sub_40A258+1C3 j
text:0040A427 dec dword ptr [ebx+1Ch]
text:0040A42A dec dword ptr [ebx+1Ch]
text:0040A42D dec dword ptr [ebx+1Ch]
text:0040A430 lea eax, [ebp-88h]
text:0040A436 mov word ptr [ebx+10h], 8Ch
text:0040A43C push eax
text:0040A43D lea edx, [ebp+var_A0]
text:0040A443 inc dword ptr [ebx+1Ch]
text:0040A446 push offset asc_4B2717 ; "\n"
text:0040A44B push edx ; _DWORD
text:0040A44C call FormatString
text:0040A451 add dword ptr [ebx+1Ch], 4
text:0040A455 mov ecx, [ebp+var_18+4]
text:0040A458 add esp, 0Ch
text:0040A45B cmp ecx, [ebp+var_18+10h]
text:0040A45E jz short loc_40A4A1
text:0040A460 mov eax, [ebp+var_18+4]
text:0040A463 mov [ebp+var_134], eax
text:0040A469 mov edx, [ebp+var_134]
text:0040A46F mov [ebp+var_A4], edx
text:0040A475 test edx, edx
text:0040A477 jz short loc_40A49B
text:0040A479 mov word ptr [ebx+10h], 98h
text:0040A47F lea eax, [ebp+var_A0]
text:0040A485 push eax
text:0040A486 mov ecx, [ebp+var_A4]
text:0040A48C push ecx
text:0040A48D call sub_40AD98
text:0040A492 mov word ptr [ebx+10h], 8Ch
text:0040A498 add esp, 8
text:0040A49B
text:0040A49B loc_40A49B: ; CODE XREF: sub_40A258+21F j
text:0040A49B add [ebp+var_18+4], 18h
text:0040A49F jmp short loc_40A4C3
text:0040A4A1 ; ---------------------------------------------------------------------------
text:0040A4A1
text:0040A4A1 loc_40A4A1: ; CODE XREF: sub_40A258+206 j
text:0040A4A1 push 1
text:0040A4A3 push 1
text:0040A4A5 lea eax, [ebp+var_13C]
text:0040A4AB push eax
text:0040A4AC lea edx, [ebp+var_A0]
text:0040A4B2 push edx
text:0040A4B3 mov ecx, [ebp+var_18+4]
text:0040A4B6 push ecx
text:0040A4B7 lea eax, [ebp+var_18]
text:0040A4BA push eax
text:0040A4BB call sub_40A968
text:0040A4C0 add esp, 18h
text:0040A4C3
text:0040A4C3 loc_40A4C3: ; CODE XREF: sub_40A258+247 j
text:0040A4C3 dec dword ptr [ebx+1Ch]
text:0040A4C6 mov word ptr [ebx+10h], 8
text:0040A4CC dec dword ptr [ebx+1Ch]
text:0040A4CF mov edi, [ebp+var_A0+10h]
text:0040A4D5 sub edi, [ebp+var_A0]
text:0040A4DB mov esi, [ebp+var_A0]
text:0040A4E1 test esi, esi
text:0040A4E3 jz short loc_40A500
text:0040A4E5 cmp edi, 80h
text:0040A4EB jbe short loc_40A4F6
text:0040A4ED push esi ; handle
text:0040A4EE call __rtl_close
text:0040A4F3 pop ecx
text:0040A4F4 jmp short loc_40A500
text:0040A4F6 ; ---------------------------------------------------------------------------
text:0040A4F6
text:0040A4F6 loc_40A4F6: ; CODE XREF: sub_40A258+293 j
text:0040A4F6 push edi
text:0040A4F7 push esi
text:0040A4F8 call sub_4A0CA4
text:0040A4FD add esp, 8
text:0040A500
text:0040A500 loc_40A500: ; CODE XREF: sub_40A258+28B j
text:0040A500 ; sub_40A258+29C j
text:0040A500 dec dword ptr [ebx+1Ch]
text:0040A503 dec dword ptr [ebx+1Ch]
text:0040A506 dec dword ptr [ebx+1Ch]
text:0040A509 lea eax, [ebp+var_AC]
text:0040A50F mov word ptr [ebx+10h], 0BCh
text:0040A515 inc dword ptr [ebx+1Ch]
text:0040A518 mov [ebp+var_140], eax
text:0040A51E xor edx, edx
text:0040A520 xor ecx, ecx
text:0040A522 mov [ebp+var_30], edx
text:0040A525 mov [ebp+var_30+4], ecx
text:0040A528 inc dword ptr [ebx+1Ch]
text:0040A52B xor eax, eax
text:0040A52D mov [ebp+var_30+10h], eax
text:0040A530 lea edx, [ebp+var_30]
text:0040A533 inc dword ptr [ebx+1Ch]
text:0040A536 inc dword ptr [ebx+1Ch]
text:0040A539 inc dword ptr [ebx+1Ch]
text:0040A53C dec dword ptr [ebx+1Ch]
text:0040A53F lea ecx, [ebp+var_18]
text:0040A542 mov word ptr [ebx+10h], 8
text:0040A548 push edx
text:0040A549 push ecx
text:0040A54A mov eax, [ebp+arg_4]
text:0040A54D push eax
text:0040A54E call sub_40B7F4
text:0040A553 add esp, 0Ch
text:0040A556 mov edi, [ebp+var_30]
text:0040A559 jmp loc_40A850
text:0040A55E ; ---------------------------------------------------------------------------
text:0040A55E
text:0040A55E loc_40A55E: ; CODE XREF: sub_40A258+5FB j
text:0040A55E push 28h
text:0040A560 call @$bnew$qui ; operator new(uint)
text:0040A565 pop ecx
text:0040A566 mov [ebp+var_B0], eax
text:0040A56C test eax, eax
text:0040A56E jz short loc_40A5E6
text:0040A570 mov word ptr [ebx+10h], 0E0h
text:0040A576 mov edx, [ebp+var_B0]
text:0040A57C xor ecx, ecx
text:0040A57E mov [edx+14h], ecx
text:0040A581 mov eax, offset off_4B2DD4
text:0040A586 mov edx, [ebp+var_B0]
text:0040A58C mov [edx+18h], eax
text:0040A58F mov ecx, [ebp+var_B0]
text:0040A595 xor eax, eax
text:0040A597 mov [ecx+1Ch], eax
text:0040A59A mov edx, offset off_4B2DE4
text:0040A59F mov ecx, [ebp+var_B0]
text:0040A5A5 mov [ecx+18h], edx
text:0040A5A8 mov esi, [ebp+var_B0]
text:0040A5AE add esi, 20h
text:0040A5B1 xor eax, eax
text:0040A5B3 mov [esi], eax
text:0040A5B5 inc dword ptr [ebx+1Ch]
text:0040A5B8 mov edx, [ebp+var_B0]
text:0040A5BE add edx, 24h
text:0040A5C1 mov [ebp+var_144], edx
text:0040A5C7 mov ecx, [ebp+var_144]
text:0040A5CD xor eax, eax
text:0040A5CF mov [ecx], eax
text:0040A5D1 inc dword ptr [ebx+1Ch]
text:0040A5D4 add dword ptr [ebx+1Ch], 0FFFFFFFEh
text:0040A5D8 mov word ptr [ebx+10h], 0D4h
text:0040A5DE mov edx, [ebp+var_B0]
text:0040A5E4 jmp short loc_40A5EC
text:0040A5E6 ; ---------------------------------------------------------------------------
text:0040A5E6
text:0040A5E6 loc_40A5E6: ; CODE XREF: sub_40A258+316 j
text:0040A5E6 mov edx, [ebp+var_B0]
text:0040A5EC
text:0040A5EC loc_40A5EC: ; CODE XREF: sub_40A258+38C j
text:0040A5EC mov esi, edx
text:0040A5EE mov word ptr [ebx+10h], 8
text:0040A5F4 mov word ptr [ebx+10h], 0ECh
text:0040A5FA push 2Ch
text:0040A5FC push 0
text:0040A5FE push edi
text:0040A5FF lea eax, [ebp+var_C8]
text:0040A605 push eax
text:0040A606 call sub_40B96C
text:0040A60B add esp, 10h
text:0040A60E lea ecx, [ebp+var_C8]
text:0040A614 add dword ptr [ebx+1Ch], 4
text:0040A618 mov [ebp+var_148], ecx
text:0040A61E mov eax, [ebp+var_148]
text:0040A624 mov edx, [eax]
text:0040A626 lea eax, [ebp+var_CC]
text:0040A62C call @System@AnsiString@$bctr$qqrpxc ; System::AnsiString::AnsiString(char *)
text:0040A631 inc dword ptr [ebx+1Ch]
text:0040A634 lea edx, [ebp+var_CC]
text:0040A63A lea eax, [esi+20h]
text:0040A63D call sub_4A0484
text:0040A642 dec dword ptr [ebx+1Ch]
text:0040A645 lea eax, [ebp+var_CC]
text:0040A64B mov edx, 2
text:0040A650 call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
text:0040A655 dec dword ptr [ebx+1Ch]
text:0040A658 mov word ptr [ebx+10h], 8
text:0040A65E dec dword ptr [ebx+1Ch]
text:0040A661 mov ecx, [ebp+var_B8]
text:0040A667 mov eax, [ebp+var_C8]
text:0040A66D sub ecx, eax
text:0040A66F mov [ebp+var_14C], ecx
text:0040A675 mov [ebp+var_150], eax
text:0040A67B cmp [ebp+var_150], 0
text:0040A682 jz short loc_40A6B5
text:0040A684 cmp [ebp+var_14C], 80h
text:0040A68E jbe short loc_40A69F
text:0040A690 mov edx, [ebp+var_150]
text:0040A696 push edx ; handle
text:0040A697 call __rtl_close
text:0040A69C pop ecx
text:0040A69D jmp short loc_40A6B5
text:0040A69F ; ---------------------------------------------------------------------------
text:0040A69F
text:0040A69F loc_40A69F: ; CODE XREF: sub_40A258+436 j
text:0040A69F mov ecx, [ebp+var_14C]
text:0040A6A5 push ecx
text:0040A6A6 mov eax, [ebp+var_150]
text:0040A6AC push eax
text:0040A6AD call sub_4A0CA4
text:0040A6B2 add esp, 8
text:0040A6B5
text:0040A6B5 loc_40A6B5: ; CODE XREF: sub_40A258+42A j
text:0040A6B5 ; sub_40A258+445 j
text:0040A6B5 dec dword ptr [ebx+1Ch]
text:0040A6B8 dec dword ptr [ebx+1Ch]
text:0040A6BB xor edx, edx
text:0040A6BD mov word ptr [ebx+10h], 110h
text:0040A6C3 mov [ebp+var_D0], edx
text:0040A6C9 lea edx, [ebp+var_D0]
text:0040A6CF inc dword ptr [ebx+1Ch]
text:0040A6D2 lea eax, [esi+20h]
text:0040A6D5 call sub_4A05EC
text:0040A6DA lea edx, [ebp+var_D0]
text:0040A6E0 lea eax, [esi+20h]
text:0040A6E3 call sub_4A0484
text:0040A6E8 dec dword ptr [ebx+1Ch]
text:0040A6EB lea eax, [ebp+var_D0]
text:0040A6F1 mov edx, 2
text:0040A6F6 call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
text:0040A6FB mov word ptr [ebx+10h], 11Ch
text:0040A701 push 2Ch
text:0040A703 push 1
text:0040A705 push edi
text:0040A706 lea ecx, [ebp+var_E8]
text:0040A70C push ecx
text:0040A70D call sub_40B96C
text:0040A712 add esp, 10h
text:0040A715 lea eax, [ebp+var_E8]
text:0040A71B add dword ptr [ebx+1Ch], 4
text:0040A71F mov [ebp+var_154], eax
text:0040A725 lea eax, [ebp+var_EC]
text:0040A72B mov edx, [ebp+var_154]
text:0040A731 mov edx, [edx]
text:0040A733 call @System@AnsiString@$bctr$qqrpxc ; System::AnsiString::AnsiString(char *)
text:0040A738 inc dword ptr [ebx+1Ch]
text:0040A73B lea edx, [ebp+var_EC]
text:0040A741 lea eax, [esi+24h]
text:0040A744 call sub_4A0484
text:0040A749 dec dword ptr [ebx+1Ch]
text:0040A74C lea eax, [ebp+var_EC]
text:0040A752 mov edx, 2
text:0040A757 call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
text:0040A75C dec dword ptr [ebx+1Ch]
text:0040A75F mov word ptr [ebx+10h], 8
text:0040A765 dec dword ptr [ebx+1Ch]
text:0040A768 mov ecx, [ebp+var_D8]
text:0040A76E mov eax, [ebp+var_E8]
text:0040A774 sub ecx, eax
text:0040A776 mov [ebp+var_158], ecx
text:0040A77C mov [ebp+var_15C], eax
text:0040A782 cmp [ebp+var_15C], 0
text:0040A789 jz short loc_40A7BC
text:0040A78B cmp [ebp+var_158], 80h
text:0040A795 jbe short loc_40A7A6
text:0040A797 mov edx, [ebp+var_15C]
text:0040A79D push edx ; handle
text:0040A79E call __rtl_close
text:0040A7A3 pop ecx
text:0040A7A4 jmp short loc_40A7BC
text:0040A7A6 ; ---------------------------------------------------------------------------
text:0040A7A6
text:0040A7A6 loc_40A7A6: ; CODE XREF: sub_40A258+53D j
text:0040A7A6 mov ecx, [ebp+var_158]
text:0040A7AC push ecx
text:0040A7AD mov eax, [ebp+var_15C]
text:0040A7B3 push eax
text:0040A7B4 call sub_4A0CA4
text:0040A7B9 add esp, 8
text:0040A7BC
text:0040A7BC loc_40A7BC: ; CODE XREF: sub_40A258+531 j
text:0040A7BC ; sub_40A258+54C j
text:0040A7BC dec dword ptr [ebx+1Ch]
text:0040A7BF dec dword ptr [ebx+1Ch]
text:0040A7C2 xor edx, edx
text:0040A7C4 mov [esi+8], edx
text:0040A7C7 mov [esi+0Ch], edx
text:0040A7CA lea eax, [esi+20h]
text:0040A7CD mov byte ptr [esi+10h], 1
text:0040A7D1 cmp dword ptr [eax], 0
text:0040A7D4 jz short loc_40A7DA
text:0040A7D6 mov edx, [eax]
text:0040A7D8 jmp short loc_40A7DF
text:0040A7DA ; ---------------------------------------------------------------------------
text:0040A7DA
text:0040A7DA loc_40A7DA: ; CODE XREF: sub_40A258+57C j
text:0040A7DA mov edx, offset unk_4B2719
text:0040A7DF
text:0040A7DF loc_40A7DF: ; CODE XREF: sub_40A258+580 j
text:0040A7DF push edx ; cp
text:0040A7E0 call inet_addr
text:0040A7E5 cmp eax, 0FFFFFFFFh
text:0040A7E8 jz short loc_40A7F9
text:0040A7EA push esi
text:0040A7EB mov eax, [ebp+arg_0]
text:0040A7EE push eax
text:0040A7EF call sub_40C46C
text:0040A7F4 add esp, 8
text:0040A7F7 jmp short loc_40A84D
text:0040A7F9 ; ---------------------------------------------------------------------------
text:0040A7F9
text:0040A7F9 loc_40A7F9: ; CODE XREF: sub_40A258+590 j
text:0040A7F9 mov [ebp+var_F0], esi
text:0040A7FF cmp [ebp+var_F0], 0
text:0040A806 jz short loc_40A84D
text:0040A808 mov word ptr [ebx+10h], 14Ch
text:0040A80E dec dword ptr [ebx+1Ch]
text:0040A811 mov edx, 2
text:0040A816 mov eax, [ebp+var_F0]
text:0040A81C add eax, 24h
text:0040A81F call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
text:0040A824 dec dword ptr [ebx+1Ch]
text:0040A827 mov edx, 2
text:0040A82C mov eax, [ebp+var_F0]
text:0040A832 add eax, 20h
text:0040A835 call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
text:0040A83A mov ecx, [ebp+var_F0]
text:0040A840 push ecx ; handle
text:0040A841 call __rtl_close
text:0040A846 pop ecx
text:0040A847 mov word ptr [ebx+10h], 140h
text:0040A84D
text:0040A84D loc_40A84D: ; CODE XREF: sub_40A258+59F j
text:0040A84D ; sub_40A258+5AE j
text:0040A84D add edi, 18h
text:0040A850
text:0040A850 loc_40A850: ; CODE XREF: sub_40A258+301 j
text:0040A850 cmp edi, [ebp+var_30+4]
text:0040A853 jnz loc_40A55E
text:0040A859 dec dword ptr [ebx+1Ch]
text:0040A85C lea ecx, [ebp+var_164]
text:0040A862 mov eax, [ebp+var_30+4]
text:0040A865 mov edx, [ebp+var_30]
text:0040A868 push ecx
text:0040A869 push eax
text:0040A86A push edx
text:0040A86B call sub_40AB5C
text:0040A870 mov word ptr [ebx+10h], 8
text:0040A876 dec dword ptr [ebx+1Ch]
text:0040A879 mov ecx, 18h
text:0040A87E mov eax, [ebp+var_30+10h]
text:0040A881 add esp, 0Ch
text:0040A884 sub eax, [ebp+var_30]
text:0040A887 cdq
text:0040A888 idiv ecx
text:0040A88A mov [ebp+var_168], eax
text:0040A890 mov esi, [ebp+var_30]
text:0040A893 test esi, esi
text:0040A895 jz short loc_40A8CE
text:0040A897 mov eax, [ebp+var_168]
text:0040A89D shl eax, 3
text:0040A8A0 lea eax, [eax+eax*2]
text:0040A8A3 mov [ebp+var_16C], eax
text:0040A8A9 cmp [ebp+var_16C], 80h
text:0040A8B3 jbe short loc_40A8BE
text:0040A8B5 push esi ; handle
text:0040A8B6 call __rtl_close
text:0040A8BB pop ecx
text:0040A8BC jmp short loc_40A8CE
text:0040A8BE ; ---------------------------------------------------------------------------
text:0040A8BE
text:0040A8BE loc_40A8BE: ; CODE XREF: sub_40A258+65B j
text:0040A8BE mov edx, [ebp+var_16C]
text:0040A8C4 push edx
text:0040A8C5 push esi
text:0040A8C6 call sub_4A0CA4
text:0040A8CB add esp, 8
text:0040A8CE
text:0040A8CE loc_40A8CE: ; CODE XREF: sub_40A258+63D j
text:0040A8CE ; sub_40A258+664 j
text:0040A8CE dec dword ptr [ebx+1Ch]
text:0040A8D1 dec dword ptr [ebx+1Ch]
text:0040A8D4 dec dword ptr [ebx+1Ch]
text:0040A8D7 mov eax, [ebp+var_18+4]
text:0040A8DA mov edx, [ebp+var_18]
text:0040A8DD mov [ebp+var_170], edx
text:0040A8E3 lea ecx, [ebp+var_178]
text:0040A8E9 push ecx
text:0040A8EA push eax
text:0040A8EB mov eax, [ebp+var_170]
text:0040A8F1 push eax
text:0040A8F2 call sub_40AB5C
text:0040A8F7 add esp, 0Ch
text:0040A8FA dec dword ptr [ebx+1Ch]
text:0040A8FD mov eax, [ebp+var_18+10h]
text:0040A900 sub eax, [ebp+var_18]
text:0040A903 mov ecx, 18h
text:0040A908 cdq
text:0040A909 idiv ecx
text:0040A90B mov [ebp+var_17C], eax
text:0040A911 mov esi, [ebp+var_18]
text:0040A914 test esi, esi
text:0040A916 jz short loc_40A94F
text:0040A918 mov eax, [ebp+var_17C]
text:0040A91E shl eax, 3
text:0040A921 lea eax, [eax+eax*2]
text:0040A924 mov [ebp+var_180], eax
text:0040A92A cmp [ebp+var_180], 80h
text:0040A934 jbe short loc_40A93F
text:0040A936 push esi ; handle
text:0040A937 call __rtl_close
text:0040A93C pop ecx
text:0040A93D jmp short loc_40A94F
text:0040A93F ; ---------------------------------------------------------------------------
text:0040A93F
text:0040A93F loc_40A93F: ; CODE XREF: sub_40A258+6DC j
text:0040A93F mov edx, [ebp+var_180]
text:0040A945 push edx
text:0040A946 push esi
text:0040A947 call sub_4A0CA4
text:0040A94C add esp, 8
text:0040A94F
text:0040A94F loc_40A94F: ; CODE XREF: sub_40A258+6BE j
text:0040A94F ; sub_40A258+6E5 j
text:0040A94F dec dword ptr [ebx+1Ch]
text:0040A952 dec dword ptr [ebx+1Ch]
text:0040A955 mov ecx, [ebx]
text:0040A957 mov large fs:0, ecx
text:0040A95E pop edi
text:0040A95F pop esi
text:0040A960 pop ebx
text:0040A961 mov esp, ebp
text:0040A963 pop ebp
text:0040A964 retn
这里已经在做字符串处理了,内存中是4.2.2.1,美国 科罗拉多州布隆菲尔德市Level 3通信公司这种形式,因此需要用逗号吧地址和位置分开,查看变量的访问情况后(这是个很耗时的过程)发现还要向上回溯:
text:00402474 sub_402474 proc near ; CODE XREF: sub_401B74+1A8 p
text:00402474
text:00402474 var_48 = byte ptr -48h
text:00402474 s = dword ptr -24h
text:00402474 var_20 = byte ptr -20h
text:00402474 handle = dword ptr -18h
text:00402474 var_8 = dword ptr -8
text:00402474 arg_0 = dword ptr 8
text:00402474
text:00402474 push ebp
text:00402475 mov ebp, esp
text:00402477 add esp, 0FFFFFFB8h
text:0040247A mov eax, offset unk_4A2564
text:0040247F push ebx
text:00402480 push esi
text:00402481 push edi
text:00402482 lea edi, [ebp+var_48]
text:00402485 mov ebx, [ebp+arg_0]
text:00402488 call @__InitExceptBlockLDTC
text:0040248D mov word ptr [edi+10h], 14h
text:00402493 lea edx, [ebp+var_20]
text:00402496 xor ecx, ecx
text:00402498 push edx
text:00402499 lea eax, [ebp+s]
text:0040249C inc dword ptr [edi+1Ch]
text:0040249F mov [ebp+s], ecx
text:004024A2 push eax
text:004024A3 inc dword ptr [edi+1Ch]
text:004024A6 call sub_408F5C
text:004024AB cmp [ebp+s], 0
text:004024AF pop ecx
text:004024B0 jz short loc_4024B7
text:004024B2 mov edx, [ebp+s]
text:004024B5 jmp short loc_4024BC
text:004024B7 ; ---------------------------------------------------------------------------
text:004024B7
text:004024B7 loc_4024B7: ; CODE XREF: sub_402474+3C j
text:004024B7 mov edx, offset unk_4A21CB
text:004024BC
text:004024BC loc_4024BC: ; CODE XREF: sub_402474+41 j
text:004024BC push edx ; s
text:004024BD lea eax, [ebp+handle]
text:004024C0 push eax ; _DWORD
text:004024C1 call FormatString
text:004024C6 add dword ptr [edi+1Ch], 4
text:004024CA dec dword ptr [edi+1Ch]
text:004024CD add esp, 0Ch
text:004024D0 dec dword ptr [edi+1Ch]
text:004024D3 lea eax, [ebp+s]
text:004024D6 mov edx, 2
text:004024DB call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
text:004024E0 mov word ptr [edi+10h], 8
text:004024E6 mov eax, [ebx+400h]
text:004024EC test eax, eax
text:004024EE jz short loc_4024FD
text:004024F0 lea edx, [ebp+handle]
text:004024F3 push edx
text:004024F4 push eax
text:004024F5 call sub_40A258
text:004024FA add esp, 8
text:004024FD
text:004024FD loc_4024FD: ; CODE XREF: sub_402474+7A j
text:004024FD dec dword ptr [edi+1Ch]
text:00402500 dec dword ptr [edi+1Ch]
text:00402503 mov esi, [ebp+var_8]
text:00402506 mov eax, [ebp+handle]
text:00402509 sub esi, eax
text:0040250B mov ebx, eax
text:0040250D test ebx, ebx
text:0040250F jz short loc_40252C
text:00402511 cmp esi, 80h
text:00402517 jbe short loc_402522
text:00402519 push ebx ; handle
text:0040251A call __rtl_close
text:0040251F pop ecx
text:00402520 jmp short loc_40252C
text:00402522 ; ---------------------------------------------------------------------------
text:00402522
text:00402522 loc_402522: ; CODE XREF: sub_402474+A3 j
text:00402522 push esi
text:00402523 push ebx
text:00402524 call sub_4A0CA4
text:00402529 add esp, 8
text:0040252C
text:0040252C loc_40252C: ; CODE XREF: sub_402474+9B j
text:0040252C ; sub_402474+AC j
text:0040252C dec dword ptr [edi+1Ch]
text:0040252F dec dword ptr [edi+1Ch]
text:00402532 mov eax, [edi]
text:00402534 mov large fs:0, eax
text:0040253A pop edi
text:0040253B pop esi
text:0040253C pop ebx
text:0040253D mov esp, ebp
text:0040253F pop ebp
text:00402540 retn
text:0040254
再次调试,发现408F5C处得到的s已经包含地址,而之前再无修改s之处或者传递之处,因此确定sub_408F5C用于解密字符串,之所以是解密,是因为无法通过资源和字符串找到这些数据,也就说一定经过加密了。进入该函数,这下有趣了:
text:00408F5C sub_408F5C proc near ; CODE XREF: sub_402474+32 p
text:00408F5C
text:00408F5C var_28 = dword ptr -28h
text:00408F5C var_18 = word ptr -18h
text:00408F5C var_C = dword ptr -0Ch
text:00408F5C var_4 = dword ptr -4
text:00408F5C arg_0 = dword ptr 8
text:00408F5C
text:00408F5C push ebp
text:00408F5D mov ebp, esp
text:00408F5F add esp, 0FFFFFFD8h
text:00408F62 mov eax, offset unk_4B1FA0
text:00408F67 call @__InitExceptBlockLDTC
text:00408F6C mov [ebp+var_18], 8
text:00408F72 push 0D3EEh
text:00408F77 push offset unk_4A4B80
text:00408F7C xor edx, edx
text:00408F7E mov [ebp+var_4], edx
text:00408F81 lea ecx, [ebp+var_4]
text:00408F84 push ecx
text:00408F85 inc [ebp+var_C]
text:00408F88 call decode
text:00408F8D add esp, 0Ch
text:00408F90 lea edx, [ebp+var_4]
text:00408F93 mov eax, [ebp+arg_0]
text:00408F96 call sub_4A0484
text:00408F9B mov eax, [ebp+arg_0]
text:00408F9E mov edx, 2
text:00408FA3 mov [ebp+var_18], 14h
text:00408FA9 push eax
text:00408FAA lea eax, [ebp+var_4]
text:00408FAD dec [ebp+var_C]
text:00408FB0 call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
text:00408FB5 pop eax
text:00408FB6 mov [ebp+var_18], 8
text:00408FBC inc [ebp+var_C]
text:00408FBF mov edx, [ebp+var_28]
text:00408FC2 mov large fs:0, edx
text:00408FC9 mov esp, ebp
text:00408FCB pop ebp
text:00408FCC retn
text:00408FCC sub_408F5C endp
text:0040CA68 ; int __cdecl decode(int dest, int src, int len)
text:0040CA68 decode proc near ; CODE XREF: dosetdns+7B p
text:0040CA68 ; sub_4082F4+75 p ...
text:0040CA68
text:0040CA68 var_30 = dword ptr -30h
text:0040CA68 var_2C = dword ptr -2Ch
text:0040CA68 var_1C = word ptr -1Ch
text:0040CA68 var_10 = dword ptr -10h
text:0040CA68 var_8 = dword ptr -8
text:0040CA68 var_4 = byte ptr -4
text:0040CA68 dest = dword ptr 8
text:0040CA68 src = dword ptr 0Ch
text:0040CA68 len = dword ptr 10h
text:0040CA68
text:0040CA68 push ebp
text:0040CA69 mov ebp, esp
text:0040CA6B add esp, 0FFFFFFD0h
text:0040CA6E mov eax, offset unk_4B3420
text:0040CA73 call @__InitExceptBlockLDTC
text:0040CA78 mov [ebp+var_1C], 8
text:0040CA7E lea eax, [ebp+var_4]
text:0040CA81 call unknown_libname_1128 ; CBuilder 5 runtime
text:0040CA86 inc [ebp+var_10]
text:0040CA89 mov [ebp+var_1C], 14h
text:0040CA8F xor edx, edx
text:0040CA91 mov [ebp+var_30], edx
text:0040CA94 mov ecx, [ebp+var_30]
text:0040CA97 cmp ecx, [ebp+len]
text:0040CA9A jge short loc_40CAE4
text:0040CA9C
text:0040CA9C loc_40CA9C: ; CODE XREF: decode+7A j
text:0040CA9C mov [ebp+var_1C], 20h
text:0040CAA2 mov eax, [ebp+var_30]
text:0040CAA5 mov edx, [ebp+src]
text:0040CAA8 xor ecx, ecx
text:0040CAAA mov cl, [edx+eax]
text:0040CAAD mov dl, byte_4B32CC[ecx]
text:0040CAB3 lea eax, [ebp+var_8]
text:0040CAB6 call @System@AnsiString@$bctr$qqrc ; System::AnsiString::AnsiString(char)
text:0040CABB inc [ebp+var_10]
text:0040CABE lea edx, [ebp+var_8]
text:0040CAC1 lea eax, [ebp+var_4]
text:0040CAC4 call sub_4A0498
text:0040CAC9 dec [ebp+var_10]
text:0040CACC lea eax, [ebp+var_8]
text:0040CACF mov edx, 2
text:0040CAD4 call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
text:0040CAD9 inc [ebp+var_30]
text:0040CADC mov ecx, [ebp+var_30]
text:0040CADF cmp ecx, [ebp+len]
text:0040CAE2 jl short loc_40CA9C
text:0040CAE4
text:0040CAE4 loc_40CAE4: ; CODE XREF: decode+32 j
text:0040CAE4 mov [ebp+var_1C], 2Ch
text:0040CAEA lea edx, [ebp+var_4]
text:0040CAED mov eax, [ebp+dest]
text:0040CAF0 call sub_4A0484
text:0040CAF5 mov eax, [ebp+dest]
text:0040CAF8 mov [ebp+var_1C], 38h
text:0040CAFE push eax
text:0040CAFF dec [ebp+var_10]
text:0040CB02 lea eax, [ebp+var_4]
text:0040CB05 mov edx, 2
text:0040CB0A call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
text:0040CB0F pop eax
text:0040CB10 mov [ebp+var_1C], 2Ch
text:0040CB16 inc [ebp+var_10]
text:0040CB19 mov edx, [ebp+var_2C]
text:0040CB1C mov large fs:0, edx
text:0040CB23 mov esp, ebp
text:0040CB25 pop ebp
text:0040CB26 retn
4A4B80和4B32CC处在data段,可以看到作者煞费苦心地构造了2个数组,后者用于做ascii码可逆映射,前者是加密过的字符串数组。大小分别为54254和256,既然如此,我们写程序总不能把这些数据从文件提取出来再解密啊,所以还是用winhex拷贝来的快。这里只是一种好奇心,看看作者到底怎么存储和解密这些数据。
FASTDNS怎么测网速的呢?也就是最核心的部分?
根据前述,核心在TfrmFastDNS_actTestSpendingExecute中。
+00h virtualtable
+0 STOP
+4 FUNC1
+8 FUNC2
+04h HANDLE hthread
+08h ????
+18h FARPROC func0
+1Ch LPVOID param0
+20h FARPROC func1//OnIdle处理函数
+24h LPVOID param1
+28h BOOL IsMainthread??
+30h struct*
+00h int leftTime//剩余次数
+08h double pertime//平均消耗时间
+10h flag statu //成功0 失败3
+38h FARPROC callbackfunc //测试结束的回调函数showstatus
+3Ch DWORD param2 //callbackfunc的参数
+40h int repeatTime//取样次数
+44h int timeout//超时
+48h Class IdDNSResolver_TIdDNSResolver* extends TIdUDPBase extends TIdUDPBase extends....
//原来delphi自带了组件,好方便啊,不过我得自行解决
+00h virtualtable 00412B24
TIdUDPBase::AssignError
TIdUDPBase:efineProperties
TIdUDPBase::Assign
TIdUDPBase:oaded
。。。。。。。。。。
+74h char* ipdns
+7Ch int timeout
+90h package*//发包结构体
+94h int repeattime
+9Ch int sendinfo//要发送的数据包
。。。。。。。。
+50h char* ipstart//存放ip地址字串起始位置
+54h char* ipend//存放ip地址字串结束位置
text:0040970C ; DWORD __cdecl FUNC2(int structa, int *usedtime)
text:0040970C FUNC2 proc near ; DATA XREF: .data:fastdns___CPPdebugHook+105D4 o
text:0040970C
text:0040970C var_2C = dword ptr -2Ch
text:0040970C var_1C = word ptr -1Ch
text:0040970C var_10 = dword ptr -10h
text:0040970C var_8 = byte ptr -8
text:0040970C var_4 = byte ptr -4
text:0040970C structa = dword ptr 8
text:0040970C usedtime = dword ptr 0Ch
text:0040970C
text:0040970C push ebp
text:0040970D mov ebp, esp
text:0040970F add esp, 0FFFFFFD4h
text:00409712 push ebx
text:00409713 push esi
text:00409714 push edi
text:00409715 mov edi, [ebp+usedtime]
text:00409718 mov ebx, [ebp+structa]
text:0040971B mov eax, offset unk_4B25EC
text:00409720 call @__InitExceptBlockLDTC
text:00409725 mov [ebp+var_1C], 8
text:0040972B mov esi, [ebx+48h]
text:0040972E test esi, esi
text:00409730 jz loc_40984A
text:00409736 mov [ebp+var_1C], 14h
text:0040973C mov edx, [ebx+50h]
text:0040973F lea eax, [ebp+var_4]
text:00409742 call @System@AnsiString@$bctr$qqrpxc ; System::AnsiString::AnsiString(char *)
text:00409747 mov edx, eax
text:00409749 inc [ebp+var_10]
text:0040974C mov eax, esi
text:0040974E add eax, 74h
text:00409751 call sub_4A0484
text:00409756 dec [ebp+var_10]
text:00409759 lea eax, [ebp+var_4]
text:0040975C mov edx, 2
text:00409761 call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
text:00409766 mov ecx, [ebx+44h]
text:00409769 mov eax, [ebx+48h]
text:0040976C mov [eax+7Ch], ecx
text:0040976F mov edx, [eax]
text:00409771 call dword ptr [edx+48h]
text:00409774 mov ecx, [ebx+48h]
text:00409777 xor edx, edx
text:00409779 mov eax, [ecx+90h]
text:0040977F call sub_412E58
text:00409784 mov ecx, [ebx+48h]
text:00409787 xor edx, edx
text:00409789 mov eax, [ecx+90h]
text:0040978F call sub_412E6C
text:00409794 mov ecx, [ebx+48h]
text:00409797 mov dl, 1
text:00409799 mov eax, [ecx+90h]
text:0040979F call sub_412E88
text:004097A4 mov eax, [ebx+48h]
text:004097A7 mov edx, [eax+90h]
text:004097AD mov word ptr [edx+0Ch], 1
text:004097B3 mov eax, [eax+94h]
text:004097B9 call @TCollection@Clear ; TCollection::Clear
text:004097BE mov edx, [ebx+48h]
text:004097C1 mov eax, [edx+94h]
text:004097C7 call sub_412EA8
text:004097CC mov [ebp+var_1C], 8
text:004097D2 mov [ebp+var_1C], 20h
text:004097D8 mov esi, eax
text:004097DA lea eax, [ebp+var_8]
text:004097DD mov edx, offset aWww_microsoft_ ; "www.microsoft.com"
text:004097E2 call @System@AnsiString@$bctr$qqrpxc ; System::AnsiString::AnsiString(char *)
text:004097E7 inc [ebp+var_10]
text:004097EA lea edx, [ebp+var_8]
text:004097ED lea eax, [esi+10h]
text:004097F0 call sub_4A0484
text:004097F5 dec [ebp+var_10]
text:004097F8 lea eax, [ebp+var_8]
text:004097FB mov edx, 2
text:00409800 call @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
text:00409805 mov word ptr [esi+14h], 1
text:0040980B mov word ptr [esi+0Ch], 1
text:00409811 call @GetCurrentTime
text:00409816 mov esi, eax
text:00409818 mov [ebp+var_1C], 8
text:0040981E mov eax, [ebx+48h]
text:00409821 call sub_413174
text:00409826 call @GetCurrentTime
text:0040982B mov ebx, eax
text:0040982D sub ebx, esi
text:0040982F mov [edi], ebx
text:00409831 cmp ebx, 1
text:00409834 jnb short loc_40983C
text:00409836 mov dword ptr [edi], 1
text:0040983C
text:0040983C loc_40983C: ; CODE XREF: FUNC2+128 j
text:0040983C mov al, 1
text:0040983E mov edx, [ebp+var_2C]
text:00409841 mov large fs:0, edx
text:00409848 jmp short loc_409869
text:0040984A ; ---------------------------------------------------------------------------
text:0040984A
text:0040984A loc_40984A: ; CODE XREF: FUNC2+24 j
text:0040984A mov [ebp+var_1C], 0
text:00409850 jmp short loc_40985D
text:00409852 ; ---------------------------------------------------------------------------
text:00409852
text:00409852 loc_409852: ; DATA XREF: .data:fastdns___CPPdebugHook+1051C o
text:00409852 mov [ebp+var_1C], 10h
text:00409858 call @_CatchCleanup$qv ; _CatchCleanup(void)
text:0040985D
text:0040985D loc_40985D: ; CODE XREF: FUNC2+144 j
text:0040985D xor eax, eax
text:0040985F mov edx, [ebp+var_2C]
text:00409862 mov large fs:0, edx
text:00409869
text:00409869 loc_409869: ; CODE XREF: FUNC2+13C j
text:00409869 pop edi
text:0040986A pop esi
text:0040986B pop ebx
text:0040986C mov esp, ebp
text:0040986E pop ebp
text:0040986F retn
本段程序构造某网络包类,sub_413174为真正执行代码,在其前后取时间进行测速:
text:00413174 sub_413174 proc near ; CODE XREF: FUNC2+115 p
text:00413174
text:00413174 var_8 = dword ptr -8
text:00413174 var_4 = dword ptr -4
text:00413174
text:00413174 push ebp
text:00413175 mov ebp, esp
text:00413177 add esp, 0FFFFFFF8h
text:0041317A xor edx, edx
text:0041317C mov [ebp+var_8], edx
text:0041317F mov [ebp+var_4], eax
text:00413182 xor eax, eax
text:00413184 push ebp
text:00413185 push offset loc_413208
text:0041318A push dword ptr fs:[eax]
text:0041318D mov fs:[eax], esp
text:00413190 xor eax, eax
text:00413192 push ebp
text:00413193 push offset loc_4131EB
text:00413198 push dword ptr fs:[eax]
text:0041319B mov fs:[eax], esp
text:0041319E mov eax, [ebp+var_4]
text:004131A1 call sub_413470
text:004131A6 mov eax, [ebp+var_4]
text:004131A9 mov edx, [eax+9Ch]
text:004131AF mov eax, [ebp+var_4]
text:004131B2 call @TIdUDPClient@Send ; TIdUDPClient::Send
text:004131B7 lea ecx, [ebp+var_8]
text:004131BA or edx, 0FFFFFFFFh
text:004131BD mov eax, [ebp+var_4]
text:004131C0 call @TIdUDPBase@ReceiveString ; TIdUDPBase::ReceiveString
text:004131C5 mov edx, [ebp+var_8]
text:004131C8 mov eax, [ebp+var_4]
text:004131CB add eax, 0A0h
text:004131D0 call @@LStrAsg ; __linkproc__ LStrAsg
text:004131D5 xor eax, eax
text:004131D7 pop edx
text:004131D8 pop ecx
text:004131D9 pop ecx
text:004131DA mov fs:[eax], edx
text:004131DD push offset loc_4131F2
text:004131E2
text:004131E2 loc_4131E2: ; CODE XREF: sub_413174+7C j
text:004131E2 mov eax, [ebp+var_4]
text:004131E5 call sub_414B3C
text:004131EA retn
text:004131EB ; ---------------------------------------------------------------------------
text:004131EB
text:004131EB loc_4131EB: ; DATA XREF: sub_413174+1F o
text:004131EB jmp @@HandleFinally ; __linkproc__ HandleFinally
text:004131F0 ; ---------------------------------------------------------------------------
text:004131F0 jmp short loc_4131E2
text:004131F2 ; ---------------------------------------------------------------------------
text:004131F2
text:004131F2 loc_4131F2: ; CODE XREF: sub_413174+76 j
text:004131F2 ; DATA XREF: sub_413174+69 o
text:004131F2 xor eax, eax
text:004131F4 pop edx
text:004131F5 pop ecx
text:004131F6 pop ecx
text:004131F7 mov fs:[eax], edx
text:004131FA push offset loc_41320F
text:004131FF
text:004131FF loc_4131FF: ; CODE XREF: sub_413174+99 j
text:004131FF lea eax, [ebp+var_8]
text:00413202 call @@LStrClr ; __linkproc__ LStrClr
text:00413207 retn
text:00413208 ; ---------------------------------------------------------------------------
text:00413208
text:00413208 loc_413208: ; DATA XREF: sub_413174+11 o
text:00413208 jmp @@HandleFinally ; __linkproc__ HandleFinally
text:0041320D ; ---------------------------------------------------------------------------
text:0041320D jmp short loc_4131FF
text:0041320F ; ---------------------------------------------------------------------------
text:0041320F
text:0041320F loc_41320F: ; CODE XREF: sub_413174+93 j
text:0041320F ; DATA XREF: sub_413174+86 o
text:0041320F pop ecx
text:00413210 pop ecx
text:00413211 pop ebp
text:00413212 retn
从以上代码可以得知,重要调用有:
- sub_413470
- TIdDNSResolver::Send
- TIdDNSResolver::ReceiveString
- sub_414B3C
由于调用函数库较多,较为浪费时间,因此这里用WireShark抓取+API break的方式查看网络情况,可以得到如下结果:
启动时:对每个ip做inet_addr
检测时:WSAStartup 101
socket af=AF_INET type=SOCK_DGRAM protocol=IPPROTO_IP
setsockopt level=SOL_SOCKET optname=SO_BROADCAST optval="\0\0\0\0" optlen=4
ntohs hostshort=53//DNS
sendto len=35 flags=0 tolen=sizeof(sockaddr) buf=
b4 c3 01 00 00 01 00 00-00 00 00 00 03 77 77 77 ………….www
09 6d 69 63 72 6f 73 6f-66 74 03 63 6f 6d 00 00 .microsoft.com..
01 00 01
sockaddr=02 00 00 35 04 02 02 01-00 00 00 00 00 00 00 00
select nfds=0 readfs={1,socket} writefds={0,0} exceptfds={0,0}
timeout{tv_sec=2 tv_usec=0}
recvfrom len=8192 flag=0 from=02 00 00 35 04 02 02 01-00 00 00 00 00 00 00 00
fromlen=sizeof(sockaddr) buf=
b4 c3 81 80 00 01 00 04-00 00 00 00 03 77 77 77 ………….www
09 6d 69 63 72 6f 73 6f-66 74 03 63 6f 6d 00 00 .microsoft.com..
01 00 01 c0 0c 00 05 00-01 00 00 0c fd 00 1a 06 …………….
ntohs hostshort=13568
shutdown how=SD_SEND
closesocket
结果
直接使用udp层链接即可,另外按照前面所述,用WinHex可得到ip列表,此时要解决的问题都已解决,可以完整地写一个程序了^_^
- 4.2.2.1,美国 科罗拉多州布隆菲尔德市Level 3通信公司
- 4.2.2.2,美国 科罗拉多州布隆菲尔德市Level 3通信公司
- 4.2.2.3,美国 科罗拉多州布隆菲尔德市Level 3通信公司
- 4.2.2.4,美国 科罗拉多州布隆菲尔德市Level 3通信公司
- 4.2.2.5,美国 科罗拉多州布隆菲尔德市Level 3通信公司
自制DNS加速器
1500行代码用boost和stl一气呵成,预期可以支持ipv6 dns,批量测试/停止,解析域名镜像(如google),支持大dns库和自定义dns库,甚至以后和代理功能结合到一起。由于是初稿,因此有bug,这里贴出源码,给出工程,望和大家一起探讨改进之处,理论上说这个工具会是很强大的!
//functions.h
#pragma once
#ifndef FASTERDNS_COMMONHEADER
#define FASTERDNS_COMMONHEADER
#endif
#include <string>
#include <vector>
#include <boost/asio.hpp>
#include <boost/function.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread.hpp>
#include <boost/thread/detail/thread_group.hpp>
#include <deque>
#include <set>
#include "sqlite3.h"
#define DATABASE "dnss.db"
#define CSVDATA "nameservers.csv"
class testSpeedData//每轮测试所用数据
{
public:
testSpeedData(char* _ip, char* _location) :ip(_ip), location(_location)
{
responsetime = 0;
testtime = 0;
lefttime = 0;
failtime = 0;
timeout = 0;
}
public:
std::string ip;//DNS地址
std::string location;//所在地
int responsetime;//总响应时间
int testtime;//总测试次数
int lefttime;//剩余次数
int failtime;//失败次数
int timeout;//超时时间
};
typedef int(*DBCALLBACK)(void *NotUsed, int argc, char **argv, char **azColName);
typedef std::vector<std::string> spliter;
typedef std::vector<std::pair<std::string,std::string>> dbData;
//数据库相关
bool doadddata(dbData* dataparam, HWND progctrl);
bool dodeldata(std::vector<std::string>* dataparam, HWND progctrl);
bool getcount(int& count);
bool getdata(std::vector<testSpeedData>* dataparam, HWND listctrl, HWND statu, boost::mutex* mu);
//网络操作相关
bool dohttpconnect(const std::string& ip, uint32_t& timeout);
bool dodnsconnect(const std::string& ip, uint32_t& timeout, std::vector<uint8_t>& bufferdata);
void makedns(std::vector<uint8_t>& bufferdata, const std::string& testdomain);
void replaceXid(std::vector<uint8_t>& bufferdata, uint16_t Xid);
void resolveAnswer(std::vector<uint8_t>& bufferdata, std::set<std::string>& resolvedip, int originlen);
//系统设置相关
bool getinterface(std::vector<std::string>& interfaces);
bool setinterface(std::vector<std::string>& interfaces, std::vector<std::string>& addresss, HWND progctrl);
enum
{
//解析CSV数据文件
CSV_IP = 0,
CSV_NAME,
CSV_COUNTRYID,
CSV_CITY,
CSV_MAX,
//解析普通数据文件
COM_IP = 0,
COM_LOCATION,
COM_MAX,
//端口
PORT_HTTP = 80,
PORT_DNS = 53,
//DNS包
SIZE_DNSHEADER = sizeof(DNS_HEADER),
SIZE_DNSTAILER = 5,
//值域
INIT_THREADNUM = 1,
LOW_THREADNUM = 0,
HIGH_THREADNUM = 1000,
INIT_TIMEOUT = 1000,
LOW_TIMEOUT = 10,
HIGH_TIMEOUT = 10000,
INIT_TESTNUM = 1,
LOW_TESTNUM = 0,
HIGH_TESTNUM = 100,
//显示列
COL_IP = 0,
COL_LOC,
COL_RES,//平均响应时间
COL_FAIL,//失败次数/总次数
//其他
IDC_PROGRESS = 12345,
MAX_DOMAIN_LENGTH = 256,
MAXS_RECVNUM = 65536,
HTTP_CONNECTTIME = 5000,
TIMER1_ID=10000,
};
class ipcontainer:public boost::noncopyable
{
public:
static ipcontainer& getInstance();
bool adddata(const std::string& ip, const std::string& addr);
bool deldata(const std::string& ip);
bool getdata(std::vector<testSpeedData>* dataparam,HWND listctrl);
bool getcount(int& pcount);
virtual ~ipcontainer();
private:
ipcontainer();
static int getdatacallback(void *NotUsed, int argc, char **argv, char **azColName);
static int getcountcallback(void *NotUsed, int argc, char **argv, char **azColName);
private:
sqlite3* db;
static int* pcount;
static std::vector<testSpeedData>* testdata;
static HWND pwnd;
};
template<typename D>
class ThreadPool
{
public:
ThreadPool(boost::mutex& _mu) :mu(_mu)
{
threadnum = 0;
task = NULL;
}
virtual ~ThreadPool()
{
if (ppio)
{
for (int i = 0; i < threadnum; i++)
delete ppio[i];
delete[]ppio;
}
}
bool Attach(int _threadnum, std::deque<int>* _task, std::vector<D>* _dataarray, HWND _listview)
{
if (!_task || _task->empty() || !_dataarray)
return false;//任务未结束
task = _task;
dataarray = _dataarray;
threadnum = _threadnum;
listview = _listview;
ppio = new boost::asio::io_service*[threadnum];
if (!ppio)
return false;
for (int i = 0; i < threadnum; i++)
{
ppio[i] = new boost::asio::io_service;
if (!ppio[i])//模拟new[]的行为,释放之前成功分配的内存
{
for (int j = i-1; j >= 0; j--)
delete ppio[j];
delete[]ppio;
return false;
}
}
return true;
}
bool Exec(void(*f)(int, std::vector<D>*, HWND))
{
try
{
boost::thread_group tg;
//建立线程组
for (int i = 0; i < threadnum; i++)
{
tg.create_thread(boost::bind(&ThreadPool::wrapper, this, ppio[i],f));
}
//等待所有任务执行完毕
tg.join_all();
}
catch (...)
{
//确保释放new
return false;
}
return true;
}
private:
//用于将task里的任务分配各给threadnum个活动线程,分配时要进行线程同步
void wrapper(boost::asio::io_service* service, void(*f)(int, std::vector<D>*, HWND))
{
while (true)
{
mu.lock();
if (task->empty())
{
mu.unlock();
return;
}
service->post(boost::bind(f, task->front(), dataarray, listview));
task->pop_front();
mu.unlock();
service->run();
service->reset();
}
}
private:
int threadnum;
HWND listview;
boost::mutex& mu;//分配任务用锁
std::deque<int>* task;//要分配的总任务索引
std::vector<D>* dataarray;//原始数据
boost::asio::io_service** ppio;//耗费的线程资源
};
#pragma pack(push)
#pragma pack(2)
typedef struct _DNSANSWER_HEADER
{
WORD Name;
WORD Type;
WORD Class;
DWORD Timetolive;
WORD Datalength;
}DNSANSWER_HEADER, *PDNSANSWER_HEADER;
#pragma pack(pop)
#define DNS_BYTE_FLIP_ANSWERHEADER_COUNTS(pHeader)\
{\
PDNSANSWER_HEADER _head = (pHeader); \
INLINE_HTONS(_head->Name, _head->Name);\
INLINE_HTONS(_head->Type, _head->Type); \
INLINE_HTONS(_head->Class, _head->Class); \
INLINE_HTONS(_head->Timetolive, _head->Timetolive); \
INLINE_HTONS(_head->Datalength, _head->Datalength); \
}
class udpclient//只为做超时处理
{
public:
udpclient(const boost::asio::ip::udp::endpoint& listen_endpoint) :socket_(io_service_, listen_endpoint), deadline_(io_service_)
{
deadline_.expires_at(boost::posix_time::pos_infin);
check_deadline();
}
std::size_t receive(const boost::asio::mutable_buffer& buffer, boost::posix_time::time_duration timeout, boost::system::error_code& ec)
{
deadline_.expires_from_now(timeout);
ec = boost::asio::error::would_block;
std::size_t length = 0;
socket_.async_receive(boost::asio::buffer(buffer), boost::bind(&udpclient::handle_receive, _1, _2, &ec, &length));
do io_service_.run_one(); while (ec == boost::asio::error::would_block);
return length;
}
private:
void check_deadline()
{
if (deadline_.expires_at() <= boost::asio::deadline_timer::traits_type::now())
{
socket_.cancel();
deadline_.expires_at(boost::posix_time::pos_infin);
}
deadline_.async_wait(boost::bind(&udpclient::check_deadline, this));
}
static void handle_receive(const boost::system::error_code& ec, std::size_t length,
boost::system::error_code* out_ec, std::size_t* out_length)
{
*out_ec = ec;
*out_length = length;
}
private:
boost::asio::io_service io_service_;
boost::asio::deadline_timer deadline_;
public:
boost::asio::ip::udp::socket socket_;
};
class tcpclient//只为做超时处理
{
public:
tcpclient() :socket_(io_service_), deadline_(io_service_)
{
deadline_.expires_at(boost::posix_time::pos_infin);
check_deadline();
}
void connect(const boost::asio::ip::tcp::endpoint ep, boost::posix_time::time_duration timeout, boost::system::error_code& ec)
{
deadline_.expires_from_now(timeout);
ec = boost::asio::error::would_block;
socket_.async_connect(ep,boost::bind(&tcpclient::handle_connect, _1, &ec));
do io_service_.run_one(); while (ec == boost::asio::error::would_block);
}
private:
void check_deadline()
{
if (deadline_.expires_at() <= boost::asio::deadline_timer::traits_type::now())
{
socket_.cancel();
deadline_.expires_at(boost::posix_time::pos_infin);
}
deadline_.async_wait(boost::bind(&tcpclient::check_deadline, this));
}
static void handle_connect(const boost::system::error_code& ec, boost::system::error_code* out_ec)
{
*out_ec = ec;
}
private:
boost::asio::io_service io_service_;
boost::asio::deadline_timer deadline_;
public:
boost::asio::ip::tcp::socket socket_;
};
// FasterDNSDlg.cpp : 实现文件
#include "stdafx.h"
#include "FasterDNS.h"
#include "FasterDNSDlg.h"
#include "SetDnsDlg.h"
#include "afxdialogex.h"
#include <boost/scoped_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/range.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/xpressive/xpressive.hpp>
#include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>
#include <queue>
#include <fstream>
#include <set>
#include "functions.h"
#include <stdlib.h>
#include "ShowIp.h"
#include "GlobalSetting.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CFasterDNSDlg::CFasterDNSDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CFasterDNSDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CFasterDNSDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CFasterDNSDlg, CDialogEx)
ON_WM_PAINT()
ON_BN_CLICKED(IDC_ADDDNS, &CFasterDNSDlg::OnBnClickedAddDNS)
ON_NOTIFY(LVN_GETDISPINFO, IDC_IPLIST, &CFasterDNSDlg::OnLvnGetdispinfoIplist)
ON_COMMAND(ID_ABOUT, &CFasterDNSDlg::OnAbout)
ON_COMMAND(ID_SETDNS, &CFasterDNSDlg::OnSetdns)
ON_NOTIFY(HDN_ITEMCLICK, 0, &CFasterDNSDlg::OnHdnItemclickIplist)
ON_NOTIFY(NM_RCLICK, IDC_IPLIST, &CFasterDNSDlg::OnNMRClickIplist)
ON_COMMAND(ID_DELDNS, &CFasterDNSDlg::OnDeldns)
ON_BN_CLICKED(IDC_ALLINONE, &CFasterDNSDlg::OnBnClickedAllinone)
ON_BN_CLICKED(IDC_START, &CFasterDNSDlg::OnBnClickedStart)
ON_BN_CLICKED(IDC_STOP, &CFasterDNSDlg::OnBnClickedStop)
ON_BN_CLICKED(IDC_VIEWIP, &CFasterDNSDlg::OnBnClickedViewip)
ON_WM_TIMER()
ON_COMMAND(ID_ADDDNS, &CFasterDNSDlg::OnAdddns)
ON_COMMAND(ID_MODIFY, &CFasterDNSDlg::OnModify)
ON_COMMAND(ID_STARTALL, &CFasterDNSDlg::OnStartall)
ON_COMMAND(ID_STOPALL, &CFasterDNSDlg::OnStopall)
ON_COMMAND(ID_TESTIP, &CFasterDNSDlg::OnTestip)
ON_COMMAND(ID_EXIT, &CFasterDNSDlg::OnExit)
ON_COMMAND(ID_ALLINONE, &CFasterDNSDlg::OnAllinone)
ON_COMMAND(ID_START, &CFasterDNSDlg::OnStart)
ON_COMMAND(ID_STOP, &CFasterDNSDlg::OnStop)
END_MESSAGE_MAP()
BOOL CFasterDNSDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
m_list = (CListCtrl*)GetDlgItem(IDC_IPLIST);
m_list->SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
RECT rt;
m_list->GetClientRect(&rt);
m_list->InsertColumn(COL_IP, "DNS地址", LVCFMT_LEFT, rt.right / 5);
m_list->InsertColumn(COL_LOC, "所在地", LVCFMT_LEFT, rt.right / 5);
m_list->InsertColumn(COL_RES, "响应时间", LVCFMT_LEFT, rt.right / 5);
m_list->InsertColumn(COL_FAIL, "失败率", LVCFMT_LEFT, rt.right / 5);
boost::thread(boost::bind(getdata, &dataarray, m_list->m_hWnd, GetDlgItem(IDC_STATU)->m_hWnd, &datamutex));
issorting = false;
maxtask = 0;
repeattime = 3;
threadnum = 3;
timeout = 1000;
SetDlgItemText(IDC_DOMAIN, "www.microsoft.com");
SetTimer(TIMER1_ID, 1000, NULL);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CFasterDNSDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
void CFasterDNSDlg::OnBnClickedAddDNS()
{
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "*.*", NULL);
if (IDOK == dlg.DoModal())
{
//读取文件,解析出ip
std::fstream file;
std::string line;
dbData toadd;
boost::asio::ip::address addr;
spliter splitvec;
//获取大小
file.open(dlg.GetPathName(), std::ios::in);
file.seekg(0,std::ios::end);
int totalsize = file.tellg();
file.seekg(0,std::ios::beg);
CProgressCtrl m_progctrl;
m_progctrl.Create(WS_CHILD | WS_VISIBLE, CRect(0, 0, 400, 50), this,
IDC_PROGRESS);
m_progctrl.SetRange(0, 100);
boost::mutex::scoped_lock mdata(datamutex);
if (dlg.GetFileName() == CSVDATA)
{
getline(file, line);//跳过第一行
while (!file.eof())
{
int pos2 = file.tellg();
m_progctrl.SetPos(int(100*(double)file.tellg()/totalsize));
getline(file, line);
boost::split(splitvec, line, boost::is_any_of(","));
try
{
if (splitvec.size() < CSV_MAX)
throw "Error";
addr = addr.from_string(splitvec[CSV_IP]);
}
catch (...)
{
break;
}
LVITEM item = { 0 };
item.mask = LVIF_TEXT;
item.iItem = dataarray.size();
item.lParam = item.iItem;
item.pszText = LPSTR_TEXTCALLBACK;
dataarray.push_back(testSpeedData((char*)splitvec[CSV_IP].c_str(), (char*)(splitvec[CSV_COUNTRYID] + " " + splitvec[CSV_CITY]).c_str()));
m_list->InsertItem(&item);
toadd.push_back(make_pair(splitvec[CSV_IP], splitvec[CSV_COUNTRYID] + " " + splitvec[CSV_CITY]));
}
}
else
{//普通文件,ip地址和位置信息用逗号分隔
while (!file.eof())
{
m_progctrl.SetPos(int(100*(double)file.tellg() / totalsize));
getline(file, line);
boost::split(splitvec, line, boost::is_any_of(","));
try
{
if (splitvec.size() < COM_MAX)
throw "Error";
addr = addr.from_string(splitvec[COM_IP]);
}
catch (...)
{
break;
}
LVITEM item = { 0 };
item.mask = LVIF_TEXT;
item.iItem = dataarray.size();
item.lParam = item.iItem;
item.pszText = LPSTR_TEXTCALLBACK;
dataarray.push_back(testSpeedData((char*)splitvec[COM_IP].c_str(), (char*)splitvec[COM_LOCATION].c_str()));
m_list->InsertItem(&item);
toadd.push_back(make_pair(splitvec[COM_IP], splitvec[COM_LOCATION]));
}
}
file.close();
ProgressThread("正在添加",doadddata,&toadd);
}
}
template<typename F,typename D>
void CFasterDNSDlg::ProgressThread(LPCTSTR wndname,F& threadfunc,D paramdata)
{
CProgressCtrl m_progctrl;
m_progctrl.Create(WS_CHILD | WS_VISIBLE | PBS_SMOOTH, CRect(0, 0, 400, 50), this, IDC_PROGRESS);
m_progctrl.SetRange(0, 100);
m_progctrl.SetWindowText(wndname);
//绑定进度条到threadfunc,抽象出逻辑使在其内部动态更新进度条
boost::packaged_task<bool> pt(boost::bind(threadfunc, paramdata, m_progctrl.m_hWnd));
boost::unique_future<bool> uf = pt.get_future();
boost::thread(boost::move(pt));
uf.wait();
if (uf.get())
SetDlgItemText(IDC_STATU, "操作成功!");
else
SetDlgItemText(IDC_STATU, "操作失败!");
}
char toformat[256];
void CFasterDNSDlg::OnLvnGetdispinfoIplist(NMHDR *pNMHDR, LRESULT *pResult)
{//刷新数据
NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
int index = pDispInfo->item.iItem;
if (dataarray.size() == 0 || index > dataarray.size() - 1)
return;
testSpeedData& cur = dataarray[index];
switch (pDispInfo->item.iSubItem)
{
case COL_IP:
pDispInfo->item.pszText = (char*)cur.ip.c_str();
break;
case COL_LOC:
pDispInfo->item.pszText = (char*)cur.location.c_str();
break;
case COL_RES:
if (cur.responsetime == 0)
pDispInfo->item.pszText = "未测速";
else if (cur.testtime == cur.failtime)
pDispInfo->item.pszText = "测速失败";
else
{
sprintf_s(toformat, "%d ms", cur.responsetime / (cur.testtime - cur.failtime));
pDispInfo->item.pszText = toformat;
}
break;
case COL_FAIL:
if (dataarray[index].testtime == 0)
pDispInfo->item.pszText = "未测速";
else
{
sprintf_s(toformat, "%d/%d", cur.failtime, cur.testtime);
pDispInfo->item.pszText = toformat;
}
break;
}
*pResult = 0;
}
void CFasterDNSDlg::OnAbout()
{
AfxMessageBox("该程序在‘彗星DNS优化器’基础上修改得到,增加了数据库,有望未来支持ipv6\r\n作者:lichao890427 qq:571652571");
}
void CFasterDNSDlg::OnSetdns()
{//显示网卡窗口
std::vector<std::string> selip;
int uSelectedCount = m_list->GetSelectedCount();
int nItem = -1;
if (uSelectedCount > 0)
{
for (int i = 0; i < uSelectedCount; i++)
{
nItem = m_list->GetNextItem(nItem, LVNI_SELECTED);
selip.push_back(dataarray[nItem].ip);
}
boost::thread(boost::bind(&CFasterDNSDlg::DoDNSConnection, this));
}
CSetDnsDlg setdns(selip);
setdns.DoModal();
}
bool CompareIP(testSpeedData& lParam1, testSpeedData& lParam2)
{
using namespace boost::asio;
ip::address& addr1 = ip::address::from_string(lParam1.ip);
ip::address& addr2 = ip::address::from_string(lParam2.ip);
if (addr1.is_v4())
{
if (addr2.is_v4())
{
return addr1.to_v4().to_ulong() < addr2.to_v4().to_ulong();
}
else
return true;
}
else
{
return false;
}
}
bool CompareLOC(testSpeedData& lParam1, testSpeedData& lParam2)
{
return lParam1.location < lParam2.location;
}
bool CompareRES(testSpeedData& lParam1, testSpeedData& lParam2)
{
if (lParam1.failtime || lParam1.lefttime)
return true;
else if (lParam2.failtime || lParam2.lefttime)
return false;
else if (!lParam1.testtime || !lParam2.testtime)
return lParam1.testtime < lParam2.testtime;
else
return lParam1.responsetime / lParam1.testtime < lParam2.responsetime / lParam2.testtime;
}
void CFasterDNSDlg::DoSort(bool(*f)(testSpeedData&, testSpeedData&))
{
if (issorting)
{
AfxMessageBox("排序尚未完成!");
return;
}
boost::mutex::scoped_lock mdata(datamutex);
SetDlgItemText(IDC_STATU, "正在排序");
issorting = true;
std::sort(dataarray.begin(), dataarray.end(), f);
for (int i = 0; i < dataarray.size(); i++)
{
LVITEM item = { 0 };
item.mask = LVIF_TEXT;
item.iItem = i;
item.pszText = LPSTR_TEXTCALLBACK;
m_list->SendMessage(LVM_SETITEMTEXT, i, (LPARAM)&item);
}
SetDlgItemText(IDC_STATU, "排序完毕");
issorting = false;
}
void CFasterDNSDlg::OnHdnItemclickIplist(NMHDR *pNMHDR, LRESULT *pResult)
{//排序
LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
switch (phdr->iItem)
{//不要直接修改listview,而是先修改和listview绑定的data,再通知listview
case COL_IP:
boost::thread(boost::bind(&CFasterDNSDlg::DoSort, this, CompareIP));
break;
case COL_LOC:
boost::thread(boost::bind(&CFasterDNSDlg::DoSort, this, CompareLOC));
break;
case COL_RES:
boost::thread(boost::bind(&CFasterDNSDlg::DoSort, this, CompareRES));
break;
case COL_FAIL:
break;
}
*pResult = 0;
}
void CFasterDNSDlg::OnNMRClickIplist(NMHDR *pNMHDR, LRESULT *pResult)
{//右键弹出菜单
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
CMenu menu;
menu.LoadMenu(IDR_POPUPMENU);
CMenu* pPopup = menu.GetSubMenu(0);
POINT pt;
GetCursorPos(&pt);
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, this);
*pResult = 0;
}
void CFasterDNSDlg::OnDeldns()
{//删除dns,先从数据库中删,再重新加载数据
int uSelectedCount = m_list->GetSelectedCount();
int nItem = -1;
if (uSelectedCount > 0)
{
boost::mutex::scoped_lock mdata(datamutex);
std::vector<std::string> temp;
for (int i = 0; i < uSelectedCount; i++)
{
nItem = m_list->GetNextItem(nItem, LVNI_SELECTED);
temp.push_back(dataarray[nItem].ip);
}
dodeldata(&temp, m_list->m_hWnd);
dataarray.clear();
m_list->DeleteAllItems();
boost::thread(boost::bind(getdata, &dataarray, m_list->m_hWnd, GetDlgItem(IDC_STATU)->m_hWnd, &datamutex));
}
}
std::set<std::string> resolvedip;
std::string domain="www.microsoft.com";
void testFunc(int index, std::vector<testSpeedData>* rawdata, HWND listview)
{
testSpeedData& curdata = (*rawdata).at(index);
std::vector<uint8_t> bufferdata;
bool got = false;
while (curdata.lefttime)
{
makedns(bufferdata, domain);
int originlen = bufferdata.size();//发送包大小,用于定位返回answer
replaceXid(bufferdata, rand() & 0xFFFF);
uint32_t usedtime = curdata.timeout;
if (!dodnsconnect(curdata.ip, usedtime, bufferdata))
curdata.failtime++;
else
{
curdata.responsetime += usedtime;
if (!got)
{//解析返回包
resolveAnswer(bufferdata, resolvedip, originlen);
got = true;
}
}
curdata.lefttime--;
}
//刷新listview
LVITEM item = { 0 };
item.mask = LVIF_TEXT;
item.iItem = index;
item.pszText = LPSTR_TEXTCALLBACK;
SendMessage(listview, LVM_SETITEMTEXT, index, (LPARAM)&item);
}
void CFasterDNSDlg::OnTimer(UINT_PTR nIDEvent)
{
char status[256];
sprintf_s(status,"%06d/%06d/%06d", task.size(), maxtask, dataarray.size());
SetDlgItemText(IDC_TESTPROG, status);
CDialogEx::OnTimer(nIDEvent);
}
void CFasterDNSDlg::DoDNSConnection()
{//设置testSpeedData
maxtask = task.size();
CString domaina;
GetDlgItemText(IDC_DOMAIN, domaina);
::domain = (LPCTSTR)domaina;
resolvedip.clear();
ThreadPool<testSpeedData> newtaskset(taskmutex);
newtaskset.Attach(threadnum, &task, &dataarray,m_list->m_hWnd);
newtaskset.Exec(testFunc);
OnBnClickedViewip();
}
void CFasterDNSDlg::InitOne(testSpeedData& obj)
{//初始化单个数据
obj.failtime = 0;
obj.lefttime = repeattime;
obj.responsetime = 0;
obj.testtime = repeattime;
obj.timeout = timeout;
}
void CFasterDNSDlg::OnBnClickedAllinone()
{
boost::mutex::scoped_lock mtask(taskmutex);
//list和data绑定,数据更改通过data更新list而不直接操作list,因此该锁同时绑定data和list
if (!task.empty())
{
AfxMessageBox("测试尚未结束,请先停止测试");
return;
}
int nCount = m_list->GetItemCount();
task.clear();
for (int i = 0; i < nCount; i++)
{
task.push_back(i);
}
boost::thread(boost::bind(&CFasterDNSDlg::DoDNSConnection, this));
}
void CFasterDNSDlg::OnBnClickedStart()
{//测试选中
boost::mutex::scoped_lock mtask(taskmutex);
if (!task.empty())
{
AfxMessageBox("测试尚未结束,请先停止测试");
return;
}
int uSelectedCount = m_list->GetSelectedCount();
int nItem = -1;
if (uSelectedCount > 0)
{
task.clear();
for (int i = 0; i < uSelectedCount; i++)
{
nItem = m_list->GetNextItem(nItem, LVNI_SELECTED);
InitOne(dataarray[nItem]);
task.push_back(nItem);
}
boost::thread(boost::bind(&CFasterDNSDlg::DoDNSConnection, this));
}
}
void CFasterDNSDlg::OnBnClickedStop()
{
//停止当前任务意味着清除剩余分配任务task
boost::mutex::scoped_lock mio(taskmutex);
//使用同一个锁保证不和分配任务线程操作冲突
task.clear();
}
void CFasterDNSDlg::OnBnClickedViewip()
{
CShowIp ipdlg(domain, resolvedip);
ipdlg.DoModal();
}
void CFasterDNSDlg::OnAdddns()
{
OnBnClickedAddDNS();
}
void CFasterDNSDlg::OnModify()
{
CGlobalSetting settings(threadnum, timeout, repeattime);
settings.DoModal();
}
void CFasterDNSDlg::OnStartall()
{
OnBnClickedAllinone();
}
void CFasterDNSDlg::OnStopall()
{
OnBnClickedStop();
}
void CFasterDNSDlg::OnTestip()
{
OnBnClickedViewip();
}
void CFasterDNSDlg::OnExit()
{
SendMessage(WM_CLOSE, 0, 0);
}
void CFasterDNSDlg::OnAllinone()
{
OnBnClickedAllinone();
}
void CFasterDNSDlg::OnStart()
{
OnBnClickedStart();
}
void CFasterDNSDlg::OnStop()
{
OnBnClickedStop();
}
// functions.cpp
#include "stdafx.h"
#include <boost/function.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/date_time.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>
#include <boost/system/error_code.hpp>
#include <vector>
#include <set>
#include <winsock.h>
#include <stdint.h>
#include <iphlpapi.h>
#include <windows.h>
#include "functions.h"
#include "sqlite3.h"
#pragma comment(lib,"sqlite3.lib")
#pragma comment(lib,"iphlpapi.lib")
/************************************************************************/
/* 单例模式获取实例 */
/************************************************************************/
std::vector<testSpeedData>* ipcontainer::testdata = NULL;
int* ipcontainer::pcount = NULL;
HWND ipcontainer::pwnd = NULL;
ipcontainer& ipcontainer::getInstance()
{
boost::mutex mio;
boost::mutex::scoped_lock lock(mio);
static ipcontainer container;
return container;
}
/************************************************************************/
/* 向数据库中增加dns数据
ip:待添加dns服务器ip地址(非域名) addr:待添加dns服务器地理位置 */
/************************************************************************/
bool ipcontainer::adddata(const std::string& ip, const std::string& addr)
{
int status = SQLITE_OK;
char* zErrMsg = NULL;
std::string toadd = "insert into dnss values ('" + ip + "','" + addr + "')";
try
{
status = sqlite3_exec(db, toadd.c_str(), NULL, NULL, &zErrMsg);
if (status != SQLITE_OK)
throw "Add failed!";
}
catch (...)
{
return false;
}
return true;
}
/************************************************************************/
/* 从数据库中删除dns数据
ip:待删除dns服务器ip地址(非域名) */
/************************************************************************/
bool ipcontainer::deldata(const std::string& ip)
{
int status = SQLITE_OK;
char* zErrMsg = NULL;
std::string toadd = "delete from dnss where ipaddr = '" + ip + "'";
try
{
status = sqlite3_exec(db, toadd.c_str(), NULL, NULL, &zErrMsg);
if (status != SQLITE_OK)
throw "Del failed!";
}
catch (...)
{
return false;
}
return true;
}
/************************************************************************/
/* 获取dns数据总入口
dataparam:存放获得数据结果 */
/************************************************************************/
bool ipcontainer::getdata(std::vector<testSpeedData>* dataparam, HWND listctrl)
{
try
{
ipcontainer::testdata = dataparam;
ipcontainer::pwnd = listctrl;
int status = SQLITE_OK;
char* zErrMsg = NULL;
status = sqlite3_exec(db, "select * from dnss", getdatacallback, NULL, &zErrMsg);
if (status != SQLITE_OK)
throw "Get failed!";
}
catch (...)
{
ipcontainer::testdata = NULL;
ipcontainer::pwnd = NULL;
return false;
}
ipcontainer::testdata = NULL;
ipcontainer::pwnd = NULL;
return true;
}
/************************************************************************/
/* 获取dns数据记录总数 */
/************************************************************************/
bool ipcontainer::getcount(int& count)
{
try
{
ipcontainer::pcount = &count;
int status = SQLITE_OK;
char* zErrMsg = NULL;
status = sqlite3_exec(db, "select count(*) from dnss", getcountcallback, NULL, &zErrMsg);
if (status != SQLITE_OK)
throw "Get failed!";
}
catch (...)
{
ipcontainer::pcount = NULL;
return false;
}
ipcontainer::pcount = NULL;
return true;
}
/************************************************************************/
/* 析构时关闭数据库 */
/************************************************************************/
ipcontainer::~ipcontainer()
{
ipcontainer::testdata = NULL;
ipcontainer::pcount = NULL;
ipcontainer::pwnd = NULL;
sqlite3_close(db);
db = NULL;
}
/************************************************************************/
/* 构造函数打开数据库 */
/************************************************************************/
ipcontainer::ipcontainer()
{
int status = SQLITE_OK;
db = NULL;
status = sqlite3_open(DATABASE, &db);
if (status != SQLITE_OK)
throw "Open failed!";
}
/************************************************************************/
/* 获取记录数据数组的回调函数,用于获取记录数据数组
argc:获得条目个数=2 argv[0]:ip argv:location */
/************************************************************************/
int ipcontainer::getdatacallback(void *NotUsed, int argc, char **argv, char **azColName)
{
LVITEM item = { 0 };
item.mask = LVIF_TEXT;
item.iItem = ipcontainer::testdata->size();
item.lParam = item.iItem;
item.pszText = LPSTR_TEXTCALLBACK;
ipcontainer::testdata->push_back(testSpeedData(argv[0], argv[1]));
SendMessage(pwnd, LVM_INSERTITEM, 0, (LPARAM)&item);
return 0;
}
/************************************************************************/
/* 获取记录条目的回调函数,用于得到记录条目
argc:获得条目个数=1 argv[0]:记录条目 */
/************************************************************************/
int ipcontainer::getcountcallback(void *NotUsed, int argc, char **argv, char **azColName)
{
try
{
*ipcontainer::pcount = boost::lexical_cast<int>(argv[0]);
}
catch (...)
{
*ipcontainer::pcount = 0;
}
return 0;
}
/************************************************************************/
/* 增加dns数据总入口
setpos:设置进度显示回调函数 dataparam:要添加的数据阵列*/
/************************************************************************/
bool doadddata(dbData* dataparam, HWND progctrl)
{
int size = dataparam->size() / 100;
int i = 0, j = 0;
SendMessage(progctrl, PBM_SETPOS, 0, 0);
try
{
dbData::const_iterator itor = dataparam->begin();
ipcontainer& container=ipcontainer::getInstance();
while (itor != dataparam->end())
{
container.adddata(itor->first, itor->second);
++itor;
++i;
if (i >= size)
{
i = 0;
SendMessage(progctrl, PBM_SETPOS, ++j, 0);
}
}
}
catch (...)
{
//发生错误
return false;
}
return true;
}
/************************************************************************/
/* 删除dns数据总入口
setpos:设置进度显示回调函数 dataparam:要删除的数据阵列*/
/************************************************************************/
bool dodeldata(std::vector<std::string>* dataparam, HWND progctrl)
{
int size = dataparam->size() / 100;
int i = 0, j = 0;
SendMessage(progctrl, PBM_SETPOS, 0, 0);
try
{
std::vector<std::string>::iterator itor = dataparam->begin();
ipcontainer& container = ipcontainer::getInstance();
while (itor != dataparam->end())
{
container.deldata(*itor);
++itor;
++i;
if (i >= size)
{
i = 0;
SendMessage(progctrl, PBM_SETPOS, ++j, 0);
}
}
}
catch (...)
{
//发生错误
return false;
}
return true;
}
/************************************************************************/
/* 尝试http连接
ip:要测试连通性的地址 timeout:超时返回 */
/************************************************************************/
bool dohttpconnect(const std::string& ip,uint32_t& timeout)
{//ip不能是域名 timeout同时用于设置超时和计时
using namespace boost::asio;
using namespace boost::posix_time;
try
{
tcpclient c;
boost::system::error_code ec;
setsockopt(c.socket_.native(), SOL_SOCKET, SO_RCVTIMEO, (const char*)timeout, sizeof(timeout));
ip::tcp::endpoint ep(ip::address::from_string(ip), PORT_HTTP);
ptime ptStart = microsec_clock::local_time();
c.connect(ep, boost::posix_time::millisec(timeout), ec);
if (ec.value())
throw "error";
ptime ptEnd = microsec_clock::local_time();
timeout = (int32_t)(ptEnd - ptStart).total_milliseconds();
}
catch (...)
{
return false;
}
return true;
}
/************************************************************************/
/* 尝试dns连接
ip:要测试连通性的地址 timeout:超时返回
bufferdata:用于发送和接收数据 */
/************************************************************************/
bool dodnsconnect(const std::string& ip, uint32_t& timeout,std::vector<uint8_t>& bufferdata)
{//bufferdata用于输入和输出 ip为服务器地址
using namespace boost::asio;
using namespace boost::posix_time;
try
{
udpclient c(ip::udp::endpoint(ip::udp::v4(), rand() & 0x7FFF + 0x8000));
boost::system::error_code ec;
setsockopt(c.socket_.native(), SOL_SOCKET, SO_RCVTIMEO, (const char*)timeout, sizeof(timeout));
setsockopt(c.socket_.native(), SOL_SOCKET, SO_BROADCAST, "\0\0\0\0", 4);
ip::udp::endpoint ep(ip::address::from_string(ip), PORT_DNS);
c.socket_.send_to(buffer((bufferdata)),ep);
bufferdata.clear();
bufferdata.resize(MAXS_RECVNUM);
ptime ptStart = microsec_clock::local_time();
c.receive(buffer(bufferdata), boost::posix_time::millisec(timeout), ec);
if (ec.value())
throw "error";
ptime ptEnd = microsec_clock::local_time();
timeout = (int32_t)(ptEnd - ptStart).total_milliseconds();
}
catch (...)
{
return false;
}
return true;
}
/************************************************************************/
/* 构造dns数据包
bufferdata:用于存储构造数据包结果
testdomain:用于验证的域名,不能用ip地址 */
/************************************************************************/
void makedns(std::vector<uint8_t>& bufferdata, const std::string& testdomain)
{//testip为验证ip,此函数用于testip更换时;Xid更换时用replaceXid
bufferdata.resize(sizeof(DNS_HEADER));
DNS_HEADER* pheader = (DNS_HEADER*)bufferdata.data();
memset(pheader, 0, sizeof(DNS_HEADER));
pheader->RecursionDesired = 1;
pheader->QuestionCount = 1;//查询一个域名
DNS_BYTE_FLIP_HEADER_COUNTS(pheader);
boost::asio::ip::address addr;
spliter splitvec;
boost::split(splitvec, testdomain, boost::is_any_of("."));
for (spliter::iterator itor = splitvec.begin(); itor != splitvec.end(); ++itor)
{
bufferdata.push_back((*itor).length());
bufferdata.insert(bufferdata.end(), (*itor).begin(),(*itor).end());
}
uint8_t tailer[SIZE_DNSTAILER] = { 0x00, 0x00, 0x01, 0x00, 0x01 };
bufferdata.insert(bufferdata.end(), tailer, tailer+SIZE_DNSTAILER);
}
/************************************************************************/
/* 修改dns数据包的TransactionID,考虑优化使用
bufferdata:待修改数据 Xid:新的TransactionID */
/************************************************************************/
void replaceXid(std::vector<uint8_t>& bufferdata, uint16_t Xid)
{
((DNS_HEADER*)bufferdata.data())->Xid = htons(Xid);
}
/************************************************************************/
/*从返回包结果中解析获取到的地址
bufferdata:服务器返回的待解析数据 resolveip:存储结果
originlen:发送包大小*/
/************************************************************************/
void resolveAnswer(std::vector<uint8_t>& bufferdata, std::set<std::string>& resolvedip, int originlen)
{
DNS_HEADER* pheader = (DNS_HEADER*)bufferdata.data();
DNS_BYTE_FLIP_HEADER_COUNTS(pheader);
uint8_t* ptr = (uint8_t*)pheader + originlen;
for (int i = 0; i < pheader->AnswerCount; i++)
{
DNSANSWER_HEADER* aheader = (DNSANSWER_HEADER*)ptr;
DNS_BYTE_FLIP_ANSWERHEADER_COUNTS(aheader);
if(aheader->Type == 1)//A:host address
{
BYTE* cdata = (BYTE*)aheader + sizeof(DNSANSWER_HEADER);
if (aheader->Datalength == 4)//ipv4
{
char temp[16];
sprintf_s(temp, "%d.%d.%d.%d", cdata[0], cdata[1], cdata[2], cdata[3]);
resolvedip.insert(std::string(temp));
}
else if (aheader->Datalength == 6)//ipv6
{
//v6的没有条件研究呢。。。
}
}
ptr += aheader->Datalength + sizeof(DNSANSWER_HEADER);
}
}
/************************************************************************/
/* 获取网卡适配器
interfaces:存储结果 */
/************************************************************************/
bool getinterface(std::vector<std::string>& interfaces)
{
DWORD dwRetVal = 0;
ULONG outBufLen = 15000;
LPVOID lpMsgBuf = NULL;
PIP_ADAPTER_ADDRESSES pAddress = NULL;
interfaces.clear();
do
{
pAddress = (IP_ADAPTER_ADDRESSES*)HeapAlloc(GetProcessHeap(), 0, outBufLen);
if (pAddress == NULL)
return false;
dwRetVal = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddress, &outBufLen);
if (dwRetVal == ERROR_BUFFER_OVERFLOW)
{
HeapFree(GetProcessHeap(), 0, pAddress);
pAddress = NULL;
}
} while (dwRetVal == ERROR_BUFFER_OVERFLOW);
if (dwRetVal != NO_ERROR)
return false;
PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddress;
while (pCurrAddresses)
{
HKEY hkResult;
std::string query = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
query += pCurrAddresses->AdapterName;
query += "\\Connection\\";
dwRetVal = RegOpenKey(HKEY_LOCAL_MACHINE, query.c_str(), &hkResult);
if (dwRetVal == ERROR_SUCCESS)
{
char buffer[256];
LONG cbData = 256;
dwRetVal = RegQueryValue(hkResult, "Name", buffer, &cbData);
if (dwRetVal == ERROR_SUCCESS)
{
interfaces.push_back((char*)buffer);
}
}
pCurrAddresses = pCurrAddresses->Next;
}
if (pAddress)
HeapFree(GetProcessHeap(), 0, pAddress);
return true;
}
/************************************************************************/
/* 设置指定网卡适配器dns
setpos:设置进度显示回调函数 interfaces:待设置适配器
address为点分十进制地址 */
/************************************************************************/
bool setinterface(std::vector<std::string>& interfaces, std::vector<std::string>& addresss, HWND progctrl)
{
using namespace boost::asio;
STARTUPINFO StartupInfo = { 0 };
PROCESS_INFORMATION ProcessInfo = { 0 };
StartupInfo.cb = sizeof(STARTUPINFO);
StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow = SW_HIDE;
std::string cmd;
int count = 0;
SendMessage(progctrl, PBM_SETPOS, 0, 0);
for (std::vector<std::string>::iterator itori = interfaces.begin(); itori != interfaces.end(); ++itori)
{
BOOL bRet;
cmd = "netsh interface ipv4 set dns name=\"" + *itori + "\" source=static addr=none";
//清除DNS设置
bRet=CreateProcess(NULL, (char*)cmd.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &StartupInfo, &ProcessInfo);
if (!bRet)
return false;
if (ProcessInfo.hProcess)
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
cmd = "netsh interface ipv6 set dns name=\"" + *itori + "\" source=static addr=none";
bRet = CreateProcess(NULL, (char*)cmd.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &StartupInfo, &ProcessInfo);
if (!bRet)
return false;
if (ProcessInfo.hProcess)
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
SendMessage(progctrl, PBM_SETPOS, int(100 * (float)count++ / interfaces.size()), 0);
SetWindowText(progctrl, ("正在清除设置 " + *itori).c_str());
for (std::vector<std::string>::iterator itora = addresss.begin(); itora != interfaces.end(); ++itora)
{
if ((ip::address::from_string(*itora)).is_v4())
cmd = "netsh interface ipv4 add dns name=\"" + *itori + "\" addr=" + *itora;
else
cmd = "netsh interface ipv6 add dns name=\"" + *itori + "\" addr=" + *itora;
SetWindowText(progctrl, ("正在设置 " + *itora).c_str());
bRet = CreateProcess(NULL, (char*)cmd.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &StartupInfo, &ProcessInfo);
if (!bRet)
return false;
if (ProcessInfo.hProcess)
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
}
}
return true;
}
/************************************************************************/
/* 封装getcount */
/************************************************************************/
bool getcount(int& count)
{
try
{
ipcontainer::getInstance().getcount(count);
}
catch (...)
{
return false;
}
return true;
}
/************************************************************************/
/* 封装getdata */
/************************************************************************/
bool getdata(std::vector<testSpeedData>* dataparam, HWND listctrl, HWND statu, boost::mutex* mu)
{
boost::mutex::scoped_lock mdata(*mu);
SetWindowText(statu, "正在初始化数据!");
try
{
ipcontainer::getInstance().getdata(dataparam, listctrl);
}
catch (...)
{
return false;
}
SetWindowText(statu, "初始化完毕!");
return true;
}