Deprecated: The behavior of unparenthesized expressions containing both '.' and '+'/'-' will change in PHP 8: '+'/'-' will take a higher precedence in /home/iano/public_html/tpforums-vb5/forum/includes/class_core.php on line 5842

PHP Warning: Use of undefined constant MYSQL_NUM - assumed 'MYSQL_NUM' (this will throw an Error in a future version of PHP) in ..../includes/init.php on line 165

PHP Warning: Use of undefined constant MYSQL_ASSOC - assumed 'MYSQL_ASSOC' (this will throw an Error in a future version of PHP) in ..../includes/init.php on line 165

PHP Warning: Use of undefined constant MYSQL_BOTH - assumed 'MYSQL_BOTH' (this will throw an Error in a future version of PHP) in ..../includes/init.php on line 165

PHP Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in ..../includes/functions_navigation.php on line 588

PHP Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in ..../includes/functions_navigation.php on line 612

PHP Warning: Use of undefined constant misc - assumed 'misc' (this will throw an Error in a future version of PHP) in ..../global.php(29) : eval()'d code(6) : eval()'d code on line 1

PHP Warning: Use of undefined constant index - assumed 'index' (this will throw an Error in a future version of PHP) in ..../global.php(29) : eval()'d code(6) : eval()'d code on line 1

PHP Warning: Use of undefined constant misc - assumed 'misc' (this will throw an Error in a future version of PHP) in ..../includes/class_bootstrap.php(1422) : eval()'d code(4) : eval()'d code on line 1

PHP Warning: Use of undefined constant index - assumed 'index' (this will throw an Error in a future version of PHP) in ..../includes/class_bootstrap.php(1422) : eval()'d code(4) : eval()'d code on line 1

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6
[OTClient] How to build a Full Light Hack
Page 1 of 3 123 LastLast
Results 1 to 10 of 24

Thread: [OTClient] How to build a Full Light Hack

  1. #1
    Senior Member
    Join Date
    Jan 2012
    Posts
    417

    [OTClient] How to build a Full Light Hack

    Hi,

    this tutorial is meant to build a Full Light Hack mostly based on OTClient source code. You will need Cheat Engine to follow this guide and I'll use Medivia (Open GL version) as example, since their client is a customized OTClient version.

    Outline:



    1. Find Light address
    2. Find and patch instructions responsible for changes to the Light address when we turn a torch on/off
    3. Find and patch instructions responsible for changes to the Light address when we get into a cave


    Find Light address



    For a light hack, of course, we need somehow to overwrite the client's light value, so we need Light address.

    You can check that OTClient stores a light value in the creature object (or children objects in the hierarchy): https://github.com/edubart/otclient/...ent/creature.h

    At this time, the current Light structure is defined at https://github.com/edubart/otclient/...nt/thingtype.h

    The easiest way I can think of to find Light address is to find Direction first, because Direction is a few members above Light and Direction is enum (this means Direction is really easy to find with Cheat Engine),
    defined at https://github.com/edubart/otclient/...client/const.h

    Steps:
    1. Turn your character to north and search for 0

    2. Turn east and search for 1
    3. Turn south and search for 2
    4. After repeating this process a bit, I'll suppose you got a single address. So, add this address to the list and browse memory region
    5. As we know, Light address is really close to the Direction address. So, turning a torch on/off we can see where the Light is stored

    6. If you got to this point, you know the address where Light is stored, but you need the pointer path, since it is not static. For this, add the Light address to the list and use Pointer scan for this address CE feature with the following configuration. Hint: begin Max level with 1 and increase it until you got a path

    7. Expected result

  2. #2
    Senior Member
    Join Date
    Jan 2012
    Posts
    417
    Find and patch instructions responsible for changes to the Light address when we turn a torch on/off




    Everytime you turn a torch on/off, the server sends such information to the client and then, the client parses this message and apply a small colored light around your character. In the end, our problem can be converted to: "How can we block the client applying these new values and stay with a value that we have provided (the full light)?"


    Well, you can find the function used by the client to parse such Light changes and nop certain things.


    This time, we'll follow another route: we'll set a breakpoint in the Light address and trick the client to always assign a Full Light value, regardless the real value received from the server. In other words, we are looking for a MOV instruction referencing the address with offset equal to Light in the pointer path where we can place our Full Light value.


    The idea is:


    In C, C++, we want something like this
    Code:
    creaturePtr->setLight({FULL_INTENSITY, DAY_COLOR});

    In ASM, we want something like this
    Code:
    MOV LIGHT_ADDRESS FULL_INTENSITY_COMBINED_WITH_FULL_COLOR

    That being said, we can just "Find out what writes to this address" to Light address in CE to see related code changing values without stopping client execution.


    Steps:

    1. In the Light address path from 'Pointer scan' in the address list, right click it and Find out what writes to this address
    2. Find what writes the address pointed at by this pointer
    3. Turn on/off a torch and select the new entry generated by changes to Light address, then click Show disassembler button
    4. Scroll up a bit and we'll see something like this

      We can see a few mov instructions around:

      1. mov ax, [ebp-SOMETHING]
      2. mov [ecx+LIGHT_OFFSET], ax




      The line mov [ecx+LIGHT_OFFSET], ax in C means
      Code:
      creaturePtr->setLight(someLight);
      ,
      because ax holds the light value received from the server.


      Now, we want to swap this ax to our Full Light: how do we do that?
      From the sources, we know that Light is a structure 2-bytes long and if we try to assemble this line, there's some incompatibility in opcode length, i.e., we can't do:
      Code:
      mov [ecx+LIGHT_OFFSET], FULL_LIGHT

      The line with mov ax, [ebp-SOMETHING] means assign a value from some parameter of this function to ax register. The good news is: we can do the trick here and it solves the problem:
      Code:
      mov ax, FULL_LIGHT

      So, select this line, right click and click Assemble
    5. Type
      Code:
      mov ax, D7FF

      0xFF is our full light intensity. 0xD7 is our full light color

    6. After these steps, we'll have something like this




      • The green circle address contains these opcodes that we need to patch with full light
      • The red circle contains the bytes we are going to write through WriteProcessMemory


  3. #3
    Senior Member
    Join Date
    Jan 2012
    Posts
    417
    Find and patch instructions responsible for changes to the Light address when we get into a cave




    If you got this far, this will be easy for you.


    At this point, everytime we use a torch or cast something like utevo lux, the client writes our full light to the light address. The problem is that somewhere in OTClient, when we are in the main floor and go down + 1, you will see the dark again.


    I don't like to guess where OTClient developer wrote these things, so we will do pretty much everything we have done so far for the Torch case, except that at first step, we'll use a torch to activate our "almost finished light hack".


    Steps:

    1. Turn a torch on/off - DO NOT CAST MAGIC SPELLS (full light gets enabled)
    2. In the Light address path from 'Pointer scan' in the address list, right click it and Find out what writes to this address
    3. Find what writes the address pointed at by this pointer
    4. Go down main floor + 1 (e.g.: go to a cave). At this step, everything shall be in the darkness and Cheat Engine shown some instruction
    5. You can follow the "same" instructions from the Torch case in the second post to get:




    How To Code




    Now, this can be done programmatically:

    1. Patch Torch-case address (given by Address column) with opcode bytes (given by Bytes column)
    2. Patch Cave-case address (given by Address column) with opcode bytes (given by Bytes column)
    3. Write full light address to Light address




    Check and test this sample code to be executed in Cheat Engine (Medivia OpenGL) to understand the process:
    Code:
    -- get the base address
    local baseAddress = getAddress("Medivia_OGL.exe")
    
    
    -- light intensity = 0xFF
    -- light color = 0xD7
    local lightValue = { 0xFF, 0xD7 }
    
    
    -- address to creature pointer
    local creaturePtrAddress = baseAddress + 0x00579A68
    -- offset to light address
    local lightOffset = 0xA4
    
    
    -- address to patch when we turn torch on or
    -- cast something that changes current light
    local torchAddress = baseAddress + 0xDF336
    
    
    -- address to patch when we change our character
    -- z position (e.g.: get into a cave) and we get a light change
    local floorChangeAddress = baseAddress + 0xE5B76
    
    
    -- cheat code: mov ax, D7FF
    local opcode = { 0x66, 0xB8, 0xFF, 0xD7 }
    
    
    -- patch with our cheat code
    writeBytes(torchAddress, opcode)
    writeBytes(floorChangeAddress, opcode)
    
    
    -- at end, we write our desired light to the light address
    -- to force the client display our new light:
    -- first, read pointer
    -- later, write light value to light offset
    local creaturePtr = readInteger(creaturePtrAddress)
    local lightAddress = creaturePtr + lightOffset
    writeBytes(lightAddress, lightValue)

  4. #4
    Junior Member
    Join Date
    Jul 2009
    Posts
    22
    Thank you very much!!

  5. #5
    Administrator
    Join Date
    Mar 2007
    Posts
    1,723
    Nicely written.

  6. #6
    Great tutorial, congratulations!

  7. #7
    Nice, looking to update my old Tibianic cavebot for Medivia. Took a fast glance at OTClient source. Any notable changes the Medivia client has made to it?



    MainWindowHandle reads back an invalid number, those numbers doesnt even show up in spy++
    Last edited by normik; 02-16-2016 at 09:32 PM.

  8. #8
    Senior Member
    Join Date
    Jan 2012
    Posts
    417
    Quote Originally Posted by normik View Post
    Nice, looking to update my old Tibianic cavebot for Medivia. Took a fast glance at OTClient source. Any notable changes the Medivia client has made to it?



    MainWindowHandle reads back an invalid number, those numbers doesnt even show up in spy++
    I dont know. I just tried this light hack and simple cheats

  9. #9
    Senior Member
    Join Date
    Nov 2009
    Posts
    320
    When I try the option "Find out what writes to this address", even opening CE in Admin mode


    #Edit: nvm, i am dumb xD
    Last edited by Devil; 02-28-2016 at 01:35 AM.
    oi amiguinhos

  10. #10
    Junior Member
    Join Date
    Mar 2016
    Location
    Brazil
    Posts
    2
    My pointerscan return nothing
    how to fix that ?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •