腾讯QQ珊瑚虫外挂原理分析
由于win nt 平臺(tái)和win9x 的差異,珊瑚蟲外掛因系統(tǒng)的不同而分開兩種工作原理
?
分析工具: softice , OD
我的操作系統(tǒng): win 2000 sp4 , win 98
分析對(duì)象: QQ2005賀歲版 珊瑚蟲外掛
?
為了方便分析,我先把CoralQQ.dll和coralqq.exe先脫殼,這兩個(gè)文件加的都是超弱殼,脫殼過程不在這里多說.
?
由于win nt 平臺(tái)和win9x 的差異,珊瑚蟲外掛因系統(tǒng)的不同而分開兩種工作原理.
?
我們都知道,珊瑚外掛是給QQ的主程序QQ.exe外掛了一個(gè)Coralqq.dll,而完成這個(gè)工作的就是coralqq.exe .要加載一個(gè)dll文件必須是qq.exe自己的某個(gè)線程執(zhí)行LoadLibraryA,并且以coralqq.dll為參數(shù),但qq.exe本來根本沒有這樣的一段代碼,怎么辦?答案很簡(jiǎn)單,既然它沒有,那就讓我們幫它加上去,coralqq.exe就是利用WriteProcessMemory幫QQ.exe加上了這樣一段代碼,并且改變程序流程,讓qq.exe先加載coralqq.dll再跳到原來的oep執(zhí)行.
?
想了一下,比較合理的方法有:
?
1.在nt內(nèi)核的系統(tǒng)上,利用遠(yuǎn)程線程的方法,首先用CreateProcess創(chuàng)建QQ.exe的進(jìn)程,同時(shí)創(chuàng)建了主線程,再用VirtualAllocEx在qq.exe中申請(qǐng)一塊內(nèi)存,然后把我們的代碼寫進(jìn)去,最后用CreateRemoteThread在qq的進(jìn)程中創(chuàng)建另外一個(gè)線程,其開始執(zhí)行的地方正是我們自己加入的代碼首地址.
?
2.先用CreateProcess創(chuàng)建QQ進(jìn)程和主線程,在QQ的內(nèi)存空間中找個(gè)合理的地方寫入我們的代碼,然后修改某個(gè)地方(例如OEP)使QQ先跳去執(zhí)行我們寫入的代碼,加載coralqq.dll,修復(fù)原來改過的oep,然后跳回oep讓程序正常執(zhí)行.
?
下面就讓我們分析一下珊瑚蟲的外掛是怎樣做到的,首先分析nt平臺(tái)上的運(yùn)行過程.
?
用OD載入脫殼后的coralqq.exe,停在下面:
00418E2C >/$ 55 push ebp
00418E2D . 8BEC mov ebp,esp
00418E2F . 83C4 F0 add esp,-10
00418E32 . B8 648D4100 mov eax,CoralQQ.00418D64
00418E37 . E8 A4BAFEFF call CoralQQ.004048E0
00418E3C . A1 F49D4100 mov eax,dword ptr ds:[419DF4]
00418E41 . 33D2 xor edx,edx
00418E43 . E8 30F4FFFF call CoralQQ.00418278
00418E48 . A1 F49D4100 mov eax,dword ptr ds:[419DF4]
00418E4D . 8B00 mov eax,dword ptr ds:[eax]
00418E4F . 83C0 18 add eax,18
00418E52 . E8 F9C6FEFF call CoralQQ.00405550
00418E57 . E8 08A9FEFF call CoralQQ.00403764
?
然后下斷點(diǎn): bp CreateRemoteThread ,然后運(yùn)行,結(jié)果發(fā)現(xiàn),OD根本沒有斷下,證明珊瑚蟲的外掛沒有使用遠(yuǎn)程線程的方法,難道它是用了第二種方法?我們?cè)衮?yàn)證一下:首先在OD中bp CreateProcess,斷下,反回后,用winhex打開QQ.exe的內(nèi)存,把QQ.exe的OEP處改為CC,接著在softice中 bpint 3 ,在OD中按F9運(yùn)行,接著就是中斷在softice中,把oep(464b58)處還原,在再softice下 bpm 464b58 ,然后結(jié)束程序,再運(yùn)行coralqq.exe發(fā)現(xiàn)自始至終那個(gè)bpm斷點(diǎn)還是沒有斷下,證明珊瑚蟲外掛在2000下也沒有修改QQ.exe的oep來改變程序流程,暈.沒辦法,只好在OD中下WriteProcessMemory斷點(diǎn),看看它究竟修改了哪里.
?
00231012 57 push edi
00231013 8B4424 24 mov eax,dword ptr ss:[esp+24]
00231017 A3 70302300 mov dword ptr ds:[233070],eax
0023101C 8305 70302300 04 add dword ptr ds:[233070],4
00231023 E8 5C000000 call ;創(chuàng)建QQ的進(jìn)程
上面創(chuàng)建后的QQ主線程是暫停的,不會(huì)馬上執(zhí)行,在win9x下也是這樣.
?
第一次中斷時(shí)堆棧顯示:
0012EBDC 0040C75C /CALL 到 WriteProcessMemory 來自 CoralQQ.0040C756
0012EBE0 00000018 hProcess = 00000018
0012EBE4 5F000000 Address = 5F000000
0012EBE8 00CC0F44 Buffer = 00CC0F44
0012EBEC 000000D2 BytesToWrite = D2 (210.)
0012EBF0 0012EC68 /pBytesWritten = 0012EC68
?
第二次:
0012EC70 00416231 /CALL 到 WriteProcessMemory 來自 CoralQQ.0041622C
0012EC74 00000018 hProcess = 00000018
0012EC78 5F010000 Address = 5F010000
0012EC7C 0012EE9F Buffer = 0012EE9F
0012EC80 00000025 BytesToWrite = 25 (37.)
0012EC84 0012EFD0 /pBytesWritten = 0012EFD0
?
第三次:
0012EC70 004162CB /CALL 到 WriteProcessMemory 來自 CoralQQ.004162C6
0012EC74 00000018 hProcess = 00000018
0012EC78 77F84BC0 Address = 77F84BC0
0012EC7C 0012EFC3 Buffer = 0012EFC3
0012EC80 00000005 BytesToWrite = 5
0012EC84 0012EFD0 /pBytesWritten = 0012EFD0
?
第四次:
0012EC70 0041632B /CALL 到 WriteProcessMemory 來自 CoralQQ.00416326
0012EC74 00000018 hProcess = 00000018
0012EC78 5F010025 Address = 5F010025
0012EC7C 0012EC96 Buffer = 0012EC96
0012EC80 00000208 BytesToWrite = 208 (520.)
0012EC84 0012EFD0 /pBytesWritten = 0012EFD0
?
第五次:
0012EC70 0041634B /CALL 到 WriteProcessMemory 來自 CoralQQ.00416346
0012EC74 00000018 hProcess = 00000018
0012EC78 5F010000 Address = 5F010000
0012EC7C 0012EE9F Buffer = 0012EE9F
0012EC80 00000025 BytesToWrite = 25 (37.)
0012EC84 0012EFD0 /pBytesWritten = 0012EFD0
?
?
留意第三次中斷: 77F84BC0 對(duì)應(yīng)著: NtTestAlert 所在庫(kù):ntdll.dll
?
程序每次執(zhí)行前都要經(jīng)過 ntdll.dll 的 NtTestAlert函數(shù),它使函數(shù)首句跳到某個(gè)
地方,從而改變程序流程.
00417E7E 8B45 F4 mov eax,dword ptr ss:[ebp-C]
00417E81 50 push eax
00417E82 E8 DDCDFEFF call ;使得QQ的主線程繼續(xù)執(zhí)行
?
把 0012efc3 處的E9改為CC,再在softice中bpint 3 ,讓其中斷后跟蹤:
001B:77F84BC0 E93BB408E7 JMP 5F010000
?
單步執(zhí)行跟蹤
?
001B:5F010000 B80000015F MOV EAX,5F010000
001B:5F010005 B90000005F MOV ECX,5F000000
001B:5F01000A FFD1 CALL ECX
?
此時(shí)ecx的值為5F000000
?
001B:5F000000 55 PUSH EBP
001B:5F000001 8BEC MOV EBP,ESP
001B:5F000003 83C4EC ADD ESP,-14
001B:5F000006 53 PUSH EBX
001B:5F000007 56 PUSH ESI
001B:5F000008 8BD8 MOV EBX,EAX
001B:5F00000A 896DFC MOV [EBP-04],EBP
001B:5F00000D 8B431C MOV EAX,[EBX+1C]
001B:5F000010 8B55FC MOV EDX,[EBP-04]
001B:5F000013 83C204 ADD EDX,04
001B:5F000016 8902 MOV [EDX],EAX
001B:5F000018 8B431C MOV EAX,[EBX+1C]
001B:5F00001B 8945EC MOV [EBP-14],EAX
001B:5F00001E C745FC05000000 MOV DWORD PTR [EBP-04],00000005
001B:5F000025 8D45F8 LEA EAX,[EBP-08]
001B:5F000028 50 PUSH EAX
001B:5F000029 6A40 PUSH 40
001B:5F00002B 8D45FC LEA EAX,[EBP-04]
001B:5F00002E 50 PUSH EAX
001B:5F00002F 8D45EC LEA EAX,[EBP-14]
001B:5F000032 50 PUSH EAX
001B:5F000033 6AFF PUSH FF
001B:5F000035 FF15C600005F CALL [5F0000C6]
001B:5F00003B 8B431C MOV EAX,[EBX+1C]
001B:5F00003E 8B5320 MOV EDX,[EBX+20]
001B:5F000041 8910 MOV [EAX],EDX ;恢復(fù)Ntdll.NtTestAlert入口處
001B:5F000043 8A5324 MOV DL,[EBX+24]
001B:5F000046 885004 MOV [EAX+04],DL
001B:5F000049 C745FC05000000 MOV DWORD PTR [EBP-04],00000005
001B:5F000050 8D45F8 LEA EAX,[EBP-08]
001B:5F000053 50 PUSH EAX
001B:5F000054 8B45F8 MOV EAX,[EBP-08]
001B:5F000057 50 PUSH EAX
001B:5F000058 8D45FC LEA EAX,[EBP-04]
001B:5F00005B 50 PUSH EAX
001B:5F00005C 8D45EC LEA EAX,[EBP-14]
001B:5F00005F 50 PUSH EAX
001B:5F000060 6AFF PUSH FF
001B:5F000062 FF15CA00005F CALL [5F0000CA]
001B:5F000068 8B7318 MOV ESI,[EBX+18]
001B:5F00006B 4E DEC ESI
001B:5F00006C 85F6 TEST ESI,ESI
001B:5F00006E 7C4C JL 5F0000BC
001B:5F000070 46 INC ESI
001B:5F000071 8D4325 LEA EAX,[EBX+25]
001B:5F000074 8BD8 MOV EBX,EAX
001B:5F000076 33D2 XOR EDX,EDX
001B:5F000078 8BC3 MOV EAX,EBX
001B:5F00007A 66833800 CMP WORD PTR [EAX],00
001B:5F00007E 740C JZ 5F00008C
001B:5F000080 42 INC EDX
001B:5F000081 83C002 ADD EAX,02
001B:5F000084 81FA03010000 CMP EDX,00000103
001B:5F00008A 75EE JNZ 5F00007A
001B:5F00008C 8BC2 MOV EAX,EDX
001B:5F00008E 03C0 ADD EAX,EAX
001B:5F000090 668945F0 MOV [EBP-10],AX
001B:5F000094 6683C002 ADD AX,02
001B:5F000098 668945F2 MOV [EBP-0E],AX
001B:5F00009C 8BC3 MOV EAX,EBX
001B:5F00009E 8945F4 MOV [EBP-0C],EAX
001B:5F0000A1 8D45FC LEA EAX,[EBP-04]
001B:5F0000A4 50 PUSH EAX
001B:5F0000A5 8D45F0 LEA EAX,[EBP-10]
001B:5F0000A8 50 PUSH EAX
001B:5F0000A9 6A00 PUSH 00
001B:5F0000AB 6A00 PUSH 00
001B:5F0000AD FF15CE00005F CALL [5F0000CE] ;call LoadLibraryA
001B:5F0000B3 81C308020000 ADD EBX,00000208
001B:5F0000B9 4E DEC ESI
001B:5F0000BA 75BA JNZ 5F000076
001B:5F0000BC 5E POP ESI
001B:5F0000BD 5B POP EBX
001B:5F0000BE 8BE5 MOV ESP,EBP
001B:5F0000C0 5D POP EBP
001B:5F0000C1 C3 RET
001B:5F0000C2 0000 ADD [EAX],AL
001B:5F0000C4 0000 ADD [EAX],AL
001B:5F0000C6 C4BFF877C4BF LES EDI,[EDI+BFC477F8]
001B:5F0000CC F8 CLC
001B:5F0000CD 7761 JA 5F000130
001B:5F0000CF 32F8 XOR BH,AL
001B:5F0000D1 7700 JA 5F0000D3
?
?
我們?cè)俜治鲆幌?/span>win9x下珊瑚蟲的外掛又是怎樣運(yùn)行的.
再次用OD載入Coralqq.exe
?
00415C9D mov dword ptr ss:[ebp-C],ecx
00415CA0 mov dword ptr ss:[ebp-4],edx
00415CA3 mov dword ptr ss:[ebp-8],eax
00415CA6 xor ebx,ebx
00415CA8 call ;判斷操作系統(tǒng)
00415CAD test eax,80000000
00415CB2 je short CORALQQ.00415CFE
00415CB4 xor edi,edi
00415CB6 xor esi,esi
00415CB8 jmp short CORALQQ.00415CE7
00415CBA /cmp esi,dword ptr ss:[ebp-24]
00415CBD je short CORALQQ.00415CE2
00415CBF mov eax,dword ptr ss:[ebp-4]
00415CC2 mov edx,dword ptr ss:[ebp-24]
00415CC5 mov dword ptr ds:[eax],edx
00415CC7 cmp dword ptr ss:[ebp-18],1000
00415CCE jnz short CORALQQ.00415CDF
00415CD0 push ebp ; /Arg1
00415CD1 call CORALQQ.00415BD4 ; /CoralQQ.00415BD4
00415CD6 pop ecx
00415CD7 test al,al
00415CD9 je short CORALQQ.00415CDF
00415CDB mov bl,1
00415CDD jmp short CORALQQ.00415D29
00415CDF mov esi,dword ptr ss:[ebp-24]
00415CE2 mov eax,dword ptr ss:[ebp-1C]
00415CE5 add edi,eax
00415CE7 push 1C ; /BufSize = 1C (28.)
00415CE9 lea eax,dword ptr ss:[ebp-28] ;
00415CEC push eax ; Buffer
00415CED push edi ; Address
00415CEE mov eax,dword ptr ss:[ebp-8] ;
00415CF1 push eax ; hProcess
00415CF2 call ; /VirtualQueryEx 獲得內(nèi)存業(yè)面信息
00415CF7 cmp eax,1C
00415CFA /je short CORALQQ.00415CBA
00415CFC jmp short CORALQQ.00415D29
?
上面的代碼是判斷操作系統(tǒng)的版本,如果是win9x的話就先跳到415ce7,
?
00415A4B > /8>lea eax,dword ptr ss:[ebp-8]
00415A4E . 5>push eax ; /pBytesWritten
00415A4F . 5>push edi ; BytesToWrite
00415A50 . 8>mov eax,dword ptr ss:[ebp-4] ;
00415A53 . 5>push eax ; Buffer
00415A54 . 5>push esi ; Address
00415A55 . 5>push ebx ; hProcess
00415A56 . E>call ; /WriteProcessMemory
?
看一下此時(shí)的堆棧:
0067EA5C 0000000C hProcess = 0000000C
0067EA60 83138AAC Address = 83138AAC
0067EA64 0067EABC Buffer = 0067EABC
0067EA68 00000292 BytesToWrite = 292 (658.)
0067EA6C 0067EA7C /pBytesWritten = 0067EA7C
?
它把緩沖區(qū) 0067eabc的658的字節(jié)寫進(jìn)QQ.exe的內(nèi)存 83138aac處,在win98下,進(jìn)程內(nèi)存中的共享(M
MF)分區(qū)是0x80000000~0xbfffffff,所有的內(nèi)存映射文件和系統(tǒng)共享DLL將加載在這個(gè)地址,而
那些映射文件和系統(tǒng)共享DLL往往都在比較高的地址,所以說,從80000000地址對(duì)上的一大段地址空間
往往是比較"空閑"的,當(dāng)然,并不是說這些地址就可以亂讀亂寫,至于這個(gè)83138aac的地址值具體是怎樣計(jì)算出來的,
我還沒有分析清楚,但我想到另外一種可行的方法,而且經(jīng)過我自己編程證實(shí),那就是以1000h大小為單位,從80000000
開始用WriteProcessMemory一直往上寫數(shù)據(jù),直到寫入成功,證明那段1000h的地址可用,而且1000h
大小的內(nèi)存空間已經(jīng)夠我們放代碼的了,之所以用1000h為單位大小,是因?yàn)榭紤]到塊對(duì)齊.
?
繼續(xù)跟蹤:
00415A39 . 8D45 F8 lea eax,dword ptr ss:[ebp-8]
00415A3C . 50 push eax ; /pOldProtect
00415A3D . 6A 40 push 40 ; NewProtect = PAGE_EXECUTE_READWRITE
00415A3F . 57 push edi ; Size
00415A40 . 56 push esi ; Address
00415A41 . 53 push ebx ; hProcess
00415A42 . E8 85F2FEFF call ; /VirtualProtectEx
?
上面的代碼是改變QQ.exe的oep處的屬性,使其可讀可寫可執(zhí)行,為改寫oep處的代碼做準(zhǔn)備
?
接著,又一次中斷在WriteProcessMemory
看看堆棧:
0067EA5C 0000000C hProcess = 0000000C
0067EA60 00464B58 Address = 464B58
0067EA64 0067EE46 Buffer = 0067EE46
0067EA68 00000005 BytesToWrite = 5
0067EA6C 0067EA7C /pBytesWritten = 0067EA7C
?
464b58就是QQ.exe的OEP,很明顯,它要改變oep來改變程序流程!!
?
好了,我們又用那套方法,把0067eea6的第一個(gè)字節(jié)改為cc,在softice中bpint 3,然后中斷,再
跟蹤.
在softice下中斷后:
0167:00464B58 E91328CE82 JMP 83147370
?
0167:83147370 C705584B4600558BEC6AMOV DWORD PTR [00464B58],6AEC8B55 ;馬上恢復(fù)oep處的代碼
0167:8314737A C6055C4B4600FF MOV BYTE PTR [00464B5C],FF
0167:83147381 68FA731483 PUSH 831473FA
0167:83147386 6838000000 PUSH 00000038
0167:8314738B 6A40 PUSH 40
0167:8314738D FF15F6731483 CALL [KERNEL32!GlobalAlloc] ;再申請(qǐng)內(nèi)存
0167:83147393 C700B85077F7 MOV DWORD PTR [EAX],F77750B8 ;從這里開始一直填入新數(shù)據(jù)
0167:83147399 C74004BFFFD068 MOV DWORD PTR [EAX+04],68D0FFBF
0167:831473A0 C7400870731483 MOV DWORD PTR [EAX+08],83147370
0167:831473A7 C7400CB89348E9 MOV DWORD PTR [EAX+0C],E94893B8
0167:831473AE C74010BFFFD0B8 MOV DWORD PTR [EAX+10],B8D0FFBF
0167:831473B5 C74014584B4600 MOV DWORD PTR [EAX+14],00464B58
0167:831473BC C74018FFE0C705 MOV DWORD PTR [EAX+18],05C7E0FF
0167:831473C3 C7401C584B4600 MOV DWORD PTR [EAX+1C],00464B58
0167:831473CA C74020558BEC6A MOV DWORD PTR [EAX+20],6AEC8B55
0167:831473D1 C74024C6055C4B MOV DWORD PTR [EAX+24],4B5C05C6
0167:831473D8 C740284600FF68 MOV DWORD PTR [EAX+28],68FF0046
0167:831473DF C7402CFA731483 MOV DWORD PTR [EAX+2C],831473FA
0167:831473E6 C7403068380000 MOV DWORD PTR [EAX+30],00003868
0167:831473ED C74034006A40FF MOV DWORD PTR [EAX+34],FF406A00
0167:831473F4 FFE0 JMP EAX ;此時(shí)eax為 0063059C
?
0167:0063059C B85077F7BF MOV EAX,KERNEL32!LoadLibraryA;加載Coralqq.dll
0167:006305A1 FFD0 CALL EAX
0167:006305A3 6870731483 PUSH 83147370
0167:006305A8 B89348E9BF MOV EAX,COMCTL32!ORD_0049
0167:006305AD FFD0 CALL EAX
0167:006305AF B8584B4600 MOV EAX,00464B58
0167:006305B4 FFE0 JMP EAX ;跳回QQ.exe的入口點(diǎn)
?
分析完畢.
到了這里,我們可以總結(jié)一下了,在win2000/xp下coralqq.exe先創(chuàng)建QQ的進(jìn)程,同時(shí)也就創(chuàng)建了
QQ的暫停的主線程,接著往QQ進(jìn)程的內(nèi)存寫入代碼,修改Ntdll.NtTestAlert的代碼跳讓程序跳到自己的
代碼處執(zhí)行,在執(zhí)行的過程中恢復(fù)Ntdll.NtTestAlert處被改了的代碼,同時(shí)加載Coralqq.dll.
?
在win9x下,coralqq.exe先創(chuàng)建QQ的進(jìn)程,同時(shí)也就創(chuàng)建了QQ的暫停的主線程,接著往QQ.exe的內(nèi)存
寫數(shù)據(jù),改寫QQ.exe的oep從而達(dá)到改變程序流程的目的,讓其先執(zhí)行加入了的代碼,加載Coralqq.dll,
加載完后再跳到原來的QQ.exe的oep繼續(xù)執(zhí)行.
其實(shí)在win2000/xp下面完全可以用遠(yuǎn)程線程的方法來實(shí)現(xiàn)加載dll文件,我后來自己編程實(shí)現(xiàn)了外掛
這一步.
也許有讀者讀完這編文章后會(huì)問:"加載了coralqq.dll又有什么用?它是怎樣顯IP的?"
其實(shí),要顯IP當(dāng)然要修改QQ的內(nèi)存中的代碼,而修改內(nèi)存代碼這一步是在加載coralqq.dll的時(shí)候由
coralqq.dll完成的.也就是說,在執(zhí)行LoadLibrary的過程中系統(tǒng)會(huì)執(zhí)行corall.dll的 LibMain ,修改
的過程就在LibMain中完成了!而說到顯IP的原理,抱歉,不在我們這編文章的討論范圍之內(nèi),我們只是討論
外掛中"掛"這一步.
?
下面是我寫的代碼,可以做出一個(gè)頂替Coralqq.exe的程序,但原理上和Coralqq.exe有一點(diǎn)點(diǎn)不同
?
.586
.model flat, stdcall
option casemap :none ; case sensitive
?
include windows.inc
include kernel32.inc
includelib kernel32.lib
?
.data
qq db "./QQ.exe",0
ikeyname db "qq",0
isecname db "main",0
szBuffer dw 50 dup(0)
?
dllname db "./CoralQQ.dll",0
szkernel32 db "Kernel32.dll",0
dllin dd 0
szloadlibrary db "LoadLibraryA",0
oaddr dd 0
wriaddr dd 0
ininame db "./CoralQQ.ini",0
?
.data?
align dword
con CONTEXT <>
align dword
con2 CONTEXT <>
?
stStartUp STARTUPINFO
stProcInfo PROCESS_INFORMATION
?
.code
start:
main proc
local wrisize:dword ;用來存放要寫入的代碼的大小
local num:dword
local oldpro:dword
local lastwri:dword
local wribase:dword ;用來存放寫入代碼的基址
invoke GetPrivateProfileString,offset isecname,offset ikeyname,/
offset szloadlibrary,offset szBuffer,/
sizeof szBuffer,offset ininame ;從Coralqq.ini中獲取QQ程序的路徑
invoke GetModuleHandle,offset szkernel32
invoke GetProcAddress,eax,offset szloadlibrary
mov dllin,eax
?
invoke GetStartupInfo,addr stStartUp
invoke CreateProcess,NULL,offset szBuffer,NULL,NULL,FALSE,/
CREATE_SUSPENDED,NULL,NULL,addr stStartUp,addr stProcInfo ;創(chuàng)建QQ進(jìn)程
cmp eax,0
jz exit
invoke GetVersion
test eax,080000000h ;判斷操作系統(tǒng)類型
jnz win9x
invoke VirtualAllocEx,stProcInfo.hProcess,NULL,01000h,MEM_COMMIT,/
PAGE_EXECUTE_READWRITE ;在QQ內(nèi)存中分配空間
mov oaddr,eax
invoke WriteProcessMemory,stProcInfo.hProcess,oaddr,offset dllname,/
sizeof dllname,addr num ;寫入數(shù)據(jù)
invoke CreateRemoteThread,stProcInfo.hProcess,NULL,0,dllin,oaddr,0,/
addr num ;創(chuàng)建遠(yuǎn)程線程
invoke CloseHandle,eax
invoke ResumeThread,stProcInfo.hThread ;讓QQ繼續(xù)運(yùn)行
invoke ExitProcess,0
ret
?
win9x:
mov wribase,oepwrite
mov wrisize,codeend-oepwrite
invoke VirtualProtect,wribase,wrisize,/
PAGE_EXECUTE_READWRITE,addr oldpro ;改變這個(gè)程序的要寫入代碼的地方的屬性,其實(shí)可以在編譯時(shí)加上開關(guān)
?
mov wrisize,codeend-codewrite
mov wriaddr,080000000h
sub wriaddr,1000h
again:
add wriaddr,1000h
mov wribase,codewrite
invoke WriteProcessMemory,stProcInfo.hProcess,wriaddr,/
wribase,wrisize,addr num ;寫入代碼
mov eax,wrisize
cmp eax,num
jnz again
?
mov eax,wriaddr
mov ebx,chan0-4
mov [ebx],eax
invoke VirtualProtectEx,stProcInfo.hProcess,0464b58h,7,/
PAGE_EXECUTE_READWRITE,addr oldpro ;改變QQ.exe的oep處的屬性
mov wribase,oepwrite
invoke WriteProcessMemory,stProcInfo.hProcess,0464b58h, wribase,7,/
addr num ;寫入數(shù)據(jù)
?
mov eax,dllin
mov ebx,chan2-4
mov [ebx],eax
mov eax,codeend-codewrite
add eax,wriaddr
mov ebx,chan1-4
mov [ebx],eax
mov wribase,codewrite
mov wrisize,codeend-codewrite
invoke WriteProcessMemory,stProcInfo.hProcess,wriaddr,/
wribase,wrisize,addr num
?
mov eax,codeend-codewrite
add eax,wriaddr
mov lastwri,eax
invoke WriteProcessMemory,stProcInfo.hProcess,lastwri,offset dllname,/
sizeof dllname,addr num
?
invoke ResumeThread,stProcInfo.hThread ;讓QQ繼續(xù)執(zhí)行
exit:
invoke ExitProcess,0
ret
?
?
main endp
?
;下面的都是要寫入到QQ.exe的內(nèi)存的附加代碼,但有些數(shù)值在寫入前要實(shí)時(shí)修正
?
oepwrite:
mov eax,0
chan0: jmp eax
?
codewrite:
mov eax,0464b58h
push 6aec8b55h
pop [eax]
mov eax,0464b5ch
push 101868ffh
pop [eax]
push 080000000
chan1:
push 464b58h
mov eax,0
chan2:
jmp eax
codeend:
?
end start
?
總結(jié)
以上是生活随笔為你收集整理的腾讯QQ珊瑚虫外挂原理分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android+蓝牙手柄+驱动+win1
- 下一篇: python 执行py文件_python