Archive

Archive for the ‘Open Source’ Category

R3E revision 3

September 13th, 2009

Just uploaded revision 3 of my ROSE 3D Engine, very exciting. It now has full support for skeletal animation! Hurray.

Here is a beautiful picture for you to enjoy:

R3E Revision 3

R3E Revision 3

The thing I do rather like about my engine is how easy it is to use, this scene was created with just the following code:
mPlayer = new Player();

mPlayer->SetSkeleton("3DDATA\\AVATAR\\MALE.ZMD");
mPlayer->SetAnimation("3DDATA\\MOTION\\AVATAR\\EMPTY_RUN_M1.ZMO");

mPlayer->SetItem(ROSE::IT_BODY, 2);
mPlayer->SetItem(ROSE::IT_FOOT, 2);
mPlayer->SetItem(ROSE::IT_ARM, 2);
mPlayer->SetItem(ROSE::IT_HAIR, 1);
mPlayer->SetItem(ROSE::IT_FACE, 2);
mPlayer->SetItem(ROSE::IT_WEAPON, 1);
mPlayer->SetItem(ROSE::IT_SUBWPN, 1);
mPlayer->SetItem(ROSE::IT_BACK, 223);

mScene.AddEntity(mPlayer);

Yay.

Code is available at http://code.google.com/p/r3e/

admin C++, Open Source, ROSE Online

New ROSE 3D Engine (R3E)

September 10th, 2009

So following the previous ‘tutorial’ I decided to create a new version of R3E, my open source ROSE 3D Engine.

The googlecode page for it can be found at http://code.google.com/p/r3e/ and the svn at http://r3e.googlecode.com/svn/trunk/.

This 3D engine is designed in a way which is optimised for rendering with OpenGL, incase you wonder why I do odd things.

I hope to update it to the point of being able to display everything and anything from ROSE in 100% accuracy (that will be fun when it comes to effects and particles…).

Currently, although the code base is very large at the moment, all that is supported is rendering simple meshes (.ZMS files), the next feature I plan to support is using .ZSC files and then on to using skeleton (.ZMD) and animation files (.ZMO) to provide a full animated render of ROSE NPCs and Characters. How exciting.

Once the engine gets to that stage I will code a few simple things such as the Item Viewer which was included with the old R3E.

Currently I am not offering binary builds of the engine as there is not much to show, if you are interested in those then expect them some time in the near future.

Note: Sorry if you get lost when looking at my code, it has 0 comments (excluding commented out old code). Maybe one day I shall consider commenting it :D .

admin C++, Open Source, Programming, ROSE Online

Tutorial: Rendering ROSE Items in OpenGL and C++ (Part 1)

September 3rd, 2009

The aim of this tutorial is to render ROSE items up to the point of showing a full player with items! How exciting. It will be based upon the use of OpenGL and C++ using the Windows API to setup the window. This tutorial is not really aimed at those who cannot do C++ but more at those who are competent need help with 3D and OpenGL. I may also stress that this ‘tutorial’ as such is not going to tell you in depth how to create the code yourself but be a light informative source on how the code works, you will have to download the source for yourself to get the full idea.

The first boring bit is creating the window and all that rubbish, so I have decided to go ahead and do that for you and create a very basic framework from which we will work off of. This framework includes creating the OpenGL window, a few math classes such as support for Matrices and Vectors and a Camera class. This leaves me to focus the tutorial on uses OpenGL to render the items as the code mentioned beforehand is not really anything new or special to ROSE and can be found anywhere.

So if you download my basic framework and compile it you will see that there is just 3 axis lines which you can move the camera around using the right mouse button with dragging to rotate and the mouse wheel to zoom in and out. This is not very pretty at all! So we shall now focus on loading ZMS, the ROSE mesh files, into this application.

The file format for ZMS can be found here: ZMS File Format

It is pretty simple to load this into memory, the only trick is using the bone lookups. At the beginning of the file there is a list of bone indices, these are the actual bone index of the ZMD, the ROSE skeleton files, I name it the ‘bone lookup’ list. The BoneWeights for each vertex actually reference an ID in the bone lookup list. Here is an example: the first bone for a vertex would actually be boneLookup[boneWeight.id[0]] for the correct index in the ZMD file.

There are multiple ways to render this model, I use things called Vertex Buffer Objects which actually upload the model data into your graphics card and uses the RAM on it to store the data there. This is much faster as the vertex data does not get sent every frame. Unfortunately to use VBOs we must use OpenGL ARB extensions which makes our code a lot messier :( . The required functions are: glBindBuffer, glGenBuffers, glBufferData and glDeleteBuffers for clean up.

To load these extensions we have to call the function wglGetProcAddress (when on Windows), and example for glGenBuffers:

PFNGLGENBUFFERSPROC glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers");

The type PFNGLGENBUFFERSPROC is defined in gl/glext.h which is an include which should come with the OpenGL headers which can be found in the windows sdk.

There are two types of buffers I use, Vertex Buffers and Index Buffers, the difference is Vertex Buffers store the per-vertex data such as position, UV coordinates, colouring, normals etc whereas Index Buffers store the face -> vertex links. ROSE ZMS files are defined with a list of vertices and a list of faces which reference those vertices. These faces -> vertex references are loaded into and index buffer and used to draw faces from the list of vertices.

I also created two helper functions for creating Vertex Buffers and Index Buffers:

GLuint CreateIndexBuffer(void* data, unsigned int size){
	GLuint buf = 0;
	glGenBuffers(1, &buf);
	if(!buf) return -1;
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
	return buf;
}

GLuint CreateVertexBuffer(void* data, unsigned int size){
	GLuint buf;
	glGenBuffers(1, &buf);
	if(!buf) return -1;
	glBindBuffer(GL_ARRAY_BUFFER, buf);
	glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
	return buf;
}

As you can see these take two arguments, data and size. The data should be an array of the vertex data, this is not only vertex positions but also uv maps, normals, colours or any other per vertex data you would like to send to the graphics card, to render from these buffers you can use the glVertexPointer and glDrawElements calls.

As mesh rendering now works at this point (I am writing the code as I write the tutorial) I come to the problem of texture loading, this requires an external library as we are loading DDS files which are not natively compliant with OpenGL! I use the DevIL library which I have always found to be reliable and work with the ROSE textures.

With an addition of loading images from DevIL and using glTexCoordPointer we can now render the textured ZMS:

ZMS Texture Render

ZMS Texture Render

As the first part of this ‘tutorial’ comes to an end I realise this is either 1. a really shit tutorial or 2. not really a tutorial at all. There is the bare minimum of explanation here, it is more of a source code release with a slight explanation. I apologise for this, but maybe once this rendering engine is complete I can make a nice item viewer and people will use that rather than read this ‘tutorial’ :D .

Coming up in the part 2: using the ZSC files to render full models!

Edit: Sorry I forgot the source, you can find it here: Rendering ROSE Part 1

admin C++, Open Source, Programming, ROSE Online, Tutorials

TRose.exe the library

July 20th, 2009

So there comes a time when you decide ‘hey, I am going to have to edit the client to do this’ which is where my TRose library comes into use. I attempted to keep the interface to it as clean as possible which is why if you look at the code (I suggest you don’t :D ) you will probably be like ‘wtf is he doing’.

It works in the way that every class and its functions are defined in my library, I also have one function which must be used before all others (RoseAPI::Init()) this function goes through every class member functions and rewrites the first bytes of them to a JMP to the original code using my function ‘FixMemberFuncAddress’.

template<class T> void FixMemberFuncAddress(int troseAddr, T func){
	CodeHook::ApplyJmpHook((unsigned char*)(*((void**)&func)), (unsigned char*)troseAddr, 0);
}

The crazy recasting of func is to get around the fact that you cannot convert a member function pointer to a memory address directly so I used the redirection shown above to get around this compiler restriction.

There was one more challenge to handle though, rewriting constructor and destructor addresses, so far I only have a need for constructor so I did not bother with writing a handler for them. The reason this was a challenge is because in the c++ specification it is stated that constructors are not functions, not physically existent and thus you cannot get their address. Well, fuck the standards, we don’t want any of that shit. So I declared it was time for a workaround!

This is where my code gets dodgy and I highly recommend you use my .lib file and do not attempt to recompile the lib as this constructor code is based on the final assembly generated and it will differ between compilers.

First step was making a small function which just creates an object:

void CSlotCreator(){
	CSlot* slot = new CSlot();
}

The next step was to write a function which reads the assembly generated for this small function and attempts to get the address of the constructor, I found two types of constructing, one which used a CALL and one which used a JMP to go to the constructor, both are able to be processed in my code.

void FixConstructorAddress(int addrROSE, unsigned char* createFunc){
	unsigned char* addr = createFunc;
	if(addr[2] == 0xE8){
		for(int i = 0; i < 0x20; ++i){
			if(addr[i] != 0xE9) continue;
			int relAddr = *(int*)(addr + i + 1);
			int cAddr = (int)(addr + i);
			int ctorAddr = cAddr + relAddr + 5;
			unsigned char* codePtr = (unsigned char*)ctorAddr;
			DWORD oldProtect;
			VirtualProtect(codePtr, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
			codePtr[0] = 0x8B;
			codePtr[1] = 0xC8;
			VirtualProtect(codePtr, 5, oldProtect, &oldProtect);
			CodeHook::ApplyJmpHook(codePtr + 2, (unsigned char*)addrROSE, 0);
			break;
		}
	}else{
		addr = addr + 0x30;
		for(int i = 0; i < 0x20; ++i){
			if(addr[i] != 0xE8) continue;
			int relAddr = *(int*)(addr + i + 1);
			int cAddr = (int)(addr + i);
			int ctorAddr = cAddr + relAddr + 5;
			unsigned char* codePtr = (unsigned char*)ctorAddr;
			DWORD oldProtect;
			VirtualProtect(codePtr, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
			codePtr[0] = 0x8B;
			codePtr[1] = 0xCE;
			VirtualProtect(codePtr, 5, oldProtect, &oldProtect);
			CodeHook::ApplyJmpHook(codePtr + 2, (unsigned char*)addrROSE, 1);
			break;
		}
	}
}

So as you can see, it reads the bytes until it finds a JMP or CALL and then reads the address to the constructor, once this is done it rewrites the first bytes of the constructor to MOV ECX, ESI or MOV ECX, EAX (depending on CALL or JMP style) then JMP to the original TRose constructor! Hurray, that was fun.

Download the code and library here: TRose.lib.

admin C++, Open Source, Programming, ROSE Online, Reverse Engineering

TGameCtrl_r.lib, doing the impossible :D

June 11th, 2009

After my lovely TriggerVFS.lib I decided to move onto something a bit more complex, making a lib for TGameCtrl_r.dll, which is probably over 9000% more complex as it uses full classes, multiple inheritance and virtual functions. Making a lib for that would be madness surely!

Yes it is madness, but I actually got it to work. I still can’t believe it even works to be honest as it is completely reliant on Visual C++ compiling my lib (with all its inheritance and virtual functions) to be identical to the ROSE dll. Which is ridiculous, yet worked.

Most likely you will not understand how ridiculous it is that this works unless you have a good knowledge of C++ and how those aforementioned features compile into assembly.

What does this mean then? This means it is piss easy to create a custom dialog for ROSE Online, simple link to my library and include required header files such as #include ‘TDialog.H’ or ‘WinCtrl.h’ or w/e you want :) .

Custom dialogs are now as easy as this:

class TestDialog : public CTDialog {
public:
	TestDialog(){}
	virtual ~TestDialog(){}
};

void AddTestDialog(){
	TestDialog* testDlg = new TestDialog();
	testDlg->Create("dlgAchievements");
	AddDialog(1339, testDlg, testDlg->GetControlID());
	testDlg->Show();
}

How simple eh? It is as if we actually have the real code to TGameCtrl, this is how it would be used in ROSE, with the simple inheritance, all the virtual functions working properly and everything :D .

Pretty awesome :) .

It is not yet ready for release as I have many more classes to reverse from TGameCtrl_r.dll, below is a list of what I have done so far after many hours of reverse engineering. It may look light a random assortment of classes but it is basically every class which CTDialog depends on, other than the scroll bar related ones, I began implementing them now so I can implement the ZListBox class so I can fully recreate my achievements dialog with my new code.


Directory of C:\Programming\Libraries\TGameCtrl\TGameCtrl

221 ActionListenerList.h
161 IActionListener.h
115 IScrollModel.cpp
495 IScrollModel.h
79 ITControl.cpp
340 ITControl.h
134 ITDraw.h
319 SinglelineString.h
886 TButton.cpp
1,300 TButton.h
677 TCaption.cpp
886 TCaption.h
171 TCommand.h
217 TCommandQ.h
2,281 TDialog.cpp
2,582 TDialog.h
345 TGameCtrl.h
5,878 TGameCtrl.vcproj
593 TImage.cpp
923 TImage.h
131 TObject.cpp
256 TObject.h
1,012 TScrollBar.cpp
1,289 TScrollBar.h
190 TScrollBarType.h
704 TScrollBox.cpp
974 TScrollBox.h
251 TStatusBar.cpp
411 TStatusBar.h
2,156 WinCtrl.cpp
2,892 WinCtrl.h
33 File(s) 28,869 bytes

Sorry if you guys are not as excited as I am but I thought this was totally awesome, it might not seem as awesome if you do not know how C++ works and how it compiles into ASM.

Expect a release soon.

admin C++, Open Source, Programming, ROSE Online, Reverse Engineering

Tutorial: ‘My First Inject DLL’

June 6th, 2009

In a bid to compete with xadet’s blog I have realised I must post something useful on here, so I have come up with the idea of this tutorial which is rather patronisingly title ‘My First Inject DLL’, how whimsical of me. Also this allows me to continue the TRose.exe name colour tutorial properly, which expect to come very soon (I can’t be bothered to wait for Ruff to come back up, I am just going to do it without running ROSE :P )

In this tutorial we will make an EXE to inject our DLL into ROSE Online, or any other program, but of course this tutorial will focus on ROSE, we will also learn how to do hook code and how to call functions in the ROSE online exe, how exciting does that sound? Very.

So go ahead and create a new solution and add a win32 console application project, tick Empty Project so visual studio does not create worthless code that we do not want! Note that this first project will be for the EXE so name it something applicable, such as ‘My First Injector’!

Obviously the first thing to do with our new project is add a main.cpp file and put in the default code:

int main(int argc, char** argv){
	return 0;
}

Brilliant start I would say, now we have to add #include as pretty much every function we use will be from the windows API! Before we can attempt to inject any dll we must start the application so we shall use CreateProcess for that.

So here is a snippet showing you how to use it:

char* exename = "TRose.exe @TRIGGER_SOFT@ _server 127.0.0.1"

STARTUPINFOA si = { sizeof( si ) };
PROCESS_INFORMATION pi;

if(!CreateProcessA(NULL, exename, NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi)){
	printf("Failed to CreateProcess for trose.exe!\n");
	return 0;
}

Once we have called CreateProcessA, if it succeeds, it will return the new process handle in ‘PROCESS_INFORMATION pi;’ struct, we can now use this handle for injecting our dll, I went ahead and put the actual injection code in a separate function, ill paste the code below and then explain it to you:

bool InjectDLL(HANDLE hProcess, const char* dll){
	DWORD dwWritten;
	LPVOID pStringInRemoteProcess;

	if(!hProcess) return false;
	pStringInRemoteProcess = VirtualAllocEx(hProcess, 0, strlen(dll)+1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

	if(pStringInRemoteProcess == NULL) return false;

	WriteProcessMemory(hProcess, pStringInRemoteProcess, dll, strlen(dll)+1, &dwWritten);
	if(dwWritten != strlen(dll)+1) return false;

	CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"), pStringInRemoteProcess, 0, 0);
	return true;
}

So yes this looks complicated, but it is all required! Basically, we use VirtualAllocEx so we can allocate memory in the remote process (TRose.exe) with which to write the dll name, as obviously we cannot call a function across processes with its parameters coming from our process! WriteProcessMemory then writes this dll name to the previously allocated memory. Now the main code, CreateRemoteThread, this does as named, it creates a new thread in the remote process of TRose.exe! This code automatically runs the function LoadLibraryA which is imported from kernel32.dll, and passes it the argument of the pointer to the previously allocated memory which contains our dll’s name!

That was complicated and it is not important that you understand it as the windows API is funtastic, the main point of this tutorial is to teach you about the actual inject dll, not the exe which injects it!

So my final code for the main procedure is:

int main(int argc, char** argv){
	const char* dllname = "myfirstinject.dll";
	char* exename = "TRose.exe @TRIGGER_SOFT@ _server 127.0.0.1";

	STARTUPINFOA si = { sizeof( si ) };
	PROCESS_INFORMATION pi;

	if(!CreateProcessA(NULL, exename, NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi)){
		printf("Failed to CreateProcess for trose.exe!\n");
		return 0;
	}

	if(!InjectDLL(pi.hProcess, dllname)){
		printf("Failed to inject the dll!\n");
		return 0;
	}

	printf("Successfully injected the dll to TRose.exe!\n");

	return 0;
}

You should customise that code to include your dll’s name and the IP of the server you will be connecting to!

Now we shall add a new project to the solution for the dll, set it as a win32 console application but then in the wizard that comes up select DLL for the application type and tick the empty project again :) .

Once again add a main.cpp or whatever you like to call it and add the entry point code, it is slightly different for a dll:

#include <windows.h>

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){
	UNREFERENCED_PARAMETER(hModule);
	UNREFERENCED_PARAMETER(lpReserved);

	switch(ul_reason_for_call){
		case DLL_PROCESS_ATTACH:
			break;
		case DLL_PROCESS_DETACH:
			break;
	};

	return TRUE;
}

So now is where the magic happens, the main point in this tutorials existence and it only took 730 words to get here! Yay!

I am sure you can decipher the code above, UNREFERENCED_PARAMETER is a macro used to prevent the compiler giving me warnings about unreferenced formal parameters, from the switch cases I believe it is simple that the code we will be writing will be in the ATTACH section but I have included the detach case if you wanted to do any clean up or dumping :) .

The first thing we are going to do is rival xadet’s recent post on sending chat messages to ROSE but hopefully our end result will be prettier because we are using C++ and not that .NET managed rubbish.

We are going to hide the code in a header file so it can be reused in your other applications, so go ahead and create a file called ‘RoseAPI.hpp’ or whatever you want, but that is what I am calling mine :) .

Because the function which adds text messages to the chatbox is actually a class function we need to create a fake class, following the naming convention from xadet’s tutorial I shall call it CIT_MGR, it will be defined simply by adding a small declaration to the header, I have also added a function which returns the IT_MGR class from the TRose memory by casting 0×697AD0 (which is the location of this class in TRose.exe) to a CIT_MGR* pointer.

class CIT_MGR {};

static inline CIT_MGR* IT_MGR(){
	return reinterpret_cast<CIT_MGR*>(0x697AD0);
}

That was simple, now it gets a bit more complicated, we must define the function declaration which is:

typedef void (__thiscall IT_MGR::*PTR_AddChatText)(const char* message, int type, unsigned int customColour);

As you can see it uses the __thiscall mechanism which states it is a call to a class function, this looks like a typical function pointer, you can read more about them here.

The next part requires some trickery due to how class function pointers work, due to the nature of class pointers we cannot directly convert an address to a class pointer which is why I have found this rediculous method:

