HackShield


HackShieldはMMORPGの為に開発されたアンチハッキングツールキットのセットである.Combat Arms, メイプルストーリー, マビノギなど数多くのオンラインゲームで採用されている. HackShieldは韓国のセキュリティ・ソリューション・プロバイダであるアンラボ社(AhnLab,Inc.)によって開発され, 韓国では2001年から, アメリカでは2005年から, 日本では2006年から広く利用されるようになった.

製品

AhnLab HackShield にはHackShield Basic For OnlineGame, HackShield Plus For OnlineGame, HackShield Pro For OnlineGameの三種類があるが日本で主に販売されているのはProである.

機能

以下に示すオンラインゲームセキュリティに特化する優れた機能を多数有しており機能面ではライバルの nProtect GameGuard とほぼ同等である.
  • メモリハッキング遮断
  • スピードハック遮断
  • デバッガ遮断
  • メッセージフック遮断
  • オートマウス遮断
  • ファイル改ざん遮断
  • ランタイム改ざん遮断
  • 実行ファイルパッキング/暗号化
  • パケット暗号化
  • データファイル暗号化
  • サーバサイドクラック保護
  • スマートアップデート

HackShieldコンポーネント

  • EhSvc.dll
    • HackShieldのインターフェースのDLLでありゲームクライアントとHackShield間の通信およびHackShieldドライバ(EagleNT.sys)との通信を担っている
    • このDLLによって主なハッキング検出エンジンが実行されるため,Bypassを行う上ではこのDLLに手が加えられることが多い
  • V3Pro32s.dll
    • ハッキングツール検出インターフェースのDLLである
    • このDLLによってハッキングツールの検出エンジンが実行され,既知のハッキングツールシグニチャのスキャンが開始される
  • 3N.mhe
    • ヒューリスティックエンジンのためのファイルであり既知のハッキングを検索するためのパターンが含まれている
  • psapi.dll
    • プロセスステートヘルパーDLL
    • プロセスシグニチャとプロセス制御関数のスキャンに利用される
  • V3Warp(d)(n)s.v3d
    • アンチハッキングエンジンパターンファイル
    • 3N.mheファイルを読み込んでいる
  • EagleNT.sys
    • HackShieldのカーネルドライバ
    • ゲームクライアントプロセスの保護,特定のAPIのフックなどアンチハッキング機能を実行する

HackShieldの動作

HackShieldの特徴は強力な暗号システムの実装であり,クライアントとサーバ間で送信されるすべてのデータがAES-256を用いて行われている.
ハッキングやマルウェアのシグニチャをメモリ上から走査するとともに, サーバやライブラリ(.dll)の妥当性をリアルタイムで検証している.
また,HackShieldのコンポーネントはThemidaという非常に強力なパッカーでパッキングされている.


HackShieldの機能を傍受するためにはその実行の流れを把握することが重要である.

HSUpdate

ゲームを起動時に右下にプログレスバーを含むアップデートダイアログが表示されるように,HackShieldはゲーム起動毎にHSUpdate.exeを実行してファイルの更新を行っている.
この更新システムはFTPとWEBの2つのプロトコルに基づいている.
  • FTP
    • FTPプロトコルはHackShield開発者に応じてカスタマイズされている
    • HSUpdateはMMORPGのサーバに接続してアップデートファイルのCRCハッシュを検証した後でファイルを交換する
  • WEB
    • 単にデータを取得するためにGETおよびPOSTリクエストを送信する
    • これらはFiddler2というHTTPプロキシスニファで傍受可能である

アップデートが終了するとゲームクライアントはHackShieldの根幹機能をロード(Kernel32.LoadLibraryA)してハッキング検出エンジンが実行される.

EHSvc

HackShieldのインターフェースDLLでありハッキング検出エンジンの実行およびゲームクライアントとHackShield間の通信およびHackShieldドライバ(EagleNT.sys)との通信を担っている.
このライブラリがHackShieldのバイパスにおける最も重要なコンポーネントである.

EHSvcではHackShieldにおけるすべての内部操作のロギング(暗号化されている)を行い, すべてのトラフィックが暗号化されているHSMSサーバ(HackShield Monitoring Server)にログを送信している.
この情報が不正であればゲームサーバとの通信が断たれてしまうため, HSを完全にバイパスするためには偽のログ情報を送信しなければならない.

HSの動作を理解するにはこのライブラリに焦点を当てるべきである.

EagleNT

EagleNTはライブラリの変更を防止するためのカーネルドライバである.
ゲームクライアントプロセスの保護,特定のAPIのフックなどアンチハッキング機能を実行する.

V3Pro32

ハッキングツールや任意のマルウェアの感染をスキャンするエンジンを含むインターフェースのDLLである.

HackShieldの導入

ゲームの開発者にとってHackShieldを導入することはさほど難しいことではない.
開発者はまず始めにアップデータを呼び出す.

DWORD ReturnCode = NULL;
 
ReturnCode = _AhnHS_HSUpdateEx( 
    szFullFilePath, // hshieldフォルダパス
    1000 * 600, // 更新のタイムアウト時間
    1234, // ゲームコード(ライセンスに付属)
    AHNHSUPDATE_CHKOPT_HOSTFILE| AHNHSUPDATE_CHKOPT_GAMECODE, // 追加オプション
    HsExtError, // エラーコード
    1000* 20 // サーバ接続のタイムアウト時間
);
 
switch (ReturnCode)
{
     case HSERROR_ENVFILE_NOTREAD:
     // HSUpdate.envを読み込めない
     break;
     case HSERROR_ENVFILE_NOTWRITE:
     // HSUpdate.envに書き込めない
     break;
     case HSERROR_NETWORK_CONNECT_FAIL:
     // サーバに接続できない
     break;
     [Eccetera per i vari e vari errori]
} 


HackShieldはエラーやハッキングの検出を警告すると多くの場合メッセージボックスを表示してゲームを終了する.これらはゲームクライアントのコールバック(スイッチ文)によって管理されている.
一昔前はこのコールバックを中断することでHackShieldを容易にバイパスすることが可能であった.

EHSvcについては呼び出し方がアップデータとは少し異なる.
EHSvcはゲーム開発者が購入した有効なライセンスで起動する必要があり,この情報はライブラリがロードされる際に与えられている.

BOOL HS_Init()
{
// [...]
// 任意の変数宣言
 
DWORD dwOption = AHNHS_CHKOPT_ALL; // 全てのオプションを実行
 
nRet = _AhnHS_Initialize ( 
    szFullFilePath, // hshieldフォルダパス
    HS_CallbackProc, // このコールバックはEHSvcと同じモジュールによって呼び出されクライアントからは実行されない
    1234, // ゲームコード(ライセンスに付属)
    "B228F291B7D7FAD361D7A4B7", // ライセンスキー
    dwOption, // オプションフラグ
    AHNHS_SPEEDHACK_SENSING_RATIO_NORMAL // スピードハックをチェックする頻度を設定
);
 
if (nRet != HS_ERROR_OK)
    // ...
 
} 
なお, ゲームクライアントのライセンスキーとゲームコードを見つけるのは難しいことではない.

HackShieldのバイパスを最初に考える上で安易に考えつくのがEHSvc.dllをロードさせないようにするというアイデアであるがこれは間違いである.
なぜなら, EHSvcが初期化された後でゲームクライアント側で簡単な関数 _AhnHS_StartService() が呼び出されることによってHackShieldが正常に実行されているかどうかを監視する機能が実行されるからである.

HackShieldの調査

まず第一に, ThemidaでパックされているEHSvc.dllをアンパックしてプロセスメモリのダンプを実行することがHackShieldのバイパスをを探す上で常に最善の選択である(Themidaのアンパックについてはtuts4youなどのサイトを参考にするとよい).

この調査では, "MaplsStory"というオンラインゲームに同梱されているHackShieldの最新バージョンを利用している.
現時点でのバージョンは5.6.34.449である.

