This is a two-part process, be sure you patch both Ebenezer and the client.
Client: KnightOnline.exe
The original code is:
- 0054C622 |. D1E0 SHL EAX,1
- 0054C624 3BC1 CMP EAX,ECX
- 0054C626 7C 1E JL SHORT 0054C646
复制代码 This basically translates to something like:- if ((m_curHP * 2) < m_maxHP)
- {
- // show error and return
- }
- else
- {
- // send WIZ_HOME packet
- }
复制代码 There's not really any easy way to change it to a specific percentage using this method, so we'll patch over this code and create our own check.
So patch those lines to:- 0054C622 E9 E4601500 JMP 006A270B
- 0054C627 90 NOP
复制代码 Now we'll go to the code-cave, at 006A270B and assemble these lines.- 006A270B 60 PUSHAD
- 006A270C 33D2 XOR EDX,EDX
- 006A270E F7F9 IDIV ECX
- 006A2710 6BC0 64 IMUL EAX,EAX,64
- 006A2713 83F8 5A CMP EAX,5A <---- 5A = 90, so 90%!
- 006A2716 61 POPAD
- 006A2717 ^0F8C 299FEAFF JL 0054C646
- 006A271D ^E9 069FEAFF JMP 0054C628
复制代码 Now that we're done with the client, let's move onto the server!
Server: Ebenezer
If the client passes the check, it'll then send it to the server - where Ebenezer will then check to make sure the client is telling the truth (for once, mgame didn't blindly go with what the client said...).
Let's just overwrite the check:
- 004B4802 |. 3BD0 CMP EDX,EAX
- 004B4804 |. 0F8C 97000000 JL 004B48A1
复制代码 With a jump to our code-cave:
- 004B4802 ^EB 96 JMP SHORT 004B479A
- 004B4804 90 NOP
- 004B4805 90 NOP
- 004B4806 90 NOP
- 004B4807 90 NOP
- 004B4808 90 NOP
- 004B4809 90 NOP
复制代码 Aaand now our code-cave should look like this:- 004B479A 60 PUSHAD
- 004B479B 33D2 XOR EDX,EDX
- 004B479D 8B83 26810000 MOV EAX,DWORD PTR DS:[EBX+8126]
- 004B47A3 F77E 66 IDIV DWORD PTR DS:[ESI+66]
- 004B47A6 6BC0 64 IMUL EAX,EAX,64
- 004B47A9 83F8 5A CMP EAX,5A <--- 90%
- 004B47AC 61 POPAD
- 004B47AD 0F8C EE000000 JL 004B48A1
- 004B47B3 EB 55 JMP SHORT 004B480A
复制代码 Look familiar? It should!
All we're doing here is some pretty simple math.
(m_curHP / m_maxHP) * 100
That formula look familiar? If you're not 10 years old like some people around here *you know who you are*, then it should most certainly look familiar - we're getting the percentage!
After we get the HP percentage, we compare it to 90 (5A). If it's lower than 90(%), then the check fails and we skip to returning (or erroring and returning in the client's case).
You can change 5A (90%) to whatever you prefer - just make sure that it's between 0 and 100, otherwise it won't make the slightest bit of sense. :) |