Seirbheis Windows Native Applications agus Acronis Active Restore

An-diugh tha sinn a’ leantainn leis an sgeulachd air mar a tha sinn, còmhla ris na balaich bho Oilthigh Innopolis, a’ leasachadh teicneòlas Active Restore gus leigeil leis an neach-cleachdaidh tòiseachadh ag obair air an inneal aca cho luath ‘s a ghabhas às deidh fàilligeadh. Bruidhnidh sinn mu thagraidhean dùthchasach Windows, a’ toirt a-steach feartan an cruthachadh agus an cur air bhog. Fon gearradh tha beagan mun phròiseact againn, a bharrachd air stiùireadh practaigeach air mar a sgrìobhas tu tagraidhean dùthchasach.

Seirbheis Windows Native Applications agus Acronis Active Restore

Ann an dreuchdan roimhe tha sinn air bruidhinn mu thràth mu dè a th’ ann Ath-bheothachadh gnìomhach, agus mar a leasaicheas oileanaich à Innopolis seirbheis. An-diugh tha mi airson fòcas a chuir air tagraidhean dùthchasach, chun na h-ìre gu bheil sinn airson ar seirbheis ath-bheothachaidh gnìomhach a “adhlacadh”. Ma dh’ obraicheas a h-uile càil a-mach, is urrainn dhuinn:

  • Cuir air bhog an t-seirbheis fhèin mòran nas tràithe
  • Cuir fios chun sgòth far a bheil an cùl-taic fada nas tràithe
  • Gu math nas tràithe gus tuigsinn dè am modh anns a bheil an siostam - bròg àbhaisteach no ath-bheothachadh
  • Tòrr nas lugha de fhaidhlichean ri fhaighinn air ais ro-làimh
  • Leig leis an neach-cleachdaidh tòiseachadh eadhon nas luaithe.

Dè a th’ ann an app dùthchasach co-dhiù?

Gus a 'cheist seo a fhreagairt, leig dhuinn sùil a thoirt air an t-sreath de ghlaodhan a bhios an siostam a' dèanamh, mar eisimpleir, ma tha prògramadair san iarrtas aige a 'feuchainn ri faidhle a chruthachadh.

Seirbheis Windows Native Applications agus Acronis Active Restore
Pavel Yosifovich - Prògramadh Windows Kernel (2019)

Cleachdaidh am prògramadair an gnìomh Cruthaich Faidhle, a tha air ainmeachadh anns an fhaidhle header fileapi.h agus air a chuir an gnìomh ann an Kernel32.dll. Ach, chan eil an gnìomh seo fhèin a’ cruthachadh am faidhle, cha dèan e ach sgrùdadh air na h-argamaidean a-steach agus gairm an gnìomh NtCreateFile (tha an ro-leasachan Nt dìreach a’ sealltainn gu bheil an gnìomh dùthchasach). Tha an gnìomh seo air ainmeachadh ann am faidhle header winternl.h agus air a chuir an gnìomh ann an ntdll.dll. Bidh e ag ullachadh airson leum a-steach don àite niùclasach, às deidh sin bidh e a ’dèanamh gairm siostam gus faidhle a chruthachadh. Anns a ’chùis seo, tha e a’ tionndadh a-mach nach eil ann an Kernel32 ach pasgan airson Ntdll. Is e aon de na h-adhbharan airson seo a dhèanamh gu bheil comas aig Microsoft mar sin gnìomhan an t-saoghail dhùthchasach atharrachadh, ach gun a bhith a’ beantainn ris an eadar-aghaidh àbhaisteach. Chan eil Microsoft a’ moladh a bhith a’ gairm ghnìomhan dùthchasach gu dìreach agus chan eil e a’ clàradh a’ mhòr-chuid dhiubh. Air an t-slighe, gheibhear gnìomhan gun sgrìobhainn an seo.

