How to Reverse Engineering NosTale?

02/26/2019 16:00 Koffy1#1
Hi, I'm Koofy1, I'm an C++ programmer with a medium-high level of programming. I've been envolved in this world of reverse engineering. Right now I have some projects that I want to do in this game called NosTale. I've figured out how to hook send/recv functions and then if it's necessary decrypt/encrypt the packets and be able to read them.
Now my question is: What can I do with this packets? (besides reading them :lul:)
PS: I want to make a bot that allows you to control multiple characters at the same time. (I think It would be something like sending the same packets to all the clients, so they'll do the same thing).
I appreciate any help that you can give me, TY. :handsdown:
02/26/2019 18:56 Apourtartt#2
Read them then react to with sending packets.
02/28/2019 20:35 Koffy1#3
How Can I build Microsoft Detours 4.0? I had searched a lot and still don't know what to do. I have Windows 10 and x64 bits.
PS: I'm using Visual Studio 2017
02/28/2019 21:08 FI0w#4
I would try nmake ?
02/28/2019 21:43 Koffy1#5
Quote:
Originally Posted by FI0w View Post
I would try nmake ?
What I need to do exactly with nmake? I was reading a lot of forums and nothing. I have Visual Studio 2017.

DONE :D
03/08/2019 21:53 Koffy1#6
Hi, could someone tell me if this piece of code is well-written or have any issue? It's the hooking of send function in NosTale.
Also, when I try to read the packet in the console it just doesn't appear in it. And when It opens the console it appears this message.
[Only registered and activated users can see links. Click Here To Register...]

PS: What can I make once I know how to read the packets? Should I try to make a simple packetlogger? To send packets?

Code:
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <detours.h>
#include <winsock.h>

int (WINAPI *originalSend)(SOCKET s, const char *buf, int len, int flags); // SEND

int WINAPI hookedSend(SOCKET s, const char *buf, int len, int flags) // HOOKED SEND
{

	std::ofstream myfile;
	myfile.open("example.txt", std::ofstream::out | std::ofstream::trunc);
	myfile << len << std::endl;

	for (int i = 0; i < len; i++)
	{
		myfile << std::hex << (char)((buf[i] - 0x0F) ^ 0XC3); // DECRYPT LOGIN PACKET
	}

	myfile.close();

	return originalSend(s, buf, len, flags);
}

BOOL APIENTRY DllMain(HMODULE module, DWORD  reason, LPVOID reserved)
{
    switch (reason)
    {
		case DLL_PROCESS_ATTACH:
			AllocConsole();
			DetourTransactionBegin();
			DetourUpdateThread(GetCurrentThread());
			originalSend = (int (WINAPI *)(SOCKET s, const char *buf, int len, int flags))DetourFindFunction("WS2_32.dll", "send");
			DetourAttach(&(PVOID&)originalSend, hookedSend);
			DetourTransactionCommit();
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
03/08/2019 22:05 FI0w#7
Quote:
Originally Posted by Koffy1 View Post
Hi, could someone tell me if this piece of code is well-written or have any issue? It's the hooking of send function in NosTale.
Also, when I try to read the packet in the console it just doesn't appear in it. And when It opens the console it appears this message.
[Only registered and activated users can see links. Click Here To Register...]

PS: What can I make once I know how to read the packets? Should I try to make a simple packetlogger? To send packets?

Code:
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <detours.h>
#include <winsock.h>

int (WINAPI *originalSend)(SOCKET s, const char *buf, int len, int flags); // SEND

int WINAPI hookedSend(SOCKET s, const char *buf, int len, int flags) // HOOKED SEND
{

	std::ofstream myfile;
	myfile.open("example.txt", std::ofstream::out | std::ofstream::trunc);
	myfile << len << std::endl;

	for (int i = 0; i < len; i++)
	{
		myfile << std::hex << (char)((buf[i] - 0x0F) ^ 0XC3); // DECRYPT LOGIN PACKET
	}

	myfile.close();

	return originalSend(s, buf, len, flags);
}

BOOL APIENTRY DllMain(HMODULE module, DWORD  reason, LPVOID reserved)
{
    switch (reason)
    {
		case DLL_PROCESS_ATTACH:
			AllocConsole();
			DetourTransactionBegin();
			DetourUpdateThread(GetCurrentThread());
			originalSend = (int (WINAPI *)(SOCKET s, const char *buf, int len, int flags))DetourFindFunction("WS2_32.dll", "send");
			DetourAttach(&(PVOID&)originalSend, hookedSend);
			DetourTransactionCommit();
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
You dont need to hook winsocket. Just hook the Function of game where the Packets arent Encrypted.
03/08/2019 22:09 Koffy1#8
Quote:
Originally Posted by FI0w View Post
You dont need to hook winsocket. Just hook the Function of game where the Packets arent Encrypted.
How could I do that? Could you show me please?

Something like this? I need help :(

Code:
DWORD addrToHook = 0x4D5989;

typedef int(*tHook)(SOCKET s, const char *buf, int len, int flags);
tHook oHook; // our original function

BOOL APIENTRY DllMain(HMODULE hModule,
	DWORD  ul_reason_for_call,
	LPVOID lpReserved
)
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		AllocConsole();
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		oHook = (tHook)DetourFindFunction("WS2_32.dll", "send");
		oHook = (tHook)DetourAttach(&(PVOID&)addrToHook, hHook);
		DetourTransactionCommit();
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}
03/10/2019 01:04 Cryless~#9
Quote:
Originally Posted by Koffy1 View Post
How could I do that? Could you show me please?

Something like this? I need help :(
Search for string -> c_skill -> Enter -> Few lines below you can see a call.

Hook the function pointed by it.
03/10/2019 23:11 Koffy1#10
How can I send the same packets to all my NosTale clients?
For example: With one "main account" move to x position and then, all the other clients that I have on, do exactly the same movement. Like controlling more than one account at one time.
03/11/2019 01:01 WalrossGreat#11
If you want to do it with original clients, you can open for example local TCP connections and communicate with other processes, or use pipes, or even simpler, make the bot to watch certain character and watch his "mv" packets, and then send correct "walk", however the third way has some limitations
03/11/2019 13:24 Cryless~#12
Quote:
Originally Posted by WalrossGreat View Post
If you want to do it with original clients, you can open for example local TCP connections and communicate with other processes, or use pipes, or even simpler, make the bot to watch certain character and watch his "mv" packets, and then send correct "walk", however the third way has some limitations
It is not needed for NosTale but many Anti-Cheat prevent you from opening a Tcp connection or using Pipes so it may not work. I suggest you looking for Shared Memory.

Quote:
Shared memory is the fastest interprocess communication mechanism. The operating system maps a memory segment in the address space of several processes, so that several processes can read and write in that memory segment without calling operating system functions. However, we need some kind of synchronization between processes that read and write shared memory.
[Only registered and activated users can see links. Click Here To Register...]
[Only registered and activated users can see links. Click Here To Register...]
03/11/2019 16:32 Koffy1#13
Quote:
Originally Posted by Cryless~ View Post
Search for string -> c_skill -> Enter -> Few lines below you can see a call.

Hook the function pointed by it.
Cryless, to hook a function using Microsoft Detours do you need to use always this code?

Code:
AllocConsole();
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		"function" = "parameters"DetourFindFunction("WS2_32.dll", 
                "send");
		DetourAttach(&(PVOID&)"function", "hookfunction";
		DetourTransactionCommit();
Do we need to specify always the dll and the name of the function that we're going to hook? How would you hook a function knowing only the addres, like
instead of using the name of function "send", typing his memory address. (0x004D5989). I tried to put instead of "send" this memory address, but it doesn't be the argument that DetourFindFunction() accepts. Could you show me how it would be the code please?
03/11/2019 18:26 DarkyZShadow#14
Quote:
Originally Posted by Koffy1 View Post
Cryless, to hook a function using Microsoft Detours do you need to use always this code?

Code:
AllocConsole();
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		"function" = "parameters"DetourFindFunction("WS2_32.dll", 
                "send");
		DetourAttach(&(PVOID&)"function", "hookfunction";
		DetourTransactionCommit();
Do we need to specify always the dll and the name of the function that we're going to hook? How would you hook a function knowing only the addres, like
instead of using the name of function "send", typing his memory address. (0x004D5989). I tried to put instead of "send" this memory address, but it doesn't be the argument that DetourFindFunction() accepts. Could you show me how it would be the code please?
[Only registered and activated users can see links. Click Here To Register...]
Code:
LONG DetourAttach(
    _Inout_ PVOID * ppPointer,
    _In_    PVOID pDetour
    );
The DetourAttach function takes 2 parameters: the address of the original function you want to hook and the address of the detour function. You just have to call this function without call DetourFindFunction.

Code:
// Probably need some casts
DetourAttach(0x004D5989, my_detour_fn_addy);
03/11/2019 20:28 Koffy1#15
Quote:
Originally Posted by DarkyZShadow View Post
[Only registered and activated users can see links. Click Here To Register...]
Code:
LONG DetourAttach(
    _Inout_ PVOID * ppPointer,
    _In_    PVOID pDetour
    );
The DetourAttach function takes 2 parameters: the address of the original function you want to hook and the address of the detour function. You just have to call this function without call DetourFindFunction.

Code:
// Probably need some casts
DetourAttach(0x004D5989, my_detour_fn_addy);
Thanks Darky, I finally did it. :)