Twisted 发表于 2011-10-17 07:45:31

[1.298] Patch the select char DC hack

The select character DC hack is done by memory editing your character name to your desired victim's at the character selection screen (then you select the character).

This means that the client will send your account ID... and the character name you memory edited.

Now... what CUser::SelCharToAgent does is check for any existing sessions, and disconnects them (in case you have a session stuck in-game). For those wondering, this is all done before it calls upon Aujard to execute the procedure LOAD_USER_DATA - so you will be unable to stop this one via stored procedures.

There's not really much difference with this part of the code and the original source, so here's a snippet of the original source to give you some idea of what's happening:      if( _strnicmp( accountid, m_strAccountID, MAX_ID_SIZE ) != 0 ) {
                pUser = m_pMain->GetUserPtr( accountid, 0x01 );
                if( pUser && (pUser->m_Sid != m_Sid) ) {
                        pUser->Close();
                        goto fail_return;
                }
                strcpy( m_strAccountID, accountid );
      }

      pUser = m_pMain->GetUserPtr( userid, 0x02 );
      if( pUser && (pUser->m_Sid != m_Sid) ) {
                pUser->Close();
                goto fail_return;
      }m_pMain is a pointer to CEbenezerDlg, and GetUserPtr loops through the socket array to attempt to find a session where:
- strAccountID matches accountid, if the second parameter is 1 (or 0x01 in C hexadecimal),
or
- strUserId matches userid, if the second parameter is 2 (or 0x02 in C hexadecimal).

Once it finds a session that doesn't match, it'll close the other session and error & disconnect the current session.
This is exactly what a user experiences when they attempt the DC hack.

The account search is of no relevance, as we're searching for the current account ID. On the other hand, the character search is - as we're passing in the character name of our victim.      pUser = m_pMain->GetUserPtr( userid, 0x02 );
      if( pUser && (pUser->m_Sid != m_Sid) ) {
                pUser->Close();
                goto fail_return;
      }It'll pass all the checks - as pUser will be set, and the unique session IDs (m_Sid) will definitely differ (as the victim is using another session, duuuuuhhhh) - and then call Close() on the victim's session.

Now, I see no logical reason in both searches - the account should be more than sufficient. I asked BlaDe to make sure I wasn't missing any logical reasons this might be kept, but the best we could come up was "perhaps future support for account ID changes".

So, though the new CUser::SelCharToAgent is changed a bit, the basis is pretty much the same.
We want to disable the character search as messlessly as possible (and yes, that is a word, I'm sure of it!... *cough*).

After trying a few different methods to see which I liked best, I finally settled on this one.

We replace:
00492562         8BCE            MOV ECX,ESI; Start of the character search
00492564         E8 FD15F7FF    CALL Ebenezer.00403B66; Some call using our bytes (forgot to write it down, but it's of little relevance anyway in this case - everything in this section must be bypassed!)With:00492562      ^EB 88            JMP SHORT Ebenezer.004924EC; Jump down below to below the check
00492564         90                      NOP; Extra bytes we don't need
00492565         90                      NOP
00492566         90                      NOP
00492567         90                      NOP
00492568         90                      NOPI jumped past the function internally merely because there are multiple jumps to the character search, so we don't need to go patching every little jump there.

You can patch this with OllyDbg, OR via my updated Ebenezer/Client Editor, which will be released very soon. ;)
页: [1]
查看完整版本: [1.298] Patch the select char DC hack