Advertisement
GK-Chubbz

Francesco Bypass Source

Apr 26th, 2015
695
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 30.99 KB | None | 0 0
  1. #include <windows.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6.  
  7. #include "win32_gui.h"
  8. #include "win32_console.h"
  9.  
  10. /* I'm using /W4 just to be sure I don't make any silent mistakes, so I'm gonna disable non-standard extension warnings */
  11. #pragma warning(disable: 152 221 204)
  12.  
  13. #include "hackdesu/io.h"
  14. #include "hackdesu/process.h"
  15. #include "hackdesu/command_queue.h"
  16. #include "hackdesu/hack.h"
  17. #include "hackdesu/memory.h"
  18. #if _DEBUG
  19. #pragma comment(lib, "hackdesu/debug.lib")
  20. #else
  21. #pragma comment(lib, "hackdesu/release.lib")
  22. #endif
  23.  
  24. #include <Shlwapi.h>
  25. #pragma comment(lib, "Shlwapi.lib")
  26.  
  27. #define BYPASS_NAME "Ghetto Bypass"
  28. #define BYPASS_VERSION_NUMBER "1.3"
  29. #ifdef HSONLY
  30. #define BYPASS_VERSION BYPASS_VERSION_NUMBER " (HS only)"
  31. #else
  32. #define BYPASS_VERSION BYPASS_VERSION_NUMBER
  33. #endif
  34.  
  35. #define DUMPINFO_FILE    "dupe.dumpinfo"
  36. #define BLACKCIPHER_EXE "BlackCipher.aes"
  37.  
  38. #if _DEBUG
  39. #define dbgle printf(__FUNCDNAME__ ": "); win32_show_error
  40. #else
  41. #define dbgle
  42. #endif
  43.  
  44. HMODULE bypass_dll = NULL;
  45. BOOL is_wow64 = TRUE;
  46. static uint32_t hs_memory, hs_memory_start, hs_memory_end;
  47. static uint32_t hscrc1_ret, hscrc2_ret, hscrc3_ret, hscrc4_ret;
  48.  
  49. #define EHSVC(offset)            (hs_memory_start + offset)
  50.  
  51. #define HSCRC1_OFF                0x9B252                                /* hscrc1: 8A 11 33 C2 8B */
  52. #define HSCRC1                    EHSVC(HSCRC1_OFF)
  53. #define HSCRC2_OFF                0x37C217                            /* hscrc2: set BP @hscrc1 */
  54. #define HSCRC2                    EHSVC(HSCRC2_OFF)
  55. #define HSCRC3                    EHSVC(0x26B6B7)                        /* hscrc3: set BP @hscrc1 */
  56. #define HSCRC4                    EHSVC(0x408F7)                        /* hscrc4: set BP @0x00510000 */
  57. #define HSCRC5_TABLE            EHSVC(0x164048)                        /* hscrc5: set BP @hscrc1 Press F9 until code change then go up */
  58. #define HSCRC5_TABLE_XOR_KEY    *(uint32_t *)(HSCRC5_TABLE + 0x20)
  59. #define EHSVC_EMPTY_MEM            EHSVC(0x500)                        /* some empty memory region in ehsvc.dll that we will use to store copies of the funcs checked by hscrc5 */
  60. #define EHSVC_EMPTY_MEM_SIZE    0x500
  61.  
  62. #define HS_PROCESS_SCANNER        EHSVC(0x56BF0)                        /* process scanner: 81 EC ? ? ? ? A0 ? ? ? ? 53 55 56 8B E9 */
  63. #define HS_MODULE_SCANNER        EHSVC(0x5D8B0)                        /* module scanner: 8B 41 ? 56 8B 35 ? ? ? ? 85 C0 */
  64. #define HS_HWBP_DETECTION1        EHSVC(0x11280)                        /* HWBP detection (main): 55 8B EC 81 EC ? ? ? ? 56 57 B9 */
  65. #define HS_HWBP_DETECTION2        EHSVC(0xF870)                        /* HWBP detection 2: 81 EC ? ? ? ? 53 8B 9C 24 ? ? ? ? 85 */
  66. #define HS_HWBP_DETECTION3        EHSVC(0xFA60)                        /* HWBP detection 3: 81 EC ? ? ? ? 56 57 B9 ? ? ? ? 33 C0 8D 7C 24 ? F3 AB */
  67. #define HS_HWBP_DETECTION4        EHSVC(0x101F0)                        /* HWBP detection 4: 55 8B EC 6A FF 68 ? ? ? ? 68 ? ? ? ? 64 A1 ? ? ? ? 50 64 89 25 ? ? ? ? 81 EC ? ? ? ? 53 56 57 89 65 E8 BE ? ? ? ? 89 75 */
  68. #define HS_SWBP_DETECTION        EHSVC(0x779A0)                        /* SWBP detection: 55 8B EC 6A FF 68 ? ? ? ? 68 ? ? ? ? 64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 EC ? 53 56 57 89 ? ? 8B ? ? 8B FA */
  69. #define HS_MEMORY_PROTECTION    EHSVC(0xDA5CA)                        /* memory protection: E8 ? ? ? ? 83 C4 ? 89 45 ? 3B C3 75 ? FF 75 ? 8D */
  70.  
  71. static uint32_t self_memory, self_memory_start, self_memory_end;
  72. #ifndef HSONLY
  73. static uint32_t mscrc1_ret, mscrc2_ret;
  74. #define MSCRC1    0x02051FC4                                            /* mscrc1: bp CRC2 | register = opcode */
  75. #define MSCRC2    0x0216D081                                            /* mscrc2: bp 00500000 | register = opcode */
  76.  
  77. /*
  78.     trace back callers of 55 8B EC 51 89 4D FC 8B 45 FC C7 00 ? ? ? ? 8B 4D FC 8B 55 08 89 51 04
  79.     (scroll to the beginning) 83 ?? ?? ?? 74 ?? 8B ?? ?? 83 ?? ?? 89 ?? ?? EB ?? C7 ?? ?? 00 00 00 00 8B ?? ?? ?? 8D ?? ?? E8 ?? ?? ?? ?? C7 ?? ?? 00 00 00 00 C7
  80.     callers are VMed
  81. */
  82. #define BC_HASH_DETECTION1 0x0043B800 /* 0003A81B in the CEM */
  83. #define BC_HASH_DETECTION2 0x0043B8F0 /* 0003A90B in the CEM */
  84. #endif
  85.  
  86. static void _declspec(naked) hscrc_hook_1() {
  87.     _asm {
  88.         cmp ecx, [hs_memory_start]
  89.         jb nobypass
  90.         cmp ecx, [hs_memory_end]
  91.         ja nobypass
  92.         sub ecx, [hs_memory_start]
  93.         add ecx, [hs_memory]
  94.  
  95.     nobypass:
  96.         jmp [hscrc1_ret]
  97.     }
  98. }
  99.  
  100. static void _declspec(naked) hscrc_hook_2() {
  101.     _asm {
  102.         cmp ebx, [hs_memory_start]
  103.         jb nobypass
  104.         cmp ebx, [hs_memory_end]
  105.         ja nobypass
  106.  
  107.         sub ebx, [hs_memory_start]
  108.         add ebx, [hs_memory]
  109.  
  110.     nobypass:
  111.         jmp [hscrc2_ret]
  112.     }
  113. }
  114.  
  115. static void _declspec(naked) hscrc3_hook() {
  116.     _asm {
  117.         cmp edx, [hs_memory_start]
  118.         jb ending3
  119.         cmp edx, [hs_memory_end]
  120.         ja ending3
  121.  
  122.         push edx
  123.         sub edx, [hs_memory_start]
  124.         cmp edx, HSCRC1_OFF - 0x100 /* hscrc1 */
  125.         jb ending2
  126.         cmp edx, HSCRC2_OFF + 0x100 /* hscrc2 */
  127.         ja ending2
  128.         cmp edx, HSCRC1_OFF + 0x100 /* hscrc1 */
  129.         jb ending1
  130.         cmp edx, HSCRC2_OFF - 0x100 /* hscrc2 */
  131.         ja ending1
  132.         jmp ending2
  133.  
  134.     ending1:
  135.         add edx, [hs_memory]
  136.         mov edx, [edx]
  137.         mov dword ptr[esp + 0x4],edx /* replaces edx that was pushed in the stack earlier in the routine (addy above hook) */
  138.  
  139.     ending2:
  140.         pop edx
  141.  
  142.     ending3:
  143.         jmp [hscrc3_ret]
  144.     }
  145. }
  146.  
  147. static void _declspec(naked) hscrc4_hook() {
  148.     _asm {
  149.         cmp esi, [self_memory_start]
  150.         jb nobypass
  151.         cmp esi, [self_memory_end]
  152.         ja nobypass
  153.  
  154.         sub esi, [self_memory_start]
  155.         add esi, [self_memory]
  156.  
  157.     nobypass:
  158.         jmp [hscrc4_ret]
  159.     }
  160. }
  161.  
  162. /* thanks Mahorori */
  163. #pragma pack(push, 1)
  164. typedef struct tagcrc_data {
  165.     void *address;
  166.     uint32_t size;
  167. } crc_data;
  168. #pragma pack(pop)
  169.  
  170. /* xors a memory block with a key */
  171. static void xor_memory(uint8_t *data, size_t data_size, uint8_t *xor_key, size_t xor_key_size) {
  172.     size_t i;
  173.     for (i = 0; i < data_size; i++) {
  174.         data[i] ^= xor_key[i % xor_key_size];
  175.     }
  176. }
  177.  
  178. /* xors a hs crc table entry (crc_data) with the given key */
  179. #define hscrc5_xor_entry(pentry, xor_key) xor_memory((uint8_t *)pentry, sizeof(crc_data), (uint8_t *)&xor_key, sizeof(uint32_t));
  180.  
  181. /*
  182.     iterates the hscrc5 table, creates copies of each function by copying them to a mem region
  183.     within hackshield's memory and redirects each table entry to the copied functions
  184. */
  185. static int hscrc5_table_hack(crc_data *hscrc5_table, uint32_t xor_key, uint32_t free_space_addy, size_t free_space_size) {
  186.     uint32_t oldprotect;
  187.     crc_data *i;
  188.     errno_t err;
  189.     char buferr[512] = { 0 };
  190.  
  191.     /*
  192.         we will copy each memory region in the table to an empty memory region in ehsvc.dll
  193.         because apparently it crashes if I redirect it to the hs memory dump
  194.     */
  195.     if (!memory_protect((void *)free_space_addy, free_space_size, PAGE_EXECUTE_READWRITE, &oldprotect)) {
  196.         return 0;
  197.     }
  198.  
  199.     /*
  200.         decrypt, spoof end re-encrypt each entry
  201.         the table is null-terminated. when the encrypted address == xor_key it means that it's zero
  202.     */
  203.     for (i = hscrc5_table; (uint32_t)i->address != xor_key; i++) {
  204.         hscrc5_xor_entry(i, xor_key); /* decrypt */
  205.         dbgprintf("spoofing hscrc5 table entry {ehsvc.dll + %.08X, %lu}... ", (uint32_t)i->address - (uint32_t)GetModuleHandleA("ehsvc.dll"), i->size);
  206.         err = memcpy_s((void *)free_space_addy, i->size, i->address, i->size);
  207.         if (err) {
  208.             strerror_s(buferr, 512, err);
  209.             dbgprintf("memcpy_s failed: %s", buferr);
  210.         }
  211.         i->address = (void *)free_space_addy;
  212.         free_space_addy += i->size;
  213.         hscrc5_xor_entry(i, xor_key); /* encrypt */
  214.         dbgputs("done!");
  215.     }
  216.  
  217.     return memory_protect((void *)free_space_addy, free_space_size, oldprotect, &oldprotect);
  218. }
  219.  
  220. #ifndef HSONLY
  221. static void __declspec(naked) mscrc_hook_1() {
  222.     __asm {
  223.         cmp edi,[self_memory_start]
  224.         jb nobypass
  225.         cmp edi,[self_memory_end]
  226.         ja nobypass
  227.  
  228.         sub edi,[self_memory_start]
  229.         add edi,[self_memory]
  230.  
  231.     nobypass:
  232.         jmp [mscrc1_ret]
  233.     }
  234. }
  235.  
  236. static void __declspec(naked) mscrc_hook_2() {
  237.     __asm {
  238.         cmp ecx,[self_memory_start]
  239.         jb nobypass
  240.         cmp ecx,[self_memory_end]
  241.         ja nobypass
  242.  
  243.         sub ecx,[self_memory_start]
  244.         add ecx,[self_memory]
  245.  
  246.     nobypass:
  247.         jmp [mscrc2_ret]
  248.     }
  249. }
  250. #endif
  251.  
  252. static uint32_t dump_module(HMODULE mod, uint32_t *start, uint32_t *end) {
  253.     char process_name[MAX_PATH] = { 0 };
  254.     uint32_t res = 0;
  255.  
  256.     GetModuleFileNameA(mod, process_name, MAX_PATH);
  257.     dbgprintf("Dumping %s... ", PathFindFileNameA(process_name));
  258.     res = module_dump_i(mod, start, end);
  259.     if (!res) {
  260.         dbgputs("Failed to create memory dump (out of memory?)");
  261.         return 0;
  262.     }
  263.     dbgputs("Done!");
  264.  
  265.     dbgprintf("%s: %.08X:%.08X (%lu bytes)\n", PathFindFileNameA(process_name), *start, *end, *end - *start);
  266.  
  267.     return res;
  268. }
  269.  
  270. #ifndef HSONLY
  271. static int patch_ms() {
  272.     /* mscrc */
  273.     detour mscrc1 = { (void **)&mscrc1_ret, mscrc_hook_1 };
  274.     detour mscrc2 = { (void **)&mscrc2_ret, mscrc_hook_2 };
  275.     generic_hack mscrc_group[] = {
  276.         { HACK_DETOUR, &mscrc1 },
  277.         { HACK_DETOUR, &mscrc2 },
  278.     };
  279.     hack mscrc = { 2, mscrc_group };
  280.     return hack_toggle(&mscrc, 1);
  281. }
  282. #endif
  283.  
  284. static int patch_hs() {
  285.     /* hscrc */
  286.     detour hscrc1 = { (void **)&hscrc1_ret, hscrc_hook_1 };
  287.     detour hscrc2 = { (void **)&hscrc2_ret, hscrc_hook_2 };
  288.     detour hscrc3 = { (void **)&hscrc3_ret, hscrc3_hook };
  289.     detour hscrc4 = { (void **)&hscrc4_ret, hscrc4_hook };
  290.     generic_hack hscrc_group[] = {
  291.         { HACK_DETOUR, &hscrc1 },
  292.         { HACK_DETOUR, &hscrc2 },
  293.         { HACK_DETOUR, &hscrc3 },
  294.         { HACK_DETOUR, &hscrc4 },
  295.     };
  296.     hack hscrc = { 4, hscrc_group }; /* TODO: just use a null terminated array */
  297.  
  298.     /* detection */
  299.     const char *scanner_bytes = "31 C0 C2 04 00";
  300.     memory_patch hs_process_scanner =    { (uint8_t *)HS_PROCESS_SCANNER, scanner_bytes };
  301.     memory_patch hs_module_scanner =    { (uint8_t *)HS_MODULE_SCANNER, scanner_bytes };
  302.  
  303.     const char *bp_bytes = "31 C0 C3";
  304.     memory_patch hs_hwbp_detection1 =    { (uint8_t *)HS_HWBP_DETECTION1, bp_bytes };
  305.     memory_patch hs_hwbp_detection2 =    { (uint8_t *)HS_HWBP_DETECTION2, bp_bytes };
  306.     memory_patch hs_hwbp_detection3 =    { (uint8_t *)HS_HWBP_DETECTION3, bp_bytes };
  307.     memory_patch hs_hwbp_detection4 =    { (uint8_t *)HS_HWBP_DETECTION4, "31 C0 C2 18 00" };
  308.     memory_patch hs_swbp_detection =    { (uint8_t *)HS_SWBP_DETECTION, bp_bytes };
  309.  
  310.     memory_patch hs_memory_detection =    { (uint8_t *)HS_MEMORY_PROTECTION, "B8 00 00 00 00" };
  311.  
  312.     generic_hack hs_detection_group[] = {
  313.         { HACK_MEMPATCH, &hs_process_scanner },
  314.         { HACK_MEMPATCH, &hs_module_scanner },
  315.         { HACK_MEMPATCH, &hs_hwbp_detection1 },
  316.         { HACK_MEMPATCH, &hs_hwbp_detection2 },
  317.         { HACK_MEMPATCH, &hs_hwbp_detection3 },
  318.         { HACK_MEMPATCH, &hs_hwbp_detection4 },
  319.         { HACK_MEMPATCH, &hs_swbp_detection },
  320.         { HACK_MEMPATCH, &hs_memory_detection },
  321.     };
  322.     hack hs_detection = { is_wow64 ? 8 : 7, hs_detection_group };
  323.  
  324.     /* toggle all patches */
  325.     if (!hscrc5_table_hack((crc_data *)HSCRC5_TABLE, HSCRC5_TABLE_XOR_KEY, EHSVC_EMPTY_MEM, EHSVC_EMPTY_MEM_SIZE)) {
  326.         return 0;
  327.     }
  328.  
  329.     if (!hack_toggle(&hscrc, 1)) {
  330.         return 0;
  331.     }
  332.    
  333.     if (!hack_toggle(&hs_detection, 1)) {
  334.         return 0;
  335.     }
  336.  
  337.     return 1;
  338. }
  339.  
  340. /* Hooks to inject the BlackCipher.aes bypass ----------------------------------------------------------------- */
  341. #ifndef NOBCINJECT
  342. /* ghetto hack to prevent function pointer typecast warnings */
  343. typedef union tagpfnCreateProcessW {
  344.     void *void_ptr;
  345.     BOOL(WINAPI *func_ptr)(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES,
  346.         LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID,
  347.         LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION);
  348. } pfnCreateProcessW;
  349.  
  350. static pfnCreateProcessW pCreateProcessW = { 0 };
  351.  
  352. static BOOL WINAPI CreateProcessW_hook(
  353.     _In_opt_     LPCWSTR lpApplicationName,
  354.     _Inout_opt_  LPWSTR lpCommandLine,
  355.     _In_opt_     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  356.     _In_opt_     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  357.     _In_         BOOL bInheritHandles,
  358.     _In_         DWORD dwCreationFlags,
  359.     _In_opt_     LPVOID lpEnvironment,
  360.     _In_opt_     LPCWSTR lpCurrentDirectory,
  361.     _In_         LPSTARTUPINFOW lpStartupInfo,
  362.     _Out_        LPPROCESS_INFORMATION lpProcessInformation
  363. ) {
  364.     size_t chars_converted = 0;                                /* used by wcstombs_s and mbstowcs_s */
  365.     char application_name_mb[512] =        { "(nullptr)\0" };    /* multibyte versions of the strings in the params*/
  366.     char command_line_mb[512] =            { "(nullptr)\0" };
  367.     char current_directory_mb[512] =    { "(nullptr)\0" };
  368.     BOOL res;
  369.     char buf[MAX_PATH] = { 0 };                                /* used by GetModuleNameA */
  370.     PSTR cmd_line_end;                                        /* pointer to the double quote after BlackCipher.aes in the cmd line */
  371.     size_t cmd_line_end_size;                                /* size of the buffer after cmd_line_end */
  372.     int is_bc_executable = 0;                                /* 1 if the call is related to BlackCipher.aes */
  373.     WCHAR replaced_cmd[512] = { 0 };                        /* modified cmd line (BlackCipher.aes -> BlackCipher.aes2) */
  374.  
  375. #if _DEBUG
  376.     if (!GetConsoleWindow()) {
  377.         FreeConsole();
  378.         win32_console_create();
  379.     }
  380. #endif
  381.  
  382.     do {
  383.         if (lpApplicationName && wcstombs_s(&chars_converted, application_name_mb, 512, lpApplicationName, 512) == -1) {
  384.             dbgwprintf(L"wcstombs_s failed for lpApplicationName (%s)\n", lpApplicationName);
  385.             break;
  386.         }
  387.  
  388.         if (lpCommandLine && wcstombs_s(&chars_converted, command_line_mb, 512, lpCommandLine, 512) == -1) {
  389.             dbgwprintf(L"wcstombs_s failed for lpCommandLine (%s)\n", lpCommandLine);
  390.             break;
  391.         }
  392.  
  393.         if (lpCurrentDirectory && wcstombs_s(&chars_converted, current_directory_mb, 512, lpCurrentDirectory, 512) == -1) {
  394.             dbgwprintf(L"wcstombs_s failed for lpCurrentDirectory (%s)\n", lpCurrentDirectory);
  395.             break;
  396.         }
  397.  
  398.         is_bc_executable = StrStrIA(command_line_mb, BLACKCIPHER_EXE) != NULL;
  399.  
  400.         /* replace BlackCipher.aes with BlackCipher.aes2 */
  401.         if (is_bc_executable) {
  402.             cmd_line_end = StrStrIA(command_line_mb, BLACKCIPHER_EXE) + 15;
  403.             cmd_line_end_size = MAX_PATH - (cmd_line_end - command_line_mb);
  404.             memmove_s(cmd_line_end + 1, cmd_line_end_size - 1, cmd_line_end, cmd_line_end_size - 1);
  405.             *cmd_line_end = '2';
  406.             if (mbstowcs_s(&chars_converted, replaced_cmd, 512, command_line_mb, 512)) {
  407.                 dbgprintf("mbstowcs_s failed for command_line_mb (%s)\n", command_line_mb);
  408.                 break;
  409.             }
  410.             lpCommandLine = replaced_cmd;
  411.         }
  412.  
  413.         dbgprintf(
  414.             "CreateProcessW("                        "\n"
  415.             "\t"    "lpApplicationName = %s"        "\n"
  416.             "\t"    "lpCommandLine = %s"            "\n"
  417.             "\t"    "lpProcessAttributes = %.08X"    "\n"
  418.             "\t"    "lpThreadAttributes = %.08X"    "\n"
  419.             "\t"    "bInheritHandles = %s"            "\n"
  420.             "\t"    "dwCreationFlags = %.08X"        "\n"
  421.             "\t"    "lpEnvironment = %.08X"            "\n"
  422.             "\t"    "lpCurrentDirectory = %s"        "\n"
  423.             "\t"    "lpStartupInfo = %.08X"            "\n"
  424.             "\t"    "lpProcessInformation = %.08X"    "\n"
  425.             ")"                                        "\n",
  426.             application_name_mb,
  427.             command_line_mb,
  428.             lpProcessAttributes,
  429.             lpThreadAttributes,
  430.             bInheritHandles ? "TRUE" : "FALSE",
  431.             dwCreationFlags,
  432.             lpEnvironment,
  433.             current_directory_mb,
  434.             lpStartupInfo,
  435.             lpProcessInformation
  436.         );
  437. #pragma warning(disable: 127)
  438.     } while (0);
  439. #pragma warning(default: 127)
  440.  
  441.     res = pCreateProcessW.func_ptr(lpApplicationName, lpCommandLine, lpProcessAttributes,
  442.         lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
  443.         lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
  444.  
  445.     dbgprintf("Return value: %s\n", res ? "TRUE" : "FALSE");
  446.  
  447.     do {
  448.         if (!res) {
  449.             break;
  450.         }
  451.        
  452.         if (!is_bc_executable) {
  453.             break;
  454.         }
  455.  
  456.         if (!GetModuleFileNameA(bypass_dll, buf, MAX_PATH)) {
  457.             dbgputs("Failed to determine bypass dll path");
  458.             break;
  459.         }
  460.  
  461.         dbgprintf("Injecting %s into " BLACKCIPHER_EXE " (PID %.08X)... ", buf, lpProcessInformation->dwProcessId);
  462.         if (!process_inject_dll(lpProcessInformation->dwProcessId, buf)) {
  463.             dbgle("Injection failed!");
  464.             break;
  465.         }
  466.  
  467.         dbgputs("Done!");
  468. #pragma warning(disable: 127)
  469.     } while (0);
  470. #pragma warning(default: 127)
  471.  
  472.     return res;
  473. }
  474.  
  475. static int save_ms_dump_info() {
  476.     FILE *f = NULL;
  477.     int res = 1;
  478.     errno_t err;
  479.     char buf[512] = { 0 };
  480.     uint32_t pid;
  481.     uint32_t maple_size = self_memory_end - self_memory_start;
  482.  
  483.     err = fopen_s(&f, DUMPINFO_FILE, "wb");
  484.     if (err || !f) {
  485.         strerror_s(buf, 512, err);
  486.         dbgfnprintf("fopen_s failed: %s", buf);
  487.         res = 0;
  488.     }
  489.  
  490.     if (res) {
  491.         /* dump base */
  492.         if (fwrite(&self_memory, sizeof(uint32_t), 1, f) != 1) {
  493.             dbgfnputs("fwrite failed for dump base!");
  494.             res = 0;
  495.         }
  496.  
  497.         /* pid */
  498.         pid = (uint32_t)GetCurrentProcessId();
  499.         if (fwrite(&pid, sizeof(uint32_t), 1, f) != 1) {
  500.             dbgfnputs("fwrite failed for pid!");
  501.             res = 0;
  502.         }
  503.  
  504.         /* maple base */
  505.         if (fwrite(&self_memory_start, sizeof(uint32_t), 1, f) != 1) {
  506.             dbgfnputs("fwrite failed for maple base!");
  507.             res = 0;
  508.         }
  509.  
  510.         /* maple size */
  511.         if (fwrite(&maple_size, sizeof(uint32_t), 1, f) != 1) {
  512.             dbgfnputs("fwrite failed for maple size!");
  513.             res = 0;
  514.         }
  515.  
  516.         fclose(f);
  517.         f = NULL;
  518.     }
  519.  
  520.     return res;
  521. }
  522.  
  523. static int hook_bc() {
  524.     pfnCreateProcessW phook =        { CreateProcessW_hook };
  525.     winapi_detour create_process =    { "Kernel32.dll", "CreateProcessW", (void **)&pCreateProcessW, phook.void_ptr };
  526.     generic_hack bc_inject_group[] = {
  527.         { HACK_WINAPI_DETOUR, &create_process },
  528.     };
  529.     hack bc_inject = { 1, bc_inject_group };
  530.     remove(DUMPINFO_FILE);
  531.     return hack_toggle(&bc_inject, 1);
  532. }
  533. #endif
  534.  
  535. /* BlackCipher.aes detections --------------------------------------------------------------------------------- */
  536. static uint32_t maple_pid = 0, maple_dump = 0, maple_base = 0, maple_size = 0;
  537.  
  538. #ifndef HSONLY
  539. typedef union tagpfnReadProcessMemory {
  540.     BOOL(WINAPI *func_ptr)(HANDLE, LPCVOID, LPVOID, SIZE_T, SIZE_T *);
  541.     void *void_ptr;
  542. } pfnReadProcessMemory;
  543.  
  544. static pfnReadProcessMemory pKernelbase_ReadProcessMemory = { 0 };
  545.  
  546. static BOOL WINAPI ReadProcessMemory_hook(
  547.     _In_   HANDLE hProcess,
  548.     _In_   LPCVOID lpBaseAddress,
  549.     _Out_  LPVOID lpBuffer,
  550.     _In_   SIZE_T nSize,
  551.     _Out_  SIZE_T *lpNumberOfBytesRead
  552. ) {
  553.     BOOL res;
  554.     int spoofed = 0;
  555.     uint32_t pid = (uint32_t)GetProcessId(hProcess);
  556.     uint32_t current_pid = (uint32_t)GetCurrentProcessId();
  557.     LPCVOID original_base = lpBaseAddress;
  558.  
  559.     if (pid == maple_pid || pid == current_pid) {
  560. #if _DEBUG
  561.         if (!GetConsoleWindow()) {
  562.             FreeConsole();
  563.             win32_console_create();
  564.         }
  565. #endif
  566.  
  567.         if (GetProcessId(hProcess) == maple_pid && (uint32_t)lpBaseAddress >= maple_base && (uint32_t)lpBaseAddress < maple_base + maple_size) {
  568.             lpBaseAddress = (LPCVOID)((uint32_t)lpBaseAddress - maple_base + maple_dump);
  569.             spoofed = 1;
  570.         }
  571.  
  572.         if (GetProcessId(hProcess) == GetCurrentProcessId() && (uint32_t)lpBaseAddress >= self_memory_start && (uint32_t)lpBaseAddress < self_memory_end) {
  573.             lpBaseAddress = (LPCVOID)((uint32_t)lpBaseAddress - self_memory_start + self_memory);
  574.             dbgputs("!!!BC tried to check its own memory!!!");
  575.             spoofed = 1;
  576.         }
  577.     }
  578.  
  579.     res = pKernelbase_ReadProcessMemory.func_ptr(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead);
  580.  
  581.     if (spoofed) {
  582.         dbgprintf(
  583.             "ReadProcessMemory("                    "\n"
  584.             "\t"    "hProcess = %.08X"                "\n"
  585.             "\t"    "lpBaseAddress = %.08X"            "\n"
  586.             "\t"    "lpBuffer = %.08X"                "\n"
  587.             "\t"    "nSize = %lu"                    "\n"
  588.             "\t"    "lpNumberOfBytesRead = %.08X"    "\n"
  589.             ")"                                        "\n",
  590.             hProcess,
  591.             original_base,
  592.             lpBuffer,
  593.             nSize,
  594.             lpNumberOfBytesRead
  595.         );
  596.         dbgprintf("lpBaseAddress spoofed to %.08X\n", lpBaseAddress);
  597.         dbgprintf("Return value: %s\n", res ? "TRUE" : "FALSE");
  598.     }
  599.  
  600.     return res;
  601. }
  602.  
  603. typedef DWORD NTSTATUS;
  604. typedef LPVOID POBJECT_ATTRIBUTES;
  605. typedef LPVOID PCLIENT_ID;
  606. #define STATUS_ACCESS_DENIED 0xC0000022
  607.  
  608. typedef union tagpfnNtOpenProcess {
  609.     NTSTATUS(NTAPI *func_ptr)(
  610.         OUT PHANDLE             ProcessHandle,
  611.         IN ACCESS_MASK          AccessMask,
  612.         IN POBJECT_ATTRIBUTES   ObjectAttributes,
  613.         IN PCLIENT_ID           ClientId
  614.     );
  615.     void *void_ptr;
  616. } pfnNtOpenProcess;
  617.  
  618. static pfnNtOpenProcess pNtOpenProcess = { 0 };
  619.  
  620. static NTSTATUS NTAPI NtOpenProcess_hook(
  621.     OUT PHANDLE             ProcessHandle,
  622.     IN ACCESS_MASK          AccessMask,
  623.     IN POBJECT_ATTRIBUTES   ObjectAttributes,
  624.     IN PCLIENT_ID           ClientId
  625. ) {
  626.     NTSTATUS res;
  627.     uint32_t pid;
  628.  
  629.     AccessMask |= PROCESS_QUERY_INFORMATION; /* ensures that we'll have permission to get PID */
  630.     res = pNtOpenProcess.func_ptr(ProcessHandle, AccessMask, ObjectAttributes, ClientId);
  631.     pid = (uint32_t)GetProcessId(*ProcessHandle);
  632.     if (!res && pid != maple_pid) {
  633.         dbgprintf("Blocking NtOpenProcess for pid %.08X\n", pid);
  634.         res = STATUS_ACCESS_DENIED;
  635.         *ProcessHandle = NULL;
  636.     }
  637.  
  638.     return res;
  639. }
  640.  
  641. typedef union tagpfnNtReadVirtualMemory {
  642.     NTSTATUS(NTAPI *func_ptr)(
  643.         IN HANDLE    ProcessHandle,
  644.         IN PVOID    BaseAddress,
  645.         OUT PVOID    Buffer,
  646.         IN ULONG    NumberOfBytesToRead,
  647.         OUT PULONG    NumberOfBytesReaded OPTIONAL
  648.     );
  649.     void *void_ptr;
  650. } pfnNtReadVirtualMemory;
  651.  
  652. static pfnNtReadVirtualMemory pNtReadVirtualMemory = { 0 };
  653.  
  654. static NTSTATUS NTAPI NtReadVirtualMemory_hook(
  655.     IN HANDLE    ProcessHandle,
  656.     IN PVOID    BaseAddress,
  657.     OUT PVOID    Buffer,
  658.     IN ULONG    NumberOfBytesToRead,
  659.     OUT PULONG    NumberOfBytesReaded OPTIONAL
  660. ) {
  661.     if (GetProcessId(ProcessHandle) == maple_pid) {
  662.         dbgprintf("Blocking NtReadVirtualMemory for address %.08X\n", BaseAddress);
  663.         return STATUS_ACCESS_DENIED;
  664.     }
  665.     return pNtReadVirtualMemory.func_ptr(ProcessHandle, BaseAddress,
  666.         Buffer, NumberOfBytesToRead, NumberOfBytesReaded);
  667. }
  668.  
  669. static int load_ms_dump_info() {
  670.     FILE *f = NULL;
  671.     int res = 1;
  672.     errno_t err;
  673.     char buf[512] = { 0 };
  674.  
  675.     err = fopen_s(&f, DUMPINFO_FILE, "rb");
  676.     if (err || !f) {
  677.         strerror_s(buf, 512, err);
  678.         dbgfnprintf("fopen_s failed: %s", buf);
  679.         res = 0;
  680.     }
  681.  
  682.     if (res) {
  683.         /* dump base */
  684.         if (fread(&maple_dump, sizeof(uint32_t), 1, f) != 1) {
  685.             dbgfnputs("fread failed for dump base!");
  686.             res = 0;
  687.         }
  688.  
  689.         /* pid */
  690.         if (fread(&maple_pid, sizeof(uint32_t), 1, f) != 1) {
  691.             dbgfnputs("fread failed for pid!");
  692.             res = 0;
  693.         }
  694.  
  695.         /* maple base */
  696.         if (fread(&maple_base, sizeof(uint32_t), 1, f) != 1) {
  697.             dbgfnputs("fread failed for maple base!");
  698.             res = 0;
  699.         }
  700.  
  701.         /* maple size */
  702.         if (fread(&maple_size, sizeof(uint32_t), 1, f) != 1) {
  703.             dbgfnputs("fread failed for maple size!");
  704.             res = 0;
  705.         }
  706.  
  707.         fclose(f);
  708.         f = NULL;
  709.     }
  710.  
  711.     return res;
  712. }
  713.  
  714. static int patch_bc() {
  715.     pfnReadProcessMemory pReadProcessMemory_hook = { ReadProcessMemory_hook };
  716.     winapi_detour read_process_memory = { "KERNELBASE.dll", "ReadProcessMemory", (void **)&pKernelbase_ReadProcessMemory, pReadProcessMemory_hook.void_ptr };
  717.  
  718.     const char *ret4 = "C2 04 00";
  719.     memory_patch bc_hash1 = { (uint8_t *)BC_HASH_DETECTION1, ret4 };
  720.     memory_patch bc_hash2 = { (uint8_t *)BC_HASH_DETECTION2, ret4 };
  721.  
  722.     pfnNtOpenProcess pNtOpenProcess_hook = { NtOpenProcess_hook };
  723.     winapi_detour open_process = { "NTDLL.dll", "NtOpenProcess", (void **)&pNtOpenProcess, pNtOpenProcess_hook.void_ptr };
  724.  
  725.     pfnNtReadVirtualMemory pNtReadVirtualMemory_hook = { NtReadVirtualMemory_hook };
  726.     winapi_detour read_virtual_memory = { "NTDLL.dll", "NtReadVirtualMemory", (void **)&pNtReadVirtualMemory, pNtReadVirtualMemory_hook.void_ptr };
  727.  
  728.     generic_hack bc_detection_group[] = {
  729.         { HACK_WINAPI_DETOUR, &read_process_memory },
  730.         { HACK_MEMPATCH, &bc_hash1 },
  731.         { HACK_MEMPATCH, &bc_hash2 },
  732.         { HACK_WINAPI_DETOUR, &open_process },
  733.         { HACK_WINAPI_DETOUR, &read_virtual_memory },
  734.     };
  735.     hack bc_detection = { 5, bc_detection_group };
  736.  
  737.     if (!hack_toggle(&bc_detection, 1)) {
  738.         return 0;
  739.     }
  740.  
  741.     return 1;
  742. }
  743. #endif
  744. /* ------------------------------------------------------------------------------------------------------------ */
  745.  
  746. static int bypezz_wut() {
  747.     HMODULE ehsvc = NULL;
  748.     char process_name[MAX_PATH] = { 0 };
  749.     int is_black_cipher = 0;
  750.  
  751.     if (!GetModuleFileNameA(GetModuleHandleA(NULL), process_name, MAX_PATH)) {
  752.         dbgle("Failed to determine process name");
  753.         return 0;
  754.     }
  755.  
  756.     if (!IsWow64Process(GetCurrentProcess(), &is_wow64)) {
  757.         dbgle("IsWow64Process failed");
  758.         return 0;
  759.     }
  760.  
  761.     if (StrStrIA(process_name, BLACKCIPHER_EXE)) {
  762.         is_black_cipher = 1;
  763.     }
  764.  
  765.     /* if we're injected into maple, prepare black cipher injection hook */
  766. #ifndef NOBCINJECT
  767.     if (!is_black_cipher) {
  768.         if (!hook_bc()) {
  769.             return 0;
  770.         }
  771.     }
  772. #endif
  773.  
  774.     dbgprintf("Waiting for ehsvc.dll... ");
  775.     while (!ehsvc) {
  776.         Sleep(100);
  777.         ehsvc = GetModuleHandleA("ehsvc.dll");
  778.     }
  779.     dbgputs("Done!");
  780.  
  781.     /* dump HS memory */
  782.     hs_memory = dump_module(ehsvc, &hs_memory_start, &hs_memory_end);
  783.     if (!hs_memory) {
  784.         return 0;
  785.     }
  786.  
  787.     /* dump current process memory */
  788. #ifdef HSONLY
  789.     module_size_i(GetModuleHandleA(NULL), &self_memory_start, (size_t *)&self_memory_end);
  790.     self_memory_end += self_memory_start;
  791.     self_memory = self_memory_start;
  792. #else
  793.     self_memory = dump_module(GetModuleHandleA(NULL), &self_memory_start, &self_memory_end);
  794.     if (!self_memory) {
  795.         return 0;
  796.     }
  797. #endif
  798.  
  799.     /* now that ehsvc is loaded and dumped, we can initialize the addys */
  800.     hscrc1_ret = HSCRC1;
  801.     hscrc2_ret = HSCRC2;
  802.     hscrc3_ret = HSCRC3;
  803.     hscrc4_ret = HSCRC4;
  804. #ifndef HSONLY
  805.     mscrc1_ret = MSCRC1;
  806.     mscrc2_ret = MSCRC2;
  807. #endif
  808.  
  809.     /* patch HS detections */
  810.     if (!patch_hs()) {
  811.         return 0;
  812.     }
  813.  
  814.     /* patch mscrc or bc detections depending on what we're injected to */
  815. #ifndef HSONLY
  816.     if (!is_black_cipher) {
  817.         if (!save_ms_dump_info()) {
  818.             return 0;
  819.         }
  820.         if (!patch_ms()) {
  821.             return 0;
  822.         }
  823.     }
  824.     else {
  825.         dbgputs("Waiting for dump info...");
  826.         while (!load_ms_dump_info()) {
  827.             Sleep(1);
  828.         }
  829.         dbgprintf("MapleStory dump: %.08X\n", maple_dump);
  830.         dbgprintf("MapleStory pid: %.08X\n", maple_pid);
  831.         dbgprintf("MapleStory base: %.08X\n", maple_base);
  832.  
  833.         if (!patch_bc()) {
  834.             return 0;
  835.         }
  836.     }
  837. #endif
  838.  
  839.     /* you'd normally call this from maple's main thread every frame but this is just a bypass */
  840.     cq_process_all();
  841.  
  842. #ifndef _DEBUG
  843.     if (is_black_cipher) {
  844.         MessageBoxA(NULL, "BlackCipher should have gone fucking itself now", BYPASS_NAME " v" BYPASS_VERSION, MB_OK | MB_ICONINFORMATION);
  845.     }
  846.     else {
  847.         MessageBoxA(NULL, "wao, bypezz :wut:\n\nmade by Franc[e]sco @ gamekiller.net\n"
  848.             "huge credits to DBlmao who first discovered the BlackCipher checks.", BYPASS_NAME " v" BYPASS_VERSION, MB_OK | MB_ICONINFORMATION);
  849.     }
  850. #endif
  851.  
  852.     return 1;
  853. }
  854.  
  855. /*
  856.     displays an error message as a messagebox with a specific MB icon
  857.     followed by the formatted GetLastError message
  858. */
  859. static void msgbox_gle(const char *msg, UINT icon) {
  860.     DWORD gle;
  861.     char *gle_msg;
  862.     char buf[512] = { 0 };
  863.  
  864.     gle = GetLastError();
  865.     if (!gle) {
  866.         return;
  867.     }
  868.  
  869.     FormatMessageA(
  870.         FORMAT_MESSAGE_ALLOCATE_BUFFER |
  871.         FORMAT_MESSAGE_FROM_SYSTEM |
  872.         FORMAT_MESSAGE_IGNORE_INSERTS,
  873.         NULL, gle,
  874.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  875.         (LPSTR)&gle_msg,
  876.         0, NULL
  877.     );
  878.  
  879.     sprintf_s(buf, 512, "%s, GLE=%.08X (%lu): %s\n", msg, gle, gle, gle_msg);
  880.     MessageBoxA(NULL, buf, BYPASS_NAME, MB_OK | icon);
  881.     LocalFree(gle_msg);
  882. }
  883.  
  884. /* wrapper for a msgbox_gle call with a MB_ICONERROR icon */
  885. #define msgbox_gle_error(msg) msgbox_gle(msg, MB_ICONERROR)
  886.  
  887. static DWORD WINAPI rundll(HMODULE module) {
  888.     uint32_t res;
  889.        
  890.     bypass_dll = module;
  891.  
  892. #if _DEBUG
  893.     if (!win32_console_create()) {
  894.         msgbox_gle_error("Failed to create console");
  895.         return EXIT_FAILURE;
  896.     }
  897. #endif
  898.  
  899.     dbgputs(BYPASS_NAME " v" BYPASS_VERSION);
  900.     dbgputchar('\n');
  901.        
  902.     if (!cq_init()) {
  903.         return EXIT_FAILURE;
  904.     }
  905.     res = bypezz_wut() ? EXIT_SUCCESS : EXIT_FAILURE;
  906.     cq_destroy();
  907.  
  908.     return res;
  909. }
  910.  
  911. BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
  912.     (void)reserved;
  913.  
  914.     if (reason != DLL_PROCESS_ATTACH)
  915.         return TRUE;
  916.  
  917.     DisableThreadLibraryCalls(module);
  918.     if (!CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)rundll, (LPVOID)module, 0, NULL)) {
  919.         msgbox_gle_error("Failed to start main dll thread.");
  920.         FreeLibraryAndExitThread(module, EXIT_SUCCESS);
  921.     }
  922.  
  923.     /* I could write de-attach code and dealloc the dumps but it's kinda pointless and I'm too lazy */
  924.  
  925.     return TRUE;
  926. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement