این دو تا رو همیشه جدا نگه دارید
Crash
↓
چه اتفاقی افتاد
ولی
Root Cause
↓
چرا این اتفاق افتاد
مثلا:
Crash
↓
SIGSEGV
↓
Invalid Memory Access
هنوز Root Cause مشخص نیست
ممکنه بعد از بررسی بفهمیم
Input
↓
Unsafe Copy
↓
Buffer Overflow
↓
Memory Corruption
↓
Crash
اینجا دیگه علت اصلی رو پیدا کردیم
از دید Reverse Engineer:
وقتی یک Crash دارید مدام این سوالها رو از خودتون بپرسید
CPU
کجا Crash کرد
کدوم Instruction مشکلدار بود
کدوم Register یا Address درگیر بود
این مقدار از کجا اومده
چه دادهای باعث رسیدن به این وضعیت شده
اولین جایی که رفتار اشتباه ایجاد شده کجاست
آخرین سؤال از همه مهمتره
چون ممکنه Crash در یک نقطه اتفاق بیفته ولی Bug چند تابع قبلتر ایجاد شده باشه
وقتی یک Crash پیدا کردیم
مستقیم نمیگیم علت باگ رو فهمیدیم
اول محل Crash رو پیدا میکنیم
بعد Instruction مشکلدار رو بررسی میکنیم بعد Register ها و Memory رو نگاه میکنیم بعد مسیر داده رو به عقب دنبال میکنیم تا برسیم به جایی که مشکل واقعا ایجاد شده
یعنی
Crash
↓
Where
↓
How
↓
Why
↓
Root Cause
و این دقیقا تفاوت بین دیدن Crash و فهمیدن باگ هست
@reverseengine
Crash
↓
چه اتفاقی افتاد
ولی
Root Cause
↓
چرا این اتفاق افتاد
مثلا:
Crash
↓
SIGSEGV
↓
Invalid Memory Access
هنوز Root Cause مشخص نیست
ممکنه بعد از بررسی بفهمیم
Input
↓
Unsafe Copy
↓
Buffer Overflow
↓
Memory Corruption
↓
Crash
اینجا دیگه علت اصلی رو پیدا کردیم
از دید Reverse Engineer:
وقتی یک Crash دارید مدام این سوالها رو از خودتون بپرسید
CPU
کجا Crash کرد
کدوم Instruction مشکلدار بود
کدوم Register یا Address درگیر بود
این مقدار از کجا اومده
چه دادهای باعث رسیدن به این وضعیت شده
اولین جایی که رفتار اشتباه ایجاد شده کجاست
آخرین سؤال از همه مهمتره
چون ممکنه Crash در یک نقطه اتفاق بیفته ولی Bug چند تابع قبلتر ایجاد شده باشه
وقتی یک Crash پیدا کردیم
مستقیم نمیگیم علت باگ رو فهمیدیم
اول محل Crash رو پیدا میکنیم
بعد Instruction مشکلدار رو بررسی میکنیم بعد Register ها و Memory رو نگاه میکنیم بعد مسیر داده رو به عقب دنبال میکنیم تا برسیم به جایی که مشکل واقعا ایجاد شده
یعنی
Crash
↓
Where
↓
How
↓
Why
↓
Root Cause
و این دقیقا تفاوت بین دیدن Crash و فهمیدن باگ هست
@reverseengine
ReverseEngineering
بخش سی و یکم بافر اور فلو Root Cause Analysis پیدا کردن علت واقعی Crash توی قسمت قبل یاد گرفتیم وقتی Fuzzer کلی Crash پیدا میکنه چطور اونها رو دستهبندی کنیم حالا میخوایم یک مرحله عمیقتر بشیم این بار فقط نمیخوایم بدونیم برنامه کجا Crash کرده میخوایم…
Part 31 Buffer Overflow
Root Cause Analysis
Finding the Real Cause of a Crash
In the previous part, we learned how to classify crashes when a Fuzzer finds them. Now we want to go a step deeper. This time, we don't just want to know where the program crashed.
We want to understand.
Why it crashed.
Because saying.
Program crashed.
doesn't really help.
It's almost like a car broke down and the mechanic just said.
The car broke down.
Well, thanks for this great discovery.
Crash.
itself is not a bug.
Suppose the debugger shows this.
SIGSEGV.
This means that the program has reached an invalid memory access, but we still don't know why it happened.
It could be one of these.
Buffer Overflow.
Use After Free.
Out of Bounds Read.
Null Pointer Dereference.
So we have to go after the crash itself. Let's go
Crash
↓
What happened
↓
Why happened
↓
Root Cause
Find the problematic instruction
Suppose the Debugger shows this instruction
mov eax,[rcx]
and the program crashes right here
Here the first question is
What is the value of RCX
For example
RCX = 0x00000000000000000
Well here the program is actually reading something from address zero, so the path could be like this
mov eax,[rcx]
↓
RCX = 0
↓
Invalid Memory Access
↓
Crash
But we haven't found the root cause yet
We need to understand
Why RCX is zero
Checking the Registers
After the Crash, we check the status of the Registers
For example:
RAX = 0x000000001
RBX = 0x00000000
RCX = 0x00000000
RDX = 0x00000020
RIP = 0x401234
Here RIP tells us where the CPU was approximately at the time of the Crash
And RCX can also give us important information about the address that was supposed to be used
But the main question is still the same
RCX
↓
Where did it come from
Let's go back
Suppose we have these instructions before the Crash
mov rcx,[rbp-20h]
mov eax,[rcx]
So RCX got its value from here
mov rcx,[rbp-20h]
Now we need to go back one more step
And see
[rbp-20h]
How did it get its value
For example, we may have had something like this before
mov [rbp-20h], rdi
Now we ask
Where did RDI come from
And we go back like this
Crash
↓
RCX
↓
[rbp-20h]
↓
RDI
↓
Function Argument
↓
Input
Here we are getting closer to the source of the problem
General Analysis Path
This is the path we work with a lot during Root Cause Analysis
Crash
↓
Faulting Instruction
↓
Register / Memory
↓
Previous Instruction
↓
Data Origin
↓
Root Cause
That is, we do not just look at the last instruction
We look at how this situation arose
This is where Reverse Engineering really shows itself
A simple example:
Suppose the code is
C
void process(char *input)
{
char buffer[8];
strcpy(buffer, input);
printf("%s", buffer);
}
Now suppose the input is too large
input
↓
strcpy
↓
buffer
↓
Stack Corruption
↓
Crash
The program may crash later, for example, inside printf
If we just say
Crash in printf
Our analysis is incomplete
Because the main problem may have occurred much earlier
Where is the Root Cause
Here
buffer = 8 bytes
input = larger than 8 bytes
strcpy
↓
No bounds checking
↓
Stack Buffer Overflow
That is, strcpy wrote more data than the buffer capacity
and caused memory corruption
So
Crash
≠
Root Cause
Crash
is the final result
Root Cause
Where the problem actually occurred
Another example
Suppose the debugger shows
mov rax,[rbx]
and
RBX = 0
We may say
Null Pointer Dereference
But it is still better to stop here Let's sit
We need to check
RBX
↓
How did it get its value
↓
Why did it become NULL
↓
Should it have been checked before
↓
Root Cause
We may find that a function returned a NULL value but the program used it without checking it, so mov rax,[rbx] itself is only where the problem showed itself, not the problem itself
Why is this step important for Fuzzing
Suppose the Fuzzer found this
Crash found
input_0421.dat
So what now
We still don't know what we are dealing with
It may be:
Crash
↓
Heap Buffer Overflow
or
Crash
↓
Use After Free
or
Crash
↓
Out of Bounds Read
or
Crash
↓
Null Pointer Dereference
ReverseEngineering
بخش سی و یکم بافر اور فلو Root Cause Analysis پیدا کردن علت واقعی Crash توی قسمت قبل یاد گرفتیم وقتی Fuzzer کلی Crash پیدا میکنه چطور اونها رو دستهبندی کنیم حالا میخوایم یک مرحله عمیقتر بشیم این بار فقط نمیخوایم بدونیم برنامه کجا Crash کرده میخوایم…
That's why after finding the Crash, we need to enter the analysis stage
Fuzzer
↓
Crash
↓
Debugger
↓
Root Cause Analysis
↓
Bug Classification
Don't confuse Root Cause and Crash
Always keep these two separate
Crash
↓
What happened
But
Root Cause
↓
Why did it happen
For example:
Crash
↓
SIGSEGV
↓
Invalid Memory Access
The Root Cause is still unknown
We may find out after investigation
Input
↓
Unsafe Copy
↓
Buffer Overflow
↓
Memory Corruption
↓
Crash
Here we have found the root cause
From the Reverse Engineer's perspective:
When you have a Crash, keep asking yourself these questions
Where did the CPU crash
Which instruction was problematic
Which register or address was involved
Where did this value come from
What data caused this situation
Where was the first place where the wrong behavior occurred
The last question is the most important
Because the Crash may have occurred at one point but the Bug may have occurred several functions earlier
When We found a crash
We don't say we found the cause of the bug
First we find the location of the crash
Then we examine the problematic instruction, then we look at the registers and memory, then we follow the data path back to where the problem actually occurred
That is
Crash
↓
Where
↓
How
↓
Why
↓
Root Cause
And this is exactly the difference between seeing a crash and understanding a bug
@reverseengine
Fuzzer
↓
Crash
↓
Debugger
↓
Root Cause Analysis
↓
Bug Classification
Don't confuse Root Cause and Crash
Always keep these two separate
Crash
↓
What happened
But
Root Cause
↓
Why did it happen
For example:
Crash
↓
SIGSEGV
↓
Invalid Memory Access
The Root Cause is still unknown
We may find out after investigation
Input
↓
Unsafe Copy
↓
Buffer Overflow
↓
Memory Corruption
↓
Crash
Here we have found the root cause
From the Reverse Engineer's perspective:
When you have a Crash, keep asking yourself these questions
Where did the CPU crash
Which instruction was problematic
Which register or address was involved
Where did this value come from
What data caused this situation
Where was the first place where the wrong behavior occurred
The last question is the most important
Because the Crash may have occurred at one point but the Bug may have occurred several functions earlier
When We found a crash
We don't say we found the cause of the bug
First we find the location of the crash
Then we examine the problematic instruction, then we look at the registers and memory, then we follow the data path back to where the problem actually occurred
That is
Crash
↓
Where
↓
How
↓
Why
↓
Root Cause
And this is exactly the difference between seeing a crash and understanding a bug
@reverseengine
A Year of Hacking with LLMs
https://sites.google.com/site/zhiniangpeng/blogs/Hacking-with-LLMs-Eng
@reverseengine
https://sites.google.com/site/zhiniangpeng/blogs/Hacking-with-LLMs-Eng
@reverseengine
Google
A Year of Hacking with LLMs
This blog is a summary of my talk at the Offbyone 2026 cybersecurity conference. It records some of my thoughts as a cybersecurity researcher after spending a year using LLMs for research.
Slides: https://github.com/edwardzpeng/presentations/tree/main/offbyone%202026…
Slides: https://github.com/edwardzpeng/presentations/tree/main/offbyone%202026…
Flicker and fall: rooting the Philips Hue Bridge both remotely and wirelessly
https://blog.thalium.re/posts/rooting-the-philips-hue-bridge-remotely-and-wirelessly
@reverseengine
https://blog.thalium.re/posts/rooting-the-philips-hue-bridge-remotely-and-wirelessly
@reverseengine
THALIUM
Flicker and fall: rooting the Philips Hue Bridge both remotely and wirelessly
The Philips Hue Bridge is the control center of the Hue lighting system. As part of Pwn2Own Ireland 2025, we identified several bugs which allowed fully compromising the bridge locally or remotely, including a vulnerability chain in the HomeKit component…
Silverseal is a Linux framework containing a bootkit, rootkit loader and a rootkit
https://github.com/Idov31/Silverseal
@reverseengine
https://github.com/Idov31/Silverseal
@reverseengine
GitHub
GitHub - Idov31/Silverseal: Silverseal is a Linux framework containing a bootkit, rootkit loader and a rootkit
Silverseal is a Linux framework containing a bootkit, rootkit loader and a rootkit - Idov31/Silverseal
Golang loader that uses vulnerable drivers to terminate EDR and antivirus processes before dropping Formbook
https://youtu.be/Wz6ROkJ3AZg?si=cO8uan3vRo7NTZZs
https://youtu.be/Wz6ROkJ3AZg?si=cO8uan3vRo7NTZZs
YouTube
Golang BYOVD Malware Loader and Vulnerable Driver Analysis (Stream - 08/09/2026)
In this stream we analyze a Golang loader that drops and exploits drivers (also known as Bring Your Own Vulnerable Driver or BYOVD) to terminate antivirus and EDR processes prior to downloading and executing a Formbook payload. We also analyze the drivers…
Bhatia_Sumit,_Gabhane_Chetan_Reverse_Engineering_with_Terraform.pdf
3.9 MB
Reverse Engineering with Terraform
Packt.Mobile.App.Reverse.Engineering.pdf
17.3 MB
Mobile App Reverse Engineering: Get started with discovering, analyzing, and exploring the internals of Android and iOS apps
@reverseengine
@reverseengine
Working, tested code for every chapter of the book The Art of Exploit Development: Vulnerability Research and Exploitation on Today's Hardened Systems.
https://github.com/KazamaDono/taoxd
https://github.com/KazamaDono/taoxd
GitHub
GitHub - KazamaDono/taoxd: The Art of Exploit Development companion code.
The Art of Exploit Development companion code. Contribute to KazamaDono/taoxd development by creating an account on GitHub.
Windows Exploitation Techniques: Dangling COM Object Registrations
https://projectzero.google/2026/09/windows-dangling-com.html
https://projectzero.google/2026/09/windows-dangling-com.html
projectzero.google
Windows Exploitation Techniques: Dangling COM Object Registrations
This short blog post is about abusing a privilege escalation bug that Microsoft recently fixed in...
BigDiskBuste
Windows Defender Update Denial of Service Vulnerability.
https://github.com/MSNightmare/BigDiskBuster
Windows Defender Update Denial of Service Vulnerability.
https://github.com/MSNightmare/BigDiskBuster
GitHub
GitHub - MSNightmare/BigDiskBuster: Windows Defender Update Denial of Service Vulnerability
Windows Defender Update Denial of Service Vulnerability - MSNightmare/BigDiskBuster
قسمت سی و دوم بافر اورفلو
Program Slicing
فقط کدهایی که واقعا به درد تحلیل میخورن
یعنی یک داده رو از نقطه ورود تا محل استفاده دنبال کردیم
حالا فرض کنید برنامه چند هزار دستور داره
قرار نیست همه رو خط به خط بخونیم
Program Slicing
کمک میکنه فقط قسمت هایی از برنامه رو که روی یک مقدار مشخص تأثیر دارن جدا کنیم
Program Slicing
فرض کنید یک مقدار داریم
user_input
و میخوایم بدونیم چه قسمتهایی از برنامه روی این مقدار تأثیر میذارن
مثلا:
Input
↓
Function A
↓
Function B
↓
Function C
↓
Crash
به جای بررسی کل برنامه
فقط همین مسیر رو بررسی میکنیم
دو نوع اصلی
Forward Slice
از یک مقدار شروع میکنیم و جلو میریم
سؤال اصلی
این مقدار کجا استفاده میشه
مثلا:
input
↓
buffer
↓
memcpy
↓
target
Backward Slice
از یک نقطه مهم شروع میکنیم و به عقب برمیگردیم
مثلا Crash داریم
Crash
↑
memcpy
↑
buffer
↑
input
سوال اصلی
این مقدار از کجا اومده
یک مثال ساده:
فرض کنید کد اینه
C
int process(int input)
{
int a = input;
int b = a + 10;
int c = b * 2;
int unrelated = 500;
return c;
}
اگر هدف ما مقدار
c باشهلازم نیست
unrelated رو بررسی کنیمچون روی
c تاثیری ندارهSlice
تقریبا این بخشه
input
↓
a
↓
b
↓
c
در Reverse Engineering چرا مهمه؟
فرض کنید یک Crash دارید
و Stack Trace به یک تابع بزرگ میرسه
مثلا:
process_packet()
این تابع ممکنه صدها خط کد داشته باشه
ولی Crash فقط به یک مقدار خاص وابسته باشه
مثلا:
length
حالا به جای بررسی کل تابع
مسیر
length رو دنبال میکنیمlength
↓
check
↓
calculation
↓
buffer operation
↓
Crash
وابستگی دادهای
مثلا:
C
int size = input_length;
int copy_size = size + 8;
memcpy(buffer, input, copy_size);
اینجا
copy_size به size وابسته استو
size هم به input_lengthپس مسیر داده اینه
input_length
↓
size
↓
copy_size
↓
memcpy
این دقیقا چیزی هست که موقع Slicing میخوایم پیدا کنیم
وابستگی کنترلی هم مهمه
گاهی مقدار مستقیما منتقل نمیشه ولی روی تصمیم برنامه تاثیر میذاره
مثلا:
C++
if (size > 100)
{
process_large_input();
}
اینجا
size تعیین میکنه کدوم مسیر اجرا بشهپس علاوه بر Data Dependency
یک Control Dependency هم داریم
در Ghidra یا IDA
وقتی یک متغیر یا Register مهم پیدا کردید
میتونی References و مسیرهای
استفاده از اون رو بررسی کنید
مثلا:
Variable
↓
References
↓
Functions
↓
Instructions
بعد کم کم Slice موردنظر رو تشکیل میدید
در ابزارهای پیشرفتهتر هم میشه این کار رو به شکل خودکارتر انجام داد
تفاوت Data Flow و Slicing
خیلی ساده
Data Flow
میگه داده چطور حرکت میکنه
Program Slicing
میگه برای تحلیل یک مقدار خاص دقیقا کدوم قسمتهای برنامه مهم هستن
پس
Data Flow
↓
مسیر حرکت داده
Program Slicing
↓
بخش مرتبط با یک داده یا نتیجه خاص
وقتی با یک باینری بزرگ روبهرو شدیم
لازم نیست کل برنامه رو بررسی کنیم
میتونیم یک مقدار مهم مثل
Input
Length
Pointer
Crash Value
رو انتخاب کنیم
بعد مسیر وابستگیهای اون رو پیدا کنیم
در نتیجه حجم زیادی از کد که ارتباطی با مسئله ما نداره کنار گذاشته میشه
و تحلیل خیلی سریعتر میشه
@reverseengine