-3
const char* GetName()
{
    std::string s = *(std::string*)(this + 0x28);
    return s.c_str();
}

Update:

struct Entity
{
    static Entity* GetCurrentPlayer()
    {
        return  (Entity*)(*(DWORD*)((DWORD)GetModuleHandleA("League of Legends.exe") + (DWORD)ADR_LocalPlayer));
    }
}

Update2:

This is how it looks in Cheat Engine

Actually, all i need to do is the same like Cheat Engine does: Read the string located at some pointer (this) + Offset 0x28 returned as const char* as i need this datatype right after.

I also tried directly accessing the address with const char*, this gave me cryptic symbols. Example at the top is crashing the game.

I guess i either need another datatype or another way to access the data?!

Note: This is an injected DLL and i'm accessing the data via an address

AndiiX
  • 37
  • 6
  • 1
    [undefined behaviour](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) – chris Jun 24 '14 at 20:53
  • [...] at some pointer (this) + Offset 0x28 [...] – AndiiX Jun 24 '14 at 20:57
  • 1
    How do you know what you want is at 0x28 offset? How do you know what `this` is? Modern OSes protect one process's memory from other's. – Steve Jun 24 '14 at 20:57
  • I updated the original post, it's getting called Entity::GetCurrentPlayer()->GetName(); .. how do i know what i am looking for is at my pointer + 0x28 ? Because Cheat Engine does it aswell – AndiiX Jun 24 '14 at 20:59
  • By the way, i already know where i have to get my data as this already works, for example like this to get a x coordinate of a player: float GetX() { return [star](float[star])(this + OFS_Local_PosX); } – AndiiX Jun 24 '14 at 21:14
  • @AndiiX Sorry! I can't tell actually, my 2 major _crystal ball_'s are out for this week. because of major maintenance issues I'd come out with a better suggestion when I've got them back. (I hope well, you can stand sarcastic comments here!). – πάντα ῥεῖ Jun 24 '14 at 21:14
  • 1
    You said you tried to access the offset with `const* char`, and are now trying with `std::string`. First of all, you should realize that a `std::string` is not at all the same thing as a POD C `char*`. Are you sure that at `this+0x28` you have a `std::string`? – vsoftco Jun 24 '14 at 21:19
  • Well that is one question, i have no idea what the datatype "text" actually is, which makes it more difficult – AndiiX Jun 24 '14 at 21:27
  • Considering League of Legends can be played to earn money, this question itself is fairly questionable. – Steve Jun 24 '14 at 21:39
  • Where are you getting ADR_LocalPlayer from? – David Zech Jun 24 '14 at 21:57
  • It's a pointer to my local hero object. + 0x28 gives me my name – AndiiX Jun 24 '14 at 21:59
  • I think you need to do some more reverse engineering before doing anything else. – David Zech Jun 24 '14 at 22:02

2 Answers2

1

I think this is what you need, set the target address to Read, Write and Execute (if you even want to change code).

VirtualProtect((LPVOID)targetaddress,5,PAGE_EXECUTE_READWRITE,&oldp);

This is a full scenario:

  1. Write a DLL with a shared memory section. The DLL should be linked to your main application to enable receiving notifications or data (the string), and to enable sending commands from your main app if you need to control the remote process.

  2. Your main application should create the remote thread, the code in that thread would be to Load the DLL into the remote process, and then the DLL should take over from there.

  3. Using the inter-process communication mechanism of your choice, start sending/receiving data between the remote process and your main application.

Here's a DLL injection function (in your main app) to inject your DLL into the remote process:

