Register for your free account! | Forgot your password?

Go Back   elitepvpers > Popular Games > League of Legends
You last visited: Today at 18:22

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



League of Legends camera struct reverse engineering!

Discussion on League of Legends camera struct reverse engineering! within the League of Legends forum part of the Popular Games category.

Reply
 
Old   #1
 
Alisami's Avatar
 
elite*gold: 19
Join Date: Sep 2007
Posts: 1,525
Received Thanks: 1,058
Exclamation League of Legends camera struct reverse engineering!

Hi!

I have been working on a Cameratool for League of Legends, and I wanted to share some of my explorations and maybe ask for some help.

To begin with the camera stuff, I searched for the x-axis-position of the camera by moving left and right and searching for increased and decreased float values in Cheat Engine.

I found the x-Axis and continued by trial and error, and I got this:

float xpos;
float ypos;
float zpos;
float readonly; //?
float Farclip; //standard 5000
float Rotation1; // 00 00 00 00
float Rotation2; /-0,8/0,8
float Rotation3; // 0,55/6
float Roll; //
float DoRender // 0,00 = dont draw
float readonly2;
float FOV; //standard 50


But Soon I realized that something was wrong with the Rotations, Yaw Pitch and Roll were not pi-values or degrees.

Also, important about this struct:

You cant just change the values since they are being set by a function that gets the "real" values from another place in the memory. So, you can either nop the relevant parts of the function that sets these values or you can find the "source" of the values.

So, I went looking for the source, here is the IDA-decompiled camera-setter-function:

Code:
int __thiscall setCamera7E8E20(void *this, int a2)
{
  void *v2; // edi@1
  int v3; // ecx@1
  char v4; // cl@8
  int v5; // eax@9
  double v6; // st7@11
  float v7; // ST10_4@11
  double v8; // st7@11
  float v9; // ST0C_4@11
  float v10; // xmm5_4@11
  float v11; // xmm1_4@11
  float xCamPos; // xmm4_4@11
  __m128 v13; // xmm0@11
  float zCamPos; // xmm2_4@11
  float yCamPos; // xmm3_4@11
  bool v16; // cf@11
  bool v17; // zf@11
  float v18; // xmm0_4@11
  double v19; // st7@13
  int v20; // esi@15
  float v21; // xmm1_4@15
  double v22; // st7@15
  float v23; // xmm2_4@15
  float v24; // xmm0_4@15
  double v25; // st7@16
  char v27; // [sp+8h] [bp-4Ch]@0
  int v28; // [sp+14h] [bp-40h]@11
  int v29; // [sp+18h] [bp-3Ch]@11
  int v30; // [sp+1Ch] [bp-38h]@11
  float v31; // [sp+20h] [bp-34h]@11
  float v32; // [sp+24h] [bp-30h]@11
  float v33; // [sp+28h] [bp-2Ch]@11
  float v34; // [sp+2Ch] [bp-28h]@11
  float v35; // [sp+30h] [bp-24h]@11
  float v36; // [sp+34h] [bp-20h]@11
  float v37; // [sp+38h] [bp-1Ch]@11
  float v38; // [sp+3Ch] [bp-18h]@11
  float v39; // [sp+40h] [bp-14h]@11
  float v40; // [sp+44h] [bp-10h]@12
  float v41; // [sp+48h] [bp-Ch]@11
  float v42; // [sp+4Ch] [bp-8h]@8
  float camPosPointer; // [sp+5Ch] [bp+8h]@15
 
  v2 = this;
  v3 = dword_2E279F8;
  if ( !dword_2E279F8 )
  {
    sub_9942D0(
      (int)"(spMultiplayerClient != NULL)",
      (int)"C:/jenkins/workspace/game-code-Releases-4-11-public-win32/code/Game/LoL/Main/Client/MainClient.cpp",
      2073,
      "NetAPI::GetClient",
      (int)"NetAPI::GetClient: Client pointer not created yet!",
      v27);
    v3 = dword_2E279F8;
  }
  if ( *((float *)v2 + 66) < -999.0 && !dword_2E27BEC )
  {
    if ( (unsigned __int8)(*(int (**)(void))(*(_DWORD *)v3 + 176))() )
    {
      if ( dword_2E27B94 )
      {
        if ( *(_DWORD *)(dword_2E27B94 + 288) )
        {
          sub_59ECB0(&v42);
          if ( v42 != 0.0 )
          {
            v5 = sub_5B94A0(v4, SLOBYTE(v42));
            if ( v5 )
              sub_7EA0C0(v5 + 100);
          }
        }
      }
    }
  }
  *((_DWORD *)v2 + 66) = 0;
  sub_7EAE70(v2);
  v31 = *((float *)v2 + 65);
  v32 = *((float *)v2 + 66);
  v33 = *((float *)v2 + 67);
  v34 = *((float *)v2 + 65);
  v35 = *((float *)v2 + 66);
  v36 = *((float *)v2 + 67);
  sub_7EC3A0((char *)v2 + 424);
  v6 = (*((float *)v2 + 110) + *((float *)v2 + 110)) * 0.00066666666 * *((float *)v2 + 108);
  v42 = v6;
  v7 = v6;
  sub_7EC510(LODWORD(v7));
  v8 = *((float *)v2 + 72);
  v37 = 0.0;
  v9 = v8;
  v38 = 0.0;
  v39 = 1.0;
  v28 = 0;
  v29 = 0;
  v30 = 0;
  sub_881400(LODWORD(v9), &v28);
  v10 = v36;
  v11 = v35;
  xCamPos = (float)(v42 * 0.0) + v31;
  v13 = (__m128)*((_DWORD *)v2 + 73);
  v13.m128_f32[0] = v13.m128_f32[0] - *((float *)v2 + 74);
  zCamPos = (float)((float)(COERCE_FLOAT(_mm_xor_ps((__m128)LODWORD(v38), (__m128)xmmword_1153A70)) * 600.0) * v42)
          + v32;
  yCamPos = (float)((float)(COERCE_FLOAT(_mm_xor_ps((__m128)LODWORD(v39), (__m128)xmmword_1153A70)) * 600.0) * v42)
          + v33;
  v41 = v13.m128_f32[0];
  v13.m128_i32[0] = (unsigned __int128)_mm_and_ps(v13, (__m128)xmmword_1153A60);
  v16 = v13.m128_f32[0] < 0.0000099999997;
  v17 = v13.m128_f32[0] == 0.0000099999997;
  v18 = v34;
  if ( !v16 && !v17 )
  {
    v38 = zCamPos - v35;
    v37 = xCamPos - v34;
    v39 = yCamPos - v36;
    v42 = (float)((float)(v38 * v38) + (float)(v37 * v37)) + (float)(v39 * v39);
    v40 = sub_5F5130(LODWORD(v42));
    if ( v42 > 9.9999997e-10 )
    {
      v19 = sub_66C000(LODWORD(v42));
      v37 = v37 * v19;
      v38 = v38 * v19;
      v39 = v19 * v39;
    }
    sub_5F0D30(LODWORD(v41));
    v11 = v35;
    v10 = v36;
    v18 = v34;
    zCamPos = (float)(v38 * v40) + v35;
    xCamPos = (float)(v37 * v40) + v34;
    yCamPos = (float)(v39 * v40) + v36;
  }
  v20 = a2;
  v21 = v11 - zCamPos;
  *(_DWORD *)(a2 + 48) = 0;
  v22 = *((float *)v2 + 76);
  *(float *)(a2 + 4) = zCamPos;
  v23 = v18 - xCamPos;
  *(float *)(a2 + 44) = v22;
  *(float *)a2 = xCamPos;
  *(float *)(a2 + 8) = yCamPos;
  v40 = v18 - xCamPos;
  *(float *)(a2 + 24) = v21;
  v41 = v21;
  *(float *)(a2 + 20) = v18 - xCamPos;
  v42 = v10 - yCamPos;
  v24 = v42 * v42;
  *(float *)(a2 + 28) = v10 - yCamPos;
  camPosPointer = (float)((float)(v23 * v23) + (float)(v21 * v21)) + v24;
  if ( camPosPointer > 9.9999997e-10 )
  {
    v25 = sub_66C000(LODWORD(camPosPointer));
    *(float *)(v20 + 20) = v40 * v25;
    *(float *)(v20 + 24) = v41 * v25;
    *(float *)(v20 + 28) = v25 * v42;
  }
  return sub_7EC0B0(v20);
}

The relevant thing here is
Code:
  *(float *)a2 = xCamPos;
a2 is set to the xCamPos (I named it like that).

a2 is the pointer that is a parameter to the function. Changing it would only change the position in the memory where we write.


But what is "xCamPos"?

Code:
  xCamPos = (float)(v42 * 0.0) + v31;
it seems like its just v31, since v42*0.0 is zero.

Code:
  v31 = *((float *)v2 + 65);
So, v31 is v2+65 dereferenced, but what is v2?

Code:
v2 = this;
Yes, it is "this". The "this" Pointer can be found in "ECX", since the function has the thiscall call convention.

So I went looking in ECX+65, but there wasnt a pointer to the x-axis-value of the camera, just a zero. I looked into the memory, moved the cam around to see some changing values and yes!, I found some of the values I found earlier also in this "struct".

this + 104/260 = xpos
this + 10C/268 = ypos
this + 120/288 = Pitch
this + 124/292 = Roll
this + 128/296 = Yaw
this + 12C/300 = ?
this + 130/304 = FOV
this + 1B8/440 = zpos atm
this + 1BC/444 = zpos go to pls


So, we got the Xpos, Ypos. Those and all other values in THIS particular struct can be directly set and will also instantly represent in the game. Thats definitely better than nopping parts of functions. Pitch Roll and Yaw are given in degree measure, standard is 180, alot easier than the struct I found before.

Also an interesting question: Why do these values appear so far from the beginning of the struct? There is not much inbetween.

FOV is 50 as standard value, looks like this when changed btw:




Then there is problem Number 1: We got 2 zpos values, "zpos atm" is the real value that our z-value has RIGHT AT THE MOMENT. "zpos go to pls" however is another value - If you change this one, "zpos atm" will smoothly jump to the value of "zpos go to pls". But it will not go over 2250, since thats the official maximum for zooming out. You can obviously change that by finding the place in the code where this value is being read in, but does anyone here have a better idea?

And problem number 2 is: I need the farclip, but I cannot find it in this new struct. It works if I combine the old one and the new one, but id like to avoid that. If anyone here has some information about this second structure I'd appreciate some insight.

With this new struct I can already create some nice scenes, and I will continue using that one.



If you got any questions regarding this topic, please ask, Id also like to help.

- Alisamix
Alisami is offline  
Reply


Similar Threads Similar Threads
[Buying] Reverse engineering
06/25/2014 - Coders Trading - 1 Replies
Hello everybody, I am searching for a reverse engineer+coder to help me out with something. We're paying a good amount of money if you're able to do the job. For more information PM me or add me on skype : jaxallods Thanks, - Jax
Reverse Engineering
05/26/2014 - General Coding - 5 Replies
Guten Tag, wollte mich in nächster Zeit mal mit Reverse Engineering beschäftigen. Kann mir jemand ein gutes Buch zu dem Thema empfehlen? MfG
[Help]Reverse Engineering
08/23/2011 - Private Server - 0 Replies
Hello Guys , I will not take much time from you . let me get to the story fast , me and other 300 player were playing online game which is closed now with no reason { You Can Check That } . Well We Tried To Find/Buy The Server Files But With No Good . Someone Told Me You Can Make An Emu Or Something Like That From The Game Client If You Are Pro In reverse engineering And Other Said You can Make One If You Are Pro Mysql And Got The Oldest Version Of The Game . Well I Hope Someone Can Tell Me...
Reverse Engineering...
07/11/2011 - SRO Coding Corner - 5 Replies
Hi, I just wanted to ask, if those guides, on this web: Reverse Engineering | malprogramming.net are enough to learn about reverse engineering, or a bit, or atleast, as much as that, that I as example, can do later something with it. Or its just crap and some infos about reverse engineering on that website? Because I dont want read 3hours of something wrong.



All times are GMT +1. The time now is 18:23.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.