{"id":286,"date":"2025-12-22T14:20:47","date_gmt":"2025-12-22T14:20:47","guid":{"rendered":"https:\/\/haco.club\/?p=286"},"modified":"2025-12-22T14:20:47","modified_gmt":"2025-12-22T14:20:47","slug":"executable-startup-and-initialization","status":"publish","type":"post","link":"https:\/\/haco.zone\/?p=286","title":{"rendered":"Executable Startup And Initialization"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>CRT (C Runtime) &#8220;glue code&#8221;<\/strong> refers to a set of pre-compiled object files (typically <code>crt1.o<\/code>, <code>crti.o<\/code>, <code>crtn.o<\/code>, <code>crtbegin.o<\/code>, and <code>crtend.o<\/code>) that are automatically linked with your program. They &#8220;glue&#8221; the operating system&#8217;s process loader to your <code>main()<\/code> function by handling low-level setup (stack, environment) and high-level initialization (global constructors).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Execution Order Summary:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong><code>_start<\/code><\/strong> (Entry Point)<\/li>\n\n\n\n<li><strong><code>__libc_start_main<\/code><\/strong> (Standard C Library setup)<\/li>\n\n\n\n<li><strong><code>__libc_csu_init<\/code> \/ <code>_init<\/code><\/strong> (Generic initialization hooks)<\/li>\n\n\n\n<li><strong><code>.init_array<\/code><\/strong> (Global constructors\/C++ initializers)<\/li>\n\n\n\n<li><strong><code>main()<\/code><\/strong> (Your code)<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Detailed Explanation<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>1. What is CRT Glue Code?<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The &#8220;glue&#8221; consists of startup files provided by the OS (glibc) and the compiler (GCC\/Clang). They wrap your code to ensure the environment is ready before <code>main<\/code> runs.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>crt1.o<\/code> (Start):<\/strong> Contains the actual entry point symbol <strong><code>_start<\/code><\/strong>. It sets up the very first stack frame and arguments before calling into the C library.<\/li>\n\n\n\n<li><strong><code>crti.o<\/code> (Init Prologue):<\/strong> Contains the &#8220;header&#8221; (prologue) instructions for the <code>_init<\/code> and <code>_fini<\/code> functions.<\/li>\n\n\n\n<li><strong><code>crtn.o<\/code> (Init Epilogue):<\/strong> Contains the &#8220;footer&#8221; (epilogue\/return) instructions for <code>_init<\/code> and <code>_fini<\/code>.<\/li>\n\n\n\n<li><strong><code>crtbegin.o<\/code> \/ <code>crtend.o<\/code>:<\/strong> Provided by the compiler (e.g., GCC) to handle language-specific features like C++ global constructors and destructors.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>2. Execution Order of an Executable<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Here is the step-by-step flow from the moment the kernel hands over control to the moment your code runs:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Step 1: The Kernel &amp; <code>_start<\/code><\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The OS loads the ELF binary and jumps to the address defined as the <strong>Entry Point<\/strong> (usually <code>_start<\/code> inside <code>crt1.o<\/code>).<\/li>\n\n\n\n<li><strong><code>_start<\/code><\/strong> clears the frame pointer (ebp\/rbp) to mark the end of the stack trace.<\/li>\n\n\n\n<li>It grabs <code>argc<\/code>, <code>argv<\/code>, and <code>envp<\/code> (environment variables) from the stack.<\/li>\n\n\n\n<li>It calls the helper function <code>__libc_start_main<\/code>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Step 2: <code>__libc_start_main<\/code> (The Coordinator)<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Located in <code>glibc<\/code>.<\/li>\n\n\n\n<li>It performs critical setup: initializes threading (pthreads), security cookies (stack canary), and registers the cleanup function (<code>rtld_fini<\/code>) for the dynamic linker.<\/li>\n\n\n\n<li><strong>Crucially<\/strong>, it receives pointers to the program&#8217;s initialization functions (often <code>__libc_csu_init<\/code> or similar) and calls them.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Step 3: Initialization Phase (The &#8220;Before Main&#8221; Logic)<\/strong><br>This is where the statement in your prompt comes into play. The CRT initialization code calls these in specific order:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong><code>_init<\/code> function:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Constructed from <code>crti.o<\/code> + system-specific init code + <code>crtn.o<\/code>.<\/li>\n\n\n\n<li>Historically used for setup, though now deprecated in favor of <code>.init_array<\/code>.<\/li>\n\n\n\n<li><em>Executes strictly BEFORE <code>.init_array<\/code>.<\/em><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong><code>.init_array<\/code> processing:<\/strong>\n<ul class=\"wp-block-list\">\n<li>The CRT iterates through the <code>.init_array<\/code> section of the ELF file.<\/li>\n\n\n\n<li>This array contains function pointers to <strong>C++ global constructors<\/strong> and functions marked with <code>__attribute__((constructor))<\/code>.<\/li>\n\n\n\n<li>These execute one by one.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Step 4: <code>main()<\/code><\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Once all <code>.init_array<\/code> functions return, <code>__libc_start_main<\/code> finally calls your <strong><code>main(argc, argv, envp)<\/code><\/strong>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Step 5: Cleanup<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>When <code>main<\/code> returns, <code>exit()<\/code> is called.<\/li>\n\n\n\n<li>This triggers functions in <strong><code>.fini_array<\/code><\/strong> (destructors) and finally <code>_fini<\/code>.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u00a0CRT Symbols\u00a0<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>_start<\/li>\n\n\n\n<li>deregister_tm_clones<\/li>\n\n\n\n<li>register_tm_clones<\/li>\n\n\n\n<li>__do_global_dtors_aux<\/li>\n\n\n\n<li>frame_dummy<\/li>\n\n\n\n<li>__libc_csu_init<\/li>\n\n\n\n<li>__libc_csu_fini<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">AFL++ Instrument<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Unfortunately, in a&nbsp;<strong>stripped binary<\/strong>, you&nbsp;<strong>cannot reliably exclude these specific functions by name<\/strong>&nbsp;because their names are stripped. You&#8217;ll need to rely on&nbsp;<strong>heuristics<\/strong>&nbsp;and&nbsp;<strong>location<\/strong>&nbsp;to identify and exclude them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s how to approach it, along with why it&#8217;s more challenging:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The Challenge with Stripped Binaries<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>No Symbol Names:<\/strong>\u00a0deregister_tm_clones,\u00a0register_tm_clones,\u00a0__do_global_dtors_aux,\u00a0frame_dummy\u00a0are completely unknown.<\/li>\n\n\n\n<li><strong>Variable Location:<\/strong>\u00a0Their exact position and size can vary significantly between compiler versions, optimization levels, and even different target architectures (though you&#8217;re on ARM64).<\/li>\n\n\n\n<li><strong>Interdependence:<\/strong>\u00a0These functions might be called by other CRT code, or call into other parts of the CRT that you also need to exclude.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Heuristics and Exclusion Strategies<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Entry Point Analysis (Still Key):<\/strong>\u00a0As discussed before, the initial analysis of\u00a0_start\u00a0is crucial. It gives you the addresses of\u00a0__libc_csu_init\u00a0and potentially\u00a0__libc_csu_fini. These are the &#8220;entry points&#8221; into the CRT initialization and cleanup sequences.<\/li>\n\n\n\n<li><strong>__libc_csu_init\u00a0and\u00a0__libc_csu_fini:<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>__libc_csu_init:<\/strong>\u00a0This function is where\u00a0deregister_tm_clones\u00a0and\u00a0register_tm_clones\u00a0are often called. If you exclude\u00a0__libc_csu_init\u00a0(by finding its address from\u00a0_start), you are likely excluding the blocks that contain calls to these\u00a0tm_clones\u00a0functions.<\/li>\n\n\n\n<li><strong>__libc_csu_fini:<\/strong>\u00a0This function is the counterpart for cleanup.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>__do_global_dtors_aux:<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>Purpose:<\/strong>\u00a0This is responsible for calling the destructors of global C++ objects.<\/li>\n\n\n\n<li><strong>Heuristic:<\/strong>\u00a0It&#8217;s often called by\u00a0__libc_csu_fini\u00a0or the program&#8217;s exit handler. It typically involves iterating through a list of destructors and calling them. You might be able to identify it by looking for loops that call functions via indirect jumps or register manipulation. This is harder to pinpoint reliably.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>frame_dummy:<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>Purpose:<\/strong>\u00a0This is a compiler-generated function used for stack frame setup, often in functions that require frame pointers (even if\u00a0-fomit-frame-pointer\u00a0is used).<\/li>\n\n\n\n<li><strong>Heuristic:<\/strong>\u00a0It&#8217;s a very small function (often just a few instructions). It&#8217;s usually called by other CRT or compiler-generated functions. It&#8217;s quite hard to identify purely by disassembled code unless it&#8217;s a very obvious pattern and you can trace its caller.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Practical Approach for Stripped Binaries:<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Prioritize the &#8220;Big Wins&#8221;:<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>Entry Point (_start):<\/strong>\u00a0Always exclude.<\/li>\n\n\n\n<li><strong>__libc_csu_init\u00a0and\u00a0__libc_csu_fini:<\/strong>\u00a0Exclude by finding their addresses from\u00a0_start. This is your highest priority, as it covers a lot of CRT code.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>The\u00a0cbz\u00a0Safety Net:<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>This is your primary defense.<\/strong>\u00a0Even if you miss some edge-case CRT blocks, the\u00a0cbz\u00a0instruction in your instrumentation callback will prevent the program from crashing. It&#8217;s extremely cheap performance-wise.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Heuristic Exclusion for\u00a0__do_global_dtors_aux\u00a0and\u00a0frame_dummy\u00a0(Advanced):<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>__do_global_dtors_aux:<\/strong>\u00a0This is the most likely one you might want to\u00a0<em>try<\/em>\u00a0to exclude after the\u00a0csu\u00a0functions. It&#8217;s usually called near the end of the program&#8217;s life. You might identify it by looking for code that loads a function pointer from a list and calls it. This requires some rudimentary static analysis or symbolic execution.<\/li>\n\n\n\n<li><strong>frame_dummy:<\/strong>\u00a0This is the hardest to identify generically. It&#8217;s so small and often inlined or called indirectly. Trying to exclude it without symbols is generally\u00a0<strong>not worth the effort<\/strong>\u00a0compared to the robustness of the\u00a0cbz\u00a0instruction.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Recommendation for Your Stripped Binary:<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Implement the\u00a0cbz\u00a0in your\u00a0bb_callback.<\/strong>\u00a0This is non-negotiable for reliability in stripped binaries.<\/li>\n\n\n\n<li><strong>Implement the\u00a0_start\u00a0and\u00a0__libc_csu_init\/fini\u00a0exclusion using Capstone analysis.<\/strong>\u00a0This will eliminate the most problematic CRT code.<\/li>\n\n\n\n<li><strong>Do NOT try to reliably exclude\u00a0__do_global_dtors_aux\u00a0or\u00a0frame_dummy<\/strong>\u00a0by heuristics alone in a stripped binary. The complexity and unreliability outweigh the benefits. The\u00a0cbz\u00a0will handle these cases gracefully.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">By following this, you get the best of both worlds:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Safety:<\/strong>\u00a0The\u00a0cbz\u00a0prevents crashes from uninitialized pointers.<\/li>\n\n\n\n<li><strong>Performance:<\/strong>\u00a0You avoid instrumenting the main CRT initialization\/cleanup entry points.<\/li>\n\n\n\n<li><strong>Simplicity:<\/strong>\u00a0You don&#8217;t have to build fragile heuristics for every single minor CRT helper function.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">PS: For a single object (executable or shared library), the&nbsp;<strong><code>.init<\/code><\/strong>&nbsp;section is processed and executed before the functions in the&nbsp;<strong><code>.init_array<\/code><\/strong>&nbsp;section.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The typical execution order for initialization routines in an ELF binary is as follows:&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Functions in the\u00a0<strong><code>.preinit_array<\/code><\/strong>\u00a0section (only in executables).<\/li>\n\n\n\n<li>The code in the\u00a0<strong><code>.init<\/code><\/strong>\u00a0section.<\/li>\n\n\n\n<li>Functions pointed to by entries in the\u00a0<strong><code>.init_array<\/code><\/strong>\u00a0section.\u00a0<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">This entire sequence happens as part of the C\/C++ runtime startup (often within a function like&nbsp;<code>__libc_init_array()<\/code>),&nbsp;<strong>before<\/strong>&nbsp;the program&#8217;s&nbsp;<code>main()<\/code>&nbsp;function is called. The&nbsp;<code>.init<\/code>&nbsp;section is a legacy mechanism, and modern libraries and compilers (like GCC using&nbsp;<code>__attribute__((constructor))<\/code>) primarily use the more flexible&nbsp;<code>.init_array<\/code>&nbsp;section.&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>CRT (C Runtime) &#8220;glue code&#8221; refers to a set of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[42],"tags":[30],"class_list":["post-286","post","type-post","status-publish","format-standard","hentry","category-knowledge-base","tag-binary"],"_links":{"self":[{"href":"https:\/\/haco.zone\/index.php?rest_route=\/wp\/v2\/posts\/286","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/haco.zone\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/haco.zone\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/haco.zone\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/haco.zone\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=286"}],"version-history":[{"count":1,"href":"https:\/\/haco.zone\/index.php?rest_route=\/wp\/v2\/posts\/286\/revisions"}],"predecessor-version":[{"id":287,"href":"https:\/\/haco.zone\/index.php?rest_route=\/wp\/v2\/posts\/286\/revisions\/287"}],"wp:attachment":[{"href":"https:\/\/haco.zone\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=286"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/haco.zone\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=286"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/haco.zone\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=286"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}