const int addr_TR_AddChatText = 0x48D890;
static const PTR_AddChatText TR_AddChatText = *((PTR_AddChatText*)&addr_TR_AddChatText);

#define AddChatText (IT_MGR()->*TR_AddChatText)

This may look silly but oh well, the advantage we have over xadet’s methods is the pure usability of my code, no ASM required, just pure C++ trickery going on here. The first variable has the address to the function, this is then followed by the function pointer, as you can see I have crazy pointer casting going on as this is the only way to prevent any compiler errors about converting an int to a class function pointer. The define I have added is for usability, it allows the code to be easily called, thus allowing me the functionality of:

AddChatText("I am a chat message", ChatType::ALL, 0);

How handy and neat and tidy and stuff is that final code, the method to get it may have been messy due to the use of class function pointers but I am sure you will let me off with that as it is hidden away in a header file anyway!

There is only one problem with this, we have no way of really using this AddChatText as we can’t add the text when the DLL is attached as the game is only just starting! We need some sort of trigger… Some sort of ‘hook’…

How about when the client uses a / command?! Genius plan.

To do this we need to place a hook where our code will be executed whenever the client attempts to send a chat message beginning with a ‘/’, to do this we are going to hook the send packet location! :) Hurray.

First off I am going to provide you with a generic function used to hook code:

void ApplyJmpHook(unsigned char* code, unsigned char* location, int nops = 0){
	DWORD oldProtect;
	VirtualProtect(code, 5 + nops, PAGE_EXECUTE_READWRITE, &oldProtect);
	code[0] = 0xE9;
	*(int*)(code+1) = (int)location - ((int)code + 5);
	if(nops > 0) memset(code + 5, 0x90, nops);
	VirtualProtect(code, 5 + nops, oldProtect, &oldProtect);
}

ApplyJmpHook takes 3 parameters, the code to place the hook and where this hook will redirect to, it also allows a specified amount of NOP commands to be added after the JMP. In this function you can see VirtualProtect being used, this is because the executable memory in an exe is usually protected against writing, VirtualProtect allows us to write over the code memory. The rest of the code is merely writing the code to memory, 0xE9 is the prefix for the JMP command, then I write the address for the JMP, then 0×90 is a NOP command.

Beautiful. Now this function can be used in such a way like ApplyJmpHook(roseCode, &MyFunction, 1); In order to apply this hook we need to know where the SendPacket code is, I am not going to show you how to find it as that would be another long tutorial, instead I am kind and provide you with this address to use: 0×00402D5E and I shall also inform you that this hook needs 0 NOPs :) . (NOP is used to allow OllyDBG to read the code properly after we have modified it, if our code overwrites only half of a command we need to NOP the other half of it!)

There is just one more problem with this, we can’t make it JMP directly to a C++ function as it will not have the correct arguments and will lead to errors! So first we must make a little wrapper function like the one below:

static const char* TROSE_PacketEncryption = reinterpret_cast<const char*>(0x00405020);
static _declspec(naked) void ASMOnSendPacket(){
	_asm{
		PUSH ECX
		PUSH ESI
		CALL CppOnSendPacket
		POP ECX
		CALL TROSE_PacketEncryption
		POP ESI
		RETN 0x04
	}
}

Hurray, now we can declare a function CppOnSendPacket and hook the ROSE code using:
(Note that we must apply the hook in the DLL_ATTACH code!)

bool CppOnSendPacket(char* packet);
ApplyJmpHook((unsigned char*)0x00402D5E, (unsigned char*)&ASMOnSendPacket, 0);

Now it is just a matter of reading the packet, detecting if it is a chat packet and reading the chat message to look for our / commands!

bool __stdcall CppOnSendPacket(char* packet){
	unsigned short size = *(unsigned short*)packet;
	unsigned short command = *(unsigned short*)(packet + 2);

	if(command == 0x783 && size > 7){
		char* message = packet+6;
		if(_strcmpi(message, "/hello") == 0){
			AddChatText("Hello Mr. ROSE Man", ChatType::SYSTEM, 0);
		}
	}

	return true;
}

WOOOT! So now when a player types /hello in game they should be presented with a friendly message saying “Hello Mr. ROSE Man”, how lucky are they!

Hello Mr ROSE Man

Hello Mr ROSE Man

That is the end of this absolutely massive tutorial! At this point it is currently 1820 words long and took a long time to write haha :) oh well. This tutorial was needed as it is a prerequisite for other tutorials such as the name colour tutorial part 3 (which I have already wrote 500 words of but realised I needed an inject dll to continue!) and the upcoming tutorial on creating 100% custom dialogs in ROSE!

As usual the source for this tutorial is available, download it here.

1909 words, nice.

admin C++, Open Source, Programming, ROSE Online, Reverse Engineering, Tutorials

Tutorial: Create a .LIB for an existing .DLL

May 30th, 2009

I just figured out how to do this so I thought I would share it, any of you out there using C++ with ROSE dlls like TriggerVFS.dll will have before used messy code like:

TriggerVFSDLL = LoadLibrary(_T("TriggerVFS.dll"));
if(TriggerVFSDLL == NULL) return;
OpenVFS = (EXPORT_OpenVFS)GetProcAddress(TriggerVFSDLL, "_OpenVFS@8");
CloseVFS = (EXPORT_CloseVFS)GetProcAddress(TriggerVFSDLL, "_CloseVFS@4");

There is a much better way to do this, most of the time when using dlls you link them to the compiler with .LIB files, which most people assume can only be made when you have the source code. This is not true! There is an easy way to create a .LIB, in this example I will be using TriggerVFS.dll.

So lets make a new project in Visual Studio, create a new project with type of “Win32 Console Application” when the project creation wizard comes up set the Application Type to DLL (NOT static library!!) tick the Empty Project option or the wizard will generate a bunch of rubbish we don’t want! Yay blank project, add a new header file and we shall start some code :) .

First we must get a list of all the functions we want to import and their formats, luckily ages ago there was a release of a VFS class to use the dll (it is where that code above with the GetProcAddress stuff is from) so all the hard work reversing has been done for us, hurray :) .

Here is the code from the old original header file:

typedef INDEXHANDLE (__stdcall *EXPORT_OpenVFS)          (const char *idxfile, const char *mode);
typedef DWORD       (__stdcall *EXPORT_CloseVFS)         (INDEXHANDLE handle);

And cleaned up to show only the format:

INDEXHANDLE __stdcall OpenVFS(const char *idxfile, const char *mode);
DWORD __stdcall CloseVFS(INDEXHANDLE handle);

So now we know these two functions we can go ahead and add them to this header file like this:
(I changed DWORD to unsigned long as DWORD is a definition found in windows.h files, no need.)

#ifdef TRIGGERVFS_EXPORTS
#define TRIGGERVFS_API __declspec(dllexport)
#else
#define TRIGGERVFS_API __declspec(dllimport)
#endif

typedef unsigned long INDEXHANDLE;
typedef unsigned long FILEHANDLE;

extern "C" TRIGGERVFS_API INDEXHANDLE _stdcall OpenVFS(const char* idxfile, const char* mode);
extern "C" TRIGGERVFS_API unsigned long _stdcall CloseVFS(INDEXHANDLE handle);

You may be wondering what the #ifdef is all about, it is there so we can reuse this header file for both creating the library and using the library in your applications. As we are building this library we have to define TRIGGERVFS_EXPORTS, to do this, open project properties, go to C/C++ -> Preprocessor -> Preprocessor definitions and add the value TRIGGERVFS_EXPORTS to the list.

extern “C” is required or the compiler will decorate the functions in a c++ style which basically adds a bunch of letters and symbols to the name which describe what arguments the function takes.

_stdcall is the ‘calling convention’ used in TriggerVFS.dll

So that’s the header file complete (well missing the rest of the functions, but I am not going to post them ALL!)

Now add a .cpp file to the project, in this we will just provide dummy functions to make the compiler create the dll and lib.

#include "TriggerVFS.h" //If this is what you called the header from before!

extern "C" TRIGGERVFS_API INDEXHANDLE _stdcall OpenVFS(const char* idxfile, const char* mode){
    return 0;
}

extern "C" TRIGGERVFS_API unsigned long _stdcall CloseVFS (INDEXHANDLE handle){
    return 0;
}

This should be sufficient for everything to work nicely, open project properties and change C/C++ -> Optimization -> Whole Program Optimization to No or whenever you use the generated libraries you will get some annoying warnings :) .

Go ahead and hit compile, note that you only should use the .lib file, not the generated .dll as that will just have our dummy functions, instead go steal the TriggerVFS.dll from your ROSE directory :) .

Now feel free to include your new header and link your .lib in your program and the linker will automagic fixup the dll imports so we can use TriggerVFS.dll without nasty winapi calls :) .

Here is my final solution TriggerVFS .lib it also includes a class for working with VFS, very similar to the one already available.

admin C++, Open Source, Programming, ROSE Online, Tutorials

China-ROSE Patch Format

May 29th, 2009

I was bored so I decided to figure out the China-ROSE Patch format, and I have nothing better to do so I shall release it here. Expect a ‘China-ROSE Patch Stealer’ program to come out soon :) .

http://update.iqicheng.com/
1. Vertions.zip {Use Password 1}
2. ServerList.zip {No Password}
3. Using ‘vertions’ patch versions, /_67555_patchlist.zip
4. /_67555_patchlist.zip {Use Password 1}
5. Patch Files: /_67555_patchlistPath/1_2019_2723778792.zip
   - Where 67555 == 1 << 16 | 2019
   - 2723778792 = ROSE hash of filename (same thing as quest hashes)

Password 1:
3asfqvf`~sdvo?uoyk;jqad85tuiuw*riha3lkpuj,ghfz10/sf9hg.,jfts1fsdf
Serverlist.lst Fileformat:
Text based format, open in text editor to seee :)

Basically its “ServerName, ip, ip, unk” with mix of whitespace and tabs inbetween

Vertions.lst Fileformat:
This is just a list of file versions on each line (0×0D0A seperator..)
Patchlist Fileformat:
dword version
dword count {
  byte unk
  dword version
  dword CRC-32
  dword strlen
  string filename
  dword strlen
  string vfsname
}
byte password length
string password for zips!

admin Open Source, ROSE Online, Reverse Engineering

CHR Editor Progress

April 18th, 2009

I feel like I should keep you informed as it my blog stats tell me that people do actually come here on a daily basis!
So here is a preview of the CHR Editor so far, I have updated the rendering to include effects as well as just the animation render, to provide you with an example we have a lovely glowy-handed ’stony1′, as it is named in the .CHR file!

You can click on any monster in the list and it renders it using the first animation available, click on a different animation in the animation list and it renders it, here you can see I have Attack selected and the render does indeed show an attack!

OSTools - CHR Editor

OSTools - CHR Editor

admin C++, Open Source, Programming, ROSE Online

New Project: OSTools

April 16th, 2009

Announcing a lovely new project, how exciting. I will be working on a line of Open Source Tools for ROSE Online! Yay I hear you shout! They will all be using the GUI library Qt so you will not be able to compile them unless you have that!

My first project will be a .CHR Editor, but not some normal boring one, a pretty one with a render window that supports fully animated characters! Yay. To do that render I will be using znzin so that makes it a bit easier :) .

So here is a picture of my progress so far, I hope you agree that the GUI is very pretty and should find it easy to use!

OSTools - CHR Editor

OSTools - CHR Editor

admin C++, Open Source, Programming, ROSE Online