- Joined
- Apr 14, 2013
- Messages
- 74
- Reaction score
- 7
NOTE: this tutorial requires knowledge in assembly language, and I will not be teaching it here.
So ill be showing you my method of getting the TW client structs.
The tool we will be using is Cheat Engine.
NOTE: I am using Cheat Engine 6.7, as I faced some problems testing the newest version, but this one works quite well.
I was not able to get any strings/functions/structs from the client using other tools (like IDA or ollydbg), and I think the reason is that the client code is obfuscated/encrypted. So the alternative is to look at the code at runtime, and I think Cheat Engine does this very well.
Basically, when the client runs, it unpacks and loads everything into its memory, so then we will be able to actually find stuff.
So here are the steps:
So here is the Memory Viewer of the GU_SKILL_LEARN_RES reference address:
this is the function that handles the GU_SKILL_LEARN_RES packets in the client.
In the blue square, we see a hex value being pushed and the comment "5073", those refer to the opcode, so the GU_SKILL_LEARN_RES packet has the opcode 5073, which is 000013D1 in hexadecimal.
In the red square, we see first “mov esi,[esp+08]” ==> [esp+08] is the start address of the struct, and we are moving it into esi, so the struct fields should be "esi+##"
NOTE: The opcode is 2 bytes (WORD) and it will start at esi, so the first element after that would be the first element in the struct. For the GU_SKILL_LEARN_RES packet, it is the wResultCode variable.
So now we see “movzx eax,word ptr [esi+02]”.
In short, it is moving the value of wResultCode into eax.
Next is “cmp ax,01F4”, cheat engine added the comment “500”, which means that the value of “01F4” is 500 (which is actually the GAME_SUCCESS result code).
6 steps below it we can see that the wResultCode "[esi+02]" value is being pushed as a parameter to the next function, this is probably the function for handling events. therefore, if the packet struct had other fields, they would probably be also pushed here.
i hope this was clear and helpful. i know i used the simplest packet struct (only 1 field), but finding the structs of the other packets can be acheived in a quite similar way.
im not a professional, so please correct any mistake i made or add whatever information you want to.
UPDATE:
this is how you can get all opcode numbers and how to find each number's opcode name.
1. follow the steps above until step 8.
2. scroll up until the start of the function (the line just below the "int 3" instructions).
3. you will see the line that corresponds to the data section of the function (Code/Data)
4. double click the text (Code/Data)
now you can see all opcode numbers, to find an opcode's name, you need to go to the function where the name is shown in the comment.
we can see that the opcode is being pushed to a function as a parameter:
push 000013D1
above it, there is the address of the function that handles the opcode,
5. double click on this line and copy only the address.
6. press Ctrl+G on your keyboard
7. paste and click ok to go to the address
8. scroll down until you see the opcode's name in the comment
ill be showing how to find the fields of other structs later on (just some more examples)
So ill be showing you my method of getting the TW client structs.
The tool we will be using is Cheat Engine.
NOTE: I am using Cheat Engine 6.7, as I faced some problems testing the newest version, but this one works quite well.
I was not able to get any strings/functions/structs from the client using other tools (like IDA or ollydbg), and I think the reason is that the client code is obfuscated/encrypted. So the alternative is to look at the code at runtime, and I think Cheat Engine does this very well.
Basically, when the client runs, it unpacks and loads everything into its memory, so then we will be able to actually find stuff.
So here are the steps:
- Run DBO.exe client (no servers required), wait until its in the login screen, then just minimize the window and keep it there.
- In cheat engine attach the DBO.exe process
- Go to [Memory View] -> [View] -> [Referenced strings]
- It will ask you to dissect the code, click yes and wait for it till its finished.
- Now we get the “Referenced strings” window. search for any of the game server (GU) packets. Example: GU_SKILL_LEARN_RES
- Now we can see all of the game server opcodes, and if we scroll up far enough we will be able to find other servers’ opcodes.
- On the right you will see the list of addresses that reference the opcode, most of the opcodes only have one reference, so we will only see one address.
- Double click on that address, and it will take you to it in the Memory Viewer.
So here is the Memory Viewer of the GU_SKILL_LEARN_RES reference address:
To view the content, you need to sign in or register
this is the function that handles the GU_SKILL_LEARN_RES packets in the client.
In the blue square, we see a hex value being pushed and the comment "5073", those refer to the opcode, so the GU_SKILL_LEARN_RES packet has the opcode 5073, which is 000013D1 in hexadecimal.
In the red square, we see first “mov esi,[esp+08]” ==> [esp+08] is the start address of the struct, and we are moving it into esi, so the struct fields should be "esi+##"
NOTE: The opcode is 2 bytes (WORD) and it will start at esi, so the first element after that would be the first element in the struct. For the GU_SKILL_LEARN_RES packet, it is the wResultCode variable.
So now we see “movzx eax,word ptr [esi+02]”.
In short, it is moving the value of wResultCode into eax.
Next is “cmp ax,01F4”, cheat engine added the comment “500”, which means that the value of “01F4” is 500 (which is actually the GAME_SUCCESS result code).
6 steps below it we can see that the wResultCode "[esi+02]" value is being pushed as a parameter to the next function, this is probably the function for handling events. therefore, if the packet struct had other fields, they would probably be also pushed here.
i hope this was clear and helpful. i know i used the simplest packet struct (only 1 field), but finding the structs of the other packets can be acheived in a quite similar way.
im not a professional, so please correct any mistake i made or add whatever information you want to.
UPDATE:
this is how you can get all opcode numbers and how to find each number's opcode name.
1. follow the steps above until step 8.
2. scroll up until the start of the function (the line just below the "int 3" instructions).
3. you will see the line that corresponds to the data section of the function (Code/Data)
4. double click the text (Code/Data)
now you can see all opcode numbers, to find an opcode's name, you need to go to the function where the name is shown in the comment.
we can see that the opcode is being pushed to a function as a parameter:
push 000013D1
above it, there is the address of the function that handles the opcode,
5. double click on this line and copy only the address.
6. press Ctrl+G on your keyboard
7. paste and click ok to go to the address
8. scroll down until you see the opcode's name in the comment
ill be showing how to find the fields of other structs later on (just some more examples)
Last edited: