Register for your free account! | Forgot your password?

Go Back   elitepvpers > Popular Games > Silkroad Online > SRO Coding Corner
You last visited: Today at 14:44

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

Advertisement



[Guide] Hooking the Console Input and Output

Discussion on [Guide] Hooking the Console Input and Output within the SRO Coding Corner forum part of the Silkroad Online category.

Reply
 
Old   #1

 
elite*gold: 260
Join Date: Aug 2008
Posts: 560
Received Thanks: 3,753
[Guide] Hooking the Console Input and Output

My next guide is more of a boring one, but it is necessary to show the concepts now since I will be using them in an upcoming guide (assuming I can get it done before any client updates)! There are no images to show really and I don't expect anyone to really spend a lot of time on this one now, but it will be a good reference for later on when I use the concepts.

Just remember all of the guides up to now are setting the stage for future guides (barring anything that might prevent me from doing more) so I have to show all these concepts in their own standalone form first. This guide really marks the last of the foundation guides that shows generic client specific techniques that I use.

After this guide, I will be working on a more practical guide series that I think a lot of people should find useful and like, but it might be a little controversial. There are only so many things that fit in that category, but I'll leave it to your imagination for now.

Hooking the Console Input and Output

I. Purpose

This guide will show an implementation of a console hook for input and output in Silkroad. This logic is based on some of the work I had done for Silkmod way back in the day. Silkmod was where chat block originated from before it was moved into Softmod when I stopped updating it.

This guide is an important development tool to understand because there will be times we want to be able to interact with the client without having to go through another GUI or external window. If we can use what we have in front of us, we can develop and test our code more rapidly and safely as we do not have to worry about thread safety issues.

The techniques for actually finding this stuff from scratch in the client are not going to be covered in depth. There’s no real way to teach that stuff so this guide is more of a code and explanation guide. Once you understand what is going on though, the information remains relevant for other tasks and you should be able to apply it in trying to find similar locations in other games.

II. Requirements

This guide is similar to the previous guides of extracting packets and integrating AntTweakBar. There is a mix of assembly logic with C++ programming. There are not really any new concepts presented though, we just use our codecaves again to steal data and make changes to logic!

In order to be able to follow along this guide, you will need:
• OllyDbg 1.10 (or equivalent)
• Visual Studio 2008 (or equivalent)

Before you continue this guide, you will also need to have already read and understood the previous guides! All of the guides build on one another in some shape or form, so it’s most beneficial to have read them all by now. Don’t forget to consult the assembly reference listed in the Loader guide if you need to look something up.

III. Theory

There is not much specialized theory in hooking the console input and output mechanisms in the Silkroad client. It’s really just a matter of finding the locations, saving the buffers, and using them as you need it. The way I went about tracking down this logic was by taking advantage of the swear filter in the game. If you type in a ‘bad word”, you will notice your text is not sent and you get a red error message in the console window.

If you find that error message in the PK2 files, you can find the associated string define for it in the client and start tracing from there. You will then be able to find the function that will show the error message as well as the logic for checking your input text. With that knowledge, it’s pretty easy to create your own swear filter bypass as well!

Like a lot of the previous guides’ concepts, it really just is a matter of getting lucky or spending enough time tracing through the client code until you find what you are looking for. Don’t expect to be able to open the client and just find this type of stuff without a bit of work! The code I’m showing in this guide probably took a good couple of days of tracing and testing to come up with when I first made it a while back.

With that said, and nothing really to cover, we can look at our specific code.

IV. Implementation

Basically we have 3 tasks to complete here. The first is to hook the input logic. This is the code that is called whenever we type something into the client. Silkroad has a special logic handler to where it will not display or send any text that has a / at the beginning of the line. We can use this to our advantage in implementing custom commands and arguments in our programs. For example, some of you might remember the Softmod command set, /sun, /rain, /snow, /min, /max, etc… As mentioned before, the chat input was found by finding where the swear filter took place and tracing backwards from that.

The second task we have is to hook the output logic. This was not too hard of a task if you use the approach I mentioned about finding the swear filter logic and then looking at the code that showed the error message if your text contained illegal words. In addition, there is a starting welcome message that you always see when you start the game that you could also track down in the client and base your function on. Either way, this task is not terribly hard for Silkroad!

