RO Client Unhandled Exception Overview

Introduction

This small overview describes reading of unhandled RO client exceptions (also known as 'Gravity Error'). You are required to have certain knowledge of the Assembly language and be able to work with a debugger (for example OllyDbg, which will be used in this overview). You should have some knowledge of the structure and terms related to the Portable Executable format. Before you continue reading, read the disclaimer first. If you find a mistake or have a suggestion, please post it in the bbs.

Structure

When you work with RO exceptions, it is the best, to view them with a fixed-width font, inside a text editor. If you post it in a board, put it into [code] tags, because they make it more readable.

Sample Exception

Module Name: C:\PATH\TO\YOUR\RO\091013RE.EXE
Time Stamp: 0x4ad4401b - Tue Oct 13 10:53:47 2009


Exception Type: 0xc0000005

0x0042553b	091013RE.EXE
0x004364cc	091013RE.EXE
0x00449374	091013RE.EXE
0x0047bc23	091013RE.EXE
0x004e5460	091013RE.EXE
0x004f5b9c	091013RE.EXE
0x005f086f	091013RE.EXE
0x005efd89	091013RE.EXE
0x00517524	091013RE.EXE
0x006e22d0	091013RE.EXE
0x006f6b4c	091013RE.EXE
0xbff8b560	KERNEL32.DLL
0xbff8b412	KERNEL32.DLL
0xbff89dd5	KERNEL32.DLL
0x22220000

eax: 0x00000000	ebx: 0x00000000
ecx: 0x00000000	edx: 0x00000012
esi: 0x00000012	edi: 0x00a9f7e8
ebp: 0x00a9f714	esp: 0x00a9f710

stack 00a9f710 - 00a9fb10
00A9F710 : 80 1B E8 03 24 F7 A9 00 CC 64 43 00 12 00 00 00
00A9F720 : 02 00 00 00 68 F7 A9 00 74 93 44 00 12 00 00 00
00A9F730 : 02 00 00 00 54 F7 A9 00 50 F7 A9 00 4C F7 A9 00
00A9F740 : B0 08 E8 03 00 00 00 00 80 1B E8 03 E8 F7 A9 00
00A9F750 : B0 08 E8 03 58 1C 6F 00 9C 00 00 00 3C F8 A9 00
00A9F760 : 68 6A 70 00 00 00 00 00 48 F8 A9 00 23 BC 47 00
00A9F770 : 78 00 00 00 B0 08 E8 03 18 01 00 00 00 00 00 00
00A9F780 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00A9F790 : 00 00 00 00 00 00 00 00 00 00 00 00 00 08 E8 03
00A9F7A0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 08 E8 03
00A9F7B0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 3A 40 00
00A9F7C0 : 00 00 00 00 00 00 00 00 00 00 00 00 40 60 74 00
00A9F7D0 : 48 60 74 00 54 60 74 00 14 60 74 00 04 60 74 00
00A9F7E0 : F4 5F 74 00 BD 00 00 00 60 00 00 00 EA 00 00 00
00A9F7F0 : 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00A9F800 : 00 00 00 00 79 00 00 00 7A 00 00 00 00 00 00 00

Launch Info
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000

Job : Novice

Module Name

Module Name: C:\PATH\TO\YOUR\RO\091013RE.EXE

This line shows you, where the affected client is located and how it is called. It aids finding the issue, because certain paths can have restrictions on certain operating systems. It can also give you certain clue, if the client was renamed for whatever reason.

Time Stamp

Time Stamp: 0x4ad4401b - Tue Oct 13 10:53:47 2009

This line represents the time and date, when the client was built (linked). It is not the last modification or creation date of the client. This information is hard-coded into the client and helps to find out, what client version this is supposed to be. The first part (0x4ad4401b) is the raw representation of the time-stamp in seconds since 1.1.1970 00:00:00 UTC (Unix time-stamp), the second part (Tue Oct 13 10:53:47 2009) is the human-readable representation of the time-stamp. In this case, it indicates the use of 2009-10-13RagexeRE client. Since there are sometimes multiple clients with the same date, you have to check the exact time-stamp of the client. To see the time-stamp you have to load the client into a PE editor/analyser; LordPE and PEiD are capable of displaying those for example. Note, that the time stamp can be easily changed, so do not depend on it too much, when the executable is encrypted or otherwise protected.

Exception Type

Exception Type: 0xc0000005

This line indicates, what actually went wrong with the client. The most common exception is, like in this example, 0xc0000005 (EXCEPTION_ACCESS_VIOLATION), which means, that the client attempted to read from, write to or execute an invalid memory position (for example accessing members of a NULL pointer) or a memory location, which is not enabled for such access (for example writing in executable-only memory). Execution attempts (ex. malformed JMPs) are usually caught by the Data Execution Prevention in recent operating systems. All other exception codes can be looked up in winbase.h (if you have Windows SDK installed) and/or google for 'exception <exception code>' to get more information about the exception.

Call Stack

0x0042553b	091013RE.EXE
0x004364cc	091013RE.EXE
0x00449374	091013RE.EXE
0x0047bc23	091013RE.EXE
0x004e5460	091013RE.EXE
0x004f5b9c	091013RE.EXE
0x005f086f	091013RE.EXE
0x005efd89	091013RE.EXE
0x00517524	091013RE.EXE
0x006e22d0	091013RE.EXE
0x006f6b4c	091013RE.EXE
0xbff8b560	KERNEL32.DLL
0xbff8b412	KERNEL32.DLL
0xbff89dd5	KERNEL32.DLL
0x22220000	

This block is the call stack, which shows the path from the execution begin down (actually 'up' in this representation) to the function where the exception took place. The top-most entry is where the exception occurred, the last entry before KERNEL32.DLL or NTDLL.DLL is the first call after the module entry point of the module, or thread entry point in case of additional threads. If there is no module name next to the address, it means the address is bogus. If there is no KERNEL32.DLL or NTDLL.DLL module listed or no module names at all, the stack was most probably corrupt. You can locate the addresses by simply jumping inside your debugger to given offset.

Registers

eax: 0x00000000	ebx: 0x00000000
ecx: 0x00000000	edx: 0x00000012
esi: 0x00000012	edi: 0x00a9f7e8
ebp: 0x00a9f714	esp: 0x00a9f710

This block lists the processor register state at the point of the exception. When you have located the point, where the exception occurred, they help to figure out, what the client attempted to do. Here the client attempted to read from memory from position 0x00000114, which is obviously invalid (NULL pointer access):

MOV     EAX,DWORD PTR DS:[ECX+114]       ; ECX = 0x00000000
Since there is no further clue in the current function, how ECX became 0, you have to go back in the call stack.

Stack Dump

stack 00a9f710 - 00a9fb10
00A9F710 : 80 1B E8 03 24 F7 A9 00 CC 64 43 00 12 00 00 00
00A9F720 : 02 00 00 00 68 F7 A9 00 74 93 44 00 12 00 00 00
00A9F730 : 02 00 00 00 54 F7 A9 00 50 F7 A9 00 4C F7 A9 00
00A9F740 : B0 08 E8 03 00 00 00 00 80 1B E8 03 E8 F7 A9 00
00A9F750 : B0 08 E8 03 58 1C 6F 00 9C 00 00 00 3C F8 A9 00
00A9F760 : 68 6A 70 00 00 00 00 00 48 F8 A9 00 23 BC 47 00
00A9F770 : 78 00 00 00 B0 08 E8 03 18 01 00 00 00 00 00 00
00A9F780 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00A9F790 : 00 00 00 00 00 00 00 00 00 00 00 00 00 08 E8 03
00A9F7A0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 08 E8 03
00A9F7B0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 3A 40 00
00A9F7C0 : 00 00 00 00 00 00 00 00 00 00 00 00 40 60 74 00
00A9F7D0 : 48 60 74 00 54 60 74 00 14 60 74 00 04 60 74 00
00A9F7E0 : F4 5F 74 00 BD 00 00 00 60 00 00 00 EA 00 00 00
00A9F7F0 : 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00A9F800 : 00 00 00 00 79 00 00 00 7A 00 00 00 00 00 00 00

This block represents the stack at the point of the exception, with the top most line being the stack top. The contents are usually return addresses and function parameters. Typically you are not required to use this.

Launch Info

Launch Info
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000

This block is a history of recently displayed visual effects (g_recentEffectId), starting with the most recent effect id. Each block of 4 digits represents one effect id. Typically you are not required to use this.

Job

Job : Novice

This line indicates the last selected character job class. If the exception occurs before selecting a character, the value is, like in this case 'Novice'.

Summary

As seen in registers, the cause is not obvious after examining the function (CBitmapRes::GetColor), where the exception occured. When you examine the caller function (CSkinMgr::GetColorChipColor), you find out, that ECX is set to a return value of a function (CResMgr::Get) called before the function call, where the exception occurs. Digging in that function further gives you the clue, that the function does something with files, so you can bet on missing (or corrupt) files. In this case, you receive an error message right before the exception occurs, stating:

ResourceError : Can't find file À¯ÀúÀÎÅÍÆäÀ̽º\colorchip.bmp
These messages are almost always shown, if the exception is file related, so if you ever run into such problem, but are not the one, who experienced it, ask for the presence of this message; it will make debuggung easier. Note, that all the function names in this document can be found inside the 'Highpriest' client found on kRO FTP, because it includes debugging symbols. When you are able to match the code position in both clients, the function labels will help you figure out, what a function in question is for.

As of kRO 2011-08-23aRagexeRE and 2011-08-31aRagexe the client supports the in-game command /buildinfo that reports the client's build date, version and serial number:

build : Jul  2 2012 - 17:48:44
ver : 14.2.9
s/n : G3RX8UT-Z7EWZAS-TFXCLRK-T3YH8UT-5KHQDN8

Thanks to evilpuncker for making aware of this command.

Disclaimer

This document is supposed to serve for general educational purposes and is provided AS IS, without warranty of ANY KIND, either expressed or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose. The author cannot be made liable for actions, that can arise from the direct or indirect use of this document, including but not limited to modifications of the RO client or running private RO servers. The author cannot be made liable for ANY KIND of damages on software or hardware, that may arise from, including but not limited to use of this document, the mentioned software or websites contents this document links to.



© 2010-2016 Ai4rei/AN - This work is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License.
RagnarokOnline, Ragnarok-related graphics and materials are copyright © 2002-2016 Gravity Co., Ltd. Logo Gravity Co., Ltd. & Lee Myoungjin.