1 443
Subscribers
+224 hours
+1087 days
+11030 days
Posts Archive
1 443
But there are other possibilities
Object
contains an independent member of another class type
The program uses several Interfaces or polymorphic structures
The Pointers
that we see are not Vptr at all and have a different role
To identify, we need to check where each Pointer points and from what paths the virtual functions are called
Just seeing 2 addresses in memory is not enough to conclude
What is Pointer Adjustment
One of the important clues in Multiple Inheritance is the change of Pointer address during type conversion
Suppose we have a Pointer to Object of type Duck and we want to convert it to a Pointer related to Subobject of the second base class
If the second Subobject is located at a certain Offset, the Pointer address may change by the same Offset
In Assembly, we may see a pattern like this
lea rax, [rcx+0x10]
This instruction calculates the address that is 0x10 bytes ahead of the address in RCX
If this instruction If you see a pointer in the path of a pointer conversion or a function call related to the base class, it can be a clue to Pointer Adjustment. Of course, the lea command alone does not prove that a type conversion has occurred. It may have been used to calculate another address. We should also examine the surrounding commands and how the calculated address is used. What to look for in Ghidra. Check these items for inheritance analysis. Constructors. See what pointers are written at the beginning of the object or at other offsets. Destructors. Check if there is a similar pattern for different parts of the object. Vtables. See what functions the different tables point to and if there is a connection between their entries. Pointer Adjustment. Check if the object address changes in certain paths with a fixed offset. Virtual Calls. See which pointer and table each indirect call is made from. Cross-References. Check which functions are called from a Use Vtable or Constructor
Finally, try to build a hypothetical model of the Class Hierarchy and then check its accuracy with more evidence
The goal is not to draw a quick conclusion by seeing a command, but to put together several independent clues
In Reverse Engineering C++ Classes
Inheritance
is not just a logical relationship in the Source Code
This relationship can affect the memory layout, Vptrs, Vtables, and Pointer conversion paths
To correctly diagnose, we need to put several types of things together
Constructor
↓
Object Layout
↓
Vptr / Vtable
↓
Virtual Calls
↓
Pointer Adjustment
↓
Cross-Reference Analysis
↓
Class Hierarchy Hypothesis
Important principle
None of these signs alone prove Inheritance definitively
The power of analysis comes from putting independent things together
@reverseengine
1 443
This diagram is intended solely to illustrate the concept and does not represent a definitive layout.
The actual sizes of these components and their offsets depend on the specific classes and the ABI in use.
The key point is that with multiple inheritance, an object may contain multiple subobjects corresponding to its base classes.
Consequently, if these base classes are polymorphic, we might find more than one
vptr (virtual pointer) within the object.
Why is the presence of multiple vptrs significant to us? Suppose we encounter instructions like the following within a constructor:
mov qword ptr [rcx], offset VTable_A
mov qword ptr [rcx+0x10], offset VTable_B
This pattern indicates that values corresponding to the addresses of tables are being written at offsets 0x00 and 0x10.
One hypothesis is that the object contains multiple polymorphic subobjects—a situation that could arise due to multiple inheritance.1 443
Understanding Inheritance and Multiple Inheritance
Inheritance
How does inheritance affect memory in C++?
Suppose we have the following classes:
class Animal {
public:
int age;
virtual void speak() {}
};
class Dog : public Animal {
public:
int breed;
void speak() override {}
};
The
Dog class inherits from Animal.
This means that an object of type Dog contains not only its own specific members but also the portion corresponding to Animal.
Conceptually, the memory layout might look something like this:
Dog Object
+-------------------------+
| vptr | +0x00
+-------------------------+
| Animal::age | +0x08
+-------------------------+
| Dog::breed | +0x0C
+-------------------------+
This is merely an example of a potential layout within common 64-bit ABIs; the actual layout depends on the specific ABI, alignment rules, and compilation details.
An important point is that inheritance does not necessarily result in the members of the base class and the derived class being placed side-by-side as two independent objects.
In this example, the base class portion is contained within the object of the derived class.
What can we infer from the constructor?
Suppose that in the disassembly of a constructor, we encounter instructions similar to these:
mov qword ptr [rcx], offset Animal_vftable
mov dword ptr [rcx+0x8], 0
mov qword ptr [rcx], offset Dog_vftable
mov dword ptr [rcx+0xC], 1
This code is purely schematic; the actual instructions depend on the compiler and the ABI.
In the constructor of a derived class, the base class portion is typically initialized first, followed by the initialization specific to the derived class.
In some implementations, the value of the Vptr (virtual pointer) changes as the various constructors execute.
Therefore, if we observe multiple writes to the beginning of an object within a function, we should not immediately conclude that the object is corrupted or that it possesses multiple independent pointers.
We must examine the execution order of the constructors and the functions being called to understand the reason for these changes.
Vtable
How does it assist in identifying inheritance?
Suppose that in the disassembly, we encounter instructions similar to these:
mov rax, [rcx]
call qword ptr [rax+0x10]
In a common implementation, this pattern could be interpreted as follows:
A pointer is read from the beginning of the object.
Using that pointer, an entry is retrieved from the virtual function table (vtable).
The target function is then called indirectly. ...is called.
If we have several related classes, we might observe different Vtables; some of their entries may point to shared functions, while others point to distinct implementations.
This information can help identify relationships between classes, but the similarity of Vtables alone does not prove that one class inherits from another.
To reach a more precise conclusion, we must also examine constructors, destructors, object usage patterns, and cross-references.
Multiple Inheritance
Now, consider this example:
class Flyable {
public:
virtual void fly() {}
};
class Swimmable {
public:
virtual void swim() {}
};
class Duck : public Flyable, public Swimmable {
public:
void fly() override {}
void swim() override {}
};
The Duck class inherits from two base classes.
In a typical ABI (Application Binary Interface), the components corresponding to these two base classes might be located at different offsets within an object.
Duck Object
+-------------------------+
| Flyable subobject | +0x00
| vptr |
+-------------------------+
| Swimmable subobject | +0x08 (or another offset)
| vptr |
+-------------------------+
| Duck-specific members |
+-------------------------+1 443
اما احتمالهای دیگهای هم وجود داره
Object
شامل یک عضو مستقل از نوع کلاس دیگه ایه
برنامه از چند Interface یا ساختار چندریختی استفاده میکنه
Pointer
هایی که میبینیم اصلا Vptr نیستن و نقش دیگه ای دارن
برای تشخیص باید بررسی کنیم هر Pointer به کجا اشاره میکنه و توابع مجازی از چه مسیرهایی فراخوانی میشن
صرفا دیدن 2 آدرس در حافظه برای نتیجهگیری کافی نیست
Pointer Adjustment
چیه
یکی از سرنخ های مهم توی Multiple Inheritance تغییر آدرس Pointer هنگام تبدیل نوعه
فرض کنید یک Pointer به Object از نوع
Duck داریم و میخوایم اون رو به Pointer مربوط به Subobject کلاس پایه دوم تبدیل کنیم
اگه Subobject دوم در یک Offset مشخص قرار گرفته باشه ممکنه آدرس Pointer بهاندازه همون Offset تغییر کنه
توی Assembly ممکنه الگویی شبیه این ببینیم
lea rax, [rcx+0x10]
این دستور ادرسی رو محاسبه میکنه که 0x10 بایت جلوتر از آدرس موجود در RCX قرار داره
اگه این دستور توی مسیر تبدیل Pointer یا فراخوانی تابعی مرتبط با کلاس پایه دیده بشه میتونه سرنخی از Pointer Adjustment باشه
البته دستور lea بهتنهایی ثابت نمیکنه که تبدیل نوع اتفاق افتاده
ممکنه ازش برای محاسبه آدرس دیگهای استفاده شده باشه
باید دستورهای اطراف و نحوه استفاده از آدرس محاسبه شده رو هم بررسی کنیم
توی Ghidra دنبال چه چیزهایی بگردیم
برای تحلیل Inheritance این موارد رو بررسی کنید
Constructor ها
ببینید چه Pointer هایی در اول Object یا در Offset های دیگه نوشته میشن
Destructor ها
بررسی کنید الگوی مشابهی برای بخش های مختلف Object وجود داره یا نه
Vtableها
ببینید جدول های مختلف به چه توابعی اشاره میکنن و آیا بین ورودیهاشون ارتباطی وجود داره یا نه
Pointer Adjustment
بررسی کنید ادرس Object توی مسیرهای مشخصی با یک Offset ثابت تغییر میکنه
Virtual Call
ها
ببینید هر فراخوانی غیرمستقیم از کدوم Pointer و جدول انجام میشه
Cross-Reference ها
بررسی کنید کدوم توابع از یک Vtable یا Constructor استفاده میکنن
در اخر سعی کنید یک مدل فرضی از Class Hierarchy بسازید و بعد صحتش رو با شواهد بیشتری بررسی کنید
هدف این نیست که با دیدن یک دستور سریع نتیجه بگیریم بلکه باید چند سرنخ مستقل رو کنار هم بذاریم
توی Reverse Engineering کلاس های ++C
Inheritance
فقط یک رابطه منطقی توی Source Code نیست
این رابطه میتونه روی Layout حافظه و Vptr ها و Vtable ها و مسیرهای تبدیل Pointer تاثیر بذاره
برای تشخیص درست باید چند نوع چیز رو کنار هم قرار بدیم
Constructor
↓
Object Layout
↓
Vptr / Vtable
↓
Virtual Calls
↓
Pointer Adjustment
↓
Cross-Reference Analysis
↓
Class Hierarchy Hypothesis
اصل مهم
هیچکدوم از این نشونه ها به تنهایی Inheritance رو بهصورت قطعی ثابت نمیکنن
قدرت تحلیل از کنار هم گذاشتن چیزای مستقل به دست میاد
@reverseengine1 443
تشخیص Inheritance و Multiple Inheritance
Inheritance
در ++C چه تغییری توی حافظه ایجاد میکنه
فرض کنید این کلاسها رو داریم:
C
class Animal {
public:
int age;
virtual void speak() {}
};
class Dog : public Animal {
public:
int breed;
void speak() override {}
};
کلاس
Dog از Animal ارثبری میکنه
یعنی یک Object از نوع Dog علاوه بر اعضای مخصوص خودش بخش مربوط به Animal رو هم داخل خودش داره
بهصورت مفهومی Layout حافظه میتونه چیزی شبیه این باشه
Dog Object
+-------------------------+
| vptr | +0x00
+-------------------------+
| Animal::age | +0x08
+-------------------------+
| Dog::breed | +0x0C
+-------------------------+
این فقط یک نمونه از Layout احتمالی توی ABIهای رایج 64 بیتی هست و Layout واقعی به ABI و Alignment و جزئیات کامپایل بستگی داره
نکته مهم اینه که ارثبری لزوما باعث نمیشه اعضای کلاس پایه و کلاس فرزند بهصورت 2 تا Object مستقل کنار هم قرار بگیرن
توی این مثال بخش کلاس پایه داخل Object کلاس فرزند قرار گرفته
از روی Constructor چه چیزهایی میفهمیم
فرض کنید توی Disassembly تابع سازنده با دستورهایی شبیه این رو به رو بشیم:
mov qword ptr [rcx], offset Animal_vftable
mov dword ptr [rcx+0x8], 0
mov qword ptr [rcx], offset Dog_vftable
mov dword ptr [rcx+0xC], 1
این کد فقط یک مثال شماتیکه و جزئیات واقعی دستورها به Compiler و ABI بستگی داره
توی Constructor کلاس مشتق شده ممکنه اول بخش کلاس پایه مقدار دهی بشه و بعد تنظیمات مربوط به کلاس مشتقشده انجام بشه
توی بعضی پیادهسازیها مقدار Vptr هنگام اجرای Constructorهای مختلف تغییر میکنه
پس اگه توی یک تابع چند بار نوشتن روی ابتدای Object رو دیدیم نباید فورا نتیجه بگیریم که Object خراب شده یا چند Pointer مستقل داره
باید ترتیب اجرای Constructor ها و توابعی رو که فراخوانی میشن بررسی کنیم تا دلیل این تغییرات رو بفهمیم
Vtable
چه کمکی به تشخیص Inheritance میکنه
فرض کنید توی Disassembly با دستورهایی شبیه این روبهرو بشیم
mov rax, [rcx]
call qword ptr [rax+0x10]
توی یک پیادهسازی متداول این الگو میتونه به این معنی باشه
از ابتدای Object یک Pointer خونده میشه
از طریق اون Pointer یک ورودی از جدول توابع مجازی پیدا میشه
تابع موردنظر بهصورت غیرمستقیم فراخوانی میشه
اگه چند کلاس مرتبط داشته باشیم ممکنه Vtable های متفاوتی ببینیم که بعضی از ورودی هاشون به توابع مشترک اشاره میکنن و بعضی دیگه به پیادهسازیهای متفاوت
این اطلاعات میتونه به تشخیص رابطه بین کلاسها کمک کنه اما شباهت Vtable ها بهتنهایی ثابت نمیکنه که 2 کلاس از یکدیگر ارثبری میکنن
برای رسیدن به نتیجه دقیق تر باید Constructorها و Destructorها و نحوه استفاده از Object و Cross-Referenceها رو هم بررسی کنیم
Multiple Inheritance
حالا این مثال رو در نظر بگیرید
C
class Flyable {
public:
virtual void fly() {}
};
class Swimmable {
public:
virtual void swim() {}
};
class Duck : public Flyable, public Swimmable {
public:
void fly() override {}
void swim() override {}
};
کلاس Duck از 2 کلاس پایه ارثبری میکنه
توی یک ABI رایج بخشهای مربوط به این 2 کلاس پایه ممکنه در Offset های متفاوتی از یک Object قرار بگیرن
Duck Object
+-------------------------+
| Flyable subobject | +0x00
| vptr |
+-------------------------+
| Swimmable subobject | +0x08 یا Offset دیگه
| vptr |
+-------------------------+
| Duck-specific members |
+-------------------------+
این تصویر فقط برای توضیح مفهومه و یک Layout قطعی نیست
اندازه بخشها و Offset های واقعی به کلاسها و ABI بستگی دارن
نکته مهم اینه که توی Multiple Inheritance یک Object ممکنه چند Subobject مربوط به کلاسهای پایه داشته باشه
در نتیجه اگه این کلاسهای پایه چند ریختی باشن ممکنه بیشتر از یک Vptr داخل Object ببینیم
چرا وجود چند Vptr برای ما مهمه؟
فرض کنید توی Constructor با دستور هایی شبیه این رو به رو بشیم
mov qword ptr [rcx], offset VTable_A
mov qword ptr [rcx+0x10], offset VTable_B
این الگو نشون میده که در Offset های 0x00 و 0x10 مقادیری مرتبط با آدرس جدولها نوشته میشن
یکی از فرضیه ها اینه که Object چند Subobject چندریختی داره و این وضعیت ممکنه بهخاطر Multiple Inheritance باشه1 443
+
Virtual Memory Map
+
Module Metadata
+
Thread Activity
↓
Process Analysis
If discrepancies arise within this data, the cause must be investigated. Such discrepancies do not necessarily indicate malicious behavior; they may instead stem from how the process's transient state is captured, limitations of the tool being used, or the specific conditions under which the data was collected.
Relevance to EDR
In security analysis, module information serves as one of the sources for understanding the state of a process.
However, examining the list of modules alone is insufficient to fully understand all process activities.
Each of the following sources provides a different perspective on the application's state.
By synthesizing this information, an analyst can construct a more accurate picture of the application's behavior.
Practical Exercise with WinDbg:
To begin, use WinDbg on a test process and familiarize yourself with the following commands:
!peb
lm
The
!peb command displays information from the PEB (Process Environment Block), while the lm command is used to list the modules recognized within the debugger environment.
The output may vary depending on the debugging mode, the process architecture, and the version of the tool.
For this exercise, examine the following:
What is the name of the process's main image?
Which modules appear in the output?
How are the base address and size of the modules displayed?
Does the module information align with what you observe using other tools? The general model for this section looks like this:
Process
│
├── PEB
│ │
│ └── Loader Information
│ │
│ └── Module Metadata
│
└── Virtual Address Space
│
├── Image Memory
├── Private Memory
└── Other Regions
These structures are related, but they are not the same thing.
The key point is not to confuse the list of modules with the process's entire memory space. For an accurate analysis, you must examine the loader information alongside the actual state of the memory and evidence of the program's execution.
@reverseengine1 443
But there is one important point: Loader Information and the actual Memory state are two different views of the same Process. For accurate analysis, you may need to compare the two.
Loader Information
1 443
DLL, Module, PEB and LDR
How does Windows maintain information about the modules of a process?
So far we have talked about the usual PE upload, manual mapping and memory monitoring
Now we want to look at some internal Windows structures that are important for reverse engineering and analyzing process behavior
The four main concepts in this section are DLL, Module, PEB and LDR
What is the difference between DLL and Module?
These two terms are sometimes used interchangeably, but they are not exactly the same thing.
DLL
is a type of executable file that can be loaded into Windows, usually to provide reusable functions and features.
For example:
kernel32.dll
user32.dll
advapi32.dll
But Module is a broader term that usually refers to an image loaded into the Process address space at the time of program execution.
For example:
Process: example.exe
│
├── example.exe
├── kernel32.dll
├── user32.dll
└── Other Modules
The main executable file can also be considered a Module, so Module is not limited to DLLs. The important point is that not every Memory Region is necessarily a Module, and not everything that is in memory is necessarily visible in the Modules list.
PEB
stands for Process
Environment Block
This structure stores information about the environment and state of a Process in User Mode.
Simplified:
Process
│
▼
PEB
│
│
├── Process Parameters
├── Image Information
├── Loader-related Information
└── Other Process Stat
PEB
contains various information that parts of the Windows runtime environment use. Of course, PEB is not a fixed and uniform structure in all versions of Windows. Its internal details may differ between different versions and architectures.
Difference between PEB and EPROCESS
PEB
is located in the User Mode address space and should not be confused with internal Kernel structures such as EPROCESS.
In simple terms:
PEB
holds Process environmental information in User Mode.
EPROCESS
is an internal structure in the Kernel that is used to manage Process information. These two are related, but their tasks and locations are different.
LDR
In the discussion of Windows Loader, the term LDR usually refers to information and structures related to module management. One of the well-known structures in this field is PEB_LDR_DATA.
This structure holds information about the modules known to the Loader in a Process.
Simplified:
PEB
│
└── Loader Data
│
└── Module Information
│
├── Module A
├── Module B
└── Module C
Information for each module can include things like the base address, image size, and module name
Related structures also use linked lists to store module information
In Windows documentation and symbols, you may encounter these names:
PEB_LDR_DATA
LDR_DATA_TABLE_ENTRY
These structures are very important in reverse engineering because you may encounter them when examining the internal information of a process
How is the module list organized?
Loader
stores module information in lists, each of which has a different purpose
For a better understanding, see this simple model:
Loader Module List
│
▼
Module A
│
▼
Module B
│
▼
Module C
In Windows, these lists use linked structures
Of course, this image is just a mental model. The actual details of the structures, the relationships of the fields, and the order of the lists depend on the version and architecture of Windows
The important point is that the Module List does not show all the Virtual Memory of a Process. These lists provide information about the Modules that are registered in the structures related to the Loader
Why are these structures important to us?
Suppose you are examining a Process with WinDbg and you want to understand:
What modules does the Process have?
Where is the original
Image located?
Where is the information about a DLL stored?
What do Process structures have to do with the Loader?
Understanding PEB and LDR structures will help you analyze this information better.
1 443
+
Virtual Memory Map
+
Module Metadata
+
Thread Activity
↓
Process Analysis
اگر بین این اطلاعات اختلافی وجود داشته باشه باید علتش بررسی بشه این اختلاف لزوما نشانه رفتار مخرب نیست و ممکنه به نحوه اپلود وضعیت موقت Process محدودیت ابزار یا شرایط جمعآوری اطلاعات مربوط باشه
ارتباط این موضوع با EDR
در تحلیل امنیتی اطلاعات Module ها یکی از منابع شناخت وضعیت یک Process هستن
اما مشاهده فهرست Module ها به تنهایی برای شناخت تمام فعالیتهای Process کافی نیست
هرکدوم از منابع زیر نمای متفاوتی از وضعیت برنامه ارائه میدن
با ترکیب این اطلاعات تحلیلگر میتونه تصویر دقیقتری از رفتار برنامه به دست بیاره
تمرین عملی با WinDbg:
برای شروع روی یک Process ازمایشی از WinDbg استفاده کنید و با این دستورها آشنا بشید:
!peb
lm
دستور !peb اطلاعات قابل نمایش از PEB رو ارائه میده و دستور lm برای مشاهده Module های شناختهشده در محیط Debugger استفاده میشه
خروجی ممکنه با توجه به نوع Debugging معماری Process و نسخه ابزار متفاوت باشه
برای تمرین این موارد رو بررسی کنید:
Image
اصلی Process چه اسمی داره؟
چه Module هایی در خروجی دیده میشن؟
آدرس پایه و اندازه Module ها چطور نمایش داده میشن؟
اطلاعات Module با چیزی که از ابزارهای دیگه میبینید سازگاره؟
مدل کلی این بخش به این شکله:
Process
│
├── PEB
│ │
│ └── Loader Information
│ │
│ └── Module Metadata
│
└── Virtual Address Space
│
├── Image Memory
├── Private Memory
└── Other Regions
این ساختار ها به هم مرتبط هستن اما یکی نیستن
نکته اصلی اینه که فهرست Module ها رو با تمام حافظه Process اشتباه نگیرید برای تحلیل درست باید اطلاعات Loader رو در کنار وضعیت واقعی Memory و شواهد اجرای برنامه بررسی کنید
@reverseengine
1 443
DLL، Module، PEB و LDR
ویندوز چطور اطلاعات Module های یک Process رو نگه میداره؟
تا اینجا درباره PE اپلود معمولی Manual Mapping و بررسی Memory صحبت کردیم
حالا میخوایم بریم سراغ چند ساختار داخلی ویندوز که برای Reverse Engineering و تحلیل رفتار Process ها مهم هستن
چهار مفهوم اصلی این بخش DLL، Module PEB و LDR هستن
فرق DLL با Module چیه؟
این دو اصطلاح بعضی وقتا به جای هم استفاده میشن اما دقیقا یک مفهوم نیستن
DLL
نوعی فایل اجرایی قابل اپلود در ویندوزه که معمولا برای ارائه توابع و قابلیت های قابل استفاده دوباره به کار میره
مثلا:
kernel32.dll
user32.dll
advapi32.dll
اما Module اصطلاح گسترده تریه که در زمان اجرای برنامه معمولا به یک Image اپلود شده در فضای آدرس Process اشاره میکنه
برای نمونه:
Process: example.exe
│
├── example.exe
├── kernel32.dll
├── user32.dll
└── Other Modules
فایل اجرایی اصلی هم میتونه یک Module محسوب بشه پس Module فقط به DLL محدود نیست
نکته مهم اینه که هر Memory Region لزوما یک Module نیست و هر چیزی که در حافظه وجود داره هم لزوما در فهرست Moduleها دیده نمیشه
PEB
مخفف Process
Environment Block
هست
این ساختار اطلاعاتی درباره محیط و وضعیت یک Process در User Mode نگه میداره
ساده شده ش:
Process
│
▼
PEB
│
├── Process Parameters
├── Image Information
├── Loader-related Information
└── Other Process Stat
PEB
شامل اطلاعات مختلفیه که بخش هایی از محیط اجرای ویندوز از اونها استفاده میکنن البته PEB یک ساختار ثابت و یکسان در تمام نسخههای ویندوز نیست جزئیات داخلی اون ممکنه بین نسخه ها و معماریهای مختلف تفاوت داشته باشه
تفاوت PEB با EPROCESS
PEB
در فضای آدرس User Mode قرار داره و نباید اون رو با ساختارهای داخلی Kernel مثل EPROCESS یکی بدونیم
به زبان ساده:
PEB
اطلاعات محیطی Process رو در User Mode نگه میداره
EPROCESS
ساختاری داخلی در Kernel هست که برای مدیریت اطلاعات Process استفاده میشه
این دو با هم ارتباط دارن ولی وظایف و محل استفادهشون متفاوته
LDR
در بحث Loader ویندوز اصطلاح LDR معمولا به اطلاعات و ساختارهای مرتبط با مدیریت Module ها اشاره میکنه
یکی از ساختارهای شناختهشده در این زمینه PEB_LDR_DATA هست
این ساختار اطلاعاتی درباره Module های شناختهشده برای Loader در یک Process نگه میداره
ساده شده ش:
PEB
│
└── Loader Data
│
└── Module Information
│
├── Module A
├── Module B
└── Module C
اطلاعات هر Module میتونه شامل مواردی مثل آدرس پایه اندازه Image و نام Module باشه
ساختارهای مرتبط از فهرستهای پیوندی هم برای نگهداری اطلاعات Moduleها استفاده میکنن
در مستندات و Symbol های ویندوز ممکنه با این نامها روبهرو بشید:
PEB_LDR_DATA
LDR_DATA_TABLE_ENTRY
این ساختار ها در Reverse Engineering اهمیت زیادی دارن چون هنگام بررسی اطلاعات داخلی یک Process ممکنه باهاشون برخورد کنید
فهرست Module ها چطور سازماندهی میشه؟
Loader
اطلاعات Module ها رو در فهرستهایی نگه میداره که هرکدوم کاربرد متفاوتی دارن
برای درک بهتر، این مدل ساده رو ببینید:
Loader Module List
│
▼
Module A
│
▼
Module B
│
▼
Module C
در ویندوز این فهرست ها از ساختار های پیوندی استفاده میکنن
البته این تصویر فقط یک مدل ذهنیه جزئیات واقعی ساختارها ارتباط فیلدها و ترتیب فهرست ها به نسخه و معماری ویندوز بستگی داره
نکته مهم اینه که فهرست Module ها تمام Virtual Memory یک Process رو نشون نمیده این فهرستها اطلاعات مربوط به Module هایی رو ارائه میدن که در ساختارهای مربوط به Loader ثبت شدن
چرا این ساختارها برای ما مهمن؟
فرض کنی داری یک Process رو با WinDbg بررسی میکنید و میخواید بفهمید:
Process
چه Module هایی داره؟
Image
اصلی در چه آدرسی قرار گرفته؟
اطلاعات مربوط به یک DLL کجا نگهداری میشه؟
ساختارهای Process چه ارتباطی با Loader دارن؟
شناخت PEB و ساختارهای LDR کمکتوت میکنه این اطلاعات رو بهتر تحلیل کنیو
اما یک نکته مهم وجود داره
اطلاعات Loader و وضعیت واقعی Memory دو نمای متفاوت از یک Process هستن برای تحلیل دقیق ممکنه لازم باشه این دو رو با هم مقایسه کنید
Loader Information1 443
Reverse Engineer Anything v6.5.0
A tool for reverse engineering that allows AI agents to analyze applications and binary files without access to the source code
https://github.com/morluto/rea
@reverseengine
1 443
Someone Used AI to Reverse-Engineer PS5 Security in Weeks: What Is REA?
https://pub.towardsai.net/someone-used-ai-to-reverse-engineer-ps5-security-in-weeks-what-is-rea-11aed6dd106e
1 443
How Dangerous Is REA (Reverse Engineer Anything) for Your App?
https://21zerixpm.medium.com/how-dangerous-is-rea-reverse-engineer-anything-for-your-app-2fce588968f1
@reverseengine
1 443
REA Is Impressive. But Reverse Engineering Was Never the New Part
https://crizantlai.medium.com/rea-is-impressive-but-reverse-engineering-was-never-the-new-part-ae5b26b958a1
1 443
QuarkslaB Dynamic binary Instrumentation
https://qbdi.quarkslab.com/introduction
@reverseengine
1 443
angr’s documentation
https://docs.angr.io/en/latest/welcome-to-angr-s-documentation
@reverseengine
1 443
Writing a Hyper-V Bridge for Fuzzing
https://www.alex-ionescu.com/writing-a-hyper-v-bridge-for-fuzzing-part-1-wdf
@reverseengine
1 443
Cutter is a free and open-source reverse engineering
https://github.com/rizinorg/cutter
@reverseengine
1 443
Consider this:
If a memory region does not appear in the list of loaded modules, should we conclude that it is necessarily malicious or unrelated to any executable file?
To reach a conclusion, we must examine the memory structure, the origin of the region, and the process's behavior in conjunction with one another.
What evidence does an analyst examine?
When investigating an unusual memory region, the following types of information can be useful:
None of these factors, taken in isolation, constitute definitive proof; the real value lies in how they are correlated with one another.
Relevance to EDR and Memory Forensics
From a defensive perspective, a key question arises:
Is it possible to identify all behaviors associated with code execution solely by examining the list of loaded modules? No.
The module list provides only a limited view of the process's state. A more thorough investigation may require data such as:
Process
|
├── Module Inventory
├── Virtual Memory Map
├── Memory Protection
├── Thread Information
├── Call Stack
└── Event Timeline
|
v
Behavioral Analysis
This facilitates a better distinction between the application's normal behavior and anomalous activity.
An important caveat:
Not all EDR (Endpoint Detection and Response) solutions have equal access to this information, nor do they all analyze it in the same way; the outcome depends on the quality of the product and the available telemetry.
Conceptual Exercise:
Compare the following two scenarios:
Scenario 1:
Region Type: Image
Module: Known DLL
Protection: RX (Read/Execute)
Scenario 2:
Region Type: Private
Module: No clear association
Protection: RX (Read/Execute)
Based solely on this information, one cannot definitively label the second scenario as malicious; however, it may warrant further data collection.
For both scenarios, ask the following question:
Is the memory structure consistent with the region type? Do the threads and the call stack provide relevant information?
Are there events occurring before and after the creation of a memory region?
Keep these three concepts distinct:
Standard Image Loading:
Loading via the conventional Windows path and managing the associated steps.
Manual Mapping:
Preparing an image in memory using loading logic that differs from the standard path.
Memory Forensics:
Examining the structure and state of memory to understand the events that took place within a process.
While related, these three concepts are not the same.
@reverseengine
