I-Windows Native Applications kanye nesevisi ye-Acronis Active Restore

Namuhla siqhubeka nendaba yokuthi thina, kanye nabafana baseNyuvesi yase-Innopolis, sithuthukisa kanjani ubuchwepheshe be-Active Restore ukuze sivumele umsebenzisi ukuthi aqale ukusebenza emshinini wabo ngokushesha ngangokunokwenzeka ngemva kokwehluleka. Sizokhuluma ngezinhlelo zokusebenza ze-Windows zomdabu, okuhlanganisa izici zokudala nokuqaliswa kwazo. Ngezansi kokusikiwe kukhona okuncane mayelana nephrojekthi yethu, kanye nomhlahlandlela osebenzayo wokuthi zibhalwa kanjani izinhlelo zokusebenza zomdabu.

I-Windows Native Applications kanye nesevisi ye-Acronis Active Restore

Emibhalweni edlule sesike sakhuluma ngokuthi kuyini Ukubuyisela Okusebenzayo, kanye nendlela abafundi base-Innopolis abathuthuka ngayo inkonzo. Namuhla ngifuna ukugxila ezinhlelweni zomdabu, ezingeni lapho sifuna β€œukungcwaba” insizakalo yethu yokutakula esebenzayo. Uma konke kusebenza kahle, sizokwazi:

  • Yethula isevisi ngokwayo kusenesikhathi
  • Xhumana nefu lapho isipele sitholakala ngaphambili kakhulu
  • Ngaphambili kakhulu ukuqonda ukuthi isistimu ikuyiphi imodi - ukuqalisa okujwayelekile noma ukutakula
  • Amafayela ambalwa kakhulu azobuyiselwa kusengaphambili
  • Vumela umsebenzisi ukuthi aqalise ngokushesha okukhulu.

Luyini uhlelo lokusebenza lwendabuko noma kunjalo?

Ukuze siphendule lo mbuzo, ake sibheke ukulandelana kwezingcingo ezenziwa yisistimu, isibonelo, uma umhleli esicelweni sakhe ezama ukudala ifayela.

I-Windows Native Applications kanye nesevisi ye-Acronis Active Restore
U-Pavel Yosifovich - I-Windows Kernel Programming (2019)

Umhleli usebenzisa umsebenzi YakhaIfayela, okumenyezelwe kunhlokweni yefayela fileapi.h futhi isetshenziswe ku-Kernel32.dll. Nokho, lo msebenzi ngokwawo awudali ifayela, uhlola kuphela izimpikiswano zokufaka bese ubiza umsebenzi NtCreateFile (isiqalo Nt sibonisa nje ukuthi umsebenzi ungowomdabu). Lo msebenzi umenyezelwe efayelini likanhlokweni we winternl.h futhi usetshenziswa kokuthi ntdll.dll. Ilungiselela ukugxumela endaweni yenuzi, emva kwalokho yenza ucingo lwesistimu ukuze yenze ifayela. Kulokhu, kuvela ukuthi i-Kernel32 imane nje iyisembozo se-Ntdll. Esinye sezizathu ezenza lokhu kwenziwe ukuthi iMicrosoft inamandla okushintsha imisebenzi yomhlaba wendabuko, kodwa hhayi ukuthinta izixhumanisi ezijwayelekile. I-Microsoft ayincomi ukubiza imisebenzi yomdabu ngokuqondile futhi ayibhalisi okuningi lwayo. Ngendlela, imisebenzi engabhaliwe ingatholakala lapha.

Inzuzo enkulu yezinhlelo zokusebenza zomdabu ukuthi i-ntdll ilayishwe ohlelweni ngaphambi kwesikhathi kakhulu kune-kernel32. Lokhu kunengqondo, ngoba i-kernel32 idinga ukuthi i-ntdll isebenze. Ngenxa yalokho, izinhlelo zokusebenza ezisebenzisa imisebenzi yomdabu zingaqala ukusebenza kusenesikhathi.

Ngakho-ke, izinhlelo zokusebenza ze-Windows Native ziyizinhlelo ezingaqala ekuqaleni kwe-Windows boot. Basebenzisa KUPHELA imisebenzi evela ku-ntdll. Isibonelo sohlelo lokusebenza olunjalo: autochk owenza chkdisk utility ukuhlola amaphutha kudiski ngaphambi kokuqala izinsiza eziyinhloko. Leli yizinga kanye esifuna ukuthi ukubuyisela okusebenzayo kube yilo.

Yini esiyidingayo?

  • I-DDK (Ikhithi Yokuthuthukisa Umshayeli), manje eyaziwa nangokuthi i-WDK 7 (Ikhithi Yomshayeli WeWindows).
  • Umshini obonakalayo (isibonelo, Windows 7 x64)
  • Akudingekile, kodwa amafayela anhlokweni angalandwa angasiza lapha

Yini ekukhodi?

Ake sizilolonge kancane futhi, isibonelo, sibhale isicelo esincane ukuthi:

  1. Ibonisa umlayezo esikrinini
  2. Inikeza inkumbulo ethile
  3. Ilinda okokufaka kwekhibhodi
  4. Ikhulula inkumbulo esetshenzisiwe

Kuzinhlelo zokusebenza zomdabu, indawo yokungena ayiyona eyinhloko noma ayiyona i-winmain, kodwa umsebenzi we-NtProcessStartup, njengoba empeleni sethula ngokuqondile izinqubo ezintsha ohlelweni.

Ake siqale ngokuveza umlayezo esibukweni. Kulokhu sinomsebenzi wendabuko I-NtDisplayString, okuthatha njengempikiswano isikhombi sento yesakhiwo UNICODE_STRING. I-RtlInitUnicodeString izosisiza ukuthi siyiqalise. Ngenxa yalokho, ukuze sibonise umbhalo esikrinini singabhala lo msebenzi omncane:

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

Njengoba kuphela imisebenzi evela ku-ntdll etholakala kithi, futhi awekho amanye amalabhulali enkumbulweni okwamanje, nakanjani sizoba nezinkinga ngendlela yokuwaba inkumbulo. Umsebenzisi omusha akakabi khona (ngoba uvela emhlabeni wezinga eliphezulu kakhulu le-C++), futhi awukho umsebenzi we-malloc (udinga imitapo yolwazi yesikhathi sokusebenza). Yiqiniso, ungasebenzisa kuphela isitaki. Kodwa uma sidinga ukwaba inkumbulo ngokuguquguqukayo, kuzodingeka sikwenze enqwabeni (okungukuthi, inqwaba). Ngakho-ke masizenzele inqwaba futhi sithathe inkumbulo kuyo noma nini lapho siyidinga.

Umsebenzi uwufanele lo msebenzi RtlCreateHeap. Okulandelayo, sisebenzisa i-RtlAllocateHeap ne-RtlFreeHeap, sizothatha futhi sikhulule inkumbulo lapho siyidinga.

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);

Asiqhubekele ekulindeni okokufaka kwekhibhodi.

// 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;
	}
}

Esikudingayo ukusebenzisa I-NtReadFile kudivayisi evuliwe, bese ulinda kuze kube yilapho ikhibhodi ibuyisela noma yikuphi ukucindezela kithi. Uma ukhiye we-ESC ucindezelwa, sizoqhubeka nokusebenza. Ukuze uvule idivayisi, sizodinga ukushayela umsebenzi we-NtCreateFile (sizodinga ukuvula i-DeviceKeyboardClass0). Nathi sizofona I-NtCreateEventukuqalisa into yokulinda. Sizomemezela isakhiwo se-KEYBOARD_INPUT_DATA ngokwethu, esimele idatha yekhibhodi. Lokhu kuzokwenza umsebenzi wethu ube lula.

Uhlelo lokusebenza lwendabuko luphetha ngocingo lomsebenzi NtTerminateProcessngoba simane sibulala eyethu inqubo.

Yonke ikhodi yesicelo sethu esincane:

#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: Singasebenzisa kalula umsebenzi we-DbgBreakPoint() kukhodi yethu ukuyimisa kusilungisi sephutha. Yiqiniso, uzodinga ukuxhuma i-WinDbg emshinini obonakalayo wokulungisa iphutha le-kernel. Imiyalo yokuthi ungakwenza kanjani lokhu ingatholakala lapha noma usebenzise nje I-VirtualKD.

Ukuhlanganisa nokuhlanganisa

Indlela elula yokwakha uhlelo lokusebenza lwendabuko ukusebenzisa I-DDK (Ikhithi Yokuthuthukisa Umshayeli). Sidinga inguqulo yakudala yesikhombisa, njengoba izinguqulo zakamuva zinendlela ehluke kancane futhi zisebenzisana eduze ne-Visual Studio. Uma sisebenzisa i-DDK, iphrojekthi yethu idinga kuphela i-Makefile nemithombo.

Makefile

!INCLUDE $(NTMAKEENV)makefile.def

imithombo:

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

I-Makefile yakho izofana ncamashi, kodwa ake sibheke imithombo ngokuningiliziwe okwengeziwe. Leli fayela licacisa imithombo yohlelo lwakho (.c amafayela), izinketho zokwakha, namanye amapharamitha.

  • TARGETNAME – igama lefayela elisebenzisekayo okufanele likhiqizwe ekugcineni.
  • TARGETTYPE – uhlobo lwefayela elisebenzisekayo, kungaba umshayeli (.sys), bese inani lenkambu kufanele libe ngu-DRIVER, uma umtapo wezincwadi (.lib), bese inani lithi LIBRARY. Esimweni sethu, sidinga ifayela elisebenzisekayo (.exe), ngakho-ke sibeka inani ku-PROGRAM.
  • UMTYPE - amanani angenzeka kule nkambu: ikhonsoli yohlelo lokusebenza lwekhonsoli, amawindi okusebenza ngemodi enewindi. Kodwa sidinga ukucacisa nt ukuze sithole uhlelo lokusebenza lwendabuko.
  • BUFFER_OVERFLOW_CHECKS – sibheka isitaki ngokuchichima kwebhafa, ngeshwa akulona icala lethu, siyasivala.
  • MINWIN_SDK_LIB_PATH – leli nani libhekisela kokuhluka kwe-SDK_LIB_PATH, ungakhathazeki ngokuthi awunakho okuguquguqukayo kwesistimu okumenyezelwe, uma siqalisa ukwakhiwa okuhloliwe kusuka ku-DDK, lokhu kuhlukahluka kuzomenyezelwa futhi kuzokhomba kumalabhulali adingekayo.
  • IMITHOMBO – uhlu lwemithombo yohlelo lwakho.
  • IHLANGANISA - amafayela anhlokweni adingekayo ukuze ahlanganiswe. Lapha bavame ukukhombisa indlela eya kumafayela afika ne-DDK, kodwa ungakwazi futhi ukucacisa noma yimaphi amanye.
  • I-TARGETLIBS – uhlu lwemitapo yolwazi edinga ukuxhunywa.
  • I-USE_NTDLL iyinkambu edingekayo okufanele isethelwe ku-1 ngezizathu ezisobala.
  • USER_C_FLAGS – noma imaphi amafulegi ongawasebenzisa kuziqondiso zangaphambi kokucubungula lapho ulungiselela ikhodi yohlelo.

Ngakho-ke ukwakha, sidinga ukusebenzisa i-x86 (noma i-x64) Ihloliwe Yakha, shintsha uhla lwemibhalo olusebenzayo kufolda yephrojekthi bese uqhuba umyalo othi Yakha. Umphumela kusithombe-skrini ubonisa ukuthi sinefayela elilodwa elisebenzisekayo.

I-Windows Native Applications kanye nesevisi ye-Acronis Active Restore

Leli fayela alikwazi ukwethulwa kalula kangaka, uhlelo luyaqalekisa futhi lisithumele ukuthi sicabange ngokuziphatha kwalo ngephutha elilandelayo:

I-Windows Native Applications kanye nesevisi ye-Acronis Active Restore

Ungaluqalisa kanjani uhlelo lokusebenza lwendabuko?

Lapho i-autochk iqala, ukulandelana kokuqalisa kwezinhlelo kunqunywa inani lokhiye wokubhalisa:

HKLMSystemCurrentControlSetControlSession ManagerBootExecute

Umphathi weseshini usayinisa izinhlelo ezivela kulolu hlu ngayinye ngayinye. Umphathi weseshini ubheka amafayela asebenzisekayo ngokwawo kumkhombandlela we-system32. Ifomethi yenani lokhiye wokubhalisa imi kanje:

autocheck autochk *MyNative

Inani kufanele libe ngefomethi ye-hexadecimal, hhayi i-ASCII evamile, ukuze ukhiye oboniswe ngenhla ube ngefomethi:

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

Ukuguqula isihloko, ungasebenzisa isevisi eku-inthanethi, isibonelo, lokhu.

I-Windows Native Applications kanye nesevisi ye-Acronis Active Restore
Kuvela ukuthi ukuqalisa uhlelo lokusebenza lwendabuko, sidinga:

  1. Kopisha ifayela elisebenzisekayo kufolda ye-system32
  2. Engeza ukhiye kurejista
  3. Qalisa kabusha umshini

Ukuze kube lula, nasi iskripthi esenziwe ngomumo sokufaka isicelo somdabu:

install.bat

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

engeza.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

Ngemva kokufaka nokuqalisa kabusha, nangaphambi kokuba kuvele isikrini sokukhetha umsebenzisi, sizothola isithombe esilandelayo:

I-Windows Native Applications kanye nesevisi ye-Acronis Active Restore

Umphumela

Sisebenzisa isibonelo sohlelo lokusebenza oluncane kangaka, sasiqiniseka ukuthi kungenzeka ukusebenzisa uhlelo ku-Windows Native level. Okulandelayo, abafana baseNyuvesi yase-Innopolis kanye nami sizoqhubeka nokwakha isevisi ezoqala inqubo yokusebenzisana nomshayeli ngaphambi kwesikhathi kakhulu kunenguqulo yangaphambilini yephrojekthi yethu. Futhi ngokufika kwegobolondo le-win32, kungaba okunengqondo ukudlulisa ukulawula kusevisi ephelele esivele yakhiwe (ngaphezulu kulokhu. lapha).

Esihlokweni esilandelayo sizothinta enye ingxenye yesevisi ye-Active Restore, okungukuthi umshayeli we-UEFI. Bhalisela ibhulogi yethu ukuze ungaphuthelwa okuthunyelwe okulandelayo.

Source: www.habr.com

Engeza amazwana