Guide Nexon Game Security Bypass info + hot sticky sauce

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,305
37,938
270
Game Name
N/A
Anticheat
Nexon Game Security (NGS)
How long you been coding/hacking?
what day is it
Coding Language
C++
Figured i should do a (very) little writeup to accompany the (partial) bypass i released a while ago since it'd be nice to add to the big anticheat index here.

I spent a few weeks reversing Nexon game security because i was writing that maplestory stuff.

NGS was a good bit of fun, I wrote a call tracer due to it that would log all branches a program took. During this time, I noticed that all the APIs logged were pretty nondescript. After some fine tuning, i found my exceptionally perfect code to be crashing after a set period of time, so i did some further digging.

This is the section that it crashes



Lucky for you, i save random screenshots.

What you're looking at is heaven's gate being dropped into, swapping CS to 0x33 (long mode) to execute x64 code, then swapping it back to 0x23.
In long mode, they fix up some registers as seen in the screenshot, as well as perform a call to some WINAPIs, but the catch is this will go to 64 bit winapis, whilst its running in a 32 bit WoW program.

I'll briefly touch on my bypass because honestly its not that hard. Essentially, what I did was register an exception handler in long mode (by entering heaven's gate myself) and set an x86 exception handler to catch new threads. Then for every thread i found/was created, i placed a HWBP at the location of the calls. This exception will be handled by the x64 handler (called x64handler in the assembly file because im original).

Because i'm too lazy to explain it, here's the raw assembly for the handler:



with the macros defined as:

Code:
potato_fn dq 0
macro SAVE_SCRAP
{
        push rcx
        push r8
        push rbx
        push rsi
        push r15                                                   ; TODO: Perhaps check if our breakpoint is hit immediately after a call, if so, send it to the x86 function to get return value?
        push r14
        push r13
        push r12
        push r11
        push r10
        push rdi
}
macro POP_SCRAP
{
        pop rdi
        pop r10
        pop r11
        pop r12
        pop r13
        pop r14
        pop r15
        pop rsi
        pop rbx
        pop r8
        pop rcx
}
potato_fn is the address of the "x86Callback" which switches back to x86, calls a handler function to filter the called API, and re-enters x64 before returning.

That's the "smart" part done, everything else is dead simple. I grab the syscall index at the current EIP, and send if its one i wish to "hook", i do stuff with it. For example: You can see if the index is 0x26, i hide any ZwOpenProcess calls which are targeting a program with "cheat" in the name, which enables one to use Cheat engine while playing an NGS protected game.

Like i said, this is a partial bypass because it suited my needs at the time, to get a full bypass, you only need to do one more thing, which another user on this forum has already done.

Also, you don't need to do it my way at all. I just like exceptions. You can achieve the same thing with a simple hook, it's just your hook will be able to be detected by checksums, so check for them, heh.

Too long;give source: Bitbucket
 
Last edited by a moderator:

anymoves

Full Member
Jun 11, 2020
2
102
0
Thank you so much for making this thread, I'm sure this will help many people.
Hello,

I recently started playing a Nexon game called Kingdom of Winds or "Baram" (바람의나라) and was wondering if I can ask few questions. Hope this is the appropriate place!

  1. I would like to use this game to teach/learn myself how to use macros. I downloaded the Jibit Macro Recorder and it seems to work fine in the game until it gets detected. Foremost, I have only little background in programming (python) and I'm just guessing that there is a need for some sort of bypass application on top of my macro to hide from Nexon detecting any "unusual activity". I experimented with variety of macro conditions w/ delays, pixel reading, etc. and concluding the Jibit Macro Recorder is suitable and just need a bypass code?
  2. In order to bypass, I first need to know WHAT i need to bypass... How can I search this for information? Whenever I see anything "security" related, there is an .exe application called "Black Cipher" in the game folder that activates in the processes, but i cannot delete this while the game is running. Could this be it? Doing something with this will bypass my macros? I see a lot of people here mentioning GameGuard, but I don't see that running - Has Nexon moved on from GameGuard protection?
  3. Any other places I can start from to learn about hacking into these kind of protections?

***I'm not intending to create any macros to harm the community or the game itself, just playing with my programming skills!

Since MapleStory closely operates with Baram, I hope someone related can answer this! Feel free to reach out for private contact info to talk more, if needed.

Best,
 

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,305
37,938
270
Hello,

I recently started playing a Nexon game called Kingdom of Winds or "Baram" (바람의나라) and was wondering if I can ask few questions. Hope this is the appropriate place!

  1. I would like to use this game to teach/learn myself how to use macros. I downloaded the Jibit Macro Recorder and it seems to work fine in the game until it gets detected. Foremost, I have only little background in programming (python) and I'm just guessing that there is a need for some sort of bypass application on top of my macro to hide from Nexon detecting any "unusual activity". I experimented with variety of macro conditions w/ delays, pixel reading, etc. and concluding the Jibit Macro Recorder is suitable and just need a bypass code?
  2. In order to bypass, I first need to know WHAT i need to bypass... How can I search this for information? Whenever I see anything "security" related, there is an .exe application called "Black Cipher" in the game folder that activates in the processes, but i cannot delete this while the game is running. Could this be it? Doing something with this will bypass my macros? I see a lot of people here mentioning GameGuard, but I don't see that running - Has Nexon moved on from GameGuard protection?
  3. Any other places I can start from to learn about hacking into these kind of protections?

***I'm not intending to create any macros to harm the community or the game itself, just playing with my programming skills!

Since MapleStory closely operates with Baram, I hope someone related can answer this! Feel free to reach out for private contact info to talk more, if needed.

Best,
Yeah you'll want to tackle black cipher. Searching for this information depends on your ability to reverse engineer, so you should start with practicing that
 

anymoves

Full Member
Jun 11, 2020
2
102
0
Yeah you'll want to tackle black cipher. Searching for this information depends on your ability to reverse engineer, so you should start with practicing that
Ay guys! Cheers for the prompt responses.

Yup, reading the reverse eng. guide atm. I appreciate the neat compilation. Brilliant work. I'm an engineer (water treatment) myself but feel incredible every time i get exposed to this side of engineering, it's like i'm entreing into an astral world for sure haha

@mambda,
Have you been successful at bypassing Black Cipher yourself by chance? Can I please confirm with you that the Jibit Macro Recorder is suitable to even begin with? Looking forward to hearing back from you.
 

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,305
37,938
270
Ay guys! Cheers for the prompt responses.

Yup, reading the reverse eng. guide atm. I appreciate the neat compilation. Brilliant work. I'm an engineer (water treatment) myself but feel incredible every time i get exposed to this side of engineering, it's like i'm entreing into an astral world for sure haha

@mambda,
Have you been successful at bypassing Black Cipher yourself by chance? Can I please confirm with you that the Jibit Macro Recorder is suitable to even begin with? Looking forward to hearing back from you.
this entire repo is my bypass for blackcipher (Nexon game security), i dunno anything about macro recorders because ive never used them
 

hanoob

Dank Tier Donator
Aug 6, 2020
13
212
0
I want advice! If the cheat engine works even if only zwopenprocess is hooked, I think it will search the process list before zwopenprocess api (call chain- CreateToolhelp32Snapshot or enum process api -> As a result, it calls ZwQuerySysteminformation) I tried hooking the ZwQuerySystemInformation API. To summarize the following easily, the cheatengine process was removed from the process information by hooking ZwQuerySysteminformation considering wow64. And when I inject the created dll into blackcipher.aes, the game turns off after a few minutes. Is it not enough to hook this api??
1.png

This picture is heaven's gate pointed to by the wow64reserved address on the teb structure on my computer.
(For reference, when I experimented with changing #define STR HIDE PROCESS NAME to notepad, when I injected the following dll into x32dbg, x32dbg could not find the notepad normally.)

hide cheat engine process wow64:
#include "windows.h"
#include "stdio.h"
#include "tchar.h"

#define STR_HIDE_PROCESS_NAME            (L"cheatengine-x86_64.exe")
#define STATUS_SUCCESS                    (0x00000000L)

typedef LONG NTSTATUS;
const LPVOID CreateNewJump();

typedef enum _SYSTEM_INFORMATION_CLASS {
    SystemBasicInformation = 0,
    SystemPerformanceInformation = 2,
    SystemTimeOfDayInformation = 3,
    SystemProcessInformation = 5,
    SystemProcessorPerformanceInformation = 8,
    SystemInterruptInformation = 23,
    SystemExceptionInformation = 33,
    SystemRegistryQuotaInformation = 37,
    SystemLookasideInformation = 45
} SYSTEM_INFORMATION_CLASS;

typedef struct _SYSTEM_PROCESS_INFORMATION {
    ULONG NextEntryOffset;
    BYTE Reserved1[52];
    PVOID Reserved2[3];
    HANDLE UniqueProcessId;
    PVOID Reserved3;
    ULONG HandleCount;
    BYTE Reserved4[4];
    PVOID Reserved5[11];
    SIZE_T PeakPagefileUsage;
    SIZE_T PrivatePageCount;
    LARGE_INTEGER Reserved6[6];
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;

typedef NTSTATUS(WINAPI* PFZWQUERYSYSTEMINFORMATION)(
    SYSTEM_INFORMATION_CLASS SystemInformationClass,
    PVOID SystemInformation,
    ULONG SystemInformationLength,
    PULONG ReturnLength);

NTSTATUS WINAPI NewZwQuerySystemInformation(
    SYSTEM_INFORMATION_CLASS SystemInformationClass,
    PVOID SystemInformation,
    ULONG SystemInformationLength,
    PULONG ReturnLength);

BYTE g_pOrgCPA[5] = { 0, };
BYTE g_pOrgCPW[5] = { 0, };
BYTE g_pOrgZwQSI[5] = { 0, };
BYTE g_pOrgGate[9] = { 0, };
_TEB* teb = NtCurrentTeb();
uintptr_t gate = *(uintptr_t*)((uintptr_t)teb + 0xc0);
LPVOID lpJmpRealloc = CreateNewJump(); //orginal part of gate

BOOL hook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew, PBYTE pOrgBytes) // 32bit, 32process
{
    FARPROC pFunc;
    DWORD dwOldProtect, dwAddress;
    BYTE pBuf[5] = { 0xE9, 0, };
    PBYTE pByte;

    pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);
    pByte = (PBYTE)pFunc;
    if (pByte[0] == 0xE9)
        return FALSE;

    VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);

    memcpy(pOrgBytes, pFunc, 5);

    dwAddress = (DWORD)pfnNew - (DWORD)pFunc - 5;
    memcpy(&pBuf[1], &dwAddress, 4);

    memcpy(pFunc, pBuf, 5);

    VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect);

    return TRUE;
}

const LPVOID CreateNewJump()
{
 
    LPVOID lpJmpRealloc = VirtualAlloc(nullptr, 0x1000, MEM_RESERVE | MEM_COMMIT,
        PAGE_EXECUTE_READWRITE);
    memcpy(lpJmpRealloc, (uintptr_t*)gate, 9);

    return lpJmpRealloc;
}

BOOL hook_for_gate(uintptr_t gateAddr, PROC pfnNew, PBYTE pOrgBytes) // in 64bit, 32bit process  //pOrgBytes mean nothing. i forget to delete. But not but it doesn't matter
{
    DWORD dwOldProtect, dwAddress;
    BYTE pBuf[5] = { 0xE9, 0, };
    PBYTE pByte;

    pByte = (PBYTE)gateAddr;

    VirtualProtect((LPVOID)gateAddr, 9, PAGE_EXECUTE_READWRITE, &dwOldProtect);

    memcpy(pOrgBytes, (uintptr_t*)gateAddr, 9);
    memset((uintptr_t*)gateAddr, 0x90, 9);

    dwAddress = (DWORD)pfnNew - (DWORD)gateAddr - 5;
    memcpy(&pBuf[1], &dwAddress, 4);

    memcpy((uintptr_t*)gateAddr, pBuf, 5);

    VirtualProtect((LPVOID)gateAddr, 9, dwOldProtect, &dwOldProtect);

    return TRUE;
}

BOOL unhook_for_gate(uintptr_t gateAddr, PROC pfnNew, PBYTE pOrgBytes) // in 64bit, 32bit process
{
    DWORD dwOldProtect, dwAddress;
    BYTE pBuf[5] = { 0xE9, 0, };
    PBYTE pByte;

    pByte = (PBYTE)gateAddr;

    VirtualProtect((LPVOID)gateAddr, 9, PAGE_EXECUTE_READWRITE, &dwOldProtect);

    memcpy(pOrgBytes, (uintptr_t*)gateAddr, 9);
    memset((uintptr_t*)gateAddr, 0x90, 9);

    dwAddress = (DWORD)pfnNew - (DWORD)gateAddr - 5;
    memcpy(&pBuf[1], &dwAddress, 4);

    memcpy((uintptr_t*)gateAddr, pBuf, 5);

    VirtualProtect((LPVOID)gateAddr, 9, dwOldProtect, &dwOldProtect);

    return TRUE;
}

BOOL unhook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PBYTE pOrgBytes) // 32bit, 32process
{
    FARPROC pFunc;
    DWORD dwOldProtect;
    PBYTE pByte;

    pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);
    pByte = (PBYTE)pFunc;
    if (pByte[0] != 0xE9)
        return FALSE;

    VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);

    memcpy(pFunc, pOrgBytes, 5);

    VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect);

    return TRUE;
}


//-----------------------------------------------------------------------------------------------------------------------------------------------------------

void __declspec(naked) hk_NtQuerySystemInformation()
{
    __asm
    {
        push[esp + 0x14]
        push[esp + 0x14]
        push[esp + 0x14]
        push[esp + 0x14]
        call NewZwQuerySystemInformation
        ret
    }
}

void __declspec(naked) hk_Wow64Trampoline()
{
    __asm
    {
        cmp eax, 0x36 //64bit Syscall id of NtQuerySystemInformation
        je hk_NtQuerySystemInformation

        jmp lpJmpRealloc
    }
}

void __declspec(naked) unhk_Wow64Trampoline()
{
    __asm
    {
        jmp lpJmpRealloc
    }
}


NTSTATUS WINAPI NewZwQuerySystemInformation(
    SYSTEM_INFORMATION_CLASS SystemInformationClass,
    PVOID SystemInformation,
    ULONG SystemInformationLength,
    PULONG ReturnLength)
{
    NTSTATUS status;
    FARPROC pFunc;
    PSYSTEM_PROCESS_INFORMATION pCur, pPrev=0;
    char szProcName[MAX_PATH] = { 0, };

    unhook_for_gate(gate, (PROC)unhk_Wow64Trampoline, g_pOrgGate);
    pFunc = GetProcAddress(GetModuleHandleA("ntdll.dll"),
        "ZwQuerySystemInformation");
    status = ((PFZWQUERYSYSTEMINFORMATION)pFunc)
        (SystemInformationClass, SystemInformation,
            SystemInformationLength, ReturnLength);

    if (status != STATUS_SUCCESS)
        goto __NTQUERYSYSTEMINFORMATION_END;

    if (SystemInformationClass == SystemProcessInformation)
    {
        pCur = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;

        while (TRUE)
        {
            if (pCur->Reserved2[1] != NULL)
            {
                if (!_tcsicmp((PWSTR)pCur->Reserved2[1], STR_HIDE_PROCESS_NAME))
                {
                    if (pCur->NextEntryOffset == 0)
                        pPrev->NextEntryOffset = 0;
                    else
                        pPrev->NextEntryOffset += pCur->NextEntryOffset;
                }
                else
                    pPrev = pCur;    // 원하는 프로세스를 못 찾은 경우만 pPrev 세팅
            }

            if (pCur->NextEntryOffset == 0)
                break;

            pCur = (PSYSTEM_PROCESS_INFORMATION)((ULONG)pCur + pCur->NextEntryOffset);
        }
    }

__NTQUERYSYSTEMINFORMATION_END:

    hook_for_gate(gate, (PROC)hk_Wow64Trampoline, g_pOrgGate);

    return status;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{


    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:

        hook_for_gate(gate, (PROC)hk_Wow64Trampoline, g_pOrgGate);
        break;

    case DLL_PROCESS_DETACH:

        unhook_for_gate(gate, (PROC)unhk_Wow64Trampoline, g_pOrgGate);
        break;
    }

    return TRUE;
}
 
Last edited:

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,305
37,938
270
if cheat engine is open before you inject your dll they probably already have a handle, make sure you inject first then start CE.

my bypass is entirely open source so you can just look over the stuff ive hooked
 

hanoob

Dank Tier Donator
Aug 6, 2020
13
212
0
if cheat engine is open before you inject your dll they probably already have a handle, make sure you inject first then start CE.

my bypass is entirely open source so you can just look over the stuff ive hooked
I see your source code. but When I downloaded it, there was no header in hook_lib. What should I do?
And if I understand it is correct, is it correct that the ngs-bypass source code just hooks the ZwOpenProcess API so that it doesn't get a handle to the cheat engine?? And even though I injected the dll I made into the black cipher before running the cheat engine, when I run the cheat engine, the execution stops even after a few minutes.
 

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,305
37,938
270
I see your source code. but When I downloaded it, there was no header in hook_lib. What should I do?
its a submodule, you'd need to clone that as well

regardless, all you need to do is look at the stuff i've hooked and hook the same things / see how i get around their detections, you dont need to compile and inject it (unless you want to i guess)
 

hanoob

Dank Tier Donator
Aug 6, 2020
13
212
0
its a submodule, you'd need to clone that as well

regardless, all you need to do is look at the stuff i've hooked and hook the same things / see how i get around their detections, you dont need to compile and inject it (unless you want to i guess)
I read the code you wrote, and first of all, I apologize for my inexperienced programming skills and English skills. I have a question, is there anything that actually goes into the bypass in your code except for zwopenprocess hooking through heaven's gate?? Why did you hook the zwreadvirtualmemory, zwprocessinformation, or zwqueryvirtualmemory API??
 

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,305
37,938
270
I read the code you wrote, and first of all, I apologize for my inexperienced programming skills and English skills. I have a question, is there anything that actually goes into the bypass in your code except for zwopenprocess hooking through heaven's gate?? Why did you hook the zwreadvirtualmemory, zwprocessinformation, or zwqueryvirtualmemory API??
nope looks like its all for logging purposes
 

hanoob

Dank Tier Donator
Aug 6, 2020
13
212
0
nope looks like its all for logging purposes
I apologize for not seeing your code properly. I was so urgent that I got ahead. Again, let's analyze your code and try to understand it. The file you uploaded, ngs-bypass, is a bypass method for all games that use black cipher except for Maple Story??
 
Last edited:

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,305
37,938
270
I apologize for not seeing your code properly. I was so urgent that I got ahead. Again, let's analyze your code and try to understand it. The file you uploaded, ngs-bypass, is a bypass method for all games that use black cipher except for Maple Story??
i developed it for maplestory, i dont know about any other black cipher versions used, just the one used with maplestory
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods