Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Perfect World > PW Hacks, Bots, Cheats, Exploits
You last visited: Today at 12:49

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

Advertisement



Perfect World Bot PWI-Prophet Bot Recoded

Discussion on Perfect World Bot PWI-Prophet Bot Recoded within the PW Hacks, Bots, Cheats, Exploits forum part of the Perfect World category.

Reply
 
Old 10/18/2010, 08:15   #631
 
elite*gold: 0
Join Date: Sep 2008
Posts: 35
Received Thanks: 0
Thank VuDuy for your idea, I will change in my code.
Combining with the block using{} then the memory for MemoryStream will be released right after use right ?

Currently, I knows only 2 ways to inject the function
1. Use C++ and Assembly, then export as a DLL and use them in C# application
2. The above way, creating the opcode and CreateRemoteThread to run these opcode.
Is there other way to do this with better performance ?

@Vuduy: I do review for bot, for every client you create an tab for it. so, for managing these GUI components and mapping them to the Character, you have to handle it manually ?
SunB is offline  
Old 10/18/2010, 08:46   #632
 
elite*gold: 0
Join Date: Mar 2008
Posts: 109
Received Thanks: 64
With SINS 2.x series using WinForms, the game tab thread has to update the UI every second via BeginInvoke. The new version coming up SINS 2.1 is written in WPF; so everything is data-bounded. No need to update anything, the data-binding takes care of itself.

The nice thing about WPF is the simplicity; the code size is reduced to about 1/2 compared to WinForms; but the drawback is the CPU usage. WPF uses DirectX so it sucks up a lot CPU with its UI because they look so much nicer.

Back to your question, with C#, you don't need to free/release any variables unless you are using unsafe codes and/or direct memory allocations. That's the beauty of managed API because there won't be any memory leaks nor performance penalty.

Method #1 is a lot more efficient and simpler than #2. You can set up inter-process communications between your C# program and the C++ DLL to do all the dirty work because it has direct access to the game's memory/functions.

An example is to setup named pipes between the DLL and C#. The DLL thread will sleep most of the time waiting for data from the pipe, and just call the game Send() function whenever data arrives.

The simplest way and fastest IPC option is to use Memory Mapped Files; they are as close as possible to having direct access to the game's memory from the C# program.
vuduy is offline  
Old 10/18/2010, 08:57   #633
 
elite*gold: 0
Join Date: Sep 2008
Posts: 35
Received Thanks: 0
Can you explain more about the "DLL Thread", because I built my Dll as Class Library and there is only one class in that DLL for handling in-game function. In the main project, I call these via an object.
SunB is offline  
Old 10/18/2010, 09:14   #634
 
elite*gold: 0
Join Date: Mar 2008
Posts: 109
Received Thanks: 64
Supposed that you want to create a DLL to interact with your C# program to do all the dirty work with the game's memory/functions, then your DLL's design is very simple.
  1. Create its own thread
  2. Setup IPC mechanism (eg. named pipes or memory mapped files)
  3. Wait for connection with the C# program
  4. Once connection is established then preliminary setup can be initiated; for example, your C# program may want to pass the game's current base pointer and send function address to the DLL so that it won't have to hard-code these addresses.
  5. DLL thread remains idle looping and waiting for "send data" from the C# program and execute it whenever it arrives.
The DLL will be very small in code and very efficient.
vuduy is offline  
Old 10/18/2010, 09:29   #635
 
elite*gold: 0
Join Date: Sep 2008
Posts: 35
Received Thanks: 0
I got your idea. but why do we need a thread ? is your DLL a Class Library or and VC++ console application exported as dll.
As you mentioned, how much memory that SINS may consume? My simple bot is under testing but the memory for it is about 14K with one client.
When I do the mapping between the UI component and object attribute, I setup the name convention for component + characterName.
For example : lbl_CharacterLV_MyCharName, and for updating that component I have to search them and update.
Doing searching for updating every second is not efficient right ? any better idea ?
SunB is offline  
Old 10/18/2010, 09:46   #636
 
elite*gold: 0
Join Date: Mar 2008
Posts: 109
Received Thanks: 64
DLL is a library; it is not an application.

The reason why you want to create a separate thread in your DLL is because you don't want to be looping forever in your DllMain.

Memory usage for C# programs depends on its complexity. SINS 2.x uses about 5-10k of memory per client and 0.5% cpu per client on my PC (quad-core). Yes, even with all those features

As for updating the UI, why are you making things so complicated? Why and what are you searching?

If you have a TextBox called playernameTextBox, and you want to update it, just assign it directly "playernameTextBox.Text = gamedata.playername" or whatever object is holding the name.

If you are updating from another thread than the UI thread, you have to use BeginInvoke otherwise it will throw exception because you can't modify UI from another thread directly.
vuduy is offline  
Old 10/18/2010, 11:35   #637
 
elite*gold: 0
Join Date: Sep 2008
Posts: 35
Received Thanks: 0
Is your Gui component created at runtime or you create them all at the beginning and then set them visible ?
If you create them at runtime, then how to get the object to call set text ?
SunB is offline  
Old 10/18/2010, 16:10   #638
 
