EMO Style ForumPro - Hos Geldiniz
Giriş yap

Şifremi unuttum

Istatistikler
Toplam 202 kayıtlı kullanıcımız var
Son kaydolan kullanıcımız: AnthonyFurey3

Kullanıcılarımız toplam 1186 mesaj attılar bunda 862 konu
Tarıyıcı
 Kapı
 Indeks
 Üye Listesi
 Profil
 SSS
 Arama
Arama
 
 

Sonuç :
 


Rechercher çıkıntı araştırma

RSS akısı


Yahoo! 
MSN 
AOL 
Netvibes 
Bloglines 


Kimler hatta?
Toplam 4 kullanıcı online :: 0 Kayıtlı, 0 Gizli ve 4 Misafir

Yok

[ Bütün listeye bak ]


Sitede bugüne kadar en çok 92 kişi Paz Ağus. 28, 2016 6:58 am tarihinde online oldu.
En son konular
» İnternetten Para Kazandıran Oyun ! Ödeme Alt Limiti Yok ! DEV KONU
Cuma Ağus. 29, 2014 8:33 am tarafından Hello EMO

» goldenchase.net maden yaparak para kazanma
Cuma Ağus. 29, 2014 8:18 am tarafından Hello EMO

» etichal hacker görsel egitim seti
Çarş. Ağus. 06, 2014 4:57 am tarafından Hello EMO

» KO TBL Source C#
Ptsi Ara. 09, 2013 6:36 am tarafından Hello EMO

» x86 Registers
C.tesi Ağus. 24, 2013 5:02 am tarafından Hello EMO

» [Tutorial] Pegando Address, Pointers de WYD
Çarş. Tem. 10, 2013 7:25 am tarafından Hello EMO

» [Tutorial] Pegando Address, Pointers de CS Metodo²
Çarş. Tem. 10, 2013 7:23 am tarafından Hello EMO

» [Tutorial] Aprendendo basico deASM OLLYDBG
Çarş. Tem. 10, 2013 7:22 am tarafından Hello EMO

» Basic C# DLL injector
Ptsi Tem. 08, 2013 7:48 am tarafından Hello EMO

Reklam

[1.298] Name change hack fix

Önceki başlık Sonraki başlık Aşağa gitmek

[1.298] Name change hack fix

Mesaj tarafından Hello EMO Bir Çarş. Şub. 23, 2011 8:55 am

[quote name='twostars' timestamp='1296418198' post='125']
The way the name change hack works is not specifically by EVT, instead by sending the "name change reply" packet to the server.

Name change should normally work like this:

1. Player clicks NPC,
2. Client sends the event ID as a request to Ebenezer,
3. This goes through the event logic and will finally trigger hit the EVT function that triggers name change,
4. The "call to name change" then tells the client to load up the name change edit box,
5. Player types their desired name in the edit box and it is sent to Ebenezer as a separate "reply" packet,
6. The server (CUser::RecvChangeName) then tells the client what the result was (if the name is in use, an edit box will be sent again to the client, otherwise it'll have succeeded and will take a name change scroll and change the name).

What the hack is doing is:

1. Player clicks NPC,
2. Client sends the event ID as a request to Ebenezer,
3. This goes through the event logic and will finally trigger hit the EVT function that triggers name change,
4. The "call to name change" then tells the client to load up the name change edit box,
5. Hack sends the desired name (actually, nothing/0x00 by default - though it could be sending the character name in the packet if it was a little smarter) to Ebenezer as a separate "reply" packet,
6. The server (CUser::RecvChangeName) then tells the client what the result was (if the name is in use, an edit box will be sent again FOR THE FIRST TIME to the client, otherwise it'll have succeeded and will take a name change scroll and change the name).

As you can see, the hack is skipping a whole load of steps there.
Now that we've figured out how the exploit works, let's see how we can patch it!

We should really start from the beginning. What checks is the hack actually skipping?
Well.. this is actually, really easy. If your EVT is scripted correctly, you should be checking to see if the user has a name change scroll!

So with this in mind, what we can do now, is add this check to CUser::RecvChangeName(). And this we shall do!

For this, we'll need to make use of our trusty CUser::CheckExistItem() function, which requires two parameters - the item ID that we're checking for, and the minimum count (stack size). As the name change scroll is a non-stackable item, we'll pass 1 for the latter. CUser::CheckExistItem() returns true or false, depending on whether or not the item was found or not (true in the event it was, false in the event it wasn't).

I, somewhat inconveniently, decided to patch a jump to our code-cave here:
Kod:
004C53EE  |. E9 F4000000    JMP 004C54E7
004C53F3  |  90              NOP

Going to our code-cave:-

Save the registers (so that we don't have to worry about changing anything that is used later on - so long as we restore them when we're done!).
Kod:
004C54E7  |> 60            PUSHAD

We tend to work "backwards" when passing arguments to a function. So, we're storing argument 2 here - which is our minimum count (stack size!) - so that we can pass it as a full 4 bytes, rather than take the chance and have it think we're passing a byte.
Kod:
004C54E8  |. B8 01000000    MOV EAX,1

Push our minimum count (stack size) onto the stack for use with CUser::CheckExistItem(). (CUser::CheckExistItem(, 1))
Kod:
004C54ED  |. 50            PUSH EAX

Push 2FAF8500 onto the stack. Wait... WHAT? As you may have guessed, this is hex. Olly uses numbers you give it in hex, not decimal - so, we pass 2FAF8500 instead of... 800032000! As 800032000 is the "Scroll of Identity", aka, name change scroll, we're now passing our FIRST argument (remember - we're working backwards) to CUser::CheckExistItem(). (CUser::CheckExistItem(800032000, 1)).
Kod:
004C54EE  |. 68 0085AF2F    PUSH 2FAF8500


As we're now done with our parameters, we'll finally make our call to CUser::CheckExistItem(). Note: The return value will be stored in EAX.
Kod:
004C54F3  |. E8 9DD5F3FF    CALL 00402A95

The next step is checking the result of CUser::CheckExistItem(). To do this, we'll use "TEST". We could alternatively use "CMP EAX,0" here, but we're saving bytes in our code-cave. tongue.gif
This check doesn't completely make much sense without the conditional jump that follows it... so stay tuned... we're getting there!
Kod:
004C54F8  |. 85C0          TEST EAX,EAX

Take the opportunity to restore the registers to how they were (so we don't have to do it twice after our conditional jump [if the condition matches and if it doesn't]!).
Kod:
004C54FA  |. 61            POPAD

Finally.. our conditional jump! Step two of the check two instructions above. We're checking to see if it was a match to what we were checking. If you recall:
Kod:
TEST EAX,EAX

is the equivalent of:
Kod:
CMP EAX,0

which is comparing EAX to 0, so:
Kod:
004C54FB  |. 74 0B          JE SHORT 004C5508

will jump if they match (are EQUAL - JE = Jump if Equal).

Remember that EAX is the result of CUser::CheckExistItem(), which returns true if the item exists, and false if it doesn't.
True and False basically come down to two things - 1 (true) and 0 (false).

As:
Kod:
TEST EAX,EAX

is the equivalent of:
Kod:
CMP EAX,0

You can see that we're comparing our result to 0 (false).

Going back to our conditional jump:
Kod:
004C54FB  |. 74 0B          JE SHORT 004C5508

You can now see that we're jumping to our "on fail" code if the result of CUser::CheckExistItem() was EQUAL to false (0). As 004C5508 (our conditional jump's destination) isn't the next instruction, we'll continue on line by line with the "if the item -was- found" code.

If the item -was- found, we'll continue on with the two instructions we overwrote to jump to our code-cave to begin with.
Kod:
004C54FD  |. 50            PUSH EAX
004C54FE  |. E8 2DAC0300    CALL 00500130

00500130 is the address of memset(), a function that sets a block of memory of the specified length to the value you specify. I think the most common use is to null (0x00 [0]!) terminate strings. The end of a string is commonly determined with a null-terminator, which as I bracketed before, is basically the byte 0x00 (or just 0 in decimal). Note that it is NOT the actual number 0, that character is actually represented by the byte 0x30 (48 in decimal).

A normal call to memset() looks something like:
Kod:
memset(someBlockOfMemory, 0x00, 20);

Broken down, the first parameter is the address of the block of memory that we're setting, the second parameter is the value we're filling it with, and the third and final parameter is how much of the block of memory we're setting, in this case, 20 bytes.

