Sunteți pe pagina 1din 20

:::TUTORIAL FOR TWELVE SKY MEMORY SEARCHING:::

Here is a tutorial on how to:

1: Search out the address that holds and updates your


current Health using T-Search.
2: How to breakpoint that address to find out what Static
addresses Write to it(update it).
3: How to use to OllyDbg to determine the OFFSET that points
to your Current Health in
Memory. Then how to get the Maximum Health OFFSET.
4: How to search for the Pointer Address from there that you
will use with the OFFSET you
found above to gain access to your current Health in memory
as it is constantly being
updated.
5: And last how to use the information you have obtained to
make a small program that will
automatically press your Pill key(1,2,3,or 4) when your
health drops below the percent that
you set. I will use a simple dll setup that will create a
new thread. Using
ReadProcessMemory in a loop within the new thread you will
create your own pointers to the
Maximum and Current Health values that can then be used to
make a function for your AutoKeyPress at
the time you want it to do so(50% HP & Below, 40% HP & Below
ect...).

NOTE: When Entering Addresses Into OllyDbg Remember To Add


0x In Front Of It Or It Will Not Recognize It.

_____________________________________________________

--Step 1: Searching for the initial Health address.--


_____________________________________________________

I will be using T-Search for this Tutorial as it is what I


primarily use.

First of all open up T-Search. Once T-Search is opened load


up TwelveSky, Login
to your account that you will be using(but make sure you
have at least a few HP pills on your
character), and load up your character into the game. Now
ALT+TAB out of the game and open
up the game in T-Search. To do this, Click on the "Open
Process" button in the upper left hand corner of the
program.
Now go back into the game and if your character is not in an
area with mobs that can actually do some damage to it,
then move your character to an area/zone where you can get
some damage taken. Once there stop(make sure your health
is full), then ALT+TAB back out to T-Search. Now you are
going to start
a new search. In T-Search you will need to click on the
magnifying glass icon in the top
left of the program just below the open process button. Now
leave it how it is on the "Exact Value" and "4Byte"
settings.
In the "Value" field type in your Health and in T-Search hit
"OK".
Wait for it to complete then go ahead and hit "OK" again.
Go back into
the game now and fight a mob. Make sure lose a good amount
of your health(I usually do
about half) and then kill off the mob(so it dosen't keep
hitting you while your scanning).
Now ALT+TAB back out again. Now you will start another
scan. This time you will be searching for "Changed Value".
In T-Search go ahead and hit the second magnifying glass
icon just to the
right of the first one. In "Search" field where it says
"Exact Value" hit the drop down list. Select the "Has
Changed"
option just below "Exact Value". Now hit "Ok" start the
next the scan. Again wait for completion and hit "Ok"
again.
You should now get only one address in the list. If you
have more than one address, just go back into the game and
use
HP Pills until you have full health again. Then do another
search(using the second magnifying glass again) for your
health
again. By now you should have only one address in the list,
if not just keep repeating the scans until you narrow it
down. Now hit the yellow "+" sign to move the address entry
over to the right field where you will be able to edit it.
You should notice if you are still damaged it will be
constantly going up. The address that I found was 1605C0.
This is a dynamic address so it will not be same on your
computer nor will it be the same the next time you load the
game(most of the time). To verify you found the correct
address just look in-game at what your current health is and
then ALT+TAB back out to T-Search and see where it is. Then
Heal yourself fully and go back to T-Search again and you
should see that it matches your health. Or you can just
double click in the value field and change the value to
whatever you like(ie: 1000000000). Then in-game it would
look like for example:
1000000000/1025. Of course that is only visual and has
absolutely no valuable effect, but at least you know that
you have the right address. Next we need to set a
breakpoint on that address to find the static address that
writes to it(this address will not change when you reload
the game). I will use OlyDbg to do this as it will break on
just one Static address witch is all we need for the sake of
our goal(Finding the Pointer address of your character and
the OFFSETS that point to your Maximum and Current Health)
so for the sake of this tutorial(assuming you are unfamiliar
with all of this or don't know how to use breakpoints in
OllyDbg, follow with the OllyDbg method first and then go
back later if you want to try it in T-Search, and if you
are familiar with memory scanning then skip past all of this
and go to the ollydbg section). You can however BreakPoint
your dynamic address with T-Search though, however it will
return 5 different addresses each pertaining to a different
function regarding your current health, such as Subtracting
when taken damage or Adding when healed. You BreakPoint the
address with T-Search by:

1: Clicking the "AutoHack" tab up on the top of the program.


2: Click on "Enable Debugger" from the dropdown list.
3: Click on "AutoHack Window" from the dropdown list.
4: In the "AutoHack Window" click on the edit tab up on the
top of the window.
5: Click on "Set BreakPoint" from the dropdown list.
6: Now in the little window that pops up you need to make
sure the "Type" field is set to "Write", and enter the
address you just found into the address field. So go back
to the original T-Search window, double on the address in
the "Address"
field until it is highlighted in blue(or just drag your
mouse over it to highlight) right click and select copy.
Now go back to the "AutoHack" window and paste into the
address field. Now Click on "Set BreakPoint".
7: Ok now that your breakpoint is set on the address, You
need to make your health change so that the game "writes" to
the address in order for T-Search to read what addresses are
writing to it. So go back into the game and take a couple
of good hits from a mob. Kill the mob and then use Pills to
fully heal yourself.
8: ALT+TAB Back out to T-Search and look in the "AutoHack"
window. You will see 5 addresses now with there pertaining
command. All of these addresses are static and will not
change the next you load the game, they should also be the
same on other machines. They all also have something to do
with altering your current health status in-game.

These are the addresses that I found:


These should be the same for you as well, if not don't
worry about, that is why we are going to find the Pointer.

407728: lea esi,[esp+0x70] // In this case the "ESP"


register is holding the Pointer and 0x70 is the OFFSET. So
ESP+0x70 is where your current HP is being held.
40A8AB: mov[ecx+0x168],edx // This is the address we will
eventually use. ECX+0x168 in this case would be the pointer
to your current HP, But we still need to find out what ECX
is, that is where OllyDbg comes in. I have also found that
if you set a breakpoint on this address and go into the
game, it will break if you click something(Ground to move,
Mob, ect).
44E002: sub[eax+ecx+168],edx // Subtracts the damage taken
from your HP ammount and stores the value into the EDX
Register.
44BBB6: add[eax+0x168],edx // Adds the Heal ammount to your
Current HP ammount and stores the value into the EDX
Register.
44BBF2: mov[edx+0x168],eax //Moves the New Current HP
Value into the EAX Register.

At this point we are done with T-Search. Make sure you


remember the Dynamic Address you found(open notepad and
paste/type it in for temp storage). Go ahead and close T-
Search(if you followed the steps above and attached the
debugger to breakpoint your address, since you attached a
debugger to the game, when you close T-Search it will also
close the game, in this case you will need to restart T-
Search and do Step 1 over again, since the address you
found was dynamic it will be different when you reload the
game. Or you can just use the SECOND address in the list
from "AutoHack"
(40A8AB: mov[ecx+0x168],edx) as this is the address that
OllyDbg will Break on and the address we will use to find
our pointer and offset). If you have a program to reset the
debug port you can use that first and then close T-
Search(Winject is a good example, Google it sometime if you
would to try it), otherwise don't worry about it, just
close out T-Search, reload the game, and either use the
SECOND address from "AutoHack" or Re-Scan for the Dynamic HP
Address.

On to OllyDbg >>>:<<<

_____________________________________________________

--Step 2: Setting a Breakpoint in OllyDebug.--


_____________________________________________________

Once you have realoaded the game and have logged back into
the game, go ahead and ALT+TAB back out of the game, go to
the directory where you put your copy OllyDbg. Launch
OllyDbg and attach it to the "TwelveSky.exe" Process in the
Process list. If you do not have OllyDbg just google it,
it is easy to find. The Current "Full" version is 1.10.
You want to get the 1.10 version as 2.0 is still in alpha
stages.
OK I googled for the people that don't have it:
http://www.ollydbg.de/

Look on the left side of the page under the "Files"


Category. Click on the first file "ODbg110.zip". Download
it. You will need winrar to open it(or winzip?). Make a
new folder on your computer anywhere you want it, and
extract the contents of the archive to that folder.

Ok first I will give a breakdown of the Main 4 Windows we


will be using:

CPU View: The Biggest window in Upper Left Hand Corner,


This is where all of the programs code is displayed and the
main window you will work with.

Register View: Upper Left Hand Corner, This is where the


Registers are displayed and the current values/addresses
they hold.

Hex Dump View: Bottom Left Hand Corner, Hex Dump.

Stack View: Bottom Right Hand Corner.

Ok double click OLLYDBG.exe and launch it. Once its running


you need to attach it to the game. Click on "File" "Attach
Process", then scroll through the list of running processes
until you find "TwelveSky.exe". Highlight "TwelveSky.exe"
and hit "Attach". It will then begin loading all of the
modules in the game. When it finishes attaching it then
leave the game in a Paused state. To Unpause the game click
the "Play" button on the top of the program just below the
"Debug" tab. Note: if you leave the game paused for too
long you will eventually get disconnected from the server.
If this happens you just need to log back in, NONE of the
addresses will change so you are safe and you don't have to
re-do anything(even the dynamic address will be the same
unless you reload the game entirely). Now first thing we
need to do is get to the beggining of the "TwelveSky.exe"
Module. Look at the top of the Olly window. There is a
list of buttons with letters in white boxes. Click on the
"E" button. Now double click on "TwelveSk". It should be
the first one in the list.

Note: In this view you can get the base address of the
Module you are working with(in this case TwelveSky.exe).
Here is what it should say:
Base=00400000 Size=00AA0000 (11141120.) Entry=00401000
TwelveSk.<ModuleEntryPoint> Name=TwelveSk
Path=C:\AeriaGames\12Sky\TwelveSky.exe
so if you didn't know before and you should ever need the
base address of a module in the game you are working with
this is where you can find it.

Ok now that you have double clicked on the "TwelveSk" Module


it should bring you into the "CPU" view. You will have
landed somewhere within the "NTDLL" Module. So go back to
the Modules view("E" Button up top) and double click on
"TwelveSk" one more time. Now you should be back in the CPU
View at the entry of the "TwelveSky.exe" Module. You should
be on this address:

00401000 > 8379 18 10 CMP DWORD PTR DS:[ECX+18],10


Now that we are in the "TwelveSky.exe" Module, go ahead and
left click inside of the "Hex Dump" view. Now right click
to bring up the menu of options. Find and select "Go To
Expression"(or you can just press CTRL+G within the "Hex
Dump" window, just make sure the "Hex Dump" is your active
window). Now enter in the dynamic address that you found in
T-Search. Hit "Ok". Your address is now the very first in
the list on the "Hex Dump" view. Now you need to highlight
the first 4 bytes(every 2 numbers is one byte, so for me it
is: 71 02 00 00). Here is what it should look like:

EXAMPLE:

Address Hex dump


ASCII
---------|------------------------------------------------|-
-----
001605C0 | 71 02 00 00 BB 00 00 00 BB 00 00 00 00 00 00 00|
q..»...».......
001605D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00|................
001605E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00|................

Yours will be different depending on the address you found


and your current HP ammount(the first 4 bytes are your
Current Health), so if you are damaged as it continues
healing you will see those numbers changing(You have left
click in the "Hex Dump" view for it update the numbers
though). Ok before we set the breakpoint we need to get
damaged. So go into the game and get hit for at least half
of your health(so it dosen't finish healing before the
breakpoint is set), also make to sure to finish off the mob
that you used to get damaged so you don't killed. Now
ALT+TAB back out of the game, and with the first 4 bytes
highlighted go ahead and right click again. In the Menu
this time select the "BreakPoint" option. Select and Click
on the "Memory, On Write" option. The game should pause
immediately. Now take a look in the "CPU" window again.
You should now have this address highlighted in the "CPU"
View:

0040A8AB 8991 68010000 MOV DWORD PTR DS:[ECX+168],EDX

Take note of the information in the little area there just


below the "CPU" window and just above the "Hex Dump" window.
This information will be very helpful for whatever you are
looking for:

EDX=00000204 //Value held in the EDX Register.


DS:[001605C0]=00000200 //Notice your Dynamic Address
printed between the brackets.

NOTE: again yours will look different then mine. The


dynamic address of course is different and the 2 values
shown tend to change with your Current Health Ammount.

Ok so now before we do anything else we need to remove our


breakpoint and unpause the game. So left click back into
the "Hex Dump" window and then right click again. Select
the "BreakPoint" option again. Now this time click on the
"Remove BreakPoint" option. Now hit the play button again
to unpause the game so you don't get disconnected.

_____________________________________________________

--Step 3: Using OllyDBG to get the OFFSET.--


_____________________________________________________

Ok so now back to the address that we broke on in the "CPU"


window:

0040A8AB 8991 68010000 MOV DWORD PTR DS:[ECX+168],EDX

This address should be the same on your computer as well,


but if it is not the instruction is and that is the
important thing. Right now looking at this instruction we
have found our OFFSET to the Current HP Value:

MOV DWORD PTR DS:[ECX+168],EDX // Move DWORD Pointer


[ECX+168],EDX so it moves the value of the ECX Register +
0x168 into
the EDX Register.
ECX+168 holds our Current HP Value.

So the OFFSET to the Current Health Value of your Character


is: 0x168

Now we need to know the OFFSET for the Maximum Health Value.
Subract 4 from 168 and that is the OFFSET to the Maxium
Health. So our OFFSETS are:

0x164 // Maximum Health OFFSET


0x168 // Current Health OFFSET

_____________________________________________________

--Step 4: Using OllyDBG to get the Player Pointer.--


_____________________________________________________

So, now that we have OFFSETS that point to both our Max and
Cur Health Values we need to know the pointer address of our
character. So we take another look at the instruction:

MOV DWORD PTR DS:[ECX+168],EDX //Since ECX+168 is the


Pointer to our Current HP Value then the pointer Address
that we
need to find is stored
in ECX.
So first thing we need to do is scroll up in the function
from our address containing the HP and look for something
that sets the EAX register. We are looking for something
like this as an example:

MOV ECX,DWORD PTR DS:[657D48] //Just an example, not a


real function

or sometimes it will be like this:

MOV EAX,DWORD PTR DS:[ECX] //In this case you would


need continue scrolling up until you find what sets EAX.
Until
you find the address.
IE: MOV EAX,DWORD PTR DS:[657D48]

Ok so back to our function. In this case it is really


simple to find the pointer as it is only 2 lines above our
original address. Here is the address that holds our
POINTER+OFFSET and a few lines above:

0040A876 8B0D E0A7D000 MOV ECX,DWORD PTR DS:[D0A7E0]


0040A87C 8B4424 30 MOV EAX,DWORD PTR SS:[ESP+30]
0040A880 8B7424 34 MOV ESI,DWORD PTR SS:[ESP+34]
0040A884 893D CC32A900 MOV DWORD PTR DS:[A932CC],EDI
0040A88A A3 5033A900 MOV DWORD PTR DS:[A93350],EAX
0040A88F 8935 5433A900 MOV DWORD PTR DS:[A93354],ESI
0040A895 8959 68 MOV DWORD PTR DS:[ECX+68],EBX
0040A898 8B15 E0A7D000 MOV EDX,DWORD PTR DS:[D0A7E0]
0040A89E 897A 6C MOV DWORD PTR DS:[EDX+6C],EDI
0040A8A1 8B0D E0A7D000 MOV ECX,DWORD PTR DS:
[D0A7E0] //Ah, ECX, Move ECX, DWORD POINTER [D0A7E0] ECX =
D0A7E0
0040A8A7 8B5424 28 MOV EDX,DWORD PTR SS:[ESP+28]
0040A8AB 8991 68010000 MOV DWORD PTR DS:
[ECX+168],EDX //Our Address that Holds our POINTER+OFFSET
to CUR HP.
0040A8B1 8B0D E0A7D000 MOV ECX,DWORD PTR DS:[D0A7E0]
0040A8B7 8B5424 2C MOV EDX,DWORD PTR SS:[ESP+2C]
0040A8BB 8991 70010000 MOV DWORD PTR DS:[ECX+170],EDX
0040A8C1 8B0D E0A7D000 MOV ECX,DWORD PTR DS:[D0A7E0]
0040A8C7 8981 D4000000 MOV DWORD PTR DS:[ECX+D4],EAX
0040A8CD 8B0D E0A7D000 MOV ECX,DWORD PTR DS:[D0A7E0]
0040A8D3 8B81 D8000000 MOV EAX,DWORD PTR DS:[ECX+D8]

So now to access our Current Health we just need do:

0xD0A7E0+0x168;

One way to use this in a program:

DWORD dwBytesRead; //Pointer to store original BYTES


DWORD dwPlayerBase; //Pointer to store our pointer
address into: 0xD0A7E0
DWORD dwCurrentHealth; //Pointer to store our current
health value into
DWORD dwMaximumHealth; //and pointer to store our max
health into

ReadProcessMemory(HANDLE, (void*)0xD0A7E0, &dwPlayerBase,


sizeof(dwPlayerBase), &dwBytesRead);//Reads the memory at
the

//----------
//address 0xD0A7E0.
//BreakDown:
//----------

/*HANDLE = pointer to the process to read from(ie:


TwelveSky.exe) will set that up in the next step.
0xD0A7E0 = Address to read from.

&dwPlayerBase = Our Pointer to store our Pointer Address


into from above, The function reads the memory at the
address
supplied and stores it into our Pointer dwPlayerBase.

sizeof(dwPlayerBase) = reads the size(ammount of bytes)

// BYTES READ BELOW


dwBytesRead = stores the bytes at the address(ie: the
instruction) 0040A8D3 8B81 D8000000 MOV EAX,DWORD PTR
DS[ECX+D8]

-------------
*/
ReadProcessMemory(HANDLE, (void*)(dwPlayerBase+0x168),
&dwCurrentHealth, sizeof(dwCurrentHealth), &dwBytesRead);
//----------
BreakDown:
//----------
//Same as above except now we use our POINTER+OFFSET to
store our CurrentHealth Value into our own Pointer:
dwCurrentHealth

ReadProcessMemory(HANDLE, (void*)dwPlayerBase+0x164),
&dwMaximumHealth, sizeor(dwMaximumHealth), &dwBytesRead);

//----------
BreakDown:
//----------
//Same as above except now we use our POINTER+OFFSET to
store our CurrentHealth Value into our own Pointer:
dwMaximumHealth

Now that we have our Maximum Health and Current Health


stored into our pointers we can use them to create a
function to automaically send a keypress at the correct
time. Source Code below for a simple dll project.

_____________________________________________________

--Step 5: Putting all of this information to use ----


_____________________________________________________
Now I will give an example project source code for a simple
dll that will attach to the 12Sky Process, and Create a new
thread, in the thread there will be a loop and inside the
loop goes the code from above and the function to send the
keypress to heal. The loop will force the program to keep
updating the information so that the pointers created above
will always hold the 2 Health values. Without the loop it
will just read the information once and currenthealth will
never update, it would just stay as it was when the dll was
first attached to the process. So here is the code and
explaination of the functions within:

/
************************************************************
************************************************************
************************************************************
************************************************************
*****
************************************ TWELVE SKY EXAMPLE DLL
PROJECT
*******************************************************
***********************************
+______________________________+
*******************000000000**************************
***************************************** AUTO HEALING BOT
************************************************************
****
************************************************************
************************************************************
************************************************************
************************************************************
*****/

// Single Line Comment

/*

Multi Line Comment


*/
//Commenting is used for any text within the source that you
don't want the compiler to read

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
#include <time.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <string.h>
using namespace std;

#define FILELOCATION "C:\\12SkyHelper\\12Sky.log" //Define


the output directory for the log file

void __cdecl add_log(const char * fmt, ...); //For the


log function

HANDLE TwelveSky = GetCurrentProcess(); //HANDLE


= Points to the Process/Module to read from
HWND SkyWnd = FindWindow(0, "TwelveSky"); //Used to
read if TwelveSky is the active window
//DWORD PID = GetPIDbyTitle("TwelveSky");
//Function from the winject source to find the current
//DWORD PID2 = GetPIDbyClass("TwelveSky");
//process's PID. Its just here for future use. Remove it
if you
//like or
you can google for "Winject Source" and add it to your
//project
.
DWORD dwBytesread; //Stores the original bytes from the
address read
DWORD dwCurHealth; //All of our pointers that will hold our
HP/MP Information and Our Base Pointer Address
DWORD dwMaxHealth;
DWORD dwPlayerBase;
DWORD dwCurMP;
DWORD dwMaxMP;
bool UseMed = true;//Boolean value to decipher weather or
not to use the MedKey function or to just use pills for MP
BYTE MedKey = VK_F5;//Value to tell the program which key to
use
float HPPercent = 0.5;//Float value to determine what
percentage of health we must either reach or drop below to
auto heal
float MPPercent = 0.5;//Same as above on for MP
DWORD Slot1;//Pointers for the Pill Slots to read weather
they have pills or they are empty
DWORD Slot2;
DWORD Slot3;
DWORD Slot4;
#define VK_1 0x31 //Define key 1-4 because it won't compile
if you try to use VK_1-9
#define VK_2 0x32
#define VK_3 0x33
#define VK_4 0x34

int SendKeyStroke(BYTE TheKeyToSend) //Our AutoKeyPress


function
{
keybd_event(TheKeyToSend, //KeyDown Event
MapVirtualKey(TheKeyToSend, 0),
0,
0);
keybd_event(TheKeyToSend, //KeyUp Event
MapVirtualKey(TheKeyToSend, 0),
KEYEVENTF_KEYUP,
0);
return 1;
}
DWORD ReadThread(LPVOID lpArgs) //Our Thread
{
add_log("Thread Started.");
while(1) //Start the Loop
{
//5579AC Pointer for GM Commands :)

//:::::: OUR READPROCESSMEMORY FUNCTIONS TO STORE THE


VALUES OF HP/MP INTO OUR POINTERS ::::::\\
//HANDLE TwelveSky = GetCurrentProcess();
ReadProcessMemory(TwelveSky, (void*)(0xD0A7E0),
&dwPlayerBase, sizeof(dwPlayerBase), &dwBytesread);
ReadProcessMemory(TwelveSky, (void*)
(dwPlayerBase+0x164), &dwMaxHealth, sizeof(dwMaxHealth),
&dwBytesread);
ReadProcessMemory(TwelveSky, (void*)
(dwPlayerBase+0x168), &dwCurHealth, sizeof(dwCurHealth),
&dwBytesread);

/*Our OFFSETS for MP can be found the same way as we


found the HP. Once you get the dynamic address of MP by
scanning
T-Search, BreakPoint it in OllyDbg, at the address
that it breaks on you will find ECX+170 in the instruction.
This is of course your Current MP Pointer. Subtract 4
from 170 and you get 16C(hex)*/
ReadProcessMemory(TwelveSky, (void*)
(dwPlayerBase+0x170), &dwCurMP, sizeof(dwCurMP),
&dwBytesread);
ReadProcessMemory(TwelveSky, (void*)
(dwPlayerBase+0x16C), &dwMaxMP, sizeof(dwMaxMP),
&dwBytesread);

//Read from the Pointer addresses of all 4 Pill Slots


and store the value(ammount of pills) to our own pointer
ReadProcessMemory(TwelveSky, (void*)(0xA93864), &Slot1,
sizeof(Slot1), &dwBytesread);
ReadProcessMemory(TwelveSky, (void*)(0xA9386C), &Slot2,
sizeof(Slot2), &dwBytesread);
ReadProcessMemory(TwelveSky, (void*)(0xA93874), &Slot3,
sizeof(Slot3), &dwBytesread);
ReadProcessMemory(TwelveSky, (void*)(0xA9387C), &Slot4,
sizeof(Slot4), &dwBytesread);

DWORD HealHealth = dwMaxHealth * HPPercent; // use our


MaxHealth Pointer and Multiply it by the float value we set
above
DWORD RestoreMP = dwMaxMP * MPPercent; // same but
with the MaxMP Pointer
if(SkyWnd == GetForegroundWindow()) //Makesure TwelveSky
is the Active window so It dosen't send Keypresses when you
are
{ //minimized
for(dwCurHealth; dwCurHealth <= HealHealth;
dwCurHealth++)//setup a loop for Current Health, if the
CurrentHealth
{
//is less than or equal the HealHealth(MaxHealth*HPPercent

//witch is set to 0.5 by default. 0.4 40% 0.3 30% 0.6 60%
if(Slot1 > 0) //Make sure Slot1 has pills(Slot1
Greater than 0)
{
SendKeyStroke(VK_1);
//Send the KeyPress
add_log("Your HP was just Restored via
Slot1"); //Add to the log alerting a keypress
}
else if((Slot1 == 0) && (Slot2 > 0)) //If slot1
is empty use and Slot2 has pills use slot2
{
SendKeyStroke(VK_2);
add_log("Your HP was just Restored via
Slot2");
}
else {add_log("Add HP Pills to Slot1 or
Slot2");} //if both slot1 and 2 are empty alert to the log
no pills
}
for(dwCurMP; dwCurMP <= RestoreMP; dwCurMP++)//same as
the HP but using the MP Pointers
{
if(!UseMed) //If Not UseMed(if the bool UseMed
is set to false continue)
{
if(Slot3 > 0) //check slot3 for pills
{
SendKeyStroke(VK_3);
add_log("Your MP was just Restored via
Slot3");
}
else if((Slot3 == 0) && (Slot4 > 0)) //slot3 out
of pills, check slot4 and use it if there are pills
{
SendKeyStroke(VK_4);
add_log("Your MP was just Restored via
Slot4");
}
else {add_log("Add MP Pills to Slot3 or
Slot4");} //Alert out of pills
}
if(UseMed) // if the bool value UseMed is set to
True it will use your meditation skill instead of MPPills
{ // use this when you are poor
SendKeyStroke(MedKey); //use the
sendkeystroke like normal but use the Variable MedKey so
that it can be
//can be custom set
via a config(config to be added at a later time)
add_log("Your MP is being Restored via
Meditation");
}
}
}
Sleep(1000);//Pause for 1000 miliseconds(1second) or
else the thread lags the program horribly
}
return 0;
}

BOOL WINAPI DllMain (HINSTANCE hModule, DWORD dwAttached,


LPVOID lpvReserved) //dll main, attach to process
{
if (dwAttached == DLL_PROCESS_ATTACH) //attach to
process
{
DeleteFile(FILELOCATION); //Deletes old log
to start a new one
CreateThread( NULL, NULL,(LPTHREAD_START_ROUTINE)
ReadThread , NULL, NULL, NULL); // create our thread
add_log("--------------------------"); //just some
logging
add_log("--------------------------");
add_log("----New Log Started-------");
add_log("Attached to 12Sky Client");
add_log("--------------------------");
add_log("--------------------------");
add_log("Thread Created.");
//add_log("PID = %d", PID); //used this with
winject source code to find the current PID of TwelveSky.exe
//add_log("PID = %d", PID2);
}

if (dwAttached == DLL_PROCESS_DETACH) //Detach DLL


{
add_log("DLL Detached from 12Sky Client"); //log
detach
}
return 1;
}
void __cdecl add_log(const char * fmt, ...) // and last the
logging function
{
#ifndef _NO_ADD
va_list va_alist;
char logbuf[256];
FILE * fp;
struct tm * current_tm;
time_t current_time;

time (&current_time);
current_tm = localtime (&current_time);
sprintf (logbuf, "[%02d:%02d:%02d] ", current_tm-
>tm_hour, current_tm->tm_min, current_tm->tm_sec);

va_start (va_alist, fmt);


_vsnprintf (logbuf+strlen(logbuf), sizeof(logbuf) -
strlen(logbuf), fmt, va_alist);
va_end (va_alist);

if ( (fp = fopen ( FILELOCATION , "a")) != NULL )


{
fprintf ( fp, "%s\n", logbuf );
fclose (fp);
}
#endif _NO_ADD
}

/
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
****************/

Hopefully it helps out and hopefully I didn't make too many


mistakes. I think I typed it out pretty clearly but please
if there is anything that is confusing of spelling errors or
the like point it out to me and I will fix it. Hopefully
this will spark a little bit of interest in TwelveSky and we
will see at least a small ammount of releases for the game.
Or at the very least it may help someone to find pointers
for whatever game they may want them for.

/*NOTES: To find the Pill Slot addresses just place a


certain of Pills into the slot and search that value in T-
Search(leave it at "Exact Value" and "4 Bytes". Then go in-
game and remove about 20 Pills. Then search the value of
however many Pills are left in the Slot. Then add some back
and search the new value. Rinse and Repeate until you are
down to only one address. Do the same thing for all 4
Slots. These address's are static so once you find all 4
address's in T-Search you are done and ready to add them to
your program.

MP can be the same as HP(but its a bit easier, not having


to get damaged and all). Just get your MP full, Search the
Value("Exact Value" "4 Byte"). Then use a skill, use your
buff skill. Go and search for "Changed Value". It should
now isoloate one Dynamic address. If not just rinse and
repeat the process until you have the one address. Then go
to Olly and search for the OFFSET of Current MP the same way
you did with HP(you don't need to search for the Pointer
because it is the same as HP 0xD0AE70). As of Twelve Sky
Client Version 1.10, you should find 0x170 to be the OFFSET
for Current MP. Subtract that offset by 4 to obtain the
Maximum MP offset(the values are in hex, so use calc in
scientific mode with hex selected). You will come up with
16C(Client Version 1.10).

Now you can find the Pointer and the OFFSETS needed to
update the source code for any future Client Release of
Twelve Sky. This way you should always have a working AUTO
HEAL/MP.RESTORE program for any version.*/

***********************************************
***********************************************
***** COMPILING THE SOURCE CODE INTO A DLL ****
***********************************************
***********************************************

You will need to install a C++ compiler. If you don't have


one there are some free ones out there. Off the top of my
head I know of, DevC++ by BloodShed(google it), and you
can an Express Edition of Microsoft Visual Studio from their
website(google it). Or you can go to warez if you want a
full version of Visual Studio(I currently use Visual Studio
2003 .net).

Assuming your using Visual studio you want to start a new


project. Go to Win32. Select Win32Project(not console
app). Enter the name, and directory(C:\SomeFolderName,
thats easiest for me). Next Page click application settings
and select dll and empty project. Then click finish. Your
Project is created. Now copy the source code above to an
empty Notepad document, and then saveas into the
C:\SomeFolderName directory as WHATEVERYOUWANTTONAMEIT.cpp
Then in Visual Studio and look on the right hand side,
Under Solution Explorer. There will be a list of items. At
the very top it will say "Solution 'YOURPROJECTNAME'" and
just below that it just says "YOURPROJECTNAME". Click on
that then right click on it. Choose "Add" "Add Existing
Item", now navigate to your C:\SomeFolderName Directory and
double click on the WHATEVERYOUWANTTONAMEIT.cpp. Now look
around the Mid-Top of the program you see the work "Debug"
with a dropdown list. Bring down that list and select
"Release". Now go to "Build", and Click on "Build
YOURPROJECTNAME". Now it should compile without errors and
you can find your YOURPROJECTNAME.dll in the
C:\SomeFolderName\Release directory. Now just get an
injector, start 12Sky and login to the game, Inject the
dll into TwelveSky.exe.

S-ar putea să vă placă și