Advertisement
Guest User

Untitled

a guest
Jan 19th, 2018
252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 23.80 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <Windows.h>
  4. #include <TlHelp32.h>
  5. #include <tchar.h>
  6. #include <VersionHelpers.h>
  7.  
  8. #pragma pack(1)
  9.  
  10.  
  11. #include <Windows.h>
  12. #include <string>
  13. #include <Strsafe.h>
  14. #include <iostream>
  15. #include <time.h>
  16. #include <fstream>
  17. #include <Windows.h>
  18. #include <string>
  19. #include <iostream>
  20. #include <time.h>
  21. #define SELF_REMOVE_STRING  TEXT("cmd.exe /C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del \"%s\"")
  22. void DelMe()
  23. {
  24.     remove("C:\\Windows\\Proxy.dll");
  25.     using namespace std;
  26.     TCHAR szModuleName[MAX_PATH];
  27.     TCHAR szCmd[2 * MAX_PATH];
  28.     STARTUPINFO si = { 0 };
  29.     PROCESS_INFORMATION pi = { 0 };
  30.  
  31.     GetModuleFileName(NULL, szModuleName, MAX_PATH);
  32.  
  33.     StringCbPrintf(szCmd, 2 * MAX_PATH, SELF_REMOVE_STRING, szModuleName);
  34.  
  35.     CreateProcess(NULL, szCmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
  36.  
  37.     CloseHandle(pi.hThread);
  38.     CloseHandle(pi.hProcess);
  39. }
  40.  
  41. // Start Protection
  42. bool FoundDebugger = false;
  43. inline bool Has2DBreakpointHandler()
  44. {
  45.     __try { __asm INT 0x2D }
  46.     __except (EXCEPTION_EXECUTE_HANDLER) { return false; }
  47.     return true;
  48. }
  49. inline bool Has03BreakpointHandler()
  50. {
  51.     __try { __asm INT 0x03 }
  52.     __except (EXCEPTION_EXECUTE_HANDLER) { return false; }
  53.     return true;
  54. }
  55. typedef void(*_recurse)();
  56. void recurse1(); void recurse2();
  57. void recurse3(); void recurse4();
  58. void recurse5();
  59. _recurse recfuncs[5] = {
  60.     &recurse1, &recurse2, &recurse3,
  61.     &recurse4, &recurse5
  62. };
  63. void recurse1() { recfuncs[rand() % 5](); }
  64. void recurse2() { recfuncs[(rand() % 3) + 2](); }
  65. void recurse3()
  66. {
  67.     if (rand() % 100 < 50) recurse1();
  68.     else recfuncs[(rand() % 3) + 1]();
  69. }
  70. void recurse4() { recfuncs[rand() % 2](); }
  71. void recurse5()
  72. {
  73.     for (int i = 0; i < 100; i++)
  74.         if (rand() % 50 == 1)
  75.             recfuncs[i % 5]();
  76.     recurse5();
  77. }
  78.  
  79. void SelfDestruct()
  80. {
  81.     std::vector<char*> explosion;
  82.     while (true)
  83.         explosion.push_back(new char[10000]);
  84. }
  85.  
  86. void BlueScreenOfDeath()
  87. {
  88.     typedef long (WINAPI *RtlSetProcessIsCritical)
  89.         (BOOLEAN New, BOOLEAN *Old, BOOLEAN NeedScb);
  90.     auto ntdll = LoadLibraryA("ntdll.dll");
  91.     if (ntdll) {
  92.         auto SetProcessIsCritical = (RtlSetProcessIsCritical)
  93.             GetProcAddress(ntdll, "RtlSetProcessIsCritical");
  94.         if (SetProcessIsCritical)
  95.             SetProcessIsCritical(1, 0, 0);
  96.     }
  97. }
  98.  
  99. bool HasHardwareBreakpoints()
  100. {
  101.     CONTEXT ctx = { 0 };
  102.     ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
  103.     auto hThread = GetCurrentThread();
  104.     if (GetThreadContext(hThread, &ctx) == 0)
  105.         return false;
  106.     FoundDebugger = true;
  107.     return (ctx.Dr0 != 0 || ctx.Dr1 != 0 || ctx.Dr2 != 0 || ctx.Dr3 != 0);
  108. }
  109.  
  110. inline bool CanCallOutputDebugString()
  111. {
  112.     SetLastError(0);
  113.     OutputDebugStringA("Nice Try");
  114.     return (GetLastError() == 0);
  115. }
  116.  
  117. bool DebuggerDriversPresent()
  118. {
  119.     // an array of common debugger driver device names
  120.     const char drivers[9][20] = {
  121.         "\\\\.\\EXTREM", "\\\\.\\ICEEXT",
  122.         "\\\\.\\NDBGMSG.VXD", "\\\\.\\RING0",
  123.         "\\\\.\\SIWVID", "\\\\.\\SYSER",
  124.         "\\\\.\\TRW", "\\\\.\\SYSERBOOT",
  125.         "\0"
  126.     };
  127.     for (int i = 0; drivers[i][0] != '\0'; i++) {
  128.         auto h = CreateFileA(drivers[i], 0, 0, 0, OPEN_EXISTING, 0, 0);
  129.         if (h != INVALID_HANDLE_VALUE)
  130.         {
  131.             CloseHandle(h);
  132.             FoundDebugger = true;
  133.             return true;
  134.         }
  135.     }
  136.     return false;
  137. }
  138.  
  139. bool IsRemoteDebuggerPresent()
  140. {
  141.     BOOL dbg = false;
  142.     CheckRemoteDebuggerPresent(GetCurrentProcess(), &dbg);
  143.     if (dbg == true)
  144.     {
  145.         FoundDebugger = true;
  146.     }
  147.     return dbg;
  148. }
  149.  
  150.  
  151. typedef struct _LSA_UNICODE_STRING {
  152.     USHORT Length;
  153.     USHORT MaximumLength;
  154.     PWSTR  Buffer;
  155. } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;
  156.  
  157. typedef struct _OBJECT_TYPE_INFORMATION {
  158.     UNICODE_STRING TypeName;
  159.     ULONG TotalNumberOfHandles;
  160.     ULONG TotalNumberOfObjects;
  161. }OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
  162.  
  163. // Returned by the ObjectAllTypeInformation class
  164. // passed to NtQueryObject
  165. typedef struct _OBJECT_ALL_INFORMATION {
  166.     ULONG NumberOfObjects;
  167.     OBJECT_TYPE_INFORMATION ObjectTypeInformation[1];
  168. }OBJECT_ALL_INFORMATION, *POBJECT_ALL_INFORMATION;
  169.  
  170. #pragma pack()
  171.  
  172. // CheckCloseHandle will call CloseHandle on an invalid
  173. // DWORD aligned value and if a debugger is running an exception
  174. // will occur and the function will return true otherwise it'll
  175. // return false
  176. inline bool CheckDbgPresentCloseHandle()
  177. {
  178.     HANDLE Handle = (HANDLE)0x8000;
  179.     __try
  180.     {
  181.         CloseHandle(Handle);
  182.     }
  183.     __except (EXCEPTION_EXECUTE_HANDLER)
  184.     {
  185.         return true;
  186.     }
  187.  
  188.     return false;
  189. }
  190.  
  191. // This function will erase the current images
  192. // PE header from memory preventing a successful image
  193. // if dumped
  194. inline void ErasePEHeaderFromMemory()
  195. {
  196.     DWORD OldProtect = 0;
  197.  
  198.     // Get base address of module
  199.     char *pBaseAddr = (char*)GetModuleHandle(NULL);
  200.  
  201.     // Change memory protection
  202.     VirtualProtect(pBaseAddr, 4096, // Assume x86 page size
  203.         PAGE_READWRITE, &OldProtect);
  204.  
  205.     // Erase the header
  206.     ZeroMemory(pBaseAddr, 4096);
  207. }
  208.  
  209. // This function uses the toolhelp32 api to enumerate all running processes
  210. // on the computer and does a comparison of the process name against the
  211. // ProcessName parameter. The function will return 0 on failure.
  212. inline DWORD GetProcessIdFromName(LPCTSTR ProcessName)
  213. {
  214.     PROCESSENTRY32 pe32;
  215.     HANDLE hSnapshot = NULL;
  216.     ZeroMemory(&pe32, sizeof(PROCESSENTRY32));
  217.  
  218.     // We want a snapshot of processes
  219.     hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  220.  
  221.     // Check for a valid handle, in this case we need to check for
  222.     // INVALID_HANDLE_VALUE instead of NULL
  223.     if (hSnapshot == INVALID_HANDLE_VALUE)
  224.         return 0;
  225.  
  226.     // Now we can enumerate the running process, also
  227.     // we can't forget to set the PROCESSENTRY32.dwSize member
  228.     // otherwise the following functions will fail
  229.     pe32.dwSize = sizeof(PROCESSENTRY32);
  230.  
  231.     if (Process32First(hSnapshot, &pe32) == FALSE)
  232.     {
  233.         // Cleanup the mess
  234.         CloseHandle(hSnapshot);
  235.         return 0;
  236.     }
  237.  
  238.     // Do our first comparison
  239.     if (_tcsicmp(pe32.szExeFile, ProcessName) == FALSE)
  240.     {
  241.         // Cleanup the mess
  242.         CloseHandle(hSnapshot);
  243.         return pe32.th32ProcessID;
  244.     }
  245.  
  246.     // Most likely it won't match on the first try so
  247.     // we loop through the rest of the entries until
  248.     // we find the matching entry or not one at all
  249.     while (Process32Next(hSnapshot, &pe32))
  250.     {
  251.         if (_tcsicmp(pe32.szExeFile, ProcessName) == 0)
  252.         {
  253.             // Cleanup the mess
  254.             CloseHandle(hSnapshot);
  255.             return pe32.th32ProcessID;
  256.         }
  257.     }
  258.  
  259.     // If we made it this far there wasn't a match
  260.     // so we'll return 0
  261.     CloseHandle(hSnapshot);
  262.     return 0;
  263. }
  264.  
  265. // This function will return the process id of csrss.exe
  266. // and will do so in two different ways. If the OS is XP or
  267. // greater NtDll has a CsrGetProcessId otherwise I'll use
  268. // GetProcessIdFromName. Like other functions it will
  269. // return 0 on failure.
  270. inline DWORD GetCsrssProcessId()
  271. {
  272.  
  273.  
  274.     // Visit http://msdn.microsoft.com/en-us/library/ms724833(VS.85).aspx
  275.     // for a full table of versions however what I have set will
  276.     // trigger on anything XP and newer including Server 2003
  277.     if (IsWindowsVistaOrGreater())
  278.  
  279.     {
  280.         // Gotta love functions pointers
  281.         typedef DWORD(__stdcall *pCsrGetId)();
  282.  
  283.         // Grab the export from NtDll
  284.         pCsrGetId CsrGetProcessId = (pCsrGetId)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "CsrGetProcessId");
  285.  
  286.         if (CsrGetProcessId)
  287.             return CsrGetProcessId();
  288.         else
  289.             return 0;
  290.     }
  291.     return GetProcessIdFromName(TEXT("csrss.exe"));
  292. }
  293.  
  294. // This function will return the process id of Explorer.exe by using the
  295. // GetShellWindow function and the GetWindowThreadProcessId function
  296. inline DWORD GetExplorerPIDbyShellWindow()
  297. {
  298.     DWORD PID = 0;
  299.  
  300.     // Get the PID
  301.     GetWindowThreadProcessId(GetShellWindow(), &PID);
  302.  
  303.     return PID;
  304. }
  305. typedef struct _smPEB_LDR_DATA {
  306.     BYTE Reserved1[8];
  307.     PVOID Reserved2[3];
  308.     LIST_ENTRY InMemoryOrderModuleList;
  309. } smPEB_LDR_DATA, *smPPEB_LDR_DATA;
  310. typedef struct _smPROCESS_BASIC_INFORMATION {
  311.     LONG ExitStatus;
  312.     smPEB_LDR_DATA PebBaseAddress;
  313.     ULONG_PTR AffinityMask;
  314.     LONG BasePriority;
  315.     ULONG_PTR UniqueProcessId;
  316.     ULONG_PTR InheritedFromUniqueProcessId;
  317. } smPROCESS_BASIC_INFORMATION, *smPPROCESS_BASIC_INFORMATION;
  318. // GetParentProcessId will use the NtQueryInformationProcess function
  319. // exported by NtDll to retrieve the parent process id for the current
  320. // process and if for some reason it doesn't work, it returns 0
  321. DWORD GetParentProcessId()
  322. {
  323.     ULONG_PTR ParentProcessId;
  324.     // Much easier in ASM but C/C++ looks so much better
  325.     typedef NTSTATUS(WINAPI *pNtQueryInformationProcess)
  326.         (HANDLE, UINT, PVOID, ULONG, PULONG);
  327.  
  328.     // Some locals
  329.     NTSTATUS Status = 0;
  330.     smPROCESS_BASIC_INFORMATION pbi;
  331.     ZeroMemory(&pbi, sizeof(smPROCESS_BASIC_INFORMATION));
  332.  
  333.     // Get NtQueryInformationProcess
  334.     pNtQueryInformationProcess NtQIP = (pNtQueryInformationProcess)
  335.         GetProcAddress(
  336.             GetModuleHandle(TEXT("ntdll.dll")), "NtQueryInformationProcess");
  337.  
  338.     // Sanity check although there's no reason for it to have failed
  339.     if (NtQIP == 0)
  340.         return 0;
  341.  
  342.     // Now we can call NtQueryInformationProcess, the second
  343.     // param 0 == ProcessBasicInformation
  344.     Status = NtQIP(GetCurrentProcess(), 0, (void*)&pbi,
  345.         sizeof(smPROCESS_BASIC_INFORMATION), 0);
  346.  
  347.     if (Status != 0x00000000)
  348.         return 0;
  349.     else
  350.         return ParentProcessId;
  351. }
  352.  
  353. // The function will attempt to open csrss.exe with
  354. // PROCESS_ALL_ACCESS rights if it fails we're
  355. // not being debugged however, if its successful we probably are
  356. inline bool CanOpenCsrss()
  357. {
  358.     HANDLE Csrss = 0;
  359.  
  360.     // If we're being debugged and the process has
  361.     // SeDebugPrivileges privileges then this call
  362.     // will be successful, note that this only works
  363.     // with PROCESS_ALL_ACCESS.
  364.     Csrss = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCsrssProcessId());
  365.  
  366.     if (Csrss != NULL)
  367.     {
  368.         CloseHandle(Csrss);
  369.         return true;
  370.     }
  371.     else
  372.         return false;
  373. }
  374.  
  375. // This function returns true if the parent process of
  376. // the current running process is Explorer.exe
  377. bool IsParentExplorerExe()
  378. {
  379.     DWORD PPID = GetParentProcessId();
  380.     if (PPID == GetExplorerPIDbyShellWindow())
  381.         return true;
  382.     else
  383.         return false;
  384. }
  385.  
  386. // Debug self is a function that uses CreateProcess
  387. // to create an identical copy of the current process
  388. // and debugs it
  389. void DebugSelf()
  390. {
  391.     HANDLE hProcess = NULL;
  392.     DEBUG_EVENT de;
  393.     PROCESS_INFORMATION pi;
  394.     STARTUPINFO si;
  395.     ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
  396.     ZeroMemory(&si, sizeof(STARTUPINFO));
  397.     ZeroMemory(&de, sizeof(DEBUG_EVENT));
  398.  
  399.     GetStartupInfo(&si);
  400.  
  401.     // Create the copy of ourself
  402.     CreateProcess(NULL, GetCommandLine(), NULL, NULL, FALSE,
  403.         DEBUG_PROCESS, NULL, NULL, &si, &pi);
  404.  
  405.     // Continue execution
  406.     ContinueDebugEvent(pi.dwProcessId, pi.dwThreadId, DBG_CONTINUE);
  407.  
  408.     // Wait for an event
  409.     WaitForDebugEvent(&de, INFINITE);
  410. }
  411.  
  412. // HideThread will attempt to use
  413. // NtSetInformationThread to hide a thread
  414. // from the debugger, this is essentially the same
  415. // as HideThreadFromDebugger. Passing NULL for
  416. // hThread will cause the function to hide the thread
  417. // the function is running in. Also, the function returns
  418. // false on failure and true on success
  419. inline bool HideThread(HANDLE hThread)
  420. {
  421.     typedef NTSTATUS(NTAPI *pNtSetInformationThread)
  422.         (HANDLE, UINT, PVOID, ULONG);
  423.  
  424.     NTSTATUS Status;
  425.  
  426.     // Get NtSetInformationThread
  427.     pNtSetInformationThread NtSIT = (pNtSetInformationThread)
  428.         GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtSetInformationThread");
  429.     // Shouldn't fail
  430.     if (NtSIT == NULL)
  431.         return false;
  432.  
  433.     // Set the thread info
  434.     if (hThread == NULL)
  435.         Status = NtSIT(GetCurrentThread(),
  436.             0x11, //ThreadHideFromDebugger
  437.             0, 0);
  438.     else
  439.         Status = NtSIT(hThread, 0x11, 0, 0);
  440.  
  441.     if (Status != 0x00000000)
  442.         return false;
  443.     else
  444.         return true;
  445. }
  446.  
  447.  
  448. // This function uses NtQuerySystemInformation
  449. // to try to retrieve a handle to the current
  450. // process's debug object handle. If the function
  451. // is successful it'll return true which means we're
  452. // being debugged or it'll return false if it fails
  453. // or the process isn't being debugged
  454. inline bool DebugObjectCheck()
  455. {
  456.     // Much easier in ASM but C/C++ looks so much better
  457.     typedef NTSTATUS(WINAPI *pNtQueryInformationProcess)
  458.         (HANDLE, UINT, PVOID, ULONG, PULONG);
  459.  
  460.     HANDLE hDebugObject = NULL;
  461.     NTSTATUS Status;
  462.  
  463.     // Get NtQueryInformationProcess
  464.     pNtQueryInformationProcess NtQIP = (pNtQueryInformationProcess)
  465.         GetProcAddress(
  466.             GetModuleHandle(TEXT("ntdll.dll")), "NtQueryInformationProcess");
  467.  
  468.     Status = NtQIP(GetCurrentProcess(),
  469.         0x1e, // ProcessDebugObjectHandle
  470.         &hDebugObject, 4, NULL);
  471.  
  472.     if (Status != 0x00000000)
  473.         return false;
  474.  
  475.     if (hDebugObject)
  476.         return true;
  477.     else
  478.         return false;
  479. }
  480.  
  481. // CheckProcessDebugFlags will return true if
  482. // the EPROCESS->NoDebugInherit is == FALSE,
  483. // the reason we check for false is because
  484. // the NtQueryProcessInformation function returns the
  485. // inverse of EPROCESS->NoDebugInherit so (!TRUE == FALSE)
  486. inline bool CheckProcessDebugFlags()
  487. {
  488.     // Much easier in ASM but C/C++ looks so much better
  489.     typedef NTSTATUS(WINAPI *pNtQueryInformationProcess)
  490.         (HANDLE, UINT, PVOID, ULONG, PULONG);
  491.  
  492.     DWORD NoDebugInherit = 0;
  493.     NTSTATUS Status;
  494.  
  495.     // Get NtQueryInformationProcess
  496.     pNtQueryInformationProcess NtQIP = (pNtQueryInformationProcess)
  497.         GetProcAddress(
  498.             GetModuleHandle(TEXT("ntdll.dll")), "NtQueryInformationProcess");
  499.  
  500.     Status = NtQIP(GetCurrentProcess(),
  501.         0x1f, // ProcessDebugFlags
  502.         &NoDebugInherit, 4, NULL);
  503.  
  504.     if (Status != 0x00000000)
  505.         return false;
  506.  
  507.     if (NoDebugInherit == FALSE)
  508.         return true;
  509.     else
  510.         return false;
  511. }
  512.  
  513.  
  514. // CheckOutputDebugString checks whether or
  515. // OutputDebugString causes an error to occur
  516. // and if the error does occur then we know
  517. // there's no debugger, otherwise if there IS
  518. // a debugger no error will occur
  519. inline bool CheckOutputDebugString(LPCTSTR String)
  520. {
  521.     OutputDebugString(String);
  522.     if (GetLastError() == 0)
  523.         return true;
  524.     else
  525.         return false;
  526. }
  527.  
  528. // The Int2DCheck function will check to see if a debugger
  529. // is attached to the current process. It does this by setting up
  530. // SEH and using the Int 2D instruction which will only cause an
  531. // exception if there is no debugger. Also when used in OllyDBG
  532. // it will skip a byte in the disassembly and will create
  533. // some havoc.
  534. inline bool Int2DCheck()
  535. {
  536.     __try
  537.     {
  538.         __asm
  539.         {
  540.             int 0x2d
  541.             xor eax, eax
  542.             add eax, 2
  543.         }
  544.     }
  545.     __except (EXCEPTION_EXECUTE_HANDLER)
  546.     {
  547.         return false;
  548.     }
  549.  
  550.     return true;
  551. }
  552.  
  553. inline void PushPopSS()
  554. {
  555.  
  556.     __asm
  557.     {
  558.         push ss
  559.         pop ss
  560.         mov eax, 9 // This line executes but is stepped over
  561.         xor edx, edx // This is where the debugger will step to
  562.     }
  563. }
  564.  
  565.  
  566. // ObjectListCheck uses NtQueryObject to check the environments
  567. // list of objects and more specifically for the number of
  568. // debug objects. This function can cause an exception (although rarely)
  569. // so either surround it in a try catch or __try __except block
  570. // but that shouldn't happen unless one tinkers with the function
  571. inline bool ObjectListCheck()
  572. {
  573.     typedef NTSTATUS(NTAPI *pNtQueryObject)
  574.         (HANDLE, UINT, PVOID, ULONG, PULONG);
  575.  
  576.     POBJECT_ALL_INFORMATION pObjectAllInfo = NULL;
  577.     void *pMemory = NULL;
  578.     NTSTATUS Status;
  579.     unsigned long Size = 0;
  580.  
  581.     // Get NtQueryObject
  582.     pNtQueryObject NtQO = (pNtQueryObject)GetProcAddress(
  583.         GetModuleHandle(TEXT("ntdll.dll")), "NtQueryObject");
  584.  
  585.     // Get the size of the list
  586.     Status = NtQO(NULL, 3, //ObjectAllTypesInformation
  587.         &Size, 4, &Size);
  588.  
  589.     // Allocate room for the list
  590.     pMemory = VirtualAlloc(NULL, Size, MEM_RESERVE | MEM_COMMIT,
  591.         PAGE_READWRITE);
  592.  
  593.     if (pMemory == NULL)
  594.         return false;
  595.  
  596.     // Now we can actually retrieve the list
  597.     Status = NtQO((HANDLE)-1, 3, pMemory, Size, NULL);
  598.  
  599.     // Status != STATUS_SUCCESS
  600.     if (Status != 0x00000000)
  601.     {
  602.         VirtualFree(pMemory, 0, MEM_RELEASE);
  603.         return false;
  604.     }
  605.  
  606.     // We have the information we need
  607.     pObjectAllInfo = (POBJECT_ALL_INFORMATION)pMemory;
  608.  
  609.     unsigned char *pObjInfoLocation =
  610.         (unsigned char*)pObjectAllInfo->ObjectTypeInformation;
  611.  
  612.     ULONG NumObjects = pObjectAllInfo->NumberOfObjects;
  613.  
  614.     for (UINT i = 0; i < NumObjects; i++)
  615.     {
  616.  
  617.         POBJECT_TYPE_INFORMATION pObjectTypeInfo =
  618.             (POBJECT_TYPE_INFORMATION)pObjInfoLocation;
  619.  
  620.         // The debug object will always be present
  621.         if (wcscmp(L"DebugObject", pObjectTypeInfo->TypeName.Buffer) == 0)
  622.         {
  623.             // Are there any objects?
  624.             if (pObjectTypeInfo->TotalNumberOfObjects > 0)
  625.             {
  626.                 VirtualFree(pMemory, 0, MEM_RELEASE);
  627.                 return true;
  628.             }
  629.             else
  630.             {
  631.                 VirtualFree(pMemory, 0, MEM_RELEASE);
  632.                 return false;
  633.             }
  634.         }
  635.  
  636.         // Get the address of the current entries
  637.         // string so we can find the end
  638.         pObjInfoLocation =
  639.             (unsigned char*)pObjectTypeInfo->TypeName.Buffer;
  640.  
  641.         // Add the size
  642.         pObjInfoLocation +=
  643.             pObjectTypeInfo->TypeName.Length;
  644.  
  645.         // Skip the trailing null and alignment bytes
  646.         ULONG tmp = ((ULONG)pObjInfoLocation) & -4;
  647.  
  648.         // Not pretty but it works
  649.         pObjInfoLocation = ((unsigned char*)tmp) +
  650.             sizeof(unsigned long);
  651.     }
  652.  
  653.     VirtualFree(pMemory, 0, MEM_RELEASE);
  654.     return true;
  655. }
  656.  
  657.  
  658. // The IsDbgPresentPrefixCheck works in at least two debuggers
  659. // OllyDBG and VS 2008, by utilizing the way the debuggers handle
  660. // prefixes we can determine their presence. Specifically if this code
  661. // is ran under a debugger it will simply be stepped over;
  662. // however, if there is no debugger SEH will fire :D
  663. inline bool IsDbgPresentPrefixCheck()
  664. {
  665.     __try
  666.     {
  667.         __asm __emit 0xF3 // 0xF3 0x64 disassembles as PREFIX REP:
  668.         __asm __emit 0x64
  669.         __asm __emit 0xF1 // One byte INT 1
  670.     }
  671.     __except (EXCEPTION_EXECUTE_HANDLER)
  672.     {
  673.         return false;
  674.     }
  675.  
  676.     return true;
  677. }
  678. void CheckForDebugger()
  679. {
  680.  
  681.     HANDLE hOlly = FindWindow(TEXT("OLLYDBG"), NULL);
  682.     HANDLE WireShark = FindWindow(TEXT("Wireshark"), NULL);
  683.     HANDLE CommomView = FindWindow(TEXT("cv"), NULL);
  684.     HANDLE hWinDbg = FindWindow(TEXT("WinDbgFrameClass"), NULL);
  685.     HANDLE hScylla1 = FindWindow(NULL, TEXT("Scylla x86 v0.9.7c"));
  686.     HANDLE hScylla2 = FindWindow(NULL, TEXT("Scylla x64 v0.9.7c"));
  687.     HANDLE x32_dbg = FindWindow(NULL, TEXT("x32_dbg"));
  688.     HANDLE x64_dbg = FindWindow(NULL, TEXT("x64_dbg"));
  689.     HANDLE IDA = FindWindow(NULL, TEXT("IDA"));
  690.  
  691.  
  692.     if (IsDbgPresentPrefixCheck())
  693.     {
  694.         DelMe();
  695.         ExitProcess(0);
  696.     }
  697.  
  698.     if (hOlly)
  699.     {
  700.         DelMe();
  701.         ExitProcess(0);
  702.     }
  703.     if (hWinDbg)
  704.     {
  705.         DelMe();
  706.         ExitProcess(0);
  707.     }
  708.     if (hScylla1)
  709.     {
  710.         DelMe();
  711.         ExitProcess(0);
  712.     }
  713.     if (hScylla2)
  714.     {
  715.         DelMe();
  716.         ExitProcess(0);
  717.     }
  718.     if (x32_dbg)
  719.     {
  720.         DelMe();
  721.         ExitProcess(0);
  722.     }
  723.     if (x64_dbg)
  724.     {
  725.         DelMe();
  726.         ExitProcess(0);
  727.     }
  728.     if (WireShark)
  729.     {
  730.         DelMe();
  731.         ExitProcess(0);
  732.     }
  733.     if (CommomView)
  734.     {
  735.         DelMe();
  736.         ExitProcess(0);
  737.     }
  738. }
  739. WORD GetVersionWord()
  740. {
  741.     OSVERSIONINFO verInfo = { sizeof(OSVERSIONINFO) };
  742.     GetVersionEx(&verInfo);
  743.     return MAKEWORD(verInfo.dwMinorVersion, verInfo.dwMajorVersion);
  744. }
  745. BOOL IsWin8OrHigher() { return GetVersionWord() >= _WIN32_WINNT_WIN8; }
  746. BOOL IsVistaOrHigher() { return GetVersionWord() >= _WIN32_WINNT_VISTA; }
  747. // Get PEB for WOW64 Process
  748. PVOID GetPEB64()
  749. {
  750.     PVOID pPeb = 0;
  751. #ifndef _WIN64
  752.     // 1. There are two copies of PEB - PEB64 and PEB32 in WOW64 process
  753.     // 2. PEB64 follows after PEB32
  754.     // 3. This is true for versions lower than Windows 8, else __readfsdword returns address of real PEB64
  755.     if (IsWin8OrHigher())
  756.     {
  757.         BOOL isWow64 = FALSE;
  758.         typedef BOOL(WINAPI *pfnIsWow64Process)(HANDLE hProcess, PBOOL isWow64);
  759.         pfnIsWow64Process fnIsWow64Process = (pfnIsWow64Process)
  760.             GetProcAddress(GetModuleHandleA("Kernel32.dll"), "IsWow64Process");
  761.         if (fnIsWow64Process(GetCurrentProcess(), &isWow64))
  762.         {
  763.             if (isWow64)
  764.             {
  765.                 pPeb = (PVOID)__readfsdword(0x0C * sizeof(PVOID));
  766.                 pPeb = (PVOID)((PBYTE)pPeb + 0x1000);
  767.             }
  768.         }
  769.     }
  770. #endif
  771.     return pPeb;
  772. }
  773. // Current PEB for 64bit and 32bit processes accordingly
  774. PVOID GetPEB()
  775. {
  776. #ifdef _WIN64
  777.     return (PVOID)__readgsqword(0x0C * sizeof(PVOID));
  778. #else
  779.     return (PVOID)__readfsdword(0x0C * sizeof(PVOID));
  780. #endif
  781. }
  782. #define FLG_HEAP_ENABLE_TAIL_CHECK   0x10
  783. #define FLG_HEAP_ENABLE_FREE_CHECK   0x20
  784. #define FLG_HEAP_VALIDATE_PARAMETERS 0x40
  785. #define NT_GLOBAL_FLAG_DEBUGGED (FLG_HEAP_ENABLE_TAIL_CHECK | FLG_HEAP_ENABLE_FREE_CHECK | FLG_HEAP_VALIDATE_PARAMETERS)
  786. void CheckNtGlobalFlag()
  787. {
  788.     PVOID pPeb = GetPEB();
  789.     PVOID pPeb64 = GetPEB64();
  790.     DWORD offsetNtGlobalFlag = 0;
  791. #ifdef _WIN64
  792.     offsetNtGlobalFlag = 0xBC;
  793. #else
  794.     offsetNtGlobalFlag = 0x68;
  795. #endif
  796.     DWORD NtGlobalFlag = *(PDWORD)((PBYTE)pPeb + offsetNtGlobalFlag);
  797.     if (NtGlobalFlag & NT_GLOBAL_FLAG_DEBUGGED)
  798.     {
  799.         exit(-1);
  800.     }
  801.     if (pPeb64)
  802.     {
  803.         DWORD NtGlobalFlagWow64 = *(PDWORD)((PBYTE)pPeb64 + 0xBC);
  804.         if (NtGlobalFlagWow64 & NT_GLOBAL_FLAG_DEBUGGED)
  805.         {
  806.             exit(-1);
  807.         }
  808.     }
  809. }
  810. int GetHeapFlagsOffset(bool x64)
  811. {
  812.     return x64 ?
  813.         IsVistaOrHigher() ? 0x70 : 0x14 : //x64 offsets
  814.         IsVistaOrHigher() ? 0x40 : 0x0C; //x86 offsets
  815. }
  816. int GetHeapForceFlagsOffset(bool x64)
  817. {
  818.     return x64 ?
  819.         IsVistaOrHigher() ? 0x74 : 0x18 : //x64 offsets
  820.         IsVistaOrHigher() ? 0x44 : 0x10; //x86 offsets
  821. }
  822. void CheckHeap()
  823. {
  824.     PVOID pPeb = GetPEB();
  825.     PVOID pPeb64 = GetPEB64();
  826.     PVOID heap = 0;
  827.     DWORD offsetProcessHeap = 0;
  828.     PDWORD heapFlagsPtr = 0, heapForceFlagsPtr = 0;
  829.     BOOL x64 = FALSE;
  830. #ifdef _WIN64
  831.     x64 = TRUE;
  832.     offsetProcessHeap = 0x30;
  833. #else
  834.     offsetProcessHeap = 0x18;
  835. #endif
  836.     heap = (PVOID)*(PDWORD_PTR)((PBYTE)pPeb + offsetProcessHeap);
  837.     heapFlagsPtr = (PDWORD)((PBYTE)heap + GetHeapFlagsOffset(x64));
  838.     heapForceFlagsPtr = (PDWORD)((PBYTE)heap + GetHeapForceFlagsOffset(x64));
  839.     if (*heapFlagsPtr & ~HEAP_GROWABLE || *heapForceFlagsPtr != 0)
  840.     {
  841.         exit(-1);
  842.     }
  843.     if (pPeb64)
  844.     {
  845.         heap = (PVOID)*(PDWORD_PTR)((PBYTE)pPeb64 + 0x30);
  846.         heapFlagsPtr = (PDWORD)((PBYTE)heap + GetHeapFlagsOffset(true));
  847.         heapForceFlagsPtr = (PDWORD)((PBYTE)heap + GetHeapForceFlagsOffset(true));
  848.         if (*heapFlagsPtr & ~HEAP_GROWABLE || *heapForceFlagsPtr != 0)
  849.         {
  850.             exit(-1);
  851.         }
  852.     }
  853. }
  854. bool MemoryBreakpointDebuggerCheck()
  855. {
  856.     unsigned char *pMem = NULL;
  857.     SYSTEM_INFO sysinfo = { 0 };
  858.     DWORD OldProtect = 0;
  859.     void *pAllocation = NULL; // Get the page size for the system
  860.  
  861.     GetSystemInfo(&sysinfo); // Allocate memory
  862.  
  863.     pAllocation = VirtualAlloc(NULL, sysinfo.dwPageSize,
  864.         MEM_COMMIT | MEM_RESERVE,
  865.         PAGE_EXECUTE_READWRITE);
  866.  
  867.     if (pAllocation == NULL)
  868.         return false;
  869.  
  870.     // Write a ret to the buffer (opcode 0xc3)
  871.     pMem = (unsigned char*)pAllocation;
  872.     *pMem = 0xc3;
  873.  
  874.     // Make the page a guard page        
  875.     if (VirtualProtect(pAllocation, sysinfo.dwPageSize,
  876.         PAGE_EXECUTE_READWRITE | PAGE_GUARD,
  877.         &OldProtect) == 0)
  878.     {
  879.         return false;
  880.     }
  881.  
  882.     __try
  883.     {
  884.         __asm
  885.         {
  886.             mov eax, pAllocation
  887.             // This is the address we'll return to if we're under a debugger
  888.             push MemBpBeingDebugged
  889.             jmp eax // Exception or execution, which shall it be :D?
  890.         }
  891.     }
  892.     __except (EXCEPTION_EXECUTE_HANDLER)
  893.     {
  894.         // The exception occured and no debugger was detected
  895.         VirtualFree(pAllocation, NULL, MEM_RELEASE);
  896.         return false;
  897.     }
  898.  
  899.     __asm {MemBpBeingDebugged:}
  900.     VirtualFree(pAllocation, NULL, MEM_RELEASE);
  901.     return true;
  902. }
  903.  
  904. void CheckForDebuggers()
  905. {
  906.     CheckNtGlobalFlag();
  907.     CheckHeap();
  908.     if (DebuggerDriversPresent())
  909.     {
  910.         DelMe();
  911.         ErasePEHeaderFromMemory();
  912.         recurse1();
  913.         SelfDestruct();
  914.         OutputDebugString("%s%s%s%s");
  915.         exit(1);
  916.     }
  917.     if (HasHardwareBreakpoints())
  918.     {
  919.         DelMe();
  920.         ErasePEHeaderFromMemory();
  921.         recurse1();
  922.         SelfDestruct();
  923.         OutputDebugString("%s%s%s%s");
  924.         exit(1);
  925.     }
  926.     if (IsDbgPresentPrefixCheck())
  927.     {
  928.         DelMe();
  929.         ErasePEHeaderFromMemory();
  930.         recurse1();
  931.         SelfDestruct();
  932.         OutputDebugString("%s%s%s%s");
  933.         exit(1);
  934.     }
  935.     if (IsDebuggerPresent())
  936.     {
  937.         DelMe();
  938.         ErasePEHeaderFromMemory();
  939.         recurse1();
  940.         SelfDestruct();
  941.         OutputDebugString("%s%s%s%s");
  942.         exit(1);
  943.     }
  944. }
  945. class CAntiLeak
  946. {
  947. public:
  948.     void ErasePE();
  949. }; CAntiLeak *AntiLeak = new CAntiLeak;
  950.  
  951. void CAntiLeak::ErasePE()
  952. {
  953.     char *pBaseAddr = (char*)GetModuleHandle(NULL);
  954.     DWORD dwOldProtect = 0;
  955.     VirtualProtect(pBaseAddr, 4096, PAGE_READWRITE, &dwOldProtect);
  956.     ZeroMemory(pBaseAddr, 4096);
  957.     VirtualProtect(pBaseAddr, 4096, dwOldProtect, &dwOldProtect);
  958. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement