Aikace-aikacen Native na Windows da sabis na Mayar da Acronis Active

A yau muna ci gaba da labarin yadda mu, tare da mutanen Jami'ar Innopolis, muke haɓaka fasahar Restore Active don bawa mai amfani damar fara aiki akan injin su da wuri-wuri bayan gazawar. Za mu yi magana game da aikace-aikacen Windows na asali, gami da fasalin ƙirƙirar su da ƙaddamarwa. Ƙarƙashin yanke shine kadan game da aikinmu, da kuma jagora mai amfani akan yadda ake rubuta aikace-aikacen asali.

Aikace-aikacen Native na Windows da sabis na Mayar da Acronis Active

A cikin rubuce-rubucen da suka gabata mun riga mun yi magana game da menene Maida Aiki, da kuma yadda ɗalibai daga Innopolis suke haɓaka sabis. A yau ina so in mayar da hankali kan aikace-aikacen asali, zuwa matakin da muke so mu "binne" sabis na murmurewa mai aiki. Idan komai ya yi aiki, za mu iya:

  • Kaddamar da sabis ɗin da kanta da wuri
  • Tuntuɓi gajimare inda madadin ke samuwa da yawa a baya
  • Da yawa a baya don fahimtar abin da yanayin tsarin yake - taya na al'ada ko farfadowa
  • Fayiloli kaɗan ne don murmurewa a gaba
  • Bada mai amfani don farawa har ma da sauri.

Menene app na asali ko ta yaya?

Don amsa wannan tambaya, bari mu dubi jerin kira da tsarin ke yi, misali, idan mai shirye-shirye a cikin aikace-aikacensa ya yi ƙoƙarin ƙirƙirar fayil.

Aikace-aikacen Native na Windows da sabis na Mayar da Acronis Active
Pavel Yosifovich - Shirye-shiryen Kernel na Windows (2019)

Mai shirye-shirye yana amfani da aikin CreateFile, wanda aka ayyana a cikin babban fayil fileapi.h kuma an aiwatar dashi a cikin Kernel32.dll. Koyaya, wannan aikin da kansa baya ƙirƙirar fayil ɗin, kawai yana bincika gardamar shigarwa kuma ya kira aikin NtCreateFile (kafin Nt kawai yana nuna cewa aikin ɗan ƙasa ne). An bayyana wannan aikin a cikin fayil ɗin taken winternl.h kuma an aiwatar dashi a ntdll.dll. Yana shirya tsalle zuwa sararin samaniyar nukiliya, bayan haka yana yin kiran tsarin don ƙirƙirar fayil. A wannan yanayin, ya zama cewa Kernel32 shine kawai abin rufewa don Ntdll. Ɗaya daga cikin dalilan da ya sa aka yi haka shi ne cewa Microsoft ta haka yana da ikon canza ayyuka na duniya na asali, amma ba ta taɓa daidaitattun musaya ba. Microsoft baya ba da shawarar kiran ayyuka na asali kai tsaye kuma baya rubuta yawancinsu. Ta hanyar, ana iya samun ayyuka marasa izini a nan.

Babban fa'idar aikace-aikacen asali shine cewa ntdll ana loda shi cikin tsarin da wuri fiye da kernel32. Wannan ma'ana ne, saboda kernel32 yana buƙatar ntdll don aiki. Sakamakon haka, aikace-aikacen da ke amfani da ayyuka na asali na iya fara aiki da wuri.

Don haka, Windows Applications na asali shirye-shirye ne waɗanda zasu iya farawa da wuri a cikin boot ɗin Windows. Suna amfani da ayyuka ne kawai daga ntdll. Misalin irin wannan aikace-aikacen: autochk wanda yayi chkdisk mai amfani don bincika faifai don kurakurai kafin fara manyan ayyuka. Wannan shine ainihin matakin da muke son Mayar da Ayyukan mu ya kasance.

Me muke bukata?

  • DDK (Kit ɗin Haɓaka Direba), wanda yanzu kuma aka sani da WDK 7 (Kit ɗin Driver Windows).
  • Injin Virtual (misali, Windows 7 x64)
  • Ba lallai ba ne, amma fayilolin rubutun da za a iya saukewa na iya taimakawa a nan

Me ke cikin lambar?

Bari mu yi ɗan aiki kaɗan kuma, alal misali, rubuta ƙaramin aikace-aikace wanda:

  1. Nuna saƙo akan allon
  2. Keɓance wasu ƙwaƙwalwar ajiya
  3. Yana jiran shigarwar madannai
  4. Yana 'yantar da ƙwaƙwalwar da aka yi amfani da su

