Corals plug Principle Analysis: RunJin runjin000@yahoo.com.cn analysis tools: softice, OD my operating system: win 2000 sp4, win 98 analysis objects: QQ2005 Hesuiban corals plug-in in order to facilitate analysis, and I put CoralQQ.dll Coralqq.exe first shells, these two files are superneath, the shelling process is not here. Due to the Win NT platform and Win9X difference, the coral insects have different working principles due to the different systems. We They all know that coral plug-in is a coralqq.dll, which is hung up to QQ's main program QQ.EXE, and completing this work is CORALQQ.exe. To load a DLL file must be QQ.EXE's own thread to perform LoadLibrarya, and With coralqq.dll as a parameter, QQ.EXE has not yet, what should I do? The answer is simple, since it doesn't, let us help it, CORALQQ.exe is using WriteProcessMemory to help QQ.EXE plus On such a code, and change the program process, let QQ.exe first load CORALQQ.dll to skip to the original OEP execution. Think, the relatively reasonable method is: 1. On the NT core system, use the remote thread Method, first create QQ.exe's process with CreateProcess, and create a primary thread, and use VirtualaLalkEx to apply for a memory in QQ.exe, then write our code, and finally create another one in QQ process in QQ process. Thread, where it starts to execute is the code first address we join. 2. first create QQ processes and main threads with CREATEPROCESS, find a reasonable place to write our code in QQ memory space, then modify a certain Place (for example, OEP) makes QQ first jumps to execute the code we wrote, loads CORALQQ.dll, fix the original OEP, then jump back to the OEP to make it normal. Let us analyze how the coral plug is doing First, analyze the running process on the NT platform. Use OD to load the shelled Coralqq.exe, stopped below: 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 Coralqqq.0040550 00418E57 |. E8 08A9FEFF CALALQ.00403764 Then the breakpoint: BP CreateRemoteThread, then run, the result is found that OD is not broken at all It is said that the method of the coral plug does not use the remote thread. Do you use the second method? We can then verify: First in OD, BP CreateProcess, broken, reverse, use WinHex to open QQ.EXE memory, Change the qq.exe's OEP to CC, followed by BPINT 3 in Softice, press F9 in OD to run, then it is interrupted in Softice, and the OEP (464B58) is still Original, in Softice, BPM 464B58, then end the program, then run CORALQQ.EXE to find that the BPM breakpoint is still not broken, prove that the coral insects have not modified QQ.EXE's OEP to change the program process, halo. No way, I have to go to the OD in the WriteProcessMemory breakpoint, see where it has been revised. 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
D2 (210.) 0012EBF0 0012EC68 / pBytesWritten = 0012EC68 Second: 0012EC70 00416231 / CALL to WriteProcessMemory from CoralQQ.0041622C 0012EC74 00000018 | hProcess = 00000018 0012EC78 5F010000 | Address = 5F010000 0012EC7C 0012EE9F | Buffer = 0012EE9F 0012EC80 00000025 | BytesToWrite = 25 ( 37.) 0012EC84 0012EFD0 / pBytesWritten = 0012EFD0 third: 0012EC70 004162CB / CALL to WriteProcessMemory from CoralQQ.004162C6 0012EC74 00000018 | hProcess = 00000018 0012EC78 77F84BC0 | Address = 77F84BC0 0012EC7C 0012EFC3 | Buffer = 0012EFC3 0012EC80 00000005 | BytesToWrite = 5 0012EC84 0012EFD0 / pBytesWritten = 0012EFD0 fourth: 0012EC70 0041632B / CALL to WriteProcessMemory from CoralQQ.00416326 0012EC74 00000018 | hProcess = 00000018 0012EC78 5F010025 | Address = 5F010025 0012EC7C 0012EC96 | Buffer = 0012EC96 0012EC80 00000208 | BytesToWrite = 208 (520.) 0012EC84 0012EFD0 / pBytesWritten = 0012EFD0 fifth: 0012EC70 0041634B / CALL to WRITEPROCESSMEMORY from CORALQQ.00416346 0012 EC74 00000018 | hProcess = 00000018 0012EC78 5F010000 | Address = 5F010000 0012EC7C 0012EE9F | Buffer = 0012EE9F 0012EC80 00000025 | BytesToWrite = 25 (37.) 0012EC84 0012EFD0 / pBytesWritten = 0012EFD0 pay attention to the third interruption: 77F84BC0 corresponds: NtTestAlert where the library: ntdll. DLL programs have to pass NTDLL.DLL's NTTESTALERT function before execution, which makes the first sentence to a certain place to change the program process. 00417E7E 8B45 F4 MOV EAX, DWORD PTR SS: [EBP-C] 00417E81 50 PUSH E8 DDCDFEFF CALL
Make the main thread of QQ to change the E9 at 0012EFC3 to CC, then in Softice, BPINT 3, let the broken track: 001b: 77F84BC0 E93BB408E7 JMP 5F010000 single-step execution Tracking 001b: 5F010000 B80000015F MOV EAX, 5F010000 001B: 5F010005 B90000005F MOV eCX, 5F000000 001B: 5F01000A FFD1 CALL eCX case ecx value 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;
Recovery Ntdll.NtTestAlert entrance 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 8D4 5F0 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 Let's analyze how Win9X's coral plug is running again. Use OD to load 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], EBX 00415CA6 XOR EBX, EBX 00415CA8 CALL
/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
0067EA7C It writes buffer 0067EABC's 658 byte into QQ.EXE memory 83138AAC, under Win98, shared (M MF) partition in process memory is 0x80000000 ~ 0xBFFFFFF, all memory maps and system sharing DLL Loading in this address, and those mapping files and system sharing DLLs are often relatively high, so, from the 80000000 address, a large number of address spaces are often comparative "free", of course, not to say these addresses. You can write a mess, as for how this 83138AAC's address value is calculated, I have not analyzed it, but I think another feasible method, and after my own programming confirmed, that is, the size of 1000h. From the 80000000, WriteProcessMemory has always writted data until the write is successful, proves that the address of the 1000H is available, and the memory space of 1000h is enough for us to put the code, the reason why the unit size is in size because it is considered to block alignment continue to follow: 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
Immediately recovery code oep at 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]; another Application Memory 0167: 83147393 C700B85077F7 MOV DWORD PTR [EAX], F77750B8; from here has been filled in the new data 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 C74024 C6055C4B 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 ], M 34], FF406A00 0167: 831473F4 FFE0 JMP EAX; this time EAX is 0063059C 0167: 0063059C B85077F7BF MOV Eax, kernel32! LoadingLibraryA;
Load 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; jump back to QQ! The entry point analysis of .exe is complete. Here, we can summarize it. Coralqq.exe in Win2000 / XP first created QQ process, and created the Paused main thread of QQ, then the memory of the QQ process Inc., modify NTDLL.NTTESTALERT code jump program jumps to its own code, recovering the code to be changed at NTDLL.nttelert during execution, and load coralqq.dll. Under Win9X, CORALQQ.exe first Create a QQ process, and create the main thread of QQ's suspension, then write data to QQ.EXE, to change QQ.EXE's OEP to change the purpose of changing the program process, let it execute the joined code, Load CORALQQ.dll, then skip to the original QQ.EXE OEP continues. In fact, in Win2000 / XP, you can use the remote thread method to implement the DLL file, I later programmed this step. There may be readers will ask: "What is the use of coralqq.dll?" Is it displayed for IP? "In fact, it is true that IP must modify the code in QQ memory, and modify memory code This step is done by coralqq.dll when loading coralqq.dll. That is, in the process of executing LoadLibrary, the system will execute corall.dll's libmain, and the process of modification is completed in libmain! The principle of IP, sorry, not within the discussion of our article, we just discuss the step "hanging" in the plug-in. Below is the code I wrote, you can make a proceedings for Coralqq.exe, but the principle There is a little bit different from coralqq.exe .586 .Model flat, stdcall option, 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;
Used to store the size of the code to be written to local num: dword local oldpro: dword local lastwri: dword local wribase: dword; written into the code used to store the base address invoke GetPrivateProfileString, offset isecname, offset ikeyname, / offset szloadlibrary, offset szBuffer, / sizeof szBuffer, offset ininame; QQ program acquired from Coralqq.ini path 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; create QQ process cmp eax, 0 jz exit invoke GetVersion test eax, 080000000h; determine the type of operating system jnz win9x invoke VirtualAllocEx, stProcInfo.hProcess, NULL, 01000h, MEM_COMMIT, / PAGE_EXECUTE_READWRITE; QQ in the allocated memory space mov oaddr, eax invoke WriteProcessMemory, stProcInfo.hProcess, oaddr, offset dllname, / sizeof dllname, addr num; write data invoke CreateRemoteThread, stProcInfo.hProcess, NULL, 0, dllin, OADDR, 0 , / Addr num; create a remote thread invoke CloseHandle, eax invoke ResumeThread, stProcInfo.hThread; let QQ continue invoke ExitProcess, 0 ret win9x: mov wribase, oepwrite mov wrisize, codeend-oepwrite invoke VirtualProtect, wribase, wrisize, / PAGE_EXECUTE_READWRITE, addr oldpro; local code to be written to change the attribute of this program, in fact, can be added at compile time switch mov wrisize, codeend-codewrite mov wriaddr, 080000000h sub wriaddr, 1000h again: add wriaddr, 1000h mov wribase, codewrite invoke WriteProcessMemory STPROCIMFO.HPROCESS, WRIADDR, / WRIBASE, WRISIZE, ADDR NUM