The third and final task we have is to expose the function for displaying text in the console box. Since we are hooking the console output function, we can just call the function like the client does and voila! We are able to print to the console box. The method shown in this guide is the simple way to do it.

The last thing I should talk about is the additional logic used in the console output hook. I have added in additional code to check to see if the message should be displayed or not. While this is not required, it is a little extra feature I wanted to throw in because those spam bots in towns make for a very annoying development time if you are trying to output to the console! You will need to write a bit of code to implement a chat block, but it’s a lot easier having this code in place.

As I said in the beginning, this guide is more of a code and explanation guide rather than a how to from scratch. The binary snippet for the console out was from 2007, so it should be safe for a while. The console input method is best found using the string and then looking for nearly identical code. The actual line being hooked has changed in the past. Here is the complete DLL.cpp file with all of our concepts in place:

Code:
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include "../common/common.h"

// Global instance handle to this DLL
HMODULE gInstance = NULL;

// Function prototype
void UserOnInject();

// Main DLL entry point
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ulReason, LPVOID lpReserved)
{
	UNREFERENCED_PARAMETER(lpReserved);
	if(ulReason == DLL_PROCESS_ATTACH)
	{
		gInstance = hModule;
		// Do not notify this DLL of thread based events
		DisableThreadLibraryCalls(hModule);
	}
	return TRUE;
}

// This is the main function that is called when the DLL is injected into the process
extern "C" __declspec(dllexport) void OnInject(DWORD address, LPDWORD bytes)
{
	// Restore the original bytes at the OEP
	DWORD wrote = 0;
	WriteProcessMemory(GetCurrentProcess(), UlongToPtr(address), bytes, 6, &wrote);

	// Call our user function to keep this function clean
	UserOnInject();
}

//-------------------------------------------------------------------------

void OnConsoleInput(std::string input);

namespace CC_HookConsoleInput
{
	wchar_t * message;

	void HookInput()
	{
		char mbMessage[4096] = {0};
		wcstombs(mbMessage, message, 4095);
		OnConsoleInput(mbMessage);
	}

	// Look for "UIIT_MSG_CANT_CHATTING" and scroll down a lot, code looks like:
	/*
	006CCC4E  |.  8DBC24 FC000000    LEA EDI,DWORD PTR SS:[ESP+FC]
	006CCC55  |>  896C24 24          MOV DWORD PTR SS:[ESP+24],EBP
	006CCC59  |.  896C24 18          MOV DWORD PTR SS:[ESP+18],EBP
	006CCC5D  |.  896C24 1C          MOV DWORD PTR SS:[ESP+1C],EBP
	006CCC61  |.  896C24 20          MOV DWORD PTR SS:[ESP+20],EBP
	006CCC65  |.  392D 08B9D300      CMP DWORD PTR DS:[D3B908],EBP
	006CCC6B  |.  889C24 70040000    MOV BYTE PTR SS:[ESP+470],BL
	*/
	DWORD codecave_HookInput_ReturnAddress = 0;
	__declspec(naked) void codecave_HookInput()
	{
		__asm pop codecave_HookInput_ReturnAddress
		__asm mov message, EDI
		__asm pushad
		__asm call HookInput
		__asm popad
		__asm MOV BYTE PTR SS:[ESP + 0x470], BL // Original code
		__asm push codecave_HookInput_ReturnAddress
		__asm ret
	}

	void Setup()
	{
		edx::CreateCodeCave(0x6CCC6B, 7, codecave_HookInput);
	}
}

//-------------------------------------------------------------------------

bool OnConsoleOutput(int type, std::string output);

namespace CC_HookConsoleOutput
{
	BOOL chatblocked = FALSE;
	wchar_t * msgaddr = 0;
	DWORD msgtype = 0;

	void HookOutput()
	{
		char mbMessage[4096] = {0};
		wcstombs(mbMessage, msgaddr, 4095);
		chatblocked = OnConsoleOutput(msgtype, mbMessage);
	}

	// Bin: 8B 44 24 10 8B 54 24 08 50 8B 44 24 10 6A 00 52 8B 54 24 10 50 52 6A 01 6A 01
	DWORD codecave_HookOutput_ReturnAddress = 0;
	__declspec(naked) void codecave_HookOutput(void)
	{
		__asm
		{
			pop codecave_HookOutput_ReturnAddress
			MOV EAX, DWORD PTR SS:[ESP + 0x10]
			MOV EDX, DWORD PTR SS:[ESP + 0x8]
			mov msgtype, EAX
			mov msgaddr, EDX
			pushad
			CALL HookOutput
			cmp chatblocked, 0
			mov chatblocked, 0
			jne LABEL1
			popad
			ret 0x10
LABEL1:
			popad
			push codecave_HookOutput_ReturnAddress
			ret
		}
	}

	void Setup()
	{
		edx::CreateCodeCave(0x697DA0, 8, codecave_HookOutput);
	}
}

//-------------------------------------------------------------------------

void DisplayText(DWORD color, std::string text)
{
	// Bin: 8B 44 24 10 8B 54 24 08 50 8B 44 24 10 6A 00 52 8B 54 24 10 50 52 6A 01 6A 01
	// (The address of the function we hook above!)
	FARPROC ConsoleOutFunc = (FARPROC)0x697DA0;
	wchar_t outputText[4096] = {0};
	wchar_t * pOutputText = outputText;
	mbstowcs(outputText, text.c_str(), 2048);
	color |= 0xFF000000; // Make sure alpha is set
	__asm
	{
		MOV ECX, DWORD PTR DS:[0xF5CA74]
		push 1
		push color
		push pOutputText
		push 1
		CALL ConsoleOutFunc
	}
}

//-------------------------------------------------------------------------

// The function where we place all our logic
void UserOnInject()
{
	// Create a debugging console
	edx::CreateConsole("SilkroadFramework Debugging Console");

	// Mutex for the launcher, no patches required to start Silkroad now
	CreateMutexA(0, 0, "Silkroad Online Launcher");
	CreateMutexA(0, 0, "Ready");

	CC_HookConsoleInput::Setup();
	CC_HookConsoleOutput::Setup();
}

void OnConsoleInput(std::string input)
{
	printf("[INPUT] %s\n", input.c_str());
	DisplayText(0x00FF00, input); // Color is in RRGGBB format.
}

bool OnConsoleOutput(int type, std::string output)
{
	printf("[OUTPUT][%i] %s\n", type, output.c_str());
	return true; // Keep the output
}
Here is what an example output looks like:



V. Conclusion

By following this guide, we now have additional tools available at our disposal. Being able to hook the console input allows us to implement direct interactions with our client for additional flexibility in our programs. Hooking the console output helps with logging and being able to block certain text from being on the screen. Finally, the display function helps give in game debug printing capabilities without having to rely solely on our console.

With this guide concludes most of the main core functionality we should need for our own custom injected DLLs. So far, most of the guides in this series provide a solid foundation of functionality and techniques to use to accomplish various tasks. Now that this knowledge has been disseminated, future guides can make use of it all to provide a more in depth look at complex programs that make use of all of these things.

That warps up this guide. I hope you have enjoyed it! I will be soon utilizing all of the concepts presented in my guides in one larger guide that shows something worthwhile!

Drew “pushedx” Benton
edxLabs
pushedx is offline  
Thanks
21 Users
Old 07/09/2009, 23:52   #2
 
elite*gold: 0
Join Date: Feb 2008
Posts: 40
Received Thanks: 8
Like always, great job
ser_zix is offline  
Old 07/10/2009, 00:02   #3
 
x_king_x's Avatar
 
elite*gold: 20
Join Date: Nov 2008
Posts: 746
Received Thanks: 147
Quote:
Originally Posted by ser_zix View Post
Like always, great job
+1
x_king_x is offline  
Old 08/16/2009, 02:23   #4
 
elite*gold: 0
Join Date: May 2008
Posts: 259
Received Thanks: 94
It didnt work for me :/

is it updated?

it not updated. here is the new addresses
Quote:
006FABEE |. 8DBC24 FC00000>LEA EDI,DWORD PTR SS:[ESP+FC]
006FABF5 |> 896C24 24 MOV DWORD PTR SS:[ESP+24],EBP
006FABF9 |. 896C24 18 MOV DWORD PTR SS:[ESP+18],EBP
006FABFD |. 896C24 1C MOV DWORD PTR SS:[ESP+1C],EBP
006FAC01 |. 896C24 20 MOV DWORD PTR SS:[ESP+20],EBP
006FAC05 |. 392D C06FD700 CMP DWORD PTR DS:[D76FC0],EBP
006FAC0B |. 889C24 7004000>MOV BYTE PTR SS:[ESP+470],BL


edit: i found the input address. if i write something it prints the input and closes the client.
gonna find output too and ofcourse write here after that

edit2: output must be 0x697F40 but its not working. client closes itself at dll injecting part :/
here is the code
Quote:
00697F40 |. 8B4C24 14 |MOV ECX,DWORD PTR SS:[ESP+14]
00697F44 |. 6A FF |PUSH -1 ; /Arg3 = FFFFFFFF
00697F46 |. 53 |PUSH EBX ; |Arg2
00697F47 |. 8D5424 40 |LEA EDX,DWORD PTR SS:[ESP+40] ; |
00697F4B |. 52 |PUSH EDX ; |Arg1
00697F4C |. E8 2F06E1FF |CALL sro_clie.004A8580 ; \sro_clie.004A8580
soadmania is offline  
Old 08/16/2009, 11:42   #5
 
elite*gold: 0
Join Date: May 2008
Posts: 259
Received Thanks: 94
Quote:
// Bin: 8B 44 24 10 8B 54 24 08 50 8B 44 24 10 6A 00 52 8B 54 24 10 50 52 6A 01 6A 01
i followed the bin that u gave but it didnt work either. its 6C5150.

btw how can i find a bin in olly. i cant search anything in dumb. i found it with xvi32.
soadmania is offline  
Old 08/16/2009, 11:57   #6

 
elite*gold: 260
Join Date: Aug 2008
Posts: 560
Received Thanks: 3,753
Quote:
Originally Posted by soadmania View Post
btw how can i find a bin in olly. i cant search anything in dumb. i found it with xvi32.
Ctrl + B in the editor to bring up the Binary Search dialog. Just keep trying until you can get it, part of being able to do this stuff is struggling through the updates.

Quote:
i followed the bin that u gave but it didnt work either. its 6C5150.
I get:
Code:
006C5D50  /$  8B4424 10     MOV EAX,DWORD PTR SS:[ESP+10]
for that binary snippet. Of course, your client "could" be different unpacked than mine, but just use Olly to get the addresses and it should be ok.
pushedx is offline  
Old 08/16/2009, 12:19   #7
 
elite*gold: 0
Join Date: May 2008
Posts: 259
Received Thanks: 94
lol why xvi32 gave me the wrong address?

whatever i search for binary in olly (Ctrl + B). it gave me 006C5D50. So that s the correct address but it still doesnt work >.< i cant login to sro.it disconnects me after i press connect. what is wrong now?

input:
Quote:
edx::CreateCodeCave(0x6FAC0B, 7, codecave_HookInput);
output:
Quote:
edx::CreateCodeCave(0x6C5D50, 8, codecave_HookOutput);
and
Quote:
FARPROC ConsoleOutFunc = (FARPROC)0x6C5D50;
soadmania is offline  
Old 08/16/2009, 12:40   #8

 
elite*gold: 260
Join Date: Aug 2008
Posts: 560
Received Thanks: 3,753
Quote:
Originally Posted by soadmania View Post
So that s the correct address but it still doesnt work >.< i cant login to sro.it disconnects me after i press connect. what is wrong now?
The line:
Code:
MOV ECX, DWORD PTR DS:[0xF5CA74]
needs to be updated too. The current code for 205 is:
Code:
MOV ECX,DWORD PTR DS:[0xF98184]
You can update that by looking at one of the places that makes a call to the function at 0x6C5D50. I.e., hilight that address, look at the "Local calls from" status pane and follow one of those addresses back. When you see a "CALL 006C5D50", look up a couple of lines or so and you will see an address that is moved into ECX.

After you update that address, it should work fine!
pushedx is offline  
Old 08/16/2009, 12:58   #9
 
elite*gold: 0
Join Date: May 2008
Posts: 259
Received Thanks: 94
lol are you real

it worked so i can start to analyze all codes
soadmania is offline  
Old 08/16/2009, 18:24   #10
 
elite*gold: 0
Join Date: Mar 2008
Posts: 537
Received Thanks: 65
what is this? loader or smth?
lavazzas is offline  
Old 08/16/2009, 22:54   #11

 
elite*gold: 260
Join Date: Aug 2008
Posts: 560
Received Thanks: 3,753
Quote:
Originally Posted by lavazzas View Post
what is this? loader or smth?
It's a guide that shows you how you can hook the console input and output of Silkroad to be able to display your own text or process text that is typed into the client's chat box.

You can use the concepts to make your own customized loader or Silkroad client based programs.
pushedx is offline  
Old 08/16/2009, 23:05   #12
 
.1337's Avatar
 
elite*gold: 25
Join Date: Dec 2008
Posts: 1,070
Received Thanks: 513
wow im gotta learn C++ next year @ school and i wish i will understand 1 word from what u said

by the way my friend told me that weea** was making a tutorial on his ****** site how to make client less program i wish if u could explain doing that to me cause i registered there to see but i got ip ban in the same day he's nerd or somethin..

btw if my pc was working fine but light went out and back and its not working any more and i already changed the powersupply maybe it damaged but still no light i knew when processor fan didnt work , what would be the wrong ?

P.S : Thx for the tut
.1337 is offline  
Thanks
1 User
Old 08/26/2009, 18:47   #13
 
Low_Riders's Avatar
 
elite*gold: 20
Join Date: Nov 2008
Posts: 1,579
Received Thanks: 716
I gues this needs to be updated, right ?
Low_Riders is offline  
Old 08/27/2009, 07:57   #14

 
elite*gold: 260
Join Date: Aug 2008
Posts: 560
Received Thanks: 3,753
Quote:
Originally Posted by Low_Riders View Post
I gues this needs to be updated, right ?
Correct. I will be using my code from the edxSilkroadLoader project to write examples that will autoupdate and hopefully work on other Silkroad versions with little modifications. However, I still have a bit of more updating and testing to do before being able to take the time to update all my guides to that type of format.
pushedx is offline  
Old 09/29/2010, 23:49   #15
dotCom
 
Devsome's Avatar
 
elite*gold: 12400
The Black Market: 104/0/0
Join Date: Mar 2009
Posts: 15,884
Received Thanks: 4,386
Nice job

I have one question.
This project, ou can write it in autoit?
Or is it to hard to work ?

I can't C++ ^^ I can only AutoIt and i love it.

But i need an tutorial or somethink to make it in autoit.

Regards

(I hope my english is good)
Devsome is offline  
Reply


Similar Threads Similar Threads
[Request]Guide for api.hooking
05/21/2010 - CO2 Programming - 10 Replies
Could I please request a guide for API.HOOKING a conquer.exe please ? thanks
Input = Output [LIVE]
03/11/2010 - Main - 2 Replies
I know ... ist schon was peinlich sowas als DJ zu fragen aber was solls..:facepalm: Ich habe mich immer auf meine programme verlassen die ich auf meinen rechner hatte und da von A bis Z alles dabei... nun habe ich meinen rechner formatiert und ich suche nun ein ( INPUT = OUTPUT (LIVE) PROG. ) Für dumme ;) : Wenn ich was in mein Mic reinspreche will ich das es sofort aus meinen boxen wieder rauskommt bzw meine boxen es live wiedergeben wo finde ich so ein programm..:confused:?? wäre...
Input&Output Proplem
11/05/2009 - AutoIt - 1 Replies
I want to change links like this "http://www.google.com/?d=GVOMXHQ2" to "http://www.google.com/mgr_dl.php?d=GVOMXHQ2 " but its dont convert the Url to it. Script need only to read this
input output error
10/23/2009 - Metin2 Private Server - 1 Replies
hallo habe bei fterm einen input output error beim conecten weis da vllt jemand weiter??



All times are GMT +2. The time now is 14:44.


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