PDA

View Full Version : برنامه در سطح کرنل (جلو گیری از بسته شدن برنامه )



terrorhell
دوشنبه 31 فروردین 1394, 10:53 صبح
سلام دوستان
من یک برنامه با C# میخواستم بنویسم که توسط کاربر ویندوز به هیچ وجه بسته نشه ( end task ) اما خب نشد
بعد از کمی جستجو به این رسیدم که باید در سطح کرنل با C++ این کارو انجام بدم

ممنون میشم راهنمایی کنید و منبعی برای این کار رو معرفی کنید

#target
دوشنبه 31 فروردین 1394, 11:05 صبح
بهتره به نحوی این کار رو همون User Mode انجام بدین
کرنل مد راحت نیست و از طرفی برای انتشار برنامه باید اونو امضا دیجیتال کنین تا بشه روی سیستم کاربر اجرا شه !‌

terrorhell
دوشنبه 31 فروردین 1394, 11:26 صبح
مرسی دوست عزیز اما کلا متوجه نشدم چی گفتین

ممنون میشم کمی واضحتر راهنمایی کنید

مرسی

Native
دوشنبه 31 فروردین 1394, 11:32 صبح
این که یک برنامه به هیچ عنوان بسته نشه که ممکن نیست دوست عزیز ! در این صورت همه بدافزار ها به اینصورت نوشته میشدند. :لبخندساده:

مطالعه این دو لینک برای شما خالی از لطف نیست

http://www.codeproject.com/Articles/672843/Keep-alive-processes-or-preventing-app-termination

http://stackoverflow.com/questions/17484784/how-do-i-make-a-completely-access-denied-process-on-windows

بد افزار نویسی هم کار درستی نیست ... :چشمک:

terrorhell
دوشنبه 31 فروردین 1394, 11:41 صبح
دوست عزیز مرسی از جوابت
اتفاقا با همون لینک codeproject برنامه رو نوشتم که دیگه به هیچ وجه بسته نمیشد اما با یه برنامه process explorer پروسس keepalive رو suspend کردم و جفت پروسس ها رو بستم (خیلی راحت)
من دنبال این قضیه هستم که برنامه به راحتی بسته نشه

در ضمن بد افزار نیست ، دارم دیسک های سخت وصل شده به سیستم رو کنترل میکنم تا اون دیوایسی که خودم میگم فقط قابل اجرا رو سیستم باشه :بامزه:

terrorhell
دوشنبه 31 فروردین 1394, 11:48 صبح
دوست عزیز مرسی از جوابت
اتفاقا با همون لینک codeproject برنامه رو نوشتم که دیگه به هیچ وجه بسته نمیشد اما با یه برنامه process explorer پروسس keepalive رو suspend کردم و جفت پروسس ها رو بستم (خیلی راحت)
من دنبال این قضیه هستم که برنامه به راحتی بسته نشه

در ضمن بد افزار نیست ، دارم دیسک های سخت وصل شده به سیستم رو کنترل میکنم تا اون دیوایسی که خودم میگم فقط قابل اجرا رو سیستم باشه :بامزه:

terrorhell
دوشنبه 31 فروردین 1394, 11:55 صبح
یا حداقل مثله این آنتی ویروس ها وقتی میخوایم برنامه رو end task کنیم access denied بده که توسط هر کاربر عادی بسته نشه

بهروز عباسی
دوشنبه 31 فروردین 1394, 14:37 عصر
یا حداقل مثله این آنتی ویروس ها وقتی میخوایم برنامه رو end task کنیم access denied بده که توسط هر کاربر عادی بسته نشه


#include <ntddk.h>#include <common.h>


// coded by Behrooz


VOID UnloadRoutine(IN PDRIVER_OBJECT DriverObject)
{


FreeProcFilter();
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,"Unloaded\n");
}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{


NTSTATUS status = RegisterCallbackFunction();
if(!NT_SUCCESS(status))
{
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,"Faild to RegisterCallbackFunction .status : 0x%X \n",status);
}
DriverObject->DriverUnload = UnloadRoutine;


DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,"Driver Loaded\n");


return STATUS_SUCCESS;


}
//
// PRE OPERATION
//
OB_PREOP_CALLBACK_STATUS ObjectPreCallback(
IN PVOID RegistrationContext,
IN POB_PRE_OPERATION_INFORMATION OperationInformation
)
{
LPSTR ProcName;
// OB_PRE_OPERATION_INFORMATION OpInfo;






UNREFERENCED_PARAMETER(RegistrationContext);




ProcName=GetProcessNameFromPid(PsGetProcessId((PEP ROCESS)OperationInformation->Object));


if( !_stricmp(ProcName,"calc.exe") )
{
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
{
if ((OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_TERMINATE) == PROCESS_TERMINATE)
{
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
}
if ((OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_VM_OPERATION) == PROCESS_VM_OPERATION)
{
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_OPERATION;
}
if ((OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & ~PROCESS_VM_READ) == PROCESS_VM_READ)
{
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_READ;
}
if ((OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_VM_WRITE) == PROCESS_VM_WRITE)
{
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_WRITE;
}
}
}
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,"ObjectPreCallback ----> Process Name [%s] \n", ProcName);
return OB_PREOP_SUCCESS;
}
//
//POST OPERATION
//


VOID ObjectPostCallback(
IN PVOID RegistrationContext,
IN POB_POST_OPERATION_INFORMATION OperationInformation
)
{
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,"PostProcCreateRoutine. \n");
}
//
// REGISTE CALLBACK FUNCTION
//


NTSTATUS RegisterCallbackFunction()
{
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING Altitude;
USHORT filterVersion = ObGetFilterVersion();
USHORT registrationCount = 1;
OB_OPERATION_REGISTRATION RegisterOperation;
OB_CALLBACK_REGISTRATION RegisterCallBack;
REG_CONTEXT RegistrationContext;
memset(&RegisterOperation, 0, sizeof(OB_OPERATION_REGISTRATION));
memset(&RegisterCallBack, 0, sizeof(OB_CALLBACK_REGISTRATION));
memset(&RegistrationContext, 0, sizeof(REG_CONTEXT));
RegistrationContext.ulIndex = 1;
RegistrationContext.Version = 120;
if (filterVersion == OB_FLT_REGISTRATION_VERSION) {
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,"Filter Version is correct.\n");


RegisterOperation.ObjectType = PsProcessType;
RegisterOperation.Operations = OB_OPERATION_HANDLE_CREATE;
RegisterOperation.PreOperation = ObjectPreCallback;
RegisterOperation.PostOperation = ObjectPostCallback;
RegisterCallBack.Version = OB_FLT_REGISTRATION_VERSION;
RegisterCallBack.OperationRegistrationCount = registrationCount;
RtlInitUnicodeString(&Altitude, L"XXXXXXX");
RegisterCallBack.Altitude = Altitude;
RegisterCallBack.RegistrationContext = &RegistrationContext;
RegisterCallBack.OperationRegistration = &RegisterOperation;
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,"Register Callback Function Entry.\n");




ntStatus = ObRegisterCallbacks(&RegisterCallBack, &_CallBacks_Handle);
if (ntStatus == STATUS_SUCCESS) {
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,"Register Callback Function Successful.\n");
}
else {
if (ntStatus == STATUS_FLT_INSTANCE_ALTITUDE_COLLISION) {
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,"Status Filter Instance Altitude Collision.\n");
}
if (ntStatus == STATUS_INVALID_PARAMETER) {
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,"Status Invalid Parameter.\n");
}
if (ntStatus == STATUS_ACCESS_DENIED) {
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,"The callback routines do not reside in a signed kernel binary image.\n");
}
if (ntStatus == STATUS_INSUFFICIENT_RESOURCES) {
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,"Status Allocate Memory Failed.\n");
}
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,"Register Callback Function Failed with 0x%08x\n",ntStatus);
}
}
else {
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,"Filter Version is not supported.\n");
}
return ntStatus;
}
//
// FREE PROC FILTER
//


NTSTATUS FreeProcFilter()
{
// if the callbacks are active - remove them
if (NULL != _CallBacks_Handle)
{
ObUnRegisterCallbacks(_CallBacks_Handle);
_CallBacks_Handle=NULL;
}
return STATUS_SUCCESS;
}




LPSTR GetProcessNameFromPid(HANDLE pid)
{
PEPROCESS Process;
if (PsLookupProcessByProcessId(pid, & Process) == STATUS_INVALID_PARAMETER)
{
return "pid???";
}
return (LPSTR)PsGetProcessImageFileName(Process);


}

common.h
#include <ntddk.h>


// coded by Behrooz


//-----------------------------------------------
// Defines
//-----------------------------------------------


//Process Security and Access Rights
#define PROCESS_CREATE_THREAD (0x0002)
#define PROCESS_CREATE_PROCESS (0x0080)
#define PROCESS_TERMINATE (0x0001)
#define PROCESS_VM_WRITE (0x0020)
#define PROCESS_VM_READ (0x0010)
#define PROCESS_VM_OPERATION (0x0008)
#define PROCESS_SUSPEND_RESUME (0x0800)




#define MAXIMUM_FILENAME_LENGTH 256
//-----------------------------------------------
// callback
//-----------------------------------------------


PVOID _CallBacks_Handle = NULL;


typedef struct _OB_REG_CONTEXT {
__in USHORT Version;
__in UNICODE_STRING Altitude;
__in USHORT ulIndex;
OB_OPERATION_REGISTRATION *OperationRegistration;
} REG_CONTEXT, *PREG_CONTEXT;




//-----------------------------------------------
// PID2ProcName
//-----------------------------------------------
extern UCHAR *PsGetProcessImageFileName(IN PEPROCESS Process);


extern NTSTATUS PsLookupProcessByProcessId(
HANDLE ProcessId,
PEPROCESS *Process
);
typedef PCHAR (*GET_PROCESS_IMAGE_NAME) (PEPROCESS Process);
GET_PROCESS_IMAGE_NAME gGetProcessImageFileName;


LPSTR GetProcessNameFromPid(HANDLE pid);






//-----------------------------------------------
// Forward Declaration
//-----------------------------------------------
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);


VOID UnloadDriver(
IN PDRIVER_OBJECT DriverObject
);


OB_PREOP_CALLBACK_STATUS ObjectPreCallback(
IN PVOID RegistrationContext,
IN POB_PRE_OPERATION_INFORMATION OperationInformation
);


VOID ObjectPostCallback(
IN PVOID RegistrationContext,
IN POB_POST_OPERATION_INFORMATION OperationInformation
);


NTSTATUS RegisterCallbackFunction() ;
NTSTATUS FreeProcFilter();




http://i.stack.imgur.com/vPsqB.png

terrorhell
دوشنبه 31 فروردین 1394, 14:42 عصر
فقط اینکه من زیاد C++‎‎‎‎‎‎ کار نکردم
سورس کد دوم رو که گفتید یه فایل به نام common.h
ولی سورس اول رو تو چه فایلی ذخیره کنم ؟

واقعاً نمیدونم چجوری ازش استفاده کنم :لبخندساده:
مرسی

بهروز عباسی
دوشنبه 31 فروردین 1394, 16:43 عصر
* عنوان تاپیک رو ویرایش کردم لطفا از عناوین مرتبط با موضوع استفاده کنید.




فقط اینکه من زیاد C++‎‎‎‎‎‎‎ کار نکردم
سورس کد دوم رو که گفتید یه فایل به نام common.h
ولی سورس اول رو تو چه فایلی ذخیره کنم ؟

واقعاً نمیدونم چجوری ازش استفاده کنم
:لبخندساده:

مرسی


این کد به زبان سی اه و کرنل مد٬ باید در درایور ازش استفاده بشه که داستان خاص خودش رو داره فکر کردم با برنامه نویسی کرنل اشنایی دارین.
(اسم فایل رو Source.c بزارین برای مثال !)

لینک زیر رو ببینید :
http://www.catch22.net/tuts/introduction-device-drivers

در کل برای رسیدن به پاسخ در مورد متدهای Self protection تحقیق کنید.

روز خوش/.

negative60
دوشنبه 31 فروردین 1394, 19:30 عصر
برای محافظت از بسته شدن از برنامه ميتونی از تابع RtlSetProcessIsCritical (http://stackoverflow.com/questions/5816289/how-to-unlist-my-program-from-the-process-list) API هم استفاده کنید, اگر به هر نحوی پروسه شما بسته بشه ويندوز ريست خواهد شد

بهروز عباسی
دوشنبه 31 فروردین 1394, 23:46 عصر
برای محافظت از بسته شدن از برنامه ميتونی از تابع RtlSetProcessIsCritical (http://stackoverflow.com/questions/5816289/how-to-unlist-my-program-from-the-process-list) API هم استفاده کنید, اگر به هر نحوی پروسه شما بسته بشه ويندوز ريست خواهد شداین متد هم کاربردی نیست و به راحتی بای پس میشه :| پست زیرو بخونید لطفا :http://barnamenevis.org/showthread.php?417192-%D8%A8%D8%B3%D8%AA%D9%86-%D9%BE%D9%88%D8%B1%D8%AA-usb-%D8%A8%D8%B7%D9%88%D8%B1%DB%8C%DA%A9%D9%87-%D9%81%D9%82%D8%B7-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D8%AE%D9%88%D8%AF%D9%85%D8%A7%D9%86-%D8%AF%D8%B3%D8%AA%D8%B1%D8%B3%DB%8C-%D8%AF%D8%A7%D8%B4%D8%AA%D9%87-%D8%A8%D8%A7%D8%B4%D8%AF&p=1867021&viewfull=1#post1867021

terrorhell
سه شنبه 01 اردیبهشت 1394, 00:00 صبح
برای محافظت از بسته شدن از برنامه ميتونی از تابع RtlSetProcessIsCritical (http://stackoverflow.com/questions/5816289/how-to-unlist-my-program-from-the-process-list) API هم استفاده کنید, اگر به هر نحوی پروسه شما بسته بشه ويندوز ريست خواهد شد

سلام مرسی

[DllImport("ntdll.dll", SetLastError = true)]
private static extern void RtlSetProcessIsCritical(UInt32 v1, UInt32 v2, UInt32 v3);


من از این کد برای فرمم استفاده کردم ولی وقتی برنامه رو به هر شکلی میبندم blue screen میشه و ویندوز reset میشه
فقط اینکه من بعضی مواقع احتیاج دارم که برنامه رو خودم ببندم ! چون برای فرمم hotkey گذاشتم که اگر مثلا shift+A زده شد برنامه stop بشه
ولی با این وضعیت کلا خودم نمیتونم ببند ! در این شرایط تکلیف بسته شدن برنامه توسط خودم چی میشه ؟

بهروز عباسی
سه شنبه 01 اردیبهشت 1394, 00:40 صبح
لازم به ذکره این بخش بخش C هستش نه C#‎‎‎ شما راه حل رو خواستین٬ این موارد کارهایی هستن که میتونیدانجام بدین :

۱- استفاده از درایور کرنل مد (در نسخه های قبل از Vistaباید SSDT هوک بزنید و از Vista به بعد میتونید از این کال بک که نمونه گذاشتم استفاده کنید).

۲- برنامه رو در یوزر مدحفاظت کنید٬ برای انجام این کار باید یه سرویس بنویسین که باهاش یه DLL که کار هوک کردن توابع NTDll!Zw/NTOpenProcess و یا NTDLL!Zw/NTTerminateProcess رو انجام بدین.برای انجام این کار هم باید ایجاد شدن پروسه های جدید رو تشخیص بدین و DLLمورد نظر رو بهش اینجکت کنید برای این کار هم باید تابع NTDll!Zw/NTCreateProcessInternalA/W رو هوک بزنید (اول در Explorer.exe وبعد ...) تا بتونید ایجاد شدن پروسه ها رو تشخیص بدین البته میتونید با تایمر هم لیست پروسه ها رو بگیرین و از این راه تشخیص بدین چه پروسه ای ایجاد شده ولی بهترین راه هو کردن تابع مذکوره تا بعد از ایجاد شدن پروسه رو Suspend کنید و Dll injection رو انجام بدین و در اخر پروسه رو Resume کنید تا مطئن بشید برنامه از اول محافظت رو انجام میده.همین !بهتره Openprocess رو هوک کنی تا بتونی برنامتو در برابر Injection هم محافظت کنی ( مثالش رو در پست قبل گذاشتم).فک نمیکنم این بحث بیش از این در این بخش لازم باشه :) مگر اینکه کسی متد کاربردی داشته باشه.---متاسفانه چون شما native کار نکردین انجام این کارها میتونه واستون مشکل باشه٬ پیشنهاد میکنم در مورد هوک توابع تحقیق کنید٬ چون این کارها کلا به هوک نیازه داره یوزر یا کرنل.شب خوش/.

negative60
سه شنبه 01 اردیبهشت 1394, 03:58 صبح
سلام مرسی

[DllImport("ntdll.dll", SetLastError = true)]
private static extern void RtlSetProcessIsCritical(UInt32 v1, UInt32 v2, UInt32 v3);



من از این کد برای فرمم استفاده کردم ولی وقتی برنامه رو به هر شکلی میبندم blue screen میشه و ویندوز reset میشه
فقط اینکه من بعضی مواقع احتیاج دارم که برنامه رو خودم ببندم ! چون برای فرمم hotkey گذاشتم که اگر مثلا shift+A زده شد برنامه stop بشه
ولی با این وضعیت کلا خودم نمیتونم ببند ! در این شرایط تکلیف بسته شدن برنامه توسط خودم چی میشه ؟
برای غير فعال کردنش تو همون لينکی که دادم توضيح داده: RtlSetProcessIsCritical(0, 0, 0)


این متد هم کاربردی نیست و به راحتی بای پس میشه :| پست زیرو بخونید لطفا :http://barnamenevis.org/showthread.php?417192-%D8%A8%D8%B3%D8%AA%D9%86-%D9%BE%D9%88%D8%B1%D8%AA-usb-%D8%A8%D8%B7%D9%88%D8%B1%DB%8C%DA%A9%D9%87-%D9%81%D9%82%D8%B7-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D8%AE%D9%88%D8%AF%D9%85%D8%A7%D9%86-%D8%AF%D8%B3%D8%AA%D8%B1%D8%B3%DB%8C-%D8%AF%D8%A7%D8%B4%D8%AA%D9%87-%D8%A8%D8%A7%D8%B4%D8%AF&p=1867021&viewfull=1#post1867021

بله هر زمانی که از تابع API استفاده بشه ميشه با تزريق کد و هوک کردن روش محافظت رو دور زد حتی روشی که تو پست آخر هم توضيح داديد قابل دور زدن هست کافيه پروسه اتکر قبل از پروسه برنامه محافظ اجرا بشه و تابع Openprocess و terminateprocess رو هوک کنه...

بهروز عباسی
سه شنبه 01 اردیبهشت 1394, 09:51 صبح
بله هر زمانی که از تابع API استفاده بشه ميشه با تزريق کد و هوک کردن روش محافظت رو دور زد حتی روشی که تو پست آخر هم توضيح داديد قابل دور زدن هست کافيه پروسه اتکر قبل از پروسه برنامه محافظ اجرا بشه و تابع Openprocess و terminateprocess رو هوک کنه...
درسته متدهای یوزر مد در کل اسیب پذیر هستن٬ ولی در این مورد که فرمودین اولویت هوک باعث میشه دور بخوره باید بگم در مورد هوک این کار قابل انجامه حتی اگی تابع X!X هوک هم شده باشه ما با برنامه خودمون مجدد اونو هوک کنیم .
خلاصه این قصه سر دراز دارد :)