English
Search
Main Menu
Forums

WormKit Modules Development

Started by rUNaW4y, January 09, 2025, 04:34 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

rUNaW4y

As a huge amount of WormKit modules have been developed over the time, I am wondering whether there is any chance to have some kind of handbook/tutorial for doing that. I think even a basic "HelloWorld" would be a good starting point.
  • Does something like that already exist?
  • Did anybody already provide a tutorial/guideline in the past?

Big Billy

Good question. Was always thinking about that too, to maybe start making one..
Didn't seen any tutorial of that kind yet. Would be nice tho.

But a good starting point could be downloading the module code from an existing one's (like the GitHUb Repros from https://github.com/nizikawa-worms/) and looking into the code and maybe changing something.
And since its coded in C++ maybe look into tutorials for that.


rUNaW4y

Yeah, I saw all these open source implementations of the existing modules, and looking at the core parts (in C++ or C#) I can also understand what action is performed. Nevertheless, what I would like to have is a kind of basic tutorial which describes:

  • How to create a simple Windows DLL project for WA from scratch;
  • What kind of tools are usually used/needed for a complete development (e.g. VisualStudio, etc.);
  • What kind of libraries/dependencies/variables are used (as well as their meaning) to make sure that the WormKit properly loads a developed functionality compiled in a .dll file;
  • How to properly export/compile the project in order to get the final working .dll file;
  • etc.

As a comparison, If we change the topic and move to WA maps development, what I would like to have is similar to what Shadowman did years ago for beginners:

https://www.youtube.com/watch?v=-eoR3YkGY9c

So, for the instance, let us assume I would like to see a simple dialog message appearing when a game starts, listing all joined players and their teams names. Where should I start from?

I hope this further clarifies my point.
Bests.

jsgnextortex

Wormkit module development is not something thats accesible enough to fit a tutorial right now, if one were to make one, it would be more about reverse engineering than anything else.....needless to say, reverse engineering is not the most intuitive of the fields to the average joe and is not usually something people look tutorials for (the kind of people thats into reverse engineering usually is not the kind that follows tutorials as a way of learning).
In conclusion, the reason why, after all these years, noone bothered to make a tutorial for it is because:
  • Theres no single standard way of making a wormkit module. Everyone has their own way of working, hooking, building and handling the modules.
  • The process is too complex to boil down into a tutorial accesible enough to those that seek tutorials. If done, it would either be felt "half assed and doesnt explain enough" or "too complicated" by tutorial watchers.
  • The demand for such a thing is simply not there. Nowadays people scream just by seeing C++ code, I dont want to imagine their faces when they see assembly code (because, yes, you need to know some assembly to make modules).
Old T17 Forums Handle: JSGnext
Used to fool around on Worms4 Mayhem, Made some Binding of Isaac mods and some Worms Armageddon Terrains.

rUNaW4y

Quote from: jsgnextortex on Yesterday at 02:48 AMWormkit module development is not something thats accesible enough to fit a tutorial right now, if one were to make one, it would be more about reverse engineering than anything else.....needless to say, reverse engineering is not the most intuitive of the fields to the average joe and is not usually something people look tutorials for (the kind of people thats into reverse engineering usually is not the kind that follows tutorials as a way of learning).
In conclusion, the reason why, after all these years, noone bothered to make a tutorial for it is because:
  • Theres no single standard way of making a wormkit module. Everyone has their own way of working, hooking, building and handling the modules.
  • The process is too complex to boil down into a tutorial accesible enough to those that seek tutorials. If done, it would either be felt "half assed and doesnt explain enough" or "too complicated" by tutorial watchers.
  • The demand for such a thing is simply not there. Nowadays people scream just by seeing C++ code, I dont want to imagine their faces when they see assembly code (because, yes, you need to know some assembly to make modules).

"If you can't explain it simply, you don't understand it well enough."
― Albert Einstein

nizikawa

Quote from: rUNaW4y on Yesterday at 07:56 AM"If you can't explain it simply, you don't understand it well enough."
― Albert Einstein
stfu, JSG is right.
― nizikawa

and for anyone interested in actual wormkit development, I suggest checking out those two posts on WA discord channel:
https://discord.com/channels/416225356706480128/691342271861358592/1327161154908323884
https://discord.com/channels/416225356706480128/691342271861358592/1327681546437529641

TheKomodo

There are many reasons however I believe three of the biggest reasons stopping people making tutorials are as follows:

1) They don't want to make them.
2) Not enough people want/need them.
3) They don't want to share their knowledge.