A cikin aikace-aikacen asali, wurin shigarwa ba shine babba ko winmain ba, amma aikin NtProcessStartup, tunda a zahiri muna ƙaddamar da sabbin matakai kai tsaye a cikin tsarin.

Bari mu fara da nuna sako akan allo. Don wannan muna da aikin ɗan ƙasa NtDisplayString, wanda ke ɗaukar matsayin hujja mai nuni zuwa ga wani abu na tsarin UNICODE_STRING. RtlInitUnicodeString zai taimake mu mu fara shi. Sakamakon haka, don nuna rubutu akan allon za mu iya rubuta wannan ƙaramin aikin:

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

Tunda kawai ayyuka daga ntdll ke samuwa a gare mu, kuma kawai babu wasu ɗakunan karatu da ke cikin ƙwaƙwalwar ajiya tukuna, tabbas za mu sami matsala game da yadda ake rarraba ƙwaƙwalwar ajiya. Sabon ma'aikacin bai wanzu ba tukuna (saboda ya fito daga babban matakin duniya na C++), kuma babu aikin malloc (yana buƙatar ɗakunan karatu na C na lokaci). Tabbas, zaku iya amfani da tari kawai. Amma idan muna buƙatar rarraba ƙwaƙwalwar ajiya a hankali, dole ne mu yi shi akan tsibi (watau tudu). Don haka bari mu ƙirƙira wa kanmu tudu kuma mu ɗauki ƙwaƙwalwar ajiya a duk lokacin da muke buƙata.

Aikin ya dace da wannan aikin RtlCreateHeap. Na gaba, ta amfani da RtlAllocateHeap da RtlFreeHeap, za mu shagaltar da ƙwaƙwalwar ajiyar kyauta lokacin da muke buƙata.

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

Bari mu matsa zuwa jiran shigarwar madannai.

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

Duk abin da muke bukata shine amfani NtReadFile a buɗaɗɗen na'ura, kuma jira har sai maballin ya dawo mana da kowane latsa. Idan an danna maɓallin ESC, za mu ci gaba da aiki. Don buɗe na'urar, za mu buƙaci kiran aikin NtCreateFile (za mu buƙaci buɗe DeviceKeyboardClass0). Za mu kuma kira NtCreateEventdon fara abin jira. Za mu ayyana tsarin KEYBOARD_INPUT_DATA da kanmu, wanda ke wakiltar bayanan madannai. Wannan zai sauƙaƙa ayyukanmu.

Aikace-aikacen na asali yana ƙare tare da kiran aiki NtTerminateTsarindomin muna kashe kanmu kawai.

Duk lambar don ƙaramin aikace-aikacen mu:

#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: Za mu iya sauƙin amfani da aikin DbgBreakPoint() a cikin lambar mu don dakatar da shi a cikin mai cirewa. Gaskiya, kuna buƙatar haɗa WinDbg zuwa injin kama-da-wane don cire kernel. Ana iya samun umarnin yadda ake yin hakan a nan ko kawai amfani VirtualKD.

Tari da taro

Hanya mafi sauƙi don gina aikace-aikacen asali shine amfani DDK (Kit ɗin Ci gaban Direba). Muna buƙatar tsohuwar siga ta bakwai, tunda daga baya sigogin suna da ɗan bambanci daban-daban kuma suna aiki tare da Visual Studio. Idan muna amfani da DDK, to aikinmu yana buƙatar Makefile da tushe kawai.

Makefile

!INCLUDE $(NTMAKEENV)makefile.def

