[{"content":"Bismillah, and peace and blessings upon the Messenger of Allah, and upon his family and companions and those who follow him.\nPraise be to Allah, Lord of the worlds, by whose favor and guidance the Entry P01NT workshop has been completed. I ask Allah to record for you beneficial knowledge and righteous deeds through it, and that it be a good beginning for you.\nThe Road Ahead Reverse engineering is not merely reading articles; it is practice, experimentation, and building muscle memory in handling tools and analyzing code. Accordingly, we have prepared a simple roadmap for you:\n1. Practice via Crackmes Proceed to the platform crackmes.one, a vast library of programs specifically designed for reverse engineering practice. Begin by applying what you have learned in a progressive manner:\nBuilding the foundation: Solve 10 simple challenges (level 1 - 2) to solidify your use of IDA and x64dbg. Understanding algorithms: Solve 10 intermediate challenges (level 2 - 4) to practice encryption and validation algorithms. Bypassing protections: Solve 10 advanced challenges (level 4 - 6) to test your ability to handle code obfuscation techniques and debugger detection (Anti-Debugging). 2. Professional Challenges and Methodology (Just-in-Time Learning) After surpassing the crackmes stage, it is time to move on to challenges that emulate real-world malware, most notably the Flare-On challenges.\nAt this stage, you will inevitably encounter techniques and methods you have never heard of before. Here you must not be discouraged; rather, you should employ the Just-in-Time Learning methodology. I have discussed this methodology in detail in the following article: How to Learn Reverse Engineering with Just-in-Time.\nSummary of the methodology: Do not attempt to learn everything theoretically in advance. Begin with analysis, and when you encounter a technique you are unfamiliar with, stop, research it and study it, then return immediately to apply it and dismantle the challenge.\nWhat\u0026rsquo;s Next? God willing, I am currently working on preparing an upcoming workshop dedicated to studying and solving Flare-On challenges. I will begin with you from the earliest edition, Flare-On 2014, progressing gradually in difficulty step by step, and together we will build a strong professional portfolio in this field. The matter requires some time for preparation and setting up the lab environment, so stay tuned for it soon!\nFinally, do not forget me, my parents, and our oppressed brethren in all lands in your righteous supplications.\nAnd peace be upon you, and the mercy of Allah and His blessings.\n","permalink":"https://outofsrvc.github.io/entry-p01nt/en/posts/2026-03-26-after-that/","summary":"\u003cp\u003eBismillah, and peace and blessings upon the Messenger of Allah, and upon his family and companions and those who follow him.\u003c/p\u003e\n\u003cp\u003ePraise be to Allah, Lord of the worlds, by whose favor and guidance the \u003cstrong\u003eEntry P01NT\u003c/strong\u003e workshop has been completed. I ask Allah to record for you beneficial knowledge and righteous deeds through it, and that it be a good beginning for you.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"the-road-ahead\"\u003eThe Road Ahead\u003c/h2\u003e\n\u003cp\u003eReverse engineering is not merely reading articles; it is practice, experimentation, and building muscle memory in handling tools and analyzing code. Accordingly, we have prepared a simple roadmap for you:\u003c/p\u003e","title":"0xB. After That"},{"content":"Bismillah\nIn this article, we will solve a simple lab challenge that relies entirely on dynamic analysis using the x64dbg debugger. We assess that the exercise demonstrates how to bypass anti-debugging mechanisms and how to patch the program\u0026rsquo;s execution flow so that it accepts any key we provide.\nLab environment setup: The executable for this lab can be downloaded from the following link dyn4m1c_cr4ckm3 in the course repository. Archive password: p01nt\n1. Reconnaissance To begin, we open a command prompt (CMD) and run the program to observe its initial output.\nFigure (1)\nWe observe that the program requires an argument (key) to operate.\nWhen inspecting the strings section using the PE-Bear tool, we note an interesting message indicating debugger detection.\nFigure (2)\nThis clearly indicates that a protection routine exists within the code that checks whether the program is running under a debugging environment. By examining the import functions (Imports), we identify the following function:\nFigure (3)\nThe IsDebuggerPresent function is a Windows API responsible for detecting whether the program is running inside a debugger. We treat this information as our first pivot point.\n2. Debugging Environment Setup (x64dbg Setup) We now load the program into x64dbg. Since the program requires an argument to be passed at launch, we must inform the debugger accordingly:\nFrom the top menu, click File -\u0026gt; Change Command Line. Append a test word after the program path, for example test_key. Figure (4)\nClick OK, then press the shortcut Ctrl + F2 to restart the program and apply the command line. We then press F9 (Run) to let the program execute the initial system routines until it halts at the program\u0026rsquo;s main entry point (Entry Point), where the program name will appear in the comments.\nFigure (5)\n3. Bypassing Anti-Debugging We now seek to locate the point where the program checks for the presence of a debugger in order to neutralize it.\nRight-click inside the CPU window (code view). Figure (6)\nSelect: Search for -\u0026gt; Current Module -\u0026gt; String References.\nIn the strings window that appears, search for the Debugger detected message and double-click it to navigate to its location in the code.\nFigure (7)\nIf we examine the instructions preceding this message, we observe a call to the IsDebuggerPresent function, immediately followed by a test of the result to determine whether we are operating under a debugger, and subsequently a conditional jump (je - Jump if Equal).\nPatching Operation: We will now manipulate this conditional jump to invert the logic entirely.\nSingle-click on the je instruction, then press the Space (spacebar) key to open the Edit Instruction window. Figure (8)\nChange the instruction from je (jump if equal) to jne (jump if not equal). Figure (9)\nWe confirm the appearance of the message Instruction encoded successfully at the bottom, indicating that the modification was successfully applied in memory. With this, we have effectively blinded the program, and it will no longer detect that we are analyzing it!\n4. Analysis of the Validation Routine and Final Patching (The Core Logic) We return to the strings window (String References) once again. This time, we search for the success message and navigate to it.\nFigure (10)\nExamining the code preceding the success message, we observe a call to the strcmp function (the well-known routine that compares two strings: the original key and the key we supplied).\nFigure (11)\nWe click on the call instruction for strcmp and press F2 to set a breakpoint at it (the address will turn red).\nWe now press F9 (Run) one or more times until program execution reaches this breakpoint. Note: The program will successfully bypass the debugger check thanks to our earlier modification, which can be observed in the CMD window accompanying x64dbg.\nFigure (12)\nLeaking the Key Immediately before the strcmp call is executed, if we examine the registers window or the stack, we will see that two values were passed to the function:\nThe test key we entered (test_key). The correct original key stored in memory! Figure (13)\nModifying the Jump Logic (Forcing Success) We now press F8 (Step Over) to execute and skip the comparison function. Immediately after the comparison function, we find a test eax, eax instruction followed by a conditional jump jne (which would jump to the failure message because our key is incorrect).\nFigure (14)\nWe perform another patch here: click on jne and press Space, then change it to je. We press F8 to continue. We observe that the Zero Flag (ZF) equals zero, and because we changed the instruction to je, the program will not take the failure jump; instead it falls through to the success message.\nFigure (15)\nWe continue pressing F8 until we reach the memset call or the end of the procedure.\nFigure (16)\nIf we take a look at the CMD window now:\nFigure (17)\nWe have now successfully applied the concept of patching, because the program displayed the \u0026ldquo;success\u0026rdquo; message despite the fact that the key we entered (test_key) was incorrect!\n5. Confirming the Original Key If we wish to verify our work without patching, we can take the original key we discovered in memory during the analysis prior to the strcmp call, and run the program normally from the CMD while passing this key to it.\nFigure (18)\nCongratulations! You have just reverse engineered a program, bypassed its anti-debugging protection, modified its program logic, and successfully extracted the secret key.\n","permalink":"https://outofsrvc.github.io/entry-p01nt/en/posts/2026-03-25-dynamic/","summary":"\u003cp\u003eBismillah\u003c/p\u003e\n\u003cp\u003eIn this article, we will solve a simple lab challenge that relies entirely on dynamic analysis using the x64dbg debugger. We assess that the exercise demonstrates how to bypass anti-debugging mechanisms and how to patch the program\u0026rsquo;s execution flow so that it accepts any key we provide.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eLab environment setup: The executable for this lab can be downloaded from the following link \u003ca href=\"https://github.com/outofsrvc/entry-p01nt/blob/main/assets/binaries/dyn4m1c_cr4ckm3.7z\"\u003edyn4m1c_cr4ckm3\u003c/a\u003e in the course repository. Archive password: \u003cstrong\u003ep01nt\u003c/strong\u003e\u003c/p\u003e","title":"0xA. Dynamic Lab"},{"content":"Bismillah\nIn this article, we will solve a simple lab challenge that relies entirely on static analysis (Static Analysis). The objective here is to apply the concepts learned previously to decrypt the flag hidden within the program.\nLab environment setup: You may download the executable for this lab from the following link 5t4t1c_cr4ckm3 in the course repository. The archive password is: p01nt\nTo open this file you must open it inside a VM. Although I am the one who designed this file, never trust the cyber community. We will run the file with the following command\n{: .shadow .rounded .mx-auto .d-block} Figure (1)\n1. Initial Triage To begin, we open the program using Detect It Easy (DIE) to identify the program\u0026rsquo;s architecture, programming language, and whether it is packed or not.\nFigure (2)\nAs seen in the image, the program runs on a 32-bit architecture, was written in the C language, and was compiled using the GCC compiler. The file type is a Windows executable (PE32), and there is no indication of any packer being used.\nWe then move to PE-Bear to take a quick look at the header sections. After confirming that the program is an EXE, we focus on the Strings and Imports sections with the aim of finding any clear indicator of the Flag.\nFigure (3)\nAfter searching, we discover that the Flag is not present as plaintext, which means it has been concealed or encrypted (Obfuscation).\n2. Analysis Inside IDA Pro Now we open the executable inside IDA Pro to begin analyzing the code. The program will automatically recognize the file\u0026rsquo;s architecture and disassemble it.\nFigure (4)\nExtracting Strings We begin by searching for any interactive messages that help us locate the verification logic. We press the Shift + F12 shortcut to open the Strings Window, and search for the phrase that appears upon entering a correct solution (or the error message).\nFigure (5)\nWe double-click on the desired phrase, which takes IDA to the location where this text is stored in the data section (.rdata or .data).\nFigure (6)\nCross-References To determine where this text is used in the code, we click on it, then press the X shortcut (or double-click on the side comment leading to the function). This takes us directly to the function that calls this message.\nWe are now in Visual Mode. Recall that you can switch between the graph view (Graph View) and the sequential text view (Text View) by pressing the Space button. In our case, we want to remain in Graph View to clearly track the program path and the branches (Branches).\n3. Verification Algorithm Analysis We zoom in on the graph to focus on the basic block that precedes the success message, in an effort to understand the programmatic logic.\nFigure (7)\nWe double-click the function\nA) Length Check If we focus on the cmp comparison instruction, we notice that it is preceded by a call to the strlen function (which calculates the length of the entered text). The result is compared against the value 0Bh (equivalent to the decimal number 11).\nFigure (8)\nFirst conclusion: The correct Flag must consist of 11 characters. B) Encryption Loop We trace the program path to reach the following iteration loop (Loop):\nFigure (9)\nWe clearly observe an xor instruction executed using the constant value 5Ah (or 0x5A).\nFigure (10)\nSecond conclusion: The Flag consists of 11 characters, and was encrypted via a simple XOR operation using the key 0x5A. C) Extracting the Encrypted Values To determine the original characters, we must see what is being compared inside the loop. We observe a cmp instruction comparing two registers: eax and edx.\nThe edx register holds the characters entered by the user. The eax register holds the encrypted Flag characters that the program fetches from memory (specifically from the address byte_407070). We single-click on the address byte_407070 and press the X references button.\nA references window appears. We inspect the Type column and select the reference carrying the letter w (which denotes Write, i.e., the location where these values are written/stored in memory), then press OK.\nFigure (11)\nThe encrypted values stored in memory (as a byte array) now appear, and IDA helpfully displays the accompanying comments. The equation is now complete!\nFigure (12)\n4. Decryption Script We now have an array of 11 encrypted characters, and the encryption key is 0x5A. Since the XOR algorithm is reversible (i.e., encrypting the ciphertext with the same key yields the plaintext), we will write a simple Python script to decrypt and extract the Flag.\n# The encrypted values array extracted from IDA encrypted_hex = [0x29, 0x2e, 0x6a, 0x28, 0x37, 0x1a, 0x29, 0x32, 0x69, 0x36, 0x36] # The encryption key (XOR Key) key = 0x5A # Decrypt via a loop that takes each character (byte), applies XOR with the key, then converts it to text flag = \u0026#34;\u0026#34;.join([chr(b ^ key) for b in encrypted_hex]) print(f\u0026#34;The Flag is: {flag}\u0026#34;) When this code is executed, the output will be as follows:\nThe Flag is: st0rm@sh3ll\n5. Verification To confirm the validity of the solution, we run the program and enter the Flag we obtained:\nFigure (13)\nThe success message appears. We have analyzed the file statically, understood the algorithm, and successfully decrypted it!\n","permalink":"https://outofsrvc.github.io/entry-p01nt/en/posts/2026-03-24-static/","summary":"\u003cp\u003eBismillah\u003c/p\u003e\n\u003cp\u003eIn this article, we will solve a simple lab challenge that relies entirely on static analysis (Static Analysis). The objective here is to apply the concepts learned previously to decrypt the flag hidden within the program.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eLab environment setup: You may download the executable for this lab from the following link \u003ca href=\"https://github.com/outofsrvc/entry-p01nt/blob/main/assets/binaries/5t4t1c_cr4ckm3.7z\"\u003e5t4t1c_cr4ckm3\u003c/a\u003e in the course repository. The archive password is: \u003cstrong\u003ep01nt\u003c/strong\u003e\u003c/p\u003e\u003c/blockquote\u003e\n\u003chr\u003e\n\u003cblockquote\u003e\n\u003cp\u003eTo open this file you must open it inside a \u003cstrong\u003eVM\u003c/strong\u003e. Although I am the one who designed this file, never trust the cyber community. We will run the file with the following command\u003c/p\u003e","title":"0x9. Static Lab"},{"content":"Bismillah\nThe reverse engineer does not perceive code merely as complex programming instructions, but rather as a \u0026ldquo;black box\u0026rdquo; with inputs and outputs. In this article, we discuss how the reverse engineer\u0026rsquo;s mindset is built and how to infer the hidden programmatic logic.\nThe Scenario Imagine we are confronted with a locked electronic door. This door opens only if a single correct character is entered from the keyboard. We have only the keyboard and a small screen that displays a single message upon each input attempt.\nThe Experiment We entered three different characters to observe the door\u0026rsquo;s behavior, and the on-screen results were as follows:\nEntering A \u0026ndash;\u0026gt; Result: 66 Entering B \u0026ndash;\u0026gt; Result: 67 Entering C \u0026ndash;\u0026gt; Result: 68 Subsequently, a message appeared indicating that the door opens only when the number 89 is displayed.\nThe Thought Process Here the reverse engineer\u0026rsquo;s mind begins by posing three pivotal questions:\n(Static Analysis): What is the algorithm by which this door operates, based on the inputs and outputs? (Extracting the Flag): What is the precise character that must be entered to reach the required result of opening the door? (Dynamic Analysis \u0026amp; Patching): If we disassemble the keyboard and find a programmatic wire labeled \u0026ldquo;If the result is 89, send a signal to open the door\u0026rdquo;, and we decide to cut this wire and connect it to a battery to produce a permanent open signal\u0026hellip; what do we call this operation? The Solution and Analysis 1. Algorithm Analysis Upon examining the results, we observe a consistent and steady pattern. In computer science, every character has a numeric value representing it, known as the (ASCII Code).\nThe character A has a true value in the computer of 65. The character B has a true value of 66. The character C has a true value of 67. Conclusion: The algorithm by which the door operates is (Input + 1). The program takes the entered character\u0026rsquo;s value (ASCII) and adds 1 to it.\n2. Finding the Flag The objective is to reach the number 89. Applying the reverse mathematical operation of the algorithm we discovered: 89 - 1 = 88\nConsulting the ASCII table, we find that the number 88 represents the character X. Therefore, the solution to opening the door through legitimate means is: enter the X.\n3. Patching The third task explains a fundamental concept in reverse engineering, namely Patching.\nRather than searching for the character X (which represents the legitimate password), we modified the program\u0026rsquo;s \u0026ldquo;behavior\u0026rdquo; (cut the wires) so that it ignores the check and the comparison operation entirely.\nIn a real debugging environment (x64dbg), this action is exactly analogous to changing the conditional jump instruction JZ (jump if the result is equal/zero) to an unconditional jump instruction JMP (jump always). This simple modification causes the door to open every time, regardless of whether the entered password is correct or incorrect!\n","permalink":"https://outofsrvc.github.io/entry-p01nt/en/posts/2026-03-23-thinking-lab/","summary":"\u003cp\u003eBismillah\u003c/p\u003e\n\u003cp\u003eThe reverse engineer does not perceive code merely as complex programming instructions, but rather as a \u0026ldquo;black box\u0026rdquo; with inputs and outputs. In this article, we discuss how the reverse engineer\u0026rsquo;s mindset is built and how to infer the hidden programmatic logic.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"the-scenario\"\u003eThe Scenario\u003c/h2\u003e\n\u003cp\u003eImagine we are confronted with a locked electronic door. This door opens only if a single correct character is entered from the keyboard. We have only the keyboard and a small screen that displays a single message upon each input attempt.\u003c/p\u003e","title":"0x8. The Reverse Engineer's Mindset"},{"content":"Bismillah\nHaving completed the basic analysis (Basic Analysis), we proceed to the advanced analysis (Advanced Analysis). In this article, we examine the principal disassembler and debugger tools employed to analyze binaries, providing a concise and rapid overview. During hands-on application, these tools will be explored in greater depth and detail.\nDisassemblers These tools are used to read a program without executing it (Static Analysis), analogous to reading a map to identify directions and terrain before commencing a journey.\nIDA Free (to be used in the workshop) Figure (1): The IDA Free application interface.\nGhidra Philosophy of Using Both Tools Together: IDA (the radar): Its interface offers the best and fastest navigation across functions and graph views (Graph View). It is the tool we begin with to understand \u0026ldquo;where\u0026rdquo; we are heading and to grasp the program\u0026rsquo;s overall structure. Ghidra (the deep dive): The free version of IDA imposes limitations, such as lack of support for certain architectures like ARM, and the absence of a Decompiler (converting code to C) for some files. Ghidra, by contrast, provides these powerful features entirely free of charge (Open Source). Visual Modes Graph Mode: Displays control flow as a graph, facilitating the tracking of jumps and programmatic decisions (If/Else, Loops). Text Mode: Displays assembly code sequentially and conventionally, from top to bottom. Advanced Functions These enable the analyst to navigate to code references, Xrefs (Cross-References), to determine where specific strings or functions are called, and to trace the reverse path back to the entry point (Start Function or Main).\n⌨️ IDA Command CheatSheet IDA-Cheatsheet\nCommand (Shortcut) Action X Jump to Xref (navigate to cross-references) G Jump to address (navigate to a specific memory address) SHIFT + ; or : Enter comment (add a comment to the code) Debuggers x64dbg (to be used in the workshop) Figure (2): The x64dbg application interface.\nThese tools are used to conduct deeper analysis by actually executing the program within a controlled environment to observe its hidden behavior, which often does not surface in the disassembler due to obfuscation techniques (Obfuscation).\nExecution Control (Logic Manipulation) These tools allow the analyst to \u0026ldquo;manipulate\u0026rdquo; the program\u0026rsquo;s path in live memory. For example, modifying register (Registers) or flag (Flags) values to bypass certain conditions (Branch Statements) and reach hidden code, or to skip activation verification screens (Cracking).\n⌨️ x64dbg Command CheatSheet Command (Shortcut) Action ; Enter comment (add a comment) F2 Toggle Breakpoint (set/remove a breakpoint) F7 Step Into (enter into the function) F8 Step Over (skip the function and move to the next line) F9 Run (run the program until the next breakpoint) Space Edit Instruction (modify the assembly instruction in memory) Keyboard Layout for IDA Free \u0026amp; x64dbg Figure (3): A map of the keys we will continually need to operate during analysis.\n","permalink":"https://outofsrvc.github.io/entry-p01nt/en/posts/2026-03-22-re-tools/","summary":"\u003cp\u003eBismillah\u003c/p\u003e\n\u003cp\u003eHaving completed the basic analysis (Basic Analysis), we proceed to the advanced analysis (Advanced Analysis). In this article, we examine the principal disassembler and debugger tools employed to analyze binaries, providing a concise and rapid overview. During hands-on application, these tools will be explored in greater depth and detail.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"disassemblers\"\u003eDisassemblers\u003c/h2\u003e\n\u003cp\u003eThese tools are used to read a program without executing it (Static Analysis), analogous to reading a map to identify directions and terrain before commencing a journey.\u003c/p\u003e","title":"0x7. RE Toolkit: Disassemblers \u0026 Debuggers"},{"content":"Bismillah\nWhenever we intend to analyze any file, we follow the steps below, irrespective of whether the objective is to determine whether the file is benign or contains malware, or even whether we intend to crack its protection:\nThe 4 Stages of Analysis Basic Static Analysis: This analysis does not require deep technical expertise, but relies entirely on tools that operate automatically (such as VirusTotal). It reveals indicators that show whether the file is a virus or not.\nRule: This analysis is performed without running the executable.\nBasic Dynamic Analysis: Similar to the preceding stage, but the distinction is that here a virtualized environment is required.\nRule: This step requires running the executable in order to observe its mechanism and actual behavior.\nAdvanced Static Analysis: At this stage, one must possess sufficient expertise to work with disassemblers such as IDA Pro and Ghidra. We summarize this stage as the analysis of assembly code to understand its operation—that is, the structure the program follows.\nAdvanced Dynamic Analysis: This stage demands technical expertise, as one will work with a debugger. To contrast it with a disassembler: the difference is that a debugger permits the execution of code and stepping through it line by line in live memory, whereas a disassembler does not execute code (which is the basis of static analysis). Among the foremost debuggers is x64dbg.\nBasic Reconnaissance In this article, we discuss the first two steps of the analysis process, known as basic reconnaissance: the rapid collection of preliminary information and indicators concerning the file prior to undertaking deeper analysis. As noted, this step does not require complex technical expertise; it consists of employing simple tools. We will enumerate each tool, its purpose, and an image of its interface.\n1. Helpful Websites VirusTotal: To verify the file\u0026rsquo;s digital fingerprint (hashing) and determine whether antivirus vendors have classified it as malicious.\nFigure (1): The VirusTotal website interface.\nHybrid-Analysis: A service providing automated execution of the file and producing a rapid report on its behavior (file, process, and network logs).\nFigure (2): The Hybrid-Analysis website interface.\nCyberChef: A tool for decoding and analyzing data (such as Base64, XOR).\nFigure (3): The CyberChef website interface.\n2. Information Gathering: Static Detect It Easy (DIE): To determine the file type and compiler type, and whether it is packed with a packer. Among the most important indicators in this program is the entropy.\nFigure (4): The DIE application interface.\nFLOSS: A tool capable of extracting strings that the programmer attempts to encrypt within the code (obfuscated strings).\nFigure (5): The FLOSS program execution command.\nPE-Bear: Used to analyze the file headers (PE Headers) and explore resources, and to identify the libraries (DLLs) and functions the program invokes, such as CreateProcessA.\nFigure (6): The PE-Bear application interface.\n3. Information Gathering: Dynamic Process Monitor (ProcMon): Monitors file activity, the system registry, and network traffic in real time.\nFigure (7): The ProcMon application interface.\nProcess Explorer (ProcExp): Used to monitor the processes currently active within the system and to detect any suspicious processes.\nFigure (8): The ProcExp application interface.\n4. Network Monitoring FakeNet-NG: Used to simulate internet services locally, enabling the analyst to observe network requests (such as HTTP, GET) without requiring a genuine internet connection, thereby avoiding risk.\nFigure (9): Image of the file generated when the application is run, bearing the .pcap extension, which is opened in Wireshark.\nWireshark: A tool for capturing and analyzing network traffic (network sniffing) to determine whether the file is attempting to communicate with external command-and-control servers.\nFigure (10): The Wireshark application interface.\n","permalink":"https://outofsrvc.github.io/entry-p01nt/en/posts/2026-03-21-basic-recon/","summary":"\u003cp\u003eBismillah\u003c/p\u003e\n\u003cp\u003eWhenever we intend to analyze any file, we follow the steps below, irrespective of whether the objective is to determine whether the file is benign or contains malware, or even whether we intend to crack its protection:\u003c/p\u003e\n\u003ch2 id=\"the-4-stages-of-analysis\"\u003eThe 4 Stages of Analysis\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eBasic Static Analysis:\u003c/strong\u003e This analysis does not require deep technical expertise, but relies entirely on tools that operate automatically (such as VirusTotal). It reveals indicators that show whether the file is a virus or not.\u003c/p\u003e","title":"0x6. Basic Reconnaissance"},{"content":"Bismillah\nWhen engaging with malicious software (malware) that warrants examination, one must understand the mindset of the adversary and the objectives they pursue. Therefore, in this research we examine the attack lifecycle and explain several fundamental concepts in malware development.\nThe attack cycle is divided into three principal stages:\nFigure (1): Illustration of the attack lifecycle.\nStage 1: Initial Access This stage focuses on breaching the initial defensive perimeter and gaining a foothold within the target system.\nReconnaissance: The operation begins with the collection of information about the target. This encompasses identifying IP addresses, scanning for open ports, and even gathering intelligence on personnel for use in social engineering. Exploitation: Upon identifying a vulnerability (a flaw in the system, an unpatched service, or even a deceivable employee), the threat actor employs a specific tool or code to exploit that weakness. Infiltration: This is the moment of successful exploitation and traversal of the security boundary, whereby the adversary obtains an initial foothold within the network. Stage 2: Entrenchment \u0026amp; Discovery Once the adversary has gained entry, they must understand their new environment and ensure they are not evicted from it.\nInternal Reconnaissance: The adversary is now inside the network and begins to survey their surroundings to determine which assets are available, what privileges they hold, and where sensitive data resides (such as databases or administrative servers). Entrenchment: This step is critical; the adversary does not wish to lose access should the system administrator reboot the server or patch the initial vulnerability. Consequently, they establish backdoors or implant malware to ensure persistence. Note: This is precisely the point at which reverse engineering and malware code analysis become critically important for understanding how the adversary conceals themselves and maintains their privileges within the system.\nStage 3: Objective Execution Here the adversary begins to reap the benefits of the compromise and execute the operation for which they initiated the intrusion.\nCommand \u0026amp; Control (C2): The implanted malware establishes communication with external servers under the adversary\u0026rsquo;s control. Through this channel, the adversary continuously and covertly issues and receives commands to and from the compromised system. Exfiltration: The aggregation of sensitive data (credit card numbers, trade secrets, passwords) and its covert transfer beyond the victim\u0026rsquo;s network boundary. Purge: The final step, consisting of clearing logs and deleting the tooling the adversary employed to conceal any evidence of their presence. In certain cases, this stage may encompass destruction of the system (such as encrypting files in ransomware attacks or wiping them via wiper malware). In summary: We now possess an understanding of the methodology underlying every attack conducted over the internet. As reverse engineers and malware analysts, our work concentrates primarily on Stage 2 and Stage 3.\nMalware Terminology The preceding steps involve specific technical terminology that we must understand in order to facilitate the analysis process:\n1. Compression / Packing This involves combining compressed files via a packer together with decompression code into a single executable. The concept is that, upon reaching the victim\u0026rsquo;s machine, the file is in effect a wrapper program whose primary function is to decompress the genuine malicious payload and execute it in memory in order to evade antivirus products.\nFigure (2): Illustration of how files are compressed and decompressed.\n2. Obfuscation A deliberate act of producing code that is difficult for humans (and analysts) to comprehend or read with ease.\nSimple strings appear encrypted with algorithms such as Base64 or XOR. Non-functional functions are inserted to distract attention (junk code). In assembly language, one may observe an abundance of NOP (No Operation) instructions that perform no function. The repeated use of push instructions as a technique to conceal string construction in memory. Figure (3): Code illustrating how obfuscation is performed.\nThe following is an illustrative example of how to design obfuscated code in C:\nFigure (4): Illustration of how code is manipulated.\n3. Persistence The malware developer seeks to ensure that the malware executes on the host and persists for as long as possible, even following a reboot.\nSpecial Files: The program is placed in hidden system paths or those that ordinary users rarely inspect, such as the %APPDATA% folder. Certain of these paths afford deeper access privileges within the system. Advanced Techniques: Further research may be conducted on the use of shared files, access via namespaces, or the use of Alternative Data Streams (ADS) within the NTFS file system. 4. Privilege Escalation The exploitation of a flaw in the system\u0026rsquo;s design or configuration to obtain elevated access to system resources with administrator (Admin) or root privileges.\nCommon techniques:\nDLL Hijacking DLL Injection Buffer Overflow Stack Overflow Heap Spray ROP (Return-Oriented Programming) UAC Bypasses 5. Defense Evasion This refers to techniques used to evade detection by security controls (such as antivirus and EDR) in order to arouse less suspicion.\nCommon techniques:\nKilling AV Deleting itself after run Time bombs / Time stomping DLL Side-Loading Process Hollowing Code Injection ","permalink":"https://outofsrvc.github.io/entry-p01nt/en/posts/2026-03-20-attack-flow/","summary":"\u003cp\u003eBismillah\u003c/p\u003e\n\u003cp\u003eWhen engaging with malicious software (malware) that warrants examination, one must understand the mindset of the adversary and the objectives they pursue. Therefore, in this research we examine the attack lifecycle and explain several fundamental concepts in malware development.\u003c/p\u003e\n\u003cp\u003eThe attack cycle is divided into three principal stages:\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Attack Lifcycle\" loading=\"lazy\" src=\"https://outofsrvc.github.io/entry-p01nt/assets/img/posts/lifecycle/lifecycle.png\"\u003e\n\u003cem\u003eFigure (1): Illustration of the attack lifecycle.\u003c/em\u003e\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"stage-1-initial-access\"\u003eStage 1: Initial Access\u003c/h2\u003e\n\u003cp\u003eThis stage focuses on breaching the initial defensive perimeter and gaining a foothold within the target system.\u003c/p\u003e","title":"0x5. Cyber Attack Lifecycle"},{"content":"Bismillah\nWhen beginning to work with Assembly language, one invariably perceives a degree of difficulty owing to its low-level nature, in contrast to higher-level languages such as C or Python. In this research, we attempt to simplify assembly code so that it may be more readily understood.\nThe premise of this article is that we will author a simple program in C, compile it into x86 Assembly, and then explain the operations that occur in order to analyze the control flow.\nBefore proceeding, if you do not possess sufficient familiarity with C and Assembly, we recommend reviewing the following series: 🔗 C language series on the Shell Network 🔗 Assembly language series on the Shell Network\n1. Global vs. Local Variables Global Variables We begin by authoring the following simple C code:\nint x = 1; int y = 2; void main() { x = x + y; printf(\u0026#34;Total = %d\\n\u0026#34;, x); } We then compile it using the following command:\ngcc -S -masm=intel -m32 -O0 filename.c -o filename.s When we open the file bearing the .s extension, the following is produced:\nx86 Assembly:\n00401003 mov eax, dword_40CF60 00401008 add eax, dword_40C000 0040100E mov dword_40CF60, eax ; [1] Store the result 00401013 mov ecx, dword_40CF60 00401019 push ecx 0040101A push offset aTotalD ; \u0026#34;total = %d\\n\u0026#34; 0040101F call printf In assembly, global variables are expressed as memory addresses (Memory Addresses) such as: dword_40CF60.\nLocal Variables With respect to local variables, these are expressed as an offset relative to ebp, esp, or any other register (for example: dword ptr [ebp-4]). When we employ a disassembler such as IDA Pro (which we will examine in detail in forthcoming articles, God willing), the local variables appear clearly.\nvoid main() { int x = 1; int y = 2; x = x+y; printf(\u0026#34;Total = %d\\n\u0026#34;, x); } x86 Assembly:\n00401006 mov dword ptr [ebp-4], 1 ; [1] 0040100D mov dword ptr [ebp-8], 2 ; [2] 00401014 mov eax, [ebp-4] 00401017 add eax, [ebp-8] 0040101A mov [ebp-4], eax 0040101D mov ecx, [ebp-4] 00401020 push ecx 00401021 push offset aTotalD ; \u0026#34;Total = %d\\n\u0026#34; 00401026 call printf When we employ a disassembler such as ida (which we will examine in forthcoming articles, God willing), the local variables appear as illustrated here.\n00401006 mov [ebp+var_4], 1 ; [1] 0040100D mov [ebp+var_8], 2 ; [2] 00401014 mov eax, [ebp+var_4] 00401017 add eax, [ebp+var_8] 0040101A mov [ebp+var_4], eax 0040101D mov ecx, [ebp+var_4] 00401020 push ecx 00401021 push offset aTotalD ; \u0026#34;Total = %d\\n\u0026#34; 00401026 call printf 2. If Statement int x = 1; int y = 2; if(x == y) { printf(\u0026#34;x equals y.\\n\u0026#34;); } else { printf(\u0026#34;x is not equal to y.\\n\u0026#34;); } x86 Assembly:\n00401006 mov [ebp+var_8], 1 0040100D mov [ebp+var_4], 2 00401014 mov eax, [ebp+var_8] 00401017 cmp eax, [ebp+var_4] ; [1] Comparison instruction 0040101A jnz short loc_40102B ; [2] Conditional jump to else 0040101C push offset aXEqualsY_ ; \u0026#34;x equals y.\\n\u0026#34; 00401021 call printf 00401026 add esp, 4 00401029 jmp short loc_401038 ; [3] Unconditional jump to skip else 0040102B loc_40102B: ; else section 0040102B push offset aXIsNotEqualToY ; \u0026#34;x is not equal to y.\\n\u0026#34; 00401030 call printf The first element we encounter is the CMP instruction, followed by a conditional jump. (If the conditional jump is taken, the code has followed the else path.) If it is not taken, execution continues and performs an unconditional jump, which constitutes the primary if path.\n3. For Loop int i; for(i = 0; i \u0026lt; 100; i++) { printf(\u0026#34;i equals %d\\n\u0026#34;, i); } x86 Assembly:\n00401004 mov [ebp+var_4], 0 ; [1] Initialization (i=0) 0040100B jmp short loc_401016 ; [2] Jump to comparison 0040100D loc_40100D: ; Update region 0040100D mov eax, [ebp+var_4] ; [3] 00401010 add eax, 1 ; Increment counter 00401013 mov [ebp+var_4], eax ; [4] 00401016 loc_401016: ; Condition region 00401016 cmp [ebp+var_4], 64h ; [5] 64h = 100 0040101A jge short loc_40102F ; [6] Conditional jump to exit loop 0040101C mov ecx, [ebp+var_4] ; Loop body 0040101F push ecx 00401020 push offset aID ; \u0026#34;i equals %d\\n\u0026#34; 00401025 call printf 0040102A add esp, 8 0040102D jmp short loc_40100D ; [7] Return to update Initialization is performed with a local variable inside the for. We observe an unconditional jump that leads to the CMP comparison. This is followed by a conditional jump to exit. If the exit is not taken, the instructions within the for are executed. Finally, an unconditional jump leads back to the update location (increment or decrement). The process repeats until the exit condition is satisfied. Figure (1): An excerpt from IDA Pro.\n4. While Loop int status = 0; int result = 0; while(status == 0) { result = performAction(); status = checkResult(result); } x86 Assembly:\n00401036 mov [ebp+var_4], 0 0040103D mov [ebp+var_8], 0 00401044 loc_401044: ; Loop start 00401044 cmp [ebp+var_4], 0 ; Comparison 00401048 jnz short loc_401063 ; [1] Conditional jump to exit 0040104A call performAction 0040104F mov [ebp+var_8], eax 00401052 mov eax, [ebp+var_8] 00401055 push eax 00401056 call checkResult 0040105B add esp, 4 0040105E mov [ebp+var_4], eax ; Update status 00401061 jmp short loc_401044 ; [2] Return to loop start This is similar to the for loop but somewhat simpler. It begins with a CMP comparison followed by a conditional jump to exit the while. If the jump is not taken, the code inside the loop is executed, and at its conclusion an unconditional jump repeats the cycle. This continues until the CMP condition is satisfied and execution jumps out, ending the loop.\n5. Switch Statement A switch may be compiled in one of two ways depending on the compiler:\nMethod 1: If Style This is nearly identical to chained if statements. We observe a number of comparisons equal to the number of cases, and after each comparison a conditional jump to execute the corresponding block. At the end, an unconditional jump leads to default.\nswitch(i) { case 1: printf(\u0026#34;i = %d\u0026#34;, i+1); break; case 2: printf(\u0026#34;i = %d\u0026#34;, i+2); break; case 3: printf(\u0026#34;i = %d\u0026#34;, i+3); break; default: break; } x86 Assembly:\n00401013 cmp [ebp+var_8], 1 00401017 jz short loc_401027 ; [1] Case 1 00401019 cmp [ebp+var_8], 2 0040101D jz short loc_40103D ; Case 2 0040101F cmp [ebp+var_8], 3 00401023 jz short loc_401053 ; Case 3 00401025 jmp short loc_401067 ; [2] Default 00401027 loc_401027: ; Execute Case 1 00401027 mov ecx, [ebp+var_4] ; [3] 0040102A add ecx, 1 ; ... (remaining instructions) ... Figure (2): An excerpt from IDA Pro.\nMethod 2: Jump Table switch(i) { case 1: printf(\u0026#34;i = %d\u0026#34;, i+1); break; case 2: printf(\u0026#34;i = %d\u0026#34;, i+2); break; case 3: printf(\u0026#34;i = %d\u0026#34;, i+3); break; case 4: printf(\u0026#34;i = %d\u0026#34;, i+4); break; default: break; } x86 Assembly:\n00401016 sub ecx, 1 ; Subtract 1 because the compiler starts from 0 00401019 mov [ebp+var_8], ecx 0040101C cmp [ebp+var_8], 3 ; Compare against maximum 00401020 ja short loc_401082 ; If out of range, go to default 00401022 mov edx, [ebp+var_8] 00401025 jmp ds:off_401088[edx*4] ; [1] Direct jump via the table ; --- Target addresses --- 0040102C loc_40102C: ; ... 00401042 loc_401042: ; ... 00401082 loc_401082: ; End (Default/Exit) 00401082 xor eax, eax 00401087 retn ; --- Jump table --- 00401088 off_401088: ; [2] 00401088 dd offset loc_40102C 0040108C dd offset loc_401042 00401090 dd offset loc_401058 00401094 dd offset loc_40106E The jump-table method relies on subtracting a value to obtain a zero-based index, then comparing it against the number of cases. If it falls within range, it jumps directly using the table according to the equation [edx*4]. If it is outside the range, default is executed immediately.\nFigure (3): An excerpt from IDA Pro.\n6. Arrays int b[5] = {123, 87, 487, 7, 978}; void main() { int i; int a[5]; for(i = 0; i \u0026lt; 5; i++) { a[i] = i; b[i] = i; } } x86 Assembly:\n00401021 mov edx, [ebp+var_18] 00401024 mov [ebp+ecx*4+var_14], edx ; [1] Local Array 00401028 mov eax, [ebp+var_18] 0040102B mov ecx, [ebp+var_18] 0040102E mov dword_40A000[ecx*4], eax ; [2] Global Array The memory address of an array depends on its declaration (global or local). It is always accompanied by a register acting as an index multiplied by the size of its elements. (For example: for an integer array the index is multiplied by 4, expressed as [ecx * 4].) Note that array indices start at 0, so the last element is at index n-1.\n7. Structs \u0026amp; Linked Lists Struct struct my_structure { ; [1] int x[5]; char y; double z; }; struct my_structure *gms; ; [2] void main() { gms = (struct my_structure *) malloc(sizeof(struct my_structure)); test(gms); } x86 Assembly:\n00401053 push 20h ; Struct size (32 bytes) 00401055 call malloc 0040105A add esp, 4 0040105D mov dword_40EA30, eax ; Store base address 00401062 mov eax, dword_40EA30 00401067 push eax ; [1] Pass pointer to function 00401068 call sub_401000 A struct is declared as a variable, and values are written into it according to the variables it contains and according to the function call. When declaring the struct and allocating space for it with malloc, we are provided with the base address, which marks the beginning of the struct.\nLinked List struct node { int x; struct node * next; }; typedef struct node pnode; void main() { pnode * curr, * head; int i; head = NULL; for(i=1; i\u0026lt;=10; i++) { ; [1] Build the nodes curr = (pnode *)malloc(sizeof(pnode)); curr-\u0026gt;x = i; curr-\u0026gt;next = head; head = curr; } curr = head; while(curr) { ; [2] Traverse the nodes printf(\u0026#34;%d\\n\u0026#34;, curr-\u0026gt;x); curr = curr-\u0026gt;next; } } x86 Assembly:\n0040107E mov [esp+18h+var_18], 8 ; Node size 00401085 call malloc 0040108A mov [ebp+var_4], eax ; eax holds the new node address 0040108D mov edx, [ebp+var_4] 00401090 mov eax, [ebp+var_C] 00401093 mov [edx], eax ; [1] curr-\u0026gt;x = i 00401095 mov edx, [ebp+var_4] 00401098 mov eax, [ebp+var_8] 0040109B mov [edx+4], eax ; [2] curr-\u0026gt;next = head 0040109E mov eax, [ebp+var_4] 004010A1 mov [ebp+var_8], eax ; head = curr The fundamental difference between a conventional struct and a linked list in assembly is the profusion of mov operations that indicate the construction of the links between nodes, as shown in the lines marked [1] and [2].\n","permalink":"https://outofsrvc.github.io/entry-p01nt/en/posts/2026-03-19-c-and-asm/","summary":"\u003cp\u003eBismillah\u003c/p\u003e\n\u003cp\u003eWhen beginning to work with Assembly language, one invariably perceives a degree of difficulty owing to its low-level nature, in contrast to higher-level languages such as C or Python. In this research, we attempt to simplify assembly code so that it may be more readily understood.\u003c/p\u003e\n\u003cp\u003eThe premise of this article is that we will author a simple program in C, compile it into x86 Assembly, and then explain the operations that occur in order to analyze the control flow.\u003c/p\u003e","title":"0x4. Recognizing C code constructs in Asm"},{"content":"Bismillah\nHave you ever wondered how programs operate within systems? Or has the following thought occurred to you: what is the difference between an ordinary user and a developer in terms of their understanding of the systems they interact with?\nGod willing, in this article we will clarify the executable file format in Windows and discuss some important matters regarding Windows architecture that we must not be ignorant of.\nBefore beginning, if you do not have sufficient knowledge of operating systems, we advise you to review the following series: 🔗 Operating Systems Series on the Shell Network\nFile Format (PE file format) The PE (Portable Executable) file format is the native format for win32 files such as (dll, exe). Understanding this format is a cornerstone for analyzing Windows system files.\nThe PE format derives some of its specifications from Unix COFF (Common Object File Format), which is the executable file format in the Unix system that was recently replaced by ELF (Executable and Linkable Format).\nWhat does Portable Executable mean? It means that the format is comprehensive and widespread across the win32 platform such that the PE Loader recognizes it on any platform running win32 regardless of the processor type.\nWhat is the Structure of this Format? This format is fundamentally identified by the PE Header: it is the core component that defines PE files intrinsically. It consists of several successive layers that perform specific functions to ensure the file is loaded and executed correctly in the Windows environment.\nThe PE Header consists of several parts that define its identity and behavior:\n1. DOS Header It is the first 64 bytes of the file and contains the information necessary to recognize that this file is in PE format:\ne_magic: the magic number that indicates the two characters MZ or 4d 5a in hex, named after the engineer \u0026ldquo;Mark Zbikowski\u0026rdquo;, and these are what determine that the file is in PE format. Figure (1): The magic number.\ne_lfanew: located at offset 0x3c within the DOS Header, it is an address that points to the location where the PE Header (the new NT Header) begins. 2. DOS Stub It is a remnant of the DOS Header that comes after the first 64 bytes of the DOS Header; it is a memory region that is usually filled with zeros or contains a simple error message indicating that this program cannot run in DOS mode (which had a 16-bit architecture in MS-DOS).\nFigure (2): An image illustrating the DOS Stub.\n3. NT Header / PE Header It is defined programmatically as the IMAGE_NT_HEADER structure.\nFigure (3): An image illustrating the structure definition.\nIt consists of three parts:\nSignature: consists of the magic bytes PE\\0\\0 or in hex 50 45 00 00 to identify the file format. Figure (4): An image illustrating the signature.\nFile Header (or COFF Header): describes the basic properties of the file such as: Machine: the processor type. NumberOfSections: the number of sections present in the file. Characteristics: the file attributes (such as whether it is an Exe or a DLL). Figure (5): An image illustrating the file header.\nOptional Header: despite its name, it is mandatory for PE files and contains critically important variables: AddressOfEntryPoint: the program\u0026rsquo;s entry point. ImageBase: the preferred address for loading the file into memory. DataDirectory: a list of 16 elements pointing to important tables such as the export table and the import table. Figure (6): An image illustrating the optional header.\n4. Section Table / Headers Like a map that illustrates how data is divided and distributed in memory, this table comes immediately after the Headers and before the actual section data. The section table consists of an array called IMAGE_SECTION_HEADER, where each element in this array describes a specific section in the file. The size of each element in this table is 0x28 bytes.\nEach entry in the table contains important details:\nName: the name of the section (such as .text or .data). VirtualSize: the actual size of the section when loaded into memory. VirtualAddress: the address at which the section will be placed in virtual memory. SizeOfRawData: the size on disk (hard disk). Characteristics: the section attributes (such as readable, writable, or executable). 5. Sections They come after the section table. What are these sections?\n.text: contains the program\u0026rsquo;s executable code. .rdata: contains read-only data (such as Strings and Constants). Sometimes the rdata is split into two sections, and we most often see this in DLL files: .idata: for the imports directory. .edata: for the exports directory, and this is an important section in dll files for linking exported Functions to names or identifying numbers. .data: contains the data and variables that have been initialized. .rsrc: contains resources such as the program\u0026rsquo;s images and icons. Figure (7): An image illustrating the sections.\nWhat is the Difference Between Exe vs DLL Files? Exe files: require the existence of a function called Main that the OS Loader calls when the new process is ready. These files run independently; the system creates a new process and a dedicated virtual space for it. DLL files: require a function called DllMain; the code is executed directly as soon as the appropriate dll library is loaded into memory. They cannot run independently but must be loaded inside a pre-existing virtual address space. Why? Because the process may require functions provided by this library. In short: while the exe file represents the program that starts the process, the dll file represents the library that supplies that process with functions.\nWindows Architecture (Windows Internals) We return to ask what distinguishes the developer in systems from the user? Simply, it is knowledge of the system\u0026rsquo;s internal matters that do not concern the ordinary user, known as Windows Internals.\nWindows internals are the concepts that you must know how to work with in the Windows system. Anyone who will learn low-level topics or program something low-level must have experience with these points:\n1. Processes It means any program that is under execution. Processes have a structure in the kernel called the Process Control Block = PCB, also called KProcess, which the kernel uses to control the operations of that process.\nIn memory the situation differs; there is something called the EProcess structure, which is distinct from the KProcess; the EProcess contains a great deal of information, the most important of which are:\nProcess id: the process number. exe name: the name of the executable file associated with that process. dll files: the dll files associated with that process. PCB: the kernel structure associated with that process. Figure (8): An image illustrating the interrelationship of processes.\nThese EProcesses exist in kernel memory as a double-linked list, meaning each process has a forward link and a back link. Of course, many programs can reach this EProcess, such as Process Explorer.\nFigure (9): An image illustrating a view from within the program.\n2. Threads In short, it is what Windows executes. As for the Process: it contains threads within it. The process itself is not what runs the code; rather, it must contain at least one thread to run the code on the processor, but it does not follow that a thread can run by itself if it is not inside a process.\nA thread has 3 possible states:\nRunning: meaning it is active or under execution. Ready: ready and waiting for the processor to run it. Blocked/Suspended: stopped or blocked, let us say as a result of an interrupt. Figure (10): An image illustrating thread states.\nSince a process may contain more than one thread. Are they isolated from one another? No, they share memory, meaning the threads share the resources and the address spaces (such as the .data section and the .code section). But each thread still has its own stack and registers.\nFigure (11): An image illustrating memory sharing between threads.\n3. Virtual Memory / Virtual Address Space Any exe.file that we run will have a process, and that process has its own address space. The address space takes a range from 00000000 to ffffffff and this range is divided into two parts, each 2Gb: a part for user mode and a part for kernel mode.\nFigure (12): An image illustrating the comparison between the physical and virtual portions of memory.\nThe user mode range: from 00000000 to 7fffffff And kernel mode: from 80000000 to ffffffff (Noting that this applies to the 32-bit system.) 4. Virtual Address VS Physical Address Every program has a process, and every process has virtual memory. And as we know, every exe file has a section in memory. So if we have two applications that placed .text and .data at random addresses, and fate willed that the .data addresses are identical, does that mean the .data section is shared?\nNo, because the base addresses of programs exist in RAM, which is the physical memory, and the addresses we are currently dealing with are virtual. So when the process begins to read data, something called virtual-to-physical occurs; the operating system handles the matter and connects each section to a specific address in RAM.\nWe must know: The virtual address does not represent an actual location in RAM; instead, the system maintains pages for each process (in order to translate virtual addresses into physical addresses). At the same time, this applies to threads, and this process is called virtual-to-physical translation.\nIn Windows, they made a move so that not every process loads its own segments from RAM. They created files with dll extensions; thus any process must load ntdll.dll and kernel32.dll, and these are libraries, or more precisely (dynamic link libraries), meaning linking libraries in which multiple processes are linked to the same address. The first process performs the mapping or division of this dll at shared addresses between all the processes.\n5. Synchronization In short, it prevents simultaneous access (meaning several programs or threads using the same file or the same memory at the same time). They created something called a mutex, also referred to as a lock: it is an object used generally in programming that prevents simultaneous access from occurring.\nAn example to clarify matters somewhat: If we have two different processes and they both want to write to memory at the same time, what happens? Imagine the memory is overseen by a police officer; this officer does not allow anyone to enter and write unless they hold the mutex. So a process comes with the mutex object, writes to memory, and releases the mutex; then the second process comes, takes this mutex, and writes to memory.\n6. Services Services allow us to run long-running executable apps. They will continue running in the background, operating in a special Windows session called svchost.exe (which is a host for the services; the services are scheduled and run by the Windows Service Manager without user intervention).\n7. Registry It is a database in which the settings of the Windows system and the programs present on it are stored. The registry contains two basic elements:\nKeys: these are the folders. Values: these are the files. In the registry there is something called root keys or HKEYs, and these are the most important paths we interact with:\nHKEY_CURRENT_USER HKEY_LOCAL_MACHINE HKEY_USERS HKEY_CLASSES_ROOT So what are the important things present in the registry?\nThe list of programs and services installed on the system. The settings of the programs and services. The programs that auto run after boot. The file associations (meaning if the user wants to open an .html page, they open it in chrome or firefox, for example). We see the history of usb devices and the network adapter settings. The file containing the registry functions is called advapi32.dll, and all functions related to the registry begin with Reg. 8. Windows Coding Conventions Some constants in the Windows API; these constants make it easier for you to read Microsoft\u0026rsquo;s docs or to predict, for example, what some function does from its name. Windows data types:\nByte -\u0026gt; 1Byte Word -\u0026gt; 2Bytes DWord -\u0026gt; 4Bytes QWord -\u0026gt; 8Bytes Microsoft relies on prefix naming in naming (prefix meaning the forepart) to let us know, for example, what the data type of a variable or a certain structure is. And we can query every function via MSDN - MicroSoft Developer Network, and at the end of every function we find the dll file in which that function resides.\n9. Handles The handle is almost like the pointer\u0026hellip; The difference is that we can perform arithmetic operations on a pointer, but we cannot on a handle (meaning we simply take this handle, store it, and use it as-is at a later time).\nFor example: We want to make a call to a function named CreateWindowEx; this function, once called, creates a window and returns a handle to that window. And if I want to perform any operation on that window, such as adding or controlling a button or anything else, I must reference that window through the handle.\n10. Network Functions in the API Microsoft provides 2 APIs for Networking:\nlow-level API: It deals with sockets and is called winsock. The socket is a handle at the endpoint for network communications. Example: in the cups game where they communicate with each other: Figure (13): An image illustrating the sender and receiver principle.\nEach cup is a socket; a cup for listening and a cup for speaking. So we treat the socket as a file: we can write or read to it.\nhigh-level API: It is called wininet and allows programmers to use high-level protocols such as http, ftp. Of course, this library keeps pace with the standards specific to the protocols, such as http, and there are many dll files specific to the high-level such as: winhttp.dll, dnsapi.dll, urlmon.dll. 11. The Native API When we make a Call to a function from the win32api, that function does not directly perform what we requested. Rather, it needs to communicate with the kernel in order to reach the hardware. So the userapps use win32api from files such as kernel32.dll, and these files make a Call to a file named ntdll.dll: it is responsible for the interactions between user mode and kernel mode.\nThe native api allows the apps to communicate directly with ntdll.dll.\nReferences Practical Malware Analysis Windows Internals Malware Development for Ethical Hackers ","permalink":"https://outofsrvc.github.io/entry-p01nt/en/posts/2026-03-18-win-arch-and-pe/","summary":"\u003cp\u003eBismillah\u003c/p\u003e\n\u003cp\u003eHave you ever wondered how programs operate within systems? Or has the following thought occurred to you: what is the difference between an ordinary user and a developer in terms of their understanding of the systems they interact with?\u003c/p\u003e\n\u003cp\u003eGod willing, in this article we will clarify the executable file format in Windows and discuss some important matters regarding Windows architecture that we must not be ignorant of.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eBefore beginning, if you do not have sufficient knowledge of operating systems, we advise you to review the following series:\n🔗 \u003ca href=\"https://sh3ll.cloud/xf2/threads/4230/\"\u003eOperating Systems Series on the Shell Network\u003c/a\u003e\u003c/p\u003e","title":"0x3. Windows Architecture \u0026 PE Format"},{"content":"Bismillah\nIn this article we will review the foundational disciplines that must be learned before embarking on the field of reverse engineering. We have distilled this knowledge from several international references and formulated it into Arabic explanations and series that we published on the \u0026ldquo;Arabic Shell Network\u0026rdquo; (Shabakat Shill al-Arabiya), and we append them here along with the original references at the end of each section.\nTo begin, every field has fundamentals that cannot be overlooked, and learning them is an obligation, for they will be the launching point of the journey of empowerment that we strive toward, God willing.\nEvery science rests upon pillars.. and the pillars of our era are those that reside beneath the fortress of 0 and 1.\n1. Programming To be a developer or a researcher in this field, you must possess a strong programming background that enables you to understand how code flows (Control Flow).\nAnd since, in reverse engineering, we will be dealing with software at a middle level close to hardware (Middle-Level), we must have experience with the C/C++ language, which we discussed in an extended series where we explained its most precise details.\n🔗 C Programming Series on the Shell Network\nFigure (1): Excerpt from the C programming lessons.\n📚 Primary reference: C Programming Language (K\u0026amp;R) 2. Computer Architecture Certainly, we cannot take anything apart in life without understanding its design and how it operates. Like the mechanic who services automobiles, one must have complete knowledge of how the vehicle operates from the moment of power-on to the moment of power-off.\nWe have therefore prepared a series explaining in detail how the computer operates, in order to build this deep understanding.\n🔗 Computer Architecture Series on the Shell Network\nFigure (2): Excerpt from the computer architecture lessons.\n📚 Primary reference: Modern Computer Architecture and Organization 3. Operating Systems (OS Concepts) Given our direct interaction with software, we must understand how the operating system interacts with processes (Processes), how it organizes them, and what role the processor and memory play therein. We have prepared a series explaining the most important matters that we must be familiar with in this regard.\n🔗 Operating Systems Concepts Series on the Shell Network\nFigure (3): Excerpt from the operating systems lessons.\n📚 Primary reference: Operating System Concepts 4. Networking With the existence of the internet, it has become very important that we realize and understand how things operate within networks, and how software (especially malicious software) communicates with the outside world.\nThis excellent series was prepared by my brother and mentor, Storm.\n🔗 Networking Fundamentals Series on the Shell Network\nFigure (4): Excerpt from the networking lessons by brother Storm.\n5. Low-Level Programming The most important matter in reverse engineering is learning and understanding Assembly code. Why? Because when reverse engineering any program, we are dealing with executable code in machine language (Machine Code), that is, it is represented in zeros and ones (Binary System).\nBut this code can be disassembled (Disassemble) so that it appears in a readable language, namely Assembly. We have therefore prepared a complete series dedicated to the x86 Assembly language.\n🔗 x86 Assembly Language Series on the Shell Network\nFigure (5): Excerpt from the x86 Assembly lessons.\n📚 Primary reference: Assembly Language for x86 Processors Conclusion To be honest with you, upon completing the study of these matters, I will not tell you that you will have built a foundation that is 100% complete.\nKnowledge is a vast ocean, and the more we drink from it, the more we thirst. But, God willing, by completing these series you will have finished 90% of the foundational knowledge required of you to begin strongly in this field.\n","permalink":"https://outofsrvc.github.io/entry-p01nt/en/posts/2026-03-17-fundamentals-of-re/","summary":"\u003cp\u003eBismillah\u003c/p\u003e\n\u003cp\u003eIn this article we will review the foundational disciplines that must be learned before embarking on the field of reverse engineering. We have distilled this knowledge from several international references and formulated it into Arabic explanations and series that we published on the \u0026ldquo;Arabic Shell Network\u0026rdquo; (Shabakat Shill al-Arabiya), and we append them here along with the original references at the end of each section.\u003c/p\u003e\n\u003cp\u003eTo begin, every field has fundamentals that cannot be overlooked, and learning them is an obligation, for they will be the launching point of the journey of empowerment that we strive toward, God willing.\u003c/p\u003e","title":"0x2. Fundamentals of Reverse Engineering"},{"content":"Bismillah\nIntroduction From childhood, human beings possess an innate curiosity to understand \u0026ldquo;how things work?\u0026rdquo;. It is this curiosity that drives a child to break apart a favorite toy in order to see the small motor inside it. In the advanced world of technology, this curiosity evolves into a precise and critical engineering discipline known as reverse engineering.\nMost computer users may not have heard of reverse engineering before, perhaps because it is not as widespread as the field of hacking, or perhaps because they know it by another term, namely \u0026ldquo;cracking\u0026rdquo;.\nMany differ in their definition of reverse engineering, but in short we can state:\nReverse engineering: the process of analyzing something in order to understand its mechanism of operation.\nReverse engineering is therefore divided into two main branches:\nSoftware reverse engineering: Reverse Code Engineering (RCE) Hardware reverse engineering: Hardware Reverse Engineering (HRE) In this workshop, we will focus on and delve into RCE.\nWhy is There a Need for Reverse Engineering in the First Place? This varies depending on the reverse engineer and their objectives:\n1. The Programmer\u0026rsquo;s Perspective (Developer) If you are the author of the program, you will most likely wish to debug your software in order to discover errors or their root causes. After discovering and correcting errors, you may wish to assess the strength of the program\u0026rsquo;s protection, that is, its susceptibility to being defeated by crackers. In this case, you would reverse engineer your own program with the aim of hardening it against cracking.\n2. The Cracker\u0026rsquo;s Perspective Crackers\u0026rsquo; motivations for learning reverse engineering differ from person to person or team to team:\nChallenge: adopting it as a tool to defeat protections and obfuscation techniques. Knowledge for all: sharing with others the techniques they have discovered. Breaking monopolies: assisting users in obtaining expensive software. Sabotage: adopting it as a tool for disruption, whether for financial motives (such as defeating a competitor\u0026rsquo;s software) or for other reasons. 🚁 To Simplify the Concept: The Drone Scenario No example is clearer than the world of weapons for simplifying this complex concept.\nImagine the following scenario: a highly advanced reconnaissance drone has crashed relatively intact within your territory. This aircraft is a \u0026ldquo;black box\u0026rdquo; to you; you observe the end result (an aircraft that flies, spies, and evades detection), yet you possess neither the engineering schematics, nor the source code that drives its engines, nor its encrypted communications system.\nFigure (1): Treating unknown technology as a black box.\nIn this scenario, the objective of reverse engineering is not to destroy the aircraft, but to understand it so that you can:\nBuild defensive counter-systems against it. Replicate the technology for your own advantage. Identify weaknesses in order to disable it in the future. What is Reverse Engineering Precisely? Reverse engineering is the process of analyzing a system (mechanical, electronic, or software) in order to determine its components and the relationships among them, and using this analysis to recreate a representation of the system that illustrates how it works (such as schematics or source code).\nIn the software context (the most prevalent today), you begin with a ready-to-run executable file (.exe or ELF) and lack the source code (Source Code) written by the programmers (such as C/C++). Your objective is: to transform this complex binary file (Machine Code) into a human-readable language in order to understand the detailed operation of the code (Functionality).\n⚙️ Stages of Reverse Engineering Whether the target is a mechanical weapon such as a rifle, or an electronic one such as malicious software, the process passes through four fundamental stages:\n1. Reconnaissance Before touching anything, the target\u0026rsquo;s behavior is observed:\nIn weapons: how are they loaded? What is the rate of fire? What type of ammunition is used? In software: the program is executed and its behavior is monitored (its network connections, the files it creates, and how it consumes memory). 2. Disassembly In weapons: disassembling the rifle piece by piece, screw by screw, to understand the mechanical mechanism of the trigger and firing chamber. In software: using tools called disassemblers to convert machine code (0s and 1s) into Assembly Language, a low-level language that accurately describes the operations executed by the processor. 3. Analysis and Comprehension Here the arduous mental work begins, where the disassembled pieces are connected to understand the overall logic:\nIn weapons: understanding that the particular shape of the feeding component is what enables automatic firing. Figure (2): Analysis of the mechanical mechanism of hardware and solid components.\nIn software: attempting to trace the execution path (Control Flow) through the code in order to reach the core \u0026ldquo;algorithm\u0026rdquo;, such as locating the encryption algorithm. Figure (3): Analysis of code flow and programming logic.\n4. Reconstruction (Decompilation) Reaching the highest level of understanding, where Assembly language is converted into a high-level programming language (such as C) using decompilers, thereby allowing the programming logic to be understood in a form closer to human language.\nConclusion Reverse engineering is not merely knowledge of how to use tools such as disassemblers and debuggers, but rather a mindset. It demands enormous patience, the ability to solve complex puzzles, and a very deep knowledge of how computers, operating systems, and processors work.\nBy understanding how to \u0026ldquo;take apart\u0026rdquo; technology, the reverse engineer acquires the ability to build better and more secure technology, much as the maker of armor learns by studying \u0026ldquo;projectiles\u0026rdquo;.\n","permalink":"https://outofsrvc.github.io/entry-p01nt/en/posts/2026-03-16-introduction-to-re/","summary":"\u003cp\u003eBismillah\u003c/p\u003e\n\u003ch2 id=\"introduction\"\u003eIntroduction\u003c/h2\u003e\n\u003cp\u003eFrom childhood, human beings possess an innate curiosity to understand \u003cem\u003e\u0026ldquo;how things work?\u0026rdquo;\u003c/em\u003e. It is this curiosity that drives a child to break apart a favorite toy in order to see the small motor inside it. In the advanced world of technology, this curiosity evolves into a precise and critical engineering discipline known as reverse engineering.\u003c/p\u003e\n\u003cp\u003eMost computer users may not have heard of reverse engineering before, perhaps because it is not as widespread as the field of hacking, or perhaps because they know it by another term, namely \u0026ldquo;cracking\u0026rdquo;.\u003c/p\u003e","title":"0x1. Introduction to Reverse Engineering"},{"content":"🚩 What is Entry P01NT? Entry P01NT is an open-source educational initiative aimed at demystifying reverse engineering (RE) and malware analysis for an Arabic-speaking audience.\nThis workshop is designed to serve as the bridge that carries you from a surface-level understanding of programming to a deep comprehension of how systems operate, and of how software communicates with hardware and the operating system in the language of the machine.\n🎯 Workshop Objectives Break down the fear barrier surrounding assembly language and complex analysis tooling. Provide a hands-on lab environment for learning through trial and error. Cultivate the mindset of a reverse engineer who is not satisfied with knowing how a program works, but why it behaves the way it does. 👤 About the Author Hello, I am P01NT (@outofsrvc).\nI am interested in cybersecurity, specifically malware analysis and reverse engineering. I built this workshop as a distillation of my own learning journey, intended to be the reference I wished I had when I started.\nFor contact or contributions: The repository is open to everyone on GitHub. I welcome your suggestions and corrections!\n*\"If you can't build it, you don't own it. If you can't break it, you don't understand it.\"* ","permalink":"https://outofsrvc.github.io/entry-p01nt/en/about/","summary":"\u003ch2 id=\"-what-is-entry-p01nt\"\u003e🚩 What is Entry P01NT?\u003c/h2\u003e\n\u003cp\u003eEntry P01NT is an open-source educational initiative aimed at demystifying reverse engineering (RE) and malware analysis for an Arabic-speaking audience.\u003c/p\u003e\n\u003cp\u003eThis workshop is designed to serve as the bridge that carries you from a surface-level understanding of programming to a deep comprehension of how systems operate, and of how software communicates with hardware and the operating system in the language of the machine.\u003c/p\u003e\n\u003ch3 id=\"-workshop-objectives\"\u003e🎯 Workshop Objectives\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eBreak down the fear barrier surrounding assembly language and complex analysis tooling.\u003c/li\u003e\n\u003cli\u003eProvide a hands-on lab environment for learning through trial and error.\u003c/li\u003e\n\u003cli\u003eCultivate the mindset of a reverse engineer who is not satisfied with knowing \u003cem\u003ehow\u003c/em\u003e a program works, but \u003cem\u003ewhy\u003c/em\u003e it behaves the way it does.\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"-about-the-author\"\u003e👤 About the Author\u003c/h2\u003e\n\u003cp\u003eHello, I am P01NT (\u003ca href=\"https://github.com/outofsrvc\"\u003e@outofsrvc\u003c/a\u003e).\u003c/p\u003e","title":"About"}]