其實很簡單,這類控制元件(VCL、ActiveX)多半是用FindWindow、FindWindowEx等來查詢編譯器的IDE程式的視窗,據此來判斷IDE是否正在執行。當然實際上也可以透過自己的父程式名來判斷(即判斷自己的loader是誰)IDE是否正在執行;還可以列舉系統所有程式,從中查詢IDE的程式名・・・無非是根據IDE程式的某些獨有特徵。比如,假定某個IDE在執行時必定會建立一個名為“XXXXMutex”的mutex,則也可以透過是否存在這個mutex來判斷IDE是否正在執行。
例子:
VCLZip v2.22 for BCB5
http://www.donet.com/~vclzip/
關閉BCB,執行編譯好的程式,彈出個視窗說“This unregistered version of VCLZip will only run while
the Delphi/BCB IDE is running”。
反編譯VCLZipBCB5.bpl,看見:
* Referenced by a CALL at Addresses:
|:00406AA2 , :00410639 , :00410A2A , :00410F1F , :00410FF6
|:004110C8 , :00411206 , :004112F3 , :004113E3 , :004114EA
|:00411AA6
|
:004115C8 55
push ebp
:004115C9 8BEC
mov ebp, esp
:004115CB 6A00
push 00000000
:004115CD 6A00
push 00000000
:004115CF 53
push ebx
:004115D0 8BD8
mov ebx, eax
:004115D2 33C0
xor eax, eax
:004115D4 55
push ebp
:004115D5 68D1164100 push 004116D1
:004115DA 64FF30
push dword ptr fs:[eax]
:004115DD 648920
mov dword ptr fs:[eax], esp
:004115E0 F6432010 test
[ebx+20], 10
:004115E4 7554
jne 0041163A
:004115E6 E811170000 call 00412CFC
:004115EB 84C0
test al, al
:004115ED 754B
jne 0041163A
:004115EF 8D55F8
lea edx, dword ptr [ebp-08]
* Possible Reference to String Resource ID=00200: "This unregistered version
of VCLZip will only run while the "
|
:004115F2 B8C8000000 mov eax,
000000C8
* Reference To: VCL50.Sysutils::LoadStr(()), Ord:0000h
|
:004115F7 E8DC7A0000 Call 004190D8
:004115FC 8B55F8
mov edx, dword ptr [ebp-08]
:004115FF 8D8360010000 lea eax, dword
ptr [ebx+00000160]
* Reference To: VCL50.System::::LStrAsg(void()), Ord:0000h
|
:00411605 E87C780000 Call 00418E86
:0041160A 8D55FC
lea edx, dword ptr [ebp-04]
* Possible Reference to String Resource ID=00201: "Warning!"
|
:0041160D B8C9000000 mov eax,
000000C9
* Reference To: VCL50.Sysutils::LoadStr(()), Ord:0000h
|
:00411612 E8C17A0000 Call 004190D8
:00411617 6A00
push 00000000
:00411619 8D45FC
lea eax, dword ptr [ebp-04]
:0041161C E8BF6B0000 call 004181E0
:00411621 50
push eax
:00411622 8D8360010000 lea eax, dword
ptr [ebx+00000160]
:00411628 E8B36B0000 call 004181E0
:0041162D 50
push eax
:0041162E 6A00
push 00000000
:00411630 E8F57D0000 call 0041942A
* Reference To: VCL50.Sysutils::Abort(void()), Ord:0000h
|
:00411635 E8C6790000 Call 00419000
很明顯call 00412CFC是關鍵的,其中檢查BCB的IDE的視窗類和標題:
* Referenced by a CALL at Addresses:
|:0040F5E4 , :0040F5EF , :004115E6
|
* Possible StringData Ref from Data Obj ->"C++Builder 5"
|
:00412CFC 6890A44100 push 0041A490
:00412D01 6864A44100 push 0041A464
:00412D06 E813670000 call 0041941E
:00412D0B 85C0
test eax, eax
:00412D0D 7420
je 00412D2F
:00412D0F 6A00
push 00000000
:00412D11 6874A44100 push 0041A474
:00412D16 E803670000 call 0041941E
:00412D1B 85C0
test eax, eax
:00412D1D 7410
je 00412D2F
:00412D1F 6A00
push 00000000
* Possible StringData Ref from Data Obj ->"TAppBuilder"
|
:00412D21 6884A44100 push 0041A484
:00412D26 E8F3660000 call 0041941E
:00412D2B 85C0
test eax, eax
:00412D2D 7503
jne 00412D32
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00412D0D(C), :00412D1D(C)
|
:00412D2F 33C0
xor eax, eax
:00412D31 C3
ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00412D2D(C)
|
:00412D32 B001
mov al, 01
:00412D34 C3
ret