Is e am prìomh bhuannachd a tha aig tagraidhean dùthchasach gu bheil ntdll air a luchdachadh a-steach don t-siostam fada nas tràithe na kernel32. Tha seo loidsigeach, oir feumaidh kernel32 ntdll a bhith ag obair. Mar thoradh air an sin, faodaidh tagraidhean a chleachdas gnìomhan dùthchasach tòiseachadh ag obair mòran nas tràithe.

Mar sin, is e prògraman a th’ ann an Windows Native Applications a thòisicheas tràth ann am bròg Windows. Bidh iad A-MHÀIN a’ cleachdadh gnìomhan bho ntdll. Eisimpleir de leithid de thagradh: fèineag a bhios a' coileanadh goireas chkdisk gus sùil a thoirt air an diosc airson mhearachdan mus tòisich thu air na prìomh sheirbheisean. Is e seo dìreach an ìre a tha sinn ag iarraidh gum bi ar Active Restore.

Dè a dh'fheumas sinn?

  • DDK (Kit Leasachaidh Dràibhearan), ris an canar a-nis WDK 7 (Windows Driver Kit).
  • Inneal mas-fhìor (mar eisimpleir, Windows 7 x64)
  • Chan eil feum air, ach dh’ fhaodadh gun cuidich faidhlichean cinn a ghabhas luchdachadh a-nuas an seo

Dè th' anns a' chòd?

Cleachdamaid beagan agus, mar eisimpleir, sgrìobh sinn tagradh beag a tha:

  1. A’ taisbeanadh teachdaireachd air an sgrion
  2. A 'riarachadh beagan cuimhne
  3. A’ feitheamh ri cuir a-steach meur-chlàr
  4. A 'saoradh cuimhne cleachdte

Ann an tagraidhean dùthchasach, chan e prìomh àite no winmain a th’ anns an àite inntrigidh, ach gnìomh NtProcessStartup, leis gu bheil sinn dha-rìribh a’ cur pròiseasan ùra air bhog san t-siostam.

Feuch an tòisich sinn le bhith a’ taisbeanadh teachdaireachd air an sgrion. Airson seo tha gnìomh dùthchasach againn NtDisplayString, a bheir mar argamaid puing gu nì structarail UNICODE_STRING. Cuidichidh RtlInitUnicodeString sinn gus a thòiseachadh. Mar thoradh air an sin, gus teacsa a thaisbeanadh air an sgrion is urrainn dhuinn an gnìomh beag seo a sgrìobhadh:

//usage: WriteLn(L"Here is my textn");
void WriteLn(LPWSTR Message)
{
    UNICODE_STRING string;
    RtlInitUnicodeString(&string, Message);
    NtDisplayString(&string);
}

Leis nach eil ach gnìomhan bho ntdll rim faighinn dhuinn, agus dìreach nach eil leabharlannan eile ann mar chuimhneachan fhathast, gu cinnteach bidh duilgheadasan againn a thaobh mar a thèid cuimhne a riarachadh. Chan eil an gnìomhaiche ùr ann fhathast (seach gu bheil e a’ tighinn bhon t-saoghal ro àrd-ìre C ++), agus chan eil gnìomh malloc ann (feumaidh e leabharlannan runtime C). Gu dearbh, chan urrainn dhut ach stac a chleachdadh. Ach ma dh’ fheumas sinn cuimhne a riarachadh gu dinamach, feumaidh sinn a dhèanamh air a’ chàrn (i.e. tiùrr). Mar sin cruthaichidh sinn carn dhuinn fhìn agus bheir sinn cuimhne bhuaithe uair sam bith a bhios feum againn air.

Tha an gnìomh freagarrach airson na h-obrach seo RtlCreateHeap. An ath rud, a’ cleachdadh RtlAllocateHeap agus RtlFreeHeap, bidh sinn a’ gabhail còmhnaidh agus a’ saoradh cuimhne nuair a bhios feum againn air.

PVOID memory = NULL;
PVOID buffer = NULL;
ULONG bufferSize = 42;

// create heap in order to allocate memory later
memory = RtlCreateHeap(
  HEAP_GROWABLE, 
  NULL, 
  1000, 
  0, NULL, NULL
);

// allocate buffer of size bufferSize
buffer = RtlAllocateHeap(
  memory, 
  HEAP_ZERO_MEMORY, 
  bufferSize
);

// free buffer (actually not needed because we destroy heap in next step)
RtlFreeHeap(memory, 0, buffer);

RtlDestroyHeap(memory);

Gluaisidh sinn air adhart gu bhith a’ feitheamh ri cuir a-steach meur-chlàr.

// https://docs.microsoft.com/en-us/windows/win32/api/ntddkbd/ns-ntddkbd-keyboard_input_data
typedef struct _KEYBOARD_INPUT_DATA {
  USHORT UnitId;
  USHORT MakeCode;
  USHORT Flags;
  USHORT Reserved;
  ULONG  ExtraInformation;
} KEYBOARD_INPUT_DATA, *PKEYBOARD_INPUT_DATA;

//...

HANDLE hKeyBoard, hEvent;
UNICODE_STRING skull, keyboard;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK Iosb;
LARGE_INTEGER ByteOffset;
KEYBOARD_INPUT_DATA kbData;

// inialize variables
RtlInitUnicodeString(&keyboard, L"DeviceKeyboardClass0");
InitializeObjectAttributes(&ObjectAttributes, &keyboard, OBJ_CASE_INSENSITIVE, NULL, NULL);

// open keyboard device
NtCreateFile(&hKeyBoard,
			SYNCHRONIZE | GENERIC_READ | FILE_READ_ATTRIBUTES,
			&ObjectAttributes,
			&Iosb,
			NULL,
			FILE_ATTRIBUTE_NORMAL,
			0,
			FILE_OPEN,FILE_DIRECTORY_FILE,
			NULL, 0);

// create event to wait on
InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
NtCreateEvent(&hEvent, EVENT_ALL_ACCESS, &ObjectAttributes, 1, 0);

while (TRUE)
{
	NtReadFile(hKeyBoard, hEvent, NULL, NULL, &Iosb, &kbData, sizeof(KEYBOARD_INPUT_DATA), &ByteOffset, NULL);
	NtWaitForSingleObject(hEvent, TRUE, NULL);

	if (kbData.MakeCode == 0x01)    // if ESC pressed
	{
			break;
	}
}

Chan eil againn ach a chleachdadh NtReadFile air inneal fosgailte, agus feitheamh gus an till am meur-chlàr air ais thugainn. Ma thèid an iuchair ESC a bhrùthadh, cumaidh sinn oirnn ag obair. Gus an inneal fhosgladh, feumaidh sinn an gnìomh NtCreateFile a ghairm (feumaidh sinn DeviceKeyboardClass0 fhosgladh). Canaidh sinn cuideachd Tachartas ntCreategus an nì feitheamh a thòiseachadh. Cuiridh sinn an cèill structar KEYBOARD_INPUT_DATA sinn fhìn, a tha a’ riochdachadh dàta a’ mheur-chlàir. Nì seo ar n-obair nas fhasa.

Bidh an tagradh dùthchasach a’ crìochnachadh le gairm gnìomh Pròiseas NtTerminateoir tha sinn dìreach a 'marbhadh ar pròiseas fhèin.

A h-uile còd airson an tagradh beag againn:

#include "ntifs.h" // WinDDK7600.16385.1incddk
#include "ntdef.h"

//------------------------------------
// Following function definitions can be found in native development kit
// but I am too lazy to include `em so I declare it here
//------------------------------------

NTSYSAPI
NTSTATUS
NTAPI
NtTerminateProcess(
  IN HANDLE               ProcessHandle OPTIONAL,
  IN NTSTATUS             ExitStatus
);

NTSYSAPI 
NTSTATUS
NTAPI
NtDisplayString(
	IN PUNICODE_STRING String
);

NTSTATUS 
NtWaitForSingleObject(
  IN HANDLE         Handle,
  IN BOOLEAN        Alertable,
  IN PLARGE_INTEGER Timeout
);

NTSYSAPI 
NTSTATUS
NTAPI
NtCreateEvent(
    OUT PHANDLE             EventHandle,
    IN ACCESS_MASK          DesiredAccess,
    IN POBJECT_ATTRIBUTES   ObjectAttributes OPTIONAL,
    IN EVENT_TYPE           EventType,
    IN BOOLEAN              InitialState
);



// https://docs.microsoft.com/en-us/windows/win32/api/ntddkbd/ns-ntddkbd-keyboard_input_data
typedef struct _KEYBOARD_INPUT_DATA {
  USHORT UnitId;
  USHORT MakeCode;
  USHORT Flags;
  USHORT Reserved;
  ULONG  ExtraInformation;
} KEYBOARD_INPUT_DATA, *PKEYBOARD_INPUT_DATA;

//----------------------------------------------------------
// Our code goes here
//----------------------------------------------------------

// usage: WriteLn(L"Hello Native World!n");
void WriteLn(LPWSTR Message)
{
    UNICODE_STRING string;
    RtlInitUnicodeString(&string, Message);
    NtDisplayString(&string);
}

void NtProcessStartup(void* StartupArgument)
{
	// it is important to declare all variables at the beginning
	HANDLE hKeyBoard, hEvent;
	UNICODE_STRING skull, keyboard;
	OBJECT_ATTRIBUTES ObjectAttributes;
	IO_STATUS_BLOCK Iosb;
	LARGE_INTEGER ByteOffset;
	KEYBOARD_INPUT_DATA kbData;
	
	PVOID memory = NULL;
	PVOID buffer = NULL;
	ULONG bufferSize = 42;

	//use it if debugger connected to break
	//DbgBreakPoint();

	WriteLn(L"Hello Native World!n");

	// inialize variables
	RtlInitUnicodeString(&keyboard, L"DeviceKeyboardClass0");
	InitializeObjectAttributes(&ObjectAttributes, &keyboard, OBJ_CASE_INSENSITIVE, NULL, NULL);

	// open keyboard device
	NtCreateFile(&hKeyBoard,
				SYNCHRONIZE | GENERIC_READ | FILE_READ_ATTRIBUTES,
				&ObjectAttributes,
				&Iosb,
				NULL,
				FILE_ATTRIBUTE_NORMAL,
				0,
				FILE_OPEN,FILE_DIRECTORY_FILE,
				NULL, 0);

	// create event to wait on
	InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
	NtCreateEvent(&hEvent, EVENT_ALL_ACCESS, &ObjectAttributes, 1, 0);
	
	WriteLn(L"Keyboard readyn");
	
	// create heap in order to allocate memory later
	memory = RtlCreateHeap(
	  HEAP_GROWABLE, 
	  NULL, 
	  1000, 
	  0, NULL, NULL
	);
	
	WriteLn(L"Heap readyn");

	// allocate buffer of size bufferSize
	buffer = RtlAllocateHeap(
	  memory, 
	  HEAP_ZERO_MEMORY, 
	  bufferSize
	);
	
	WriteLn(L"Buffer allocatedn");

	// free buffer (actually not needed because we destroy heap in next step)
	RtlFreeHeap(memory, 0, buffer);

	RtlDestroyHeap(memory);
	
	WriteLn(L"Heap destroyedn");
	
	WriteLn(L"Press ESC to continue...n");

	while (TRUE)
	{
		NtReadFile(hKeyBoard, hEvent, NULL, NULL, &Iosb, &kbData, sizeof(KEYBOARD_INPUT_DATA), &ByteOffset, NULL);
		NtWaitForSingleObject(hEvent, TRUE, NULL);

		if (kbData.MakeCode == 0x01)    // if ESC pressed
		{
				break;
		}
	}

	NtTerminateProcess(NtCurrentProcess(), 0);
}

