released :P

This commit is contained in:
Pari Malam
2026-06-15 19:22:35 +08:00
parent 2b1869e4a2
commit 8f40299adc
3 changed files with 316 additions and 13 deletions
+115
View File
@@ -0,0 +1,115 @@
# REST API Reference
All API endpoints are served from the web UI port. Authentication uses a JWT token passed via the `o11-token` localStorage key or `?token=` query parameter.
## Authentication
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/login` | Login with username/password, returns JWT token |
| POST | `/account/login` | Account login (provider script account) |
| POST | `/account/pairstart` | Start device pairing flow |
| POST | `/account/pairinput` | Submit pairing input |
| GET | `/account/pairstatus` | Check pairing status |
| POST | `/account/pairstop` | Stop pairing flow |
## Providers
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/providers` | List all providers |
| GET | `/provider/get` | Get provider details |
| POST | `/provider/add` | Add a new provider |
| POST | `/provider/edit` | Edit provider configuration |
| POST | `/provider/delete` | Delete a provider |
| POST | `/provider/import` | Import provider config |
| GET | `/provider/export` | Export provider config |
| GET | `/provider/exportkeys` | Export decryption keys |
| GET | `/provider/exportmanifestandkeys` | Export manifest + keys |
| POST | `/provider/pushkeys` | Push decryption keys to streams |
| POST | `/provider/rescan` | Rescan provider scripts |
| POST | `/provider/backup` | Backup provider data |
| POST | `/provider/cachelogos` | Cache provider logos |
| POST | `/provider/massupdate` | Bulk update providers |
| GET | `/provider/config` | Get provider configuration |
## Accounts
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/account/get` | Get account details |
| POST | `/account/add` | Add a script account |
| POST | `/account/edit` | Edit account |
| POST | `/account/disableall` | Disable all accounts |
## Streams
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/stream/status` | Get all stream statuses |
| GET | `/stream/get` | Get stream details |
| POST | `/stream/start` | Start a stream |
| POST | `/stream/add` | Add a new stream |
| POST | `/stream/refresh` | Refresh stream |
| POST | `/stream/refreshkeys` | Refresh decryption keys |
| POST | `/stream/flushkeys` | Flush key cache |
| POST | `/stream/stoprefresh` | Stop refreshing a stream |
## EPG
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/epg` | EPG overview |
| GET | `/epg/:provider?/:stream?` | EPG for specific provider/stream |
| GET | `/epg/get` | Get EPG data |
| POST | `/epg/refresh` | Trigger EPG refresh |
| POST | `/epg/refreshapply` | Refresh and apply EPG |
## Events & Recordings
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/events/:provider?` | List events for provider |
| GET | `/recordings/:provider?` | List recordings for provider |
| POST | `/recording/add` | Schedule a recording |
| POST | `/recording/edit` | Edit a recording |
| POST | `/recording/delete` | Delete a recording |
| POST | `/recording/stop` | Stop an active recording |
| GET | `/recording/get` | Get recording details |
| POST | `/replay/delete` | Delete a replay |
## Users & Servers
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/users` | List all users |
| POST | `/user/add` | Add a new user |
| POST | `/user/edit` | Edit user |
| POST | `/user/delete` | Delete user |
| GET | `/user/get` | Get user details |
| GET | `/servers` | List remote servers |
| POST | `/server/add` | Add a remote server |
## Jobs
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/jobs` | List all jobs |
| POST | `/job/add` | Add a job |
| POST | `/job/edit` | Edit a job |
| POST | `/job/delete` | Delete a job |
| POST | `/job/run` | Run a job |
## System
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/config` | Get server configuration |
| GET | `/bootstrap` | Bootstrap/init data for UI |
| GET | `/logos` | List available logos |
| GET | `/logos/:name` | Get logo image |
| POST | `/log/clean` | Clean old logs |
| GET | `/log/export` | Export logs |
| GET | `/search` | Search across streams |
| POST | `/refreshrequest` | Request data refresh |
| POST | `/shutdown` | Shutdown the server |
+119
View File
@@ -0,0 +1,119 @@
# Reverse Engineering
## Frontend Deobfuscation Analysis
The web UI JavaScript (`resources/index-BX-yLeHZ.js`) is obfuscated using **obfuscator.io** with the following techniques:
### Obfuscation Method
- **String Array**: 6,922 encoded strings stored in `o11_0xf6cf()` array
- **Decoder Function**: `o11_0x3b01(index)` — performs base64 decode followed by RC4 decryption
- **Control Flow Flattening**: All string references replaced with `o11_0x3b01(0xHEX)` calls
- **Dead Code Injection**: Anti-debug traps with `debugger` statements and `parseInt` chains
- **Self-Defending**: Checksum validation that crashes if the code is modified
### Deobfuscated Vue Components
| Component | Purpose |
|-----------|---------|
| `LoginView` | Authentication page |
| `ProvidersView` | Provider list and management |
| `LinearView` | Live stream channel grid |
| `EventsView` | Scheduled event streams |
| `VodView` | Video-on-demand browser |
| `RecordingsView` | Recording scheduler and manager |
| `MonitoringView` | Real-time stream monitoring |
| `LogsView` | Log viewer |
| `UsersView` | User administration |
| `ServerView` | Remote server management |
| `ConfigView` | Provider configuration |
| `StreamPlayer` | HLS.js embedded video player |
| `Mp4VideoPlayer` | MP4 playback for VOD downloads |
| `DropdownProviderSelector` | Provider dropdown filter |
| `StreamTypeSelector` | Stream type filter (linear/event/VOD) |
| `EpgTimezoneSelector` | EPG timezone picker |
| `DropdownTrackSelector` | Audio/subtitle track selector |
| `ItemProvider` | Provider list item |
| `ItemProviderAccount` | Script account item |
| `ItemStream` | Stream list item |
| `ItemStreamCompact` | Compact stream row |
| `ItemStreamConfig` | Stream configuration editor |
| `ItemEpg` | EPG program entry |
| `ItemVod` | VOD title entry |
| `ItemJob` | Scheduled job entry |
| `ItemServer` | Remote server entry |
| `ItemUser` | User management entry |
| `ItemMonitoring` | Monitoring status card |
| `ItemTableStreams` | Stream data table row |
| `ItemTableEpg` | EPG data table row |
| `ItemTableEvent` | Event data table row |
| `ItemTableRecording` | Recording data table row |
| `CheckBoxConfig` | Toggle config option |
| `ButtonDanger` | Destructive action button |
| `ButtonText` | Text-style action button |
| `ConfirmationModal` | Confirm dialog |
| `InformationModal` | Info dialog |
| `ServerInfoModal` | Server details dialog |
| `ServerSelector` | Remote server picker |
### Deobfuscated Config Sections
| Section ID | Purpose |
|------------|---------|
| `config-page` | Main config page |
| `config-script` | Provider script settings |
| `config-script-accounts` | Script account management |
| `config-update-channels` | Channel update/refresh settings |
| `config-epg-timezone` | EPG timezone configuration |
| `config-network-parameters` | Network/proxy settings |
| `config-additional-parameters` | Extra provider parameters |
| `config-stream-config` | Stream type and output mode |
| `config-stream-options` | Stream start/stop options |
| `config-manifest-script` | Manifest download script |
| `config-cdm-script` | CDM/DRM script settings |
| `config-modal-cdm-mode` | CDM mode selector |
| `config-modal-cdm-type` | CDM type selector |
| `config-events-channels-script` | Events/channels script settings |
| `config-channels` | Channel list editor |
| `config-hw-accel` | Hardware acceleration toggle |
### Provider JSON Schema (Deobfuscated)
```json
{
"ManifestUrl": "<manifest url>",
"Cdn": [
{
"Name": "akamai",
"ManifestUrl": "http://..."
}
],
"Headers": {
"manifest": {
"user-agent": "mozilla/5.0 ...",
"custom-header": "value"
},
"media": {
"user-agent": "mozilla/5.0 ...",
"custom-header": "value"
}
},
"Heartbeat": {
"Url": "<heartbeat url>",
"Params": ["param1", "param2"],
"PeriodMs": 300000
}
}
```
---
## TODO
- [ ] Full deobfuscation of `resources/index-BX-yLeHZ.js` — replace all `o11_0x3b01(0xHEX)` calls with decoded string literals for readability
- [ ] Reconstruct Vue SFC components from the flattened render functions
- [ ] Map all API endpoint handlers to their backend Go functions
- [ ] Reverse engineer the Go backend API handler routing logic
- [ ] Deobfuscate and document the provider script Python API (`scripts/o11.py`)
- [ ] Extract and analyze embedded Go symbol names (obfuscated with `ha4dhe`, `ijo4VwtOa`, etc.)
- [ ] Document the CDM integration flow (Widevine/PlayReady/Verimatrix)
- [ ] Analyze the internal remuxer pipeline (HLS → FMP4 conversion)
+82 -13
View File
@@ -4,6 +4,19 @@
---
## Tech Stack
| Layer | Technology | Details |
|-------|-----------|---------|
| **Backend** | **Golang** (Go) | ELF64 binary, CGo-linked (`libc`, `libpthread`, `libresolv`), statically compiled runtime with dynamic libc linking |
| **Frontend** | **Vue.js 3** | Composition API, `<script setup>` SFCs, Pinia state management, Vue Router |
| **HTTP Client** | **Axios** | API requests, JWT token auth |
| **Video Player** | **HLS.js** | In-browser HLS stream playback |
| **CSS** | **Tailwind CSS** | Utility-first classes throughout (`flex`, `gap-4`, `capitalize`, etc.) |
| **Obfuscation** | **obfuscator.io** | String array rotation + base64 + RC4 cipher, `o11_0x3b01` decoder function with 6,922 encoded strings |
---
## Quick Start
```bash
@@ -39,7 +52,7 @@ Open `http://<your-ip>:<port>` in a browser to access the web interface.
| Flag | Description | Default |
|------|-------------|---------|
| `-p` | **HTTP port** to listen on (required) | `0` (none - must be set) |
| `-p` | **HTTP port** to listen on (required) | `0` (none must be set) |
| `-b` | HTTP bind address | `0.0.0.0` (all interfaces) |
| `-https` | Enable HTTPS (requires `server.crt` and `server.key` in the O11 directory) | `false` |
| `-baseurl` | HTTP base URL (for reverse proxy setups) | *(empty)* |
@@ -53,8 +66,8 @@ Open `http://<your-ip>:<port>` in a browser to access the web interface.
| Flag | Description | Default |
|------|-------------|---------|
| `-user` | Static admin username for web UI login | *(empty - temp account generated)* |
| `-password` | Static admin password for web UI login | *(empty - temp account generated)* |
| `-user` | Static admin username for web UI login | *(empty temp account generated)* |
| `-password` | Static admin password for web UI login | *(empty temp account generated)* |
| `-jwtsecret` | JWT secret for login sessions. Default is randomly generated on each start | *(random)* |
### Configuration & Files
@@ -124,9 +137,9 @@ These options are used when downloading and converting VOD (Video On Demand) str
| Flag | Description | Default |
|------|-------------|---------|
| `-manifest` | Download and convert this manifest URL to MP4, then exit | *(empty)* |
| `-video` | Video track index to grab | *(empty - all)* |
| `-audio` | Audio track indexes to grab (comma-separated) | *(empty - all)* |
| `-subs` | Subtitle indexes to grab (comma-separated or `all`) | *(empty - none)* |
| `-video` | Video track index to grab | *(empty all)* |
| `-audio` | Audio track indexes to grab (comma-separated) | *(empty all)* |
| `-subs` | Subtitle indexes to grab (comma-separated or `all`) | *(empty none)* |
| `-extrasubs` | Extra subtitle file URL. Can be used multiple times | *(empty)* |
| `-maxsegments` | Max segments to download (`0` = unlimited) | `0` |
| `-dashperiod` | Force DASH period index. `-1` = all non-ad periods | `-2` |
@@ -146,6 +159,26 @@ These options are used when downloading and converting VOD (Video On Demand) str
---
## Web UI Pages
The Vue.js frontend provides the following pages accessible via the navigation sidebar:
| Page | Route | Description |
|------|-------|-------------|
| **Providers** | `/providers` | List of configured IPTV/OTT providers. Add, edit, delete, import, export providers |
| **Linear** | `/linear` | Live channel management. Start/stop streams, view on-air status |
| **Events** | `/events/:provider?` | Scheduled event streams with filtering and replay support |
| **VOD** | `/vod` | Video-on-demand library per provider. Download and convert to MP4 |
| **Recordings** | `/recordings/:provider?` | Manage stream recordings. Schedule and review recorded events |
| **Monitoring** | `/monitoring` | Real-time stream status overview, running streams dashboard |
| **Logs** | `/logs/:provider?/:stream?` | Per-channel and main log viewer. Export and clean logs |
| **Users** | `/users` | User management. Create/edit users, set admin, assign provider access |
| **Config** | `/config` | Provider configuration (script, CDM, network, channels, stream options) |
| **Help** | `/help` | Built-in documentation with table of contents |
| **Login** | `/login` | Authentication page. JWT-based token auth |
---
## Examples
### Basic IPTV Proxy
@@ -221,11 +254,23 @@ Access via `https://localhost:8443`.
When using `-path`, O11 creates the following sub-directories:
```
<path>/
o11pro-unpacked/
├── hls/
── live/ # Live HLS segments (recommend RAMFS)
── live/ # Live HLS segments (recommend RAMFS)
│ ├── replay/ # Replayed stream segments
│ └── vod/ # VOD stream segments
├── dl/
│ └── tmp/ # VOD download temp files
├── epg/ # EPG data cache
├── fonts/ # Custom fonts
├── logos/ # Channel/provider logos
├── logs/ # Rotating log files
├── providers/ # Provider configuration files
├── manifests/ # Downloaded manifest cache
├── offair/ # Off-air placeholder media
├── overlay/ # Picture overlays for streams
├── providers/ # Provider configuration files & scripts
├── rec/ # Recording output files
├── scripts/ # CDM scripts (o11.py auto-generated)
├── keys.txt # KID:KEY decryption fallback
├── o11.cfg # Main configuration
├── o11-job.cfg # Jobs configuration
@@ -234,6 +279,30 @@ When using `-path`, O11 creates the following sub-directories:
---
## EPG Access
O11 serves EPG data in multiple formats:
| Format | URL |
|--------|-----|
| XML (gzip) | `http://ip:epgport/providerid.xml.gz` |
| XML (plain) | `http://ip:epgport/providerid.xml` |
| Web UI | `http://ip:port/epg` |
| API | `GET /epg/:provider?/:stream?` |
Use the `-epgport` flag to enable the EPG endpoint.
---
## Playlist Access
Streams are accessible via playlist format. The `-plstreamname` flag controls the display name format:
- Default: `[%p] %s` shows `[ProviderName] StreamName`
- Custom: `-plstreamname "%s (%p)"` shows `StreamName (ProviderName)`
---
## Log Levels Reference
| Level | Name | Description |
@@ -248,12 +317,12 @@ When using `-path`, O11 creates the following sub-directories:
---
## Notes
- resources/ is a embedded content from the unpacked binary
- **The `-p` flag is required.** The binary will not start without an HTTP port.
- Without `-user` / `-password`, a temporary admin account is generated on each start and printed to the log.
- For HTTPS, both `server.crt` and `server.key` must exist in the O11 working directory.
- The `-key` flag accepts KID:KEY pairs in hex format and can be specified multiple times for multiple keys.
- The `-H` flag for custom headers can be repeated: `-H "Authorization:Bearer token" -H "X-Custom:value"`.
- VOD downloader mode (`-manifest`) downloads, converts, and exits - it does not start the server.
---
- VOD downloader mode (`-manifest`) downloads, converts, and exits it does not start the server.
- Script accounts use the format: `user=join@mail.com password=mypassword device=123456 pin=1234`
- Proxy support: `http://user:pass@ip:port` and `socks5://user:pass@ip:port`