elite*gold: 0
Join Date: Mar 2008
Posts: 109
Received Thanks: 64
It doesn't matter whether you create your UI at design time or runtime; just make sure to keep a reference for the UI component that you want to update and access it directly.

If you are creating a TextBox object at runtime to display the player's name, then after initializing the TextBox, make a copy reference of the object with a local variable and when you need to update it, use the local variable name.
vuduy is offline  
Thanks
1 User
Old 10/18/2010, 16:33   #639
 
elite*gold: 0
Join Date: Sep 2008
Posts: 35
Received Thanks: 0
I will test that kind of mapping tonight
ah, your bot is just amazing work since you stated that you are not a programmer ) When you release the new bot in WPF, please give me a chance to test it )

I stuck with the sendPackage in C++, I need to pass 2 things
- the source of the package (LPVOID)
- package size (int)
as the old method, I put all the same type a param into LPVOID and call it before code Assembly. now 2 different types, I really dont know how to merge them >_<
SunB is offline  
Old 10/18/2010, 19:52   #640
 
elite*gold: 0
Join Date: Mar 2008
Posts: 109
Received Thanks: 64
What kind of design are you doing? Keep it simple. Here's a simple design using memory mapped files without any synchronization. The layout of the memory map is as follow:

In the DLL, create a memory file mapping of say 64k in size with
Code:
HANDLE  hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 64000, "Name");
unsigned int *data = (unsigned int*) MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 64000);
*data = command value
*(data+1) = base address
*(data+2) = send function address
*(data+10) = size of byte[] data
(data+11) = the start address of byte[] data

then in your loop

Code:
while (1)
{
  if (*data == 99)  break; // command 99 = exit thread and unload the DLL
  if (*data == 1) // send function command
  {
     unsigned int base = *(data+1);
     unsigned int send = *(data+2);
     unsigned int length = *(data+10);
     unsigned int *buffer = data+11;
     __asm
    {
      pushad
      push length
      push buffer
      mov eax, base
      mov edx, [eax]
      mov ecx, [edx + 0x20]
      mov esi, send
      call esi
      popad
      ret
    }
    *data = 0;
  }
  Sleep(5);
}
From the C#, you create a memory map view:
Code:
IntPtr hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, "Name");
IntPtr pData = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 64000);
Then, to setup the base address and send address do:
Code:
Marshal.WriteInt32(pData, 4, baseaddress);
Marshal.WriteInt32(pData, 8, sendaddress);
To send some opcodes, build the opcodes first (example to select target id):
Code:
uint targetid = 0x8000000;
MemoryStream stream = new MemoryStream();
stream.Write(BitConverter.GetBytes(2), 0, 2); // 02 00
stream.Write(BitConverter.GetBytes(targetid), 0, 4);
byte[] data = stream.ToArray();
Marshal.Copy(data, 0, (IntPtr)(pData.ToInt64() + 44), data.Length); // writing the buffer to (data+11) position
Marshal.WriteInt32(pData, 40,  data.Length); // writing the buffer size to *(data+10)
Marshal.WriteInt32(pData, 0, 1) // writing command 1
vuduy is offline  
Thanks
2 Users
Old 10/19/2010, 03:03   #641
 
elite*gold: 0
Join Date: Jun 2008
Posts: 16
Received Thanks: 1
Hi Interest07,

The code for auto follow doesn't seem to be working in PW PH. Below is my code snippet written in C#.net:

Code:
// Real BaseAddress
ReadProcessMemory(ProcessHandle, (IntPtr)OxFBaseAddress, &FBaseAddress, 4, out bytesRead);
// StructurePointer
ReadProcessMemory(ProcessHandle, (IntPtr)(FBaseAddress + 0x1C), &StructPointer, 4, out bytesRead);
// PlayerPointer
ReadProcessMemory(ProcessHandle, (IntPtr)(StructPointer + 0x20), &PlayerPointer, 4, out bytesRead);
// ActionStruct
ReadProcessMemory(ProcessHandle, (IntPtr)(PlayerPointer + OxPlayerActionStruct), &ActionStruct, 4, out bytesRead);
// TargetID
ReadProcessMemory(ProcessHandle, (IntPtr)(PlayerPointer + OxTargetOffset), &TargetID, 4, out bytesRead);
// ActionList
ReadProcessMemory(ProcessHandle, (IntPtr)(ActionStruct + 0x30), &ActionList, 4, out bytesRead);
// FollowPlayer
ReadProcessMemory(ProcessHandle, (IntPtr)(ActionList + 0x1C), &FollowPlayer, 4, out bytesRead);
WriteProcessMemory(ProcessHandle, (IntPtr)(FollowPlayer + 0x8), 0, 4, out bytesOut);
WriteProcessMemory(ProcessHandle, (IntPtr)(FollowPlayer + 0x20), TargetID, 4, out bytesOut);
WriteProcessMemory(ProcessHandle, (IntPtr)(ActionStruct + 0xC), FollowPlayer, 4, out bytesOut);
WriteProcessMemory(ProcessHandle, (IntPtr)(ActionStruct + 0x18), 1, 4, out bytesOut);
WriteProcessMemory(ProcessHandle, (IntPtr)(ActionStruct + 0x14), FollowPlayer, 4, out bytesOut);
serpentmind is offline  
Old 10/19/2010, 03:31   #642
 
elite*gold: 0
Join Date: Sep 2008
Posts: 35
Received Thanks: 0
I'll try it after work
SunB is offline  
Old 10/19/2010, 08:03   #643
 
Interest07's Avatar
 
elite*gold: 0
Join Date: Mar 2010
Posts: 862
Received Thanks: 576
Quote:
Originally Posted by serpentmind View Post
Hi Interest07,

The code for auto follow doesn't seem to be working in PW PH. Below is my code snippet written in C#.net:
Are you getting sensible values from your readmemory calls? Because your offsets seem to be alright, but I can't judge on how you implemented your read and write memory functions.

just tried it in C# and the offsets definitely work in PWI, so they most likely should in PW RU too.

follow function: (values is my player structure as it's read from memory, with actionStructPointer obviously being the pointer to the actionStruct hehe)
Code:
        public void follow(int playerId)
        {
            int actionStruct = values.actionStructPointer;
            int actionList = MemFunctions.MemReadInt(pr_processHandle, actionStruct + 0x30);
            int followAction = MemFunctions.MemReadInt(pr_processHandle, actionList + 0x1C);

            MemFunctions.MemWriteInt(pr_processHandle, followAction + 0x8, 0);          //Set error = 0
            MemFunctions.MemWriteInt(pr_processHandle, followAction + 0x20, playerId);  //Set playerId to follow
            //MemFunctions.MemWriteInt(pr_processHandle, followAction + 0x48, 0);       //Set stopped following = 0

            MemFunctions.MemWriteInt(pr_processHandle, actionStruct + 0xC, followAction);   //Set new action at position 1
            MemFunctions.MemWriteInt(pr_processHandle, actionStruct + 0x18, 1);             //Set next action position to 1
            MemFunctions.MemWriteInt(pr_processHandle, actionStruct + 0x14, followAction);  //Set new action type follow as next action
 
        }
The MemFunctions used:
Code:
    [DllImport("Kernel32.dll")]
    private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, 
        byte[] lpBuffer, UInt32 nSize, ref UInt32 lpNumberOfBytesRead);

    [DllImport("kernel32.dll")]
    private static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
            byte[] lpBuffer, UInt32 nSize, ref UInt32 lpNumberOfBytesWritten);


    public static void MemWriteInt(IntPtr processHandle, int address, int value)
    {
        bool success;
        byte[] buffer = BitConverter.GetBytes(value);
        UInt32 nBytesRead = 0;
        success = WriteProcessMemory(processHandle, (IntPtr)address, buffer, 4, ref nBytesRead);
    }


    public static int MemReadInt(IntPtr processHandle, int address)
    {
        bool success;
        byte[] buffer = new byte[4];
        UInt32 nBytesRead = 0;
        success = ReadProcessMemory(processHandle, (IntPtr)address, buffer, 4, ref nBytesRead);
        return BitConverter.ToInt32(buffer, 0);
    }
Interest07 is offline  
Old 10/19/2010, 08:42   #644
 
elite*gold: 0
Join Date: Jun 2008
Posts: 16
Received Thanks: 1
Hi Interest07,

Can you show me how you created this player structure (values.actionStructPointer)?
serpentmind is offline  
Old 10/19/2010, 08:53   #645
 
Interest07's Avatar
 
elite*gold: 0
Join Date: Mar 2010
Posts: 862
Received Thanks: 576
How you build up your struct would depend on your version of course (it's not as flexible as working with offsets for every single value that you can obtain for all version by offsetFinders, but I only play one version so I don't mind that :P)

edit: I'm not claiming any of my methods are efficient, just in case. Should prolly consult vuduy about that kinda thing.

Code:
values = (playerStruct)MemFunctions.MemReadStruct(pr_processHandle, playerAddress, typeof(playerStruct));

    public static object MemReadStruct(IntPtr processHandle, int address, Type anyType)
    {
        int rawsize = Marshal.SizeOf(anyType);
        bool success;
        byte[] buffer = new byte[rawsize];
        UInt32 nBytesRead = 0;
        success = ReadProcessMemory(processHandle, (IntPtr)address, buffer, (UInt32)rawsize, ref nBytesRead);
        return RawDeserialize(buffer, 0, anyType);
    }


    private static object RawDeserialize(byte[] rawData, int position, Type anyType)
    {
        int rawsize = Marshal.SizeOf(anyType);
        if (rawsize > rawData.Length)
            return null;
        IntPtr buffer = Marshal.AllocHGlobal(rawsize);
        Marshal.Copy(rawData, position, buffer, rawsize);
        object retobj = Marshal.PtrToStructure(buffer, anyType);
        Marshal.FreeHGlobal(buffer);
        return retobj;
    }

And apologies to Prophets as his thread is getting hijacked again as usual :P And not even with AutoIt code, so it's particularly useless to him
Interest07 is offline  
Reply




All times are GMT +1. The time now is 12:50.


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.