Load from Memory

JadeView 2.0 supports loading JAPK packages directly from memory, without a local file system. This is suitable for scenarios where JAPK data is embedded in an executable or used directly after being downloaded from the network.

This page describes the memory-loading APIs. To load from a local file, see Load from Local. To build an obfuscated JAPK package, use the JadePack desktop client.


Overview

JadeView_load_from_bytes loads a JAPK package from memory, detecting the package format via the magic number:

  • Only JAPK v2 signed packages are accepted, decrypted and loaded after verification against the JadeTweak platform root public key embedded in JadeView
  • The verification public key is compiled into the DLL; hosts do not need to (and cannot) inject one at runtime

💡 Tip: Both signed and obfuscated packages are built by JadePack. Memory loading only accepts signed packages; load obfuscated packages from a local file instead.

FormatMagic numberDescriptionBuild tool
JAPK v2 signed packageJAPKV002Ed25519 signature + AES-256-GCM encryptionJadePack
Obfuscated package v2JPKBIN02SHA256 dynamic key derivation + 3-layer reversible transformJadePack

Key security constraint: Memory loading only accepts JAPK v2 signed packages; a failed signature verification will never fall back to the obfuscated-package logic.


Core API

JadeView_load_from_bytes

Loads a JAPK package from memory.

C
int JadeView_load_from_bytes(const uint8_t* japk_data, size_t data_size);

Parameters:

  • japk_data uint8_t* - Pointer to the JAPK file data
  • data_size size_t - Data size (in bytes)

Return value:

  • 0 - Loaded successfully
  • Negative number - Error code; see the error code table below

Call order:

  1. JadeView_init — Initialize the runtime
  2. JadeView_load_from_bytes — Load the JAPK data

JadeView_is_loaded

Checks whether a JAPK package has been loaded successfully.

C
int JadeView_is_loaded(void);

Return value:

  • 1 - Loaded
  • 0 - Not loaded

JadeView_get_app_signature

Returns the app_signature set during JadeView_init (regardless of whether a package is loaded or its package type).

C
char* JadeView_get_app_signature(void);

Return value:

  • Non-NULL - The application identifier string; the caller must free it with jade_text_free

JadeView_get_signature_info

Returns the signature information JSON. Has a value only after a signed package has been loaded successfully.

C
char* JadeView_get_signature_info(void);

Return value:

  • Non-NULL - The signature information JSON string; the caller must free it with jade_text_free

JadeView_unload

Clears the loaded state and releases the in-memory JAPK data.

C
int JadeView_unload(void);

Error Codes

ValueConstantDescription
0JADEVIEW_JAPK_OKSuccess
-1JADEVIEW_JAPK_ERROR_INVALID_PARAMInvalid parameter (null pointer / size 0)
-2JADEVIEW_JAPK_ERROR_NOT_INITIALIZEDJadeView_init was not called
-3JADEVIEW_JAPK_ERROR_LOAD_FAILEDLoad failed
-4JADEVIEW_JAPK_ERROR_INVALID_FORMATInvalid / unsupported format
-5JADEVIEW_JAPK_ERROR_INVALID_SIGNATURESignature verification failed
-6JADEVIEW_JAPK_ERROR_APP_MISMATCHapp_signature/app_name mismatch
-7JADEVIEW_JAPK_ERROR_DECRYPT_FAILEDDecryption / deobfuscation failed
-8JADEVIEW_JAPK_ERROR_UNSIGNED_NOT_ALLOWEDSigned package is missing a signature
-9JADEVIEW_JAPK_ERROR_MISSING_PUBLIC_KEYPublic key not set
-10JADEVIEW_JAPK_ERROR_INVALID_PUBLIC_KEYInvalid public key format
-11JADEVIEW_JAPK_ERROR_POLICY_DENIEDDenied by security policy
-12JADEVIEW_JAPK_ERROR_NOT_LOADEDNot loaded

Events

The loading process is notified asynchronously via callbacks registered with jade_on:

japk-load-success

Triggered when loading succeeds; the callback receives JSON data:

JSON
{
  "app_signature": "com.example.app",
  "app_name": "MyApp",
  "asar_size": 1048576,
  "type": "signed"
}
FieldSigned packageObfuscated package
app_signature✓✗
app_name✓✗
asar_size✓✓
type"signed""scrambled"

japk-load-failed

Triggered when loading fails; the callback receives a plain-text error message, such as "Signature verification failed".


Usage Examples

C

C
#include "JadeView.h"

void load_from_memory_example() {
    // 1. Initialize
    JadeView_init(1, NULL, NULL, "MyApp", "com.example.app", 0);

    // 2. Read the JAPK file into memory
    FILE* f = fopen("app.japk", "rb");
    fseek(f, 0, SEEK_END);
    size_t size = ftell(f);
    fseek(f, 0, SEEK_SET);
    uint8_t* data = malloc(size);
    fread(data, 1, size, f);
    fclose(f);

    // 3. Load from memory (JAPK v2 signed package)
    int rc = JadeView_load_from_bytes(data, size);
    if (rc != 0) {
        printf("Load failed: %d\n", rc);
        free(data);
        return;
    }

    // 4. Get the protocol URL (pass an empty string for memory loading)
    char url_buffer[256];
    set_protocol_service_path("", url_buffer, sizeof(url_buffer), 0);  // 4th param hot_reload; pass 0 for memory loading
    // url_buffer content looks like: JADE://{app_signature}/ (app_signature is the 5th JadeView_init arg, lowercased)

    // 5. Create a window using that URL
    WebViewWindowOptions options = {
        .title = "JAPK Memory Load",
        .width = 800,
        .height = 600,
        .frame_style = "normal"
    };
    create_webview_window(url_buffer, 0, &options, NULL);

    free(data);
}

Python (ctypes)

Python
import ctypes
from ctypes import c_char_p, c_int, c_uint8, c_size_t, POINTER

dll = ctypes.WinDLL("JadeView.dll")

dll.JadeView_init.argtypes = [c_int, c_char_p, c_char_p, c_char_p, c_char_p, c_int]
dll.JadeView_init.restype = c_int

dll.JadeView_load_from_bytes.argtypes = [POINTER(c_uint8), c_size_t]
dll.JadeView_load_from_bytes.restype = c_int

dll.JadeView_is_loaded.argtypes = []
dll.JadeView_is_loaded.restype = c_int

# 1. Initialize
dll.JadeView_init(1, None, b"./data", b"MyApp", b"com.example.app", 0)

# 2. Read the JAPK into memory
with open("app.japk", "rb") as f:
    japk_data = f.read()

# 3. Load from memory (JAPK v2 signed package)
data_ptr = (c_uint8 * len(japk_data)).from_buffer_copy(japk_data)
rc = dll.JadeView_load_from_bytes(data_ptr, len(japk_data))
if rc != 0:
    raise RuntimeError(f"JadeView_load_from_bytes failed: {rc}")

# 4. Get the protocol URL (pass an empty string for memory loading)
dll.set_protocol_service_path.argtypes = [c_char_p, c_char_p, c_size_t, c_int]
dll.set_protocol_service_path.restype = c_int

url_buffer = ctypes.create_string_buffer(256)
dll.set_protocol_service_path(b"", url_buffer, 256, 0)  # 4th param hot_reload; pass 0 for memory loading
print(f"Protocol URL: {url_buffer.value.decode()}")

# 5. Create a window using that URL
loaded = dll.JadeView_is_loaded()
print(f"JAPK loaded: {loaded}")

Full Call Sequence

Markdown
Caller                          JadeView DLL
  │                                 │
  ├─ JadeView_init ────────────────►│ Initialize
  │                                 │
  ├─ jade_on("japk-load-success")──►│ Register success callback
  ├─ jade_on("japk-load-failed") ──►│ Register failure callback
  │                                 │
  ├─ JadeView_load_from_bytes ─────►│ Magic detection → signature verification/decryption → ASAR
  │                                 │
  │  ◄── japk-load-success ────────┤ Asynchronous event
  │                                 │
  ├─ set_protocol_service_path("")─►│ Get protocol URL
  │  ◄── url_buffer ───────────────┤ JADE://{app_signature}/
  │                                 │
  ├─ create_webview_window(url) ───►│ Create window
  │                                 │
  ├─ run_message_loop ─────────────►│ Enter the event loop