Say for instance our block of memory looks like this:
Kod:
01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16

After calling memset() to basically replace the first 20 bytes with 0x00, our block of memory will look like this:
Kod:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 13 14 15 16

And that's basically how it works! (though you'd typically set the length of the WHOLE block of memory, otherwise you'll cause memory leaks - with strings)

With that in mind, we're passing it only one argument.. the other two have already been pushed onto the stack before the jump to our code-cave. This is why I mentioned that it was an "inconvenient place to patch" earlier. There's no problem at all with it if the player has the item and it continues along the original path of code... but what happens when the player hasn't got the item, and it jumps to the other code to fail - and never finishes calling memset()? More on this when we get there (very soon).

So, everything's fine, we'll continue on our merry way back to the original code path we were on!
Kod:
004C5503  |.^E9 ECFEFFFF    JMP 004C53F4

If the user has hit this jump, it means that they have the item and we don't need to do a THING - we give control back to CUser::RecvChangeName() to do what it needs to do (change the name preferrably, otherwise error if the name is in use).

Moving onto the next line:

Now... remember our earlier conditional jump, that one that triggers if the item was not found? Well... it jumps here! At this point in time, the user hasn't got the item, so what we want to do is do nothing! However, doing nothing actually takes a lot of effort (doesn't it always).

So going back to our question, "what happens when the player hasn't got the item, and it jumps to the other code to fail - and never finishes calling memset()"..
The answer to this is that the two previous additions to the stack (two parameters of memset) are never taken off the stack. With our stack pointer (ESP) never being reverted to what it was before the additions to the stack (everything pushed onto the stack takes [data size of addition] off the stack pointer), the stack pointer is left completely off. When you take something off the stack (usually by popping them), you add the length of the data back onto ESP (our stack pointer), so...

Going back to our problem with two DWORDs (4 bytes each) being forgotten about and left on the stack, we need to take them off!
4 bytes * 2 = 8 bytes, so we'll need to add 8 bytes to the stack pointer (ESP).

So we do!
Kod:
004C5508    83C4 08        ADD ESP,8

..and now all is be happy; the stack is exactly as it was before the memset() call!

With that problem out the way, we can then take a (short) jump to the end of CUser::RecvChangeName() - hence, we've done nothing in answer to the client. For the record, we don't particularly want to error as it will trigger an edit box to appear in the client (though of course, the player doesn't even have a name change scroll, so no matter what.. they won't be able to exploit name change - without a name change scroll!).
Kod:
004C550B  \.^EB D2          JMP SHORT 004C54DF

And we're done!

Code recap
Kod:
004C53EE  |. E9 F4000000    JMP 004C54E7
004C53F3  |  90              NOP

004C54E7  |> 60            PUSHAD
004C54E8  |. B8 01000000    MOV EAX,1
004C54ED  |. 50            PUSH EAX
004C54EE  |. 68 0085AF2F    PUSH 2FAF8500
004C54F3  |. E8 9DD5F3FF    CALL 00402A95
004C54F8  |. 85C0          TEST EAX,EAX
004C54FA  |. 61            POPAD
004C54FB  |. 74 0B          JE SHORT 004C5508
004C54FD  |. 50            PUSH EAX
004C54FE  |. E8 2DAC0300    CALL 00500130
004C5503  |.^E9 ECFEFFFF    JMP 004C53F4
004C5508    83C4 08        ADD ESP,8
004C550B  \.^EB D2          JMP SHORT 004C54DF

Have fun!
[/quote]


Hello Kitty
vs
eMoStyLe



avatar
Hello EMO
EMO Team
EMO Team

Cinsiyet : Erkek
Burçlar : Yay
Yılan
Mesaj Sayısı : 935
Puan : 244393
Rep Puanı : 18
Doğum tarihi : 28/11/89
Kayıt tarihi : 21/07/09
Yaş : 27
Nerden : EMO WorlD
İş/Hobiler : RCE Student / Game Hacking / Learn Beginner C#,C++,Delphi
Lakap : EMO

Kullanıcı profilini gör http://emostyle.myforumpro.com

Sayfa başına dön Aşağa gitmek

Önceki başlık Sonraki başlık Sayfa başına dön


 
Bu forumun müsaadesi var:
Bu forumdaki mesajlara cevap veremezsiniz