<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: ddupard</title>
    <description>The latest articles on DEV Community by ddupard (@ddupard).</description>
    <link>https://dev.to/ddupard</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3949744%2Fab1a1cf3-7a46-4fa9-92d1-8ac9855809d3.png</url>
      <title>DEV Community: ddupard</title>
      <link>https://dev.to/ddupard</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ddupard"/>
    <language>en</language>
    <item>
      <title>From Source Code to Binary: What Does GCC Actually Do?</title>
      <dc:creator>ddupard</dc:creator>
      <pubDate>Sat, 04 Jul 2026 07:03:24 +0000</pubDate>
      <link>https://dev.to/ddupard/from-source-code-to-binary-what-does-gcc-actually-do-dng</link>
      <guid>https://dev.to/ddupard/from-source-code-to-binary-what-does-gcc-actually-do-dng</guid>
      <description>&lt;p&gt;When we write a C program, we work with high-level concepts like functions, variables, and loops. However, your computer's processor only understands raw binary instructions. The compiler, gcc (GNU Compiler Collection), acts as a universal translator, transforming your human-readable code into machine-executable logic.&lt;/p&gt;

&lt;p&gt;To illustrate this, we use a simple program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello world&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"multiple parameters %s %i %i&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. The Invisible Compilation Journey
&lt;/h3&gt;

&lt;p&gt;gcc is not just a single tool; it is an orchestrator that runs several sequential stages:&lt;/p&gt;

&lt;p&gt;The Preprocessor: It handles directives like #include . It replaces this line with the entire content of the header file, preparing the code for compilation.&lt;/p&gt;

&lt;p&gt;Compilation: The C code is transformed into assembly language, which is a textual representation of machine instructions.&lt;/p&gt;

&lt;p&gt;Assembly: The assembler translates these instructions into binary format (object files .o).&lt;/p&gt;

&lt;p&gt;Linking: This is the crucial final step. Your code uses printf, a function belonging to the standard C library (libc). The linker connects your code to the actual addresses of these functions within the system library.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Anatomy of a Binary: From Source to Execution
&lt;/h3&gt;

&lt;p&gt;After the linking process, gcc generates an ELF File which contains several sections and several compiler-generated functions&lt;/p&gt;

&lt;h4&gt;
  
  
  A. Binary Sections: The Anatomy of the ELF File
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;.init&lt;/code&gt; &amp;amp; &lt;code&gt;.fini&lt;/code&gt;&lt;/strong&gt;: These sections contain code executed before and after your &lt;code&gt;main&lt;/code&gt; function. They handle global setup and teardown.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;.plt&lt;/code&gt; (Procedure Linkage Table)&lt;/strong&gt;: This section acts as a "trampoline" for external library functions (like &lt;code&gt;printf&lt;/code&gt;). Since the exact memory address of &lt;code&gt;libc&lt;/code&gt; is determined at runtime, the &lt;code&gt;.plt&lt;/code&gt; enables dynamic linking.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;.text&lt;/code&gt;&lt;/strong&gt;: This is where your actual code—the &lt;code&gt;main&lt;/code&gt; function and compiler-generated support functions—resides. It is marked as &lt;strong&gt;Read-Only and Executable&lt;/strong&gt; to prevent tampering.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  B. Compiler-Generated Functions
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;gcc&lt;/code&gt; adds several functions to your binary that you never explicitly wrote. These are essential for the program's lifecycle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;_start&lt;/code&gt;&lt;/strong&gt;: This is the real entry point of your program. It is called by the OS kernel. It initializes the environment (arguments, environment variables) and then calls &lt;code&gt;__libc_start_main&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;__libc_start_main&lt;/code&gt;&lt;/strong&gt;: A standard library function that prepares the environment for your &lt;code&gt;main&lt;/code&gt; function and calls it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;register_tm_clones&lt;/code&gt; / &lt;code&gt;deregister_tm_clones&lt;/code&gt;&lt;/strong&gt;: These functions handle Transactional Memory management. They are part of the GCC runtime overhead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;__do_global_dtors_aux&lt;/code&gt;&lt;/strong&gt;: This function is responsible for calling destructors for global objects before the program exits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;frame_dummy&lt;/code&gt;&lt;/strong&gt;: A helper function used to register frame information for exception handling.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  C. Execution Flow: What Happens When You Run &lt;code&gt;./hello&lt;/code&gt;?
&lt;/h4&gt;

&lt;p&gt;When you launch the program from your shell, the following sequence occurs:&lt;/p&gt;

&lt;p&gt;a. &lt;strong&gt;OS Kernel Loading&lt;/strong&gt;: The Linux kernel maps the binary into memory and hands control to the dynamic linker (&lt;code&gt;ld-linux.so&lt;/code&gt;).&lt;br&gt;
b. &lt;strong&gt;&lt;code&gt;_start&lt;/code&gt;&lt;/strong&gt;: The kernel jumps to &lt;code&gt;_start&lt;/code&gt;. It cleans up the stack, sets up the initial registers, and invokes the C library's initialization logic.&lt;br&gt;
c. &lt;strong&gt;Initialization (&lt;code&gt;.init&lt;/code&gt;)&lt;/strong&gt;: The code in the &lt;code&gt;.init&lt;/code&gt; section runs, setting up the runtime environment.&lt;br&gt;
d. &lt;strong&gt;&lt;code&gt;main&lt;/code&gt; Invocation&lt;/strong&gt;: &lt;code&gt;__libc_start_main&lt;/code&gt; calls your &lt;code&gt;main&lt;/code&gt; function.&lt;br&gt;
e. &lt;strong&gt;&lt;code&gt;printf&lt;/code&gt; Execution&lt;/strong&gt;: Inside &lt;code&gt;main&lt;/code&gt;, your code calls &lt;code&gt;printf&lt;/code&gt;. It jumps to the &lt;code&gt;.plt&lt;/code&gt; entry, which resolves the library address and executes the actual print command.&lt;br&gt;
f. &lt;strong&gt;Termination&lt;/strong&gt;: After &lt;code&gt;main&lt;/code&gt; returns, the program invokes &lt;code&gt;__do_global_dtors_aux&lt;/code&gt; (to clean up globals) and the &lt;code&gt;.fini&lt;/code&gt; section, then exits by calling a kernel system call.&lt;/p&gt;
&lt;h5&gt;
  
  
  Summary Table
&lt;/h5&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;Function/Section&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;_start&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Prepare registers and invoke &lt;code&gt;libc&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Init&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Global initializations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Logic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;main&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your custom code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Linkage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.plt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Resolving library functions (&lt;code&gt;printf&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cleanup&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.fini&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Final program shutdown&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  3. The Mechanics of Parameter Passing (System V AMD64 ABI Convention)
&lt;/h3&gt;

&lt;p&gt;In the C programming language, passing arguments between functions does not rely on a "magic" stack, but on a strict convention called the System V AMD64 ABI. To optimize for speed, the gcc compiler prioritizes using CPU registers before resorting to memory (the stack).&lt;/p&gt;

&lt;p&gt;When a function is called, the parameters are placed in the following specific registers, in this exact order:&lt;/p&gt;

&lt;p&gt;rdi: 1st argument&lt;br&gt;
rsi: 2nd argument&lt;br&gt;
rdx: 3rd argument&lt;br&gt;
rcx: 4th argument&lt;br&gt;
r8: 5th argument&lt;br&gt;
r9: 6th argument&lt;/p&gt;

&lt;p&gt;If your function requires more than 6 arguments, the additional parameters are then pushed onto the stack, which is significantly slower.&lt;/p&gt;

&lt;p&gt;See below for some examples of the System V AMD64 ABI mechanism&lt;/p&gt;

&lt;p&gt;In the objdump analysis of the main function, you could observe this sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0000000000401156 &amp;lt;main&amp;gt;:
  401156:   f3 0f 1e fa             endbr64
  40115a:   55                      push   %rbp
  40115b:   48 89 e5                mov    %rsp,%rbp
  40115e:   48 8d 05 9f 0e 00 00    lea    0xe9f(%rip),%rax        # 402004 &amp;lt;_IO_stdin_used+0x4&amp;gt;
  401165:   48 89 c7                mov    %rax,%rdi
  401168:   e8 e3 fe ff ff          call   401050 &amp;lt;puts@plt&amp;gt;
  40116d:   b9 02 00 00 00          mov    $0x2,%ecx
  401172:   ba 01 00 00 00          mov    $0x1,%edx
  401177:   48 8d 05 92 0e 00 00    lea    0xe92(%rip),%rax        # 402010 &amp;lt;_IO_stdin_used+0x10&amp;gt;
  40117e:   48 89 c6                mov    %rax,%rsi
  401181:   48 8d 05 8d 0e 00 00    lea    0xe8d(%rip),%rax        # 402015 &amp;lt;_IO_stdin_used+0x15&amp;gt;
  401188:   48 89 c7                mov    %rax,%rdi
  40118b:   b8 00 00 00 00          mov    $0x0,%eax
  401190:   e8 cb fe ff ff          call   401060 &amp;lt;printf@plt&amp;gt;
  401195:   b8 00 00 00 00          mov    $0x0,%eax
  40119a:   5d                      pop    %rbp
  40119b:   c3                      ret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One of the most interesting aspects revealed by disassembly is GCC's optimization logic. For the simple string 'Hello world\n', the compiler identifies that no formatting is required and replaces the call to the more complex printf with a call to the more efficient puts function. This demonstrates that GCC is not just a translator, but an optimizer that actively refines your code for better performance.&lt;/p&gt;

&lt;p&gt;For the first instruction the compiler fills the register rdi.&lt;/p&gt;

&lt;p&gt;When calling the second printf, we can observe the compiler strictly adhering to the System V ABI. It populates the registers in the following order:&lt;/p&gt;

&lt;p&gt;rdi: Holds the address of the format string.&lt;br&gt;
rsi: Holds the address of the string argument 'test'.&lt;br&gt;
rdx: Holds the first integer (1).&lt;br&gt;
rcx: Holds the second integer (2).&lt;/p&gt;

&lt;p&gt;By analyzing the assembly, we see exactly how the compiler maps your C variables to the CPU's 'highways'."&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Epilogue
&lt;/h3&gt;

&lt;p&gt;In this very short article we explained what gcc does when it compiles a C source code.&lt;br&gt;
By disassembling your own code (with objdump), you precisely see what gcc creates during the compilation process. gcc adds control code (prologues/epilogues) and linking mechanisms (.plt, .got) that are essential for your program to communicate with the operating system. Moreover it follows a strict mechanism for passing arguments.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>computerscience</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Building a comfortable workflow for debugging an old version of the Linux kernel</title>
      <dc:creator>ddupard</dc:creator>
      <pubDate>Mon, 25 May 2026 01:38:52 +0000</pubDate>
      <link>https://dev.to/ddupard/building-a-comfortable-workflow-for-debugging-an-old-version-of-the-linux-kernel-557c</link>
      <guid>https://dev.to/ddupard/building-a-comfortable-workflow-for-debugging-an-old-version-of-the-linux-kernel-557c</guid>
      <description>&lt;p&gt;When you want to work on the Linux kernel, for example to see how an exploit acts (like Dirty COW on kernel 4.7), you need to build a comfortable working environment.&lt;/p&gt;

&lt;p&gt;I use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt; for compiling sources in their original version (with the GCC/LD versions corresponding to the source era).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QEMU&lt;/strong&gt; for running the executables in a virtual machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VS Code&lt;/strong&gt; as a debugger.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Through this article, I will show you how I configured my environment to achieve an efficient setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  1) Compiling source code
&lt;/h2&gt;

&lt;p&gt;The first step is to retrieve the kernel source code.&lt;/p&gt;

&lt;p&gt;For relatively recent versions (beyond 5.10), the simplest way is to download the tar file from &lt;a href="https://www.kernel.org/" rel="noopener noreferrer"&gt;kernel.org&lt;/a&gt;. For older versions, the best solution is to fetch them via git.&lt;/p&gt;

&lt;p&gt;For example, for 4.7, we start by retrieving the tags:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;git ls-remote --tags git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git | grep "v4.7"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then we clone it to get the version without downloading the entire history:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;git clone --depth 1 --branch v4.7 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 4.7&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After a few minutes, you have a &lt;code&gt;4.7/&lt;/code&gt; directory containing a working version of the 4.7 kernel sources.&lt;/p&gt;

&lt;p&gt;However, these sources are not compilable as-is. Compiling a 4.7 kernel (released in 2016) with a modern compiler (GCC 13+) produces compilation errors due to changes in C language standards or security attribute handling. This is why you need to load versions of GCC and LD compatible with these sources (see the table below), and the easiest way to do this is via Docker.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Kernel Version&lt;/th&gt;
&lt;th&gt;Ubuntu Version&lt;/th&gt;
&lt;th&gt;Codename&lt;/th&gt;
&lt;th&gt;Release Date&lt;/th&gt;
&lt;th&gt;Default GCC&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;v2.6.x&lt;/td&gt;
&lt;td&gt;6.06&lt;/td&gt;
&lt;td&gt;Dapper Drake&lt;/td&gt;
&lt;td&gt;June 2006&lt;/td&gt;
&lt;td&gt;GCC 4.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v3.2&lt;/td&gt;
&lt;td&gt;12.04&lt;/td&gt;
&lt;td&gt;Precise Pangolin&lt;/td&gt;
&lt;td&gt;April 2012&lt;/td&gt;
&lt;td&gt;GCC 4.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v3.13&lt;/td&gt;
&lt;td&gt;14.04&lt;/td&gt;
&lt;td&gt;Trusty Tahr&lt;/td&gt;
&lt;td&gt;April 2014&lt;/td&gt;
&lt;td&gt;GCC 4.8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v4.4&lt;/td&gt;
&lt;td&gt;16.04&lt;/td&gt;
&lt;td&gt;Xenial Xerus&lt;/td&gt;
&lt;td&gt;April 2016&lt;/td&gt;
&lt;td&gt;GCC 5.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v4.15&lt;/td&gt;
&lt;td&gt;18.04&lt;/td&gt;
&lt;td&gt;Bionic Beaver&lt;/td&gt;
&lt;td&gt;April 2018&lt;/td&gt;
&lt;td&gt;GCC 7.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v5.4&lt;/td&gt;
&lt;td&gt;20.04&lt;/td&gt;
&lt;td&gt;Focal Fossa&lt;/td&gt;
&lt;td&gt;April 2020&lt;/td&gt;
&lt;td&gt;GCC 9.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v5.15&lt;/td&gt;
&lt;td&gt;22.04&lt;/td&gt;
&lt;td&gt;Jammy Jellyfish&lt;/td&gt;
&lt;td&gt;April 2022&lt;/td&gt;
&lt;td&gt;GCC 11.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v6.8&lt;/td&gt;
&lt;td&gt;24.04&lt;/td&gt;
&lt;td&gt;Noble Numbat&lt;/td&gt;
&lt;td&gt;April 2024&lt;/td&gt;
&lt;td&gt;GCC 13.2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We need to retrieve the Docker container corresponding to the kernel version we are interested in. For 4.7, it is Ubuntu 16.04.&lt;/p&gt;

&lt;p&gt;To search for available containers, there are 2 solutions:&lt;br&gt;
a) Run the command:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;skopeo list-tags docker://docker.io/library/ubuntu&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;you should see something like &lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
    "Repository": "docker.io/library/ubuntu",&lt;br&gt;
    "Tags": [&lt;br&gt;
        "10.04",&lt;br&gt;
        "12.04",&lt;br&gt;
        "12.04.5",&lt;br&gt;
        "12.10",&lt;br&gt;
        "13.04",&lt;br&gt;
        "13.10",&lt;br&gt;
        "14.04",&lt;br&gt;
        "14.04.1",&lt;br&gt;
...&lt;/p&gt;

&lt;p&gt;...then run the command:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo docker pull ubuntu:16.04&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;b) Go to Docker Hub &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52j4gppztvssbvxchx44.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52j4gppztvssbvxchx44.png" alt="Docker Hub" width="800" height="394"&gt;&lt;/a&gt;&lt;br&gt;
and download it.&lt;/p&gt;

&lt;p&gt;After a few minutes, you can run the following command to check that your container was downloaded &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo docker images&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and you should see&lt;/p&gt;

&lt;p&gt;kernel-builder-515:latest   9f311ec05f16        580MB          147MB    U&lt;br&gt;&lt;br&gt;
ubuntu:16.04                1f1a2d56de1d        195MB         46.5MB    U   &lt;/p&gt;

&lt;p&gt;I always favor LTS (Long Term Support) versions like 16.04, because they guarantee library longevity and compilation tool stability, which is critical to avoid linking errors when generating &lt;code&gt;vmlinux&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;See the difference here: ubuntu:16.04 is the raw image we just downloaded, while kernel-builder-515 represents the kernel 5.15 image that I customized to include all the necessary compilation tools. We will now cover this customization step using the Dockerfile.&lt;/p&gt;

&lt;p&gt;To customize the downloaded Docker container, we use a &lt;code&gt;Dockerfile&lt;/code&gt;, here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;### Example for kernel 4.7 (based on Ubuntu 16.04 - Xenial)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ubuntu:16.04&lt;/span&gt;

&lt;span class="c"&gt;### Install compilation dependencies&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    build-essential &lt;span class="se"&gt;\
&lt;/span&gt;    libncurses5-dev &lt;span class="se"&gt;\
&lt;/span&gt;    bison &lt;span class="se"&gt;\
&lt;/span&gt;    flex &lt;span class="se"&gt;\
&lt;/span&gt;    libssl-dev &lt;span class="se"&gt;\
&lt;/span&gt;    libelf-dev &lt;span class="se"&gt;\
&lt;/span&gt;    gcc-5 g++-5 &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; update-alternatives &lt;span class="nt"&gt;--install&lt;/span&gt; /usr/bin/gcc gcc /usr/bin/gcc-5 100

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/linux&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a personal container version, just run the command:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo docker build -t my-ubuntu:16.04 .&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;if we launch sudo docker images, you should see  the following result&lt;/p&gt;

&lt;p&gt;kernel-builder-515:latest   9f311ec05f16        580MB          147MB    U&lt;br&gt;&lt;br&gt;
my-ubuntu:16.04             3aa5b81c120f        822MB          188MB    U&lt;br&gt;&lt;br&gt;
ubuntu:16.04                1f1a2d56de1d        195MB         46.5MB    U   &lt;/p&gt;

&lt;p&gt;You can find other Dockerfile examples at &lt;a href="https://github.com/ddupard/low-level-security-research" rel="noopener noreferrer"&gt;https://github.com/ddupard/low-level-security-research&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have followed all previous steps, you should be able to compile without issues by running these commands in a shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; ~/Desktop/KERNEL/4.7:/build &lt;span class="se"&gt;\&lt;/span&gt;
  my-ubuntu:16.04

make x86_64_defconfig

scripts/config &lt;span class="nt"&gt;--enable&lt;/span&gt; CONFIG_DEBUG_INFO
scripts/config &lt;span class="nt"&gt;--disable&lt;/span&gt; CONFIG_DEBUG_INFO_REDUCED
scripts/config &lt;span class="nt"&gt;--enable&lt;/span&gt; CONFIG_GDB_SCRIPTS
scripts/config &lt;span class="nt"&gt;--enable&lt;/span&gt; CONFIG_DEBUG_KERNEL
scripts/config &lt;span class="nt"&gt;--disable&lt;/span&gt; CONFIG_RANDOMIZE_BASE

make olddefconfig
make scripts_gdb

make &lt;span class="nt"&gt;-j&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;nproc&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;et voila&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa52f4xs6l1dpoifdhshi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa52f4xs6l1dpoifdhshi.png" alt="kernel compilation" width="799" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2) Creating the runtime
&lt;/h2&gt;

&lt;p&gt;This step consists of two parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieving and compiling BusyBox.&lt;/li&gt;
&lt;li&gt;Creating the &lt;code&gt;initramfs.cpio.gz&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike a complete Linux distribution that weighs gigabytes, BusyBox bundles essential utilities (ls, cat, sh, etc.) into a single binary executable.&lt;/p&gt;

&lt;p&gt;We start by creating a shell script (&lt;code&gt;build_busybox.sh&lt;/code&gt;) to download the BusyBox sources and compile them within Docker using &lt;code&gt;my-ubuntu:16.04&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;BUSYBOX_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1.36.1"&lt;/span&gt;
&lt;span class="nv"&gt;BUSYBOX_TAR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"busybox-&lt;/span&gt;&lt;span class="nv"&gt;$BUSYBOX_VERSION&lt;/span&gt;&lt;span class="s2"&gt;.tar.bz2"&lt;/span&gt;
&lt;span class="nv"&gt;BUILD_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/busybox_build"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUSYBOX_TAR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Downloading BusyBox &lt;/span&gt;&lt;span class="nv"&gt;$BUSYBOX_VERSION&lt;/span&gt;&lt;span class="s2"&gt;..."&lt;/span&gt;
    wget &lt;span class="s2"&gt;"https://busybox.net/downloads/&lt;/span&gt;&lt;span class="nv"&gt;$BUSYBOX_TAR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nb"&gt;tar &lt;/span&gt;xvf &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUSYBOX_TAR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"busybox-&lt;/span&gt;&lt;span class="nv"&gt;$BUSYBOX_VERSION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

make defconfig
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s/.*CONFIG_STATIC.*/CONFIG_STATIC=y/'&lt;/span&gt; .config

&lt;span class="c"&gt;### 4. Compilation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Compilation of BusyBox..."&lt;/span&gt;
make &lt;span class="nt"&gt;-j&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;nproc&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
make &lt;span class="nb"&gt;install &lt;/span&gt;&lt;span class="nv"&gt;CONFIG_PREFIX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUILD_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"BusyBox compiled in : &lt;/span&gt;&lt;span class="nv"&gt;$BUILD_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then we launch the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/build &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-w&lt;/span&gt; /build &lt;span class="se"&gt;\&lt;/span&gt;
  my-ubuntu:16.04 &lt;span class="se"&gt;\&lt;/span&gt;
  /bin/bash ./build_busybox.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the compilation fails with the following message indicating that wget and other executables are missing&lt;/p&gt;

&lt;p&gt;sudo docker run -it \&lt;br&gt;
  -v "$(pwd)":/build \&lt;br&gt;
  -w /build \&lt;br&gt;
  my-ubuntu:16.04 \&lt;br&gt;
  /bin/bash ./build_busybox.sh&lt;br&gt;
Téléchargement de BusyBox 1.36.1...&lt;br&gt;
./build_busybox.sh: line 11: wget: command not found&lt;br&gt;
tar: busybox-1.36.1.tar.bz2: Cannot open: No such file or directory&lt;br&gt;
tar: Error is not recoverable: exiting now&lt;/p&gt;

&lt;p&gt;so we need to modify the Dockerfile in order to include these new executables&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ubuntu:16.04&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    build-essential &lt;span class="se"&gt;\
&lt;/span&gt;    gcc &lt;span class="se"&gt;\
&lt;/span&gt;    make &lt;span class="se"&gt;\
&lt;/span&gt;    libncurses5-dev &lt;span class="se"&gt;\
&lt;/span&gt;    libssl-dev &lt;span class="se"&gt;\
&lt;/span&gt;    bc &lt;span class="se"&gt;\
&lt;/span&gt;    bison &lt;span class="se"&gt;\
&lt;/span&gt;    flex &lt;span class="se"&gt;\
&lt;/span&gt;    nano &lt;span class="se"&gt;\
&lt;/span&gt;    git &lt;span class="se"&gt;\
&lt;/span&gt;    cpio &lt;span class="se"&gt;\
&lt;/span&gt;    openssh-client &lt;span class="se"&gt;\
&lt;/span&gt;    wget &lt;span class="se"&gt;\
&lt;/span&gt;    bzip2 &lt;span class="se"&gt;\
&lt;/span&gt;    ca-certificates &lt;span class="se"&gt;\
&lt;/span&gt;    linux-headers-generic &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class="k"&gt;*&lt;/span&gt;


&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /opt&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;git clone https://github.com/radareorg/radare2 &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; radare2/sys/install.sh &lt;span class="nt"&gt;--install&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; radare2

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now we can recreate the container using &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo docker build -t my-ubuntu:16.04 .&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;then we rebuild busybox with the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/build &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-w&lt;/span&gt; /build &lt;span class="se"&gt;\&lt;/span&gt;
  my-ubuntu:16.04 &lt;span class="se"&gt;\&lt;/span&gt;
  /bin/bash ./build_busybox.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F694oirrooyyeo53sgqbe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F694oirrooyyeo53sgqbe.png" alt=" " width="799" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;however the compilation process wil fail with the following message&lt;/p&gt;

&lt;p&gt;CC      miscutils/mt.o&lt;br&gt;
  CC      miscutils/nandwrite.o&lt;br&gt;
  CC      miscutils/partprobe.o&lt;br&gt;
  CC      miscutils/raidautorun.o&lt;br&gt;
  CC      miscutils/readahead.o&lt;br&gt;
  CC      miscutils/runlevel.o&lt;br&gt;
  CC      miscutils/rx.o&lt;br&gt;
  CC      miscutils/seedrng.o&lt;br&gt;
miscutils/seedrng.c:45:24: fatal error: sys/random.h: No such file or directory&lt;/p&gt;

&lt;p&gt;it's because you are compiling a recent version of BusyBox with an old Ubuntu 16.04 base.&lt;br&gt;
in order to solve our problem, we will launch the following commands&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo docker ps -a&lt;br&gt;
in order to get the list of the last docker commands launched&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CONTAINER ID&lt;/th&gt;
&lt;th&gt;IMAGE&lt;/th&gt;
&lt;th&gt;COMMAND&lt;/th&gt;
&lt;th&gt;CREATED&lt;/th&gt;
&lt;th&gt;STATUS&lt;/th&gt;
&lt;th&gt;PORTS NAMES&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;49c7144e4dbb&lt;/td&gt;
&lt;td&gt;my-ubuntu:16.04&lt;/td&gt;
&lt;td&gt;"/bin/bash ./build_b…"&lt;/td&gt;
&lt;td&gt;13 minutes ago&lt;/td&gt;
&lt;td&gt;Exited (0) 10 minutes ago&lt;/td&gt;
&lt;td&gt;mystifying_mayer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;eb9d3d19f3a0&lt;/td&gt;
&lt;td&gt;58aacbfbda6f&lt;/td&gt;
&lt;td&gt;"/bin/bash ./build_b…"&lt;/td&gt;
&lt;td&gt;23 minutes ago&lt;/td&gt;
&lt;td&gt;Exited (0) 23 minutes ago&lt;/td&gt;
&lt;td&gt;wonderful_jemison&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;then&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker start 49c7144e4dbb
&lt;span class="nb"&gt;sudo &lt;/span&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; 49c7144e4dbb /bin/bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to restart the docker environment  (root@49c7144e4dbb:/build#)&lt;br&gt;
then the following commands&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /build/busybox-1.36.1
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s/CONFIG_SEEDRNG=y/CONFIG_SEEDRNG=n/'&lt;/span&gt; .config

make clean
make &lt;span class="nt"&gt;-j&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;nproc&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;compilation should restart and go to the end.&lt;/p&gt;

&lt;p&gt;then we launch the following command to make the install&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;make install CONFIG_PREFIX="$(pwd)/../busybox_build"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;at the end a new directory should appear &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fyxsmkse0un5knc5tjd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fyxsmkse0un5knc5tjd.png" alt=" " width="736" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that BusyBox has copiled, it's time to create initramfs.cpio.gz that sets up the file structure (&lt;code&gt;/proc&lt;/code&gt;, &lt;code&gt;/sys&lt;/code&gt;, etc.) &lt;/p&gt;

&lt;p&gt;we are going to create and lauch a new shell script (create_initramfs.sh)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;BUILD_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/busybox_build"&lt;/span&gt;
&lt;span class="nv"&gt;ROOTFS_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/initramfs_staging"&lt;/span&gt;

&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ROOTFS_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ROOTFS_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUILD_DIR&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ROOTFS_DIR&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt;

&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ROOTFS_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; proc sys dev etc/init.d

&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt; &amp;gt; init
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
echo "--- Système démarré avec succès ---"
exec /bin/sh
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x init

find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-print0&lt;/span&gt; | cpio &lt;span class="nt"&gt;--null&lt;/span&gt; &lt;span class="nt"&gt;-ov&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;newc | &lt;span class="nb"&gt;gzip&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ../initramfs.cpio.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;at the end of its execution, we should see something like &lt;br&gt;
./bin/mknod&lt;br&gt;
./bin/more&lt;br&gt;
./bin/zcat&lt;br&gt;
./bin/pidof&lt;br&gt;
./bin/egrep&lt;br&gt;
./bin/watch&lt;br&gt;
./bin/link&lt;br&gt;
./bin/pwd&lt;br&gt;
./bin/dd&lt;br&gt;
./bin/netstat&lt;br&gt;
./bin/fgrep&lt;br&gt;
./bin/stty&lt;br&gt;
./bin/mt&lt;br&gt;
./bin/gunzip&lt;br&gt;
./proc&lt;br&gt;
./etc&lt;br&gt;
./etc/init.d&lt;br&gt;
./init&lt;br&gt;
5556 blocks&lt;/p&gt;

&lt;p&gt;and a new file in the root directory (initramfs.cpio.gz)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffyg3s2h7jf12x4uze6p9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffyg3s2h7jf12x4uze6p9.png" alt=" " width="736" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;to check that everything is fine , we are going to launch the VM using the following command&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;qemu-system-x86_64 \&lt;br&gt;
  -kernel ./4.7/arch/x86/boot/bzImage \&lt;br&gt;
  -initrd ./initramfs.cpio.gz \&lt;br&gt;
  -append "console=ttyS0 nokaslr" \&lt;br&gt;
  -nographic &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and something like below should appear&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2hxpzfg0zra09ijqy444.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2hxpzfg0zra09ijqy444.png" alt=" " width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;if it happens , congrats your environment is working now&lt;/p&gt;
&lt;h2&gt;
  
  
  3) Debugging setup
&lt;/h2&gt;

&lt;p&gt;To debug the kernel, the base tool is GDB, but it isn't very user-friendly. The idea here is to use VS Code's overlay for GDB.&lt;/p&gt;

&lt;p&gt;First, ensure you compile with debug options in your &lt;code&gt;compile_4.7.sh&lt;/code&gt; script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./scripts/config &lt;span class="nt"&gt;--enable&lt;/span&gt; CONFIG_DEBUG_INFO
./scripts/config &lt;span class="nt"&gt;--disable&lt;/span&gt; CONFIG_DEBUG_INFO_REDUCED
./scripts/config &lt;span class="nt"&gt;--enable&lt;/span&gt; CONFIG_GDB_SCRIPTS
./scripts/config &lt;span class="nt"&gt;--enable&lt;/span&gt; CONFIG_DEBUG_KERNEL
./scripts/config &lt;span class="nt"&gt;--disable&lt;/span&gt; CONFIG_RANDOMIZE_BASE

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;file ./4.7/vmlinux&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(You should see a line containing "with debug_info")&lt;/p&gt;

&lt;p&gt;Then, launch QEMU with the &lt;code&gt;-s&lt;/code&gt; and &lt;code&gt;-S&lt;/code&gt; options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-s&lt;/code&gt;: Opens a GDB server on &lt;code&gt;tcp::1234&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-S&lt;/code&gt;: Freezes QEMU at the first instruction.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;qemu-system-x86_64 \&lt;br&gt;
  -kernel ./4.7/arch/x86/boot/bzImage \&lt;br&gt;
  -initrd ./initramfs.cpio.gz \&lt;br&gt;
  -append "console=ttyS0 nokaslr" \&lt;br&gt;
  -nographic \&lt;br&gt;
  -s -S&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In VS Code, install the &lt;strong&gt;C/C++&lt;/strong&gt; extension from Microsoft and create a &lt;code&gt;.vscode/launch.json&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"configurations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"(gdb) Attacher au Kernel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cppdbg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"launch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"program"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${workspaceFolder}/4.7/vmlinux"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"miDebuggerServerAddress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"localhost:1234"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"miDebuggerPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/bin/gdb"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"setupCommands"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-enable-pretty-printing"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"cwd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${workspaceFolder}"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Debugging Workflow
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Launch QEMU (using your script with &lt;code&gt;-s -S&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;In VS Code, go to the 4.7 directory and launch the "Debug Kernel LKM" configuration.&lt;/li&gt;
&lt;li&gt;This triggers the kernel to start. You can now set breakpoints, view registers, and use the debug console to launch commands like the following&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;-exec info functions&lt;/code&gt;&lt;br&gt;
&lt;code&gt;-exec p/x $rax&lt;/code&gt;&lt;br&gt;
&lt;code&gt;-exec monitor xp/512gx  0x4786000&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffsnsf7tq0aehypb1i6l3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffsnsf7tq0aehypb1i6l3.png" alt=" " width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: If you load an LKM, you must load the symbol file and tell GDB where the source files are located using:&lt;/em&gt;&lt;br&gt;
&lt;code&gt;-exec add-symbol-file /path/to/my_attack.ko ...&lt;/code&gt;&lt;br&gt;
&lt;code&gt;-exec set substitute-path ...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Happy kernel debugging!&lt;/p&gt;


&lt;h2&gt;
  
  
  Appendix: Automation Script
&lt;/h2&gt;

&lt;p&gt;To make the environment setup more efficient, I use a script (&lt;code&gt;run_qemu.sh&lt;/code&gt;) to quickly switch between different kernel versions and automate the LKM injection process for the 5.15 LTS kernel.&lt;/p&gt;

&lt;p&gt;You can save the following code into a file named &lt;code&gt;run_qemu.sh&lt;/code&gt; in your &lt;code&gt;~/Desktop/KERNEL&lt;/code&gt; directory. Make sure to give it execution permissions with &lt;code&gt;chmod +x run_qemu.sh&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# This script runs on the host (Ubuntu) in ~/Desktop/KERNEL&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/Desktop/KERNEL"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"-------------------------------------------------------"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  COGNITIVE FIREWALL LAB - TEST ENVIRONMENT"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"-------------------------------------------------------"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Select the kernel version to test:"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"1) Kernel 4.7  (Dirty COW vulnerable)"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"2) Kernel 4.8  (Intro XDP)"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"3) Kernel 4.9  (Dirty COW patched)"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"4) Kernel 5.15 (LTS)"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"q) Quit"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"-------------------------------------------------------"&lt;/span&gt;

&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Your choice [1-4] : "&lt;/span&gt; choice

&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nv"&gt;$choice&lt;/span&gt; &lt;span class="k"&gt;in
    &lt;/span&gt;1&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"4.7"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;KERNEL_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"./4.7/arch/x86/boot/bzImage"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    2&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"4.8"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;KERNEL_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"./4.8/arch/x86/boot/bzImage"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    3&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"4.9"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;KERNEL_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"./4.9/arch/x86/boot/bzImage"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;        
    4&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"5.15"&lt;/span&gt;
        &lt;span class="nv"&gt;KERNEL_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"./5.15/arch/x86/boot/bzImage"&lt;/span&gt;
        &lt;span class="nv"&gt;LKM2_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"./lkm/poc/my_attack.ko"&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LKM2_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
            &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Building initramfs for Kernel 5.15..."&lt;/span&gt;
            &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; .initramfs_root
            &lt;span class="nb"&gt;cd&lt;/span&gt; .initramfs_root
            zcat ../initramfs.cpio.gz | cpio &lt;span class="nt"&gt;-idmv&lt;/span&gt; &amp;amp;&amp;gt;/dev/null
            &lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="s2"&gt;"../&lt;/span&gt;&lt;span class="nv"&gt;$LKM2_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;

            &lt;span class="c"&gt;# Automatic LKM injection script&lt;/span&gt;
            &lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;' &amp;gt; init
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev 2&amp;gt;/dev/null
if [ -f /my_attack.ko ]; then insmod /my_attack.ko; fi
exec /bin/sh
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;            &lt;span class="nb"&gt;chmod&lt;/span&gt; +x init
            find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-print0&lt;/span&gt; | cpio &lt;span class="nt"&gt;--null&lt;/span&gt; &lt;span class="nt"&gt;-ov&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;newc 2&amp;gt;/dev/null | &lt;span class="nb"&gt;gzip&lt;/span&gt; &lt;span class="nt"&gt;-9&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ../initramfs.cpio.gz
            &lt;span class="nb"&gt;cd&lt;/span&gt; ..
            &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; .initramfs_root
        &lt;span class="k"&gt;fi
        &lt;/span&gt;qemu-system-x86_64 &lt;span class="nt"&gt;-kernel&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KERNEL_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-initrd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/Desktop/KERNEL/initramfs.cpio.gz"&lt;/span&gt; &lt;span class="nt"&gt;-nographic&lt;/span&gt; &lt;span class="nt"&gt;-append&lt;/span&gt; &lt;span class="s2"&gt;"console=ttyS0 loglevel=7 nosmep nosmap nokaslr"&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-S&lt;/span&gt;
        &lt;span class="nb"&gt;exit &lt;/span&gt;0
        &lt;span class="p"&gt;;;&lt;/span&gt;
    q&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;0 &lt;span class="p"&gt;;;&lt;/span&gt;
    &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Invalid choice"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1 &lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="k"&gt;esac&lt;/span&gt;

&lt;span class="c"&gt;# Launch QEMU for versions 1, 2, 3&lt;/span&gt;
qemu-system-x86_64 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-kernel&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KERNEL_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-initrd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/Desktop/KERNEL/initramfs.cpio.gz"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-nographic&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-append&lt;/span&gt; &lt;span class="s2"&gt;"console=ttyS0 nokaslr loglevel=7"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-S&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>linux</category>
      <category>kernel</category>
      <category>security</category>
    </item>
  </channel>
</rss>
