Windows Aplikasi Asli sareng layanan Acronis Active Restore

Dinten ieu, urang bade neraskeun carita ngeunaan kumaha urang damel sareng Universitas Innopolis pikeun ngembangkeun téknologi Active Restore supados pangguna tiasa neraskeun damel dina mesinna gancang-gancang saatos kacilakaan. Urang bade ngobrol ngeunaan aplikasi asli. Windows, kalebet spésifikasi tina kreasi sareng peluncuranna. Di handap ieu aya sakedik latar tukang ngeunaan proyék kami, ogé pituduh praktis ngeunaan kumaha nyerat aplikasi asli.

Windows Aplikasi Asli sareng layanan Acronis Active Restore

Dina tulisan sateuacana urang parantos nyarioskeun naon éta Aktip Mulangkeun, sareng kumaha murid ti Innopolis berkembang palayananDinten ayeuna, kuring hoyong difokuskeun aplikasi asli, dimana urang hoyong "ngubur" jasa pamulihan aktip kami. Lamun sagalana jalan kaluar, urang bakal bisa:

  • Ngajalankeun jasa sorangan leuwih awal
  • Kontak awan dimana cadangan lokasina leuwih saméméhna
  • Saméméhna mungkin ngartos naon mode sistem - boot normal atawa recovery
  • Langkung sakedik file pikeun pulih sateuacanna
  • Ngidinan pangguna pikeun ngamimitian langkung gancang.

Naon ari aplikasi asli?

Pikeun ngajawab patarosan ieu, hayu urang nempo runtuyan panggero sistem, contona, lamun programmer dina aplikasi na nyoba nyieun file.

Windows Aplikasi Asli sareng layanan Acronis Active Restore
Pavel Yosifovich — Windows Pemrograman Kernel (2019)

Programmer ngagunakeun fungsi JieunFile, anu dinyatakeun dina file header fileapi.h sareng dilaksanakeun dina Kernel32.dll. Sanajan kitu, fungsi ieu sorangan teu nyieun file; éta ngan ukur pariksa argumen input sareng nyauran fungsina. NtCreateFile (Awalan Nt nunjukkeun yén fungsina asli). Pungsi ieu dinyatakeun dina file lulugu winternl.h sarta dilaksanakeun dina ntdll.dll. Nyiapkeun pikeun luncat ka rohangan kernel, saatos éta nelepon sistem pikeun nyiptakeun file. Dina hal ieu, Kernel32 ngan saukur bungkus pikeun Ntdll. Salah sahiji alesan pikeun ieu nyaéta ku kituna Microsoft tiasa ngarobih fungsi asli tanpa mangaruhan antarmuka standar. Microsoft henteu nyarankeun nyauran fungsi asli sacara langsung sareng henteu ngadokumentasikeun kalolobaanana. Saliwatan, fungsi undocumented bisa kapanggih di dieu.

Kauntungan utama tina aplikasi asli nyaéta ntdll dimuat kana sistem sacara signifikan langkung awal ti kernel32. Ieu logis, sabab kernel32 merlukeun ntdll pikeun fungsi. Hasilna, aplikasi anu nganggo pungsi asli tiasa ngamimitian damel langkung awal.

Ku kituna, Windows Aplikasi Asli nyaéta program anu tiasa dijalankeun langkung awal nalika boot. WindowsAranjeunna ngan ukur nganggo fungsi tina ntdll. Conto aplikasi sapertos kitu: autochk nu ngalaksanakeun chkdisk utiliti Pikeun mariksa disk pikeun kasalahan sateuacan ngamimitian jasa utama. Ieu persis tingkat dimana urang hoyong Active Restore beroperasi.

Urang peryogi naon?

  • DDK (Pakakas Pangwangunan Supir), ayeuna katelah ogé WDK 7 (Windows Pakakas Supir).
  • Mesin virtual (misalna. Windows 7 x64)
  • Teu perlu, tapi file lulugu nu bisa diundeur bisa mantuan. di dieu

Naon dina kode?

Hayu urang latihan saeutik tur nulis aplikasi leutik salaku conto yén:

  1. Mintonkeun pesen dina layar
  2. Allocates sababaraha memori
  3. Ngadagoan input keyboard
  4. Frees up memori dijajah

Dina aplikasi asli, titik Éntri teu utama atawa winmain, tapi fungsi NtProcessStartup, saprak urang sabenerna langsung dimimitian prosés anyar dina sistem.

Hayu urang mimitian ku mintonkeun pesen dina layar. Kami ngagaduhan fungsi asli pikeun ieu. NtDisplayString, nu nyokot pointer kana objék struktur UNICODE_STRING salaku argumen. RtlInitUnicodeString bakal ngabantosan urang ngamimitian. Hasilna, pikeun mintonkeun téks dina layar, urang bisa nulis fungsi leutik kawas kieu:

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

Kusabab urang ngan boga aksés ka fungsi ti ntdll, tur teu aya perpustakaan séjén dina mémori acan, urang pasti boga masalah allocating memori. The operator anyar teu acan aya (sabab asalna ti dunya teuing-tingkat C ++), tur euweuh fungsi malloc (merlukeun runtime perpustakaan C). Tangtosna, urang ngan ukur tiasa nganggo tumpukan. Tapi lamun urang kudu dinamis allocate memori, urang gé kudu ngalakukeun hal eta dina numpuk. Ku kituna hayu urang nyieun tumpukan pikeun diri urang sorangan sarta nyandak memori ti eta nalika urang butuh eta.

Fungsi anu cocog pikeun ieu tugas nyaéta RtlCreateHeapSalajengna, nganggo RtlAllocateHeap sareng RtlFreeHeap, kami bakal nyayogikeun sareng ngosongkeun mémori nalika kami peryogina.

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

Hayu urang ngaléngkah ka ngantosan input keyboard.

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

Sadaya anu urang kedah laksanakeun nyaéta ngagunakeunana NtReadFile dina alat nu kabuka sarta antosan nepi ka kibor mulangkeun keystroke a. Lamun kenop ESC dipencet, urang bakal neruskeun gawé. Pikeun muka alat, urang kedah nyauran fungsi NtCreateFile (DeviceKeyboardClass0 kedah dibuka). Urang ogé bakal nelepon NtCreateEventpikeun initialize obyék pikeun ngantosan. Urang bakal sacara manual nyatakeun struktur KEYBOARD_INPUT_DATA, anu ngagambarkeun data keyboard. Ieu bakal ngagampangkeun padamelan urang.

Aplikasi asli ditungtungan ku telepon fungsi NtTerminateProcess, sabab urang ngan saukur maéhan prosés urang sorangan.

Sakabéh kode pikeun aplikasi leutik kami:

#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: Urang bisa kalayan gampang ngagunakeun fungsi DbgBreakPoint () dina kode urang eureun debugger. Nanging, urang kedah nyambungkeun WinDbg ka mesin virtual pikeun debugging kernel. Pitunjuk ngeunaan cara ngalakukeun ieu tiasa dipendakan di dieu. di dieu atawa ngan ngagunakeun VirtualKD.

Kompilasi jeung assembly

Cara panggampangna pikeun ngawangun aplikasi asli nyaéta ngagunakeun DDK (Supir Development Kit). Urang husus kudu versi katujuh kuna, sakumaha versi engké boga pendekatan rada béda jeung dianggo raket jeung Visual Studio. Upami kami nganggo DDK, proyék kami ngan ukur peryogi Makefile sareng sumber.

Ngadamel

!INCLUDE $(NTMAKEENV)makefile.def

sumber:

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

Makefile anjeun bakal persis sarua, tapi hayu urang nempo sumber dina bit leuwih jéntré. Berkas ieu netepkeun kode sumber program anjeun (.c file), pilihan ngawangun, sareng parameter sanésna.

  • TARGETNAME – ngaran file laksana anu kudu dihasilkeun salaku hasilna.
  • TARGETTYPE - jinis file anu tiasa dieksekusi. Bisa jadi supir (.sys), dina hal ieu nilai widang kudu DRIVER; lamun éta perpustakaan (.lib), nilai kudu PUSTAKA. Dina kasus urang, urang peryogi file anu tiasa dieksekusi (.exe), ku kituna urang nyetél nilai kana PROGRAM.
  • UMTYPE - nilai anu mungkin pikeun widang ieu: konsol pikeun aplikasi konsol, windows pikeun ngajalankeun dina modeu windowed. Nanging, urang kedah netepkeun nt pikeun kéngingkeun aplikasi asli.
  • BUFFER_OVERFLOW_CHECKS - mariksa tumpukan pikeun panyangga mudal, hanjakalna teu bisi urang, urang nganonaktipkeun.
  • MINWIN_SDK_LIB_PATH - nilai ieu nujul kana variabel SDK_LIB_PATH. Tong hariwang upami anjeun henteu gaduh variabel sistem anu sami anu dinyatakeun. Nalika urang ngajalankeun hiji ngawangun dipariksa ti DDK, variabel ieu bakal dinyatakeun sarta bakal nunjuk ka perpustakaan perlu.
  • SUMBER – daptar sumber program anjeun.
  • Kaasup - file lulugu diperlukeun pikeun ngawangun. Ieu biasana nangtukeun jalur ka file kaasup kana DDK, tapi anjeun bisa nangtukeun mana wae tambahan.
  • TARGETLIBS - daptar perpustakaan pikeun numbu.
  • USE_NTDLL mangrupakeun widang diperlukeun nu kudu disetel ka 1. Pikeun alesan atra.
  • USER_C_FLAGS - sagala umbul nu bisa Anjeun pake dina directives preprocessor nalika Nyiapkeun kode aplikasi.

Janten, pikeun ngawangun, urang kedah ngajalankeun x86 (atanapi x64) Checked Build, ngarobih diréktori kerja kana folder proyék, sareng ngajalankeun paréntah Build. Potret layar nunjukkeun yén kami parantos ngawangun hiji file anu tiasa dieksekusi.

Windows Aplikasi Asli sareng layanan Acronis Active Restore

file ieu moal ngajalankeun jadi gampang; sistem complains sarta ngabejaan urang mikir ngeunaan kabiasaan na kalawan kasalahan handap:

Windows Aplikasi Asli sareng layanan Acronis Active Restore

Kumaha ngajalankeun aplikasi asli?

Nalika autochk dimimitian, runtuyan peluncuran program ditangtukeun ku nilai konci pendaptaran:

HKLMSystemCurrentControlSetControlSession ManagerBootExecute

Pangatur sési ngaéksekusi program tina daptar ieu hiji-hiji. Pangatur sési milarian file anu tiasa dieksekusi dina diréktori system32. Format nilai konci pendaptaran nyaéta kieu:

autocheck autochk *MyNative

Nilaina kedah dina format héksadesimal, sanés ASCII biasa, janten konci anu dipidangkeun di luhur bakal gaduh format ieu:

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

Pikeun ngarobah nami, anjeun tiasa nganggo jasa online, contona, ieu.

Windows Aplikasi Asli sareng layanan Acronis Active Restore
Tétéla pikeun ngaluncurkeun aplikasi asli, urang peryogi:

  1. Nyalin file laksana ka folder system32
  2. Tambahkeun konci pikeun pendaptaran
  3. Reboot mesin

Pikeun genah anjeun, ieu skrip anu siap-siap pikeun masang aplikasi asli:

install.bat

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

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

Saatos instalasi sareng reboot, sateuacan layar pamilihan pangguna muncul, urang bakal ningali gambar ieu:

Windows Aplikasi Asli sareng layanan Acronis Active Restore

hasil

Ngagunakeun aplikasi leutik ieu salaku conto, kami yakin yén ngaluncurkeun aplikasi dina tingkat Windows Native téh mungkin pisan. Salajengna, abdi sareng réréncangan ti Universitas Innopolis bakal teras ngawangun layanan anu bakal ngamimitian interaksi sareng supir langkung awal tibatan dina vérsi proyék kami sateuacanna. Sareng kalayan datangna cangkang Win32, bakal logis pikeun mindahkeun kontrol ka layanan lengkep anu parantos dikembangkeun (langkung seueur ngeunaan éta engké). di dieu).

Dina artikel salajengna urang, urang bakal nutupan komponén séjén tina jasa Active Restore: supir UEFI. Ngalanggan blog kami pikeun tetep up-to-date sareng postingan salajengna.

sumber: www.habr.com

Mésér hosting anu dipercaya pikeun situs anu gaduh panyalindungan DDoS, server VPS VDS 🔥 Meser hosting situs wéb anu tiasa dipercaya nganggo panyalindungan DDoS, server VPS VDS | ProHoster