kafofin:

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 ɗinku zai kasance daidai, amma bari mu kalli tushen dalla-dalla. Wannan fayil yana ƙayyadaddun tushen shirin ku (.c files), gina zaɓuɓɓuka, da sauran sigogi.

  • TARGETNAME – sunan fayil ɗin da za a iya aiwatarwa wanda ya kamata a samar a ƙarshe.
  • TARGETTYPE - nau'in fayil ɗin da za a iya aiwatarwa, yana iya zama direba (.sys), to ƙimar filin yakamata ya zama DRIVER, idan ɗakin karatu (.lib), to ƙimar shine LIBRARY. A cikin yanayinmu, muna buƙatar fayil ɗin da za a iya aiwatarwa (.exe), don haka muka saita ƙimar zuwa PROGRAM.
  • UMTYPE – masu yuwuwar ƙimar wannan filin: na'ura wasan bidiyo don aikace-aikacen wasan bidiyo, windows don aiki a yanayin taga. Amma muna buƙatar saka nt don samun aikace-aikacen ɗan ƙasa.
  • BUFFER_OVERFLOW_CHECKS - duba tarin don cikar buffer, abin takaici ba shari'ar mu ba, mun kashe shi.
  • MINWIN_SDK_LIB_PATH - wannan darajar tana nufin madaidaicin SDK_LIB_PATH, kada ku damu cewa ba ku da irin wannan tsarin canjin tsarin da aka bayyana, lokacin da muka gudanar da bincike da aka bincika daga DDK, za a ayyana wannan canjin kuma zai nuna mahimman ɗakunan karatu.
  • SOURCES – jerin tushen tushen shirin ku.
  • HADA – fayilolin taken da ake buƙata don taro. Anan yawanci suna nuna hanyar zuwa fayilolin da suka zo tare da DDK, amma kuna iya ƙayyade wasu.
  • TARGETLIBS – jerin ɗakunan karatu waɗanda ke buƙatar haɗawa.
  • USE_NTDLL filin da ake buƙata wanda dole ne a saita shi zuwa 1 don dalilai na zahiri.
  • USER_C_FLAGS - kowane tutoci da za ku iya amfani da su a cikin umarnin mai sarrafawa lokacin shirya lambar aikace-aikacen.

Don haka don ginawa, muna buƙatar gudu x86 (ko x64) Ginin da aka bincika, canza kundin aiki zuwa babban fayil ɗin aikin kuma gudanar da umarnin Gina. Sakamakon a cikin hoton hoton yana nuna cewa muna da fayil guda ɗaya wanda za'a iya aiwatarwa.

Aikace-aikacen Native na Windows da sabis na Mayar da Acronis Active

Ba za a iya ƙaddamar da wannan fayil ɗin cikin sauƙi ba, tsarin yana la'anta kuma ya aiko mana don yin tunani game da halayensa tare da kuskure mai zuwa:

Aikace-aikacen Native na Windows da sabis na Mayar da Acronis Active

Yadda za a kaddamar da aikace-aikacen asali?

Lokacin da autochk ya fara, jerin farawa na shirye-shirye ana ƙaddara ta ƙimar maɓallin rajista:

HKLMSystemCurrentControlSetControlSession ManagerBootExecute

Mai sarrafa zaman yana aiwatar da shirye-shirye daga wannan jeri ɗaya bayan ɗaya. Manajan zaman yana neman fayilolin aiwatarwa da kansu a cikin tsarin tsarin32. Tsarin darajar maɓallin rajista kamar haka:

autocheck autochk *MyNative

Dole ne ƙimar ta kasance a cikin tsarin hexadecimal, ba ASCII na yau da kullun ba, don haka maɓallin da aka nuna a sama zai kasance cikin tsari:

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

Don canza take, zaku iya amfani da sabis na kan layi, misali, wannan.

Aikace-aikacen Native na Windows da sabis na Mayar da Acronis Active
Ya zama cewa don ƙaddamar da aikace-aikacen ɗan ƙasa, muna buƙatar:

  1. Kwafi fayil ɗin da za a iya aiwatarwa zuwa babban fayil ɗin system32
  2. Ƙara maɓalli zuwa wurin yin rajista
  3. Sake kunna injin

Don saukakawa, ga rubutun da aka shirya don shigar da aikace-aikacen asali:

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

Bayan shigarwa da sake kunnawa, ko da kafin allon zaɓin mai amfani ya bayyana, za mu sami hoto mai zuwa:

Aikace-aikacen Native na Windows da sabis na Mayar da Acronis Active

Sakamakon

Yin amfani da misalin irin wannan ƙaramar aikace-aikacen, mun tabbata cewa abu ne mai yiwuwa a gudanar da aikace-aikacen a matakin Native na Windows. Bayan haka, ni da mutanen Jami'ar Innopolis za mu ci gaba da gina sabis ɗin da zai fara aiwatar da hulɗa tare da direba da yawa a baya fiye da na baya na aikinmu. Kuma tare da zuwan harsashi win32, zai zama ma'ana don canja wurin sarrafawa zuwa cikakken sabis wanda aka riga aka haɓaka (ƙari akan wannan). a nan).

A cikin labarin na gaba za mu tabo wani ɓangaren sabis ɗin Restore Active, wato direban UEFI. Kuyi subscribing dinmu domin kada ku rasa post na gaba.

source: www.habr.com

Add a comment