{"componentChunkName":"component---gatsby-theme-mdx-deck-src-templates-deck-js","path":"/","matchPath":"/*","result":{"data":{"deck":{"id":"27cab91a-d6e2-509a-ba42-c292c8617a1c","body":"var _excluded = [\"components\"];\nfunction _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }, _typeof(obj); }\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\nfunction _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\nfunction _toPropertyKey(arg) { var key = _toPrimitive(arg, \"string\"); return _typeof(key) === \"symbol\" ? key : String(key); }\nfunction _toPrimitive(input, hint) { if (_typeof(input) !== \"object\" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || \"default\"); if (_typeof(res) !== \"object\") return res; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (hint === \"string\" ? String : Number)(input); }\n/* @jsxRuntime classic */\n/* @jsx mdx */\n\nvar theme = _objectSpread(_objectSpread(_objectSpread({}, vsDark), hack), {}, {\n  styles: _objectSpread(_objectSpread(_objectSpread({}, vsDark.styles), hack.styles), {}, {\n    Slide: {\n      display: 'block',\n      paddingTop: '0px',\n      paddingLeft: '2em',\n      paddingRight: '2em',\n      fontSize: '2.5rem',\n      textAlign: 'left'\n    }\n  })\n});\nvar _frontmatter = {};\nvar makeShortcode = function makeShortcode(name) {\n  return function MDXDefaultShortcode(props) {\n    console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n    return mdx(\"div\", props);\n  };\n};\nvar Notes = makeShortcode(\"Notes\");\nvar layoutProps = {\n  theme: theme,\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n    props = _objectWithoutProperties(_ref, _excluded);\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"h1\", null, \"Binary Patching at Runtime\"), mdx(\"h2\", null, \"The basics of in-process hacking via library injection.\"), mdx(\"hr\", null), mdx(\"h2\", null, \"Sections of this talk\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"General Information.\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Library initialization\", mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Windows or Wine\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Linux\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Hooking & Patching Techniques\", mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Signature Scanning\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Detours\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"VTable hooking.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Exception/Signal handler hooks.\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Library Deinitialization\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"A bit on Manual Mapping\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Mitigations & Detection\", mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Regular Injection\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"The challenge of Manual Mappers\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Demo and Questions\")), mdx(\"hr\", null), mdx(\"h2\", null, \"General Information - Definition of library injection\"), mdx(\"p\", null, \"Library injection is the act of forcibly loading a dynamic library (.dll, .so, .dylib) into a process.\\nA dynamic library is a library of code that can be linked into the program at runtime, forcibly loading one\\nallows you to patch or redirect (A.K.A. hook) functionality in memory to modify the running program.\"), mdx(Notes, {\n    mdxType: \"Notes\"\n  }, mdx(\"p\", null, \"What is library injection? Talk about how DLLs normally get loaded.\")), mdx(\"hr\", null), mdx(\"h2\", null, \"General Information - Common scenarios where library injection is used\"), mdx(StepsCustom, {\n    mdxType: \"StepsCustom\"\n  }, mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Patching binaries loaded from ROM.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Avoiding file integrity checks.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Hiding changes made to a binary.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Creating update-resistant patches that use heuristics to patch a binary.\"))), mdx(Notes, {\n    mdxType: \"Notes\"\n  }, mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Patching binaries loaded from ROM.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Avoiding file integrity checks.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Hiding changes made to a binary.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Creating update-resistant patches that use heuristics to patch a binary.\"))), mdx(\"hr\", null), mdx(\"h2\", null, \"General Information - Common use cases for library injection\"), mdx(StepsCustom, {\n    mdxType: \"StepsCustom\"\n  }, mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Game overlays (for example: Discord & Steam Overlays).\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Game Hacks.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Anti-Cheat Software.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Debuggers.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Hooking and replacing system functionality for a specific application (i.e. redirecting network traffic through TOR for example).\"))), mdx(Notes, {\n    mdxType: \"Notes\"\n  }, mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Game overlays (for example: Discord & Steam Overlays).\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Game Hacks.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Anti-Cheat Software.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Debuggers.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Tor sockets\"))), mdx(\"hr\", null), mdx(\"h2\", null, \"General Information - A bit on library injectors\"), mdx(\"p\", null, \"Library injectors aren't explained much in this talk due to it being generally more OS dependant, but here is some general info.\"), mdx(StepsCustom, {\n    mdxType: \"StepsCustom\"\n  }, mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Two main types: regular and manual mapping\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Regular library injectors uses the OS's functionality to load a library in.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Manual mappers allocate or find unused memory for the library and dynamically links it without any interaction with the OS's dynamic linker producing less of a footprint that can be used to detect the library.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Manual mappers may be kernelmode, which means they can perform additional techniques to hide the library.\"))), mdx(Notes, {\n    mdxType: \"Notes\"\n  }, mdx(\"p\", null, \"Manually Mapped injection vs Regular injection.\")), mdx(\"hr\", null), mdx(\"h2\", null, \"General Information - Injected Libraries\"), mdx(StepsCustom, {\n    mdxType: \"StepsCustom\"\n  }, mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Does the actual patching/hooking or instrumentation.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Uses various techniques to find functionality to hook or patch including:\", mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"dlsym (posix) or GetProcAddress (microsoft)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"VTable Traversal (If the target binary was written with C++)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Signature Scanning\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Runtime Type Information (RTTI) and Debug Symbols\"))), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Uses various techniques to hook or patch functions including:\", mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"simple instruction-patching hooks with (or without) trampolines (A.K.A. Detours)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"VTable hooks (if hooking C++ code)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"exception/signal handler hooks (slow but hard to detect)\"))))), mdx(\"hr\", null), mdx(\"h2\", null, \"General Information - So how do we write a injected DLL?\"), mdx(\"p\", null, \"Let's start with what the dll needs to do. First it must:\"), mdx(StepsCustom, {\n    mdxType: \"StepsCustom\"\n  }, mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Start running code when loaded.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Create a new thread so we don't interrupt execution of the process for too long.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Interface with the already running program.\"))), mdx(\"hr\", null), mdx(\"h2\", null, \"Initialization on Windows or Wine\"), mdx(\"p\", null, \"This is fairly easy due to convenient functions that windows provides.\"), mdx(\"hr\", null), mdx(CodeSurfer, {\n    mdxType: \"CodeSurfer\"\n  }, mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"BOOL APIENTRY DllMain(HMODULE hModule,\\n    DWORD  ul_reason_for_call,\\n    LPVOID lpReserved\\n)\\n{\\n    switch (ul_reason_for_call)\\n    {\\n        case DLL_PROCESS_ATTACH:\\n            OnProcessAttach(hModule, lpReserved);\\n            break;\\n        case DLL_PROCESS_DETACH:\\n            OnProcessDetach();\\n            break;\\n    }\\n    return TRUE;\\n}\\n\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\",\n    \"metastring\": \"2[5:29],8[14:31]\",\n    \"2[5:29],8[14:31]\": true\n  }, \"BOOL APIENTRY DllMain(HMODULE hModule,\\n    DWORD  ul_reason_for_call,\\n    LPVOID lpReserved\\n)\\n{\\n    switch (ul_reason_for_call)\\n    {\\n        case DLL_PROCESS_ATTACH:\\n            OnProcessAttach(hModule, lpReserved);\\n            break;\\n        case DLL_PROCESS_DETACH:\\n            OnProcessDetach();\\n            break;\\n    }\\n    return TRUE;\\n}\\n\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\",\n    \"metastring\": \"1[23:37],9[29:35]\",\n    \"1[23:37],9[29:35]\": true\n  }, \"BOOL APIENTRY DllMain(HMODULE hModule,\\n    DWORD  ul_reason_for_call,\\n    LPVOID lpReserved\\n)\\n{\\n    switch (ul_reason_for_call)\\n    {\\n        case DLL_PROCESS_ATTACH:\\n            OnProcessAttach(hModule, lpReserved);\\n            break;\\n        case DLL_PROCESS_DETACH:\\n            OnProcessDetach();\\n            break;\\n    }\\n    return TRUE;\\n}\\n\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"void OnProcessAttach(HMODULE module,LPVOID imageInfo){\\n    TCHAR szModPath[MAX_PATH + 1];\\n    szModPath[0] = _T('\\\\0');\\n    GetModuleFileName(module, szModPath, MAX_PATH);\\n    if (strlen(szModPath) > 0) {\\n        //Create a new thread for running the code.\\n        CreateThread(NULL, 0, MainThread, module, 0, NULL);\\n        return;\\n    }else{\\n        // We are manually mapped, this will be covered later.\\n    }\\n}\\n\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\",\n    \"metastring\": \"1[22:35],2:4\",\n    \"1[22:35],2:4\": true\n  }, \"void OnProcessAttach(HMODULE module,LPVOID imageInfo){\\n    TCHAR szModPath[MAX_PATH + 1];\\n    szModPath[0] = _T('\\\\0');\\n    GetModuleFileName(module, szModPath, MAX_PATH);\\n    if (strlen(szModPath) > 0) {\\n        //Create a new thread for running the code.\\n        CreateThread(NULL, 0, MainThread, module, 0, NULL);\\n        return;\\n    }else{\\n        // We are manually mapped, this will be covered later.\\n    }\\n}\\n\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\",\n    \"metastring\": \"3,5[9:29]\",\n    \"3,5[9:29]\": true\n  }, \"void OnProcessAttach(HMODULE module,LPVOID imageInfo){\\n    TCHAR szModPath[MAX_PATH + 1];\\n    szModPath[0] = _T('\\\\0');\\n    GetModuleFileName(module, szModPath, MAX_PATH);\\n    if (strlen(szModPath) > 0) {\\n        //Create a new thread for running the code.\\n        CreateThread(NULL, 0, MainThread, module, 0, NULL);\\n        return;\\n    }else{\\n        // We are manually mapped, this will be covered later.\\n    }\\n}\\n\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"7\": true,\n    \"className\": \"language-cpp\",\n    \"metastring\": \"7\"\n  }, \"void OnProcessAttach(HMODULE module,LPVOID imageInfo){\\n    TCHAR szModPath[MAX_PATH + 1];\\n    szModPath[0] = _T('\\\\0');\\n    GetModuleFileName(module, szModPath, MAX_PATH);\\n    if (strlen(szModPath) > 0) {\\n        //Create a new thread for running the code.\\n        CreateThread(NULL, 0, MainThread, module, 0, NULL);\\n        return;\\n    }else{\\n        // We are manually mapped, this will be covered later.\\n    }\\n}\\n\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"10\": true,\n    \"className\": \"language-cpp\",\n    \"metastring\": \"10\"\n  }, \"void OnProcessAttach(HMODULE module,LPVOID imageInfo){\\n    TCHAR szModPath[MAX_PATH + 1];\\n    szModPath[0] = _T('\\\\0');\\n    GetModuleFileName(module, szModPath, MAX_PATH);\\n    if (strlen(szModPath) > 0) {\\n        //Create a new thread for running the code.\\n        CreateThread(NULL, 0, MainThread, module, 0, NULL);\\n        return;\\n    }else{\\n        // We are manually mapped, this will be covered later.\\n    }\\n}\\n\"))), mdx(Notes, {\n    mdxType: \"Notes\"\n  }, mdx(\"p\", null, \"Explain what each snippet does.\")), mdx(\"hr\", null), mdx(\"h2\", null, \"Initialization on Linux\"), mdx(\"p\", null, \"This is a little more difficult as we have to do a lot of the work ourselves.\"), mdx(VideoCustom, {\n    src: \"https://backstore.fra1.digitaloceanspaces.com/dllInjectionTalk/discord_demo.m4v\",\n    widthPercent: 75,\n    mdxType: \"VideoCustom\"\n  }), mdx(Notes, {\n    mdxType: \"Notes\"\n  }, mdx(\"p\", null, \"Talk about patching discord krisp.\")), mdx(\"hr\", null), mdx(CodeSurfer, {\n    mdxType: \"CodeSurfer\"\n  }, mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"__attribute__((constructor))\\nvoid init(void){\\n    //For each phdr call findCurrentModule with the callback OnProcessAttach as a parameter.\\n    dl_iterate_phdr(findCurrentModule,OnProcessAttach);\\n    OnProcessAttach(NULL);\\n}\\n\\n__attribute__((destructor))\\nvoid deinit(void){\\n    OnProcessDetach();\\n}\\n\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\",\n    \"metastring\": \"1,8\",\n    \"1,8\": true\n  }, \"__attribute__((constructor))\\nvoid init(void){\\n    //For each phdr call findCurrentModule with the callback OnProcessAttach as a parameter.\\n    dl_iterate_phdr(findCurrentModule,OnProcessAttach);\\n    OnProcessAttach(NULL);\\n}\\n\\n__attribute__((destructor))\\nvoid deinit(void){\\n    OnProcessDetach();\\n}\\n\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\",\n    \"metastring\": \"4[5:19]\",\n    \"4[5:19]\": true\n  }, \"__attribute__((constructor))\\nvoid init(void){\\n    //For each phdr call findCurrentModule with the callback OnProcessAttach as a parameter.\\n    dl_iterate_phdr(findCurrentModule,OnProcessAttach);\\n    OnProcessAttach(NULL);\\n}\\n\\n__attribute__((destructor))\\nvoid deinit(void){\\n    OnProcessDetach();\\n}\\n\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\",\n    \"metastring\": \"4[21:38]\",\n    \"4[21:38]\": true\n  }, \"__attribute__((constructor))\\nvoid init(void){\\n    //For each phdr call findCurrentModule with the callback OnProcessAttach as a parameter.\\n    dl_iterate_phdr(findCurrentModule,OnProcessAttach);\\n    OnProcessAttach(NULL);\\n}\\n\\n__attribute__((destructor))\\nvoid deinit(void){\\n    OnProcessDetach();\\n}\\n\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\",\n    \"metastring\": \"4[39:54]\",\n    \"4[39:54]\": true\n  }, \"__attribute__((constructor))\\nvoid init(void){\\n    //For each phdr call findCurrentModule with the callback OnProcessAttach as a parameter.\\n    dl_iterate_phdr(findCurrentModule,OnProcessAttach);\\n    OnProcessAttach(NULL);\\n}\\n\\n__attribute__((destructor))\\nvoid deinit(void){\\n    OnProcessDetach();\\n}\\n\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"int findCurrentModule(struct dl_phdr_info * info, size_t size, void * data){\\n    //convert the parameter to a callable function pointer.\\n    void (callback*)(void*) = reinterperet_cast<void (*)(void*)>(data);\\n\\n    //Get the base of the shared object\\n    unsigned char * base = (unsigned char *)info->dlpi_addr;\\n\\n    //get the name of the shared object\\n    const char * soname = info->dlpi_name;\\n\\n    //skip the main executable\\n    if(info->dlpi_name == NULL || info->dlpi_name[0] == 0x00)\\n        return 0;\\n\\n    //Loop over the sections of the shared object\\n    for (unsigned int j = 0; j < info->dlpi_phnum; j++) {\\n        const ElfW(Phdr) *phdr = &info->dlpi_phdr[j];\\n        if (phdr->p_type == PT_LOAD) {\\n            unsigned char *beg = base + phdr->p_vaddr;\\n            size_t msize = phdr->p_memsz;\\n\\n            //If one contains this function, then we know it is this library.\\n            if((reinterpret_cast<uintptr_t>(beg) < reinterpret_cast<uintptr_t>(findCurrentModule)) \\n                && (reinterpret_cast<uintptr_t>(beg) + msize > reinterpret_cast<uintptr_t>(findCurrentModule))){\\n                \\n                //Call the callback with a handle to ourself.\\n                callback(dlopen(soname,RTLD_NOLOAD));\\n\\n                //Stop iterating.\\n                return 1;\\n            }\\n        }\\n    }\\n    return 0;\\n}\\n\")), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"void * currentModule = NULL;\\n\\nvoid OnProcessAttach(void* module){\\n    if(currentModule != NULL)\\n        return;\\n    currentModule = module;\\n    if(currentModule != NULL){\\n        pthread_t thread;\\n        pthread_create(&thread,NULL,MainThread,currentModule);\\n        pthread_detach(thread);\\n    }else{\\n        // We are Manually Mapped, this will be covered later.\\n    }\\n}\\n\"))), mdx(Notes, {\n    mdxType: \"Notes\"\n  }, mdx(\"p\", null, \"Explain what each snippet does.\")), mdx(\"hr\", null), mdx(\"h2\", null, \"Hooking and Patching Techniques\"), mdx(\"p\", null, \"Once we are initialized we can start using various internal techniques to locate, hook and patch functionality of the target.\"), mdx(\"hr\", null), mdx(\"h2\", null, \"Hooking and Patching Techniques - Signature Scanning\"), mdx(\"p\", null, \"Signature scanning is the process of scanning for a pattern of bytes using a mask and then applying an offset to the found address.\\nIt can be used to find pointers to variables, and addresses of functions in the target executable in an update-resistant manner.\"), mdx(\"p\", null, \"Here is an example of a signature, mask and offset (for the check in discord_krisp.node (on linux)):\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\"\n  }, \"Signature: \\\\x85\\\\xC0\\\\x74\\\\x48\\\\x48\\\\x8D\\nMask: xxxxxx\\nOffset: -54\\n\")), mdx(\"p\", null, \"The mask consists of the characters 'x' and '?', if the coresponding character to a specific byte is '?' that character is not checked.\\nThere are more advanced versions of this technique that use hashes or checksums and bitfields to represent the signature and mask respectively.\"), mdx(\"hr\", null), mdx(\"h2\", null, \"Hooking and Patching Techniques - Detours\"), mdx(\"p\", null, \"Detours are the simplest type of hook you can do, you simply patch the instructions to call your code instead.\\nThis also means they're the easiest to detect.\"), mdx(\"hr\", null), mdx(\"h2\", null, \"Hooking and Patching Techniques - VTable Hooking/Traversal\"), mdx(\"p\", null, \"VTables are highly ABI (Application Binary Interface) dependent, and the ABI is highly OS dependant.\"), mdx(\"p\", null, \"A VTable is a table of pointers to 'virtual' functions in a C++ class residing in a binary.\\nYou can copy a vtable to a new chunk of memory then alter the pointers in an instance of a class to point to your new copy which you can change to point to your code.\\nVTables can be nested on some systems, which will require pointer traversal, or combined sequentially on others.\"), mdx(\"hr\", null), mdx(\"h2\", null, \"Hooking and Patching Techniques - VTable Hooking/Traversal (Cont.)\"), mdx(\"p\", null, \"Here is an example disassembly of the Mac OSX version of the IVClient class's implementation's vtable in Valve Software's Counter Strike: Global Offensive:\"), mdx(CenterCustom, {\n    mdxType: \"CenterCustom\"\n  }, mdx(\"img\", {\n    \"src\": \"https://i.imgur.com/YCnbeKH.png\",\n    \"alt\": \"IVClient vtable\"\n  })), mdx(\"hr\", null), mdx(\"h2\", null, \"Hooking and Patching Techniques - Exception/Signal Handler Hooks\"), mdx(\"p\", null, \"Exception and Signal handler hooks are pretty clever. They exploit the OS's error and debugging features to hook functions without altering memory.\\nYou create a exception when the memory you want to hook is accessed (usually through memory permissions) and catch the error when it gets thrown to hook that code.\\nThese types of hooks are very hard to detect because they don't alter memory and look exactly like regular error handlers.\"), mdx(\"p\", null, \"On Windows this can be done with Virtual Exception Handlers (VEH) and the PAGE_GUARD flag for example.\\nOne of the major downsides of these is they are MUCH slower to execute than other hook methods.\"), mdx(\"hr\", null), mdx(\"h2\", null, \"Library Deinitialization\"), mdx(\"p\", null, \"The steps for library deinitialization are as follows:\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Signal all running threads in your library that the library is about to be unloaded.\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Have those threads undo the hooks and de-interface with the running application.\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"When all threads have exited except the thread that intially signaled for the library to be unloaded follow the steps on the following slide coresponding to your OS.\")), mdx(\"hr\", null), mdx(\"h2\", null, \"Library Deinitialization (Cont.) - Windows\"), mdx(\"p\", null, \"Regular Injection:\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Call FreeLibraryAndExitThread\")), mdx(\"p\", null, \"Manually Mapped:\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Execute a ROP chain that does the following.\", mdx(\"ol\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"run RtlSecureZeroMemory on the current dll's address space.\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"run VirtualFree on the current dll's address space.\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"call ExitThread.\")))), mdx(\"hr\", null), mdx(\"h2\", null, \"Library Deinitialization (Cont.) - Linux\"), mdx(\"p\", null, \"Regular Injection:\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Call dlclose on your handle to the current shared object.\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Execute a ROP chain that does the following.\", mdx(\"ol\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"call dlclose on the current shared object's handle (yes, you do this twice).\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"call pthread_exit.\")))), mdx(\"p\", null, \"Manually Mapped:\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Execute a ROP chain that does the following.\", mdx(\"ol\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"call explicit_bzero on the current shared object's address space.\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"call munmap on the current shared object's address space.\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"call pthread_exit.\")))), mdx(\"hr\", null), mdx(\"h2\", null, \"Mitigations against regular library injection\"), mdx(\"p\", null, \"There is some good reference material on this on \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://www.ired.team/offensive-security/defense-evasion/preventing-3rd-party-dlls-from-injecting-into-your-processes\"\n  }, \"Red Team Notes\"), \".\\nThe best way to avoid dll injection is to establish a secure chain of trust from the UEFI all the way to the application level.\\nThere are some things you can do outside of this to make it more challenging however. These include:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Kernelmode syscall hooks that prevent library injection of unknown libraries.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Using library injection to hook the functions required for library injection in other processes and preventing unknown libraries from being injected.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"On linux, you can use a custom build of ld-linux.so that doesn't support the LD_PRELOAD environment variable, or checks to see if the binary is signed by you before loading.\")), mdx(\"hr\", null), mdx(\"h2\", null, \"A bit on Manual Mapping\"), mdx(\"p\", null, \"Manually mapped libraries appear to be normal chunks of allocated memory or in some cases they are appended on to the end of other loaded libraries' memory.\\nThis is a rather difficult technique that I'm not going to go into in this talk but this means they are very difficult to detect.\\nThere are no real good mitigations for manually mapped injected libraries except:\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Scanning for executable chunks of memory that aren't associated with your program.\", mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"this won't catch libraries mapped into extra space in existing executable pages.\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Validating your entire program's address space periodically against a database of known threats.\", mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"this won't work if your attacker has used a kernelmode manual mapper, or if it's a new threat or if your attacker is using something like Intel SGX.\")))), mdx(\"hr\", null), mdx(\"h2\", null, \"A bit on Manual Mapping (Cont.)\"), mdx(\"ol\", {\n    \"start\": 3\n  }, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Using library injection to hook library calls and prevent other processes from manually mapping into your process.\", mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"this won't work if your attacker has used a kernelmode manual mapper.\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Using kernelmode hooks to hook syscalls and prevent other processes from manually mapping into your process.\", mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"this won't work if your attacker has used a kernelmode manual mapper.\")))), mdx(\"hr\", null), mdx(\"h2\", null, \"Reference Links those who would like to learn more.\"), mdx(\"p\", null, \"If you want to read more about manual mapping I'd check out \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://www.codeproject.com/Tips/430684/Loading-Win-DLLs-manually-without-LoadLibrary\"\n  }, \"this code project article\"), \".\\nAlso there's a wealth of information on in-memory hacking on \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://unknowncheats.me\"\n  }, \"UnknownCheats\"), \" and the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://web.archive.org/web/sitemap/gamedeception.net\"\n  }, \"Game Deception\"), \" archive.\\nThere may also be some useful information on the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://wiki.alliedmods.net\"\n  }, \"AlliedModders Wiki\"), \".\"), mdx(\"hr\", null), mdx(\"h2\", null, \"Demo\"), mdx(\"hr\", null), mdx(\"h2\", null, \"Questions?\"));\n}\n;\nMDXContent.isMDXComponent = true;"}},"pageContext":{"matchPath":"/*","id":"27cab91a-d6e2-509a-ba42-c292c8617a1c","slug":"","title":"Binary Patching at Runtime"}},"staticQueryHashes":[]}