<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های سید عمید قائم مقامی</title>
        <link>https://virgool.io/feed/@m_14047363</link>
        <description>برنامه نویسی سیستم ویندوز و مهندسی معکوس و علاقه مند به آموزش.</description>
        <language>fa</language>
        <pubDate>2026-06-16 05:33:09</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/4383485/avatar/UKYPrq.jpg?height=120&amp;width=120</url>
            <title>سید عمید قائم مقامی</title>
            <link>https://virgool.io/@m_14047363</link>
        </image>

                    <item>
                <title>نوشتن اسمبلی در سی پلاس پلاس 64 بیتی</title>
                <link>https://virgool.io/@m_14047363/%D9%86%D9%88%D8%B4%D8%AA%D9%86-%D8%A7%D8%B3%D9%85%D8%A8%D9%84%DB%8C-%D8%AF%D8%B1-%D8%B3%DB%8C-%D9%BE%D9%84%D8%A7%D8%B3-%D9%BE%D9%84%D8%A7%D8%B3-64-%D8%A8%DB%8C%D8%AA%DB%8C-kgzl6h6jpwap</link>
                <description>در ویژوال استدیو در زبان سی پلاس پلاس 32 بیت، ما مجاز بودیم با دستور زیر اینلاین اسمبلی بنویسیم.__asm
{

}اما در 64 بیت دیگر مجاز به اینکار نیستیم. برای نوشتن اسمبلی و استفاده از اون در زبان سی پلاس پلاس 64 بیت باید روند زیر را در پیش بگیریم:ویژوال استدیو رو باز کرده و یک پروژه خالی سی پلاس پلاس میسازیم. سپس مطابق شکل ها ادامه میدهیم:بخش زیر را در قسمت سی پلاس پلاس وارد میکنیم:extern &quot;C&quot; int hello();با این کار به لینکر میگوییم که تابع hello در خارج از این سورس پیاده سازی شده. و میتوانی آن را فراخوانی کنی:کد زیر رو در فایل asm وارد میکنیم (صرفا یک مثال است):.code

hello proc
xor rax, rax
push 1
pop rax
ret
hello endp

endدر این پست ما یک تابع امبلی نوشته و یادگرفتیم که چطور آن را در سی پلاس پلاس در ویژوال استدیو فراخوانی کنیم.Telegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Thu, 11 Jun 2026 12:59:23 +0330</pubDate>
            </item>
                    <item>
                <title>گرفتن ورژن ویندوز با ساختمان داده _KUSER_SHARED_DATA</title>
                <link>https://virgool.io/@m_14047363/%DA%AF%D8%B1%D9%81%D8%AA%D9%86-%D9%88%D8%B1%DA%98%D9%86-%D9%88%DB%8C%D9%86%D8%AF%D9%88%D8%B2-%D8%A8%D8%A7-%D8%B3%D8%A7%D8%AE%D8%AA%D9%85%D8%A7%D9%86-%D8%AF%D8%A7%D8%AF%D9%87-kusershareddata-ordzikvrs8ho</link>
                <description>برای گرفتن ورژن دقیق ویندوز راه های فراوانی وجود دارد. یکی از این راه ها که قابل اعتماد تر است استفاده از ساختمان داده ای هست که درون همه پردازه سطح کاربر وجود دارد.در ادامه روش آن را با هم بررسی میکنیم.برای گرفتن ورژن ویندوز باید ساختمان داده  kuser_shared_data   را درون windbg ببینیم.(برای مثال پردازه notepad.exe را باز میکنیم)گام اول: مانند تصاویر زیر notepad.exe را درون windbg باز میکنیم:دستور زیر رو در بخش کامند وارد میکنیم:dt nt!_KUSER_SHARED_DATAخروجی مانند زیر خواهیم دید:0:000&gt; dt nt!_KUSER_SHARED_DATA
ntdll!_KUSER_SHARED_DATA
   +0x000 TickCountLowDeprecated : Uint4B
   +0x004 TickCountMultiplier : Uint4B
   +0x008 InterruptTime    : _KSYSTEM_TIME
   +0x014 SystemTime       : _KSYSTEM_TIME
   +0x020 TimeZoneBias     : _KSYSTEM_TIME
   +0x02c ImageNumberLow   : Uint2B
   +0x02e ImageNumberHigh  : Uint2B
   +0x030 NtSystemRoot     : [260] Wchar
   +0x238 MaxStackTraceDepth : Uint4B
   +0x23c CryptoExponent   : Uint4B
   +0x240 TimeZoneId       : Uint4B
   +0x244 LargePageMinimum : Uint4B
   +0x248 AitSamplingValue : Uint4B
   +0x24c AppCompatFlag    : Uint4B
   +0x250 RNGSeedVersion   : Uint8B
   +0x258 GlobalValidationRunlevel : Uint4B
   +0x25c TimeZoneBiasStamp : Int4B
   +0x260 NtBuildNumber    : Uint4B
   +0x264 NtProductType    : _NT_PRODUCT_TYPE
   +0x268 ProductTypeIsValid : UChar
   +0x269 Reserved0        : [1] UChar
   +0x26a NativeProcessorArchitecture : Uint2B
   +0x26c NtMajorVersion   : Uint4B
   +0x270 NtMinorVersion   : Uint4B
   +0x274 ProcessorFeatures : [64] UChar
   +0x2b4 Reserved1        : Uint4B
   +0x2b8 Reserved3        : Uint4B
   +0x2bc TimeSlip         : Uint4B
   +0x2c0 AlternativeArchitecture : _ALTERNATIVE_ARCHITECTURE_TYPE
   +0x2c4 BootId           : Uint4B
   +0x2c8 SystemExpirationDate : _LARGE_INTEGER
   +0x2d0 SuiteMask        : Uint4B
   +0x2d4 KdDebuggerEnabled : UChar
   +0x2d5 MitigationPolicies : UChar
   +0x2d5 NXSupportPolicy  : Pos 0, 2 Bits
   +0x2d5 SEHValidationPolicy : Pos 2, 2 Bits
   +0x2d5 CurDirDevicesSkippedForDlls : Pos 4, 2 Bits
   +0x2d5 Reserved         : Pos 6, 2 Bits
   +0x2d6 CyclesPerYield   : Uint2B
   +0x2d8 ActiveConsoleId  : Uint4B
   +0x2dc DismountCount    : Uint4B
   +0x2e0 ComPlusPackage   : Uint4B
   +0x2e4 LastSystemRITEventTickCount : Uint4B
   +0x2e8 NumberOfPhysicalPages : Uint4B
   +0x2ec SafeBootMode     : UChar
   +0x2ed VirtualizationFlags : UChar
   +0x2ee Reserved12       : [2] UChar
   +0x2f0 SharedDataFlags  : Uint4B
   +0x2f0 DbgErrorPortPresent : Pos 0, 1 Bit
   +0x2f0 DbgElevationEnabled : Pos 1, 1 Bit
   +0x2f0 DbgVirtEnabled   : Pos 2, 1 Bit
   +0x2f0 DbgInstallerDetectEnabled : Pos 3, 1 Bit
   +0x2f0 DbgLkgEnabled    : Pos 4, 1 Bit
   +0x2f0 DbgDynProcessorEnabled : Pos 5, 1 Bit
   +0x2f0 DbgConsoleBrokerEnabled : Pos 6, 1 Bit
   +0x2f0 DbgSecureBootEnabled : Pos 7, 1 Bit
   +0x2f0 DbgMultiSessionSku : Pos 8, 1 Bit
   +0x2f0 DbgMultiUsersInSessionSku : Pos 9, 1 Bit
   +0x2f0 DbgStateSeparationEnabled : Pos 10, 1 Bit
   +0x2f0 SpareBits        : Pos 11, 21 Bits
   +0x2f4 DataFlagsPad     : [1] Uint4B
   +0x2f8 TestRetInstruction : Uint8B
   +0x300 QpcFrequency     : Int8B
   +0x308 SystemCall       : Uint4B
   +0x30c Reserved2        : Uint4B
   +0x310 SystemCallPad    : [2] Uint8B
   +0x320 TickCount        : _KSYSTEM_TIME
   +0x320 TickCountQuad    : Uint8B
   +0x320 ReservedTickCountOverlay : [3] Uint4B
   +0x32c TickCountPad     : [1] Uint4B
   +0x330 Cookie           : Uint4B
   +0x334 CookiePad        : [1] Uint4B
   +0x338 ConsoleSessionForegroundProcessId : Int8B
   +0x340 TimeUpdateLock   : Uint8B
   +0x348 BaselineSystemTimeQpc : Uint8B
   +0x350 BaselineInterruptTimeQpc : Uint8B
   +0x358 QpcSystemTimeIncrement : Uint8B
   +0x360 QpcInterruptTimeIncrement : Uint8B
   +0x368 QpcSystemTimeIncrementShift : UChar
   +0x369 QpcInterruptTimeIncrementShift : UChar
   +0x36a UnparkedProcessorCount : Uint2B
   +0x36c EnclaveFeatureMask : [4] Uint4B
   +0x37c TelemetryCoverageRound : Uint4B
   +0x380 UserModeGlobalLogger : [16] Uint2B
   +0x3a0 ImageFileExecutionOptions : Uint4B
   +0x3a4 LangGenerationCount : Uint4B
   +0x3a8 Reserved4        : Uint8B
   +0x3b0 InterruptTimeBias : Uint8B
   +0x3b8 QpcBias          : Uint8B
   +0x3c0 ActiveProcessorCount : Uint4B
   +0x3c4 ActiveGroupCount : UChar
   +0x3c5 Reserved9        : UChar
   +0x3c6 QpcData          : Uint2B
   +0x3c6 QpcBypassEnabled : UChar
   +0x3c7 QpcShift         : UChar
   +0x3c8 TimeZoneBiasEffectiveStart : _LARGE_INTEGER
   +0x3d0 TimeZoneBiasEffectiveEnd : _LARGE_INTEGER
   +0x3d8 XState           : _XSTATE_CONFIGURATION
   +0x710 FeatureConfigurationChangeStamp : _KSYSTEM_TIME
   +0x71c Spare            : Uint4Bاین سه بخش برای ما قابل استفاده هست:+0x260 NtBuildNumber    : Uint4B
+0x26c NtMajorVersion   : Uint4B
+0x270 NtMinorVersion   : Uint4Bویژوال استدیو را باز کرده و با توجه به مقادیر بدست آمده از Windbg کد زیر را مینویسیم:#include&lt;iostream&gt;
#include&lt;Windows.h&gt;

using namespace std;

void main()
{
	BYTE *Shared_Data = (BYTE*)0x7ffe0000;

	UINT NtMajorVersion = *(UINT*)(Shared_Data + 0x26c);
	UINT NtMinorVersion = *(UINT*)(Shared_Data + 0x270);
	UINT NtBuildNumber = *(UINT*)(Shared_Data + 0x260);

	cout &lt;&lt; NtMajorVersion &lt;&lt; &quot;.&quot; &lt;&lt; NtMinorVersion &lt;&lt; &quot;.&quot; &lt;&lt; NtBuildNumber;
}در خروجی ورژن ویندوز را مشاهده میکنیم:Telegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Fri, 05 Jun 2026 18:36:50 +0330</pubDate>
            </item>
                    <item>
                <title>یک IDE خوب برای زبان اسمبلی (Visual MASM)</title>
                <link>https://virgool.io/@m_14047363/%DB%8C%DA%A9-ide-%D8%AE%D9%88%D8%A8-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%B2%D8%A8%D8%A7%D9%86-%D8%A7%D8%B3%D9%85%D8%A8%D9%84%DB%8C-visual-masm-hla7btp80dx8</link>
                <description>برای زبان اسمبلی متوان گفت IDE خوب وجود ندارد. در این قسمت میخواهیم مراحل راه اندازی Visual MASM رو توضیح دهیم. از ابتدا ، یعنی دانلود و روش بالا اوردن و آماده سازی این IDE رو با هم انجام میدهیم.گام اول : نصب MASMاز آدرس زیر MASM32 رو دانلود میکنیم:https://www.masm32.com/فایل زیپ را باز کرده و فرایند نصب را شروع کرده:فرایند نصب را در مسیر پیش فرض کامل کنید ، و سپس به دنبال دانلود Visual MASM در مسیر زیر میرویم:https://visualmasm.com/home/برنامه VisualMASM را نصب میکنیم:بعد از نصب باید MASM32 رو در Visual MASM معرفی کنیم :یک پروژه برای تست Visual MASM ایجاد میکنیم:این هم از دیباگر محبوبمون!Telegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Tue, 02 Jun 2026 19:15:10 +0330</pubDate>
            </item>
                    <item>
                <title>Windows System Internals (Memory management)</title>
                <link>https://virgool.io/@m_14047363/windows-system-internals-memory-management-jtrpczmf96zi</link>
                <description>مدیریت حافظهدر این فصل، با نحوه پیاده‌سازی حافظه مجازی (Virtual Memory) در ویندوز و چگونگی مدیریت بخشی از آن که در حافظه فیزیکی (Physical Memory) نگهداری می‌شود، آشنا خواهید شد. همچنین ساختار داخلی و اجزای تشکیل‌دهنده «مدیر حافظه» (Memory Manager)، از جمله ساختارهای داده کلیدی و الگوریتم‌های آن را بررسی خواهیم کرد. پیش از بررسی این مکانیسم‌ها، نگاهی به سرویس‌های پایه‌ای ارائه‌شده توسط مدیر حافظه و مفاهیم کلیدی مانند تفاوت حافظه رزرو شده (Reserved) و واگذار شده (Committed) و همچنین حافظه اشتراکی (Shared Memory) خواهیم داشت.مقدمه‌ای بر مدیر حافظهبه‌طور پیش‌فرض، اندازه فضای مجازی یک فرآیند (Process) در نسخه ۳۲ بیتی ویندوز، ۲ گیگابایت است. اگر فایل اجرایی (Image) به‌طور خاص به عنوان «آگاه از فضای آدرس‌دهی بزرگ» (Large Address Space-Aware) علامت‌گذاری شده باشد و سیستم با گزینه خاصی بوت شود (که در بخش «چیدمان فضای آدرس‌دهی x86» در ادامه این فصل توضیح داده شده است)، یک فرآیند ۳۲ بیتی می‌تواند در ویندوز ۳۲ بیتی تا ۳ گیگابایت و در ویندوز ۶۴ بیتی تا ۴ گیگابایت رشد کند. اندازه فضای آدرس‌دهی مجازی فرآیند در نسخه‌های ۶۴ بیتی ویندوز ۸ و سرور ۲۰۱۲ برابر با ۸۱۹۲ گیگابایت (۸ ترابایت) است و در ویندوز ۸.۱ (و نسخه‌های جدیدتر) و سرور ۲۰۱۲ R2، این مقدار به ۱۲۸ ترابایت می‌رسد.همان‌طور که در فصل ۲ («معماری سیستم»، به‌ویژه در جدول ۲-۲) مشاهده کردید، حداکثر مقدار حافظه فیزیکی که ویندوز در حال حاضر پشتیبانی می‌کند، بسته به نسخه و ویرایش مورد استفاده، بین ۲ گیگابایت تا ۲۴ ترابایت متغیر است. از آنجا که فضای آدرس‌دهی مجازی ممکن است بزرگ‌تر یا کوچک‌تر از حافظه فیزیکی موجود در دستگاه باشد، مدیر حافظه دو وظیفه اصلی بر عهده دارد:۱. ترجمه یا نگاشت (Mapping): تبدیل فضای آدرس‌دهی مجازی یک فرآیند به حافظه فیزیکی؛ به گونه‌ای که وقتی یک «رشته» (Thread) در بافت آن فرآیند، اقدام به خواندن یا نوشتن در فضای آدرس مجازی می‌کند، به آدرس فیزیکی صحیح ارجاع داده شود. (به آن بخش از فضای آدرس مجازی یک فرآیند که در حافظه فیزیکی مقیم است، «مجموعه کاری» یا Working Set گفته می‌شود).۲. صفحه‌بندی (Paging): انتقال بخشی از محتوای حافظه به دیسک در زمانی که حافظه بیش از حد اشغال شده باشد (یعنی زمانی که رشته‌های در حال اجرا سعی می‌کنند بیش از حافظه فیزیکی موجود استفاده کنند) و بازگرداندن آن محتوا به حافظه فیزیکی در صورت نیاز.علاوه بر مدیریت حافظه مجازی، مدیر حافظه مجموعه‌ای از سرویس‌های هسته‌ای را ارائه می‌دهد که زیرسیستم‌های مختلف محیط ویندوز بر پایه آن‌ها بنا شده‌اند. این سرویس‌ها شامل «فایل‌های نگاشت‌شده در حافظه» (که در داخل سیستم Section Objects نامیده می‌شوند)، حافظه «کپی در هنگام نوشتن» (Copy-on-write) و پشتیبانی از برنامه‌هایی است که از فضاهای آدرس‌دهی بزرگ و پراکنده (Sparse) استفاده می‌کنند. همچنین، مدیر حافظه راهکاری را برای فرآیندها فراهم می‌کند تا بتوانند مقادیر بیشتری از حافظه فیزیکی را (نسبت به آنچه در یک لحظه در فضای آدرس مجازی قابل نگاشت است) تخصیص داده و استفاده کنند؛ برای مثال در سیستم‌های ۳۲ بیتی با بیش از ۳ گیگابایت حافظه فیزیکی.اجزای مدیر حافظهمدیر حافظه (Memory Manager) بخشی از «اجراییِ ویندوز» (Windows Executive) است و به همین دلیل در فایل Ntoskrnl.exe قرار دارد. این بخش بزرگ‌ترین مؤلفه در Executive محسوب می‌شود که نشان‌دهنده اهمیت و پیچیدگی بالای آن است. لازم به ذکر است که هیچ بخشی از مدیر حافظه در لایه انتزاع سخت‌افزار (HAL) وجود ندارد. مدیر حافظه از اجزای زیر تشکیل شده است:مجموعه‌ای از سرویس‌های سیستمیِ اجرایی: برای تخصیص، آزادسازی و مدیریت حافظه مجازی که بیشتر آن‌ها از طریق APIهای ویندوز یا رابط‌های درایورِ دستگاه در حالت هسته (Kernel-mode) در دسترس هستند.مدیریت‌کننده تله (Trap Handler) برای خطاهای دسترسی و عدم اعتبار ترجمه: جهت رفع استثناهای مدیریت حافظه که توسط سخت‌افزار شناسایی می‌شوند و همچنین مقیم کردن صفحات مجازی در حافظه فیزیکی به نیابت از یک فرآیند.شش روتین کلیدی سطح بالا: هر یک از این روتین‌ها در یکی از شش رشته (Thread) مختلفِ حالت هسته در فرآیند سیستم (System Process) اجرا می‌شوند:مدیر مجموعه تعادل (KeBalanceSetManager، اولویت ۱۷): این بخش یک روتین داخلی به نام «مدیر مجموعه کاری» (MmWorkingSetManager) را یک بار در ثانیه و همچنین زمانی که حافظه آزاد به کمتر از حد معینی می‌رسد، فراخوانی می‌کند. مدیر مجموعه کاری، سیاست‌های کلی مدیریت حافظه مانند هرس کردن (Trimming) مجموعه‌های کاری، تعیین عمر صفحات (Aging) و نوشتن صفحات تغییریافته را هدایت می‌کند.تعویض‌کننده فرآیند/پشته (KeSwapProcessOrStack، اولویت ۲۳): این بخش وظیفه ورود و خروج (Inswapping/Outswapping) پشته‌های رشته‌های هسته و خودِ فرآیندها را بر عهده دارد. مدیر مجموعه تعادل و کد زمان‌بندی رشته‌ها در هسته، در صورت نیاز به عملیات جابه‌جایی، این رشته را بیدار می‌کنند.نویسنده صفحات تغییریافته (MiModifiedPageWriter، اولویت ۱۸): این بخش صفحات «کثیف» (Dirty - صفحاتی که محتوای آن‌ها تغییر کرده) را از لیست صفحات تغییریافته به فایل‌های صفحه‌بندی (Paging Files) مناسب منتقل می‌کند. این رشته زمانی بیدار می‌شود که نیاز به کاهش حجم لیست صفحات تغییریافته باشد.نویسنده صفحات نگاشت‌شده (MiMappedPageWriter، اولویت ۱۸): محتوای صفحات تغییریافته در فایل‌های نگاشت‌شده (Mapped Files) را روی دیسک یا فضای ذخیره‌سازی راه دور می‌نویسد. این رشته زمانی بیدار می‌شود که حجم لیست تغییریافته‌ها باید کاهش یابد یا صفحاتی بیش از ۵ دقیقه در این لیست مانده باشند. وجود این رشته دومِ نویسنده ضروری است، زیرا ممکن است باعث ایجاد «خطای صفحه» (Page Fault) شود که خود نیازمند صفحات آزاد است. اگر تنها یک رشته نویسنده وجود داشت و حافظه آزاد تمام می‌شد، سیستم در انتظارِ صفحه آزاد دچار بن‌بست (Deadlock) می‌شد.رشته ارجاع‌زدایی قطعه (MiDereferenceSegmentThread، اولویت ۱۹): مسئول کاهش حافظه پنهان (Cache) و همچنین افزایش یا کاهش حجم فایل صفحه‌بندی (Page File) است. برای مثال، اگر فضای آدرس مجازی برای رشد «استخر صفحه‌بندی شده» (Paged Pool) وجود نداشته باشد، این رشته حافظه پنهان صفحات را هرس می‌کند تا فضای اشغال شده توسط آن برای استفاده مجدد آزاد شود.رشته صفر کردن صفحه (MiZeroPageThread، اولویت ۰): وظیفه این رشته صفر کردن محتوای صفحات در «لیست آزاد» است تا مجموعه‌ای از صفحات صفرشده برای پاسخگویی به خطاهای صفحه (که نیاز به صفحه خالی دارند) آماده باشد. در برخی موارد، صفر کردن حافظه توسط تابع سریع‌تری به نام MiZeroInParallel انجام می‌شود.صفحات بزرگ و کوچکمدیریت حافظه در قطعات مجزایی به نام «صفحه» (Page) انجام می‌شود؛ زیرا واحد مدیریت حافظه در سخت‌افزار (MMU)، ترجمه آدرس‌های مجازی به فیزیکی را در سطحِ دانه‌بندی یک صفحه انجام می‌دهد. از این رو، صفحه کوچک‌ترین واحد حفاظتی (Protection) در سطح سخت‌افزار محسوب می‌شود. پردازنده‌هایی که ویندوز بر روی آن‌ها اجرا می‌شود، از دو اندازه صفحه پشتیبانی می‌کنند: کوچک و بزرگ. اندازه‌های واقعی این صفحات بر اساس معماری پردازنده متفاوت است که در جدول ۵-۱ فهرست شده‌اند.مزیت اصلی صفحات بزرگ (Large Pages)، سرعت بالای ترجمه آدرس برای مراجعاتی است که به داده‌های درون آن صفحه صورت می‌گیرد. این مزیت به این دلیل است که با اولین مراجعه به هر بایت در یک صفحه بزرگ، بافر ترجمه سخت‌افزاری یا همان TLB ، اطلاعات لازم برای ترجمه آدرس تمامی بایت‌های دیگر آن صفحه بزرگ را در حافظه پنهان (Cache) خود ذخیره می‌کند.در مقابل، اگر از صفحات کوچک استفاده شود، برای پوشش همان محدوده از آدرس‌های مجازی، به ورودی‌های بیشتری در TLB نیاز است؛ این امر باعث می‌شود با ترجمه آدرس‌های مجازی جدید، ورودی‌های قبلی سریع‌تر جایگزین (Recycle) شوند. در نتیجه، هنگام مراجعه به آدرس‌های مجازی خارج از محدوده یک صفحه کوچک (که ترجمه آن قبلاً کش نشده)، سیستم مجبور است مجدداً به ساختارهای «جدول صفحه» (Page Table) مراجعه کند. از آنجا که TLB یک حافظه پنهان بسیار کوچک است، صفحات بزرگ از این منبع محدود استفاده بهینه‌تری می‌کنند.کاربرد صفحات بزرگ در ویندوزویندوز برای بهره‌گیری از این مزیت در سیستم‌هایی با بیش از ۲ گیگابایت رم، موارد زیر را با صفحات بزرگ نگاشت می‌کند:فایل‌های اصلی سیستم‌عامل (Ntoskrnl.exe و Hal.dll).داده‌های حیاتی سیستم‌عامل (مانند بخش اولیه یا Non-paged Pool و ساختارهای داده‌ای که وضعیت هر صفحه از حافظه فیزیکی را توصیف می‌کنند).درخواست‌های فضای I/O (فراخوانی MmMapIoSpace توسط درایورها)، مشروط بر اینکه طول و تراز (Alignment) درخواست به اندازه کافی بزرگ باشد.علاوه بر این، اپلیکیشن‌ها نیز می‌توانند فایل‌های اجرایی، حافظه خصوصی و بخش‌های متصل به فایل صفحه‌بندی خود را با صفحات بزرگ نگاشت کنند (به پرچم MEM_LARGE_PAGES در توابع VirtualAlloc و امثال آن مراجعه کنید). همچنین می‌توانید با افزودن مقدار LargePageDrivers در ریجستری (مسیر HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management)، درایورهای خاصی را برای استفاده از صفحات بزرگ تعیین کنید.محدودیت‌ها و چالش‌هاتخصیص صفحات بزرگ ممکن است پس از مدتی که از کارکرد سیستم گذشت، با شکست مواجه شود. دلیل آن این است که هر صفحه بزرگ باید از تعدادی صفحات کوچک متوالی در حافظه فیزیکی تشکیل شده باشد (جدول ۵-۱ را ببینید). علاوه بر این، این صفحات باید دقیقاً از مرز (Boundary) یک صفحه بزرگ شروع شوند. برای مثال در یک سیستم x64، صفحات فیزیکی ۰ تا ۵۱۱ می‌توانند یک صفحه بزرگ بسازند، اما صفحات ۱۰ تا ۵۲۱ خیر. با فعالیت سیستم، حافظه فیزیکی آزاد دچار «قطعه‌قطعه شدن» (Fragmentation) می‌شود که مشکلی برای صفحات کوچک ایجاد نمی‌کند، اما مانع از تخصیص صفحات بزرگ می‌شود.نکات مهم دیگر:این نوع حافظه همیشه غیرقابل صفحه‌بندی (Non-pageable) است، زیرا سیستم فایل صفحه‌بندی از صفحات بزرگ پشتیبانی نمی‌کند. به همین دلیل، فراخواننده باید دارای مجوز SeLockMemoryPrivilege باشد.این تخصیص‌ها جزئی از «مجموعه کاری» (Working Set) فرآیند محسوب نمی‌شوند و مشمول محدودیت‌های Job برای استفاده از حافظه مجازی نیستند.در ویندوز ۱۰ (نسخه ۱۶۰۷) و سرور ۲۰۱۶، صفحات بزرگ می‌توانند به صورت صفحات عظیم (Huge Pages) با اندازه ۱ گیگابایت نگاشت شوند.عوارض جانبی و امنیتاستفاده از صفحات بزرگ یک جنبه منفی دارد: هر صفحه (چه بزرگ، چه کوچک) باید دارای یک سطح حفاظتی واحد برای کل صفحه باشد. اگر یک صفحه بزرگ شامل هر دو بخش «کد فقط‌خواندنی» و «داده‌های خواندنی/نوشتنی» باشد، کل صفحه باید به صورت خواندنی/نوشتنی علامت‌گذاری شود. این یعنی کد سیستم‌عامل قابل تغییر خواهد بود! در این حالت، یک درایور مخرب یا دارای باگ می‌تواند کدهای حساس سیستم‌عامل را بدون بروز خطای دسترسی (Access Violation) تغییر دهد.اگر از صفحات کوچک استفاده شود، بخش‌های فقط‌خواندنی به درستی محافظت می‌شوند و در صورت تلاش برای تغییر آن‌ها، سیستم بلافاصله با یک صفحه آبی (Crash) متوقف شده و دستور خاطی را شناسایی می‌کند. این امر اگرچه کارایی ترجمه آدرس را کمی کاهش می‌دهد، اما از تخریب تدریجی و سخت‌تشخیصِ داده‌های سیستم جلوگیری می‌کند.نکته: اگر مشکوک به تخریب کدهای هسته (Kernel) هستید، ابزار Driver Verifier را فعال کنید؛ این ابزار استفاده از صفحات بزرگ را غیرفعال می‌کند تا امنیت و عیب‌یابی دقیق‌تر میسر شود.حافظه اشتراکی و فایل‌های نگاشت‌شدهویندوز نیز مانند اکثر سیستم‌عامل‌های مدرن، مکانیزمی را برای اشتراک‌گذاری حافظه میان فرآیندها و سیستم‌عامل فراهم می‌کند. حافظه اشتراکی (Shared Memory) را می‌توان به عنوان حافظه‌ای تعریف کرد که برای بیش از یک فرآیند قابل مشاهده است و یا در فضای آدرس‌دهی مجازیِ بیش از یک فرآیند حضور دارد.برای مثال، اگر دو فرآیند از یک DLL یکسان استفاده کنند، منطقی است که صفحاتِ کد مربوط به آن DLL تنها یک‌بار در حافظه فیزیکی بارگذاری شوند و همان صفحات بین تمام فرآیندهایی که آن DLL را نگاشت (Map) کرده‌اند، به اشتراک گذاشته شود؛ همان‌طور که در شکل ۵-۲ نشان داده شده است.هر فرآیند همچنان نواحی حافظه اختصاصی (Private) خود را برای ذخیره داده‌های شخصی حفظ می‌کند، اما صفحات کد DLL و داده‌های تغییرنیافته می‌توانند بدون هیچ مشکلی به اشتراک گذاشته شوند. همان‌طور که در ادامه توضیح خواهیم داد، این نوع اشتراک‌گذاری به‌طور خودکار رخ می‌دهد؛ زیرا صفحات کد در فایل‌های اجرایی (مانند EXE، DLL و موارد دیگری نظیر محافظ‌های صفحه نمایش یا SCR که در واقع همان DLL با نامی متفاوت هستند) به صورت «فقط-اجرا» (Execute-only) و صفحات قابل‌نوشتن به صورت «کپی در هنگام نوشتن» (Copy-on-write) نگاشت می‌شوند..شکل ۵-۲ دو فرآیند را نشان می‌دهد که بر اساس فایل‌های اجرایی متفاوتی هستند، اما یک DLL مشترک را که تنها یک بار در حافظه فیزیکی بارگذاری شده، به اشتراک می‌گذارند. در این حالت، کد خودِ فایل‌های اجرایی (EXE) به اشتراک گذاشته نمی‌شود چون دو فرآیند متفاوت هستند. اما اگر دو یا چند فرآیند یک فایل واحد (مثلاً Notepad.exe) را اجرا کنند، کد EXE نیز بین آن‌ها به اشتراک گذاشته خواهد شد.اشیاء بخش (Section Objects)ابتدایی‌ترین ساختارها در مدیر حافظه که برای پیاده‌سازی حافظه اشتراکی استفاده می‌شوند، اشیاء بخش (Section Objects) نام دارند که در Windows API با نام File-mapping objects شناخته می‌شوند. این ساختار بنیادین برای نگاشت آدرس‌های مجازی به کار می‌رود؛ خواه این آدرس‌ها در حافظه اصلی باشند، خواه در فایل صفحه‌بندی (Page File) یا هر فایل دیگری که اپلیکیشن بخواهد مانند حافظه رم به آن دسترسی داشته باشد. یک «بخش» می‌تواند توسط یک یا چند فرآیند باز شود؛ به عبارت دیگر، اشیاء بخش لزوماً به معنای حافظه اشتراکی نیستند (ممکن است فقط توسط یک فرآیند استفاده شوند).یک Section Objects می‌تواند به دو صورت متصل شود: ۱. به یک فایل باز روی دیسک: که به آن «فایل نگاشت‌شده» (Mapped File) می‌گویند. ۲. به حافظه واگذار شده (Committed Memory): برای ایجاد حافظه اشتراکی. به این نوع، «بخش‌های متکی به فایل صفحه‌بندی» (Page-file-backed sections) گفته می‌شود؛ زیرا در صورت نیازِ سیستم به حافظه فیزیکی، این صفحات (برخلاف فایل‌های معمولی) در فایل صفحه‌بندی نوشته می‌شوند. (از آنجا که ویندوز می‌تواند بدون فایل صفحه‌بندی هم اجرا شود، این بخش‌ها ممکن است در واقع فقط توسط حافظه فیزیکی پشتیبانی شوند). مانند هر صفحه خالی دیگری که در حالت کاربر (User-mode) قابل مشاهده می‌شود، صفحات اشتراکی واگذار شده نیز در اولین دسترسی همیشه با صفر پر می‌شوند تا اطمینان حاصل شود که هیچ داده حساسی نشت نمی‌کند.ایجاد و مدیریت بخش‌هابرای ایجاد یک Section Objects ، از توابع CreateFileMapping یا نسخه‌های مشابه آن استفاده می‌شود. در این توابع، دستگیره (Handle) فایلی که قبلاً باز شده مشخص می‌گردد (یا برای بخش‌های متکی به فایل صفحه‌بندی، مقدار INVALID_HANDLE_VALUE داده می‌شود). فرآیندهای دیگر می‌توانند از طریق نام، ارث‌بری دستگیره یا تکثیر دستگیره (DuplicateHandle) به این بخش‌ها دسترسی پیدا کنند. درایورهای دستگاه نیز می‌توانند با توابعی نظیر ZwOpenSection و ZwMapViewOfSection با این اشیاء کار کنند.یک Section Objects می‌تواند به فایل‌هایی ارجاع دهد که بسیار بزرگ‌تر از فضای آدرس‌دهی یک فرآیند هستند. برای دسترسی به چنین بخش‌های بزرگی، فرآیند تنها قسمتی را که نیاز دارد نگاشت می‌کند که به آن نمای بخش (View of the section) می‌گویند. این کار با توابع خانواده MapViewOfFile انجام می‌شود. استفاده از «نماها» به فرآیندها اجازه می‌دهد در فضای آدرس‌دهی خود صرفه‌جویی کنند، زیرا فقط بخش‌های مورد نیاز در هر لحظه وارد حافظه می‌شوند.کاربردهااپلیکیشن‌های ویندوز از فایل‌های نگاشت‌شده برای انجام راحتِ عملیات ورودی/خروجی (I/O) استفاده می‌کنند، به‌طوری که فایل به سادگی به صورت داده‌های موجود در حافظه ظاهر می‌شود. اما اپلیکیشن‌ها تنها مصرف‌کنندگان این اشیاء نیستند:بارگذار تصویر (Image Loader): از اشیاء بخش برای نگاشت فایل‌های EXE، DLL و درایورها به حافظه استفاده می‌کند.مدیر حافظه پنهان (Cache Manager): از آن‌ها برای دسترسی به داده‌ها در فایل‌های کش‌شده استفاده می‌کند.جلوگیری از اجرای داده‌ها (DEP)قابلیت جلوگیری از اجرای داده‌ها (Data Execution Prevention یا DEP) یا همان حفاظت از صفحه به روش «عدم اجرا» (NX)، باعث می‌شود تا هرگونه تلاش برای انتقال کنترل به دستورالعملی در یک صفحه که با علامت «عدم اجرا» مشخص شده است، منجر به خطای دسترسی (Access Fault) شود. این ویژگی می‌تواند از سوءاستفاده برخی بدافزارها از باگ‌های سیستم از طریق اجرای کدهای قرار داده شده در صفحات داده (مانند پشته یا Stack) جلوگیری کند.DEP همچنین می‌تواند برنامه‌هایی را که ضعیف نوشته شده‌اند و مجوزهای صفحاتی را که قصد اجرای کد از آن‌ها دارند به درستی تنظیم نمی‌کنند، شناسایی کند.اگر در حالت هسته (Kernel mode) تلاشی برای اجرای کد در صفحه «عدم اجرا» صورت گیرد، سیستم با کد خطای ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY (0xFC) دچار فروپاشی (Crash) می‌شود.اگر این اتفاق در حالت کاربر (User mode) رخ دهد، یک استثنای STATUS_ACCESS_VIOLATION (0xC0000005) به رشته‌ای که قصد ارجاع غیرقانونی داشته، ارسال می‌شود.اگر فرآیندی حافظه‌ای تخصیص دهد که نیاز به قابلیت اجرا داشته باشد، باید صراحتاً آن صفحات را با تعیین پرچم‌های PAGE_EXECUTE ،PAGE_EXECUTE_READ ،PAGE_EXECUTE_READWRITE یا PAGE_EXECUTE_WRITECOPY در توابع تخصیص حافظه مشخص کند.پیاده‌سازی در سیستم‌های مختلفسیستم‌های ۳۲ بیتی (x86): در سیستم‌هایی که از DEP پشتیبانی می‌کنند، بیت شماره ۶۳ در «ورودی جدول صفحه» (PTE) برای علامت‌گذاری صفحه به عنوان غیرقابل‌اجرا استفاده می‌شود. بنابراین، ویژگی DEP تنها زمانی در دسترس است که پردازنده در حالت PAE (Physical Address Extension) کار کند؛ در غیر این صورت، ورودی‌های جدول صفحه تنها ۳۲ بیت عرض خواهند داشت و فضایی برای این بیت وجود ندارد.سیستم‌های ARM: در این سیستم‌ها، DEP همیشه روی حالت AlwaysOn (همیشه روشن) تنظیم شده است.ویندوزهای ۶۴ بیتی: حفاظت از اجرا همیشه برای تمام فرآیندهای ۶۴ بیتی و درایورهای دستگاه اعمال می‌شود و تنها با تنظیم گزینه nx در تنظیمات BCD به حالت AlwaysOff قابل غیرفعال شدن است. در ویندوز ۶۴ بیتی، این حفاظت بر روی پشته‌های رشته (در هر دو حالت کاربر و هسته)، صفحات حالت کاربر که صراحتاً به عنوان قابل‌اجرا علامت‌گذاری نشده‌اند، «استخر صفحه‌بندی شده هسته» (Kernel Paged Pool) و «استخر نشست هسته» (Kernel Session Pool) اعمال می‌شود.تفاوت‌های نسخه ۳۲ بیتی و تنظیمات کاربردر ویندوز ۳۲ بیتی، حفاظت از اجرا فقط روی پشته‌های رشته و صفحات حالت کاربر اعمال می‌شود و شامل استخرهای حافظه هسته (Paged Pool و Session Pool) نمی‌شود.نحوه اعمال DEP برای فرآیندهای ۳۲ بیتی به مقدار گزینه nx در داده‌های پیکربندی بوت (BCD) بستگی دارد. برای تغییر این تنظیمات، می‌توان از تب Data Execution Prevention در کادر محاوره‌ای Performance Options استفاده کرد (شکل ۵-۳). تنظیمات انجام شده در این بخش، مقدار گزینه nx را در BCD تغییر می‌دهد.برنامه‌های ۳۲ بیتی که از این حفاظت مستثنی شده‌اند، در ریجستری و در مسیر زیر فهرست می‌شوند: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers در اینجا، نام مقدار (Value Name) همان مسیر کامل فایل اجرایی و داده‌ی آن (Data) برابر با DisableNXShowUI قرار داده می‌شود.در نسخه‌های کلاینت ویندوز (اعم از ۶۴ بیتی و ۳۲ بیتی)، حفاظت از اجرا برای فرآیندهای ۳۲ بیتی به‌طور پیش‌فرض به گونه‌ای پیکربندی شده است که تنها بر فایل‌های اجرایی اصلیِ سیستم‌عامل ویندوز اعمال شود؛ به عبارت دیگر، گزینه nx در BCD روی حالت OptIn تنظیم شده است. هدف از این کار، جلوگیری از خرابی برنامه‌های ۳۲ بیتی (مانند برنامه‌های فشرده‌شده یا خود-استخراج‌گر) است که ممکن است برای اجرا به صفحاتی متکی باشند که صراحتاً به عنوان «قابل اجرا» علامت‌گذاری نشده‌اند. در مقابل، در سیستم‌های سرور ویندوز، این حفاظت به‌طور پیش‌فرض برای تمامی برنامه‌های ۳۲ بیتی اعمال می‌شود و گزینه nx روی حالت OptOut قرار دارد.حتی اگر DEP را به‌صورت اجباری فعال کنید، همچنان روش‌های دیگری وجود دارد که برنامه‌ها از طریق آن‌ها می‌توانند DEP را برای فایل‌های اجرایی خود غیرفعال کنند. برای مثال، صرف‌نظر از اینکه کدام گزینه حفاظتی فعال باشد، «بارگذار تصویر» (Image Loader) امضای فایل اجرایی را با مکانیسم‌های شناخته‌شده‌ی قفل‌گذاری (مانند SafeDisc و SecuROM) مطابقت می‌دهد و در صورت شناسایی، جهت حفظ سازگاری با نرم‌افزارهای قدیمیِ دارای قفل (مانند بازی‌های کامپیوتری)، حفاظت از اجرا را غیرفعال می‌کند.هیپ‌های حالت هسته (استخرهای حافظه سیستم)در زمان مقداردهی اولیه سیستم، مدیر حافظه دو «استخر حافظه» (Memory Pool) یا «هیپ» (Heap) با اندازه پویا ایجاد می‌کند که اکثر مؤلفه‌های حالت هسته (Kernel-mode) برای تخصیص حافظه سیستم از آن‌ها استفاده می‌کنند:استخر غیرصفحه‌بندی شده (Non-paged pool): این استخر شامل محدوده‌هایی از آدرس‌های مجازی سیستم است که تضمین می‌شود در تمام لحظات در حافظه فیزیکی مقیم باشند. بنابراین، در هر زمانی می‌توان بدون بروز «خطای صفحه» (Page Fault) به آن‌ها دسترسی داشت؛ این بدان معناست که از هر سطح IRQL (سطح درخواست وقفه) می‌توان به این حافظه دسترسی پیدا کرد. یکی از دلایل نیاز به این استخر این است که خطاهای صفحه در سطح DPC/dispatch یا بالاتر قابل رفع نیستند. در نتیجه، هر کد یا داده‌ای که ممکن است در سطح DPC/dispatch یا بالاتر اجرا یا فراخوانی شود، باید در حافظه غیرقابل‌صفحه‌بندی باشد.استخر صفحه‌بندی شده (Paged pool): این بخش ناحیه‌ای از حافظه مجازی در فضای سیستم است که می‌تواند به دیسک منتقل (Page out) یا از آن بازگردانده (Page in) شود. درایورهای دستگاه که نیازی به دسترسی به حافظه در سطح DPC/dispatch یا بالاتر ندارند، می‌توانند از این استخر استفاده کنند. این حافظه از بافت (Context) هر فرآیندی قابل دسترسی است.هر دوی این استخرها در بخش «سیستمیِ» فضای آدرس‌دهی قرار دارند و در فضای آدرس مجازیِ تمام فرآیندها نگاشت می‌شوند. بخش اجرایی ویندوز (Executive) روتین‌هایی را برای تخصیص و آزادسازی حافظه از این استخرها فراهم می‌کند. برای اطلاعات بیشتر درباره این روتین‌ها، می‌توانید به توابعی که با ExAllocatePool ،ExAllocatePoolWithTag و ExFreePool شروع می‌شوند در مستندات WDK مراجعه کنید.سیستم‌ها با چهار استخر صفحه‌بندی شده (که برای تشکیل کل استخر صفحه‌بندی شده سیستم با هم ترکیب می‌شوند) و دو استخر غیرصفحه‌بندی شده شروع به کار می‌کنند. بسته به تعداد گره‌های NUMA در سیستم، ممکن است استخرهای بیشتری (تا ۶۴ عدد) ایجاد شود. داشتن بیش از یک استخر صفحه‌بندی شده، تداخل و مسدود شدن کدهای سیستم را هنگام فراخوانی‌های هم‌زمان روتین‌های استخر کاهش می‌دهد. علاوه بر این، استخرهای مختلف در محدوده‌های آدرس مجازی متفاوتی نگاشت می‌شوند که با گره‌های مختلف NUMA در سیستم مطابقت دارند. ساختارهای داده‌ای مختلف (مانند لیست‌های Look-aside برای صفحات بزرگ) که تخصیص‌های استخر را توصیف می‌کنند نیز در گره‌های مختلف NUMA توزیع می‌شوند.علاوه بر استخرهای صفحه‌بندی شده و غیرصفحه‌بندی شده، چند استخر دیگر با ویژگی‌ها یا کاربردهای خاص وجود دارد:استخر فضای نشست (Session space pool): برای داده‌هایی استفاده می‌شود که بین تمام فرآیندهای یک «نشست» (Session) مشترک هستند.استخر ویژه (Special pool): تخصیص‌ها در این استخر توسط صفحاتی با علامت «عدم دسترسی» (No access) محصور می‌شوند. این کار به شناسایی و ایزوله کردن مشکلاتی در کد کمک می‌کند که به حافظه، قبل یا بعد از محدوده تخصیص‌یافته‌ی خود دست‌اندازی می‌کنند.مدیر هیپ (Heap Manager)بیشتر برنامه‌ها بلوک‌هایی را تخصیص می‌دهند که کوچک‌تر از حداقل واحد ۶۴ کیلوبایتیِ قابل تخصیص توسط توابع سطح صفحه (مانند VirtualAlloc) هستند. اختصاص دادن چنین فضای بزرگی برای موارد نسبتاً کوچک، از نظر مصرف حافظه و کارایی بهینه نیست. برای حل این مشکل، ویندوز مؤلفه‌ای به نام مدیر هیپ را ارائه می‌دهد. این مؤلفه، تخصیص‌های کوچک را درون نواحی بزرگ‌تری که قبلاً توسط توابع سطح صفحه رزرو شده‌اند، مدیریت می‌کند. واحد دانه‌بندی (Granularity) تخصیص در مدیر هیپ بسیار کوچک است: ۸ بایت در سیستم‌های ۳۲ بیتی و ۱۶ بایت در سیستم‌های ۶۴ بیتی. مدیر هیپ برای بهینه‌سازی مصرف حافظه و افزایش کارایی در مواجهه با این تخصیص‌های کوچک طراحی شده است.مدیر هیپ در دو مکان وجود دارد: Ntdll.dll و Ntoskrnl.exe. رابط‌های برنامه‌نویسی زیرسیستم (مانند Windows Heap APIs) توابع موجود در Ntdll.dll را فراخوانی می‌کنند، در حالی که اجزای مختلف اجرایی (Executive) و درایورهای دستگاه، توابع موجود در Ntoskrnl.exe را صدا می‌زنند. رابط‌های بومی آن (با پیشوند Rtl) فقط برای استفاده در اجزای داخلی ویندوز یا درایورهای حالت هسته در دسترس هستند. رابط‌های مستند شده‌ی Windows API برای هیپ (با پیشوند Heap)، در واقع درخواست‌ها را به توابع بومی در Ntdll.dll ارجاع می‌دهند. علاوه بر این، رابط‌های قدیمی (با پیشوند Local یا Global) جهت پشتیبانی از برنامه‌های قدیمی ویندوز ارائه شده‌اند؛ این‌ها نیز در داخل سیستم، مدیر هیپ را فراخوانی کرده و از برخی رابط‌های تخصصی آن برای بازسازی رفتارهای قدیمی استفاده می‌کنند.رایج‌ترین توابع هیپ در ویندوز عبارتند از:*   HeapCreate یا HeapDestroy: به ترتیب برای ایجاد یا حذف یک هیپ استفاده می‌شوند. در زمان ایجاد، می‌توان اندازه اولیه رزرو شده و واگذار شده (Committed) را مشخص کرد.*   HeapAlloc: یک بلوک از هیپ تخصیص می‌دهد. این تابع به RtlAllocateHeap در Ntdll.dll ارجاع داده می‌شود.*   HeapFree: بلوکی را که قبلاً با HeapAlloc تخصیص یافته بود، آزاد می‌کند.*   HeapReAlloc: اندازه یک تخصیص موجود را تغییر می‌دهد (بزرگ یا کوچک می‌کند). این تابع به RtlReAllocateHeap در Ntdll.dll ارجاع داده می‌شود.*   HeapLock و HeapUnlock: انحصار متقابل (Mutual Exclusion) را برای عملیات‌های روی هیپ کنترل می‌کنند.*   HeapWalk: ورودی‌ها و نواحی موجود در یک هیپ را پیمایش و فهرست می‌کند. هیپ‌های فرآیند (Process Heaps)هر فرآیند حداقل یک هیپ دارد که به آن «هیپ پیش‌فرض فرآیند» (Default Process Heap) گفته می‌شود. این هیپ در زمان آغاز به کار فرآیند ایجاد شده و در طول تمام مدت حیات آن هرگز حذف نمی‌شود. اندازه پیش‌فرض آن ۱ مگابایت است، اما می‌توانید با استفاده از پرچم /HEAP در زمان لینک کردن فایل اجرایی، اندازه اولیه بزرگ‌تری برای آن تعیین کنید. البته این مقدار صرفاً رزرو اولیه است و در صورت نیاز، هیپ به‌طور خودکار منبسط می‌شود. همچنین می‌توانید اندازه اولیه «واگذار شده» (Committed) را نیز در فایل اجرایی مشخص کنید.هیپ پیش‌فرض می‌تواند به‌طور صریح توسط برنامه یا به‌طور ضمنی توسط برخی توابع داخلی ویندوز استفاده شود. یک اپلیکیشن می‌تواند با فراخوانی تابع GetProcessHeap آدرس هیپ پیش‌فرض خود را استعلام کند. همچنین فرآیندها می‌توانند با تابع HeapCreate هیپ‌های اختصاصی (Private) اضافی ایجاد کنند. زمانی که فرآیند دیگر به یک هیپ اختصاصی نیاز نداشته باشد، می‌تواند با فراخوانی HeapDestroy فضای آدرس مجازی آن را بازپس بگیرد. آرایه‌ای از تمام هیپ‌های موجود در هر فرآیند نگهداری می‌شود که یک رشته (Thread) می‌تواند با تابع GetProcessHeaps آن‌ها را بررسی کند.انواع هیپتا پیش از ویندوز ۱۰ و سرور ۲۰۱۶، تنها یک نوع هیپ وجود داشت که ما آن را «NT heap» می‌نامیم. هیپ NT توسط یک لایه اختیاری در بخش جلویی (Front-end) تقویت می‌شود که در صورت استفاده، شامل «هیپ با قطعه‌قطعه شدنِ کم» یا همان LFH (Low-Fragmentation Heap) است.ویندوز ۱۰ نوع جدیدی از هیپ را با نام «Segment heap» معرفی کرد. این دو نوع هیپ دارای عناصر مشترکی هستند، اما ساختار و نحوه پیاده‌سازی آن‌ها با یکدیگر متفاوت است. به‌طور پیش‌فرض، تمام اپلیکیشن‌های UWP و برخی از فرآیندهای سیستمی از Segment heap استفاده می‌کنند، در حالی که سایر فرآیندها از همان NT heap بهره می‌برند. این تنظیمات را می‌توان در ریجستری تغییر داد.Telegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Thu, 21 May 2026 13:11:19 +0330</pubDate>
            </item>
                    <item>
                <title>زبان اسمبلی قسمت چهارم(Shell Code)CreateProcess</title>
                <link>https://virgool.io/@m_14047363/%D8%B2%D8%A8%D8%A7%D9%86-%D8%A7%D8%B3%D9%85%D8%A8%D9%84%DB%8C-%D9%82%D8%B3%D9%85%D8%AA-%DA%86%D9%87%D8%A7%D8%B1%D9%85shell-codecreateprocess-jftsgvck74m5</link>
                <description>این کد یک شلکد (Shellcode) است که برنامه calc.exe را اجرا می‌کند.۱. تنظیمات اولیه.386              ; از دستورالعمل‌های پردازنده 386 استفاده کن
.model flat, stdcall  ; مدل حافظه flat و قرارداد فراخوانی stdcall
.code
start:
    xor ebx, ebx  ; EBX = 0 (صفر کردن رجیستر برای استفاده بعدی)۲. پیدا کردن آدرس پایه Kernel32ASSUME fs:NOTHING
mov edi, dword ptr fs:[ebx+30h]  
; fs:[30h] = آدرس PEB (Process Environment Block)
; PEB اطلاعات کلی پروسه را نگه می‌داره

ASSUME fs:ERROR
mov edi, dword ptr ds:[edi+0ch]  
; PEB+0x0C = آدرس PEB_LDR_DATA
; این ساختار لیست ماژول‌های لود شده را داره

mov edi, dword ptr ds:[edi+1ch]  
; PEB_LDR_DATA+0x1C = InInitializationOrderModuleList
; لیست پیوندی ماژول‌های لود شدهPEB
 └──&gt; PEB_LDR_DATA (offset 0x0C)
       └──&gt; InInitializationOrderModuleList (offset 0x1C)
             ├── ntdll.dll
             ├── kernel32.dll  &lt;── ما این رو می‌خوایم
             └── ...۳. حلقه جستجوی Kernel32module_loop:
    mov eax, dword ptr ds:[edi+08h]  
    ; آدرس پایه ماژول جاری رو بخون (DllBase)
    
    mov esi, dword ptr ds:[edi+20h]  
    ; آدرس نام ماژول (FullDllName) رو بخون
    
    mov edi, dword ptr ds:[edi]      
    ; به ماژول بعدی در لیست پیوندی برو (Flink)
    
    cmp byte ptr ds:[esi+12], &#039;3&#039;    
    ; کاراکتر ۱۲ام نام ماژول رو با &#039;3&#039; مقایسه کن
    ; نام kernel32.dll در حافظه Unicode هست
    ; &quot;kernel32.dll&quot; → کاراکتر index 12 = &#039;3&#039;
    
    jne module_loop                  
    ; اگه &#039;3&#039; نبود، ماژول بعدی رو چک کن&quot;k e r n e l 3 2 . d l  l&quot;
  0 2 4 6 8 10 12 ...
               ↑
           index 12 = &#039;3&#039;۴. رفتن به PE Headermov edi, eax                        
; آدرس پایه kernel32 رو در EDI بذار

add edi, dword ptr ds:[eax+3ch]     
; eax+0x3C = offset به PE Header (e_lfanew در DOS Header)
; EDI الان به PE Header اشاره می‌کنه┌─────────────────┐ ← eax (base address)
│   DOS Header    │
│  0x3C: e_lfanew │──→ offset to PE Header
├─────────────────┤
│   PE Header     │ ← edi
└─────────────────┘۵. پیدا کردن Export Directorymov edx, dword ptr ds:[edi+78h]     
; PE Header + 0x78 = Export Directory RVA
; (در Data Directory، اولین entry = Export Table)

add edx, eax                        
; RVA + Base Address = آدرس واقعی Export Directory۶. پیدا کردن جدول اسامی توابعmov edi, dword ptr ds:[edx+20h]     
; Export Directory + 0x20 = Name Pointer Table RVA
; این جدول آدرس اسامی تمام توابع export شده رو داره

add edi, eax                        
; تبدیل RVA به آدرس واقعی۷. جستجوی CreateProcessAmov ebp, ebx        ; EBP = 0 (شمارنده/ایندکس)

name_loop:
    mov esi, dword ptr ds:[edi+ebp*4]  
    ; آدرس RVA نام تابع i‌ام رو بخون
    
    add esi, eax                        
    ; تبدیل به آدرس واقعی رشته نام
    
    inc ebp                             
    ; ایندکس رو یکی زیاد کن
    
    cmp dword ptr ds:[esi],   61657243h  
    ; مقایسه ۴ بایت اول با 0x61657243
    ; به صورت little-endian = &quot;aerC&quot; = &quot;Crea&quot;
    
    jne name_loop
    
    cmp dword ptr ds:[esi+8h], 7365636fh 
    ; مقایسه ۴ بایت از offset 8 با 0x7365636f
    ; به صورت little-endian = &quot;seco&quot; = &quot;oces&quot; ← بخشی از &quot;Process&quot;
    
    jne name_loop
    ; اگه هر دو شرط برقرار بود، CreateProcessA پیدا شد!C  r  e  a  t  e  P  r  o  c  e  s  s  A
43 72 65 61 74 65 50 72 6F 63 65 73 73 41
└──────────┘        └──────────┘
 &quot;Crea&quot;=61657243h    &quot;oces&quot;=7365636fh
 offset 0            offset 8۸. پیدا کردن Ordinal تابعmov edi, dword ptr ds:[edx+24h]     
; Export Directory + 0x24 = Ordinal Table RVA

add edi, eax                        
; تبدیل به آدرس واقعی

mov bp, word ptr ds:[edi+ebp*2]     
; ordinal تابع CreateProcessA رو بخون
; (هر ordinal یک WORD = 2 بایت هست)۹. پیدا کردن آدرس نهایی CreateProcessAmov edi, dword ptr ds:[edx+1Ch]     
; Export Directory + 0x1C = Address Table RVA

add edi, eax                        
; تبدیل به آدرس واقعی

mov edi, dword ptr ds:[edi+ebp*4-4] 
; آدرس تابع رو از جدول آدرس‌ها بخون
; منهای ۴ برای تنظیم ordinal base

add edi, eax                        
; RVA + Base = آدرس واقعی CreateProcessA۱۰. صفر کردن حافظه روی Stackmov ecx, ebx    ; ECX = 0
mov cl, 11111111b  ; ECX = 255 (0xFF)

zero_loop:
    push ebx    ; مقدار 0 رو push کن
    loop zero_loop  
    ; این حلقه 255 بار اجرا میشه
    ; 255 × 4 = 1020 بایت صفر روی stack
    ; برای ساختن STARTUPINFO و PROCESS_INFORMATION خالی۱۱. آماده کردن نام برنامهpush 636c6163h  
; مقدار 0x636c6163 رو push کن
; little-endian: &quot;calc&quot; ← نام برنامه!

mov edx, esp    
; EDX = اشاره‌گر به رشته &quot;calc&quot; روی stack۱۲. فراخوانی CreateProcessA; پارامترها به ترتیب معکوس push میشن (stdcall)

push edx  ; lpProcessInformation → اشاره‌گر به &quot;calc&quot; (buffer صفر شده)
push edx  ; lpStartupInfo → همون buffer
push ebx  ; lpCurrentDirectory = NULL
push ebx  ; lpEnvironment = NULL
push ebx  ; dwCreationFlags = 0
push ebx  ; bInheritHandles = FALSE
push ebx  ; lpThreadAttributes = NULL
push ebx  ; lpProcessAttributes = NULL
push edx  ; lpCommandLine → &quot;calc&quot;
push ebx  ; lpApplicationName = NULL

call edi  ; فراخوانی CreateProcessATelegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Thu, 21 May 2026 09:41:09 +0330</pubDate>
            </item>
                    <item>
                <title>زبان اسمبلی قسمت سوم(Shell Code)MessagBox</title>
                <link>https://virgool.io/@m_14047363/%D8%B2%D8%A8%D8%A7%D9%86-%D8%A7%D8%B3%D9%85%D8%A8%D9%84%DB%8C-%D9%82%D8%B3%D9%85%D8%AA-%D8%B3%D9%88%D9%85shell-codemessagbox-qdjeumqyh873</link>
                <description>هدف کلیاین کد یک شلکد (Shellcode) است که:    آدرس GetProcAddress را از حافظه پیدا می‌کند    کتابخانه user32.dll را لود می‌کند    تابع MessageBoxA را پیدا می‌کند    یک پیام &quot;hello&quot; نمایش می‌دهد    سپس برنامه را با ExitProcess خاتمه می‌دهدبخش اول: پیدا کردن بیس آدرس kernel32.dll.386                          ; هدف: پردازنده 386 (32 بیتی)
.model flat, stdcall          ; مدل حافظه flat و قرارداد فراخوانی stdcall
.code
start:xor ecx, ecxرجیستر ECX را صفر می‌کند (معادل mov ecx, 0 اما سریع‌تر)ASSUME fs:NOTHING
mov eax, dword ptr fs:[ecx+30h]
ASSUME fs:ERRORاز سگمنت FS آدرس PEB (Process Environment Block) را می‌خواندآفست 0x30 در TEB (Thread Environment Block) اشاره به PEB داردچون ECX=0 است، fs:[ecx+30h] == fs:[30h]TEB
 └─ [0x30] ──► PEBmov eax, dword ptr ds:[eax+0Ch]    از PEB آفست 0x0C را می‌خواند که به PEB_LDR_DATA اشاره داردPEB
 └─ [0x0C] ──► PEB_LDR_DATAmov esi, dword ptr ds:[eax+14h]از PEB_LDR_DATA آفست 0x14 را می‌خواند که InMemoryOrderModuleList استاین لیست شامل ماژول‌های لود شده در حافظه استPEB_LDR_DATA
 └─ [0x14] ──► InMemoryOrderModuleList
               ├─ [0] ntdll.dll
               ├─ [1] kernel32.dll  ◄── هدف ما
               └─ ...بخش دوم: پیمایش لیست ماژول‌هاlodsd   ; eax = dword ptr ds:[esi]
        ; ESI به طور خودکار +4 می‌شوداولین عنصر لیست را می‌خواند (ntdll.dll را رد می‌کند) LODSD = Load String Double wordxchg eax, esiمقدار EAX و ESI را جابجا می‌کند حالا ESI به اولین ورودی واقعی اشاره دارد.lodsd   ; eax = dword ptr ds:[esi]دومین عنصر لیست را می‌خواند (kernel32.dll)mov ebx, dword ptr ds:[eax+10h]آفست 0x10 از ورودی ماژول = بیس آدرس kernel32.dllحالا EBX = بیس آدرس kernel32.dllبخش سوم: پیدا کردن Export Tablemov edx, dword ptr ds:[ebx+3Ch]از بیس آدرس، آفست 0x3C را می‌خوانداین آفست به PE Header (امضای NT) اشاره داردadd edx, ebx    آدرس واقعی PE Header = بیس + آفستmov edx, dword ptr ds:[edx+78h]    آفست 0x78 در PE Header = آفست Export Tableadd edx, ebx    آدرس واقعی Export Table = بیس + آفستPE Header
 └─ [0x78] ──► Export Table
               ├─ [0x20] ──► AddressOfNames
               ├─ [0x24] ──► AddressOfNameOrdinals
               └─ [0x1C] ──► AddressOfFunctionsmov esi, dword ptr ds:[edx+20h]
add esi, ebx    آدرس AddressOfNames را می‌خواند (جدول نام توابع)xor ecx, ecxشمارنده حلقه را صفر می‌کند.بخش چهارم: جستجوی GetProcAddressjne_01:
    inc ecx    شمارنده را یک واحد افزایش می‌دهد (برای پیدا کردن اوردینال)    lodsd   ; eax = dword ptr ds:[esi]    آفست نام تابع بعدی را می‌خواند    add eax, ebx    آدرس واقعی نام تابع = بیس + آفست    cmp dword ptr ds:[eax], 50746547hبررسی می‌کند آیا ۴ بایت اول = &quot;GetP&quot; است؟50746547h به صورت Little Endian = &quot;GetP&quot;    jne jne_01    اگر برابر نبود به اول حلقه برمی‌گردد    cmp dword ptr ds:[eax+04h], 41636F72h    بررسی می‌کند آیا بایت‌های بعدی = &quot;rocA&quot; است؟    jne jne_01    cmp dword ptr ds:[eax+08h], 65726464hبررسی می‌کند آیا بایت‌های بعدی = &quot;ddre&quot; است؟&quot;GetP&quot; + &quot;rocA&quot; + &quot;ddre&quot; = &quot;GetProcAddre...&quot;
یعنی تابع GetProcAddress پیدا شد!    jne jne_01بخش پنجم: گرفتن آدرس واقعی تابعmov esi, dword ptr ds:[edx+24h]
add esi, ebx    آدرس AddressOfNameOrdinals (جدول اوردینال‌ها)mov cx, word ptr ds:[esi+ecx*2h]    اوردینال تابع GetProcAddress را از جدول می‌خواندdec ecxاوردینال را یک واحد کم می‌کند (به دلیل اینکه inc در ابتدای حلقه اضافه شده بود)mov esi, dword ptr ds:[edx+1Ch]
add esi, ebx    آدرس AddressOfFunctions (جدول آدرس توابع)mov edx, dword ptr ds:[esi+ecx*4h]
add edx, ebxآدرس واقعی تابع GetProcAddress را محاسبه می‌کندحالا EDX = آدرس GetProcAddressبخش ششم: فراخوانی LoadLibraryAxor ecx, ecx
push ebx              ; بیس آدرس kernel32.dll
push edx              ; آدرس GetProcAddress
push ecx              ; صفر (null terminator)
push 41797261h        ; &quot;Ayra&quot; ◄─┐
push 7262694Ch        ; &quot;rbiL&quot; ◄─┤ روی هم = &quot;LoadLibraryA\0&quot;
push 64616F4Ch        ; &quot;daoL&quot; ◄─┘
push esp              ; اشاره‌گر به رشته &quot;LoadLibraryA&quot;
push ebx              ; هندل kernel32.dll
call edx              ; GetProcAddress(kernel32, &quot;LoadLibraryA&quot;)    بعد از فراخوانی، EAX = آدرس LoadLibraryAadd esp, 0Ch    پاکسازی پارامترها از stack (رشته &quot;LoadLibraryA&quot;)pop ecx    مقدار null را از stack برمی‌داردبخش هفتم: لود کردن user32.dllpush eax              ; آدرس LoadLibraryA را ذخیره می‌کند
xor eax, eax
mov ax, 6C6Ch         ; &quot;ll&quot;
push eax              ; &quot;ll\0\0&quot;
push 642E3233h        ; &quot;d.23&quot;
push 72657375h        ; &quot;resu&quot;
push esp              ; اشاره‌گر به &quot;user32.dll\0&quot;
call dword ptr ss:[esp+10h]   ; LoadLibraryA(&quot;user32.dll&quot;)رشته روی stack: &quot;user&quot; + &quot;32.d&quot; + &quot;ll\0&quot; = &quot;user32.dll&quot;بعد از فراخوانی، EAX = هندل user32.dlladd esp, 0Ch پاکسازی رشته از stackبخش هشتم: پیدا کردن MessageBoxApush eax              ; هندل user32.dll
xor eax, eax
mov eax, 2341786Fh    ; &quot;23Axo&quot; (با null جعلی)
push eax
sub dword ptr ss:[esp+3h], 23h  ; تبدیل &#039;23&#039; به null
push 42656761h        ; &quot;Bega&quot; -&gt; &quot;egaB&quot;
push 7373654Dh        ; &quot;sseM&quot;
push esp              ; اشاره‌گر به &quot;MessageBox&quot;
push dword ptr ss:[esp+10h]    ; هندل user32.dll
call dword ptr ss:[esp+1Ch]    ; GetProcAddress(user32, &quot;MessageBoxA&quot;)رشته ساخته شده: &quot;MesS&quot; + &quot;ageB&quot; + &quot;ox\0&quot; = &quot;MessageBoxA&quot;add esp, 0Chپاکسازی رشته از stackpush eax              ; آدرس MessageBoxA
xor eax, eax
mov eax, 23737365h    ; با null جعلی
push eax
sub dword ptr ss:[esp+03h], 23h  ; اصلاح null
push 636F7250h        ; &quot;corP&quot;
push 74697845h        ; &quot;tixE&quot;
push esp              ; اشاره‌گر به &quot;ExitProcess&quot;
push dword ptr ss:[esp+20h]    ; هندل kernel32.dll
call dword ptr ss:[esp+20h]    ; GetProcAddress(kernel32, &quot;ExitProcess&quot;)بخش دهم: نمایش MessageBoxpush eax              ; آدرس ExitProcess
xor eax, eax
mov eax, 236E6977h    ; &quot;win&quot; با null جعلی
push eax
sub dword ptr ss:[esp+03h], 23h  ; اصلاح null
push esp              ; اشاره‌گر به &quot;win\0&quot; (caption)
xor eax, eax
mov al, 6Fh           ; &#039;o&#039;
push eax              ; &quot;o\0&quot;
push 6C6C6568h        ; &quot;lleh&quot;
push esp              ; اشاره‌گر به &quot;hello\0&quot; (متن پیام)
xor eax, eax
push eax              ; NULL (هندل پنجره)
push dword ptr ss:[esp+04h]   ; &quot;hello&quot;
push dword ptr ss:[esp+14h]   ; &quot;win&quot; (caption)
xor eax, eax
push eax              ; MB_OK = 0
call dword ptr ss:[esp+28h]   ; MessageBoxA(NULL, &quot;hello&quot;, &quot;win&quot;, 0)بخش یازدهم: خاتمه برنامهadd esp, 14h    پاکسازی stack.386

.model flat, stdcall

.code
start:
		xor ecx,ecx
		ASSUME fs:NOTHING
		mov eax,dword ptr fs:[ecx+30h]
		ASSUME fs:ERROR
		mov eax,dword ptr ds:[eax+0Ch]
		mov esi,dword ptr ds:[eax+14h]
		lodsd; eax,dword ptr ds:[esi]
		xchg eax,esi
		lodsd; eax,dword ptr ds:[esi]
		mov ebx,dword ptr ds:[eax+10h]
		mov edx,dword ptr ds:[ebx+3Ch]
		add edx,ebx
		mov edx,dword ptr ds:[edx+78h]
		add edx,ebx
		mov esi,dword ptr ds:[edx+20h]
		add esi,ebx
		xor ecx,ecx
jne_01:
		inc ecx
		lodsd; eax,dword ptr ds:[esi]
		add eax,ebx
		cmp dword ptr ds:[eax],50746547h
		jne jne_01
		cmp dword ptr ds:[eax+04h],41636F72h
		jne jne_01
		cmp dword ptr ds:[eax+08h],65726464h
		jne jne_01
		mov esi,dword ptr ds:[edx+24h]
		add esi,ebx
		mov cx,word ptr ds:[esi+ecx*2h]
		dec ecx
		mov esi,dword ptr ds:[edx+1Ch]
		add esi,ebx
		mov edx,dword ptr ds:[esi+ecx*4h]
		add edx,ebx
		xor ecx,ecx
		push ebx
		push edx
		push ecx
		push 41797261h
		push 7262694Ch
		push 64616F4Ch
		push esp
		push ebx
		call edx
		add esp,0Ch
		pop ecx
		push eax
		xor eax,eax
		mov ax,6C6Ch
		push eax
		push 642E3233h
		push 72657375h
		push esp
		call dword ptr ss:[esp+10h]
		add esp,0Ch
		push eax
		xor eax,eax
		mov eax,2341786Fh
		push eax
		sub dword ptr ss:[esp+3h],23h
		push 42656761h
		push 7373654Dh
		push esp
		push dword ptr ss:[esp+10h]
		call dword ptr ss:[esp+1Ch]
		add esp,0Ch
		push eax
		xor eax,eax
		mov eax,23737365h
		push eax
		sub dword ptr ss:[esp+03h],23h
		push 636F7250h
		push 74697845h
		push esp
		push dword ptr ss:[esp+20h]
		call dword ptr ss:[esp+20h]
		add esp,0Ch
		push eax
		xor eax,eax
		mov eax,236E6977h
		push eax
		sub dword ptr ss:[esp+03h],23h
		push esp
		xor eax,eax
		mov al,6Fh
		push eax
		push 6C6C6568h
		push esp
		xor eax,eax
		push eax
		push dword ptr ss:[esp+04h]
		push dword ptr ss:[esp+14h]
		xor eax,eax
		push eax
		call dword ptr ss:[esp+28h]
		add esp,14h
END startTelegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Wed, 20 May 2026 20:11:10 +0330</pubDate>
            </item>
                    <item>
                <title>زبان اسمبلی در ویندوز قسمت دوم(گرفتن آدرس جاری برنامه)</title>
                <link>https://virgool.io/@m_14047363/%D8%B2%D8%A8%D8%A7%D9%86-%D8%A7%D8%B3%D9%85%D8%A8%D9%84%DB%8C-%D8%AF%D8%B1-%D9%88%DB%8C%D9%86%D8%AF%D9%88%D8%B2-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85%DA%AF%D8%B1%D9%81%D8%AA%D9%86-%D8%A2%D8%AF%D8%B1%D8%B3-%D8%AC%D8%A7%D8%B1%DB%8C-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-v0uakzecmgfc</link>
                <description>در 32-bit x86 معمولاً از این ترفند استفاده می‌شود:call آدرس دستور بعدی را روی stack می‌گذاردبعد با pop آن آدرس را می‌گیریماین یک نمونه کامل MASM 32-bit است:.386
.model flat,stdcall
.stack 4096


ExitProcess proto, dwExitCode:dword

.data

.code

main proc

    call get_eip
get_eip:
    pop eax

    invoke ExitProcess, 0

main endp
end mainدر خط 14 در هنگام اجرای دستور call get_eip آدرس برگشت در استک ذخیره میشود و در خط بعد با انجام عمل pop eax آن مقدار داخل eax قرار میگیرد.Telegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Tue, 19 May 2026 19:40:31 +0330</pubDate>
            </item>
                    <item>
                <title>زبان برنامه نویسی پایتون قسمت اول(معرفی)</title>
                <link>https://virgool.io/@m_14047363/%D8%B2%D8%A8%D8%A7%D9%86-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84%D9%85%D8%B9%D8%B1%D9%81%DB%8C-potqmq6pkwmg</link>
                <description>زبان برنامه‌نویسی پایتون (Python) یکی از محبوب‌ترین و پرکاربردترین زبان‌های برنامه‌نویسی در جهان است که توسط گایدو له‌ون (Guido van Rossum) در سال ۱۹۹۱ توسعه یافته است. این زبان به دلیل ساختار ساده، خوانایی بالا و سینتکس قابل فهم، به سرعت مورد استقبال توسعه‌دهندگان قرار گرفت و یکی از گزینه‌های اصلی برای پروژه‌های متنوع شده است.ویژگی‌ها و مزایای پایتون:- ساده و قابل فهم بودن: نحوه نوشتن کد در پایتون بسیار نزدیک به زبان طبیعی بوده و افراد تازه‌کار نیز می‌توانند به راحتی با آن آشنا شوند.- پشتیبانی از شیءگرایی، برنامه‌نویسی تابعی و برنامه‌نویسی رویه‌ای: این زبان انعطاف‌پذیری بالایی دارد و می‌تواند در حوزه‌های مختلف مورد استفاده قرار گیرد.- کتابخانه‌ها و چارچوب‌های گسترده: پایتون دارای کتابخانه‌های متعددی است که امکان انجام انواع وظایف مانند پردازش داده‌ها، یادگیری ماشین، توسعه وب، علم داده، و خودکارسازی را فراهم می‌کند (مثلاً NumPy، Pandas، TensorFlow، Django، Flask و غیره).- پشتیبانی از چندین سیستم‌عامل: پایتون روی ویندوز، لینوکس، macOS و سایر سیستم‌عامل‌ها اجرا می‌شود.- کمی و بیش‌تری در حوزه علم داده و هوش مصنوعی: با توجه به توسعه‌های اخیر، پایتون به عنوان زبان اصلی در حوزه‌های یادگیری ماشین و هوش مصنوعی شناخته می‌شود.موارد مصرف پایتون:1. توسعه وب: با فریم‌ورک‌هایی مانند Django و Flask، ساخت برنامه‌های وب سریع و امن امکان‌پذیر است.2. علم داده و تحلیل داده‌ها: ابزارهایی مانند Pandas، NumPy و Matplotlib برای پردازش و مصورسازی داده‌ها.3. یادگیری ماشین و هوش مصنوعی: کتابخانه‌هایی مثل TensorFlow، Keras و Scikit-learn برای توسعه مدل‌های یادگیری ماشین.4. خودکارسازی و اسکریپت‌نویسی: نوشتن اسکریپت‌های خودکار برای مدیریت سیستم‌ها و عملیات تکراری.5. برنامه‌نویسی میزبان و توسعه نرم‌افزار: ساخت نرم‌افزارهای دسکتاپ و برنامه‌های چندرسانه‌ای.6. ساخت برنامه‌های علمی و محاسباتی: در حوزه‌های مهندسی و علمی به دلیل توانایی‌های عددی و محاسباتی مناسب است.در نتیجه، پایتون به عنوان زبان برنامه‌نویسی قدرتمند، همه‌جانبه و کاربرپسند، در حال حاضر در صنایع مختلف نقش کلیدی دارد و آینده‌ای درخشان در توسعه فناوری‌های نوین دارد.Telegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Fri, 15 May 2026 18:50:59 +0330</pubDate>
            </item>
                    <item>
                <title>Windows System Internals (Chapter 3 Processes)</title>
                <link>https://virgool.io/@m_14047363/windows-system-internals-chapter-3-processes-ywfazsauw2y6</link>
                <description>ایجاد یک فرآیندویندوز API چندین تابع برای ایجاد فرآیندها ارائه می‌دهد. ساده‌ترین آن CreateProcess است که تلاش می‌کند یک فرآیند با همان توکن دسترسی فرآیند ایجادکننده بسازد. اگر توکن متفاوتی مورد نیاز باشد، می‌توان از CreateProcessAsUser استفاده کرد که یک آرگومان اضافی (اولین) می‌پذیرد - یک هندل به یک شیء توکن که قبلاً به نحوی به دست آمده است (مثلاً با فراخوانی تابع LogonUser).سایر توابع ایجاد فرآیند شامل CreateProcessWithTokenW و CreateProcessWithLogonW (هر دو بخشی از advapi32.dll) هستند. CreateProcessWithTokenW شبیه به CreateProcessAsUser است، اما این دو در امتیازات مورد نیاز برای فراخواننده تفاوت دارند. CreateProcessWithLogonW یک میانبر مفید برای ورود با اعتبار یک کاربر مشخص و ایجاد یک فرآیند با توکن به دست آمده در یک مرحله است. هر دو با برقراری یک فراخوانی رویه از راه دور (RPC) به سرویس Secondary Logon (seclogon.dll، میزبانی شده در SvcHost.Exe) برای انجام ایجاد فرآیند واقعی، آن را فراخوانی می‌کنند. SecLogon فراخوانی را در تابع داخلی SlrCreateProcessWithLogon خود اجرا می‌کند و اگر همه چیز خوب پیش برود، در نهایت CreateProcessAsUser را فراخوانی می‌کند. سرویس SecLogon به طور پیش‌فرض برای شروع دستی پیکربندی شده است، بنابراین اولین باری که CreateProcessWithTokenW یا CreateProcessWithLogonW فراخوانی می‌شود، سرویس شروع به کار می‌کند. اگر سرویس قادر به شروع نباشد (مثلاً یک مدیر می‌تواند سرویس را غیرفعال کند)، این توابع با شکست مواجه خواهند شد. ابزار خط فرمان runas، که ممکن است با آن آشنا باشید، از این توابع استفاده می‌کند.جزئیات داخلی پردازشاین بخش ساختارهای داده اصلی پردازش ویندوز را که توسط قسمت‌های مختلف سیستم نگهداری می‌شوند، توضیح می‌دهد و روش‌ها و ابزارهای مختلف برای بررسی این داده‌ها را شرح می‌دهد.هر پردازش ویندوز با یک ساختار پردازش اجرایی (EPROCESS) نمایش داده می‌شود. ساختار EPROCESS علاوه بر دارا بودن بسیاری از ویژگی‌های مربوط به یک پردازش، شامل و اشاره کننده به تعدادی ساختار داده مرتبط دیگر نیز هست. به عنوان مثال، هر پردازش یک یا چند نخ دارد که هر کدام با یک ساختار نخ اجرایی (ETHREAD) نمایش داده می‌شوند.EPROCESS و بیشتر ساختارهای داده مرتبط با آن در فضای آدرس سیستم وجود دارند. یک استثنا، بلوک محیط پردازش (PEB) است که در فضای آدرس کاربر وجود دارد (زیرا حاوی اطلاعاتی است که توسط کد حالت کاربر قابل دسترسی است). علاوه بر این، برخی از ساختارهای داده پردازش که در مدیریت حافظه استفاده می‌شوند، مانند لیست مجموعه کاری، فقط در بافت پردازش فعلی معتبر هستند، زیرا در فضای سیستم مخصوص پردازش ذخیره می‌شوند. برای هر پردازشی که یک برنامه ویندوز را اجرا می‌کند، پردازش زیرسیستم ویندوز (Csrss) یک ساختار موازی به نام CSR_PROCESS را نگهداری می‌کند. علاوه بر این، بخش حالت هسته زیرسیستم ویندوز (Win32k.sys) یک ساختار داده برای هر پردازش به نام W32PROCESS را نگهداری می‌کند که اولین بار که یک نخ، تابع USER یا GDI ویندوز را که در حالت هسته پیاده‌سازی شده است، فراخوانی می‌کند، ایجاد می‌شود. این اتفاق به محض بارگذاری کتابخانه User32.dll رخ می‌دهد. توابع معمولی که باعث بارگذاری این کتابخانه می‌شوند عبارتند از CreateWindow(Ex) و GetMessage.از آنجا که زیرسیستم ویندوز در حالت هسته از گرافیک شتاب‌دهنده سخت‌افزاری مبتنی بر DirectX استفاده زیادی می‌کند، زیرساخت مؤلفه رابط دستگاه گرافیکی (GDI) باعث می‌شود که هسته گرافیکی DirectX (Dxgkrnl.sys) ساختار خاص خود را، DXGPROCESS، مقداردهی اولیه کند. این ساختار حاوی اطلاعاتی برای اشیاء DirectX (سطوح، سایه‌زن‌ها و غیره) و شمارنده‌ها و تنظیمات خط‌مشی مربوط به GPGPU برای زمان‌بندی محاسباتی و مدیریت حافظه است.به جز پردازش بیکار، هر ساختار EPROCESS توسط مدیر اشیاء اجرایی به عنوان یک شیء پردازش کپسوله‌سازی می‌شود. از آنجا که پردازش‌ها اشیاء نام‌گذاری شده نیستند، در ابزار WinObj (از Sysinternals) قابل مشاهده نیستند. با این حال، می‌توانید شیء نوع به نام Process را در دایرکتوری \ObjectTypes (در WinObj) مشاهده کنید. یک دستگیره به یک پردازش، از طریق استفاده از APIهای مربوط به پردازش، دسترسی به برخی از داده‌های موجود در ساختار EPROCESS و در برخی از ساختارهای مرتبط با آن را فراهم می‌کند.بسیاری از درایورها و اجزای سیستم دیگر، با ثبت اعلان‌های ایجاد پردازش، می‌توانند ساختارهای داده خود را برای ردیابی اطلاعاتی که به صورت &quot;به ازای هر پردازش&quot; ذخیره می‌کنند، ایجاد کنند. (توابع اجرایی PsSetCreateProcessNotifyRoutine(Ex, Ex2) این امکان را فراهم می‌کنند و در WDK مستند شده‌اند.) هنگام بحث در مورد سربار یک پردازش، اندازه چنین ساختارهای داده‌ای اغلب باید در نظر گرفته شود، اگرچه به دست آوردن یک عدد دقیق تقریباً غیرممکن است. علاوه بر این، برخی از این توابع به چنین اجزایی اجازه می‌دهند تا ایجاد پردازش‌ها را ممنوع یا مسدود کنند. این به فروشندگان ضد بدافزار یک راه معماری برای افزودن بهبودهای امنیتی به سیستم عامل، چه از طریق لیست سیاه مبتنی بر هش و چه از طریق سایر تکنیک‌ها، ارائه می‌دهد.شکل زیر فیلدهای کلیدی در ساختار EPROCESS را نشان می‌دهد.مشابه نحوه تقسیم APIها و اجزای کرنل به ماژول‌های ایزوله و لایه‌ای با قراردادهای نام‌گذاری خاص خود، ساختارهای داده یک فرآیند نیز از طراحی مشابهی پیروی می‌کنند. همانطور که در شکل بالا نشان داده شده، اولین عضو ساختار فرآیند اجرایی (EPROCESS) &quot;Pcb&quot; (بلوک کنترل فرآیند) نامیده می‌شود. این یک ساختار از نوع KPROCESS (برای فرآیند کرنل) است. اگرچه روال‌های اجرایی اطلاعات را در EPROCESS ذخیره می‌کنند، اما دیسپچر، زمان‌بند و کد حسابداری وقفه/زمان - که بخشی از کرنل سیستم‌عامل هستند - از KPROCESS استفاده می‌کنند. این امکان وجود یک لایه انتزاعی بین قابلیت‌های سطح بالای اجرایی و پیاده‌سازی سطح پایین آن از برخی توابع را فراهم می‌کند و به جلوگیری از وابستگی‌های ناخواسته بین لایه‌ها کمک می‌کند. شکل زیر فیلدهای کلیدی در ساختار KPROCESS را نشان می‌دهد.اگر از آخرین SDK ویندوز 10 استفاده می‌کنید، نسخه به‌روز شده WinDbg شامل یک لینک مستقیم زیر آدرس PEB خواهد بود که با کلیک روی آن، دستورات .process و !peb به طور خودکار اجرا می‌شوند.PEB در فضای آدرس حالت کاربر پردازشی که توصیف می‌کند، قرار دارد. این ساختار حاوی اطلاعات مورد نیاز لودر تصویر، مدیر پشته و سایر اجزای ویندوز است که باید از حالت کاربر به آن دسترسی داشته باشند؛ ارائه تمام این اطلاعات از طریق فراخوان‌های سیستمی بسیار پرهزینه خواهد بود. ساختارهای EPROCESS و KPROCESS فقط از حالت هسته قابل دسترسی هستند. فیلدهای مهم PEB در شکل زیر نشان داده شده‌اند.ساختار CSR_PROCESS حاوی اطلاعاتی در مورد پردازش‌ها است که مختص زیرسیستم ویندوز (Csrss) است. به همین دلیل، فقط برنامه‌های ویندوز دارای ساختار CSR_PROCESS مرتبط با خود هستند (به عنوان مثال، Smss ندارد). علاوه بر این، از آنجا که هر Session نمونه خاص خود از زیرسیستم ویندوز را دارد، ساختارهای CSR_PROCESS توسط پردازش Csrss در هر Session جداگانه نگهداری می‌شوند. ساختار اصلی CSR_PROCESS در شکل زیر نشان داده شده.ساختار W32PROCESS آخرین ساختار داده سیستمی مرتبط با پردازش‌هاست که بررسی خواهیم کرد. این ساختار شامل تمام اطلاعاتی است که کد مدیریت گرافیک و پنجره ویندوز در هسته (Win32k) برای حفظ اطلاعات وضعیت در مورد پردازش‌های رابط کاربری گرافیکی (GUI) نیاز دارد (که قبلاً به عنوان پردازش‌هایی تعریف شدند که حداقل یک فراخوانی سیستمی USER/GDI انجام داده‌اند). ساختار اصلی W32PROCESS در شکل زیر نشان داده شده است. متأسفانه، از آنجا که اطلاعات نوع برای ساختارهای Win32k در نمادهای عمومی موجود نیست، نمی‌توانیم به راحتی آزمایشی را برای نمایش این اطلاعات به شما نشان دهیم.ساختار داده‌های مختلف دخیل در دستکاری و مدیریت وضعیت فرآیند و چگونگی بازرسی این اطلاعات توسط ابزارها و دستورات دیباگر را دیدیم. در این بخش، نحوه و زمان ایجاد و پر شدن این ساختار داده‌ها و همچنین رفتار کلی ایجاد و خاتمه فرآیندها را بررسی می‌کنیم. همانطور که دیدیم، تمام توابع مستند شده ایجاد فرآیند، در نهایت به CreateProcessInternalW ختم می‌شوند، بنابراین از اینجا شروع می‌کنیم.ایجاد یک فرآیند ویندوز شامل چندین مرحله است که در سه بخش از سیستم عامل انجام می‌شود: کتابخانه سمت کلاینت ویندوز Kernel32.dll (کار اصلی از CreateProcessInternalW شروع می‌شود)، Executive ویندوز، و فرآیند زیرسیستم ویندوز (Csrss). به دلیل معماری زیرسیستم چند محیطی ویندوز، ایجاد یک شیء فرآیند Executive (که سایر زیرسیستم‌ها می‌توانند از آن استفاده کنند) از کار مربوط به ایجاد یک فرآیند زیرسیستم ویندوز جدا شده است. بنابراین، اگرچه توضیحات زیر در مورد جریان تابع CreateProcess ویندوز پیچیده است، به خاطر داشته باشید که بخشی از کار مربوط به معنای اضافه شده توسط زیرسیستم ویندوز است، در مقابل کار اصلی مورد نیاز برای ایجاد یک شیء فرآیند Executive.لیست زیر مراحل اصلی ایجاد یک فرآیند با توابع CreateProcess* ویندوز را خلاصه می‌کند. عملیات انجام شده در هر مرحله به تفصیل در بخش‌های بعدی توضیح داده شده است.۱. پارامترها را اعتبارسنجی کنید؛ پرچم‌ها و گزینه‌های زیرسیستم ویندوز را به معادل‌های بومی آن‌ها تبدیل کنید؛ لیست ویژگی‌ها را تجزیه، اعتبارسنجی و به معادل بومی آن تبدیل کنید.۲. فایل تصویری (exe.) که قرار است در داخل فرآیند اجرا شود را باز کنید.۳. شیء فرآیند اجرایی ویندوز را ایجاد کنید.۴. نخ اولیه را ایجاد کنید (پشته، زمینه و شیء نخ اجرایی ویندوز).۵. عملیات پس از ایجاد و مقداردهی اولیه فرآیند خاص زیرسیستم ویندوز را انجام دهید.۶. اجرای نخ اولیه را آغاز کنید (مگر اینکه پرچم CREATE_SUSPENDED مشخص شده باشد).۷. در بستر فرآیند و نخ جدید، مقداردهی اولیه فضای آدرس را تکمیل کنید (برای مثال، DLLهای مورد نیاز را بارگذاری کنید) و اجرای نقطه ورودی برنامه را آغاز کنید.شکل زیر نمای کلی از مراحلی را نشان می‌دهد که ویندوز برای ایجاد یک فرآیند دنبال می‌کند.Telegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Fri, 15 May 2026 13:31:43 +0330</pubDate>
            </item>
                    <item>
                <title>Windows System Internals (Chapter 2 System architecture)</title>
                <link>https://virgool.io/@m_14047363/windows-system-internals-chapter-2-system-architecture-xcbo6ifk44rn</link>
                <description>در شکل 2-1، ابتدا به خطی که قسمتهای حالت کاربر و حالت هسته سیستمعامل ویندوز را تقسیم میکند توجه کنید. جعبههای بالای این خط نشاندهنده فرآیندهای حالت کاربر هستند و اجزای زیر خط خدمات سیستمعامل در حالت هسته را نشان میدهند. همانطور که در فصل 1 ذکر شد، رشتههای حالت کاربر در فضای آدرس خصوصی خود اجرا میشوند (اگرچه در هنگام اجرای حالت هسته به فضای سیستم دسترسی دارند). بنابراین، فرآیندهای سیستمی، خدماتی، کاربری و زیرسیستمهای محیطی هرکدام فضای آدرس خصوصی خاص خود را دارند. خط تقسیم دومی نیز بین قسمتهای حالت هسته ویندوز و هایپروایزر وجود دارد. بهطور دقیقتر، هایپروایزر با همان سطح امتیاز CPU (0) مانند هسته اجرا میشود، اما از آنجایی که از دستورات مخصوص CPU (VT-x بر روی اینتل، SVM بر روی AMD) استفاده میکند، میتواند خود را از هسته جدا کرده و در عین حال به نظارت بر آن (و برنامهها) بپردازد. به همین دلایل، ممکن است اغلب اصطلاح &quot;ring -1&quot; را بشنوید (که ناچیز است).چهار نوع اصلی از فرآیندهای حالت کاربر به شرح زیر هستند:1. فرآیندهای کاربر: این فرآیندها میتوانند یکی از انواع زیر باشند: ویندوز 32 بیتی یا 64 بیتی (برنامههای ویندوز که بر روی Runtime ویندوز در ویندوز 8 و بالاتر اجرا میشوند در این این دسته قرار میگیرند)، ویندوز 3.1 16 بیتی، MS-DOS 16 بیتی، یا POSIX 32 بیتی یا 64 بیتی. توجه داشته باشید که برنامههای 16 بیتی فقط بر روی ویندوز 32 بیتی قابل اجرا هستند و برنامههای POSIX از ویندوز 8 به بعد دیگر پشتیبانی نمیشوند.2. فرآیندهای خدماتی: این فرآیندها میزبان خدمات ویندوز مانند وظیفهنگار و خدمت چاپ هستند. خدمات معمولاً نیاز دارند که به طور مستقل از ورود کاربر اجرا شوند. بسیاری از برنامههای سرور ویندوز، مانند Microsoft SQL Server و Microsoft Exchange Server، شامل اجزایی هستند که به عنوان خدمات اجرا میشوند. 3. فرآیندهای سیستمی: اینها فرآیندهای ثابت و سختافزاری هستند، مانند فرآیند ورود و مدیر جلسه، که خدمات ویندوز نیستند. به عبارت دیگر، این فرآیندها توسط مدیر کنترل خدمات آغاز نمیشوند.4. فرآیندهای سرور زیرسیستم محیطی: این فرآیندها بخشی از پشتیبانی برای محیط OS یا شخصیت ارائهشده به کاربر و برنامهنویس را پیادهسازی میکنند. ویندوز NT در ابتدا با سه زیرسیستم محیطی عرضه شد: ویندوز، POSIX، و OS/2. با این حال، زیرسیستم OS/2 آخرین بار با ویندوز 2000 و زیرسیستم POSIX آخرین بار با ویندوز XP عرضه شد. نسخههای Ultimate و Enterprise از ویندوز 7 کلاینت و همچنین تمام نسخههای سرور ویندوز 2008 R2 شامل پشتیبانی از یک زیرسیستم POSIX بهبود یافته به نام زیرسیستم برای برنامههای مبتنی بر UNIX (SUA) هستند. SUA اکنون متوقف شده و دیگر به عنوان بخشی اختیاری از ویندوز (چه کلاینت و چه سرور) ارائه نمیشود.در شکل بالا، به جعبه DLLهای زیرسیستم که در زیر جعبههای فرآیندهای خدماتی و فرآیندهای کاربر قرار دارد، توجه کنید. در ویندوز، برنامههای کاربری بهطور مستقیم با خدمات بومی سیستمعامل ویندوز تماس نمیگیرند. بلکه آنها از طریق یک یا چند کتابخانه پیوندی دینامیک (DLL) زیرسیستم عمل میکنند. نقش DLLهای زیرسیستم این است که یک عملکرد مستند را به تماسهای داخلی (که معمولاً مستند نیستند) خدمات بومی سیستم تبدیل کنند، که عمدتاً در Ntdll.dll پیادهسازی شدهاند. این ترجمه ممکن است شامل ارسال یک پیام به فرآیند زیرسیستم محیطی باشد که به فرآیند کاربر خدمت میکند یا ممکن است شامل آن نباشد.اجزای حالت هسته ویندوز شامل موارد زیر است:1. مدیریت اجرایی: مدیریت اجرایی ویندوز شامل خدمات پایه سیستمعامل است، از جمله مدیریت حافظه، مدیریت فرآیند و رشته، امنیت، ورودی/خیلیابی (I/O)، شبکه و ارتباطات بین فرآیندی.2. هسته ویندوز: این شامل عملکردهای پایینسطح سیستمعامل است، مانند زمانبندی رشته، ادغام وقفهها و استثناها، و همگامسازی چند پردازنده. همچنین مجموعهای از روالها و اشیاء پایه را فراهم میکند که بقیه مدیریت اجرایی برای پیادهسازی ساختارهای سطح بالاتر از آن استفاده میکنند.3. درایورهای دستگاه: این شامل درایورهای دستگاه سختافزاری است که تماسهای عملکرد ورودی/خیلیابی کاربر را به درخواستهای ورودی/خیلیابی دستگاه سختافزاری خاص تبدیل میکند و همچنین درایورهای غیرسختافزاری، مانند درایورهای سیستم فایل و شبکه.4. لایه انتزاع سختافزاری (HAL): این یک لایه کد است که هسته، درایورهای دستگاه و بقیه مدیریت اجرایی ویندوز را از تفاوتهای سختافزاری خاص پلتفرم (مانند تفاوتها بین مادربردها) جداسازی میکند.5. سیستم پنجرهها و گرافیک: این سیستم عملکردهای رابط گرافیکی کاربر (GUI) را پیادهسازی میکند (که بهطور بهتر به عنوان عملکردهای USER و GDI ویندوز شناخته میشود)، مانند مدیریت پنجرهها، کنترلهای رابط کاربری و کشیدن.6. لایه هایپروایزر: این لایه از یک مؤلفه واحد تشکیل شده است: هایپروایزر خود. در این محیط هیچ درایور یا ماژول دیگری وجود ندارد. با این حال، هایپروایزر خود از لایهها و خدمات داخلی مختلفی تشکیل شده است، مانند مدیریت حافظه خاص خود، زمانبند پردازشگر مجازی، مدیریت وقفهها و تایمرها، روالهای همگامسازی، مدیریت بخشها (نمونههای ماشین مجازی) و ارتباطات بین بخشها (IPC) و بیشتر.مرور کلی بر معماری امنیت مبتنی بر مجازیسازیجداسازی بین حالت کاربر و حالت هسته به حفاظت از سیستمعامل در برابر کدهای حالت کاربر، چه مخرب و چه غیرمخرب، کمک میکند. با این حال، اگر یک قطعه کد ناخواسته در حالت هسته به سیستم نفوذ کند (به دلیل وجود یک آسیبپذیری در هسته یا درایور که هنوز وصله نشده یا به دلیل فریب کاربر برای نصب یک درایور مخرب یا آسیبپذیر)، سیستم اساساً به خطر میافتد زیرا تمام کدهای حالت هسته به طور کامل به کل سیستم دسترسی دارند.فناوریهایی که در فصل 1 توضیح داده شدهاند و از هایپروایزر برای ارائه تضمینهای اضافی در برابر حملات استفاده میکنند، مجموعهای از قابلیتهای امنیتی مبتنی بر مجازیسازی (VBS) را تشکیل میدهند که جدایی طبیعی مبتنی بر امتیاز پردازنده را از طریق معرفی سطوح اعتماد مجازی (VTLs) گسترش میدهند. VTLها نه تنها یک روش جدید برای جداسازی دسترسی به منابع حافظه، سختافزار و پردازنده ارائه میدهند، بلکه نیاز به کد و اجزاء جدیدی برای مدیریت سطوح بالاتر اعتماد دارند. هسته و درایورهای رایج که در VTL 0 اجرا میشوند، نمیتوانند اجازه کنترل و تعریف منابع VTL 1 را داشته باشند؛ این کار هدف را بیمعنا خواهد کرد.شکل زیر معماری ویندوز 10 Enterprise و سرور 2016 را هنگام فعالیت VBS نشان میدهد. (گاهی اوقات اصطلاح حالت امن مجازی (VSM) نیز استفاده میشود.) با نسخه 1607 ویندوز 10 و انتشارهای سرور 2016، اگر توسط سختافزار پشتیبانی شود، به طور پیشفرض همیشه فعال است. برای نسخههای قدیمیتر ویندوز 10، میتوانید آن را با استفاده از یک سیاست یا با کادر گفتگوی افزودن ویژگیهای ویندوز فعال کنید (گزینه حالت کاربر ایزوله را انتخاب کنید).حالا که به معماری سطح بالا ویندوز نگاهی انداختیم، بیایید عمیقتر به ساختار داخلی و نقش هر یک از اجزای کلیدی سیستمعامل بپردازیم. شکل زیر یک نمودار دقیقتر و کاملتر از معماری و اجزای اصلی سیستم ویندوز است که نسبت به شکل 2-1 ارائه شده است. توجه داشته باشید که این شکل هنوز شامل تمامی اجزا نیست (بهطوری که شبکه بهطور خاص در فصل 10، «شبکهسازی»، در بخش 2 توضیح داده شده است).بخش اجرایی (Executive)بخش اجرایی ویندوز، لایه بالایی فایل Ntoskrnl.exe است (لایه پایینی آن «کرنل» نام دارد). این بخش شامل توابع زیر است:*   توابع قابل فراخوانی از حالت کاربر (User-mode): این توابع که «سرویسهای سیستم» نامیده میشوند، از طریق Ntdll.dll صادر میشوند. اکثر آنها از طریق Windows API در دسترس هستند، اما برخی نیز مستند نشدهاند (مانند ALPC و توابع پرسوجوی خاص).*   توابع درایور دستگاه: از طریق تابع DeviceIoControl فراخوانی میشوند و رابطی برای ارتباط حالت کاربر با درایورها فراهم میکنند.*   توابع مخصوص حالت هسته (Kernel-mode): توابعی که در WDK مستند شدهاند و مورد نیاز توسعهدهندگان درایور هستند (مانند مدیریت ورودی/خروجی).*   توابع مستند نشده هسته: توابعی که صادر شدهاند اما در WDK مستند نیستند (مانند توابع درایور ویدئوی بوت).*   توابع داخلی: توابعی که به عنوان نمادهای سراسری تعریف شده اما صادر نشدهاند (مانند توابع داخلی مدیریت حافظه) و توابعی که کاملاً داخلی هستند و فقط توسط بخش اجرایی و هسته استفاده میشوند.اجزای اصلی بخش اجرایی:*   مدیر پیکربندی (Configuration Manager): مسئول پیادهسازی و مدیریت رجیستری سیستم.*   مدیر فرآیند (Process Manager): ایجاد و خاتمه دادن به فرآیندها (Processes) و رشتهها (Threads).*   ناظر مرجع امنیت (SRM): اجرای سیاستهای امنیتی، حفاظت از منابع سیستم و حسابرسی (Auditing).*   مدیر ورودی/خروجی (I/O Manager): پیادهسازی ورودی/خروجی مستقل از دستگاه و ارسال دستورات به درایورهای مربوطه.*   مدیر نصب و اجرا (PnP Manager): شناسایی درایورهای مورد نیاز برای سختافزارها و تخصیص منابع (مانند IRQ و پورتهای I/O).*   مدیر توان (Power Manager): هماهنگی رویدادهای مربوط به مصرف انرژی و مدیریت وضعیت خواب سیستم.*   توابع WMI: امکان انتشار اطلاعات عملکرد و پیکربندی درایورها به سرویسهای مدیریتی.*   مدیر حافظه (Memory Manager): پیادهسازی حافظه مجازی و مدیریت فضای آدرسدهی فرآیندها.*   مدیر حافظه پنهان (Cache Manager): بهبود سرعت ورودی/خروجی فایلها با نگه داشتن دادههای دیسک در حافظه اصلی.توابع پشتیبان (Support Functions):*   مدیر اشیاء (Object Manager): ایجاد، مدیریت و حذف اشیاء اجرایی ویندوز (مانند فرآیندها و اشیاء همگامسازی).*   تسهیلات ALPC: انتقال پیام بین فرآیندهای کلاینت و سرور در یک کامپیوتر واحد.*   کتابخانه زمان اجرا (Run-time Library): پردازش رشتهها، عملیات ریاضی و تبدیل دادهها.*   روتینهای پشتیبانی اجرایی: تخصیص حافظه سیستم و مکانیسمهای همگامسازی خاص (مانند Mutexهای سریع).سایر زیرساختها:*   کتابخانه دیباگر هسته: امکان عیبیابی هسته سیستم.*   چارچوب دیباگ حالت کاربر: مدیریت نقاط توقف (Breakpoints) و رویدادهای دیباگ.*   کتابخانه Hypervisor و /strong&gt; پشتیبانی از محیطهای مجازی امن.*   مدیر خطا (Errata Manager): ارائه راهکار برای سختافزارهای غیراستاندارد.*   تأییدکننده درایور (Driver Verifier): بررسی سلامت و درستی عملکرد درایورهای هسته.*   ردیابی رویداد (ETW): ردیابی رویدادها در سطح سیستم.*   زیرساخت تشخیص ویندوز (WDI): ردیابی هوشمند فعالیتهای سیستم بر اساس سناریوهای تشخیصی.*   پشتیبانی WHEA: چارچوبی برای گزارش خطاهای سختافزاری.*   کتابخانه زمان اجرای فایلسیستم (FSRTL): توابع کمکی برای درایورهای فایلسیستم.*   موتور شیم هسته (KSE): فراهم کردن وصلههای سازگاری برای درایورها.هسته (Kernel)هسته شامل مجموعهای از توابع در Ntoskrnl.exe است که مکانیزمهای بنیادی سیستمعامل را فراهم میکند. این وظایف شامل زمانبندی رشتهها (Thread Scheduling)، خدمات همگامسازی و پشتیبانی سطح پایین وابسته به معماری سختافزار (مانند مدیریت وقفهها و استثناها) است. کد هسته عمدتاً به زبان C و در موارد خاص (برای دسترسی مستقیم به دستورالعملهای پردازنده) به زبان اسمبلی نوشته شده است. توابع هسته با پیشوند Ke شناخته میشوند.اشیاء هسته (Kernel Objects)هسته با پیادهسازی مکانیزمهای پایه و اجتناب از سیاستگذاری (Policy making)، خود را از بخش اجرایی (Executive) متمایز میکند. هسته تصمیمات سیاستی را به بخش اجرایی واگذار میکند و تنها در مورد زمانبندی و ارسال رشتهها تصمیمگیرنده است.*   تفاوت با اشیاء اجرایی: اشیاء بخش اجرایی دارای سربارِ سیاستگذاری (مانند دستگیرهها، چکهای امنیتی و سهمیهبندی منابع) هستند، اما اشیاء هسته سادهتر و فاقد این سربارند.*   اشیاء کنترلی (Control Objects): برای کنترل توابع مختلف سیستمعامل استفاده میشوند؛ مانند اشیاء APC (فراخوانی رویه نامتقارن)، DPC (فراخوانی رویه با تأخیر) و اشیاء وقفه.*   اشیاء توزیعکننده (Dispatcher Objects): دارای قابلیت همگامسازی هستند و بر زمانبندی رشتهها تأثیر میگذارند؛ مانند Mutex، Event، Semaphore، Timer و Thread.ساختارهای کنترلی پردازنده (KPCR و KPRCB)هسته برای ذخیره دادههای مربوط به هر پردازنده از ساختاری به نام KPCR (ناحیه کنترل پردازنده هسته) استفاده میکند.*   KPCR: حاوی اطلاعات پایهای مانند جداول وقفه (IDT)، GDT و TSS است. در سیستمهای ۳۲ بیتی از طریق ثبات fs و در ۶۴ بیتی از طریق ثبات gs قابل دسترسی است.*   KPRCB (بلاک کنترل پردازنده هسته): یک ساختار خصوصی درون KPCR است که فقط توسط کد هسته استفاده میشود و شامل موارد زیر است:    *   اطلاعات زمانبندی: رشتههای فعلی، بعدی و رشتههای بیکار (Idle).    *   پایگاه داده توزیعکننده: صفهای آمادهبهکار برای سطوح مختلف اولویت.    *   صف DPC: لیست فراخوانیهای با تأخیر.    *   مشخصات CPU: مدل، سرعت، ویژگیها، تعداد هستهها و ساختار حافظه (NUMA).    *   آمارها: آمارهای مربوط به ورودی/خروجی (I/O)، حافظه پنهان (Cache)، مدیریت حافظه و وقفهها.    *   بهینهسازی: ذخیره ساختارهای اختصاصی هر پردازنده برای افزایش سرعت دسترسی به حافظه.پشتیبانی سختافزاریوظیفه مهم دیگر هسته، انتزاع و جداسازی بخش اجرایی (Executive) و درایورها از تفاوتهای معماری سختافزار است. این کار شامل مدیریت تفاوتها در مواردی مثل وقفهها، ارسال استثناها و همگامسازی در سیستمهای چندپردازندهای است.*   رابطهای قابل حمل: هسته مجموعهای از رابطها را ارائه میدهد که در تمام معماریها از نظر عملکردی یکسان هستند. اکثر کدهای این رابطها نیز در معماریهای مختلف تغییری نمیکنند.*   پیادهسازیهای متفاوت: برخی رابطها (مانند روتینهای Spinlock) بسته به معماری، پیادهسازی متفاوتی دارند یا بخشی از آنها در لایه HAL قرار میگیرد تا با سختافزار خاص هماهنگ شود.*   کدهای اختصاصی معماری:    *   پشتیبانی از x86: شامل کدهای خاص برای اجرای برنامههای قدیمی ۱۶ بیتی MS-DOS (در سیستمهای ۳۲ بیتی) و شبیهسازی حالت Real-mode.    *   مدیریت کش و TLB: به دلیل تفاوت در ساختار کش پردازندهها، کدهای مدیریت حافظه پنهان و بافر ترجمه (Translation Buffer) برای هر معماری بازنویسی شده است.    *   تعویض متن (Context Switching): اگرچه الگوریتم کلی انتخاب رشتهها یکسان است، اما جزئیات ذخیره و بارگذاری وضعیت پردازنده (ثباتها و...) کاملاً به معماری سختافزار بستگی دارد.لایه انتزاعی سختافزاریکی از عناصر حیاتی طراحی ویندوز، قابلیت حمل آن در طیف وسیعی از پلتفرمهای سختافزاری است. لایه انتزاعی سختافزار (HAL) بخش کلیدی در امکانپذیری این قابلیت حمل است. HAL یک ماژول قابل بارگذاری در حالت کرنل (Hal.dll) است که رابط سطح پایین را به پلتفرم سختافزاری که ویندوز روی آن اجرا میشود، فراهم میکند. این لایه جزئیات وابسته به سختافزار مانند رابطهای ورودی/خروجی، کنترلکنندههای وقفه و مکانیسمهای ارتباطی چندپردازندهای - هر تابعی که هم خاص معماری و هم وابسته به ماشین باشد - را پنهان میکند.بنابراین، به جای دسترسی مستقیم به سختافزار، اجزای داخلی ویندوز و درایورهای دستگاه نوشته شده توسط کاربر، با فراخوانی روالهای HAL، زمانی که به اطلاعات وابسته به پلتفرم نیاز دارند، قابلیت حمل را حفظ میکنند. به همین دلیل، بسیاری از روالهای HAL در WDK مستند شدهاند. برای کسب اطلاعات بیشتر در مورد HAL و استفاده از آن توسط درایورهای دستگاه، به WDK مراجعه کنید.گردانندههای دستگاه (Device Drivers)گردانندههای دستگاه، ماژولهای قابل بارگذاری در حالت کرنل (فایلهایی با پسوند .sys) هستند که بین مدیر ورودی/خروجی و سختافزار مربوطه ارتباط برقرار میکنند. این گردانندهها در حالت کرنل و در سه زمینه اجرا میشوند:*   در زمینه نخ کاربر که تابع ورودی/خروجی را آغاز کرده است (مانند عملیات خواندن).*   در زمینه یک نخ سیستمی در حالت کرنل (مانند درخواستی از مدیر Plug and Play).*   در نتیجه یک وقفه، و نه در زمینه یک نخ خاص، بلکه در زمینه نخی که در زمان وقوع وقفه فعال بوده است.گردانندههای دستگاه در ویندوز مستقیماً سختافزار را دستکاری نمیکنند. بلکه توابع موجود در HAL را برای ارتباط با سختافزار فراخوانی میکنند. گردانندهها معمولاً با زبان C و/یا C++ نوشته میشوند.انواع گردانندههای دستگاه:*   گردانندههای سختافزاری: این گردانندهها از HAL برای دستکاری سختافزار استفاده میکنند تا خروجی را به یک دستگاه فیزیکی یا شبکه بنویسند یا از آن ورودی دریافت کنند. انواع مختلفی از این گردانندهها وجود دارد، مانند گردانندههای گذرگاه، گردانندههای رابط انسانی، گردانندههای ذخیرهسازی انبوه و غیره.*   گردانندههای سیستم فایل: این گردانندهها درخواستهای ورودی/خروجی مبتنی بر فایل را میپذیرند و آنها را به درخواستهای ورودی/خروجی برای یک دستگاه خاص ترجمه میکنند.*   گردانندههای فیلتر سیستم فایل: این گردانندهها شامل مواردی هستند که عملیاتی مانند آینهسازی دیسک و رمزگذاری یا جستجو برای یافتن ویروسها را انجام میدهند، درخواستهای ورودی/خروجی را رهگیری میکنند و قبل از ارسال آنها به لایه بعدی (یا در برخی موارد رد عملیات) پردازش ارزشافزوده انجام میدهند.*   تغییر مسیر دهندهها و سرورهای شبکه: این گردانندهها، گردانندههای سیستم فایلی هستند که درخواستهای ورودی/خروجی سیستم فایل را به یک ماشین در شبکه ارسال میکنند و به ترتیب چنین درخواستهایی را دریافت میکنند.*   گردانندههای پروتکل: این گردانندهها یک پروتکل شبکه مانند TCP/IP، NetBEUI و IPX/SPX را پیادهسازی میکنند.*   گردانندههای فیلتر جریان کرنل: این گردانندهها بهصورت زنجیرهای به هم متصل میشوند تا پردازش سیگنال را روی جریانهای داده، مانند ضبط یا نمایش صدا و تصویر، انجام دهند.*   گردانندههای نرمافزاری: اینها ماژولهای کرنل هستند که عملیاتی را انجام میدهند که فقط در حالت کرنل و از طرف یک فرآیند در حالت کاربر قابل انجام است. بسیاری از ابزارهای Sysinternals مانند Process Explorer و Process Monitor از این گردانندهها برای دریافت اطلاعات یا انجام عملیاتی استفاده میکنند که از طریق APIهای حالت کاربر امکانپذیر نیست.مدل گرداننده ویندوز(Windows driver model)مدل گرداننده اصلی در اولین نسخه NT (3.1) ایجاد شد و از Plug and Play (PnP) پشتیبانی نمیکرد. این وضعیت تا زمان ویندوز 2000 (و ویندوز 95/98 در سمت مصرفکننده) ادامه داشت.ویندوز 2000 پشتیبانی از PnP، گزینههای برق و توسعهای به مدل driver  ویندوز NT به نام مدل driver ویندوز (WDM) را اضافه کرد. ویندوز 2000 و نسخههای بعدی میتوانند driver  های قدیمی ویندوز NT 4 را اجرا کنند، اما از آنجایی که این driver  ها از PnP و گزینههای برق پشتیبانی نمیکنند، سیستمهایی که از این گردانندهها استفاده میکنند، در این دو زمینه قابلیتهای کمتری خواهند داشت.در ابتدا، WDM یک مدل driver  مشترک را فراهم میکرد که (تقریباً) از نظر کد منبع بین ویندوز 2000/XP و ویندوز 98/ME سازگار بود. این کار برای آسانتر کردن نوشتن driver  ها برای دستگاههای سختافزاری انجام شد، زیرا به جای دو کد پایه، تنها یک کد پایه مورد نیاز بود. WDM در ویندوز 98/ME شبیهسازی شد. پس از اینکه این سیستمعاملها دیگر مورد استفاده قرار نگرفتند، WDM به عنوان مدل پایه برای نوشتن driver  ها برای دستگاههای سختافزاری برای ویندوز 2000 و نسخههای بعدی باقی ماند.از دیدگاه WDM، سه نوع گرداننده وجود دارد:*   گردانندههای گذرگاه (Bus drivers): یک گرداننده گذرگاه به کنترلر گذرگاه، آداپتور، پل یا هر دستگاهی که دارای دستگاههای فرزند است، خدمات میدهد. گردانندههای گذرگاه گردانندههای ضروری هستند و مایکروسافت معمولاً آنها را ارائه میکند. هر نوع گذرگاه (مانند PCI، PCMCIA و USB) در یک سیستم دارای یک گرداننده گذرگاه است. اشخاص ثالث میتوانند گردانندههای گذرگاه را برای پشتیبانی از گذرگاههای جدید مانند VMEbus، Multibus و Futurebus بنویسند.*   گردانندههای تابع (Function drivers): یک گرداننده تابع، گرداننده اصلی دستگاه است و رابط عملیاتی را برای دستگاه خود فراهم میکند. این یک گرداننده ضروری است مگر اینکه دستگاه به صورت خام (raw) استفاده شود، یعنی پیادهسازیای که در آن ورودی/خروجی توسط گرداننده گذرگاه و هر گرداننده فیلتر گذرگاه، مانند SCSI PassThru، انجام میشود. گرداننده تابع بنا به تعریف، گردانندهای است که بیشترین اطلاعات را در مورد یک دستگاه خاص دارد و معمولاً تنها گردانندهای است که به رجیسترهای خاص دستگاه دسترسی دارد.*   گردانندههای فیلتر (Filter drivers): یک گرداننده فیلتر برای افزودن قابلیت به یک دستگاه یا driver موجود، یا برای اصلاح درخواستهای ورودی/خروجی یا پاسخهای سایر گردانندهها استفاده میشود. اغلب برای رفع مشکل سختافزاری که اطلاعات نادرستی در مورد الزامات منابع سختافزاری خود ارائه میدهد، استفاده میشود. گردانندههای فیلتر اختیاری هستند و میتوانند به تعداد دلخواه، در بالا یا پایین یک گرداننده تابع و بالای یک گرداننده گذرگاه قرار گیرند. معمولاً تولیدکنندگان اصلی تجهیزات (OEMs) یا فروشندگان مستقل سختافزار (IHVs) گردانندههای فیلتر را ارائه میکنند.در محیط گرداننده WDM، هیچ گرداننده واحدی همه جنبههای یک دستگاه را کنترل نمیکند. یک گرداننده گذرگاه مسئول گزارش دستگاههای موجود در گذرگاه خود به مدیر PnP است، در حالی که یک گرداننده تابع دستگاه را دستکاری میکند.در بیشتر موارد، گردانندههای فیلتر سطح پایینتر، رفتار سختافزار دستگاه را تغییر میدهند. به عنوان مثال، اگر یک دستگاه به گرداننده گذرگاه خود گزارش دهد که به 4 پورت ورودی/خروجی نیاز دارد، در حالی که در واقع به 16 پورت ورودی/خروجی نیاز دارد، یک گرداننده فیلتر تابع خاص دستگاه در سطح پایینتر میتواند لیست منابع سختافزاری گزارش شده توسط گرداننده گذرگاه به مدیر PnP را رهگیری کرده و تعداد پورتهای ورودی/خروجی را بهروز کند.گردانندههای فیلتر سطح بالا معمولاً ویژگیهای ارزشافزوده را برای یک دستگاه فراهم میکنند. به عنوان مثال، یک گرداننده فیلتر دستگاه سطح بالا برای یک دیسک میتواند بررسیهای امنیتی اضافی را اعمال کند.فرایندهای سیستمفرایندهای سیستم زیر در هر سیستم ویندوز 10 ظاهر میشوند. یکی از آنها (Idle) اصلاً یک فرایند نیست و سه تای آنها - System، Secure System و Memory Compression - فرایندهای کاملی نیستند زیرا یک فایل اجرایی در حالت کاربر را اجرا نمیکنند. این نوع فرایندها را فرایندهای حداقلی مینامند و در فصل 3 توضیح داده شدهاند.*   فرایند Idle: این فرایند به ازای هر CPU یک رشته (thread) دارد تا زمان بیکار CPU را محاسبه کند.*   فرایند System: این فرایند اکثر رشتهها و هندلهای سیستمی در حالت هسته را شامل میشود.*   فرایند Secure System: این فرایند فضای آدرس هسته امن را در VTL 1 (در صورت اجرا) شامل میشود.*   فرایند Memory Compression: این فرایند مجموعه کاری فشرده فرایندهای حالت کاربر را شامل میشود.*   مدیر جلسه (Smss.exe).*   زیرسیستم ویندوز (Csrss.exe).*   مقداردهی اولیه جلسه 0 (Wininit.exe).*   فرایند ورود به سیستم (Winlogon.exe).*   مدیر کنترل سرویس (Services.exe) و فرایندهای سرویس فرزندی که ایجاد میکند، مانند فرایند میزبان سرویس عمومی ارائه شده توسط سیستم (Svchost.exe).*   سرویس احراز هویت امنیتی محلی (Lsass.exe)، و اگر Credential Guard فعال باشد، سرور احراز هویت امنیتی محلی ایزوله (Lsaiso.exe).Telegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Fri, 15 May 2026 11:40:22 +0330</pubDate>
            </item>
                    <item>
                <title>اسمبلی قسمت اول ثبات های CPU</title>
                <link>https://virgool.io/@m_14047363/%D8%A7%D8%B3%D9%85%D8%A8%D9%84%DB%8C-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-%D8%AB%D8%A8%D8%A7%D8%AA-%D9%87%D8%A7%DB%8C-cpu-ecemiwcj1pap</link>
                <description>پردازنده‌های اینتل 32 بیتی، مانند خانواده x86، دارای مجموعه‌ای از ثبات‌ها هستند که به دو دسته اصلی تقسیم می‌شوند: ثبات‌های عمومی (General Purpose Registers) و ثبات‌های خاص (Special Purpose Registers). در ادامه به معرفی و توضیح این ثبات‌ها می‌پردازیم:1. ثبات‌های عمومی (General Purpose Registers)پردازنده‌های اینتل 32 بیتی دارای 8 ثبات عمومی اصلی هستند که هرکدام می‌توانند برای ذخیره‌سازی داده‌ها یا نتایج محاسباتی استفاده شوند. این ثبات‌ها به اختصار به شرح زیر هستند:EAX (Extended Accumulator Register):این ثبات برای ذخیره‌سازی نتایج محاسبات اصلی مورد استفاده قرار می‌گیرد و به عنوان جمع‌کننده (Accumulator) در عملیات حسابی و منطقی عمل می‌کند.EBX (Extended Base Register):این ثبات معمولاً برای ذخیره آدرس پایه استفاده می‌شود و به عنوان مقادیری برای اشاره به داده‌ها در حافظه به کار می‌رود.ECX (Extended Counter Register):ثبات ECX به طور عمده در حلقه‌ها و عملیات شمارش (مانند شمارش در حلقه‌های for و while) استفاده می‌شود.EDX (Extended Data Register):این ثبات به طور معمول برای اجرای عملیات حسابی و نگهداری مقادیر اضافی در برخی از عملیات (مانند تقسیم و ضرب بزرگ) به کار می‌رود.ESI (Extended Source Index):این ثبات به عنوان اشاره‌گر منبع (Source Index) در عملیات کپی داده‌ها و پردازش رشته‌ها (Strings) استفاده می‌شود.EDI (Extended Destination Index):این ثبات به عنوان اشاره‌گر مقصد (Destination Index) در عملیات کپی و جابه‌جایی داده‌ها بین حافظه و ثبات‌ها به کار می‌رود.EBP (Extended Base Pointer):معمولاً برای اشاره به فریم استک (Stack Frame) در ساختارهای تابع و ذخیره متغیرهای محلی استفاده می‌شود.ESP (Extended Stack Pointer):این ثبات آدرس بالای استک را ذخیره می‌کند و به عنوان مکانیزمی برای مدیریت فراخوانی توابع و ذخیره‌سازی داده‌های موقتی عمل می‌کند.2. ثبات‌های خاص (Special Purpose Registers)این ثبات‌ها وظایف خاصی دارند و معمولاً برای کنترل و مدیریت پردازنده استفاده می‌شوند:EIP (Extended Instruction Pointer):این ثبات آدرس دستورالعمل بعدی که باید اجرا شود را ذخیره می‌کند. به عبارت دیگر، EIP بیان‌گر مکان در کد است که پردازنده در حال اجرای آن است.EFLAGS (Flags Register):این ثبات شامل وضعیت‌های مختلف پردازنده (Flags) است که به مدیریت عملیات تأثیر می‌گذارد. این وضعیت‌ها معمولاً مربوط به مقایسه‌ها و وضعیت‌های حسابی هستند و شامل مشخصه‌هایی مانند Zero Flag، Carry Flag و Sign Flag هستند.ثبات EFLAGS (یا Flags Register) در پردازنده‌های اینتل 32 بیتی، مجموعه‌ای از بیت‌ها است که وضعیت پردازنده را در زمان انجام عملیات‌های مختلف نشان می‌دهد. این بیت‌ها به سیستم‌عامل و برنامه‌ها اجازه می‌دهند تا وضعیت‌های مختلف پردازنده را بررسی کنند و تصمیمات لازم را اتخاذ کنند.توضیح بیت‌های مهم EFLAGS:در EFLAGS، بیت‌های مختلفی وجود دارند که هر کدام یک وضعیت خاص را گزارش می‌دهند. در زیر به توضیح برخی از بیت‌های مهم این ثبات می‌پردازیم:CF (Carry Flag):این بیت زمانی تنظیم می‌شود که در عملیات جمع، بیش از ظرفیت ثبات نتیجه به وجود بیاید (مثلاً در جمع دو عدد بزرگتر از حد مجاز). همچنین در عملیات تفریق، اگر مقایسه نتیجه نشان دهد که عدد کم است، CF نیز تنظیم می‌شود.PF (Parity Flag):این بیت نشان‌دهنده‌ی زوج بودن یا فرد بودن تعداد بیت‌های &quot;1&quot; در نتیجه آخرین عملیات است. اگر تعداد بیت‌های &quot;1&quot; زوج باشد، این بیت برابر با &quot;1&quot; و در غیر این صورت برابر با &quot;0&quot; خواهد بود.AF (Adjust Flag):این بیت در عملیات‌های باینری و در مقایسه‌های چهار بیتی (Nibble) استفاده می‌شود. اگر در نتیجه یک عملیات نیاز به حملی به بیتی باشد که در نشان‌دهنده عدد باینری چهار بیتی است، این بیت تنظیم می‌شود.ZF (Zero Flag):این بیت در صورتی تنظیم می‌شود که نتیجه آخرین عملیات برابر با صفر باشد. از این بیت به طور معمول برای بررسی برابری یا عدم برابری دو مقدار استفاده می‌شود.SF (Sign Flag):این بیت نشان‌دهنده علامت نتیجه آخرین عملیات است. اگر نتیجه یک عدد منفی باشد (بیت بیشترین مقدار = 1)، SF تنظیم می‌شود و در غیر این صورت (بیت بیشترین مقدار = 0) برابر با صفر خواهد بود.OF (Overflow Flag):این بیت زمانی تنظیم می‌شود که نتیجه یک عملیات حسابی بیشتر از ظرفیت ثبات باشد. به ویژه در مواردی که علامت عملیات و نتیجه آن با یکدیگر تناقض دارند (مثلاً جمع دو عدد مثبت که نتیجه‌ای منفی به دست می‌دهد).بیت‌های دیگر:علاوه بر بیت‌های فوق، EFLAGS شامل بیت‌های دیگری نیز هست که هر کدام وضعیت‌های خاصی را نشان می‌دهند، مانند:DF (Direction Flag): برای تعیین جهت پردازش داده‌ها در عملیات‌های رشته‌ای (String Operations) استفاده می‌شود.IT (Interrupt Flag): تعیین‌کننده این است که پردازنده می‌تواند به وقفه‌ها پاسخ دهد یا خیر. اگر این بیت تنظیم شود، پردازنده وقفه‌ها را پردازش می‌کند.نتیجه‌گیری:ثبات EFLAGS در پردازنده‌های اینتل 32 بیتی نقش مهمی در مدیریت و کنترل عملیات‌های مختلف ایفا می‌کند. برنامه‌نویسان و سیستم‌عامل‌ها از این بیت‌ها برای تصمیم‌گیری در مورد شرایط مختلف استفاده می‌کنند و به کمک آن‌ها می‌توانند عملکرد بهینه‌تری را برای پردازش‌های سیستم فراهم کنند.ثبات های داده (Data Registers)چهار ثبات داده ای 32 بیتی برای اعمال محاسباتی، منطقی و غیره مورد استفاده قرار می گیرند. این ثبات ها را به سه روش زیر می توان استفاده کرد:به عنوان یک ثبات 32 بیتی کامل EAX , EBX, ECX, EDX.بخش کم ارزش به عنوان ثبات های 16 بیتی AX, BX, CX, DX.بخش کم ارزش و پر ارزش هر یک به عنوان ثبات های 16 بیتی.ثبات های سگمنت (Segment Registers)ثبات‌های سگمنت (Segment Registers) در پردازنده‌های اینتل، به ویژه در معماری 16 بیتی و همچنین در نسخه‌های قبل از 32 بیتی x86، برای مدیریت حافظه مورد استفاده قرار می‌گیرند. این ثبات‌ها به سیستم اجازه می‌دهند که به یک نوع تقسیم‌بندی منطقی از فضای حافظه بپردازند که به آن «سگمنتیشن» می‌گویند. هر سگمنت نمایانگر یک بخش خاص از حافظه است و این نحوه تقسیم‌بندی به پردازنده این امکان را می‌دهد که با حجم زیادی از حافظه بدون نیاز به آدرس‌دهی مستقیم به همه حافظه، کار کند.انواع ثبات‌های سگمنت:در معماری x86، چهار ثبات سگمنت اصلی وجود دارد:CS (Code Segment Register):این ثبات آدرس سگمنت کد (برنامه) را نگه می‌دارد. هنگام اجرای برنامه، پردازنده به این ثبات مراجعه می‌کند تا آدرس‌های موجود در کد را پیدا کند.DS (Data Segment Register):این ثبات آدرس سگمنت داده‌ها را ذخیره می‌کند. هنگامی که یک برنامه به داده‌ها دسترسی پیدا می‌کند، از این ثبات برای تعیین مکان داده‌ها در حافظه استفاده می‌شود.SS (Stack Segment Register):این ثبات آدرس سگمنت استک را نگه می‌دارد. استک برای ذخیره‌سازی داده‌های موقتی مانند آدرس‌های بازگشتی و متغیرهای محلی در طول پردازش توابع استفاده می‌شود.ES (Extra Segment Register):این ثبات معمولاً به عنوان سگمنت اضافی برای عملیات‌های مختلف مانند پردازش رشته‌ها (String Operations) به کار می‌رود. می‌توان از آن برای جلوگیری از تداخل داده‌ها یا برای ذخیره داده‌های اضافی استفاده کرد.نحوه کارکرد:آدرس‌دهی مستقیم:در معماری x86، آدرس‌دهی حافظه معمولاً به دو قسمت تقسیم می‌شود: آدرس سگمنت و آدرس افست (Offset). برای مثال، برای دستیابی به یک آدرس خاص در حافظه، پردازنده آدرس سگمنت را از یکی از ثبات‌های سگمنت می‌گیرد و به آن آدرس افست اضافه می‌کند.مدیریت حافظه:این ثبات‌ها به سیستم اجازه می‌دهند که فضای حافظه را به بخش‌های مختلف تقسیم کند. به این ترتیب، برنامه‌ها می‌توانند در سگمنت‌های مختلف اجرا شوند و تداخل کمتری میان آن‌ها وجود داشته باشد.نتیجه‌گیری:ثبات‌های سگمنت در پردازنده‌های اینتل نقش حیاتی در نحوه مدیریت و دسترسی به حافظه ایفا می‌کنند. این ثبات‌ها به توسعه‌دهندگان کمک می‌کنند تا با فضای حافظه به‌طور موثری کار کنند و در عین حال از بروز خطاهای ناشی از تداخل داده‌ها جلوگیری کنند. با این حال، در پردازنده‌های مدرن، سیستم‌های عامل و برنامه‌نویسی به ویندوزهای 32 بیتی و 64 بیتی تغییر یافته و معمولاً کمتر از این نوع سگمنتیشن استفاده می‌شود.Telegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Thu, 14 May 2026 22:33:55 +0330</pubDate>
            </item>
                    <item>
                <title>اسمبلی قسمت قسمت دوم دستور mov و add و sub و div و mul</title>
                <link>https://virgool.io/@m_14047363/%D8%A7%D8%B3%D9%85%D8%A8%D9%84%DB%8C-%D9%82%D8%B3%D9%85%D8%AA-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-%D8%AF%D8%B3%D8%AA%D9%88%D8%B1-mov-%D9%88-add-%D9%88-sub-%D9%88-div-%D9%88-mul-rmlm3gujgczr</link>
                <description>.386
.model flat,stdcall
.stack 4096

ExitProcess proto, dwExitCode:dword

.data
    num1 DWORD 20
    num2 DWORD 5

    result_add DWORD ?
    result_sub DWORD ?
    result_mul DWORD ?
    result_div_q DWORD ?
    result_div_r DWORD ?

.code
main proc
    ; ADD
    mov eax, num1
    add eax, num2
    mov result_add, eax

    ; SUB
    mov eax, num1
    sub eax, num2
    mov result_sub, eax

    ; MUL
    mov eax, num1
    mov ebx, num2
    mul ebx
    mov result_mul, eax

    ; DIV
    mov eax, num1
    xor edx, edx
    mov ebx, num2
    div ebx

    mov result_div_q, eax
    mov result_div_r, edx

    invoke ExitProcess, 0
main endp
end mainTelegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Thu, 14 May 2026 22:32:18 +0330</pubDate>
            </item>
                    <item>
                <title>Windows System Internals (Chapter 1 Concepts and tools)</title>
                <link>https://virgool.io/@m_14047363/windows-system-internals-chapter-1-concepts-and-tools-o7hthvpqtuny</link>
                <description>حالت کاربر (User-mode) برنامه‌ریزی نخ‌ها (Threads)، که تنها در نسخه‌های ۶۴ بیتی ویندوز در دسترس است، همان مزایای اصلی فیبرها را فراهم می‌آورد — و تنها چند عیب دارد. نخ‌های حالت کاربر دارای وضعیت هسته‌ای خود هستند و بنابراین در مقابل هسته قابل مشاهده‌ند، که این امکان را فراهم می‌کند تا چندین نخ حالت کاربر عملیات مسدودکننده را انجام دهند، منابع را به اشتراک بگذارند و بر سر آن‌ها رقابت کنند. یا، زمانی که دو یا چند نخ حالت کاربر نیاز به انجام کار در حالت کاربر دارند، می‌توانند به‌طور دوره‌ای زمینه اجرای خود را تغییر دهند (با رها کردن از یک نخ به دیگری) در حالت کاربر، بدون نیاز به درگیری با زمان‌بندی. از دید هسته، همان نخ هسته‌ای همچنان در حال اجرا است و هیچ چیز تغییر نمی‌کند. زمانی که یک نخ حالت کاربر عملیاتی انجام دهد که نیاز به ورود به هسته دارد (مانند یک تماس سیستم‌کمک)، به نخ هسته‌ای اختصاصی خودش (که به آن تغییر زمینه مستقیم گفته می‌شود) سوئیچ می‌کند. در حالی که نخ‌های هم‌زمان حالت کاربر هنوز نمی‌توانند بر روی چند پردازنده اجرا شوند، اما از مدل غیرفعال لازم پیروی می‌کنند که تنها به صورت تعاونی نیست.اگرچه نخ‌ها دارای زمینه اجرایی خود هستند، اما هر نخ در یک فرآیند، فضای آدرس مجازی همان فرآیند را به اشتراک می‌گذارد (علاوه بر سایر منابع مربوط به آن فرآیند). بنابراین، تمام نخ‌های یک فرآیند دسترسی کامل خواندن و نوشتن به فضای آدرس مجازی آن فرآیند دارند. با این حال، نخ‌ها نمی‌توانند به طور تصادفی به فضای آدرس فرآیند دیگری ارجاع دهند، مگر اینکه فرآیند دیگر بخشی از فضای آدرس خصوصی خود را به عنوان یک بخش حافظه مشترک (که در API ویندوز به آن شیء نگاشت فایل گفته می‌شود) در اختیار قرار دهد، یا اینکه یک فرآیند حق داشته باشد فرآیند دیگری را باز کند و توابع حافظه فرآیند مانند ReadProcessMemory و WriteProcessMemory را اجرا کند (که به صورت پیش‌فرض، فرآیندی با همان حساب کاربری و در داخل یک AppContainer یا نوع دیگری از sandbox، می‌تواند این کار را انجام دهد، مگر اینکه فرآیند هدف از نظر حفاظتی محافظت شده باشد).علاوه بر فضای آدرس خصوصی و یک یا چند نخ، هر فرآیند دارای یک زمینه امنیتی است و فهرستی از هندل‌های باز به اشیاء هسته‌ای مانند فایل‌ها، بخش‌های حافظه مشترک، یا یکی از اشیاء هم‌زمان‌سازی مانند موتیج‌ها، رویدادها یا سمفورها است، همان‌طور که در شکل ۱-۲ نشان داده شده است.هر فرآیند دارای یک زمینه امنیتی است که در یک شیء به نام توکن دسترسی (access token) ذخیره می‌شود. توکن دسترسی فرآیند شامل شناسایی امنیتی و اعتبارنامه‌های مربوط به آن فرآیند است. به طور پیش‌فرض، نخ‌ها توکن دسترسی خاص خود را ندارند، اما می‌توانند یکی دریافت کنند، که این امکان را فراهم می‌آورد تا نخ‌های فردی بتوانند زمینه امنیتی یک فرآیند دیگر — از جمله فرآیندهای روی یک سیستم ویندوز راه دور — را به صورت کوتاه‌مدت به‌صورت شخصی، تقلید کنند، بدون اینکه بر دیگر نخ‌های همان فرآیند تأثیر بگذارند. (برای اطلاعات بیشتر درباره امنیت فرآیند و نخ، به فصل ۷ مراجعه کنید).افزون بر این، ساختارهای داده‌ای به نام Descriptors آدرس مجازی (VAD‌ها) وجود دارند که مدیر حافظه از آن‌ها برای پیگیری آدرس‌های مجازی مورد استفاده در فرآیند بهره می‌برد.هایپروایزرتحولات اخیر در مدل‌های کاربردی و نرم‌افزاری، همانند معرفی خدمات مبتنی بر ابر و فراگیری دستگاه‌های اینترنت اشیا (IoT)، نیاز به روش‌های مؤثرتر برای مجازی‌سازی سیستم‌عامل‌های مهمان روی سخت‌افزار میزبان، چه برای میزبانی چندین مستاجر در یک فارم سرور و اجرای صدها وب‌سایت ایزوله روی یک سرور، چه برای اجازه توسعه‌دهندگان در تست ده‌ها نوع سیستم‌عامل متفاوت بدون نیاز به سخت‌افزار اختصاصی، را افزایش داده است. این نیاز به مجازی‌سازی سریع، کارآمد و امن، مدل‌های جدیدی از محاسبات و تفکر درباره نرم‌افزار را به وجود آورده است. در واقع، در حال حاضر، برخی نرم‌افزارها — مانند داکر (Docker)، که در ویندوز ۱۰ و سرور ۲۰۱۶ پشتیبانی می‌شود — در کانتینرها اجرا می‌شوند. این کانتینرها ماشین‌های مجازی کاملاً ایزوله‌ای هستند که مخصوص اجرای یک استک یا چارچوب نرم‌افزاری خاص طراحی شده‌اند و مرزهای ماشین‌مهمان/میزبان را بیشتر توسعه می‌دهند.برای ارائه چنین خدمات مجازی‌سازی، تقریباً تمامی راه‌حل‌های مدرن از استفاده از هایپروایزر بهره می‌برند. هایپروایزر یک جزء تخصصی و با اولویت بالا است که امکان مجازی‌سازی و ایزوله‌سازی تمامی منابع روی دستگاه، از حافظه مجازی و فیزیکی گرفته تا وقفه‌های دستگاه، و حتی دستگاه‌های PCI و USB، را فراهم می‌کند. نمونه‌ای از این نوع هایپروایزر، Hyper-V است که عملکرد کلاینت Hyper-V در ویندوز ۸.۱ و نسخه‌های بعدی را تامین می‌کند. محصولات رقیب مانند Xen، KVM، VMware و VirtualBox نیز هر کدام هایپروایزرهای خاص خود را پیاده‌سازی می‌کنند که هر یک مزایا و نقاط ضعف خاص خود را دارند.به دلیل ماهیت فوق‌العاده اولویت‌دار و دسترسی فراتر از هسته، هایپروایزر مزیتی متمایز دارد که فراتر از صرف اجرای چند نمونه مهمان از سیستم‌عامل‌های دیگر است: این می‌تواند یک نمونه میزبان را محافظت و نظارت کند و گواهی‌نامه‌ها و تضمین‌هایی ارائه دهد که فراتر از امکانات هسته است. در ویندوز ۱۰، مایکروسافت حالا از هایپروایزر Hyper-V برای ارائه مجموعه جدیدی از خدمات به نام امنیت مبتنی بر مجازی‌سازی (VBS) بهره می‌برد، که شامل موارد زیر است:- Device Guard: این قابلیت، اعتبارسنجی کد (HVCI) را فراهم می‌کند و ضمانت‌های امضای کد قوی‌تر نسبت به تنها KMCS را تامین می‌کند، و اجازه می‌دهد تا سیاست امضا (Signature Policy) ویندوز در حالت کاربر و هسته سفارشی شود.- Hyper Guard: این سیستم، ساختارهای کلیدی مرتبط با هسته و هایپروایزر را محافظت می‌کند.- Credential Guard: این قابلیت، جلوگیری از دسترسی غیرمجاز به اطلاعات و اسرار حساب دامنه‌ها و احراز هویت‌های بیومتریک امن را فراهم می‌سازد.- Application Guard: این حالت، برای مرورگر مایکروسافت اج، یک محیط ایزوله و امن‌تر ارائه می‌دهد.- Host Guardian و Shielded Fabric: این فناوری‌ها با بهره‌گیری از یک TPM مجازی (v-TPM)، از ماشین‌های مجازی در برابر زیرساخت میزبان محافظت می‌کنند.علاوه بر این، هایپروایزر Hyper-V امکاناتی برای کاهش آسیب‌پذیری‌های هسته‌ای در مقابل بهره‌برداری‌های مخرب و مهاجمان فراهم می‌کند. مزیت کلیدی این فناوری‌ها این است که، برخلاف بهبودهای امنیتی مبتنی بر هسته گذشته، آسیب‌پذیری آنان در برابر درایورهای مخرب یا ناسازگار، چه امضاشده و چه امضا نشده، بسیار کم است. این امنیت بالا، به لطف اجرای لایه‌های Trusted Virtual Levels (VTLs) است.زیرا، سیستم‌عامل عادی و اجزایش در حالت کم‌اطمینان‌تر (VTL 0) قرار دارند، ولی فناوری‌های VBS در VTL 1 (سطح بالاتر از اولویت) اجرا می‌شوند و نمی‌توانند تحت تأثیر کدهای در حالت هسته‌ای قرار گیرند. بنابراین، کدهای این فناوری‌ها در حوزه فضای امتیاز VTL 0 باقی می‌مانند. می‌توان VTLها را به‌عنوان مکمل‌هایی برای سطح‌های امتیاز پردازنده در نظر گرفت: حالت هسته و کاربر در هر VTL وجود دارند، و هایپروایزر مسئول مدیریت امتیازها در بین آن‌ها است.فریم‌ویر (Firmware)اجزای ویندوز به طور فزاینده‌ای بر امنیت سیستم‌عامل و هسته آن تکیه می‌کنند، و هسته نیز در حال حاضر بر حفاظت هایپروایزر متکی است. سوال این است که چه چیزی می‌تواند تضمین کند که این اجزا با امنیت بارگذاری می‌شوند و محتواهایشان را تأیید می‌کند. این عموماً وظیفه بوت‌لودر (boot loader) است، اما آن نیز نیازمند همان سطح از بررسی و تأیید اصالت است، که موجب ایجاد یک سلسله مراتب اعتماد پیچیده‌تر می‌شود.پس، چه چیزی زنجیره اصلی اعتماد را فراهم می‌کند که می‌تواند فرآیند راه‌اندازی بدون مشکل را تضمین کند؟ در سیستم‌های مدرن ویندوز ۸ و بعد از آن، این موضوع به عهده فریم‌ویر سیستم می‌باشد، که باید بر پایه سیستم‌های تأییدشده مبتنی بر UEFI باشد. به عنوان بخشی از استاندارد UEFI (که ویندوز آن را تعیین می‌کند)، باید پیاده‌سازی راه‌اندازی امن (Secure Boot) با ضمانت‌های قوی و الزامات مربوط به کیفیت امضاهای نرم‌افزارهای مرتبط با بوت، وجود داشته باشد. از طریق این فرآیند تأیید، اجزای ویندوز مطمئن می‌شوند که به صورت امن از همان ابتدای فرآیند راه‌اندازی بارگذاری می‌شوند. علاوه بر این، فناوری‌هایی مانند ماژول اعتمادپذیر پلت‌فرم (TPM) می‌توانند فرآیند را اندازه‌گیری کرده و اثبات (attestation) انجام دهند (هم به صورت محلی و هم از راه دور). با همکاری‌های صنعت، مایکروسافت فهرست مجازها (whitelist) و فهرست غیرمجازها (blacklist) مربوط به اجزای راه‌اندازی امن UEFI را مدیریت می‌کند، در صورت بروز خطا یا نفوذ در نرم‌افزارهای راه‌اندازی، و به‌روزرسانی‌های ویندوز حالا شامل به‌روزرسانی‌های فریم‌ویر نیز می‌شود. اشیاء و دسته‌دستی‌هادر سیستم‌عامل ویندوز، یک شیء هسته‌ای (kernel object) نمونه‌ای منفرد در زمان اجرا از یک نوع شیء تعریف‌شده به صورت ایستا است. نوع شیء شامل یک دادهٔ تعریف‌شده به وسیلهٔ سیستم، توابعی که روی نمونه‌های آن داده عمل می‌کنند، و مجموعه‌ای از ویژگی‌های شیء است. اگر شما برنامه‌های ویندوز بنویسید، ممکن است با اشیایی مانند فرآیند، نخ، فایل و رویداد روبه‌رو شوید تا فقط چند نمونه را نام ببریم. این اشیاء بر پایهٔ اشیاء سطح پایین‌تری ساخته و مدیریت می‌شوند که ویندوز آن‌ها را می‌آفریند و مدیریت می‌کند. در ویندوز، یک فرآیند نمونه‌ای است از نوع شیء فرآیند، یک فایل نمونه‌ای است از نوع شیء فایل، و به همین ترتیب سایر موارد.یک ویژگیِ شیء (object attribute) مقداری داده درون شیء است که تاحدی وضعیت شیء را تعریف می‌کند. برای نمونه، شیء از نوع فرآیند ممکن است ویژگی‌هایی داشته باشد که شامل شناسهٔ فرایند (process ID)، اولویت پایهٔ زمان‌بندی، و نشانگرِ به شیءِ توکن دسترسی (access token) باشد. روش‌های شیء (object methods)، یعنی روش‌های جهت دستکاری اشیاء، معمولاً ویژگی‌های شیء را می‌خوانند یا تغییر می‌دهند. برای مثال، متد open برای یک فرآیند ورودیِ شناسهٔ فرآیند را می‌پذیرد و نشانگری به شیء را به عنوان خروجی برمی‌گرداند. fundamental difference: شیء با ساختار داده‌ای عادی تفاوت اساسی دارد این است که ساختار داخلی یک شیء مبهم (opaque است). شما باید از یک سرویس شیء استفاده کنید تا داده‌ای را از شیء بیرون بگیرید یا در آن داده‌ای وارد کنید. به طور مستقیم نمی‌توانید داده‌های داخل شیء را بخوانید یا تغییر دهید. این تفاوت، پیاده‌سازی زیرین شیء را از کدی که صرفاً از آن استفاده می‌کند جدا می‌کند؛ روشی که به شیوه‌ای امکان تغییر ساده پیاده‌سازی‌های شیء در طول زمان را می‌دهد.اشیاء با کمک بخشی از هسته که به آن مدیر شیء (object manager) گفته می‌شود، روشی مناسب برای انجام چهار کار مهم سیستم‌عامل ارائه می‌دهند:- ارائه نام‌های قابل‌خواندن برای انسان برای منابع سیستم- به اشتراک گذاری منابع و داده‌ها بین فرآیندها- محافظت از منابع در برابر دسترسی غیرمجاز- پیگیری ارجاعات، که به سیستم اجازه می‌دهد تشخیص دهد که آیا شیء دیگر استفاده نمی‌شود تا بتوان آن را به‌طور خودکار از بین بردهمه ساختارهای داده در ویندوز به‌طور کلی شیء نیستند. تنها داده‌هایی که نیاز به اشتراک‌گذاری، حفاظت، نام‌گذاری یا نمایش به برنامه‌های کاربری-حالتی (از طریق سرویس‌های سیستم) دارند، در اشیاء قرار می‌گیرند. ساختارهای استفاده‌شده فقط توسط یک جزء از OS برای انجام وظایف داخلی، شیء محسوب نمی‌شوند.امنیتویندوز از ابتدا به گونه‌ای طراحی شد که امن باشد و الزامات مربوط به ارزیابی‌های امنیتی دولتی و صنعتی مختلف را برآورده کند، مانند مشخصات Common Criteria for Information Technology Security Evaluation (CCITSE). دستیابی به یک رتبه امنیتی تأییدشده از دولت به سیستم‌عامل اجازه می‌دهد تا در این عرصه رقابت کند. البته بسیاری از این قابلیت‌ها، برای هر سیستم چندکاربره مزایای مفیدی هستند.قابلیت‌های اصلی امنیتی ویندوز عبارت‌اند از:حفاظت اختیاری (need-to-know) و اجباری برای تمام اشیای سیستم قابل به‌اشتراک‌گذاری، مانند فایل‌ها، پوشه‌ها، فرآیندها، نخ‌ها و غیرهحسابرسی امنیتی برای پاسخگویی به مسئولیت‌پذیری موضوعات، یا کاربران، و اقداماتی که انجام می‌دهنداحراز هویت کاربر هنگام ورودجلوگیری از این‌که یک کاربر به منابع بدون مقداردهی مناسب دسترسی پیدا کند، مانند حافظه آزاد یا فضای دیسک که کاربر دیگری آزاد کرده است، نیز جزء وظایف امنیتی است.ویندوز سه شکل کنترل دسترسی بر اشیاء دارد:کنترل دسترسی اختیاری (Discretionary access control)این مکانیزم حفاظتی است که اکثر افراد هنگام فکر کردن به امنیت سیستم‌عامل به آن فکر می‌کنند. این روش است که صاحبان اشیاء (مانند فایل‌ها یا پرینترها) به دیگران دسترسی بدهند یا دسترسی را محدود کنند. وقتی کاربران وارد سیستم می‌شوند، مجموعه‌ای از اعتبارنامه‌های امنیتی یا یک زمینه امنیتی به آن‌ها داده می‌شود. وقتی آن‌ها در تلاش برای دسترسی به اشیاء هستند، زمینه امنیتی‌شان با لیست کنترل دسترسی (ACL) شیء که می‌خواهند به آن دسترسی پیدا کنند مقایسه می‌شود تا تعیین کند آیا اجازه انجام درخواست وجود دارد یا خیر. در Windows Server 2012 و Windows 8 این کنترل اختیاری با پیاده‌سازی کنترل دسترسی مبتنی بر ویژگی (Attribute-Based Access Control) یا کنترل دسترسی پویا گسترش یافته است. با این حال، لیست دسترسی یک منبع الزاماً کاربران و گروه‌های فردی را شناسایی نمی‌کند. در عوض، ویژگی‌ها یا ادعاهای لازم که به دسترسی به یک منبع می‌انجامند مانند «سطح پاکت: Top Secret» یا «سن: 10 سال» را شناسایی می‌کند. با قابلیت پرکردن این ویژگی‌ها به‌طور خودکار از طریق تجزیه پایگاه‌های داده SQL و طرح‌ها از طریق دایرکتوری فعال، این مدل امنیتی بسیار زیباتر و انعطاف‌پذیرتر است و به سازمان‌ها کمک می‌کند از مدیریت گروهی و سلسله‌مراتب گروهی دستی فرار کنند.کنترل دسترسی ممتاز (Privileged access control)این کنترل برای مواقعی لازم است که کنترل دسترسی اختیاری برای امنیت کافی نیست. این روش تضمین می‌کند که کسی بتواند به اشیای محافظت‌شده دسترسی پیدا کند اگر مالک آن در دسترس نباشد. برای مثال، اگر یکی از کارمندان شرکت را ترک کند، مدیر باید راهی برای دسترسی به فایل‌هایی که ممکن است تنها برای همان کارمند قابل دسترسی بوده‌اند بیابد. در این حالت، در ویندوز مدیر می‌تواند مالکیت فایل را به‌عهده بگیرد تا بتواند حقوق آن را به‌طور لازم مدیریت کند.کنترل یکپارچگی اجباری (Mandatory integrity control)این قابلیت زمانی لازم است که یک سطح امنیتی اضافی برای محافظت از اشیایی که از همان حساب کاربری استفاده می‌کنند، مورد نیاز باشد. این برای همه چیز از فراهم کردن بخشی از فناوری sandboxing برای برنامه‌های ویندوز تا جداسازی مرورگر Internet Explorer در حالت Protected Mode و سایر مرورگرها از تنظیمات کاربر، تا محافظت از اشیایی که توسط حساب مدیر بالامرتبه ایجاد شده‌اند از دسترسی توسط حساب نوبت‌کار استفاده نشده، به کار می‌رود.از ویندوز 8 به بعد، ظرفی به نام AppContainer برای میزبانی برنامه‌های ویندوز استفاده می‌شود که با سایر AppContainerها و فرآیندهای غیر ویندوز در ارتباط است و ایزولاسیونی فراهم می‌کند. کد در AppContainerها می‌تواند با کارگزاران (فرآیندهای غیرایزوله که با اعتبارنامه کاربر اجرا می‌شوند) و گاهی با سایر AppContainerها یا فرآیندها از طریق قراردادهای روشن‌تعریف‌شده‌ای توسط زمان اجرای ویندوز ارتباط برقرار کند. نمونه‌ای استاندارد از این مورد مرورگر مایکروسافت اج است که در داخل AppContainer اجرا می‌شود و به این ترتیب حفاظت بهتری در برابر کد مخرب داخل محدوده‌های آن فراهم می‌کند. علاوه بر این، توسعه‌دهندگان ثالث نیز می‌توانند از AppContainerها برای ایزوله کردن برنامه‌های خود استفاده کنند. مدل AppContainer رویکرد سنتی برنامه‌نویسی را به سمت یک مدل چندفرایندی با چندین پردازش تغییر می‌دهد.امنیت در رابط کاربری API ویندوز نفوذ دارد. زیربنای ویندوز امنیت مبتنی بر شیء را در همان روشی که سیستم‌عامل انجام می‌دهد، پیاده‌سازی می‌کند: حفاظت اشیای مشترک ویندوز از طریق تخصیص Descriptors امنیتی ویندوز به آن‌ها. نخستین‌بار که یک برنامه قصد دسترسی به یک شیء مشترک را دارد، زیرسیستم ویندوز صحت دسترسی آن را بررسی می‌کند. اگر بررسی امنیت موفق باشد، زیربنای ویندوز اجازه می‌دهد که برنامه به کار خود ادامه دهد.رجیستریاگر با سیستم‌عامل‌های ویندوز کار کرده باشید، احتمالاً درباره رجیستری شنیده‌اید یا به آن نگاه کرده‌اید. نمی‌توانید درباره جنبه‌های داخلی ویندوز زیاد صحبت کنید بدون اینکه به رجیستری اشاره کنید، زیرا رجیستری پایگاه داده سیستم است که اطلاعات لازم برای بوت و پیکربندی سیستم، تنظیمات نرم‌افزار سطح سیستم که عملیات ویندوز را کنترل می‌کنند، پایگاه داده امنیتی و تنظیمات پیکربندی کاربر به کاربر مانند اینکه از چه screensaver استفاده شود را در بر می‌گیرد. علاوه بر این، رجیستری پنجره‌ای به داده‌های حافظه‌ای پویا در RAM را نیز ارائه می‌دهد، مانند وضعیت سخت‌افزاری فعلی سیستم (کدام درایورهای دستگاه بارگذاری شده‌اند، منابعی که از آن‌ها استفاده می‌شوند و غیره) و همچنین شمارنده‌های عملکرد ویندوز. شمارنده‌های عملکرد، در واقع در رجیستری نیستند، اما می‌توان از طریق توابع رجیستری به آن‌ها دسترسی پیدا کرد (هرچند API جدیدتری برای دسترسی به شمارنده‌های عملکرد وجود دارد).اگرچه بسیاری از کاربران و مدیران ویندوز هرگز نیاز به نگاه مستقیم به رجیستری ندارند (زیرا می‌توانید اکثر تنظیمات پیکربندی را با ابزارهای مدیریتی استاندارد مشاهده یا تغییر دهید)، اما رجیستری همچنان منبع مفیدی از اطلاعات داخلی ویندوز است زیرا حاوی بسیاری از تنظیماتی است که بر عملکرد و رفتار سیستم تأثیر می‌گذارند.یونیکدویندوز از بسیاری از سیستم‌عامل‌های دیگر متمایز است، زیرا بیشتر رشته‌های داخلی متن به صورت کاراکترهای یونیکد با عرض 16 بیت ذخیره می‌شوند و پردازش می‌شوند (از نظر فنی UTF-16LE؛ هرگاه در این کتاب از یونیکد یاد می‌شود، به UTF-16LE اشاره می‌شود مگر خلاف آن بیان شود). یونیکد یک استاندارد مجموعه کاراکتری بین‌المللی است که ارزش‌های منحصربه‌فرد برای اکثر مجموعه‌های کاراکتری جهان را تعریف می‌کند و پشتیبانی از رمزگذاری‌های 8، 16 و حتی 32 بیتی برای هر کاراکتر را فراهم می‌کند.از آنجا که بسیاری از برنامه‌ها با رشته‌های کاراکتری 8 بیتی (ANSI) سروکار دارند، بسیاری از توابع ویندوز که آرگومان‌های رشته‌ای می‌پذیرند دارای دو نقطه ورودی هستند: نسخه یونیکد (پهناور، 16 بیتی) و نسخه ANSI (باریک، 8 بیتی). اگر شما نسخه باریک یک تابع ویندوز را صدا بزنید، با کمی افت کارایی مواجه می‌شوید زیرا ورودی‌های رشته‌ای به‌صورت یونیکد قبل از پردازش توسط سیستم و خروجی‌ها قبل از بازگرداندن به برنامه، به یونیکد تبدیل می‌شوند. بنابراین، اگر سرویسی قدیمی یا قطعه‌ای از کدی دارید که می‌خواهید روی ویندوز اجرا شود اما این کد با استفاده از رشته‌های کاراکتری ANSI نوشته شده است، ویندوز کاراکترهای ANSI را برای استفاده خود به یونیکد تبدیل می‌کند. با این حال، ویندوز هرگز داده‌های داخل فایل‌ها را به یونیکد تبدیل نمی‌کند — این به عهدهٔ برنامه است تا تصمیم بگیرد آیا داده را به‌صورت یونیکد یا ANSI ذخیره کند.صرف‌نظر از زبان برنامه، همه نسخه‌های ویندوز دارای همان توابع هستند. به جای داشتن نسخه‌های جداگانه برای هر زبان، ویندوز دارای یک فایل اجرایی جهانی واحد است تا یک نصب واحد از چند زبان مختلف پشتیبانی کند (از طریق افزودن بسته‌های زبان مختلف). برنامه‌ها همچنین می‌توانند از توابع ویندوز بهره ببرند که امکان استفاده از binaries جهانی واحد برای چند زبان را فراهم می‌کند.سیستم‌های قدیمی ویندوز 9x به طور بومی از یونیکد پشتیبانی نمی‌کردند. این موضوع یکی دیگر از دلایل ایجاد دو تابع برای ANSI و یونیکد بود. برای مثال، تابع API ویندوز CreateFile در واقع تابعی نیست؛ بلکه یک ماکرو است که به یکی از دو تابع تبدیل می‌شود: CreateFileA (ANSI) یا CreateFileW (Unicode، که در آن W نشان‌دهنده wide است). این گسترش بر اساس یک ثابت کامپلایشن به نام UNICODE انجام می‌شود. این چیز به‌طور پیش‌فرض در پروژه‌های Visual Studio C++ تعریف شده است چون کار با توابع یونیکد مفیدتر است. با این حال، نام صریح تابع را می‌توان به جای ماکرو مربوطه استفاده کرد.کیت درایور ویندوز (WDK)کیت درایور ویندوز (WDK) همچنین از طریق برنامه اشتراک MSDN در دسترس است. درست مانند SDK ویندوز، می‌توان آن را به‌صورت رایگان دانلود کرد. مستندات WDK در کتابخانه MSDN گنجانده شده‌اند.اگرچه WDK با هدف توسعه‌دهندگان درایورهای دستگاه طراحی شده است، اما منبعی فراوان از اطلاعات داخلی ویندوز محسوب می‌شود. برای مثال، اگرچه فصل ششم معماری سیستم I/O، مدل درایور و ساختارهای داده پایه درایور دستگاه را توضیح می‌دهد، اما توصیف دقیقی از توابع پشتیبانی هسته‌ای به صورت جزئی ارائه نمی‌دهد. مستندسازی WDK توصیف جامع از تمام توابع پشتیبانی هسته ویندوز و مکانیسم‌های مورد استفاده توسط درایورهای دستگاه را به صورت آموزشی و مرجع ارائه می‌کند.علاوه بر گنجاندن مستندات، WDK حاوی فایل‌های هدر (به‌ویژه ntddk.h، ntifs.h و wdm.h) است که ساختارهای داخلی کلیدی داده‌ها و ثابت‌های مهم را تعریف می‌کند و همچنین رابط‌هایی به بسیاری از روال‌های داخلی سیستم را فراهم می‌نماید. این فایل‌ها هنگام کاوش در داده‌های داخلی ویندوز با دیباگر هسته مفید هستند، زیرا اگرچه طرح‌بندی کلی و محتوای این ساختارها در این کتاب نشان داده شده است، توضیحات دقیق سطح زمینه (مثلاً اندازه و انواع داده‌ها) ارائه نشده است. تعدادی از این ساختارهای داده — مانند سرصفحه‌های شی Dispatcher اشیاء، بلوک‌های انتظار، رویدادها، موتنت‌ها، سمفورها و غیره — از طریق WDK به‌خوبی توضیح داده شده‌اند.اگر می‌خواهید فراتر از آنچه در این کتاب ارائه شده است به درک سیستم I/O و مدل درایور وارد شوید، مستندات WDK را مطالعه کنید — به‌ویژه Kernel-Mode Driver Architecture Design Guide و Kernel-Mode Driver Reference manuals. همچنین ممکن است استفاده از کتاب‌های مفید دیگری مانند Programming the Microsoft Windows Driver Model، نسخهٔ دوم توسط والتر انی (Microsoft Press, 2002) و Developing Drivers with the Windows Driver Foundation توسط پنی اوریک و گای اسمیت (Microsoft Press, 2007) نیز برای شما سودمند باشد.ابزارهای Sysinternalsبسیاری از آزمایش‌های این کتاب از ابزارهای رایگان Sysinternals استفاده می‌کنند که می‌توانید از طریق وب‌سایت Sysinternals دانلود کنید. مارک روسینویچ، هم‌نگار این کتاب، بیشترین بخش این ابزارها را نوشته است. مشهورترین ابزارها شامل Process Explorer و Process Monitor هستند. توجه کنید که بسیاری از این ابزارها نصب و اجرای درایورهای دستگاه در سطح کرنل را در بر می‌گیرند و بنابراین به مجوز مدیرکل یا سطح elevated نیاز دارند — هرچند برخی از آن‌ها می‌توانند با عملکرد محدود و خروجی برای یک حساب کاربری استاندارد یا غیر elevated اجرا شوند.از آنجایی که ابزارهای Sysinternals به‌طور منظم به‌روزرسانی می‌شوند، مطمئن شوید که جدیدترین نسخه را دارید. برای دریافت اطلاع‌رسانی در مورد به‌روزرسانی ابزارها، می‌توانید وبلاگ Sysinternals Site Blog را دنبال کنید (که دارای فید RSS است). برای توضیحات مربوط به تمام ابزارها، نحوه استفاده از آن‌ها و مطالعات موردی مشکلاتی که حل می‌شوند، به کتاب Windows Sysinternals Administrator’s Reference نوشتهٔ مارک روسینویچ و آرانگ مارگوسیس (Microsoft Press، 2011) مراجعه کنید. برای سوالات و بحث‌های مربوط به ابزارها نیز از انجمن‌های Sysinternals استفاده کنید.Telegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Thu, 14 May 2026 21:24:50 +0330</pubDate>
            </item>
                    <item>
                <title>زبان اسمبلی در ویندوز(LEA)</title>
                <link>https://virgool.io/@m_14047363/%D8%B2%D8%A8%D8%A7%D9%86-%D8%A7%D8%B3%D9%85%D8%A8%D9%84%DB%8C-%D8%AF%D8%B1-%D9%88%DB%8C%D9%86%D8%AF%D9%88%D8%B2lea-mqldrnawhqzb</link>
                <description>LEA مقدار آدرس مؤثر (Effective Address) یک عملوند حافظه‌ای را محاسبه کرده و آن را به یک رجیستر منتقل می‌کند.برخلاف MOV که محتوای یک مکان حافظه را به یک رجیستر منتقل می‌کند، LEA خود آدرس آن مکان را منتقل می‌کند..386
.model flat,stdcall
.stack 4096

ExitProcess proto, dwExitCode:dword

.data
      myVariable dword 12345678h

.code
main proc

     lea eax, myVariable

    invoke ExitProcess, 0
main endp
end mainTelegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Thu, 14 May 2026 15:42:21 +0330</pubDate>
            </item>
                    <item>
                <title>زبان اسمبلی در ویندوز (آرایه ها)</title>
                <link>https://virgool.io/@m_14047363/%D8%B2%D8%A8%D8%A7%D9%86-%D8%A7%D8%B3%D9%85%D8%A8%D9%84%DB%8C-%D8%AF%D8%B1-%D9%88%DB%8C%D9%86%D8%AF%D9%88%D8%B2-%D8%A2%D8%B1%D8%A7%DB%8C%D9%87-%D9%87%D8%A7-deemcov6uvzu</link>
                <description>در این بخش در ویژوال استدیو کد اسمبلی مینویسیم و در X64DBG اون رو دیباگ میکنیم..386
.model flat,stdcall
.stack 4096

ExitProcess proto, dwExitCode:dword

.data
     myArray dword 10h, 20h, 30h, 40h, 50h

.code
main proc
    mov myArray[0 * SIZEOF DWORD], 100h
    
    mov myArray[1 * SIZEOF DWORD], 200h
    
    mov myArray[2 * SIZEOF DWORD], 300h

    mov myArray[3 * SIZEOF DWORD], 400h
    
    mov myArray[4 * SIZEOF DWORD], 500h


    invoke ExitProcess, 0
main endp
end mainTelegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Thu, 14 May 2026 15:21:47 +0330</pubDate>
            </item>
                    <item>
                <title>تاریخچه زبان اسمبلی</title>
                <link>https://virgool.io/@m_14047363/%D8%AA%D8%A7%D8%B1%DB%8C%D8%AE%DA%86%D9%87-%D8%B2%D8%A8%D8%A7%D9%86-%D8%A7%D8%B3%D9%85%D8%A8%D9%84%DB%8C-zvj61odslyff</link>
                <description>زبان اسمبلی (Assembly Language) یکی از زبان‌های برنامه‌نویسی سطح پایین است که به برنامه‌نویسان این امکان را می‌دهد که با سخت‌افزار نزدیک‌تر کار کنند. در ادامه به تاریخچه و ویژگی‌های مهم زبان اسمبلی می‌پردازیم.تاریخچه زبان اسمبلی:سال‌های 1940:اولین زبان‌های اسمبلی به دنبال نخستین کامپیوترها ایجاد شدند. کامپیوترهای اولیه مانند ENIAC و EDSAC از کدهای باینری برای برنامه‌نویسی استفاده می‌کردند، که این کار باعث دشواری در نوشتن و ویرایش کدها می‌شد.سال‌های 1950:با پیشرفت کامپیوترها و نیاز به برنامه‌نویسی آسان‌تر، زبان‌های اسمبلی به وجود آمدند. این زبان‌ها شامل نمادهای قابل خواندن توسط انسان بودند که به کد ماشین تبدیل می‌شدند. به عنوان مثال، IBM 701 اولین کامپیوتر بود که از زبان اسمبلی مخصوص خود استفاده می‌کرد.استفاده از ماکروها:در اواسط دهه 1950، مفهوم ماکروها به زبان‌های اسمبلی افزوده شد. ماکروها به برنامه‌نویسان اجازه می‌دادند تا توالی‌های کد را تعریف کرده و آن‌ها را به سادگی در برنامه‌های خود استفاده کنند.دهه 1960 تا 1970:زبان‌های اسمبلی به طور گسترده‌تری مورد استفاده قرار گرفتند و هر تولیدکننده سخت‌افزار معمولا زبان اسمبلی خاص خود را توسعه می‌داد. این زمان نقطه عطفی بود که زبان‌های سطح بالا مانند Fortran و COBOL به وجود آمدند، اما زبان اسمبلی همچنان برای برنامه‌نویسی سیستم و درایورهای سخت‌افزاری اهمیت داشت.کاهش استفاده در دهه‌های اخیر:با پیشرفت زبان‌های برنامه‌نویسی سطح بالا و همچنین توسعه کامپایلرها، استفاده از زبان اسمبلی کاهش یافت. با این حال، زبان اسمبلی هنوز برای برنامه‌نویسی در سطوح پایین، مانند سیستم‌عامل‌ها، میکروکنترلرها و توسعه درایورهای سخت‌افزاری مهم است.ویژگی‌های زبان اسمبلی:نزدیکی به سخت‌افزار: زبان اسمبلی به برنامه‌نویسان این امکان را می‌دهد که کنترل بیشتری بر سخت‌افزار داشته باشند.عملکرد بالا: کدهای نوشته شده در زبان اسمبلی معمولاً سریع‌تر از کدهای نوشته شده در زبان‌های سطح بالای دیگر اجرا می‌شوند.کم حجم: برنامه‌های نوشته شده در زبان اسمبلی به طور معمول حجم کمتری از برنامه‌های با زبان‌های سطح بالا دارند.نتیجه‌گیریزبان اسمبلی با تاریخچه‌ای غنی و اهمیت بالا در دنیای برنامه‌نویسی، هنوز در بسیاری از حوزه‌ها مورد استفاده قرار می‌گیرد. با وجود پیشرفت‌های چشمگیر در زبان‌های سطح بالا، درک زبان اسمبلی و توانایی برنامه‌نویسی آن به برنامه‌نویسان کمک می‌کند تا بهتر بتوانند با ساختارهای سخت‌افزاری کار کنند و در ایجاد نرم‌افزارهای کارآمدتر موفق‌تر باشند.Telegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Thu, 14 May 2026 10:10:20 +0330</pubDate>
            </item>
                    <item>
                <title>زبان اسمبلی در ویندوز (معرفی ابزار ها)</title>
                <link>https://virgool.io/@m_14047363/%D8%B2%D8%A8%D8%A7%D9%86-%D8%A7%D8%B3%D9%85%D8%A8%D9%84%DB%8C-%D8%AF%D8%B1-%D9%88%DB%8C%D9%86%D8%AF%D9%88%D8%B2-%D9%85%D8%B9%D8%B1%D9%81%DB%8C-%D8%A7%D8%A8%D8%B2%D8%A7%D8%B1-%D9%87%D8%A7-papckcthde5b</link>
                <description>زبان اسمبلی یک زبان سطح پایین و پر قدرت میباشد. در این آموزش ما آماده سازی ویژوال استدیو رو برای نوشتن اسمبلی 32 bit انجام میدهیم و برای دیباگ کردن اون کد از ابزار قدرتمند x64DBG استفاده میکنیم.بریم کار رو شروع کنیم. ما در اینجا از ویژوال استدیو 2022 استفاده میکنیم. برای ستاپ کردن آن باید مانند تصاویر زیر عمل کنید.نمونه کد اسمبلی برای تست:.386
.model flat,stdcall
.stack 4096

ExitProcess proto,dwExitCode:dword

.data

sum DWORD ?

.code
main proc
	mov eax,7
	add eax,4
	mov sum,eax
	invoke ExitProcess,0
main endp
end mainدر قسمت های بعدی بیشتر به مبانی کامپیوتر و زبان اسمبلی و استفاده از x64dbg میپردازیم.Telegram: @CaKeeganBale: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Tue, 12 May 2026 19:26:03 +0330</pubDate>
            </item>
                    <item>
                <title>Services in windows</title>
                <link>https://virgool.io/@m_14047363/services-in-windows-da4crnfzv559</link>
                <description>سرویس‌ها در ویندوز برنامه‌هایی هستند که در پس‌زمینه اجرا می‌شوند و به طور معمول بدون تعامل مستقیم کاربر عمل می‌کنند. این برنامه‌ها معمولاً برای انجام کارهای خاص و مداوم طراحی شده‌اند، مانند ارائه خدمات شبکه، نظارت بر سیستم، یا پردازش داده‌ها.ویژگی‌های اصلی سرویس‌ها در ویندوز:اجرای پس‌زمینه: سرویس‌ها به گونه‌ای طراحی شده‌اند که بدون نیاز به کاربران اجرا شوند. این یعنی که آن‌ها می‌توانند در پشت صحنه و حتی در زمان راه‌اندازی سیستم (قبل از ورود کاربران) فعال شوند.مدیریت سیستم: بسیاری از سرویس‌ها به مدیریت منابع سیستم، مانند حافظه، پردازنده و شبکه کمک می‌کنند. به عنوان مثال، سرویس‌هایی مانند &quot;Windows Update&quot; به طور منظم به‌روزرسانی‌های امنیتی و نرم‌افزاری را برای سیستم نصب می‌کنند.شروع به کار خودکار: سرویس‌ها می‌توانند به صورت خودکار با شروع ویندوز فعال شوند. این می‌تواند شامل تنظیماتی باشد که سرویس به صورت دستی، خودکار یا غیرفعال تنظیم شود.عدم وابستگی به حساب کاربر: سرویس‌ها به حساب کاربری نیاز ندارند و می‌توانند تحت یک حساب مخصوص به نام &quot;Local System&quot; اجرا شوند که دسترسی‌های وسیعی به منابع سیستم را فراهم می‌کند.کنترل و مدیریت از طریق ابزارهای خاص: مدیریت سرویس‌ها از طریق ابزارهایی مانند &quot;Services.msc&quot; در ویندوز انجام می‌شود. در این محیط، کاربران می‌توانند سرویس‌ها را مشاهده، راه‌اندازی، متوقف یا تنظیم کنند.سرویس‌ها بخش مهمی از سیستم عامل ویندوز هستند و به مدیریت و عملکرد پایدار سیستم کمک می‌کنند. فهمیدن نحوه کار سرویس‌ها می‌تواند در عیب‌یابی مشکلات و بهینه‌سازی عملکرد سیستم مفید باشد.سرویس‌ها بخش مهمی از سیستم عامل ویندوز هستند و به مدیریت و عملکرد پایدار سیستم کمک می‌کنند. فهمیدن نحوه کار سرویس‌ها می‌تواند در عیب‌یابی مشکلات و بهینه‌سازی عملکرد سیستم مفید باشد.توضیح کد:SERVICE_STATUS_HANDLE g_ServiceStatus = NULL;این خط یک متغیر سراسری به نام g_ServiceStatus از نوع SERVICE_STATUS_HANDLE تعریف می‌کند و آن را با NULL مقداردهی اولیه می‌کند.SERVICE_STATUS_HANDLE: یک دستگیره (handle) است که سیستم‌عامل به سرویس شما اختصاص می‌دهد. این دستگیره برای ارتباط با مدیر کنترل سرویس (Service Control Manager - SCM) استفاده می‌شود، مثلاً برای گزارش وضعیت سرویس.SERVICE_STATUS g_ServiceStatusInfo = { 0 };این خط یک متغیر سراسری به نام g_ServiceStatusInfo از نوع SERVICE_STATUS تعریف می‌کند و تمام اعضای آن را با صفر مقداردهی اولیه می‌کند.SERVICE_STATUS: یک ساختار است که حاوی اطلاعات مربوط به وضعیت فعلی یک سرویس است (مانند نوع سرویس، وضعیت فعلی، کدهای خطا و غیره).VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv);این خط یک نمونه اولیه (prototype) برای تابع ServiceMain اعلام می‌کند.VOID: نشان می‌دهد که تابع هیچ مقداری را برنمی‌گرداند.WINAPI: یک قرارداد فراخوانی (calling convention) است که توسط مایکروسافت برای توابع API ویندوز استفاده می‌شود.ServiceMain: این تابع نقطه ورود اصلی (main entry point) برای سرویس شماست. وقتی مدیر کنترل سرویس، سرویس شما را شروع می‌کند، این تابع را فراخوانی می‌کند.DWORD argc: تعداد آرگومان‌های خط فرمان که به سرویس شما ارسال شده‌اند.LPTSTR* argv: آرایه‌ای از رشته‌ها (آرگومان‌های خط فرمان) که به سرویس شما ارسال شده‌اند. LPTSTR نیز یک نوع کاراکتر عمومی است.VOID WINAPI ServiceHandler(DWORD control);این خط یک نمونه اولیه برای تابع ServiceHandler اعلام می‌کند.ServiceHandler: این تابع یک کنترل‌کننده (handler) برای رویدادهای کنترلی است که توسط مدیر کنترل سرویس به سرویس شما ارسال می‌شود (مثلاً دستور توقف، مکث، ادامه و غیره).DWORD control: کدی که نوع رویداد کنترلی را مشخص می‌کند.int main()این تابع، نقطه ورود اصلی برنامه اجرایی (EXE) شماست. این تابع مسئول ثبت سرویس با مدیر کنترل سرویس است.SERVICE_TABLE_ENTRY ServiceTable[] = { ... };این خط یک آرایه از ساختارهای SERVICE_TABLE_ENTRY تعریف می‌کند.SERVICE_TABLE_ENTRY: ساختاری است که نام سرویس و اشاره‌گر به تابع ServiceMain مربوط به آن سرویس را نگهداری می‌کند.{ (LPWSTR)L&quot;MyService&quot;, (LPSERVICE_MAIN_FUNCTION)ServiceMain }: اولین ورودی در جدول سرویس.(LPWSTR)L&quot;MyService&quot;: نام سرویس شماست. L نشان‌دهنده یک رشته پهن (wide string) است و LPWSTR یک اشاره‌گر به یک رشته پهن است.(LPSERVICE_MAIN_FUNCTION)ServiceMain: اشاره‌گری به تابع ServiceMain که نقطه ورود سرویس &quot;MyService&quot; است.{ NULL, NULL }: این ورودی به عنوان نشانگر پایان جدول سرویس عمل می‌کند.if (StartServiceCtrlDispatcher(ServiceTable) == FALSE)این خط تابع StartServiceCtrlDispatcher را فراخوانی می‌کند.StartServiceCtrlDispatcher: این تابع برنامه را به عنوان یک فرآیند سرویس در مدیر کنترل سرویس ثبت می‌کند. این تابع منتظر می‌ماند تا مدیر کنترل سرویس یک سرویس را در این فرآیند شروع کند و سپس تابع ServiceMain مربوط به آن سرویس را فراخوانی می‌کند.اگر این تابع FALSE برگرداند، به این معنی است که عملیات ناموفق بوده است (معمولاً به این معنی است که برنامه به عنوان یک سرویس شروع نشده است، بلکه به صورت یک برنامه معمولی اجرا شده است).{ return GetLastError(); }اگر StartServiceCtrlDispatcher ناموفق باشد، این بلوک اجرا می‌شود و کد خطای مربوطه را با استفاده از GetLastError() برمی‌گرداند.return 0;اگر StartServiceCtrlDispatcher با موفقیت برگردد، این خط 0 را برمی‌گرداند که نشان‌دهنده اجرای موفقیت‌آمیز برنامه است.VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv)این تابع نقطه ورود اصلی سرویس شماست که توسط StartServiceCtrlDispatcher فراخوانی می‌شود، زمانی که مدیر کنترل سرویس تصمیم به شروع &quot;MyService&quot; می‌گیرد.g_ServiceStatusInfo.dwServiceType = SERVICE_WIN32_OWN_PROCESS;این خط نوع سرویس را مشخص می‌کند.SERVICE_WIN32_OWN_PROCESS: نشان می‌دهد که سرویس در فرآیند خود اجرا می‌شود (یعنی یک فرآیند جداگانه برای این سرویس ایجاد می‌شود).g_ServiceStatusInfo.dwCurrentState = SERVICE_START_PENDING;این خط وضعیت فعلی سرویس را به SERVICE_START_PENDING (در حال شروع) تنظیم می‌کند. این به مدیر کنترل سرویس اطلاع می‌دهد که سرویس در حال آماده‌سازی برای شروع است.g_ServiceStatusInfo.dwControlsAccepted = SERVICE_ACCEPT_STOP;این خط مشخص می‌کند که سرویس چه کنترل‌هایی را می‌پذیرد.SERVICE_ACCEPT_STOP: به مدیر کنترل سرویس اطلاع می‌دهد که این سرویس دستور توقف را می‌پذیرد.g_ServiceStatus = RegisterServiceCtrlHandler(_T(&quot;MyService&quot;), ServiceHandler);این خط تابع کنترل‌کننده سرویس (ServiceHandler) را با مدیر کنترل سرویس ثبت می‌کند.RegisterServiceCtrlHandler: این تابع به مدیر کنترل سرویس اطلاع می‌دهد که تابع ServiceHandler مسئول رسیدگی به دستورات کنترلی برای &quot;MyService&quot; است._T(&quot;MyService&quot;): نام سرویس (با استفاده از _T برای پشتیبانی از کاراکترهای عمومی).ServiceHandler: اشاره‌گری به تابع کنترل‌کننده.این تابع یک SERVICE_STATUS_HANDLE را برمی‌گرداند که در g_ServiceStatus ذخیره می‌شود.if (g_ServiceStatus == NULL)اگر ثبت کنترل‌کننده سرویس ناموفق باشد، g_ServiceStatus برابر با NULL خواهد بود.{ return; }اگر ثبت ناموفق باشد، تابع ServiceMain به سادگی برمی‌گردد.g_ServiceStatusInfo.dwCurrentState = SERVICE_RUNNING;این خط وضعیت سرویس را به SERVICE_RUNNING (در حال اجرا) تغییر می‌دهد. این به مدیر کنترل سرویس اطلاع می‌دهد که سرویس با موفقیت شروع شده است.SetServiceStatus(g_ServiceStatus, &amp;g_ServiceStatusInfo);این تابع وضعیت فعلی سرویس را به مدیر کنترل سرویس گزارش می‌دهد.g_ServiceStatus: دستگیره سرویس که قبلاً با RegisterServiceCtrlHandler به دست آمده است.&amp;g_ServiceStatusInfo: اشاره‌گری به ساختار SERVICE_STATUS که حاوی اطلاعات وضعیت جدید است.while (g_ServiceStatusInfo.dwCurrentState == SERVICE_RUNNING)این یک حلقه اصلی است که تا زمانی که وضعیت سرویس SERVICE_RUNNING باشد، اجرا می‌شود. این حلقه جایی است که کار اصلی سرویس شما انجام می‌شود.این کد نمونه به زبان c++ هست:#include &lt;windows.h&gt;
#include &lt;tchar.h&gt;

SERVICE_STATUS_HANDLE g_ServiceStatus = NULL;
SERVICE_STATUS g_ServiceStatusInfo = { 0 };

VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv);
VOID WINAPI ServiceHandler(DWORD control);

int main()
{
    SERVICE_TABLE_ENTRY ServiceTable[] =
    {
        { (LPWSTR)L&quot;MyService&quot;, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
        { NULL, NULL }
    };

    if (StartServiceCtrlDispatcher(ServiceTable) == FALSE)
    {
        return GetLastError();
    }
    return 0;
}

VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
{
    g_ServiceStatusInfo.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    g_ServiceStatusInfo.dwCurrentState = SERVICE_START_PENDING;
    g_ServiceStatusInfo.dwControlsAccepted = SERVICE_ACCEPT_STOP;

    g_ServiceStatus = RegisterServiceCtrlHandler(_T(&quot;MyService&quot;), ServiceHandler);
    if (g_ServiceStatus == NULL)
    {
        return;
    }

    g_ServiceStatusInfo.dwCurrentState = SERVICE_RUNNING;
    SetServiceStatus(g_ServiceStatus, &amp;g_ServiceStatusInfo);

    // سرویس شما در اینجا شروع می‌شود
    while (g_ServiceStatusInfo.dwCurrentState == SERVICE_RUNNING)
    {
        // کد سرویس
        Sleep(1000); // مثلاً یک توقف برای جلوگیری از استفاده زیاد از CPU
    }

    g_ServiceStatusInfo.dwCurrentState = SERVICE_STOPPED;
    SetServiceStatus(g_ServiceStatus, &amp;g_ServiceStatusInfo);
}

VOID WINAPI ServiceHandler(DWORD control)
{
    switch (control)
    {
    case SERVICE_CONTROL_STOP:
        g_ServiceStatusInfo.dwCurrentState = SERVICE_STOP_PENDING;
        SetServiceStatus(g_ServiceStatus, &amp;g_ServiceStatusInfo);
        g_ServiceStatusInfo.dwCurrentState = SERVICE_STOPPED;
        SetServiceStatus(g_ServiceStatus, &amp;g_ServiceStatusInfo);
        break;
    default:
        break;
    }
}این کد را درون ویژوال استدیو کامپایل کنید.برای نصب سرویس ویندوز، شما نیاز به استفاده از خط فرمان (Command Prompt) با دسترسی ادمین دارید. مراحل زیر را دنبال کنید:باز کردن Command Prompt با دسترسی ادمین:کلید Windows را فشار دهید و &quot;cmd&quot; را جستجو کنید.روی &quot;Command Prompt&quot; راست کلیک کرده و گزینه &quot;Run as administrator&quot; را انتخاب کنید.استفاده از دستور sc create:دستور زیر را وارد کنید (پوشه را با مسیر واقعی فایل exe خود که ساخته‌اید جایگزین کنید):sc create MyService binPath= &quot;C:\Users\MyWindows\source\repos\YourService\Release\YourService.exe&quot;توجه: دقت داشته باشید که پس از binPath= حتماً یک فاصله وجود داشته باشد.برای شروع سرویس، از دستور زیر استفاده کنید:sc start MyServiceاگر بخواهید سرویس را متوقف کنید، می‌توانید دستور زیر را وارد کنید:sc stop MyServiceاگر بخواهید سرویس را از سیستم حذف کنید، از دستور زیر استفاده کنید:sc delete MyServiceTelegram: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Fri, 08 May 2026 14:53:56 +0330</pubDate>
            </item>
                    <item>
                <title>لیست پیوندی در زبان C</title>
                <link>https://virgool.io/@m_14047363/%D9%84%DB%8C%D8%B3%D8%AA-%D9%BE%DB%8C%D9%88%D9%86%D8%AF%DB%8C-%D8%AF%D8%B1-%D8%B2%D8%A8%D8%A7%D9%86-c-fkhixpxtrdqk</link>
                <description>یک پیاده‌سازی ساده از یک لیست پیوندی (Linked List) در زبان C است.در این بخش، یک ساختار به نام Node تعریف شده است که شامل دو فیلد است:data: یک عدد صحیح که مقدار ذخیره شده در گره را نشان می‌دهد.next: یک اشاره‌گر به گره بعدی در لیست، که به نوع ساختار Node اشاره دارد.// تعریف یک ساختار (struct) برای گره‌های لیست پیوندی
struct Node
{
    int data;              // مقداری که در گره ذخیره می‌شود
    struct Node* next;     // اشاره‌گری به گره بعدی در لیست
};شروع تابعی به نام insertAtEnd که برای اضافه کردن یک گره جدید به انتهای لیست استفاده می‌شود. این تابع دو پارامتر دارد:head_ref: اشاره‌گر به اشاره‌گر به سر لیست (برای امکان تغییر سر لیست اگر لیست خالی باشد).new_data: داده‌ای که باید در گره جدید ذخیره شود.// تابعی برای اضافه کردن یک گره جدید در انتهای لیست
void insertAtEnd(struct Node** head_ref, int new_data)در این خط یک گره جدید در حافظه با استفاده از تابع malloc ایجاد می‌شود و نوع آن به Node تبدیل می‌شود. این گره هنوز هیچ مقداری ندارد.    // ایجاد یک گره جدید در حافظه
    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));یک اشاره‌گر کمکی به نام last ساخته می‌شود که در ابتدا به سر لیست اشاره می‌کند و برای پیمایش لیست استفاده خواهد شد.    // اشاره‌گر کمکی برای پیمایش لیست
    struct Node* last = *head_ref; /* استفاده در مرحله یافتن آخر لیست */فیلد data گره جدید با مقدار new_data مقداردهی می‌شود و فیلد next به NULL تنظیم می‌شود چون این گره قرار است آخرین گره لیست باشد.    // مقداردهی فیلدهای گره جدید
    new_node-&gt;data = new_data;
    new_node-&gt;next = NULL;   // چون قرار است در انتها قرار بگیرد، next خالی استاگر سر لیست خالی باشد (یعنی لیست خالی است)، گره جدید تبدیل به نخستین گره لیست می‌شود و تابع خاتمه می‌یابد.    // اگر لیست خالی باشد، گره جدید نخستین گره می‌شود
    if (*head_ref == NULL) {
        *head_ref = new_node;
        return;
    }اگر لیست خالی نباشد، درون یک حلقه while پیمایش لیست انجام می‌شود تا به آخرین گره برسیم. تا زمانی که گره بعدی خالی نباشد، به گره بعدی منتقل می‌شویم.    // پیمایش لیست تا رسیدن به آخرین گره
    while (last-&gt;next != NULL)
    {
        last = last-&gt;next;   // رفتن به گره بعدی
    }در نهایت، گره جدید به انتهای لیست متصل می‌شود و تابع خاتمه می‌یابد.    // اتصال گره جدید به انتهای لیست
    last-&gt;next = new_node;
    return;این تابع به نام printList برای چاپ عناصر لیست پیوندی است.با استفاده از یک حلقه while تا زمانی که به انتهای لیست نرسیده‌ایم، مقادیر هر گره را چاپ می‌کند و به گره بعدی منتقل می‌شود.// تابعی برای چاپ عناصر لیست پیوندی
void printList(struct Node* node)
{
    // تا زمانی که به انتهای لیست نرسیده‌ایم
    while (node != NULL) 
    {
        cout &lt;&lt; node-&gt;data &lt;&lt; &quot; &quot;; // چاپ مقدار گره
        node = node-&gt;next;         // رفتن به گره بعدی
    }
}در تابع main، یک لیست خالی ایجاد می‌شود که سر آن NULL است.سپس یک مقدار (۱) به انتهای لیست اضافه می‌شود و در نهایت کل لیست چاپ می‌شود.این کد به طور کلی مثال ساده‌ای از استفاده از لیست پیوندی برای ذخیره و نمایش داده‌ها در زبان C است.void main()
{
    // ایجاد یک لیست خالی (head خالی است)
    struct Node* head = NULL;

    // افزودن یک مقدار به انتهای لیست
    insertAtEnd(&amp;head, 1);

    // چاپ کل لیست
    printList(head);
}کد به زبان C++ در یک نگاه:#include &lt;iostream&gt;
using namespace std;


// تعریف یک ساختار (struct) برای گره‌های لیست پیوندی
struct Node
{
    int data;              // مقداری که در گره ذخیره می‌شود
    struct Node* next;     // اشاره‌گری به گره بعدی در لیست
};

// تابعی برای اضافه کردن یک گره جدید در انتهای لیست
void insertAtEnd(struct Node** head_ref, int new_data) {

    // ایجاد یک گره جدید در حافظه
    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));

    // اشاره‌گر کمکی برای پیمایش لیست
    struct Node* last = *head_ref; /* استفاده در مرحله یافتن آخر لیست */

    // مقداردهی فیلدهای گره جدید
    new_node-&gt;data = new_data;
    new_node-&gt;next = NULL;   // چون قرار است در انتها قرار بگیرد، next خالی است

    // اگر لیست خالی باشد، گره جدید نخستین گره می‌شود
    if (*head_ref == NULL) {
        *head_ref = new_node;
        return;
    }

    // در غیر این صورت، پیمایش لیست تا رسیدن به آخرین گره
    while (last-&gt;next != NULL)
    {
        last = last-&gt;next;   // رفتن به گره بعدی
    }

    // اتصال گره جدید به انتهای لیست
    last-&gt;next = new_node;
    return;
}

// تابعی برای چاپ عناصر لیست پیوندی
void printList(struct Node* node)
{
    // تا زمانی که به انتهای لیست نرسیده‌ایم
    while (node != NULL) 
    {
        cout &lt;&lt; node-&gt;data &lt;&lt; &quot; &quot;; // چاپ مقدار گره
        node = node-&gt;next;         // رفتن به گره بعدی
    }
}

void main()
{
    // ایجاد یک لیست خالی (head خالی است)
    struct Node* head = NULL;

    // افزودن یک مقدار به انتهای لیست
    insertAtEnd(&amp;head, 1);

    // چاپ کل لیست
    printList(head);
}Telegram: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Thu, 07 May 2026 10:50:12 +0330</pubDate>
            </item>
                    <item>
                <title>SQLite در سیشارپ در رایدر</title>
                <link>https://virgool.io/@m_14047363/sqlite-%D8%AF%D8%B1-%D8%B3%DB%8C%D8%B4%D8%A7%D8%B1%D9%BE-%D8%AF%D8%B1-%D8%B1%D8%A7%DB%8C%D8%AF%D8%B1-rcfcx5h4qfeb</link>
                <description>برای راه اندازی sqlite در سیشارپ و در رایدر. ابتدا پکیج های زیر رو نصب میکنیمMicrosoft.EntityFrameworkCore.Sqlite
Microsoft.EntityFrameworkCore.Tools
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCoreبعد از نصب پکیج ها باید csproj شما به گونه زیر باشد:بعد در صفحه اصلی پروژه کد زیر رو جای گذاری میکنیم:using Microsoft.EntityFrameworkCore;

using var db = new DbContext(
    new DbContextOptionsBuilder()
        .UseSqlite(&quot;Data Source=MyDatabase.db&quot;)
        .Options
);

db.Database.EnsureCreated();//در این خط کد میاد برسی میکنه اگر دیتابیس ساخته نشده باشه اون رو میسازه.در داخل پوشه پروژه یک دیتابیس با نام MyDatabase.db ایجاد میشود.Telegram: @CaKeeganGmail : amidgm2020@gmail.com</description>
                <category>سید عمید قائم مقامی</category>
                <author>سید عمید قائم مقامی</author>
                <pubDate>Thu, 05 Feb 2026 14:33:11 +0330</pubDate>
            </item>
            </channel>
</rss>