PS: Is urrainn dhuinn an gnìomh DbgBreakPoint() sa chòd againn a chleachdadh gu furasta gus stad a chuir air san dì-bhugadair. Fìor, feumaidh tu WinDbg a cheangal ri inneal brìgheil airson debugging kernel. Gheibhear stiùireadh air mar a nì thu seo an seo no dìreach cleachd VirtualKD.

Cruinneachadh agus co-chruinneachadh

Is e an dòigh as fhasa tagradh dùthchasach a thogail a chleachdadh DDK (Kit Leasachaidh Dràibhearan). Feumaidh sinn an t-seachdamh dreach àrsaidh, oir tha dòigh-obrach beagan eadar-dhealaichte aig dreachan nas fhaide air adhart agus bidh iad ag obair gu dlùth le Visual Studio. Ma chleachdas sinn an DDK, chan fheum ar pròiseact ach Makefile agus stòran.

Dèan cinnteach

!INCLUDE $(NTMAKEENV)makefile.def

stòran:

TARGETNAME			= MyNative
TARGETTYPE			= PROGRAM
UMTYPE				= nt
BUFFER_OVERFLOW_CHECKS 		= 0
MINWIN_SDK_LIB_PATH		= $(SDK_LIB_PATH)
SOURCES 			= source.c

INCLUDES 			= $(DDK_INC_PATH); 
				  C:WinDDK7600.16385.1ndk;

TARGETLIBS 			= $(DDK_LIB_PATH)ntdll.lib	
				  $(DDK_LIB_PATH)nt.lib

USE_NTDLL			= 1

Bidh do Makefile dìreach mar an ceudna, ach leig dhuinn sùil a thoirt air stòran ann am beagan nas mionaidiche. Bidh am faidhle seo a 'sònrachadh stòran a' phrògraim agad (.c faidhlichean), roghainnean togail, agus crìochan eile.

  • TARGETNAME - ainm an fhaidhle so-ghnìomhaichte a bu chòir a thoirt a-mach aig a’ cheann thall.
  • TARGETTYPE - seòrsa faidhle so-ghnìomhaichte, faodaidh e a bhith na dhràibhear (.sys), an uairsin bu chòir luach an raoin a bhith DRIVER, ma tha leabharlann (.lib) ann, is e LEABHARLANG an luach. Anns a’ chùis againn, feumaidh sinn faidhle so-ghnìomhaichte (.exe), agus mar sin suidhich sinn an luach gu PROGRAM.
  • UMTYPE - luachan a dh’ fhaodadh a bhith san raon seo: tòcan airson tagradh tòcan, uinneagan airson a bhith ag obair ann am modh uinneig. Ach feumaidh sinn nt a shònrachadh gus tagradh dùthchasach fhaighinn.
  • BUFFER_OVERFLOW_CHECKS - a’ sgrùdadh a’ chruach airson tar-shruth bufair, gu mì-fhortanach chan e a’ chùis againn, bidh sinn ga tionndadh dheth.
  • MINWIN_SDK_LIB_PATH - tha an luach seo a’ toirt iomradh air an caochladair SDK_LIB_PATH, na gabh dragh nach eil an leithid de chaochladair siostam agad air ainmeachadh, nuair a ruitheas sinn togail le seic bhon DDK, thèid an caochladair seo ainmeachadh agus comharraichidh e na leabharlannan riatanach.
  • SOURCES - liosta de stòran airson do phrògram.
  • A 'GABHAIL A-STEACH - faidhlichean cinn a tha riatanach airson co-chruinneachadh. An seo mar as trice bidh iad a’ comharrachadh an t-slighe gu na faidhlichean a thig leis an DDK, ach faodaidh tu cuideachd gin eile a shònrachadh.
  • TARGETLIBS - liosta de leabharlannan a dh’ fheumas a bhith ceangailte.
  • Tha USE_NTDLL na raon riatanach a dh'fheumas a bhith air a shuidheachadh gu 1 airson adhbharan follaiseach.
  • USER_C_FLAGS - brataichean sam bith as urrainn dhut a chleachdadh ann an stiùiridhean ro-phròiseasar nuair a bhios tu ag ullachadh còd tagraidh.