分析に必要なツール:
  • IDA Pro
  • Olly(Strong ODやPhantOmなどのアンチ-アンチデバッグプラグインが導入済みのもの)
  • PEiDとKrypto Analyzer

バイパスの構築に必要な知識:
  • PE構造についての知識
  • CまたはC++の知識
  • Microsoft Detours 3 (または 1.5)
  • メモリ編集機能についての知識
  • Injector (RemoteDLLなど)

IDA Proによる分析が完了した後でEHSvcの構造について認識する必要がある. エクスポートテーブルを見れば序数だけで構成された関数を確認することができる.
これらの関数のほとんどが各種更新やAhnlabのスワップ機能でありそれらは役に立たないが, それ以外のコールバックを呼び出しエラーを返す関数はバイパスを行う上で重要である.

インポートテーブルを確認するのは, EHSvc内で行われるいくつかの機能を特定するのに有用であろう.
+ インポート一覧
Address  Ordinal Name                                  Library 
-------  ------- ----                                  ------- 
10120000         AddAce                                ADVAPI32
10120004         GetLengthSid                          ADVAPI32
10120008         CopySid                               ADVAPI32
1012000C         GetTokenInformation                   ADVAPI32
10120010         RegOpenKeyA                           ADVAPI32
10120014         RegDeleteValueA                       ADVAPI32
10120018         OpenThreadToken                       ADVAPI32
1012001C         RegEnumValueA                         ADVAPI32
10120020         RegQueryInfoKeyA                      ADVAPI32
10120024         RegEnumKeyExA                         ADVAPI32
10120028         OpenProcessToken                      ADVAPI32
1012002C         LookupPrivilegeValueA                 ADVAPI32
10120030         AdjustTokenPrivileges                 ADVAPI32
10120034         RegCreateKeyExA                       ADVAPI32
10120038         RegCloseKey                           ADVAPI32
1012003C         RegOpenKeyExA                         ADVAPI32
10120040         RegSetValueExA                        ADVAPI32
10120044         RegQueryValueExA                      ADVAPI32
10120048         AllocateAndInitializeSid              ADVAPI32
1012004C         LookupAccountSidA                     ADVAPI32
10120050         FreeSid                               ADVAPI32
10120054         InitializeSecurityDescriptor          ADVAPI32
10120058         SetSecurityDescriptorDacl             ADVAPI32
1012005C         InitializeAcl                         ADVAPI32
10120060         EqualSid                              ADVAPI32
10120064         GetExplicitEntriesFromAclA            ADVAPI32
10120068         GetNamedSecurityInfoA                 ADVAPI32
1012006C         GetAce                                ADVAPI32
10120070         GetAclInformation                     ADVAPI32
10120074         IsValidSid                            ADVAPI32
10120078         GetSidSubAuthority                    ADVAPI32
1012007C         GetSidSubAuthorityCount               ADVAPI32
10120080         CloseServiceHandle                    ADVAPI32
10120084         CreateServiceA                        ADVAPI32
10120088         OpenSCManagerA                        ADVAPI32
1012008C         DeleteService                         ADVAPI32
10120090         OpenServiceA                          ADVAPI32
10120094         StartServiceA                         ADVAPI32
10120098         ControlService                        ADVAPI32
1012009C         QueryServiceStatus                    ADVAPI32
101200A0         UnlockServiceDatabase                 ADVAPI32
101200A4         ChangeServiceConfigA                  ADVAPI32
101200A8         LockServiceDatabase                   ADVAPI32
101200AC         RegSetValueExW                        ADVAPI32
101200B0         GetKernelObjectSecurity               ADVAPI32
101200B4         SetNamedSecurityInfoA                 ADVAPI32
101200BC         CryptMsgUpdate                        CRYPT32 
101200C0         CryptQueryObject                      CRYPT32 
101200C4         CertFreeCertificateChain              CRYPT32 
101200C8         CertGetSubjectCertificateFromStore    CRYPT32 
101200CC         CryptMsgControl                       CRYPT32 
101200D0         CertOpenSystemStoreA                  CRYPT32 
101200D4         CertCloseStore                        CRYPT32 
101200D8         CryptMsgClose                         CRYPT32 
101200DC         CertFreeCRLContext                    CRYPT32 
101200E0         CertVerifySubjectCertificateContext   CRYPT32 
101200E4         CertFindCertificateInStore            CRYPT32 
101200E8         CryptMsgGetParam                      CRYPT32 
101200EC         CryptDecodeObject                     CRYPT32 
101200F0         CertGetNameStringA                    CRYPT32 
101200F4         CryptMsgOpenToDecode                  CRYPT32 
101200F8         CertOpenStore                         CRYPT32 
10120100         SelectObject                          GDI32   
10120104         DeleteObject                          GDI32   
10120108         CreateCompatibleDC                    GDI32   
1012010C         GetObjectA                            GDI32   
10120110         BitBlt                                GDI32   
10120114         StretchBlt                            GDI32   
10120118         GetStockObject                        GDI32   
1012011C         SetBkMode                             GDI32   
10120120         SetTextColor                          GDI32   
10120124         CreateFontA                           GDI32   
10120128         DeleteDC                              GDI32   
1012012C         GetBitmapBits                         GDI32   
10120130         CreateCompatibleBitmap                GDI32   
10120134         GetDeviceCaps                         GDI32   
10120138         CreateDCA                             GDI32   
10120140         lstrcat                               kernel32
10120144         lstrcpyn                              kernel32
10120148         GlobalMemoryStatus                    kernel32
1012014C         GetSystemInfo                         kernel32
10120150         FileTimeToSystemTime                  kernel32
10120154         FileTimeToLocalFileTime               kernel32
10120158         GetFileTime                           kernel32
1012015C         GetLocalTime                          kernel32
10120160         lstrlen                               kernel32
10120164         LocalFree                             kernel32
10120168         lstrcpy                               kernel32
1012016C         LocalAlloc                            kernel32
10120170         DeleteFileA                           kernel32
10120174         OutputDebugStringA                    kernel32
10120178         FormatMessageA                        kernel32
1012017C         CreateProcessW                        kernel32
10120180         CreateFileW                           kernel32
10120184         GetExitCodeProcess                    kernel32
10120188         GetExitCodeThread                     kernel32
1012018C         SetThreadPriority                     kernel32
10120190         ResetEvent                            kernel32
10120194         OpenEventA                            kernel32
10120198         QueryPerformanceCounter               kernel32
1012019C         QueryPerformanceFrequency             kernel32
101201A0         CreateProcessA                        kernel32
101201A4         OpenProcess                           kernel32
101201A8         MultiByteToWideChar                   kernel32
101201AC         LoadLibraryExA                        kernel32
101201B0         lstrlenW                              kernel32
101201B4         ExitThread                            kernel32
101201B8         TlsAlloc                              kernel32
101201BC         TlsSetValue                           kernel32
101201C0         TlsGetValue                           kernel32
101201C4         CreateMutexA                          kernel32
101201C8         GetLongPathNameA                      kernel32
101201CC         SetEndOfFile                          kernel32
101201D0         WriteFile                             kernel32
101201D4         ReleaseMutex                          kernel32
101201D8         CreateFileMappingW                    kernel32
101201DC         Module32Next                          kernel32
101201E0         Module32First                         kernel32
101201E4         CreateToolhelp32Snapshot              kernel32
101201E8         OpenMutexA                            kernel32
101201EC         OpenFileMappingA                      kernel32
101201F0         FlushViewOfFile                       kernel32
101201F4         DuplicateHandle                       kernel32
101201F8         lstrcmp                               kernel32
101201FC         WaitForSingleObjectEx                 kernel32
10120200         DefineDosDeviceA                      kernel32
10120204         QueryDosDeviceA                       kernel32
10120208         TerminateProcess                      kernel32
1012020C         SetFileAttributesA                    kernel32
10120210         GetShortPathNameA                     kernel32
10120214         MoveFileExA                           kernel32
10120218         IsBadWritePtr                         kernel32
1012021C         IsBadReadPtr                          kernel32
10120220         InitializeCriticalSectionAndSpinCount kernel32
10120224         OpenSemaphoreA                        kernel32
10120228         ReadProcessMemory                     kernel32
1012022C         Process32Next                         kernel32
10120230         Process32First                        kernel32
10120234         GetDriveTypeA                         kernel32
10120238         FindClose                             kernel32
1012023C         FindNextFileA                         kernel32
10120240         FindFirstFileA                        kernel32
10120244         ReadFile                              kernel32
10120248         Thread32Next                          kernel32
1012024C         Thread32First                         kernel32
10120250         lstrcpynW                             kernel32
10120254         VirtualFreeEx                         kernel32
10120258         HeapReAlloc                           kernel32
1012025C         GetComputerNameA                      kernel32
10120260         GetDiskFreeSpaceA                     kernel32
10120264         GetVolumeInformationA                 kernel32
10120268         GetTempFileNameA                      kernel32
1012026C         GetTempPathA                          kernel32
10120270         GetPrivateProfileStringA              kernel32
10120274         GetCurrentProcessId                   kernel32
10120278         CopyFileA                             kernel32
1012027C         CreateDirectoryA                      kernel32
10120280         GetProcessAffinityMask                kernel32
10120284         SetThreadAffinityMask                 kernel32
10120288         GetVersion                            kernel32
1012028C         GetThreadLocale                       kernel32
10120290         GetStartupInfoA                       kernel32
10120294         GetLocaleInfoA                        kernel32
10120298         GetCommandLineA                       kernel32
1012029C         ExitProcess                           kernel32
101202A0         UnhandledExceptionFilter              kernel32
101202A4         RtlUnwind                             kernel32
101202A8         RaiseException                        kernel32
101202AC         GetStdHandle                          kernel32
101202B0         TlsFree                               kernel32
101202B4         lstrcpyW                              kernel32
101202B8         lstrcmpiW                             kernel32
101202BC         lstrcatW                              kernel32
101202C0         WriteProcessMemory                    kernel32
101202C4         WaitForMultipleObjects                kernel32
101202C8         VirtualQueryEx                        kernel32
101202CC         OpenMutexW                            kernel32
101202D0         OpenFileMappingW                      kernel32
101202D4         OpenEventW                            kernel32
101202D8         GetTempPathW                          kernel32
101202DC         GetTempFileNameW                      kernel32
101202E0         GetFileAttributesW                    kernel32
101202E4         GetFileAttributesA                    kernel32
101202E8         GetCurrentDirectoryW                  kernel32
101202EC         GetCurrentDirectoryA                  kernel32
101202F0         DeleteFileW                           kernel32
101202F4         CreatePipe                            kernel32
101202F8         CreateMutexW                          kernel32
101202FC         CreateEventW                          kernel32
10120300         LockResource                          kernel32
10120304         SizeofResource                        kernel32
10120308         LoadResource                          kernel32
1012030C         FindResourceA                         kernel32
10120310         GetSystemTime                         kernel32
10120314         GetEnvironmentVariableA               kernel32
10120318         FatalAppExitA                         kernel32
1012031C         HeapSize                              kernel32
10120320         GetCPInfo                             kernel32
10120324         GetACP                                kernel32
10120328         GetOEMCP                              kernel32
1012032C         VirtualAllocEx                        kernel32
10120330         HeapDestroy                           kernel32
10120334         HeapCreate                            kernel32
10120338         DeviceIoControl                       kernel32
1012033C         CreateFileMappingA                    kernel32
10120340         MapViewOfFile                         kernel32
10120344         GetWindowsDirectoryA                  kernel32
10120348         GetCurrentThread                      kernel32
1012034C         CreateThread                          kernel32
10120350         TerminateThread                       kernel32
10120354         SetThreadContext                      kernel32
10120358         SetLastError                          kernel32
1012035C         GetModuleFileNameA                    kernel32
10120360         VirtualQuery                          kernel32
10120364         SuspendThread                         kernel32
10120368         GetThreadContext                      kernel32
1012036C         GetCurrentThreadId                    kernel32
10120370         LCMapStringA                          kernel32
10120374         LCMapStringW                          kernel32
10120378         SetUnhandledExceptionFilter           kernel32
1012037C         FlushFileBuffers                      kernel32
10120384         FreeEnvironmentStringsA               kernel32
10120388         FreeEnvironmentStringsW               kernel32
1012038C         GetEnvironmentStrings                 kernel32
10120390         GetSystemDirectoryA                   kernel32
10120394         LoadLibraryW                          kernel32
10120398         GetProcessHeap                        kernel32
1012039C         HeapAlloc                             kernel32
101203A0         HeapFree                              kernel32
101203A4         GetVersionExA                         kernel32
101203A8         GetSystemDirectoryW                   kernel32
101203AC         GetModuleFileNameW                    kernel32
101203B0         GetModuleHandleW                      kernel32
101203B4         UnmapViewOfFile                       kernel32
101203B8         CloseHandle                           kernel32
101203BC         InterlockedIncrement                  kernel32
101203C0         InterlockedDecrement                  kernel32
101203C4         DeleteCriticalSection                 kernel32
101203C8         InterlockedCompareExchange            kernel32
101203CC         Sleep                                 kernel32
101203D0         GetModuleHandleA                      kernel32
101203D4         InitializeCriticalSection             kernel32
101203D8         EnterCriticalSection                  kernel32
101203DC         LeaveCriticalSection                  kernel32
101203E0         GetCurrentProcess                     kernel32
101203E4         FlushInstructionCache                 kernel32
101203E8         GetLastError                          kernel32
101203EC         VirtualAlloc                          kernel32
101203F0         InterlockedExchange                   kernel32
101203F4         VirtualFree                           kernel32
101203F8         WideCharToMultiByte                   kernel32
101203FC         GetTickCount                          kernel32
10120400         FreeLibrary                           kernel32
10120404         LoadLibraryA                          kernel32
10120408         GetProcAddress                        kernel32
1012040C         ResumeThread                          kernel32
10120410         SetEvent                              kernel32
10120414         WaitForSingleObject                   kernel32
10120418         CreateEventA                          kernel32
1012041C         CreateFileA                           kernel32
10120420         GetFileSize                           kernel32
10120424         VirtualProtectEx                      kernel32
10120428         SetFilePointer                        kernel32
1012042C         VirtualProtect                        kernel32
10120430         GetEnvironmentStringsW                kernel32
10120434         GetStringTypeA                        kernel32
10120438         GetStringTypeW                        kernel32
1012043C         IsBadCodePtr                          kernel32
10120440         SetStdHandle                          kernel32
10120444         IsValidLocale                         kernel32
10120448         IsValidCodePage                       kernel32
1012044C         EnumSystemLocalesA                    kernel32
10120450         GetUserDefaultLCID                    kernel32
10120454         SetConsoleCtrlHandler                 kernel32
10120458         GetLocaleInfoW                        kernel32
1012045C         CompareStringA                        kernel32
10120460         CompareStringW                        kernel32
10120464         SetEnvironmentVariableA               kernel32
10120468         CompareFileTime                       kernel32
1012046C         GetTimeZoneInformation                kernel32
10120470         SetCurrentDirectoryA                  kernel32
10120474         SetFileTime                           kernel32
10120478         MoveFileA                             kernel32
1012047C         GetFullPathNameA                      kernel32
10120480         GetFileInformationByHandle            kernel32
10120484         lstrcmpi                              kernel32
10120488         PeekNamedPipe                         kernel32
1012048C         GetFileType                           kernel32
10120494         CreateErrorInfo                       oleaut32
10120498         VariantChangeType                     oleaut32
1012049C         SetErrorInfo                          oleaut32
101204A0         GetErrorInfo                          oleaut32
101204A4         SysReAllocStringLen                   oleaut32
101204A8         VariantInit                           oleaut32
101204AC         VariantClear                          oleaut32
101204B0         SysStringLen                          oleaut32
101204B4         SysAllocString                        oleaut32
101204B8         SysFreeString                         oleaut32
101204BC         OleLoadPicturePath                    oleaut32
101204C4         Shell_NotifyIcon                      SHELL32 
101204C8         ShellExecuteEx                        SHELL32 
101204D0         SendMessageA                          USER32  
101204D4         EnumThreadWindows                     USER32  
101204D8         PostMessageA                          USER32  
101204DC         FindWindowExA                         USER32  
101204E0         GetWindowLongA                        USER32  
101204E4         GetWindowModuleFileName               USER32  
101204E8         EnumWindows                           USER32  
101204EC         RegisterClipboardFormatA              USER32  
101204F0         FindWindowA                           USER32  
101204F4         DefWindowProcA                        USER32  
101204F8         IsWindow                              USER32  
101204FC         GetWindowInfo                         USER32  
10120500         SendMessageTimeoutA                   USER32  
10120504         GetClassNameA                         USER32  
10120508         IsWindowUnicode                       USER32  
1012050C         EnumChildWindows                      USER32  
10120510         CharUpperBuffA                        USER32  
10120514         CharLowerBuffA                        USER32  
10120518         CallNextHookEx                        USER32  
1012051C         UnhookWindowsHookEx                   USER32  
10120520         SetWindowsHookExA                     USER32  
10120524         GetKeyboardType                       USER32  
10120528         PeekMessageA                          USER32  
1012052C         OpenInputDesktop                      USER32  
10120530         GetForegroundWindow                   USER32  
10120534         GetWindowThreadProcessId              USER32  
10120538         CreateDialogParamA                    USER32  
1012053C         GetMessageA                           USER32  
10120540         IsDialogMessage                       USER32  
10120544         TranslateMessage                      USER32  
10120548         DispatchMessageA                      USER32  
1012054C         IsIconic                              USER32  
10120550         GetDlgItem                            USER32  
10120554         ShowWindow                            USER32  
10120558         GetClientRect                         USER32  
1012055C         GetParent                             USER32  
10120560         GetDesktopWindow                      USER32  
10120564         GetWindowRect                         USER32  
10120568         GetSystemMetrics                      USER32  
1012056C         SetWindowPos                          USER32  
10120570         SetTimer                              USER32  
10120574         KillTimer                             USER32  
10120578         PostQuitMessage                       USER32  
1012057C         CopyImage                             USER32  
10120580         LoadImageA                            USER32  
10120584         MessageBoxA                           USER32  
10120588         wsprintfW                             USER32  
1012058C         wvsprintfA                            USER32  
10120590         wsprintfA                             USER32  
10120594         CharUpperA                            USER32  
10120598         MsgWaitForMultipleObjects             USER32  
1012059C         GetUserObjectInformationA             USER32  
101205A0         GetThreadDesktop                      USER32  
101205A4         CloseDesktop                          USER32  
101205AC         VerQueryValueA                        VERSION 
101205B0         GetFileVersionInfoSizeW               VERSION 
101205B4         GetFileVersionInfoW                   VERSION 
101205B8         VerQueryValueW                        VERSION 
101205BC         GetFileVersionInfoSizeA               VERSION 
101205C0         GetFileVersionInfoA                   VERSION 
101205C8         HttpQueryInfoA                        WININET 
101205CC         InternetReadFileExA                   WININET 
101205D0         HttpSendRequestA                      WININET 
101205D4         InternetSetStatusCallback             WININET 
101205D8         InternetConnectA                      WININET 
101205DC         InternetCloseHandle                   WININET 
101205E0         HttpOpenRequestA                      WININET 
101205E4         DeleteUrlCacheEntry                   WININET 
101205E8         InternetReadFile                      WININET 
101205EC         InternetCrackUrlA                     WININET 
101205F0         InternetCanonicalizeUrlA              WININET 
101205F4         InternetOpenA                         WININET 
101205FC         timeGetTime                           winmm   
10120600         timeSetEvent                          winmm   
10120604         timeKillEvent                         winmm   
1012060C         WSAStartup                            WS2_32  
10120610         WSACleanup                            WS2_32  
10120614         htons                                 WS2_32  
10120618         gethostbyname                         WS2_32  
1012061C         inet_ntoa                             WS2_32  
10120624         ImageEnumerateCertificates            imagehlp
10120628         ImageGetCertificateHeader             imagehlp
10120630         GetAdaptersInfo                       iphlpapi
10120638         CoUninitialize                        ole32   
1012063C         CoSetProxyBlanket                     ole32   
10120640         CoCreateInstance                      ole32   
10120644         CoInitializeSecurity                  ole32   
10120648         CoInitializeEx                        ole32   
10120650         URLDownloadToFileA                    urlmon

バイパスに必要な機能を検索するにはアンパックされていないEHSvcをゲームクライアントを介して起動し, その実行挙動を確認して行かなければならない.
残念ながら, ThemidaによってパッキングされているためIDAやOllyでこれを行うことは困難である.Cheat Engineのデバッグ機能を活用する方法はある).
アンパックされたEHSvcをアンパックされたゲームクライアントを介して起動して分析する方法も考えられるが, この方法ではモジュールがサーバの署名と一致しないために分析は失敗に終わるだろう.

いずれにせよ, 真のバイパスを実現するために見つけなければならないEHSvcに実装されている関数を以下に示す:
  • LMP Check
    • EHSvcまたはゲームクライアントはサーバに登録されたディジタル署名によって改竄が行われていないかどうかをチェックしている.
    • このチェックを回避する唯一の方法が, 我々が独自に実装したもので本来の機能を置き換えるものである.
  • Main Thread
    • スキャンの開始を処理する関数であり, これを回避するためには独自の機能に置き換えた上で偽のスキャンスレッドによって動作を偽装する必要がある.
  • Heuristic Scan
    • この関数は,ゲームクライアントからあらゆるチート行為をスキャンしている.
  • Heuristic Module Scan
    • この関数は,EHSvcの走査モジュールの改竄を監視している.
  • Integrity Check
    • モジュールが完全であるかどうかをチェックし,内部の整合性を確認するためにサーバへのコールを実行する.
  • Kernel Tracer [KDTrace]
    • メモリ改ざんを検出するために, EHSvcとドライバ間でコールモニタリングを実行する.

EHSvcモジュール内のすべての文字列を識別するのは良いアイデアだが, 残念ながらいくつかの文字列はBase64または各文字列キーによるXORでエンコードされている.
これらの文字列を復号するためには暗号化アルゴリズムとそのキーを調査する必要があるが, これはバイパスにおいて必須ではない.


これら重要な関数を特定することはそこまで難しいものではない:
HSは我々がバイパスするべきスレッドを起動する上でCreateEventA, CreateEventW, CreateThread, SetEventなどの関数を利用している.
一度リバースエンジニアリングおよびデバッギングによってバイパスすべきスレッドを識別してしまえば, それを独自のスレッドと置き換えることは容易である.
また, CRCによるチェックを特定するには, 単にKrypto Analyzerなどのツールを利用してCRCが行われている関数を明らかにしてしまえば良い.
これらの操作はIDA Proによって容易に実行することが可能である.

Tip & Tricks

ログを利用した機能の追跡

DEBUGモードを有効にすることでEHSvcの収集するログ情報を監視して興味深い関数呼び出しを見つけるのに役立てるトリックを紹介する.
DEBUGモードはシングルバイトで管理されており, Kernel32.wsprintfAを呼び出す関数を調べることによって見つけることができる.

このシングルバイトを0x01または0x02に変更した上で, 単にOutputDebugStringA()による出力をロギングするだけでよい.

引用元文献

最終更新:2014年12月03日 10:57