/*
that is pure Native Windows API code.
it should be executed from native application during
system boot.
*/
#include <ddkntddk.h>
#include "nt.h"
/*
file "nt.h" you can get here:
http://x1machine.com/db/ru/nt.rar
*/
// our remote functions prototypes
typedef VOID (NTAPI *my_RtlInitUnicodeString)(PUNICODE_STRING ,PCWSTR);
typedef NTSTATUS (NTAPI *my_NtDisplayString)(PUNICODE_STRING);
typedef NTSTATUS (NTAPI *my_NtTerminateThread)( HANDLE , NTSTATUS );
typedef NTSTATUS (NTAPI *my_NtDelayExecution)(BOOLEAN, PLARGE_INTEGER);
typedef struct _NtRemoteStructure {
PVOID pvRtlInitUnicodeString;
PVOID pvNtDisplayString;
PVOID pvNtTerminateThread;
WCHAR dbgMessage[100];
UNICODE_STRING output;
} NtRemoteStructure;
NtRemoteStructure my_Structure,*pmy_Structure;
HANDLE KeGetPID(WCHAR *pstrProcessName){
UNICODE_STRING dbgMessage;
NTSTATUS Status;
SIZE_T cbBuffer = 0x8000;
PVOID pBuffer = NULL;
HANDLE hResult = NULL;
PULONG dwId;
PSYSTEM_PROCESSES pProcesses;
RTL_HEAP_DEFINITION heapParams;
heapParams.Length = sizeof( RTL_HEAP_PARAMETERS );
do{
pBuffer = (void *)RtlAllocateHeap(NtGetProcessHeap(), 0, cbBuffer); if (pBuffer == NULL){return 0;}
Status = NtQuerySystemInformation(SystemProcessInformation, pBuffer, cbBuffer, NULL);
if (Status == STATUS_INFO_LENGTH_MISMATCH){
RtlFreeHeap(NtGetProcessHeap(), 0, pBuffer); cbBuffer *= 2;
}else if (!NT_SUCCESS(Status)){
RtlFreeHeap(NtGetProcessHeap(), 0, pBuffer); return 0;
}
}
while (Status == STATUS_INFO_LENGTH_MISMATCH);
pProcesses = (PSYSTEM_PROCESSES)pBuffer;
for (;;){
WCHAR *pszProcessName = pProcesses->ProcessName.Buffer;
if (pszProcessName == NULL)pszProcessName = L"Idle";
if(wcscmp(pszProcessName, pstrProcessName) == 0){
dwId = (HANDLE)pProcesses->ProcessId;
break;
}
if (pProcesses->NextEntryDelta == 0)break;
pProcesses = (PSYSTEM_PROCESSES)(((BYTE *)pProcesses)+ pProcesses->NextEntryDelta);
}
RtlFreeHeap(NtGetProcessHeap(), 0, pBuffer);
return dwId;
}
LPVOID NTAPI NtVirtualAllocEx(IN HANDLE hProcess,IN LPVOID lpAddress,IN SIZE_T dwSize, // VirtualAllocEx
IN DWORD flAllocationType, IN DWORD flProtect) {
NTSTATUS Status;
Status = NtAllocateVirtualMemory(hProcess,(PVOID *)&lpAddress,0,&dwSize,flAllocationType,flProtect);
if (!NT_SUCCESS(Status))return NULL;
return lpAddress;
}
BOOL NtDelayExecutionEx(DWORD dwSeconds){
LARGE_INTEGER Interval;
Interval.QuadPart = -(unsigned __int64)dwSeconds * 10000 * 1000;
NtDelayExecution (FALSE, &Interval);
}
DWORD __stdcall ReThread(NtRemoteStructure *Parameter){
my_RtlInitUnicodeString myRtlInitUnicodeString = (my_RtlInitUnicodeString)Parameter->pvRtlInitUnicodeString;
my_NtDisplayString myNtDisplayString = (my_NtDisplayString)Parameter->pvNtDisplayString;
my_NtTerminateThread myNtTerminateThread = (my_NtTerminateThread)Parameter->pvNtTerminateThread;
myRtlInitUnicodeString( &(Parameter->output), Parameter->dbgMessage);
myNtDisplayString(&Parameter->output);
myNtTerminateThread(NtCurrentThread(), 0);
}
void NtProcessStartup( PSTARTUP_ARGUMENT Argument ){
void *pThread;
HANDLE hProcess; // handle to smss
UNICODE_STRING dbgMessage, uniNameNtDLL; // ....[]....... ..тю тю тю...
OBJECT_ATTRIBUTES ObjectAttributes; // needed for open process function
BOOL en; // out argument, needed for adjust privilege function
WCHAR storage[250]; // here we will store smss's pid for later manipulations ;)
CLIENT_ID ClientId; // this will contain smss's pid
SIZE_T stThreadSize = 2048; // size of our remote thread
HANDLE hNtDLL; // handle to loaded ntdll.dll
ANSI_STRING ansiRtlInitUnicodeString, ansiNtDisplayString, ansiNtTerminateThread;
// ^ this strings will contain names of our import functions, passed to LdrGetProcedureAddress;
// functions names must be ansi strings
PVOID fRtlInitUnicodeString, fNtDisplayString, fNtTerminateThread;
RtlInitUnicodeString(&dbgMessage, L"nTrying to inject thread...n");
NtDisplayString( &dbgMessage );
RtlAdjustPrivilege(20, TRUE, AdjustCurrentProcess, &en); // set debug privileges
ClientId.UniqueProcess = (HANDLE)KeGetPID(L"smss.exe"); // get smss.exe pid
ClientId.UniqueThread = 0; // zero
swprintf(storage, L"smss pid: %d", ClientId); // store smss pid for later print out
RtlInitUnicodeString(&dbgMessage, storage);
NtDisplayString( &dbgMessage ); // print smss's pid
InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); // whatever...
NtOpenProcess(&hProcess, PROCESS_ALL_ACCESS , &ObjectAttributes, &ClientId); // open this smss.exe programm xD
pThread = NtVirtualAllocEx(hProcess, 0, stThreadSize, MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
NtWriteVirtualMemory(hProcess, pThread, &ReThread, stThreadSize,0);
RtlZeroMemory(&my_Structure,sizeof(NtRemoteStructure));
// ^ we are allocating memory in smss.exe
RtlInitUnicodeString(&uniNameNtDLL, L"ntdll.dll"); // convert "ntdll.dll" to unicode string
RtlInitAnsiString(&ansiRtlInitUnicodeString, "RtlInitUnicodeString"); // convertion to ansi string
RtlInitAnsiString(&ansiNtDisplayString, "NtDisplayString");
RtlInitAnsiString(&ansiNtTerminateThread, "NtTerminateThread");
LdrLoadDll(NULL ,0 , &uniNameNtDLL, &hNtDLL); // load ntdll.dll
LdrGetProcedureAddress(hNtDLL, &ansiRtlInitUnicodeString, 0, &fRtlInitUnicodeString);
LdrGetProcedureAddress(hNtDLL, &ansiNtDisplayString, 0, &fNtDisplayString);
LdrGetProcedureAddress(hNtDLL, &ansiNtTerminateThread, 0, &fNtTerminateThread);
// ^ lets get all needed procedures adresses
my_Structure.pvRtlInitUnicodeString = (void *)fRtlInitUnicodeString;
my_Structure.pvNtDisplayString = (void *)fNtDisplayString;
my_Structure.pvNtTerminateThread = (void *)fNtTerminateThread;
swprintf(my_Structure.dbgMessage, L"nInjected!n");
// ^ assign values to the structure
DWORD dwSize = sizeof(NtRemoteStructure);
pmy_Structure =(NtRemoteStructure *)NtVirtualAllocEx (hProcess ,0,sizeof(NtRemoteStructure),MEM_COMMIT,PAGE_READW RITE);
NtWriteVirtualMemory(hProcess ,pmy_Structure,&my_Structure,sizeof(my_Structure),0);
RtlCreateUserThread(hProcess, NULL,FALSE, 0, 0, 0,(PVOID)pThread,(PVOID)pmy_Structure, 0, 0);
NtClose(hProcess);
NtDelayExecutionEx(5); // just to show you output from our remote thread inside smss.exe
NtTerminateProcess( NtCurrentProcess(), 0 );
}
/*
compile with:
MinGW/bin/gcc.exe nt.c -o native.exe -lntdll -nostdlib -Wl,--subsystem,native,-e,_NtProcessStartup
*/