int Inject(char *fname,char *dllname,int NewProcess,DWORD PID) // 1=new process, 2= PID, 3=current process
{
    STARTUPINFOA si;
    PROCESS_INFORMATION pi;
    BOOL rv;
    void *pr;
    HANDLE hh;
    SIZE_T bwrit;
    DWORD par,tid;HANDLE th;
    FARPROC LoadLibProc = GetProcAddress(GetModuleHandleA("KERNEL32.dll"), "LoadLibraryA");
    FARPROC ExitThreadProc = GetProcAddress(GetModuleHandleA("KERNEL32.dll"), "ExitThread");
    char InjectedCode[500] = 

        {// 0xcc,
            0x60,        // pushad
            0xB8, 00, 00, 00, 00,   // mov EAX,  0h | Pointer to LoadLibraryA() (DWORD)
            0xBB, 00, 00, 00, 00,   // mov EBX,  0h | DLLName to inject (DWORD)
            0x53,                   // push EBX
            0xFF, 0xD0,             // call EAX
            0x5b,                   // pop EBX
            0xB8, 00, 00, 00, 00,   // EAX 2 mov EAX,  0h | Pointer to ExitThreadProc() (DWORD)
            0x6a,00,         // Push 00
            0xFF, 0xD0,             // call EAX

            //0xcc                  // INT 3h
    0x61,                 // popad
    //0xcc
        //  0xc3 // ret
        };

            int nob=30;

            char *DLLName;
            DWORD *EAX, *EBX, *EAX2;

            DLLName = (char*)((DWORD)InjectedCode + nob);
            strcpy( DLLName, dllname );
            EAX = (DWORD*)( InjectedCode +  2);
            EBX = (DWORD*) ( InjectedCode +  7);

            EAX2 = (DWORD*)( InjectedCode +  16);

    *EAX=(DWORD)LoadLibProc;
    *EAX2=(DWORD)ExitThreadProc;
    *EBX=nob;

    ZeroMemory((VOID*)&si, sizeof(si));
    si.dwFlags=STARTF_USESHOWWINDOW;//1
    si.wShowWindow=SW_HIDE;//0

    if (NewProcess==1) {
        rv=CreateProcessA(fname,0,0,0,FALSE,CREATE_SUSPENDED,0,0,&si,&pi);
        if (rv==FALSE) {return -1;}
        hh=pi.hProcess;
    }

    TCHAR bb[200];
    if (NewProcess==2) {////PROCESS_ALL_ACCESS
        hh=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_WRITE|PROCESS_VM_OPERATION  ,0,PID);
        if (hh==NULL) return -6;
    }

    if (NewProcess==3) {
        hh=GetCurrentProcess();
    }

    //if (hh==INVALID_HANDLE_VALUE) {printf("\nError Opening Process...");return;}
    pr=VirtualAllocEx(hh,0,500,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
    if (pr==NULL) return -7;
    Sleep(100);
    //printf("\nAddress Allocated=%x",pr);
    *EBX+=(DWORD)pr;

    rv=WriteProcessMemory(hh,pr,InjectedCode,500,&bwrit);
    if (rv==0) return -8;

    th=CreateRemoteThread(hh,NULL,0,(LPTHREAD_START_ROUTINE)pr,&par,0,&tid);

    if (th==NULL) return -9;
        return 0;
}

Now for the DLL, in your DLL CPP, add the shared memory section to hold data for inter-process communication:

    #pragma data_seg("shared")

    char whateverdatatoshare[16384]={0}; 

// you can also define events or variables to use to signal the remote process or the main app of any incoming data


#pragma data_seg()
#pragma comment(linker, "/section:shared,rws") // This instructs the linker to make this section readable,writable and shared

In your APIENTRY dllmain function, create a thread to do whatever you want, like reading your string or data every second to send it back to the main app.

BOOL APIENTRY DllMain1( HMODULE hModule,
                   DWORD  ul_reason_for_call,
                   LPVOID lpReserved
                 )
{
DWORD par,tid;
HANDLE thandle;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:

    thandle= CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&MsgThread,&par,0,&tid);

    break;
case DLL_THREAD_ATTACH:
    break;
case DLL_THREAD_DETACH:
    break;
case DLL_PROCESS_DETACH:

    break;
}
return TRUE;

}

The your thread code should do the actual work of sniffing the string you want.

Very Important: To make sure you can read/write in memory, use this:

First set the page to PAGE_EXECUTE_READWRITE

**VirtualProtect((LPVOID)targetaddress,5,PAGE_EXECUTE_READWRITE,&oldp);**

Second: IsBadWritePtr or IsBadReadPtr, to make sure you can write or read.

Anmar
  • 11
  • 2
0

As Steve already mentioned you won't be able to access an other application's memory since it is protected by the OS. You can check that by running two little programs, the first creates a variable, stores its pointer in a file and keeps running after that (by waiting for user input or whatever). The second program reads the pointer from the file and then tries to use its content. Won't work.

Furthermore check out the documentation for GetModuleHandleA: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683199%28v=vs.85%29.aspx

It says:

"Retrieves a module handle for the specified module. The module must have been loaded by the calling process."

And:

"The name is compared (case independently) to the names of modules currently mapped into the address space of the calling process."

As you want to get a module which was loaded by another process this won't work either.

a_guest
  • 34,165
  • 12
  • 64
  • 118
  • GetModuleHandleA gives me the module entry address as this changes each game start. I can actually even access the data already, the question is only how the data is stored or how i can get it – AndiiX Jun 24 '14 at 21:46