
Reverse-engineered Umgehung des Easy Anti-Cheat-Kernel-Treibers, die die Speicherzuweisung abfängt, um Verstoßpakete zu unterdrücken, mit Berichtentschlüsselungsroutinen und Analysenotizen.
Nicht mein Code. Nur zum Speichern https://www.unknowncheats.me/forum/anti-cheat-bypass/503052-easy-anti-cheat-kernel-packet-fucker.html
Dies ist der Easy Anti-Cheat Kernel Packet Fucker (kurz: EACKPFucker). Was ist das? Im Grunde werden Pakete über ihren Kernel-Mode-Treiber nicht mehr an sie gesendet, was bedeutet, dass deine Pasta-Pasta-2023-kdmapper-FUD-Bypasses ohne Probleme verwendet werden können.
Okay, du hast mich aus meiner Hose geholt. Wie zum Teufel funktioniert das? Indem man einfach eine Adresse ändert. Lass uns nun tief eintauchen, wie EAC tatsächlich funktioniert.
Von Anfang an muss Easy Anti-Cheat tatsächlich deine Daten erhalten, um dich bannen zu können. Diese Pakete werden über ihren Hydra-Kanal gesendet und sind kryptografisch sicher. Das ist alles, was du für diesen Bypass wissen musst, ich werde nicht näher darauf eingehen.
Schauen wir uns an, wie das in ihrem Kernel-Treiber funktioniert, mit einer zufälligen Violation:

Sieht das für dich nicht verwundbar aus? Denn für mich schon.
Schauen wir uns unsere erste Funktion an: kalloc_rt
Hmm, okay. Springen wir in alloc_pool_with_tag
Es importiert ExAllocatePoolWithTag dynamisch. Hmmmm... Ich frage mich, was passieren würde, wenn jemand dieses Qword auf seine modifizierte malloc-Funktion ändern würde... (ja, es funktioniert -- und da du einen beschreibbaren Abschnitt modifizierst, ist EAC nichts klüger)
Okay, jetzt haben wir die Kontrolle über die Speicherzuweisung. Cool! Was können wir damit machen?
Ich bin froh, dass du gefragt hast! Hier ist die Sache: Alle Pakete aus dem Kernel-Mode haben die Größe 33096i64.. uuund zuvor haben wir gesehen, dass EAC die Violation einfach.. ignoriert, wenn der Speicher nicht zugewiesen wird.
Okay, sagen wir, jemand würde einfach.. das tun:



---------------------------------------------------------------------------------------------------------------------------------------```C++ // report encryption looks like this (some parts may vary for each report, i believe they use key1, key2, key3 to use only 1 function for decryption) static report_t* encrypt(uint8_t* data, uint64_t size) {
report_t* packet = (report_t*)malloc(sizeof(report_t));
if (!packet) return nullptr;
uint32_t seed = 0x80BE5ED5 * ((uint64_t)&data >> 2);
memset(&packet->key1, 0, 0x8200);
packet->raw_size = 0;
packet->key1 = 0x66259F86; // gives key4?
packet->key2 = 0x21EBA81; // gives key5?
packet->key3 = 0xACE987AF; // gives key6?
packet->key4 = 0x50BFC583; // gives seed
packet->key5 = 0x3C61A927; // gives dynamic_key (from end)
packet->key6 = 0x70881859; // gives actual payload size
uint8_t* raw_data = packet->raw;
uint64_t raw_size = 24;
uint8_t* payload_data = packet->payload;
uint64_t payload_size = 0;
uint32_t dynamic_key = seed ^ 0x6957FDB6;
while (payload_size < size && payload_size < 0x8000) {
uint32_t a = (dynamic_key << 0xD) ^ dynamic_key;
uint32_t b = (a >> 0x11) ^ a;
uint32_t c = (b << 0x5) ^ b;
uint32_t d = _rotr(c, 2);
uint8_t shift = 8 * (payload_size & 3);
payload_data[payload_size] = data[payload_size] ^ (d >> shift);
dynamic_key = data[payload_size] ^ d;
payload_size++;
raw_size++;
}
uint64_t aligned_size = (raw_size + 0xFF) & ~0xFF; // align up by 0x100
while (raw_size < aligned_size) {
dynamic_key *= 0x80BE5ED5;
raw_data[raw_size++] = dynamic_key;
}
packet->key4 ^= seed;
packet->key5 ^= dynamic_key;
packet->key6 ^= payload_size;
packet->raw_size = raw_size;
return packet;
}
// thus my decryption looks like this static void decrypt(report_t* packet) {
uint32_t seed = packet->key4 ^ 0x50BFC583;
uint32_t dynamic_key = seed ^ 0x6957FDB6;
//uint32_t dynamic_key = packet->key5 ^ 0x3C61A927;
uint8_t* payload_data = packet->payload;
uint32_t payload_size = packet->key6 ^ 0x70881859;
for (uint32_t i = 0; i < payload_size; i++) {
uint32_t a = (dynamic_key << 0xD) ^ dynamic_key;
uint32_t b = (a >> 0x11) ^ a;
uint32_t c = (b << 0x5) ^ b;
uint32_t d = _rotr(c, 2);
uint8_t shift = 8 * (i & 3);
payload_data[i] ^= (d >> shift);
dynamic_key = payload_data[i] ^ d;
}
}
nach dem Ausgeben einiger Berichte und Entschlüsseln: