Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <string.h>
- #include "win32_gui.h"
- #include "win32_console.h"
- /* I'm using /W4 just to be sure I don't make any silent mistakes, so I'm gonna disable non-standard extension warnings */
- #pragma warning(disable: 152 221 204)
- #include "hackdesu/io.h"
- #include "hackdesu/process.h"
- #include "hackdesu/command_queue.h"
- #include "hackdesu/hack.h"
- #include "hackdesu/memory.h"
- #if _DEBUG
- #pragma comment(lib, "hackdesu/debug.lib")
- #else
- #pragma comment(lib, "hackdesu/release.lib")
- #endif
- #include <Shlwapi.h>
- #pragma comment(lib, "Shlwapi.lib")
- #define BYPASS_NAME "Ghetto Bypass"
- #define BYPASS_VERSION_NUMBER "1.3"
- #ifdef HSONLY
- #define BYPASS_VERSION BYPASS_VERSION_NUMBER " (HS only)"
- #else
- #define BYPASS_VERSION BYPASS_VERSION_NUMBER
- #endif
- #define DUMPINFO_FILE "dupe.dumpinfo"
- #define BLACKCIPHER_EXE "BlackCipher.aes"
- #if _DEBUG
- #define dbgle printf(__FUNCDNAME__ ": "); win32_show_error
- #else
- #define dbgle
- #endif
- HMODULE bypass_dll = NULL;
- BOOL is_wow64 = TRUE;
- static uint32_t hs_memory, hs_memory_start, hs_memory_end;
- static uint32_t hscrc1_ret, hscrc2_ret, hscrc3_ret, hscrc4_ret;
- #define EHSVC(offset) (hs_memory_start + offset)
- #define HSCRC1_OFF 0x9B252 /* hscrc1: 8A 11 33 C2 8B */
- #define HSCRC1 EHSVC(HSCRC1_OFF)
- #define HSCRC2_OFF 0x37C217 /* hscrc2: set BP @hscrc1 */
- #define HSCRC2 EHSVC(HSCRC2_OFF)
- #define HSCRC3 EHSVC(0x26B6B7) /* hscrc3: set BP @hscrc1 */
- #define HSCRC4 EHSVC(0x408F7) /* hscrc4: set BP @0x00510000 */
- #define HSCRC5_TABLE EHSVC(0x164048) /* hscrc5: set BP @hscrc1 Press F9 until code change then go up */
- #define HSCRC5_TABLE_XOR_KEY *(uint32_t *)(HSCRC5_TABLE + 0x20)
- #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 */
- #define EHSVC_EMPTY_MEM_SIZE 0x500
- #define HS_PROCESS_SCANNER EHSVC(0x56BF0) /* process scanner: 81 EC ? ? ? ? A0 ? ? ? ? 53 55 56 8B E9 */
- #define HS_MODULE_SCANNER EHSVC(0x5D8B0) /* module scanner: 8B 41 ? 56 8B 35 ? ? ? ? 85 C0 */
- #define HS_HWBP_DETECTION1 EHSVC(0x11280) /* HWBP detection (main): 55 8B EC 81 EC ? ? ? ? 56 57 B9 */
- #define HS_HWBP_DETECTION2 EHSVC(0xF870) /* HWBP detection 2: 81 EC ? ? ? ? 53 8B 9C 24 ? ? ? ? 85 */
- #define HS_HWBP_DETECTION3 EHSVC(0xFA60) /* HWBP detection 3: 81 EC ? ? ? ? 56 57 B9 ? ? ? ? 33 C0 8D 7C 24 ? F3 AB */
- #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 */
- #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 */
- #define HS_MEMORY_PROTECTION EHSVC(0xDA5CA) /* memory protection: E8 ? ? ? ? 83 C4 ? 89 45 ? 3B C3 75 ? FF 75 ? 8D */
- static uint32_t self_memory, self_memory_start, self_memory_end;
- #ifndef HSONLY
- static uint32_t mscrc1_ret, mscrc2_ret;
- #define MSCRC1 0x02051FC4 /* mscrc1: bp CRC2 | register = opcode */
- #define MSCRC2 0x0216D081 /* mscrc2: bp 00500000 | register = opcode */
- /*
- 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
- (scroll to the beginning) 83 ?? ?? ?? 74 ?? 8B ?? ?? 83 ?? ?? 89 ?? ?? EB ?? C7 ?? ?? 00 00 00 00 8B ?? ?? ?? 8D ?? ?? E8 ?? ?? ?? ?? C7 ?? ?? 00 00 00 00 C7
- callers are VMed
- */
- #define BC_HASH_DETECTION1 0x0043B800 /* 0003A81B in the CEM */
- #define BC_HASH_DETECTION2 0x0043B8F0 /* 0003A90B in the CEM */
- #endif
- static void _declspec(naked) hscrc_hook_1() {
- _asm {
- cmp ecx, [hs_memory_start]
- jb nobypass
- cmp ecx, [hs_memory_end]
- ja nobypass
- sub ecx, [hs_memory_start]
- add ecx, [hs_memory]
- nobypass:
- jmp [hscrc1_ret]
- }
- }
- static void _declspec(naked) hscrc_hook_2() {
- _asm {
- cmp ebx, [hs_memory_start]
- jb nobypass
- cmp ebx, [hs_memory_end]
- ja nobypass
- sub ebx, [hs_memory_start]
- add ebx, [hs_memory]
- nobypass:
- jmp [hscrc2_ret]
- }
- }
- static void _declspec(naked) hscrc3_hook() {
- _asm {
- cmp edx, [hs_memory_start]
- jb ending3
- cmp edx, [hs_memory_end]
- ja ending3
- push edx
- sub edx, [hs_memory_start]
- cmp edx, HSCRC1_OFF - 0x100 /* hscrc1 */
- jb ending2
- cmp edx, HSCRC2_OFF + 0x100 /* hscrc2 */
- ja ending2
- cmp edx, HSCRC1_OFF + 0x100 /* hscrc1 */
- jb ending1
- cmp edx, HSCRC2_OFF - 0x100 /* hscrc2 */
- ja ending1
- jmp ending2
- ending1:
- add edx, [hs_memory]
- mov edx, [edx]
- mov dword ptr[esp + 0x4],edx /* replaces edx that was pushed in the stack earlier in the routine (addy above hook) */
- ending2:
- pop edx
- ending3:
- jmp [hscrc3_ret]
- }
- }
- static void _declspec(naked) hscrc4_hook() {
- _asm {
- cmp esi, [self_memory_start]
- jb nobypass
- cmp esi, [self_memory_end]
- ja nobypass
- sub esi, [self_memory_start]
- add esi, [self_memory]
- nobypass:
- jmp [hscrc4_ret]
- }
- }
- /* thanks Mahorori */
- #pragma pack(push, 1)
- typedef struct tagcrc_data {
- void *address;
- uint32_t size;
- } crc_data;
- #pragma pack(pop)
- /* xors a memory block with a key */
- static void xor_memory(uint8_t *data, size_t data_size, uint8_t *xor_key, size_t xor_key_size) {
- size_t i;
- for (i = 0; i < data_size; i++) {
- data[i] ^= xor_key[i % xor_key_size];
- }
- }
- /* xors a hs crc table entry (crc_data) with the given key */
- #define hscrc5_xor_entry(pentry, xor_key) xor_memory((uint8_t *)pentry, sizeof(crc_data), (uint8_t *)&xor_key, sizeof(uint32_t));
- /*
- iterates the hscrc5 table, creates copies of each function by copying them to a mem region
- within hackshield's memory and redirects each table entry to the copied functions
- */
- static int hscrc5_table_hack(crc_data *hscrc5_table, uint32_t xor_key, uint32_t free_space_addy, size_t free_space_size) {
- uint32_t oldprotect;
- crc_data *i;
- errno_t err;
- char buferr[512] = { 0 };
- /*
- we will copy each memory region in the table to an empty memory region in ehsvc.dll
- because apparently it crashes if I redirect it to the hs memory dump
- */
- if (!memory_protect((void *)free_space_addy, free_space_size, PAGE_EXECUTE_READWRITE, &oldprotect)) {
- return 0;
- }
- /*
- decrypt, spoof end re-encrypt each entry
- the table is null-terminated. when the encrypted address == xor_key it means that it's zero
- */
- for (i = hscrc5_table; (uint32_t)i->address != xor_key; i++) {
- hscrc5_xor_entry(i, xor_key); /* decrypt */
- dbgprintf("spoofing hscrc5 table entry {ehsvc.dll + %.08X, %lu}... ", (uint32_t)i->address - (uint32_t)GetModuleHandleA("ehsvc.dll"), i->size);
- err = memcpy_s((void *)free_space_addy, i->size, i->address, i->size);
- if (err) {
- strerror_s(buferr, 512, err);
- dbgprintf("memcpy_s failed: %s", buferr);
- }
- i->address = (void *)free_space_addy;
- free_space_addy += i->size;
- hscrc5_xor_entry(i, xor_key); /* encrypt */
- dbgputs("done!");
- }
- return memory_protect((void *)free_space_addy, free_space_size, oldprotect, &oldprotect);
- }
- #ifndef HSONLY
- static void __declspec(naked) mscrc_hook_1() {
- __asm {
- cmp edi,[self_memory_start]
- jb nobypass
- cmp edi,[self_memory_end]
- ja nobypass
- sub edi,[self_memory_start]
- add edi,[self_memory]
- nobypass:
- jmp [mscrc1_ret]
- }
- }
- static void __declspec(naked) mscrc_hook_2() {
- __asm {
- cmp ecx,[self_memory_start]
- jb nobypass
- cmp ecx,[self_memory_end]
- ja nobypass
- sub ecx,[self_memory_start]
- add ecx,[self_memory]
- nobypass:
- jmp [mscrc2_ret]
- }
- }
- #endif
- static uint32_t dump_module(HMODULE mod, uint32_t *start, uint32_t *end) {
- char process_name[MAX_PATH] = { 0 };
- uint32_t res = 0;
- GetModuleFileNameA(mod, process_name, MAX_PATH);
- dbgprintf("Dumping %s... ", PathFindFileNameA(process_name));
- res = module_dump_i(mod, start, end);
- if (!res) {
- dbgputs("Failed to create memory dump (out of memory?)");
- return 0;
- }
- dbgputs("Done!");
- dbgprintf("%s: %.08X:%.08X (%lu bytes)\n", PathFindFileNameA(process_name), *start, *end, *end - *start);
- return res;
- }
- #ifndef HSONLY
- static int patch_ms() {
- /* mscrc */
- detour mscrc1 = { (void **)&mscrc1_ret, mscrc_hook_1 };
- detour mscrc2 = { (void **)&mscrc2_ret, mscrc_hook_2 };
- generic_hack mscrc_group[] = {
- { HACK_DETOUR, &mscrc1 },
- { HACK_DETOUR, &mscrc2 },
- };
- hack mscrc = { 2, mscrc_group };
- return hack_toggle(&mscrc, 1);
- }
- #endif
- static int patch_hs() {
- /* hscrc */
- detour hscrc1 = { (void **)&hscrc1_ret, hscrc_hook_1 };
- detour hscrc2 = { (void **)&hscrc2_ret, hscrc_hook_2 };
- detour hscrc3 = { (void **)&hscrc3_ret, hscrc3_hook };
- detour hscrc4 = { (void **)&hscrc4_ret, hscrc4_hook };
- generic_hack hscrc_group[] = {
- { HACK_DETOUR, &hscrc1 },
- { HACK_DETOUR, &hscrc2 },
- { HACK_DETOUR, &hscrc3 },
- { HACK_DETOUR, &hscrc4 },
- };
- hack hscrc = { 4, hscrc_group }; /* TODO: just use a null terminated array */
- /* detection */
- const char *scanner_bytes = "31 C0 C2 04 00";
- memory_patch hs_process_scanner = { (uint8_t *)HS_PROCESS_SCANNER, scanner_bytes };
- memory_patch hs_module_scanner = { (uint8_t *)HS_MODULE_SCANNER, scanner_bytes };
- const char *bp_bytes = "31 C0 C3";
- memory_patch hs_hwbp_detection1 = { (uint8_t *)HS_HWBP_DETECTION1, bp_bytes };
- memory_patch hs_hwbp_detection2 = { (uint8_t *)HS_HWBP_DETECTION2, bp_bytes };
- memory_patch hs_hwbp_detection3 = { (uint8_t *)HS_HWBP_DETECTION3, bp_bytes };
- memory_patch hs_hwbp_detection4 = { (uint8_t *)HS_HWBP_DETECTION4, "31 C0 C2 18 00" };
- memory_patch hs_swbp_detection = { (uint8_t *)HS_SWBP_DETECTION, bp_bytes };
- memory_patch hs_memory_detection = { (uint8_t *)HS_MEMORY_PROTECTION, "B8 00 00 00 00" };
- generic_hack hs_detection_group[] = {
- { HACK_MEMPATCH, &hs_process_scanner },
- { HACK_MEMPATCH, &hs_module_scanner },
- { HACK_MEMPATCH, &hs_hwbp_detection1 },
- { HACK_MEMPATCH, &hs_hwbp_detection2 },
- { HACK_MEMPATCH, &hs_hwbp_detection3 },
- { HACK_MEMPATCH, &hs_hwbp_detection4 },
- { HACK_MEMPATCH, &hs_swbp_detection },
- { HACK_MEMPATCH, &hs_memory_detection },
- };
- hack hs_detection = { is_wow64 ? 8 : 7, hs_detection_group };
- /* toggle all patches */
- if (!hscrc5_table_hack((crc_data *)HSCRC5_TABLE, HSCRC5_TABLE_XOR_KEY, EHSVC_EMPTY_MEM, EHSVC_EMPTY_MEM_SIZE)) {
- return 0;
- }
- if (!hack_toggle(&hscrc, 1)) {
- return 0;
- }
- if (!hack_toggle(&hs_detection, 1)) {
- return 0;
- }
- return 1;
- }
- /* Hooks to inject the BlackCipher.aes bypass ----------------------------------------------------------------- */
- #ifndef NOBCINJECT
- /* ghetto hack to prevent function pointer typecast warnings */
- typedef union tagpfnCreateProcessW {
- void *void_ptr;
- BOOL(WINAPI *func_ptr)(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES,
- LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID,
- LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION);
- } pfnCreateProcessW;
- static pfnCreateProcessW pCreateProcessW = { 0 };
- static BOOL WINAPI CreateProcessW_hook(
- _In_opt_ LPCWSTR lpApplicationName,
- _Inout_opt_ LPWSTR lpCommandLine,
- _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
- _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
- _In_ BOOL bInheritHandles,
- _In_ DWORD dwCreationFlags,
- _In_opt_ LPVOID lpEnvironment,
- _In_opt_ LPCWSTR lpCurrentDirectory,
- _In_ LPSTARTUPINFOW lpStartupInfo,
- _Out_ LPPROCESS_INFORMATION lpProcessInformation
- ) {
- size_t chars_converted = 0; /* used by wcstombs_s and mbstowcs_s */
- char application_name_mb[512] = { "(nullptr)\0" }; /* multibyte versions of the strings in the params*/
- char command_line_mb[512] = { "(nullptr)\0" };
- char current_directory_mb[512] = { "(nullptr)\0" };
- BOOL res;
- char buf[MAX_PATH] = { 0 }; /* used by GetModuleNameA */
- PSTR cmd_line_end; /* pointer to the double quote after BlackCipher.aes in the cmd line */
- size_t cmd_line_end_size; /* size of the buffer after cmd_line_end */
- int is_bc_executable = 0; /* 1 if the call is related to BlackCipher.aes */
- WCHAR replaced_cmd[512] = { 0 }; /* modified cmd line (BlackCipher.aes -> BlackCipher.aes2) */
- #if _DEBUG
- if (!GetConsoleWindow()) {
- FreeConsole();
- win32_console_create();
- }
- #endif
- do {
- if (lpApplicationName && wcstombs_s(&chars_converted, application_name_mb, 512, lpApplicationName, 512) == -1) {
- dbgwprintf(L"wcstombs_s failed for lpApplicationName (%s)\n", lpApplicationName);
- break;
- }
- if (lpCommandLine && wcstombs_s(&chars_converted, command_line_mb, 512, lpCommandLine, 512) == -1) {
- dbgwprintf(L"wcstombs_s failed for lpCommandLine (%s)\n", lpCommandLine);
- break;
- }
- if (lpCurrentDirectory && wcstombs_s(&chars_converted, current_directory_mb, 512, lpCurrentDirectory, 512) == -1) {
- dbgwprintf(L"wcstombs_s failed for lpCurrentDirectory (%s)\n", lpCurrentDirectory);
- break;
- }
- is_bc_executable = StrStrIA(command_line_mb, BLACKCIPHER_EXE) != NULL;
- /* replace BlackCipher.aes with BlackCipher.aes2 */
- if (is_bc_executable) {
- cmd_line_end = StrStrIA(command_line_mb, BLACKCIPHER_EXE) + 15;
- cmd_line_end_size = MAX_PATH - (cmd_line_end - command_line_mb);
- memmove_s(cmd_line_end + 1, cmd_line_end_size - 1, cmd_line_end, cmd_line_end_size - 1);
- *cmd_line_end = '2';
- if (mbstowcs_s(&chars_converted, replaced_cmd, 512, command_line_mb, 512)) {
- dbgprintf("mbstowcs_s failed for command_line_mb (%s)\n", command_line_mb);
- break;
- }
- lpCommandLine = replaced_cmd;
- }
- dbgprintf(
- "CreateProcessW(" "\n"
- "\t" "lpApplicationName = %s" "\n"
- "\t" "lpCommandLine = %s" "\n"
- "\t" "lpProcessAttributes = %.08X" "\n"
- "\t" "lpThreadAttributes = %.08X" "\n"
- "\t" "bInheritHandles = %s" "\n"
- "\t" "dwCreationFlags = %.08X" "\n"
- "\t" "lpEnvironment = %.08X" "\n"
- "\t" "lpCurrentDirectory = %s" "\n"
- "\t" "lpStartupInfo = %.08X" "\n"
- "\t" "lpProcessInformation = %.08X" "\n"
- ")" "\n",
- application_name_mb,
- command_line_mb,
- lpProcessAttributes,
- lpThreadAttributes,
- bInheritHandles ? "TRUE" : "FALSE",
- dwCreationFlags,
- lpEnvironment,
- current_directory_mb,
- lpStartupInfo,
- lpProcessInformation
- );
- #pragma warning(disable: 127)
- } while (0);
- #pragma warning(default: 127)
- res = pCreateProcessW.func_ptr(lpApplicationName, lpCommandLine, lpProcessAttributes,
- lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
- lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
- dbgprintf("Return value: %s\n", res ? "TRUE" : "FALSE");
- do {
- if (!res) {
- break;
- }
- if (!is_bc_executable) {
- break;
- }
- if (!GetModuleFileNameA(bypass_dll, buf, MAX_PATH)) {
- dbgputs("Failed to determine bypass dll path");
- break;
- }
- dbgprintf("Injecting %s into " BLACKCIPHER_EXE " (PID %.08X)... ", buf, lpProcessInformation->dwProcessId);
- if (!process_inject_dll(lpProcessInformation->dwProcessId, buf)) {
- dbgle("Injection failed!");
- break;
- }
- dbgputs("Done!");
- #pragma warning(disable: 127)
- } while (0);
- #pragma warning(default: 127)
- return res;
- }
- static int save_ms_dump_info() {
- FILE *f = NULL;
- int res = 1;
- errno_t err;
- char buf[512] = { 0 };
- uint32_t pid;
- uint32_t maple_size = self_memory_end - self_memory_start;
- err = fopen_s(&f, DUMPINFO_FILE, "wb");
- if (err || !f) {
- strerror_s(buf, 512, err);
- dbgfnprintf("fopen_s failed: %s", buf);
- res = 0;
- }
- if (res) {
- /* dump base */
- if (fwrite(&self_memory, sizeof(uint32_t), 1, f) != 1) {
- dbgfnputs("fwrite failed for dump base!");
- res = 0;
- }
- /* pid */
- pid = (uint32_t)GetCurrentProcessId();
- if (fwrite(&pid, sizeof(uint32_t), 1, f) != 1) {
- dbgfnputs("fwrite failed for pid!");
- res = 0;
- }
- /* maple base */
- if (fwrite(&self_memory_start, sizeof(uint32_t), 1, f) != 1) {
- dbgfnputs("fwrite failed for maple base!");
- res = 0;
- }
- /* maple size */
- if (fwrite(&maple_size, sizeof(uint32_t), 1, f) != 1) {
- dbgfnputs("fwrite failed for maple size!");
- res = 0;
- }
- fclose(f);
- f = NULL;
- }
- return res;
- }
- static int hook_bc() {
- pfnCreateProcessW phook = { CreateProcessW_hook };
- winapi_detour create_process = { "Kernel32.dll", "CreateProcessW", (void **)&pCreateProcessW, phook.void_ptr };
- generic_hack bc_inject_group[] = {
- { HACK_WINAPI_DETOUR, &create_process },
- };
- hack bc_inject = { 1, bc_inject_group };
- remove(DUMPINFO_FILE);
- return hack_toggle(&bc_inject, 1);
- }
- #endif
- /* BlackCipher.aes detections --------------------------------------------------------------------------------- */
- static uint32_t maple_pid = 0, maple_dump = 0, maple_base = 0, maple_size = 0;
- #ifndef HSONLY
- typedef union tagpfnReadProcessMemory {
- BOOL(WINAPI *func_ptr)(HANDLE, LPCVOID, LPVOID, SIZE_T, SIZE_T *);
- void *void_ptr;
- } pfnReadProcessMemory;
- static pfnReadProcessMemory pKernelbase_ReadProcessMemory = { 0 };
- static BOOL WINAPI ReadProcessMemory_hook(
- _In_ HANDLE hProcess,
- _In_ LPCVOID lpBaseAddress,
- _Out_ LPVOID lpBuffer,
- _In_ SIZE_T nSize,
- _Out_ SIZE_T *lpNumberOfBytesRead
- ) {
- BOOL res;
- int spoofed = 0;
- uint32_t pid = (uint32_t)GetProcessId(hProcess);
- uint32_t current_pid = (uint32_t)GetCurrentProcessId();
- LPCVOID original_base = lpBaseAddress;
- if (pid == maple_pid || pid == current_pid) {
- #if _DEBUG
- if (!GetConsoleWindow()) {
- FreeConsole();
- win32_console_create();
- }
- #endif
- if (GetProcessId(hProcess) == maple_pid && (uint32_t)lpBaseAddress >= maple_base && (uint32_t)lpBaseAddress < maple_base + maple_size) {
- lpBaseAddress = (LPCVOID)((uint32_t)lpBaseAddress - maple_base + maple_dump);
- spoofed = 1;
- }
- if (GetProcessId(hProcess) == GetCurrentProcessId() && (uint32_t)lpBaseAddress >= self_memory_start && (uint32_t)lpBaseAddress < self_memory_end) {
- lpBaseAddress = (LPCVOID)((uint32_t)lpBaseAddress - self_memory_start + self_memory);
- dbgputs("!!!BC tried to check its own memory!!!");
- spoofed = 1;
- }
- }
- res = pKernelbase_ReadProcessMemory.func_ptr(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead);
- if (spoofed) {
- dbgprintf(
- "ReadProcessMemory(" "\n"
- "\t" "hProcess = %.08X" "\n"
- "\t" "lpBaseAddress = %.08X" "\n"
- "\t" "lpBuffer = %.08X" "\n"
- "\t" "nSize = %lu" "\n"
- "\t" "lpNumberOfBytesRead = %.08X" "\n"
- ")" "\n",
- hProcess,
- original_base,
- lpBuffer,
- nSize,
- lpNumberOfBytesRead
- );
- dbgprintf("lpBaseAddress spoofed to %.08X\n", lpBaseAddress);
- dbgprintf("Return value: %s\n", res ? "TRUE" : "FALSE");
- }
- return res;
- }
- typedef DWORD NTSTATUS;
- typedef LPVOID POBJECT_ATTRIBUTES;
- typedef LPVOID PCLIENT_ID;
- #define STATUS_ACCESS_DENIED 0xC0000022
- typedef union tagpfnNtOpenProcess {
- NTSTATUS(NTAPI *func_ptr)(
- OUT PHANDLE ProcessHandle,
- IN ACCESS_MASK AccessMask,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN PCLIENT_ID ClientId
- );
- void *void_ptr;
- } pfnNtOpenProcess;
- static pfnNtOpenProcess pNtOpenProcess = { 0 };
- static NTSTATUS NTAPI NtOpenProcess_hook(
- OUT PHANDLE ProcessHandle,
- IN ACCESS_MASK AccessMask,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN PCLIENT_ID ClientId
- ) {
- NTSTATUS res;
- uint32_t pid;
- AccessMask |= PROCESS_QUERY_INFORMATION; /* ensures that we'll have permission to get PID */
- res = pNtOpenProcess.func_ptr(ProcessHandle, AccessMask, ObjectAttributes, ClientId);
- pid = (uint32_t)GetProcessId(*ProcessHandle);
- if (!res && pid != maple_pid) {
- dbgprintf("Blocking NtOpenProcess for pid %.08X\n", pid);
- res = STATUS_ACCESS_DENIED;
- *ProcessHandle = NULL;
- }
- return res;
- }
- typedef union tagpfnNtReadVirtualMemory {
- NTSTATUS(NTAPI *func_ptr)(
- IN HANDLE ProcessHandle,
- IN PVOID BaseAddress,
- OUT PVOID Buffer,
- IN ULONG NumberOfBytesToRead,
- OUT PULONG NumberOfBytesReaded OPTIONAL
- );
- void *void_ptr;
- } pfnNtReadVirtualMemory;
- static pfnNtReadVirtualMemory pNtReadVirtualMemory = { 0 };
- static NTSTATUS NTAPI NtReadVirtualMemory_hook(
- IN HANDLE ProcessHandle,
- IN PVOID BaseAddress,
- OUT PVOID Buffer,
- IN ULONG NumberOfBytesToRead,
- OUT PULONG NumberOfBytesReaded OPTIONAL
- ) {
- if (GetProcessId(ProcessHandle) == maple_pid) {
- dbgprintf("Blocking NtReadVirtualMemory for address %.08X\n", BaseAddress);
- return STATUS_ACCESS_DENIED;
- }
- return pNtReadVirtualMemory.func_ptr(ProcessHandle, BaseAddress,
- Buffer, NumberOfBytesToRead, NumberOfBytesReaded);
- }
- static int load_ms_dump_info() {
- FILE *f = NULL;
- int res = 1;
- errno_t err;
- char buf[512] = { 0 };
- err = fopen_s(&f, DUMPINFO_FILE, "rb");
- if (err || !f) {
- strerror_s(buf, 512, err);
- dbgfnprintf("fopen_s failed: %s", buf);
- res = 0;
- }
- if (res) {
- /* dump base */
- if (fread(&maple_dump, sizeof(uint32_t), 1, f) != 1) {
- dbgfnputs("fread failed for dump base!");
- res = 0;
- }
- /* pid */
- if (fread(&maple_pid, sizeof(uint32_t), 1, f) != 1) {
- dbgfnputs("fread failed for pid!");
- res = 0;
- }
- /* maple base */
- if (fread(&maple_base, sizeof(uint32_t), 1, f) != 1) {
- dbgfnputs("fread failed for maple base!");
- res = 0;
- }
- /* maple size */
- if (fread(&maple_size, sizeof(uint32_t), 1, f) != 1) {
- dbgfnputs("fread failed for maple size!");
- res = 0;
- }
- fclose(f);
- f = NULL;
- }
- return res;
- }
- static int patch_bc() {
- pfnReadProcessMemory pReadProcessMemory_hook = { ReadProcessMemory_hook };
- winapi_detour read_process_memory = { "KERNELBASE.dll", "ReadProcessMemory", (void **)&pKernelbase_ReadProcessMemory, pReadProcessMemory_hook.void_ptr };
- const char *ret4 = "C2 04 00";
- memory_patch bc_hash1 = { (uint8_t *)BC_HASH_DETECTION1, ret4 };
- memory_patch bc_hash2 = { (uint8_t *)BC_HASH_DETECTION2, ret4 };
- pfnNtOpenProcess pNtOpenProcess_hook = { NtOpenProcess_hook };
- winapi_detour open_process = { "NTDLL.dll", "NtOpenProcess", (void **)&pNtOpenProcess, pNtOpenProcess_hook.void_ptr };
- pfnNtReadVirtualMemory pNtReadVirtualMemory_hook = { NtReadVirtualMemory_hook };
- winapi_detour read_virtual_memory = { "NTDLL.dll", "NtReadVirtualMemory", (void **)&pNtReadVirtualMemory, pNtReadVirtualMemory_hook.void_ptr };
- generic_hack bc_detection_group[] = {
- { HACK_WINAPI_DETOUR, &read_process_memory },
- { HACK_MEMPATCH, &bc_hash1 },
- { HACK_MEMPATCH, &bc_hash2 },
- { HACK_WINAPI_DETOUR, &open_process },
- { HACK_WINAPI_DETOUR, &read_virtual_memory },
- };
- hack bc_detection = { 5, bc_detection_group };
- if (!hack_toggle(&bc_detection, 1)) {
- return 0;
- }
- return 1;
- }
- #endif
- /* ------------------------------------------------------------------------------------------------------------ */
- static int bypezz_wut() {
- HMODULE ehsvc = NULL;
- char process_name[MAX_PATH] = { 0 };
- int is_black_cipher = 0;
- if (!GetModuleFileNameA(GetModuleHandleA(NULL), process_name, MAX_PATH)) {
- dbgle("Failed to determine process name");
- return 0;
- }
- if (!IsWow64Process(GetCurrentProcess(), &is_wow64)) {
- dbgle("IsWow64Process failed");
- return 0;
- }
- if (StrStrIA(process_name, BLACKCIPHER_EXE)) {
- is_black_cipher = 1;
- }
- /* if we're injected into maple, prepare black cipher injection hook */
- #ifndef NOBCINJECT
- if (!is_black_cipher) {
- if (!hook_bc()) {
- return 0;
- }
- }
- #endif
- dbgprintf("Waiting for ehsvc.dll... ");
- while (!ehsvc) {
- Sleep(100);
- ehsvc = GetModuleHandleA("ehsvc.dll");
- }
- dbgputs("Done!");
- /* dump HS memory */
- hs_memory = dump_module(ehsvc, &hs_memory_start, &hs_memory_end);
- if (!hs_memory) {
- return 0;
- }
- /* dump current process memory */
- #ifdef HSONLY
- module_size_i(GetModuleHandleA(NULL), &self_memory_start, (size_t *)&self_memory_end);
- self_memory_end += self_memory_start;
- self_memory = self_memory_start;
- #else
- self_memory = dump_module(GetModuleHandleA(NULL), &self_memory_start, &self_memory_end);
- if (!self_memory) {
- return 0;
- }
- #endif
- /* now that ehsvc is loaded and dumped, we can initialize the addys */
- hscrc1_ret = HSCRC1;
- hscrc2_ret = HSCRC2;
- hscrc3_ret = HSCRC3;
- hscrc4_ret = HSCRC4;
- #ifndef HSONLY
- mscrc1_ret = MSCRC1;
- mscrc2_ret = MSCRC2;
- #endif
- /* patch HS detections */
- if (!patch_hs()) {
- return 0;
- }
- /* patch mscrc or bc detections depending on what we're injected to */
- #ifndef HSONLY
- if (!is_black_cipher) {
- if (!save_ms_dump_info()) {
- return 0;
- }
- if (!patch_ms()) {
- return 0;
- }
- }
- else {
- dbgputs("Waiting for dump info...");
- while (!load_ms_dump_info()) {
- Sleep(1);
- }
- dbgprintf("MapleStory dump: %.08X\n", maple_dump);
- dbgprintf("MapleStory pid: %.08X\n", maple_pid);
- dbgprintf("MapleStory base: %.08X\n", maple_base);
- if (!patch_bc()) {
- return 0;
- }
- }
- #endif
- /* you'd normally call this from maple's main thread every frame but this is just a bypass */
- cq_process_all();
- #ifndef _DEBUG
- if (is_black_cipher) {
- MessageBoxA(NULL, "BlackCipher should have gone fucking itself now", BYPASS_NAME " v" BYPASS_VERSION, MB_OK | MB_ICONINFORMATION);
- }
- else {
- MessageBoxA(NULL, "wao, bypezz :wut:\n\nmade by Franc[e]sco @ gamekiller.net\n"
- "huge credits to DBlmao who first discovered the BlackCipher checks.", BYPASS_NAME " v" BYPASS_VERSION, MB_OK | MB_ICONINFORMATION);
- }
- #endif
- return 1;
- }
- /*
- displays an error message as a messagebox with a specific MB icon
- followed by the formatted GetLastError message
- */
- static void msgbox_gle(const char *msg, UINT icon) {
- DWORD gle;
- char *gle_msg;
- char buf[512] = { 0 };
- gle = GetLastError();
- if (!gle) {
- return;
- }
- FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, gle,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPSTR)&gle_msg,
- 0, NULL
- );
- sprintf_s(buf, 512, "%s, GLE=%.08X (%lu): %s\n", msg, gle, gle, gle_msg);
- MessageBoxA(NULL, buf, BYPASS_NAME, MB_OK | icon);
- LocalFree(gle_msg);
- }
- /* wrapper for a msgbox_gle call with a MB_ICONERROR icon */
- #define msgbox_gle_error(msg) msgbox_gle(msg, MB_ICONERROR)
- static DWORD WINAPI rundll(HMODULE module) {
- uint32_t res;
- bypass_dll = module;
- #if _DEBUG
- if (!win32_console_create()) {
- msgbox_gle_error("Failed to create console");
- return EXIT_FAILURE;
- }
- #endif
- dbgputs(BYPASS_NAME " v" BYPASS_VERSION);
- dbgputchar('\n');
- if (!cq_init()) {
- return EXIT_FAILURE;
- }
- res = bypezz_wut() ? EXIT_SUCCESS : EXIT_FAILURE;
- cq_destroy();
- return res;
- }
- BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
- (void)reserved;
- if (reason != DLL_PROCESS_ATTACH)
- return TRUE;
- DisableThreadLibraryCalls(module);
- if (!CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)rundll, (LPVOID)module, 0, NULL)) {
- msgbox_gle_error("Failed to start main dll thread.");
- FreeLibraryAndExitThread(module, EXIT_SUCCESS);
- }
- /* I could write de-attach code and dealloc the dumps but it's kinda pointless and I'm too lazy */
- return TRUE;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement