Allods Developers Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Modifying Clients

Suspicious Elf

New member
Hello hello,

This is my first post on these forums.

I've been playing around a while with the 1.0 and 4.0 allods server/clients.

1.0 (Oct 15 2009 leaked internal version)
This version is very interesting to me as it still has the oldest original class designs from the days of Nival and will definitely be useful to me, but problem is this version is extremely bugged: only killable mobs are in the starting instance and the shard logs constantly spit out errors about "too small roaming area" for the others as they regen hp constantly, so I can't even do a levelling run to 40 to refresh my memory about this once glorious game.

It is however very easily modifiable, I managed to add my own .xdb files and modify the index to unlock an elf psionicist race-class combination, it was missing some startup screen animation and description in one place, but it was definitely playable (at least as playable as existing race-class-combinations are in this version). Then seeing as I won't progress past starting island due to bugs, I moved on to exploring 4.0.

4.0 (with AllodsME client)
This one was much more playable, however it is nearly useless to me, I actually remember this version well-enough.

I've noticed (and read some online about it) that all the resources (that are unpacked and freely-modifiable in 1.0) are in binary format in 4.0 and they need to be unpacked (first from .pak files, then from .bin inside the .pak) to a modifiable form (.xdb) and then (probably) re-packed again after modification to use in the client. Are there tools freely available already to do that or do they need to be developed with use of reverse-engineering? I've seen people talk about "pack.bin" here on the forums, is it related to that problem?

I've noticed some serious obstacles with the 4.0 client:

It has some sort of protection that prevents it from running if anything is changed. If I do one of smallest possible changes: modify account_srv_host field in Profiles/accountServer.cfg file to point to my local server on 127.0.0.1 instead of "Allods-account.gpotato.com", it looks like the client never starts, running the .exe just does nothing. I had to actually do a hack to add an entry that binds Allods-account.gpotato.com to 1270.0.1 on my machine to even connect to my server using this client.

I guess the client probably does some sort of checksum on the files in the directory where it runs and exits if it doesn't match (the process is gone from the process list very fast).

I've seen some weird solutions like writing your server ip inside the binary with in HEX or running a starter.exe and injecting some custom dll... they do solve the problem of running the client (but not modifying it) in a very crude and convoluted way. I think the proper and clean way to do it would be to binary patch the AOGame.exe itself so it never even runs the old IE-based launcher and just straight up boots into the game whether anything was modified or not, then reads the server IP from accountServer.cfg (like vanilla World of Warcraft client does reading realmlist.wtf)

Has anyone solved those problems cleanly like that already? Would I be wasting time reinventing the wheel trying to run the game with x64dbg trying to figure this out?

I'd love to backport old game and class mechanics (especially talent and ruby grids) from the internal 1.0 version into the 4.0 version and test them out by doing some levelling runs from 1 to 40, but in order to do that I need to be able to modify the 4.0 client.

Also, while trying to find an unmodified 4.0 client, I've managed to find an old polish version (the link is shockingly still alive after 12 years):

You do not have permission to view link Log in or register now.


Might be of use to someone here, it is a clean, original installer. Still has all those "protection" issues tho.
 
in the client there is a file game.version, which contains the files and their hash sums. At startup, the client checks them and exits if something doesn't match.

long ago this problem has been solved by injecting asm, which skips the verification stage, there is even a launcher with a dll that can do this.

There is also an alternative solution, you can rebuild game.version every time you change game files, but it is not so easy there too, because we do not have a private key, which is used to sign the hash sum, we have to use our own and substitute the public key in aogame.exe (you can do it in the original launcher too, because it also checks files from game.version)
 
in the client there is a file game.version, which contains the files and their hash sums. At startup, the client checks them and exits if something doesn't match.

long ago this problem has been solved by injecting asm, which skips the verification stage, there is even a launcher with a dll that can do this.

There is also an alternative solution, you can rebuild game.version every time you change game files, but it is not so easy there too, because we do not have a private key, which is used to sign the hash sum, we have to use our own and substitute the public key in aogame.exe (you can do it in the original launcher too, because it also checks files from game.version)
Thanks for a very clear answer.

If I were to use an own private key, is it documented somewhere which part (address) inside AOgame.exe needs to be patched?
 
I don't think anyone else has done this but me, so you won't find any documentation

The client uses in-memory decompression, which makes it difficult to modify aogame.exe, unlike Launcher.exe, which can be easily patched.
If you can do this, the whole process can be simplified a lot.

Directly overwriting the key in the process memory will not work either, I resorted to such a hack:
1. auto inject dll to process
2. hook CreateFileA and wait until the client tries to read ../Profiles/game.version
3. replace the public key address with your own.
4. wait until the client tries to read any other file and change the pointer back.

DWORD ptr = 0x0047c749;
char newKey[] = {...}; // len = 140

replace key:
DWORD OldProt;
VirtualProtect((LPVOID)ptr, 5, PAGE_EXECUTE_READWRITE, &OldProt);
*(char*)ptr = (char)0x68;
*(DWORD*)((DWORD)ptr + 1) = (DWORD)&newKey;
VirtualProtect((LPVOID)ptr, 5, OldProt, &OldProt);

restore as it was:
DWORD OldProt;
VirtualProtect((LPVOID)ptr, 5, PAGE_EXECUTE_READWRITE, &OldProt);
*(char*)ptr = (char)0x68;
*(char*)((DWORD)ptr + 1) = (char)0xE8;
*(char*)((DWORD)ptr + 2) = (char)0x2A;
*(char*)((DWORD)ptr + 3) = (char)0x32;
*(char*)((DWORD)ptr + 4) = (char)0x01;
VirtualProtect((LPVOID)ptr, 5, OldProt, &OldProt);

If you really need it, I can write a guide on how to work with version 5 of game.version
 
Thanks for a detailed example, but I think I won't be going this route then, in-memory decompression complicates everything too much.

I thought it can be done cleanly and without adding extra dlls or executables, by just binary-patching AOgame.exe and bypassing launcher, but if the data inside the .exe file is actually compressed that's the reason it hasn't been done yet.

Is the launcher that bypasses game.version check available for 4.0 version? I am guessing it's not the starter scripts supplied with AllodsME client, because they don't allow modifying accountServer.cfg
 
Back
Top