If they really wanted to make a tutorial they could, anyone who understands their field could achieve this with relative ease in their own way. Whether it's simple or complex is irrelevant.

For the same reason I don't make more tutorials for the game with all my knowledge, the community is too small therefore there is a lack of inspiration/interest and it's not exactly required anyway.

Evidently and historically many people feel the need to protect their line of work. If other people can do the things they can do the same way they do then their product wouldn't be as special/unique. To put it simply, they don't want other people on their turf.

Of course there are always the exceptions, those are three big things that can stop people from making tutorials anyway. For me it's usually #2.

nizikawa

Here's the glimpse of it:

First think of a simple idea you would like to implement. For example, let's make all explosions 10 times more powerful.

Ok, let's use Wormkit API to make explosions 10 times bigger. Haha, there is no wormkit API. All wormkit does is in fact loading your DLL in the game, that's all. Everything else needs to be done by you, starting from dllmain, and I really mean it. You need to carefully patch the game's code in memory in order to change its behavior in a desired way.

Try to guess how the explosions are created in the game. You can see, that the game is able to create both small and big explosions, so they probably have some "power" parameter. The explosion can be placed anywhere on the map, usually where a weapon, mine or worm explodes, so there must be a way to specify XY coordinates of the explosion. This tells us, that there is some hypotethical function "create explosion" that accepts at least "x, y, power" parameters.
With this in mind, can you think of the simplest way to make the explosions 10 times more powerful? How about modifying the "create explosion" function in a way that will multiply the
"power" parameter by 10 whenever it's called? Sounds easy.

Now, we need to find this "create explosion" function. For this to work, we need to analyze WA's code. You need a disassembler (and to make things easier, decompiler) - your two main options are Ghidra and IDA Free/Pro. I roll with IDA Pro, but Ghidra is fine too.

Once you load WA in your disassembler, you will see thousands of functions, most of them will be named something like sub_401530, sub_401550, sub_401560, sub_4015A0, sub_4015F0... where is our "create explosion"? You need to find it (given it exists and our assumption was correct).

Think of an explosion in WA. What exactly happens when stuff explodes? You see a flash, hear a bang, a hole is created in the land, worms lose hp if hit, worms are pushed away from the explosion, worms change their animation from standing to flying/hurt, worms emit blood (if set in scheme), oil barrells explode and create fire, debris in background is pushed away from the explosion... you get the idea.
If we don't know where the "create explosion" function is, maybe we can find a function that is somewhat related to creating explosion? After all, there should be some connection between creating an explosion and making a hole in the land, right?

Now, do we know any functions that implement those side effects? No, we don't know any function names and there are thousands of functions in the game. This seems impossible.

Let's analyze the side effects - some of them seem more complex than others. For example, making a hole in the ground seems more difficult than playing an explosion sound. What's seemingly the easiest side effect? I think it's damaging the worm - specifically, reducing it's hp. Let's find a function that reduces worm's HP.

Start the game in single player mode, make a playground scheme - place only one worm on the map, give yourself all ammo, infinite turn time. Launch Cheat Engine and scan for a dword "100", as your worm currently as 100 hp. You should have thousands of matches. Damage your worm a little, do a further scan for your worm's current hp. Repeat this until you have only one or very few matches. Add the address to the list and modify the value to 9999 and try damaging the worm again. If done correctly, your worm should have a lot of hp. Congrats, you found the variable that holds your current worm's HP.

Now, how to find the function that actually damages your worm? You need to check what accesses this variable. In cheat engine, select this variable and activate a memory breakpoint on write, (aka see what writes to this address). Continue damaging the worm, you will see that some addresses will appear, along with the number of accesses to the variable. You will probably see one ore two functions - copy their addresses. Go to IDA/Ghidra and go to this address. It probably does not exist, because of ASLR changing the base address of WA process. You can rebase the function address manually, but in general, you will need to disable ASLR in WA.exe for convenient debugging - https://osandamalith.com/2018/10/24/pe-sec-info-a-simple-tool-to-manipulate-aslr-and-dep-flags/

Now take a look at the code in IDA/Ghidra, does it look like something that writes the worm's HP? Look at the xref's to this function (aka functions that call this function). Probably one of them will be the one that creates an explosion. You can also look for other functions, like the one that plays sounds.

Once you identify your "create explosion" function, you will need to hook using minhook or polyhook or any other hooking library (you need to know function address or bettr, find address by function signature) and make a wrapper call that will roughly look like this:
int create_explosion_hooked(int x, int y, int power) {
  return create_explosion_original(x, y, power*10);
}

Make a shared library with cmake and msvc toolchain, compile it and load in the game, voila


Sorry, i've run out of time writing this guide. That's the basic idea. Check out my modules and the discord links - i've posted over 4000 function addresses, so you don't have to find them yourself, cheers.

rUNaW4y

Quote from: nizikawa on Yesterday at 01:18 PM
Quote from: rUNaW4y on Yesterday at 07:56 AM"If you can't explain it simply, you don't understand it well enough."
― Albert Einstein
stfu, JSG is right.
― nizikawa

and for anyone interested in actual wormkit development, I suggest checking out those two posts on WA discord channel:
https://discord.com/channels/416225356706480128/691342271861358592/1327161154908323884
https://discord.com/channels/416225356706480128/691342271861358592/1327681546437529641

Calm down, you just misunderstood my citation based on the jsgnextortex's answer. It was not referred to jsgnextortex himself who just pointed out how difficult modules' development would be for a noob like me. The citation was referred to a generic individual whose answer to the hypothetical <<Please, can you teach me how to develop dynamic libraries for Worms Armageddon?>> question would have been <<Sorry, I can not explain you how to do so just because:>>

1)..reverse engineering is not the most intuitive of the fields..
2)..the kind of people that's into reverse engineering usually is not the kind that follows tutorials as a way of learning..
3)..The process is too complex to boil down into a tutorial accessible enough to those that seek tutorials..
4).."too complicated" by tutorial watchers..
5)..people scream just by seeing C++ code, I don't want to imagine their faces when they see assembly code..

My question wasn't that one, so the citation does not apply to the subject I cited in my previous message (jsgnextortex).



This answer is way better, thanks.

Quote from: nizikawa on Yesterday at 03:42 PMHere's the glimpse of it:

First think of a simple idea you would like to implement. For example, let's make all explosions 10 times more powerful.

Ok, let's use Wormkit API to make explosions 10 times bigger. Haha, there is no wormkit API. All wormkit does is in fact loading your DLL in the game, that's all. Everything else needs to be done by you, starting from dllmain, and I really mean it. You need to carefully patch the game's code in memory in order to change its behavior in a desired way.

Try to guess how the explosions are created in the game. You can see, that the game is able to create both small and big explosions, so they probably have some "power" parameter. The explosion can be placed anywhere on the map, usually where a weapon, mine or worm explodes, so there must be a way to specify XY coordinates of the explosion. This tells us, that there is some hypotethical function "create explosion" that accepts at least "x, y, power" parameters.
With this in mind, can you think of the simplest way to make the explosions 10 times more powerful? How about modifying the "create explosion" function in a way that will multiply the
"power" parameter by 10 whenever it's called? Sounds easy.

Now, we need to find this "create explosion" function. For this to work, we need to analyze WA's code. You need a disassembler (and to make things easier, decompiler) - your two main options are Ghidra and IDA Free/Pro. I roll with IDA Pro, but Ghidra is fine too.

Once you load WA in your disassembler, you will see thousands of functions, most of them will be named something like sub_401530, sub_401550, sub_401560, sub_4015A0, sub_4015F0... where is our "create explosion"? You need to find it (given it exists and our assumption was correct).

Think of an explosion in WA. What exactly happens when stuff explodes? You see a flash, hear a bang, a hole is created in the land, worms lose hp if hit, worms are pushed away from the explosion, worms change their animation from standing to flying/hurt, worms emit blood (if set in scheme), oil barrells explode and create fire, debris in background is pushed away from the explosion... you get the idea.
If we don't know where the "create explosion" function is, maybe we can find a function that is somewhat related to creating explosion? After all, there should be some connection between creating an explosion and making a hole in the land, right?

Now, do we know any functions that implement those side effects? No, we don't know any function names and there are thousands of functions in the game. This seems impossible.

Let's analyze the side effects - some of them seem more complex than others. For example, making a hole in the ground seems more difficult than playing an explosion sound. What's seemingly the easiest side effect? I think it's damaging the worm - specifically, reducing it's hp. Let's find a function that reduces worm's HP.

Start the game in single player mode, make a playground scheme - place only one worm on the map, give yourself all ammo, infinite turn time. Launch Cheat Engine and scan for a dword "100", as your worm currently as 100 hp. You should have thousands of matches. Damage your worm a little, do a further scan for your worm's current hp. Repeat this until you have only one or very few matches. Add the address to the list and modify the value to 9999 and try damaging the worm again. If done correctly, your worm should have a lot of hp. Congrats, you found the variable that holds your current worm's HP.

Now, how to find the function that actually damages your worm? You need to check what accesses this variable. In cheat engine, select this variable and activate a memory breakpoint on write, (aka see what writes to this address). Continue damaging the worm, you will see that some addresses will appear, along with the number of accesses to the variable. You will probably see one ore two functions - copy their addresses. Go to IDA/Ghidra and go to this address. It probably does not exist, because of ASLR changing the base address of WA process. You can rebase the function address manually, but in general, you will need to disable ASLR in WA.exe for convenient debugging - https://osandamalith.com/2018/10/24/pe-sec-info-a-simple-tool-to-manipulate-aslr-and-dep-flags/

Now take a look at the code in IDA/Ghidra, does it look like something that writes the worm's HP? Look at the xref's to this function (aka functions that call this function). Probably one of them will be the one that creates an explosion. You can also look for other functions, like the one that plays sounds.

Once you identify your "create explosion" function, you will need to hook using minhook or polyhook or any other hooking library (you need to know function address or bettr, find address by function signature) and make a wrapper call that will roughly look like this:
int create_explosion_hooked(int x, int y, int power) {
  return create_explosion_original(x, y, power*10);
}

Make a shared library with cmake and msvc toolchain, compile it and load in the game, voila


Sorry, i've run out of time writing this guide. That's the basic idea. Check out my modules and the discord links - i've posted over 4000 function addresses, so you don't have to find them yourself, cheers.

kirill470

What if we take for example use the ChatGPT or other AI to write code, won't they be able to help with this?

Corujão

@rUNaW4y  I value your determination. Creating modules from scratch can be very challenging and frustrating, and I want you to realize that by doing it on your own, without much encouragement, not only will you become more skilled, but you'll also gain a solid experimental foundation. After all, what comes easy, goes easy, just like everything in life. Someday, it will all become obvious to you. :)

My channel - https://bit.ly/3dCb4A3

Triad

Quote from: kirill470 on Yesterday at 05:51 PMWhat if we take for example use the ChatGPT or other AI to write code, won't they be able to help with this?
I don't think current AI models will be helpful for something as niche and specific as wormkit development.



rUNaW4y

#13
I think I got everything from the example you mentioned. It is better for me to start from functions you have already mapped, trying to play with hooking them, wrapping their calls and compiling the corresponding shared library to check the WA behavior. I will rely on Ghidra in order to have a look at the functions' content (since I am a Windows user, would disabling ASLR from Windows Security settings be sufficient - by selecting Off  in the "Force randomization for images (Mandatory ASLR)" and "Randomize memory allocations (bottom-up ASLR) - dropdown options?). Furthermore:

  • Can you please link here the function addresses you managed to map?
  • Once the function is identified, hooked and a wrapper call is implemented, is the original WA function completely overridden?
  • I assume that a custom functionality implemented through a new WormKit module will work during a multiplayer session only in case all participants have the module locally loaded, right? Are there any exceptions or is this just the way it works?

Thanks.

Quote from: nizikawa on Yesterday at 03:42 PMHere's the glimpse of it:

First think of a simple idea you would like to implement. For example, let's make all explosions 10 times more powerful.

Ok, let's use Wormkit API to make explosions 10 times bigger. Haha, there is no wormkit API. All wormkit does is in fact loading your DLL in the game, that's all. Everything else needs to be done by you, starting from dllmain, and I really mean it. You need to carefully patch the game's code in memory in order to change its behavior in a desired way.

Try to guess how the explosions are created in the game. You can see, that the game is able to create both small and big explosions, so they probably have some "power" parameter. The explosion can be placed anywhere on the map, usually where a weapon, mine or worm explodes, so there must be a way to specify XY coordinates of the explosion. This tells us, that there is some hypotethical function "create explosion" that accepts at least "x, y, power" parameters.
With this in mind, can you think of the simplest way to make the explosions 10 times more powerful? How about modifying the "create explosion" function in a way that will multiply the
"power" parameter by 10 whenever it's called? Sounds easy.

Now, we need to find this "create explosion" function. For this to work, we need to analyze WA's code. You need a disassembler (and to make things easier, decompiler) - your two main options are Ghidra and IDA Free/Pro. I roll with IDA Pro, but Ghidra is fine too.

Once you load WA in your disassembler, you will see thousands of functions, most of them will be named something like sub_401530, sub_401550, sub_401560, sub_4015A0, sub_4015F0... where is our "create explosion"? You need to find it (given it exists and our assumption was correct).

Think of an explosion in WA. What exactly happens when stuff explodes? You see a flash, hear a bang, a hole is created in the land, worms lose hp if hit, worms are pushed away from the explosion, worms change their animation from standing to flying/hurt, worms emit blood (if set in scheme), oil barrells explode and create fire, debris in background is pushed away from the explosion... you get the idea.
If we don't know where the "create explosion" function is, maybe we can find a function that is somewhat related to creating explosion? After all, there should be some connection between creating an explosion and making a hole in the land, right?

Now, do we know any functions that implement those side effects? No, we don't know any function names and there are thousands of functions in the game. This seems impossible.

Let's analyze the side effects - some of them seem more complex than others. For example, making a hole in the ground seems more difficult than playing an explosion sound. What's seemingly the easiest side effect? I think it's damaging the worm - specifically, reducing it's hp. Let's find a function that reduces worm's HP.

Start the game in single player mode, make a playground scheme - place only one worm on the map, give yourself all ammo, infinite turn time. Launch Cheat Engine and scan for a dword "100", as your worm currently as 100 hp. You should have thousands of matches. Damage your worm a little, do a further scan for your worm's current hp. Repeat this until you have only one or very few matches. Add the address to the list and modify the value to 9999 and try damaging the worm again. If done correctly, your worm should have a lot of hp. Congrats, you found the variable that holds your current worm's HP.

Now, how to find the function that actually damages your worm? You need to check what accesses this variable. In cheat engine, select this variable and activate a memory breakpoint on write, (aka see what writes to this address). Continue damaging the worm, you will see that some addresses will appear, along with the number of accesses to the variable. You will probably see one ore two functions - copy their addresses. Go to IDA/Ghidra and go to this address. It probably does not exist, because of ASLR changing the base address of WA process. You can rebase the function address manually, but in general, you will need to disable ASLR in WA.exe for convenient debugging - https://osandamalith.com/2018/10/24/pe-sec-info-a-simple-tool-to-manipulate-aslr-and-dep-flags/

Now take a look at the code in IDA/Ghidra, does it look like something that writes the worm's HP? Look at the xref's to this function (aka functions that call this function). Probably one of them will be the one that creates an explosion. You can also look for other functions, like the one that plays sounds.

Once you identify your "create explosion" function, you will need to hook using minhook or polyhook or any other hooking library (you need to know function address or bettr, find address by function signature) and make a wrapper call that will roughly look like this:
int create_explosion_hooked(int x, int y, int power) {
  return create_explosion_original(x, y, power*10);
}

Make a shared library with cmake and msvc toolchain, compile it and load in the game, voila


Sorry, i've run out of time writing this guide. That's the basic idea. Check out my modules and the discord links - i've posted over 4000 function addresses, so you don't have to find them yourself, cheers.