Mar sin airson togail, feumaidh sinn x86 (no x64) Checked Build a ruith, atharraich an eòlaire obrach gu pasgan a’ phròiseict agus ruith an àithne Togail. Tha an toradh san dealbh-sgrìn a’ sealltainn gu bheil aon fhaidhle so-ghnìomhaichte againn.

Seirbheis Windows Native Applications agus Acronis Active Restore

Chan urrainnear am faidhle seo a chuir air bhog cho furasta, tha an siostam a’ mallachadh agus gar cur gu smaoineachadh air a ghiùlan leis a’ mhearachd a leanas:

Seirbheis Windows Native Applications agus Acronis Active Restore

Ciamar a chuireas tu tagradh dùthchasach air bhog?

Nuair a thòisicheas autochk, tha an t-sreath tòiseachaidh de phrògraman air a dhearbhadh le luach iuchair a’ chlàr:

HKLMSystemCurrentControlSetControlSession ManagerBootExecute

Bidh manaidsear an t-seisein a' cur an gnìomh prògraman bhon liosta seo aon ri aon. Bidh manaidsear an t-seisein a’ coimhead airson na faidhlichean so-ghnìomhaichte iad fhèin san eòlaire system32. Tha cruth prìomh luach a’ chlàraidh mar a leanas:

autocheck autochk *MyNative

Feumaidh an luach a bhith ann an cruth hexadecimal, chan e an ASCII àbhaisteach, agus mar sin bidh an iuchair gu h-àrd san fhòrmat:

61,75,74,6f,63,68,65,63,6b,20,61,75,74,6f,63,68,6b,20,2a,00,4d,79,4e,61,74,69,76,65,00,00

Gus an tiotal a thionndadh, faodaidh tu seirbheis air-loidhne a chleachdadh, mar eisimpleir, seo.

Seirbheis Windows Native Applications agus Acronis Active Restore
Tha e coltach gum feum sinn:

  1. Dèan lethbhreac den fhaidhle so-ghnìomhaichte gu pasgan system32
  2. Cuir iuchair ris a’ chlàr
  3. Ath-thòisich an inneal

Airson goireasachd, seo sgriobt deiseil airson a bhith a’ stàladh tagradh dùthchasach:

stàladh.bat

@echo off
copy MyNative.exe %systemroot%system32.
regedit /s add.reg
echo Native Example Installed
pause

cuir.reg

REGEDIT4

[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession Manager]
"BootExecute"=hex(7):61,75,74,6f,63,68,65,63,6b,20,61,75,74,6f,63,68,6b,20,2a,00,4d,79,4e,61,74,69,76,65,00,00

Às deidh an stàladh agus ath-thòiseachadh, eadhon mus nochd an scrion taghadh cleachdaiche, gheibh sinn an dealbh a leanas:

Seirbheis Windows Native Applications agus Acronis Active Restore

An toradh

A’ cleachdadh an eisimpleir de thagradh cho beag, bha sinn cinnteach gu bheil e gu math comasach an aplacaid a ruith aig ìre Windows Native. An uairsin, cumaidh na balaich bho Oilthigh Innopolis agus mise a’ togail seirbheis a thòisicheas am pròiseas eadar-obrachadh leis an draibhear fada nas tràithe na anns an dreach roimhe den phròiseact againn. Agus le teachd an t-slige win32, bhiodh e loidsigeach smachd a ghluasad gu seirbheis làn-chuimseach a chaidh a leasachadh mar-thà (barrachd air seo an seo).

Anns an ath artaigil bruidhnidh sinn air pàirt eile den t-seirbheis Ath-nuadhachadh Gnìomhach, is e sin an draibhear UEFI. Subscribe to ar blog gus nach caill thu an ath phost.

Source: www.habr.com

Cuir beachd ann