Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Conquer Online 2 > CO2 Programming
You last visited: Today at 05:45

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

Advertisement



[Release] Advanced hooking

Discussion on [Release] Advanced hooking within the CO2 Programming forum part of the Conquer Online 2 category.

Closed Thread
 
Old 07/08/2011, 02:50   #46
 
elite*gold: 0
Join Date: Dec 2007
Posts: 108
Received Thanks: 42
Since the encryption seems to have changed enough to stump me I finally decided to look into this. Quite blown away by how easy it is to use but two things not explained in any sample are bothering me:

1. How to block a packet from being received by/sent from the client.

2. How to send packets to the client.
Belth is offline  
Old 07/08/2011, 03:08   #47
 
elite*gold: 20
Join Date: Aug 2007
Posts: 1,749
Received Thanks: 2,199
Quote:
Originally Posted by Belth View Post
Since the encryption seems to have changed enough to stump me I finally decided to look into this. Quite blown away by how easy it is to use but two things not explained in any sample are bothering me:

1. How to block packets.

2. How to send packets to the clients.
There's many different ways of blocking say a client->server packet. For example, if you place your hook at the start of the SendPacket function, you could simply just change the instruction pointer (Context.EIP) to any random "retn8" instruction - because that is how the function returns, with a retn8 instruction. You'll see this if you look at the function in ollydbg (or whatever disassembler you prefer). That way, you'll skip the entire function that actually encrypts and sends the packet to the server.

I'm not sure what you mean by "send packets to the client", but I'm assuming you mean faking a packet from the server sent to the client? If so, you just either call the "ProcessMessage" function, or you edit the loop where Conquer checks for received packets and replace them with your own packets. That's kinda tricky unless you know what you're doing though.
IAmHawtness is offline  
Old 07/08/2011, 03:48   #48
 
elite*gold: 0
Join Date: Dec 2007
Posts: 108
Received Thanks: 42
Quote:
Originally Posted by IAmHawtness View Post
There's many different ways of blocking say a client->server packet. For example, if you place your hook at the start of the SendPacket function, you could simply just change the instruction pointer (Context.EIP) to any random "retn8" instruction - because that is how the function returns, with a retn8 instruction. You'll see this if you look at the function in ollydbg (or whatever disassembler you prefer). That way, you'll skip the entire function that actually encrypts and sends the packet to the server.

I'm not sure what you mean by "send packets to the client", but I'm assuming you mean faking a packet from the server sent to the client? If so, you just either call the "ProcessMessage" function, or you edit the loop where Conquer checks for received packets and replace them with your own packets. That's kinda tricky unless you know what you're doing though.
I generally haven't a clue . I've asked questions about it but never got anywhere really (probably my own fault).

So, I don't know how to "change the instruction pointer (Context.EIP) to any random "retn8" instruction" though I understand what that means.

I think I may understand how to call the "ProcessMessage" function after going through your SendPacket function in the sample.

Edit:

Just realised the SendPacket function no longer works so I'm even more lost than I thought. So basically I'm looking for how to intercept and subsequently block/relay a packet sent from the server or client.
Belth is offline  
Old 07/08/2011, 13:29   #49
 
elite*gold: 0
Join Date: Sep 2006
Posts: 774
Received Thanks: 8,580
Quote:
Originally Posted by Belth View Post
I generally haven't a clue . I've asked questions about it but never got anywhere really (probably my own fault).

So, I don't know how to "change the instruction pointer (Context.EIP) to any random "retn8" instruction" though I understand what that means.

I think I may understand how to call the "ProcessMessage" function after going through your SendPacket function in the sample.

Edit:

Just realised the SendPacket function no longer works so I'm even more lost than I thought. So basically I'm looking for how to intercept and subsequently block/relay a packet sent from the server or client.
You don't change EIP, you overwrite the instructions about to get executed with a RETN 8. Just remember to preserve the original code so you can restore it after it's been executed. It's way easier to do something like this if you are in-process (dll) but doing it externally is awesome.

Truth is you won't get far with this without any reverse engineering skills. I recommend lena's tutorials on tuts4you.com

Edit: Didn't read the previous posts, you can change EIP instead if you happen to find a retn 8 instruction

Code:
if (AimBot->OnChat(TokenizeStr(text, " ")) == 0)
{
	CONTEXT* c = (CONTEXT*)GetContext();
	c->Eip = Pattern->GetAddress("LeaveRetn18Loc");
}
That is so much cleaner!
phize is offline  
Thanks
2 Users
Old 07/08/2011, 14:47   #50
 
elite*gold: 20
Join Date: Aug 2007
Posts: 1,749
Received Thanks: 2,199
Quote:
Originally Posted by Synsia View Post
Code:
if (AimBot->OnChat(TokenizeStr(text, " ")) == 0)
{
	CONTEXT* c = (CONTEXT*)GetContext();
	c->Eip = Pattern->GetAddress("LeaveRetn18Loc");
}
That is so much cleaner!
Isn't that code executed "in-process", from your injected DLL?
If so, why not just make your own "retn8" function inside the DLL, and re-direct the EIP to that function? Instead of using the Pattern->GetAddress

Code:
void Handler(char[] text)
{
  if (AimBot->OnChat(TokenizeStr(text, " ")) == 0)
  {
    CONTEXT* c = (CONTEXT*)GetContext();
    c->Eip = &Retn8Function
  }
}

int Retn8Function
{
  __asm
  {
    retn 8
  }
}
My C++ isn't that great (almost non-existant), but I think you get the point
IAmHawtness is offline  
Old 07/08/2011, 14:58   #51
 
elite*gold: 0
Join Date: Sep 2006
Posts: 774
Received Thanks: 8,580
Nah, that's using the win debug api from an extern process.

I was overwriting instruction code to force a RETN but that seems overkill, when you can just change EIP. I don't know why I never thought of that to be honest lol.
phize is offline  
Old 07/08/2011, 15:02   #52
 
elite*gold: 20
Join Date: Aug 2007
Posts: 1,749
Received Thanks: 2,199
Quote:
Originally Posted by Synsia View Post
Nah, that's using the win debug api from an extern process.

I was overwriting instruction code to force a RETN but that seems overkill, when you can just change EIP. I don't know why I never thought of that to be honest lol.
Haha, I see . Hell, there's like a million ways to "skip" functions, since most well-coded functions check for all kind of things to prevent errors, I could even imagine that the SendPacket function might check for a 0 length packet, if so it would be possible to skip the packet just by modifying the PacketLength parameter.
IAmHawtness is offline  
Old 07/08/2011, 15:09   #53
 
elite*gold: 0
Join Date: Sep 2006
Posts: 774
Received Thanks: 8,580
Quote:
Originally Posted by IAmHawtness View Post
Haha, I see . Hell, there's like a million ways to "skip" functions, since most well-coded functions check for all kind of things to prevent errors, I could even imagine that the SendPacket function might check for a 0 length packet, if so it would be possible to skip the packet just by modifying the PacketLength parameter.
True that
phize is offline  
Old 07/08/2011, 18:06   #54
 
elite*gold: 0
Join Date: Dec 2007
Posts: 108
Received Thanks: 42
Quote:
Originally Posted by Synsia View Post
Truth is you won't get far with this without any reverse engineering skills.
All I needed to know, thanks.
Belth is offline  
Old 07/09/2011, 10:01   #55
 
elite*gold: 0
Join Date: Dec 2007
Posts: 108
Received Thanks: 42
May I get some help as to what is wrong with this method?

Code:
public void SendPacket(byte[] packet)
{[INDENT]int packetType = BitConverter.ToUInt16(packet, 2);
int packetAddr = (int)this.Dbg.AllocateMemory((uint)packet.Length);
this.Dbg.WriteByteArray(packet, (int)packetAddr);

byte[] buffer = new byte[]
{ [INDENT]0xBA, 0x00, 0x00, 0x00, 0x00,	// mov edx, 0; reserved for packet type
0x68, 0x00, 0x00, 0x00, 0x00,	// push 0 ; reserved for packet size
0x68, 0x00, 0x00, 0x00, 0x00,	// push 0 ; reserved for packet address
0xB9, 0x00, 0x00, 0x80, 0x00,	// move ecx, 0; reserved for NetWorkClass
0x60, 0x12, 0x80,				// mov ecx, [esi+14]
0xB8, 0x00, 0x00, 0x00, 0x00,	// mov eax, SendPacketFn; reserved for SendPacket() Address
0xFF, 0xD0,					// call eax; call SendPacket()
0xC3,						// RET[/INDENT]};

using (BinaryWriter writer = new BinaryWriter(new MemoryStream(buffer)))
{[INDENT]writer.BaseStream.Position++;
writer.Write(packetType);
writer.BaseStream.Position++;
writer.Write(packet.Length);
writer.BaseStream.Position++;
writer.Write(packetAddr);
writer.BaseStream.Position++;
writer.Write(NetworkClass);
writer.BaseStream.Position += 4;
writer.Write(SendPacketAddress);[/INDENT]}
this.Dbg.ExecuteCode(buffer);
this.Dbg.FreeMemory(packetAddr);[/INDENT]}
Belth is offline  
Old 07/09/2011, 10:25   #56
 
elite*gold: 0
Join Date: Sep 2006
Posts: 774
Received Thanks: 8,580
The way you're overwriting the buffer does not look right at all. Only incrementing position by 1?
phize is offline  
Old 07/09/2011, 20:47   #57
 
elite*gold: 0
Join Date: Dec 2007
Posts: 108
Received Thanks: 42
Quote:
Originally Posted by Synsia View Post
The way you're overwriting the buffer does not look right at all. Only incrementing position by 1?
The original buffer is almost certainly wrong anyways. Hawtness said that SendPacket() takes two parameters, size and address so I figure this part has to be right:

Code:
using (MemoryStream ms = new MemoryStream())
using (BinaryWriter writer = new BinaryWriter(ms))
{[INDENT]// push packet size
writer.Write((byte)0x68);
writer.Write(packet.Length);

// push packet address
writer.Write((byte)0x68);
writer.Write(packetAddress);

// store SendPacket() address in EAX
writer.Write((byte)0xB8);
writer.Write(SendPacketAddress);

// call function stored in EAX
writer.Write(new byte[] {0xFF, 0xD0});

// return
writer.Write((byte)0xC3);[/INDENT]				
}
Simple and I understand that. What I don't understand is why in the sample he does:

Code:
mov edx, packetType - [COLOR="Red"]why the hell would I need to do this?[/COLOR]
push packetSize
push packetAddress
mov esi, networkClass - [COLOR="Red"]why the hell would I need to do this?[/COLOR]
mov ecx, [esi+14] - [COLOR="Red"]and subsequently, this?[/COLOR]
mov eax, sendpacketfunction
call eax
ret
Then Ian posts his own function which seemed a lot easier to read and is almost what I expected:

Code:
unsafe public void SendPacket(byte[] packet)
{[INDENT]int packetAdr = AllocMem(packet.Length);
Write(packetAdr, packet);
byte[] buffer = new byte[]
{[INDENT]0x68, 0x00, 0x00, 0x00, 0x00,    // PUSH 0 ; Size
0x68, 0x00, 0x00, 0x00, 0x00,    // PUSH 0 ; Packet
0xB9, 0x60, 0x12, 0x80, 0x00,    // MOV ECX, SendPacketEcx - [COLOR="Red"]why?[/COLOR]
0xB8, 0x00, 0x00, 0x00, 0x00,    // MOV EAX, SendPacketFn
0xFF, 0xD0,                        // CALL EAX
0xC3,                            // RET[/INDENT]};
fixed (byte* ptr = buffer)
{[INDENT]
*((int*)(ptr + 1)) = packet.Length;
*((int*)(ptr + 6)) = packetAdr;
*((int*)(ptr + 11)) = SendPacketEcx;
*((int*)(ptr + 16)) = SendPacketFn;
[/INDENT]}
Execute(buffer);
FreeMem(packetAdr);[/INDENT]}
AND either way executing both of these in memory crashes the client so I'm assuming some part of both is outdated though I can't imagine what.
Belth is offline  
Old 07/09/2011, 21:39   #58
 
elite*gold: 0
Join Date: Sep 2006
Posts: 774
Received Thanks: 8,580
Quote:
Originally Posted by Belth View Post
The original buffer is almost certainly wrong anyways. Hawtness said that SendPacket() takes two parameters, size and address so I figure this part has to be right:

Code:
using (MemoryStream ms = new MemoryStream())
using (BinaryWriter writer = new BinaryWriter(ms))
{[INDENT]// push packet size
writer.Write((byte)0x68);
writer.Write(packet.Length);

// push packet address
writer.Write((byte)0x68);
writer.Write(packetAddress);

// store SendPacket() address in EAX
writer.Write((byte)0xB8);
writer.Write(SendPacketAddress);

// call function stored in EAX
writer.Write(new byte[] {0xFF, 0xD0});

// return
writer.Write((byte)0xC3);[/INDENT]				
}
Simple and I understand that. What I don't understand is why in the sample he does:

Code:
mov edx, packetType - [COLOR="Red"]why the hell would I need to do this?[/COLOR]
push packetSize
push packetAddress
mov esi, networkClass - [COLOR="Red"]why the hell would I need to do this?[/COLOR]
mov ecx, [esi+14] - [COLOR="Red"]and subsequently, this?[/COLOR]
mov eax, sendpacketfunction
call eax
ret
Then Ian posts his own function which seemed a lot easier to read and is almost what I expected:

Code:
unsafe public void SendPacket(byte[] packet)
{[INDENT]int packetAdr = AllocMem(packet.Length);
Write(packetAdr, packet);
byte[] buffer = new byte[]
{[INDENT]0x68, 0x00, 0x00, 0x00, 0x00,    // PUSH 0 ; Size
0x68, 0x00, 0x00, 0x00, 0x00,    // PUSH 0 ; Packet
0xB9, 0x60, 0x12, 0x80, 0x00,    // MOV ECX, SendPacketEcx - [COLOR="Red"]why?[/COLOR]
0xB8, 0x00, 0x00, 0x00, 0x00,    // MOV EAX, SendPacketFn
0xFF, 0xD0,                        // CALL EAX
0xC3,                            // RET[/INDENT]};
fixed (byte* ptr = buffer)
{[INDENT]
*((int*)(ptr + 1)) = packet.Length;
*((int*)(ptr + 6)) = packetAdr;
*((int*)(ptr + 11)) = SendPacketEcx;
*((int*)(ptr + 16)) = SendPacketFn;
[/INDENT]}
Execute(buffer);
FreeMem(packetAdr);[/INDENT]}
AND either way executing both of these in memory crashes the client so I'm assuming some part of both is outdated though I can't imagine what.
The SendPacket function takes two params, that is the pushes you wrote in opcodes. But you can't simply pass the address of your buffer from another process space, you have to allocate space (VirtualAllocEx) for it in the target process, then write the buffer there (WriteProcessMemory) and finally pushing that address you just allocated. When you're done with the buffer you injected you need to free it (VirtualFreeEx), or you'll have a memory leak

ECX is a "this"-pointer, which points to a class instance (some socket class in this case). It's needed in order to call class member functions that are non-static.

Edit: I just noticed that you do allocate memory for it, hah.
Well, your crashes could be due to addresses being outdated.
phize is offline  
Thanks
2 Users
Old 07/09/2011, 22:27   #59
 
elite*gold: 0
Join Date: Dec 2007
Posts: 108
Received Thanks: 42
Quote:
Originally Posted by Synsia View Post
The SendPacket function takes two params, that is the pushes you wrote in opcodes. But you can't simply pass the address of your buffer from another process space, you have to allocate space (VirtualAllocEx) for it in the target process, then write the buffer there (WriteProcessMemory) and finally pushing that address you just allocated. When you're done with the buffer you injected you need to free it (VirtualFreeEx), or you'll have a memory leak

ECX is a "this"-pointer, which points to a class instance (some socket class in this case). It's needed in order to call class member functions that are non-static.

Edit: I just noticed that you do allocate memory for it, hah.
Well, your crashes could be due to addresses being outdated.
Ah, you cleared up the ECX thing for me. So Ian's function makes sense, though it still crashes the client.

const int SendPacketAddress = 0x6E01B7;
const int RecvPacketAddress = 0x6E2809;

Aren't those the right addresses for the latest client? (5509)

Also, why does Hawtness store the packet type in EDX?
Belth is offline  
Old 07/09/2011, 22:50   #60
 
elite*gold: 0
Join Date: Sep 2006
Posts: 774
Received Thanks: 8,580
SendFunc: 0x6dfee2

I have no idea why he's using edx, but it's not needed to call the function.
phize is offline  
Closed Thread


Similar Threads Similar Threads
[RELEASE] Make a more Advanced NPC
02/02/2011 - CO2 PServer Guides & Releases - 55 Replies
This guide will show you how to make a NPC. I will update this post daily with new things to add to your NPC. First. We are going to take this NPC from Paralyzer and modify this a little bit. here is the link if you have never made a simple NPC. http://www.elitepvpers.com/forum/co2-pserver-guide s-releases/492901-release-how-code-decent-npc-npcs -txt-entry.html Easiest stuff first. How to make an NPC check for a specific level. To make an NPC check for a level we can do this by adding...
Advanced Tribalwars Bot Release
05/31/2010 - Browsergames - 20 Replies
Ein Bot für das Browsergame "Die Stämme". Features: Multiaccountfähig baut Dörfer selbstständig aus Bot merkt sich, wann ein Gebäude gebaut werden kann, bzw. wann es fertiggestellt ist Information: Bei "Server" z.B. de60.die-staemme.de o.ä. eingeben.
ReViSiOn [Advanced Public Release]
02/13/2009 - WarRock Hacks, Bots, Cheats & Exploits - 5 Replies
http://i295.photobucket.com/albums/mm150/gfx_forum s/revvv3.png ReViSiOn Public Beta 1.2 _____ Working features: No Recoil No Spread



All times are GMT +1. The time now is 05:46.


Powered by vBulletin®
Copyright ©2000 - 2026, 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 ©2026 elitepvpers All Rights Reserved.