by TheNullz

Below is a coded guide to writing a DLL for injection into MapleStory. The principles and lesson taught here actually applies to creating a DLL for injection into any process.

These are just the very basics (creating the DLL skeleton and the reasons why we use DLL for certain types of Tool.). The more advanced stuff will be coming soon.

This is a working example. That means you can copy it, paste it, compile it, and inject it if you want to see it work.

The code below is in C++. If you are unfamiliar with the language please check out these resources:

Código:
//
// DllExample.cpp (by The Nu||z)
//
// 1. Open Microsoft Visual Studio, or Visual C++ Express:
// 2. Go to File > New > Project.
// 3. Select 'Win32 Project' as your project type.
// 4. In the next dialog, go to setting and check 'DLL',
//    and 'Empty Project'.
// 5. Write your code.
// 6. Go to Build > Build Solution.
//

// This statement includes the standard Windows
// header file. It contains many #includes that
// will include (usually) most, if not all, the
// header that you'll need.
#include 

// This is just a dummy function that will be the code
// executed as our thread. It will popup a message box
// letting us know that it has been injected.
void WINAPI MyThread ( )
{
    // All code in our DLL will be executed in the same address space
    // as the process that we've been attached to. This means that we
    // can manipulat process memory and do any task that requires
    // the code to be execute from the same process.
    //
    // NOTE: When declaring string literals always put an L before the string.
    // This tells the compiler that the string is going to be interpreted as
    // Unicode and not ANSI (Unicode is the default encoding for most modern
    // MS Windows OSs).
    MessageBox(NULL, L"I've just been injected into MapleStory", L"Hello, World!", MB_OK | MB_ICONWARNING | MB_SETFOREGROUND);
}

// DllMain is an optional function for you to declare.
// It serves as the entry point for any DLL and is called every time
// the DLL receive a message.
//
// NOTE: Notice how WINAPI is put between our returned type and the identifier
// of our functions. This is a safe guard that will make sure your functions are all
// using the same calling convention as the windows API itself. WINAPI is most commonly
// defined as __stdcall in most modern version of the OS.

// HMODULE hModule - This is just a handle (both a pointer type, and a integral value)
// to the current instance of your DLL Note: For DLLs, the a handle is also their base
// address in loaded memory.

// DWORD dwReason -  A value that tells you why the DllMain function was called.
// (the _reason_ for the function call, lol)

BOOL WINAPI DllMain ( HMODULE hModule, DWORD dwReason, LPVOID lpvReserved )
{
    // Your standard DllMain function will usually consist of a switch statement
    // if you are going to handle multiple values for the dwReason variable. Or
    // just an if statement if you'll be handling just one value.
    
    switch ( dwReason ) {
        // The DLL has been attached (linked) to a process.
        // If you plan on making a DLL that i going to be injected into
        // another process, then this is the only value you'll be handling.
        case DLL_PROCESS_ATTACH:
            // Make a call to DisableThreadLibraryCalls with the hModule variable
            // as its argument; Doing this is an optimization trick to prevent
            // needless thread attach/detach messages from triggering further calls
            // to our DllMain function.
            DisableThreadLibraryCalls(hModule);

            //
            // If you're code is only doing a few tasks once attached:
            //         This is where you would either place your could to be run, OR more pragmatically
            // call some function you've defined elsewhere.
            //
            // If  you're code is doing things that need to happen persistently over the life of the
            // process then youw ould include something similar like the code below.
            //

            // We're calling CreateThread to create a thread that will execute alongside the process
            // we've been attached to. The reason why DLLs are so great for Tool is because all of
            // their code is executed in the same address space of the process that they're injected
            // in to.
            //
            // NOTE: Notice how we check for to see if the returned value is NULL and not 0.
            // Some people will check to see if CreateThread returns 0, this is a bad practice.
            // NULL is defined differently depending on the settings of your compiler. Notably,
            // NULL will be defined as 0 in C++, and as (void*)0 in C.
            if ( CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThread, NULL, 0, NULL) == NULL ) {
                // We did not successfully create a thread.
                return FALSE;
            }

            // We successfully created a thread of execution.
            // Now we can break the switch statement and return.
            break;
            
        // The DLL has been detached (unlinked) from a process.
        case DLL_PROCESS_DETACH:
            break;
            
        // These values will never occur because we called DisableThreadLibraryCalls.

        // The current process (the one we're attached to) is creating a thread.
        case DLL_THREAD_ATTACH:
            break;
            
        // The current process (the one we're attached to) has a thread that is exiting.
        case DLL_THREAD_DETACH:
            break;
    }

    // Although the return value doesn't actually matter. You typically
    // return the value TRUE or FALSE indicatinng success or failure.
    return TRUE;
}