O2JamO2 Launch Arguments

Overview

O2JamO2 Client (v5.89 — Client/Distribution ID: 726PNA-B1YW-28ZG9M-I5SC-Q0OPM6) is one of two O2Jam Classic clients released by NOWCOM after X2 was terminated. In addition to reworked interfaces, 3K Mode was introduced late into the update iteration, right before the major UI revamp.

O2JamO2
Figure 1. Planet selection of O2JamO2 client.

It is important to note that 3K Mode introduction is considered major version update within this client sub-version. This is also affect launch arguments:

  • Old: Plain text
  • New: Encrypted with RSA (using slightly different keys than O2Jam Classic)

The client is unfortunately keep using the same Client/Distribution ID throughout its O2JamO2 lifetime.
This document focuses on the plain text arguments (the older client version).

Command-Line Parsing

The sub_541580 is the primary command-line parser. It is called by sub_542540, which itself is a thin wrapper function that validate against empty args before calling the actual parser logic and invoked by WinMain when the process receives a non-empty lpCmdLine.

When the official service was running, the game was launched via ActiveX from NOWCOM’s web portal, which passed all connection parameters as a command-line string.

If sub_542540 returns 0 (failure), WinMain shows a Korean error message: “홈페이지에서 로그인 후 GameStart를 실행하세요!” (“Please log in from the homepage and run GameStart!”) and exits.


Command-Line Format

OTwo.exe <mode> <unk1> <user_id> <service_name> <password> <gender> <gem> <ftp_host:ftp_port> <ftp_path> <num_servers> [<server_ip> <server_port>]...

Example

OTwo.exe INET 0 khzero76 O2Jam mypassword 1 50000 filedown2.o2jam.com:21 O2Jam/ 2 221.132.84.4 15010 218.50.4.176 15010

Parameters

Service Mode

The first token is compared against two known mode strings:

Service Mode Value Description
O2_INET 0 Older NOWCOM style; gender passed as "m"/"f" string
INET 1 Newer NOWCOM style; gender passed as numeric 1/2

If the first token is neither O2_INET nor INET, the parse function implied to silently do nothing. Since those locals are uninitialized, the behaviour in this case is undefined.

Unknown Flag

It is parsed as long, stored on the stack, and never consumed. The original game launcher pass 1 as the value.

User ID

A null-terminated string username of the account. The maximum length is 64 bytes and it is to be sent in login packet (opcode 1000).

Buffer overflow happen when the maximum length is not respected. The password will be appended right after the username in the login packet.

Service Name

Retrieved but never stored or used. The original game launcher pass O2Jam as the value.

Password

A null-terminated string password of the account.

By default, the password is never included anywhere in the network payload. But when user id buffer overflow happen, it will appended right after the username.

Gender

The interpretation depends on the client mode set by <mode>

  • O2_INET: The value is a string; m for male, f for female.
  • INET: The value is a numeric string; 1 for male, 2 for female. Internally, it is converted via atol and the corresponding letter (m or f) is stored instead of the number.

Gem

This is the player’s Gem balance passed from the web portal, which converted and stored as long via atol. The value is likely to be overwritten by room or shop related packet in the game.

It is very-likely a leftover from X2 where the player Gemstar is displayed in the server selection.

FTP

FTP Host, port and path for music download. The original full address is assumed to be filedown2.o2jam.com:21/O2Jam/. Note that FTP port (e.g, :21) is optional and will assume to have value 21 if left unspecified.

Game servers

The number of server followed by pair of server ip address and port separated by space. This format is consistent with previous O2Jam clients.

Development leftover functions

A separate, unreferenced dispatch function exists at sub_542510 with no xrefs. It was likely a development/debugging launcher that was superseded by the ActiveX + cmdline path.

This dispatch checks whether an argument string is provided:

Condition Function Called Behaviour
Empty/no argument sub_541AE0 Read servers from INI (up to 6 entries)
Non-empty argument sub_541FA0 Ignore argument; hardcode Korean servers

Both functions force mode to 1 (INET) and read credentials from .\Identifaction.ini.

Note: The filename is misspelled as Identifaction.ini (missing the second i in “Identification”) in the binary itself. This typo appears in the string literal.

INI File Format

The file uses the standard Windows INI format, read via GetPrivateProfileStringA.

Validation

Both functions first call GetPrivateProfileStringA(NULL, NULL, NULL, buf, 256, path); passing all NULLs for section and key enumerates all section names. If the return value is 0 (no sections found / file missing), a MessageBox is shown:

  • Message: “오투잼 ID를 입력” (“Enter O2Jam ID”)
  • Title: “총인자” (“Total Arguments”)

And the function returns without further initialization.

Section: [IDENTIFICATION]

All fields reside under a single section called IDENTIFICATION.

Credential Fields

The credential keys vary by mode, but since both INI functions force mode = 1 (INET), only the mode-1 keys are reachable in practice. The mode-0 keys are dead code within the INI paths but documented here for completeness.

Mode Key Default Value Max Length Stored To Actual Meaning
0 USER_ID1 khzero_o2 256 chars Data (0x6B91CB) User ID
0 PASSWORD1 m 256 chars byte_6B922B Gender ("m" or "f")
1 USER_ID khzero76 256 chars Data (0x6B91CB) User ID
1 PASSWORD m 256 chars byte_6B922B Gender ("m" or "f")

Despite the key names PASSWORD / PASSWORD1, the values are stored to the gender field. The default value "m". These are not actual passwords; the naming is misleading (likely a leftover from an earlier design where authentication credentials were read from the INI).

The default user IDs khzero_o2 and khzero76 are likely developer test account.

Server Fields

These fields are only read by sub_541AE0 (the “empty argument” path). sub_541FA0 hardcodes servers instead.

The function reads up to 6 server entries using generated key names IP<n> and PORT<n>:

Key Default Value Description
IP1 221.132.84.4 Server 1 IP address
PORT1 15010 Server 1 port
IP2 221.132.84.4 Server 2 IP address
PORT2 15010 Server 2 port
IP3 221.132.84.4 Server 3 IP address
PORT3 15010 Server 3 port
IP4 221.132.84.4 Server 4 IP address
PORT4 15010 Server 4 port
IP5 221.132.84.4 Server 5 IP address
PORT5 15010 Server 5 port
IP6 221.132.84.4 Server 6 IP address
PORT6 15010 Server 6 port

Each IP is read as a string (buffer size 64 chars). Each PORT is read as a string (buffer size 12 chars) and converted via atol.

Hardcoded Values

After reading the INI, both functions set the following fields to hardcoded values; these are not read from the INI:

Field Value in sub_541AE0 Value in sub_541FA0
Host string (obj+0x114) filedown2.o2jam.com filedown2.o2jam.com
FTP path (obj+0x514) O2Jam/ ./
Client mode (obj+0x30) 1 (INET) 1 (INET)

Note that neither INI function sets the GEM balance (dword_6B927C), the port field (obj+0x914), or the password global (byte_6B920B). These remain at their zero-initialized defaults.

Example Identifaction.ini

[IDENTIFICATION]
USER_ID=khzero76
PASSWORD=m
IP1=221.132.84.4
PORT1=15010
IP2=218.50.4.176
PORT2=15010
IP3=218.50.4.177
PORT3=15011
IP4=218.50.4.178
PORT4=15011
IP5=221.132.84.4
PORT5=15010
IP6=218.50.4.181
PORT6=15013

Hardcoded Korean Servers

sub_541FA0 ignores both its argument and the INI server keys, instead hardcoding 7 NOWCOM production server entries:

# IP Port Object Offset
0 221.132.84.4 15010 +0xB0
1 218.50.4.176 15010 +0xC0
2 218.50.4.177 15011 +0xD0
3 218.50.4.178 15011 +0xE0
4 221.132.84.4 15010 +0xF0
5 218.50.4.181 15013 +0x100
6 218.50.4.188 15014 +0x110