Welcome to hackvshack.net Forum!
Download Free HvH CS2/CS:GO Cheats, CFG, LUA/JS Scripts, and More!
Register

Safe Net Kobalt Beta (early Access) | Internal Legit cheat | Updated: 22nd May 2026

Status
Thread closed. Topic resolved/outdated. For updates, start new thread. Files removed to save server space.
You're mixing up two things that have nothing to do with each other. UI polish and the actual engineering behind a cheat are completely different skillsets. I spend my time on what actually matters for the users and I'm sure you know Kobalt is in BETA.

You also dodged what I asked. Show me your work and then I can challenge you on the real stuff.
I am not dodging because i dont think there is a point in doing so, the next thing is that the issue isnt 2-3 rushed UI parts, its all of them, every single part of the UI is horribly made.

this is a little off topic but something i noticed is and wanted to ask you on, why are you importing the VMProtect SDK statically inside your loader, this makes absolutely no sense from a security perspective.1779595660519.png
 
I feel like youre missing the point on what ive just said, you cannot tell people to do something that you cannot do yourself. you clearly use ImGui in your loader yet it looks like absolute garbage, ImGui is by far one of the easiest UI libraries out there yet you cannot work with it properly, cant implement rounded corners which ImGui can handle with ease :D
I appreciate the reports, I’ll add them to my ‘easy to‑do list’ once I finish the things that matter most.
 
I am not dodging because i dont think there is a point in doing so, the next thing is that the issue isnt 2-3 rushed UI parts, its all of them, every single part of the UI is horribly made.

this is a little off topic but something i noticed is and wanted to ask you on, why are you importing the VMProtect SDK statically inside your loader, this makes absolutely no sense from a security perspective.1779595660519.png
I had VMProtect on the loader earlier in development and dropped it later, the SDK header stayed in the source so the imports still resolve at link time, but the calls are dead (IsProtected returns false on an unpacked binary, IsValidImageCRC returns true). No actual protection logic running. It's leftover noise though, I'll strip it whenever I do tbh
 
I had VMProtect on the loader earlier in development and dropped it later, the SDK header stayed in the source so the imports still resolve at link time, but the calls are dead (IsProtected returns false on an unpacked binary, IsValidImageCRC returns true). No actual protection logic running. It's leftover noise though, I'll strip it whenever I do tbh
This feels like a excuse but ill take it, since its literally 30 seconds worth of work to remove it from your project. a little bit funnier to me is the frankenstein DIE output of the Loader:

1779596169773.png

but i myself could imagine this happens due to bass.dll being embedded and whatnot. still pretty funny.
 
This feels like a excuse but ill take it, since its literally 30 seconds worth of work to remove it from your project. a little bit funnier to me is the frankenstein DIE output of the Loader:

1779596169773.png

but i myself could imagine this happens due to bass.dll being embedded and whatnot. still pretty funny.
The small embedded PE is a kernel driver (no longer using it - same excuse too lazy to clean it), bundled so the loader drops and loads it at runtime. The bigger one (~163KB) is bass.dll for radio and yt audio (no longer relying on it). bass uses an ancient toolchain with custom section names so DIE flags it as packed every time, so it's a false positive, you'd see the exact same warnings on a clean BASS download from un4seen.com.
 
The small embedded PE is a kernel driver (no longer using it - same excuse too lazy to clean it), bundled so the loader drops and loads it at runtime. The bigger one (~163KB) is bass.dll for radio and yt audio (no longer relying on it). bass uses an ancient toolchain with custom section names so DIE flags it as packed every time, so it's a false positive, you'd see the exact same warnings on a clean BASS download from un4seen.com.
Ive noticed the same, yet reviewing your code or well what Ghidra does out of it still indicates major AI involvement.
 
Ive noticed the same, yet reviewing your code or well what Ghidra does out of it still indicates major AI involvement.
Decompilation isn't source and I'm sure you know that.
Compiled code restructured by ghidra always looks weird, that's not evidence of your claim. Point at a specific function and we can start from there.
 
Decompilation isn't source and I'm sure you know that.
Compiled code restructured by ghidra always looks weird, that's not evidence of your claim. Point at a specific function and we can start from there.
decompilation is not source that is correct, but it will still reflect the choices a developer makes during writing his code, such as weird function structure, logging and what not :D
 
All code is extracted from FUN_1400438e0 (orchestration) and FUN_140042150 (injection) from "KobaltInjector hackvshack.net.exe"
Decompilation isn't source and I'm sure you know that.
Compiled code restructured by ghidra always looks weird, that's not evidence of your claim. Point at a specific function and we can start from there.

// error handling is exremly verbose and self repeating.
// this block appears ~20 times across both functions, character for character.
// every single error path in both functions looks exactly like this:

iVar1 = FUN_140056cbc((uint *)&DAT_1400ccde0);
if (iVar1 != 0) {
FUN_1400561bc(5); // non returning fatal error path A
}
if (DAT_1400cce2c == 0x7fffffff) {
DAT_1400cce2c = 0x7ffffffe;
FUN_1400561bc(6); // non returning fatal error path B
}

// this exact same sequence is used throughout the entire binary, especially in the 2 previously mentioned functions.
// line for line (5, 6, 0x7fffffff, 0x7ffffffe), never a wrapper function or macro.

// repeating string literals.
// All strings are built identically: allocate buffer, write endian.
// hex literals, null-terminate, log. The strings themselves are also very similar: full sentences, perfect grammar, consistent capitalisation, no abbreviations.

// From FUN_1400438e0 — every possible state has a complete English sentence:

// "Failed to prepare bass.dll"
pWVar8 = (LPCWSTR)FUN_1400543a0(0x20);
*(undefined8 *)pWVar8 = 0x742064656c696146; // "Failed t"
*(undefined8 *)(pWVar8 + 4) = 0x726170657270206f; // "o prepar"
pWVar8[8] = L'⁥'; pWVar8[9] = L'慢';
pWVar8[10] = L'獳'; pWVar8[0xb] = L'搮';
pWVar8[0xc] = L'汬'; *(char *)(pWVar8 + 0xd) = '\0';

// "DLL verified, preparing..."
// "Waiting for CS2..."
// "Launching CS2..."
// "CS2 detected! Waiting for game to load..."
// "CS2 failed to start - check Steam"
// "Waiting for CS2 to start..."
// "Timed out waiting for CS2 modules"
// "Waiting for CS2 window..."
// "Waiting for CS2 window response."
// "Timed out waiting for CS2 window response"
// "Checking audio library..."
// "bass.dll not found next to loader"
// "Injecting..."
// "Applying bypass..."
// "Kobalt loaded but menu initialization timed out"
// "Injection complete."

// FUN_140042150 — every API failure has a full sentence:

builtin_strncpy(pcVar9, "Failed to allocate memory in target process", 0x2c);
builtin_strncpy(pcVar9, "Failed to write DLL path to target process", 0x2b);
builtin_strncpy(pcVar9, "Failed to get kernel32 handle", 0x1e);
builtin_strncpy(pcVar9, "Failed to get LoadLibraryA address", 0x23);
builtin_strncpy(pcVar9, "Failed to create remote thread", 0x1f);
builtin_strncpy(pcVar9, "LoadLibrary failed - DLL may have crashed on load", 0x32);
builtin_strncpy(pcVar9, "DLL file too small: ", 0x14);
builtin_strncpy(pcVar9, "DLL not found: ", 0x0f);

// essentially what ive said in line 27 before, but more concise: every single error case in both functions is handled with a unique, perfectly grammatical English sentence. No error code logging, no abbreviations, no placeholders. Just a full sentence describing exactly what went wrong in plain English. This is not how a human would write error handling code, especially not in C where performance and binary size are often concerns. This is textbook AI slop.
// the sentence above was written by the VSC Text AI thing.
 
All code is extracted from FUN_1400438e0 (orchestration) and FUN_140042150 (injection) from "KobaltInjector hackvshack.net.exe"


// error handling is exremly verbose and self repeating.
// this block appears ~20 times across both functions, character for character.
// every single error path in both functions looks exactly like this:

iVar1 = FUN_140056cbc((uint *)&DAT_1400ccde0);
if (iVar1 != 0) {
FUN_1400561bc(5); // non returning fatal error path A
}
if (DAT_1400cce2c == 0x7fffffff) {
DAT_1400cce2c = 0x7ffffffe;
FUN_1400561bc(6); // non returning fatal error path B
}

// this exact same sequence is used throughout the entire binary, especially in the 2 previously mentioned functions.
// line for line (5, 6, 0x7fffffff, 0x7ffffffe), never a wrapper function or macro.

// repeating string literals.
// All strings are built identically: allocate buffer, write endian.
// hex literals, null-terminate, log. The strings themselves are also very similar: full sentences, perfect grammar, consistent capitalisation, no abbreviations.

// From FUN_1400438e0 — every possible state has a complete English sentence:

// "Failed to prepare bass.dll"
pWVar8 = (LPCWSTR)FUN_1400543a0(0x20);
*(undefined8 *)pWVar8 = 0x742064656c696146; // "Failed t"
*(undefined8 *)(pWVar8 + 4) = 0x726170657270206f; // "o prepar"
pWVar8[8] = L'⁥'; pWVar8[9] = L'慢';
pWVar8[10] = L'獳'; pWVar8[0xb] = L'搮';
pWVar8[0xc] = L'汬'; *(char *)(pWVar8 + 0xd) = '\0';

// "DLL verified, preparing..."
// "Waiting for CS2..."
// "Launching CS2..."
// "CS2 detected! Waiting for game to load..."
// "CS2 failed to start - check Steam"
// "Waiting for CS2 to start..."
// "Timed out waiting for CS2 modules"
// "Waiting for CS2 window..."
// "Waiting for CS2 window response."
// "Timed out waiting for CS2 window response"
// "Checking audio library..."
// "bass.dll not found next to loader"
// "Injecting..."
// "Applying bypass..."
// "Kobalt loaded but menu initialization timed out"
// "Injection complete."

// FUN_140042150 — every API failure has a full sentence:

builtin_strncpy(pcVar9, "Failed to allocate memory in target process", 0x2c);
builtin_strncpy(pcVar9, "Failed to write DLL path to target process", 0x2b);
builtin_strncpy(pcVar9, "Failed to get kernel32 handle", 0x1e);
builtin_strncpy(pcVar9, "Failed to get LoadLibraryA address", 0x23);
builtin_strncpy(pcVar9, "Failed to create remote thread", 0x1f);
builtin_strncpy(pcVar9, "LoadLibrary failed - DLL may have crashed on load", 0x32);
builtin_strncpy(pcVar9, "DLL file too small: ", 0x14);
builtin_strncpy(pcVar9, "DLL not found: ", 0x0f);

// essentially what ive said in line 27 before, but more concise: every single error case in both functions is handled with a unique, perfectly grammatical English sentence. No error code logging, no abbreviations, no placeholders. Just a full sentence describing exactly what went wrong in plain English. This is not how a human would write error handling code, especially not in C where performance and binary size are often concerns. This is textbook AI slop.
// the sentence above was written by the VSC Text AI thing.
Most of what you're flagging is msvc compiler emitted code, not my code. The repeated block with 0x7fffffff / 0x7ffffffe and a non returning helper is a CRT internal sentinel pattern the compiler emits inline at every call site, which is why it shows up +20 times identical, nobody writes the same magic numbers 20 times verbatim instead of wrapping it in a helper. The qword string stores are msvc's small string optimization (short string literals inlined as 8-byte stores instead of memcpy). The Asian characters Ghidra is showing are rendering artifacts, not actual source.

The error strings are mine, I write full sentences because they end up in user submitted crash logs where readable text triages faster than an error code, same convention Win32 / NTSTATUS / HRESULT messages use, nothing ai here.

If you find something that isn't compiler boilerplate or generic logging and still looks off, send it over.
 
Most of what you're flagging is msvc compiler emitted code, not my code. The repeated block with 0x7fffffff / 0x7ffffffe and a non returning helper is a CRT internal sentinel pattern the compiler emits inline at every call site, which is why it shows up +20 times identical, nobody writes the same magic numbers 20 times verbatim instead of wrapping it in a helper. The qword string stores are msvc's small string optimization (short string literals inlined as 8-byte stores instead of memcpy). The Asian characters Ghidra is showing are rendering artifacts, not actual source.

The error strings are mine, I write full sentences because they end up in user submitted crash logs where readable text triages faster than an error code, same convention Win32 / NTSTATUS / HRESULT messages use, nothing ai here.

If you find something that isn't compiler boilerplate or generic logging and still looks off, send it over.
which you are highly correct with yet this still looks extremly suspicious to anyone even for the average user.

Another thing i do not fully understand but this could just be a oversight on your end:

WaitForSingleObject(hHandle, 10000);
local_118[0] = 0;
GetExitCodeThread(hHandle, local_118); // DWORD[0] — truncates 64-bit HMODULE
CloseHandle(hHandle);
VirtualFreeEx(param_1, lpBaseAddress, 0, 0x8000);
if (local_118[0] == 0) {
// reports failure even if DLL loaded at 0x00007FF800000000
// because (DWORD)0x00007FF800000000 == 0
builtin_strncpy(pcVar9, "LoadLibrary failed - DLL may have crashed on load", 0x32);
return 0; // false negative
}
return 1; // uVar12 = 1 on the success path

and the 50 000 bytes limit:

uVar6 = FUN_140040900((LPCSTR)local_78); // returns file size
if (49999 < uVar13) {
// proceed to inject
} else {
// "DLL file too small: name"
FUN_140052180(&local_d8, param_2, uVar6);
puVar5 = FUN_140053850(&local_d8, param_2, "DLL file too small: ", 0x14);
return 0;
}


I find both of these quite odd.
 
which you are highly correct with yet this still looks extremly suspicious to anyone even for the average user.

Another thing i do not fully understand but this could just be a oversight on your end:

WaitForSingleObject(hHandle, 10000);
local_118[0] = 0;
GetExitCodeThread(hHandle, local_118); // DWORD[0] — truncates 64-bit HMODULE
CloseHandle(hHandle);
VirtualFreeEx(param_1, lpBaseAddress, 0, 0x8000);
if (local_118[0] == 0) {
// reports failure even if DLL loaded at 0x00007FF800000000
// because (DWORD)0x00007FF800000000 == 0
builtin_strncpy(pcVar9, "LoadLibrary failed - DLL may have crashed on load", 0x32);
return 0; // false negative
}
return 1; // uVar12 = 1 on the success path

and the 50 000 bytes limit:

uVar6 = FUN_140040900((LPCSTR)local_78); // returns file size
if (49999 < uVar13) {
// proceed to inject
} else {
// "DLL file too small: name"
FUN_140052180(&local_d8, param_2, uVar6);
puVar5 = FUN_140053850(&local_d8, param_2, "DLL file too small: ", 0x14);
return 0;
}


I find both of these quite odd.
First one is indeed a bug, you're right. GetExitCodeThread stores into a DWORD and the LoadLibraryA thread returns HMODULE which is 64bit on x64, so any DLL that loads at an address where the low 32 bits are zero gets reported as a failure even though it injected fine.
Real false negative path, I'll fix it! Either by trusting post load module enumeration instead of the thread exit code, or by using shellcode that returns a 32bit success indicator instead of the raw HMODULE.

Second one is just a sanity check, not anything weird. The cheat DLL itself is +16MB, so the 50KB minimum is there to catch corrupt or empty files (interrupted download, AV quarantine truncating to 0 bytes, etc.) before parsing PE headers off them. Bails out with a readable error instead of crashing on garbage input.

Appreciate the code review by the way, at least you brought something meaningful to discuss here.
 
First one is indeed a bug, you're right. GetExitCodeThread stores into a DWORD and the LoadLibraryA thread returns HMODULE which is 64bit on x64, so any DLL that loads at an address where the low 32 bits are zero gets reported as a failure even though it injected fine.
Real false negative path, I'll fix it! Either by trusting post load module enumeration instead of the thread exit code, or by using shellcode that returns a 32bit success indicator instead of the raw HMODULE.

Second one is just a sanity check, not anything weird. The cheat DLL itself is +16MB, so the 50KB minimum is there to catch corrupt or empty files (interrupted download, AV quarantine truncating to 0 bytes, etc.) before parsing PE headers off them. Bails out with a readable error instead of crashing on garbage input.

Appreciate the code review by the way, at least you brought something meaningful to discuss here.
Well glad to hear your sanity check is certainly interesting to me but to each their own, but glad i found something you can fix. Either way i am not even trying to discredit your work since one way or another there is a free usable cheat on this forum but regardless of that I will still believe for myself that the UI has been made with AI to atleast some degree, I cannot speak on the features since most of them function as what they should in one way or another. Saying that the cheat has potential yet its not good in my eyes, a UI overhall is the LEAST i personally would need, its buggy, its ugly, i dont like, this might not be your opinion but so be it. One thing ive noticed for example is sliders being a little to small (maybe?) which causes users to drag the menu instead of adjusting the sliders value. Anyways im gonna go to bed now we had a great discussion and all that, maybe ill give it a second chance.
 
First one is indeed a bug, you're right. GetExitCodeThread stores into a DWORD and the LoadLibraryA thread returns HMODULE which is 64bit on x64, so any DLL that loads at an address where the low 32 bits are zero gets reported as a failure even though it injected fine.
Real false negative path, I'll fix it! Either by trusting post load module enumeration instead of the thread exit code, or by using shellcode that returns a 32bit success indicator instead of the raw HMODULE.

Second one is just a sanity check, not anything weird. The cheat DLL itself is +16MB, so the 50KB minimum is there to catch corrupt or empty files (interrupted download, AV quarantine truncating to 0 bytes, etc.) before parsing PE headers off them. Bails out with a readable error instead of crashing on garbage input.

Appreciate the code review by the way, at least you brought something meaningful to discuss here.
1779603488361.png
funnily enough i wrote down the same fix.
 
Well glad to hear your sanity check is certainly interesting to me but to each their own, but glad i found something you can fix. Either way i am not even trying to discredit your work since one way or another there is a free usable cheat on this forum but regardless of that I will still believe for myself that the UI has been made with AI to atleast some degree, I cannot speak on the features since most of them function as what they should in one way or another. Saying that the cheat has potential yet its not good in my eyes, a UI overhall is the LEAST i personally would need, its buggy, its ugly, i dont like, this might not be your opinion but so be it. One thing ive noticed for example is sliders being a little to small (maybe?) which causes users to drag the menu instead of adjusting the sliders value. Anyways im gonna go to bed now we had a great discussion and all that, maybe ill give it a second chance.
I get it, not everyone is going to be a fan of the design, and I’m aware of the flaws you mentioned. Some users have complained about it, but I never gave it much priority since the project is still in Beta. It’s also possible that they’re more familiar with designs like Plague’s, Bank’s, or Skeet’s, etc.
I didn’t put much effort into the injector, but I’m planning to redesign the entire UI to be more familiar to the user base (both the injector and the cheat’s UI).
I'll go to sleep as well, my sleep schedule has never been the same since I started this.
 
I get it, not everyone is going to be a fan of the design, and I’m aware of the flaws you mentioned. Some users have complained about it, but I never gave it much priority since the project is still in Beta. It’s also possible that they’re more familiar with designs like Plague’s, Bank’s, or Skeet’s, etc.
I didn’t put much effort into the injector, but I’m planning to redesign the entire UI to be more familiar to the user base (both the injector and the cheat’s UI).
I'll go to sleep as well, my sleep schedule has never been the same since I started this.
Well thats valid, have a great day or night whatever time it is for you :D
 
1779603488361.png
funnily enough i wrote down the same fix.
Nice, that's actually the cleaner fix, second VirtualAllocEx region for the shellcode to write the full HMODULE into, then ReadProcessMemory it back. It is more reliable than the Module32First route since you skip the snapshot race and get the exact handle instead of matching by module name. Nice!!
 
  • Love
Reactions: calloc0x75
Status
Thread closed. Topic resolved/outdated. For updates, start new thread. Files removed to save server space.

Who has read this thread (Total: 1) in last 1 hours View details