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.

Dina tulisan sateuacana urang parantos nyarioskeun naon éta , sareng kumaha murid ti Innopolis berkembang Dinten 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.

Pavel Yosifovich — Windows Pemrograman Kernel (2019)
Programmer ngagunakeun fungsi , 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. (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 .
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: nu ngalaksanakeun Pikeun mariksa disk pikeun kasalahan sateuacan ngamimitian jasa utama. Ieu persis tingkat dimana urang hoyong Active Restore beroperasi.
Urang peryogi naon?
- (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.
Naon dina kode?
Hayu urang latihan saeutik tur nulis aplikasi leutik salaku conto yén:
- Mintonkeun pesen dina layar
- Allocates sababaraha memori
- Ngadagoan input keyboard
- 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. , 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 Salajengna, 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 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 pikeun 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 , 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. atawa ngan ngagunakeun .
Kompilasi jeung assembly
Cara panggampangna pikeun ngawangun aplikasi asli nyaéta ngagunakeun (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.defsumber:
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 = 1Makefile 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.

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

Kumaha ngajalankeun aplikasi asli?
Nalika autochk dimimitian, runtuyan peluncuran program ditangtukeun ku nilai konci pendaptaran:
HKLMSystemCurrentControlSetControlSession ManagerBootExecutePangatur 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 *MyNativeNilaina 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,00Pikeun ngarobah nami, anjeun tiasa nganggo jasa online, contona, .

Tétéla pikeun ngaluncurkeun aplikasi asli, urang peryogi:
- Nyalin file laksana ka folder system32
- Tambahkeun konci pikeun pendaptaran
- 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
pauseadd.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,00Saatos instalasi sareng reboot, sateuacan layar pamilihan pangguna muncul, urang bakal ningali gambar ieu:

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é). ).
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
