[{"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/en/workshop/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":"Introduction to Reverse Engineering"},{"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/en/workshop/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":"Fundamentals of Reverse Engineering"},{"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/en/workshop/windows-architecture-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":"Windows Architecture \u0026 PE Format"},{"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/en/workshop/c-constructs-in-assembly/","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":"Recognizing C Code Constructs in Assembly"},{"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/en/workshop/cyber-attack-lifecycle/","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\" decoding=\"async\" loading=\"lazy\" src=\"/assets/img/workshop/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":"Cyber Attack Lifecycle"},{"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/en/workshop/basic-reconnaissance/","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":"Basic Reconnaissance"},{"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/en/workshop/re-toolkit/","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":"RE Toolkit: Disassemblers \u0026 Debuggers"},{"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/en/workshop/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":"The Reverse Engineer's Mindset"},{"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\nFigure (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/en/workshop/static-lab/","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=\"/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":"Static Lab"},{"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/en/workshop/dynamic-lab/","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=\"/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":"Dynamic Lab"},{"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/en/workshop/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":"After That"},{"content":"بسم الله\nIn this article, we are going to solve the first challenge of Flare-On (2015). As usual, we will rely on the Learning-by-Doing methodology and the Just-in-Time Learning approach.\n1. Downloading and Running the Challenge First, we download the challenge from the official website: flare-on.com\nArchive password: flare.\nLet\u0026rsquo;s start by running the file we have in front of us:\nFigure (1): Running the file for the first time\nWe copy the specified path where we will place the challenge file:\nFigure (2): Copying the challenge file path\nThe challenge file appears with the name: i_am_happy_you_are_to_playing_the_flareon_challenge.\nWe inspect the file with Detect It Easy (DIE):\nFigure (3): File information as shown by DIE\nAs shown in the image, the file is a PE32 executable written in x86 Assembly.\n2. First Run and Behavior Nice, let\u0026rsquo;s run the program:\nFigure (4): Running the program\nOkay, it is a console (DOS) program, not a GUI. Let\u0026rsquo;s try typing something:\nWhen we type anything, the CMD window closes immediately. The reason: the program executes very quickly and closes in the same instant.\nSo we open CMD ourselves, navigate to the program\u0026rsquo;s directory, and run it just by typing its name, then we try typing something again:\nFigure (5): Running the program from a CMD window\nAn error message appears: you are failure.\n3. Reviewing the Strings Great, this means the program currently contains two strings:\nEnter the password you are failure And surely there is a third string indicating that the password we entered is correct.\nLet\u0026rsquo;s open the file in IDA Pro and perform a static analysis:\nFigure (6): Opening the file inside IDA Pro\nWe open the Strings window by pressing SHIFT + F12:\nFigure (7): The Strings Window\nAll the strings contained in the program appear here. Let\u0026rsquo;s look closely at the one indicating a correct password: you are success.\n4. Following the Cross-References (Xrefs) We double-click the Enter the password string, and IDA takes us to the following view:\nFigure (8): Location of the Enter the password string in the disassembly\nAs we can see, both the success and failure strings are present, and there appears to be an array which, as expected, is the password. However, we notice that IDA does not recognize all the characters — so there is most likely a simple encryption applied.\nNow, we click on the aYouAreSuccess label:\nFigure (9): The aYouAreSuccess label\nThen we press X to open the cross-references window:\nFigure (10): The Xrefs window\nWe press OK, and IDA sends us to the function: loc_40104D:\nFigure (11): The verification function loc_40104D\n5. Analyzing the Algorithm As is clear, the array entered by the user — byte_402158 — is moved into the al register, then a simple XOR encryption is applied to it with the value 0x7D, and the result is compared against the array we saw earlier: byte_402140.\nWe double-click the byte_402140 array:\nFigure (12): The data of the byte_402140 array\nWe copy the array data completely, and use any AI model to perform an XOR with 0x7D against the array data, and a clear text appears:\nbunny_sl0pe@flare-on.com\nLet\u0026rsquo;s try it:\nFigure (13): Verifying the correct password\nAnd with this, we have successfully solved the challenge. To be continued, God willing.\n","permalink":"https://outofsrvc.github.io/en/posts/flare-on15-1/","summary":"\u003cp\u003eبسم الله\u003c/p\u003e\n\u003cp\u003eIn this article, we are going to solve the first challenge of \u003cstrong\u003eFlare-On (2015)\u003c/strong\u003e. As usual, we will rely on the \u003cstrong\u003eLearning-by-Doing\u003c/strong\u003e methodology and the \u003cstrong\u003eJust-in-Time Learning\u003c/strong\u003e approach.\u003c/p\u003e\n\u003ch2 id=\"1-downloading-and-running-the-challenge\"\u003e1. Downloading and Running the Challenge\u003c/h2\u003e\n\u003cp\u003eFirst, we download the challenge from the official website: \u003ca href=\"https://flare-on.com/\"\u003eflare-on.com\u003c/a\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eArchive password: \u003cstrong\u003eflare\u003c/strong\u003e.\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003eLet\u0026rsquo;s start by running the file we have in front of us:\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Running the file for the first time\" decoding=\"async\" loading=\"lazy\" src=\"/assets/img/flareon15/run1.png\"\u003e\n\u003cem\u003eFigure (1): Running the file for the first time\u003c/em\u003e\u003c/p\u003e","title":"Flare-On 2015: Solving Challenge 1"},{"content":"بسم الله\nIn this article, we are going to solve the first challenge of Flare-On (2014). We will rely — for this challenge and for most of the upcoming ones — on the Just-in-Time Learning methodology, also known as Learning-by-Doing.\nWhy Did We Start with Flare-On? Because these challenges are built around real-world techniques, and they are not just artificial CTF puzzles as commonly presented in competitions.\nImportant note: CTF challenges are only a bridge between theoretical learning and hands-on practice. They do not, in any way, prove that you are an expert in the field. Real experience is gained by working with real-world programs — whether malware, games, or software we reverse engineer.\nAny suggestion to improve these articles, any mistake, or any question — you can always reach out to me.\nIf I did well, it is by the grace of Allah; and if I erred, it is from myself and Satan.\n1. Downloading the Challenge and Initial Triage First, we download the challenge from the official website: flare-on.com\nArchive password: either flare or infected.\nWe begin by inspecting the program with Detect It Easy (DIE) to learn about it. We get the following information:\nFigure (1): File information as shown by DIE\nAs is clear, it is a PE32 program written in C#.\n2. Essential .NET Fundamentals Before we start solving, we need to understand a few things about .NET programs, because they are completely different from C/C++ programs.\nC/C++ Programs When writing programs in C/C++, we use a compiler (such as GCC). In short, the program goes through two stages:\nAhead-of-Time Compilation: the compiler takes the source code and converts it directly into machine code. Linking: external libraries are merged with the code to produce an executable (.exe). C# (.NET) Programs On the other hand, C#/.NET programs go through a different process, which we can call Managed Code: .NET programs are not compiled directly into machine language. Instead, they go through two stages and run inside a runtime environment called the CLR - Common Language Runtime.\nStage 1: Compile Time\nWhen building a C# program, it is not converted directly into machine code. Instead, the following happens:\nA .NET compiler (such as Roslyn) converts the code into an intermediate representation called IL - Intermediate Language. It is a language similar to assembly, but it is not tied to any specific CPU architecture. This intermediate code is compiled together with the metadata into an assembly file with a .dll or .exe extension. This same file can be taken and run on Linux, Windows, and macOS. Stage 2: Runtime\nWhen you open the program, the CLR (the .NET runtime engine) takes over:\nThe CLR reads the assembly file that contains the IL. It uses a compiler called JIT - Just-in-Time Compiler. The JIT converts the IL into native machine code at the very moment the program runs, converting only the parts that the program needs at that moment. 3. Running the Program and Observing Its Behavior Let\u0026rsquo;s run the program and observe its behavior:\nFigure (2): The initial program window\nAs you can see in the image, there is a character with \u0026ldquo;Let\u0026rsquo;s start with something easy!\u0026rdquo; written above it, and a Decode button below. When we press it, the image changes and appears as follows:\nFigure (3): The window after pressing the Decode button\nAs shown, the differences are clear in the image. What we need here is to figure out the encrypted text visible in the image.\n4. Decompiling with ILSpy As we explained above about how .NET programs are compiled, this makes many things easier for us, such as working with a decompiler while being confident that the code it outputs is exactly the original code. That is why we will use the ILSpy decompiler to handle this program.\nFigure (4): Opening the program in ILSpy\nSince we are dealing with a Form, we will focus on the resources embedded inside it:\nFigure (5): The resources inside the Form\nAs is clear, there are three files, and one of them is suspicious because it has the .encode extension — something related to encryption.\nNow, let\u0026rsquo;s move to the core logic that contains the encryption algorithm, so we look into the Form\u0026rsquo;s code:\nFigure (6): Browsing the Form\u0026rsquo;s code\nThe following code appears:\nFigure (7): The code shown in the ILSpy window\nbtnDecode_Click: This pattern is the code behind the Decode button (what happens when you click it):\nFirst, the image is replaced with one named bob_roge. It declares a byte array named dat_secret — the same one present in the Resources — which most likely represents the original text that gets encrypted. The encryption algorithm is applied. Here we notice the use of obfuscation. We will focus only on the text variable and the algorithm related to it:\nFigure (8): The algorithm in the code after removing the obfuscation\nThe algorithm consists of Nipple Swap and an XOR operation:\nNipple Swap: for example, if we have the byte 0011 1100, applying the swap to it turns it into 1100 0011; i.e., it swaps the right half with the left half. After the swap, it performs an XOR with the value 0x29. We simply ignore the rest of the code.\n5. Writing the Solver Script Now, we export the dat_secret file from the Resources:\nFigure (9): Exporting the dat_secret file\nWe will ask any AI model to write a Python solver script to decode the dat_secret file:\ndef decode_dat_secret(file_path): try: with open(file_path, \u0026#39;rb\u0026#39;) as f: dat_secret = f.read() except FileNotFoundError: print(\u0026#34;File not found. Make sure \u0026#39;dat_secret\u0026#39; is in the same directory.\u0026#34;) return None text = [] for b in dat_secret: # (b \u0026gt;\u0026gt; 4) grabs the high nibble # ((b \u0026lt;\u0026lt; 4) \u0026amp; 0xF0) grabs the low nibble and shifts it up dec_val = ((b \u0026gt;\u0026gt; 4) | ((b \u0026lt;\u0026lt; 4) \u0026amp; 0xF0)) ^ 0x29 if dec_val == 0x00: # stop at the null terminator break text.append(chr(dec_val)) return \u0026#34;\u0026#34;.join(text) if __name__ == \u0026#34;__main__\u0026#34;: file_name = \u0026#34;dat_secret\u0026#34; # put the file path here result = decode_dat_secret(file_name) print(\u0026#34;--- Decoded text ---\u0026#34;) print(result) Make sure the Python file is in the same directory as the dat_secret file.\nWe run the Python script:\nFigure (10): The text after decoding\nAnd with this, we have successfully finished solving the challenge. To be continued, God willing.\n","permalink":"https://outofsrvc.github.io/en/posts/flare-on-14-1/","summary":"\u003cp\u003eبسم الله\u003c/p\u003e\n\u003cp\u003eIn this article, we are going to solve the first challenge of \u003cstrong\u003eFlare-On (2014)\u003c/strong\u003e. We will rely — for this challenge and for most of the upcoming ones — on the \u003cstrong\u003eJust-in-Time Learning\u003c/strong\u003e methodology, also known as \u003cstrong\u003eLearning-by-Doing\u003c/strong\u003e.\u003c/p\u003e\n\u003ch2 id=\"why-did-we-start-with-flare-on\"\u003eWhy Did We Start with Flare-On?\u003c/h2\u003e\n\u003cp\u003eBecause these challenges are built around real-world techniques, and they are not just artificial CTF puzzles as commonly presented in competitions.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003eImportant note:\u003c/strong\u003e CTF challenges are only a bridge between theoretical learning and hands-on practice. They do not, in any way, prove that you are an expert in the field. Real experience is gained by working with real-world programs — whether malware, games, or software we reverse engineer.\u003c/p\u003e","title":"Flare-On 2014: Solving Challenge 1"},{"content":"I\u0026rsquo;m P01NT (@outofsrvc), a technical researcher specializing in reverse engineering, malware analysis, and low-level systems.\nMy focus is on dissecting executables (PE Format), analyzing malware encryption, and studying system behavior. I created the Entry P01NT workshop to make reverse engineering and disassembly concepts approachable. I have also published many technical articles that have exceeded 10,000+ views on the Arab Shell Network.\nThis blog is where I write down what I learn: technical articles, analyses, and a complete teaching workshop.\nThe Entry-P01NT Workshop The larger part of this site is the Entry-P01NT workshop — an open-source educational initiative built to make reverse engineering and malware analysis approachable, and to close the gap between theory and practice.\nIt is meant to be the bridge from a surface-level knowledge of programming to a deep understanding of how systems actually work, and how software talks to the hardware and the operating system in machine code. In short, it aims to:\nBreak down the fear of assembly and of complex analysis tooling. Provide practical labs for learning through trial and error. Build the mindset of a reverse engineer — someone not satisfied with knowing how a program works, but why it works that way. I designed the workshop as a distillation of my own learning path — the reference I wish had existed when I started.\nContact \u0026amp; Contributing The workshop repository is open to everyone on GitHub, and suggestions or corrections are always welcome.\nGitHub: @outofsrvc Twitter/X: @outofsrvc Telegram: @outofsrvce \u0026ldquo;Code never lies, documentation sometimes does\u0026rdquo; — Anonymous\n","permalink":"https://outofsrvc.github.io/en/about/","summary":"\u003cp\u003eI\u0026rsquo;m \u003cstrong\u003eP01NT\u003c/strong\u003e (\u003ca href=\"https://github.com/outofsrvc\"\u003e@outofsrvc\u003c/a\u003e), a technical researcher specializing in reverse engineering, malware analysis, and low-level systems.\u003c/p\u003e\n\u003cp\u003eMy focus is on dissecting executables (PE Format), analyzing malware encryption, and studying system behavior. I created the \u003cstrong\u003eEntry P01NT\u003c/strong\u003e workshop to make reverse engineering and disassembly concepts approachable. I have also published many technical articles that have exceeded \u003cstrong\u003e10,000+ views\u003c/strong\u003e on the \u003ca href=\"https://sh3ll.cloud/xf2/members/4161/\"\u003e\u003cstrong\u003eArab Shell Network\u003c/strong\u003e\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eThis blog is where I write down what I learn: technical articles, analyses, and a complete teaching workshop.\u003c/p\u003e","title":"About"}]