mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-01-28 22:01:50 +00:00
android: improve hooking
set desired flow control mode to basic because for android checking once isn't enough. even after calling l2c_fcr_chk_chan, it again compares the desired and the peer's supported channel modes.
This commit is contained in:
@@ -33,8 +33,111 @@ static HookFunType hook_func = nullptr;
|
||||
|
||||
static uint8_t (*original_l2c_fcr_chk_chan_modes)(void* p_ccb) = nullptr;
|
||||
|
||||
uint8_t fake_l2c_fcr_chk_chan_modes([[maybe_unused]] void* p_ccb) {
|
||||
LOGI("l2c_fcr_chk_chan_modes hooked! Always returning true");
|
||||
// Define all necessary structures for the L2CAP stack
|
||||
|
||||
// Define base FCR structure
|
||||
typedef struct {
|
||||
uint8_t mode;
|
||||
uint8_t tx_win_sz;
|
||||
uint8_t max_transmit;
|
||||
uint16_t rtrans_tout;
|
||||
uint16_t mon_tout;
|
||||
uint16_t mps;
|
||||
} tL2CAP_FCR;
|
||||
|
||||
// Flow spec structure
|
||||
typedef struct {
|
||||
uint8_t qos_present;
|
||||
uint8_t flow_direction;
|
||||
uint8_t service_type;
|
||||
uint32_t token_rate;
|
||||
uint32_t token_bucket_size;
|
||||
uint32_t peak_bandwidth;
|
||||
uint32_t latency;
|
||||
uint32_t delay_variation;
|
||||
} FLOW_SPEC;
|
||||
|
||||
// Configuration info structure
|
||||
typedef struct {
|
||||
uint16_t result;
|
||||
uint16_t mtu_present;
|
||||
uint16_t mtu;
|
||||
uint16_t flush_to_present;
|
||||
uint16_t flush_to;
|
||||
uint16_t qos_present;
|
||||
FLOW_SPEC qos;
|
||||
uint16_t fcr_present;
|
||||
tL2CAP_FCR fcr;
|
||||
uint16_t fcs_present;
|
||||
uint16_t fcs;
|
||||
uint16_t ext_flow_spec_present;
|
||||
FLOW_SPEC ext_flow_spec;
|
||||
} tL2CAP_CFG_INFO;
|
||||
|
||||
// Basic L2CAP link control block
|
||||
typedef struct {
|
||||
bool wait_ack;
|
||||
// Other FCR fields - not needed for our specific hook
|
||||
} tL2C_FCRB;
|
||||
|
||||
// Forward declarations for needed types
|
||||
struct t_l2c_rcb;
|
||||
struct t_l2c_lcb;
|
||||
|
||||
typedef struct t_l2c_ccb {
|
||||
struct t_l2c_ccb* p_next_ccb; // Next CCB in the chain
|
||||
struct t_l2c_ccb* p_prev_ccb; // Previous CCB in the chain
|
||||
struct t_l2c_lcb* p_lcb; // Link this CCB belongs to
|
||||
struct t_l2c_rcb* p_rcb; // Registration CB for this Channel
|
||||
|
||||
uint16_t local_cid; // Local CID
|
||||
uint16_t remote_cid; // Remote CID
|
||||
uint16_t p_lcb_next; // For linking CCBs to an LCB
|
||||
|
||||
uint8_t ccb_priority; // Channel priority
|
||||
uint16_t tx_mps; // MPS for outgoing messages
|
||||
uint16_t max_rx_mtu; // Max MTU we will receive
|
||||
|
||||
// State variables
|
||||
bool in_use; // True when channel active
|
||||
uint8_t chnl_state; // Channel state
|
||||
uint8_t local_id; // Transaction ID for local trans
|
||||
uint8_t remote_id; // Transaction ID for remote
|
||||
|
||||
uint8_t timer_entry; // Timer entry
|
||||
uint8_t is_flushable; // True if flushable
|
||||
|
||||
// Configuration variables
|
||||
uint16_t our_cfg_bits; // Bitmap of local config bits
|
||||
uint16_t peer_cfg_bits; // Bitmap of peer config bits
|
||||
uint16_t config_done; // Configuration bitmask
|
||||
uint16_t remote_config_rsp_result; // Remote config response result
|
||||
|
||||
tL2CAP_CFG_INFO our_cfg; // Our saved configuration options
|
||||
tL2CAP_CFG_INFO peer_cfg; // Peer's saved configuration options
|
||||
|
||||
// Additional control fields
|
||||
uint8_t remote_credit_count; // Credits sent to peer
|
||||
tL2C_FCRB fcrb; // FCR info
|
||||
bool ecoc; // Enhanced Credit-based mode
|
||||
} tL2C_CCB;
|
||||
|
||||
uint8_t fake_l2c_fcr_chk_chan_modes(void* p_ccb) {
|
||||
LOGI("l2c_fcr_chk_chan_modes hooked");
|
||||
|
||||
auto* ccb = static_cast<tL2C_CCB*>(p_ccb);
|
||||
|
||||
LOGI("Original FCR mode: 0x%02x", ccb->our_cfg.fcr.mode);
|
||||
|
||||
ccb->our_cfg.fcr.mode = 0;
|
||||
|
||||
ccb->our_cfg.fcr_present = true;
|
||||
|
||||
ccb->peer_cfg.fcr.mode = 0;
|
||||
ccb->peer_cfg.fcr_present = true;
|
||||
|
||||
LOGI("FCR mode set to Basic Mode (0) for both local and peer config, here's the new desired FCR mode: 0x%02x, and the peer's FCR mode: 0x%02x", ccb->our_cfg.fcr.mode, ccb->peer_cfg.fcr.mode);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -46,20 +149,26 @@ uintptr_t loadHookOffset([[maybe_unused]] const char* package_name) {
|
||||
if (len > 0) {
|
||||
LOGI("Read hook offset from property: %s", value);
|
||||
|
||||
uintptr_t offset = 0;
|
||||
uintptr_t offset;
|
||||
char* endptr = nullptr;
|
||||
|
||||
const char* parse_start = value;
|
||||
if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) {
|
||||
sscanf(value + 2, "%x", &offset);
|
||||
} else {
|
||||
sscanf(value, "%x", &offset);
|
||||
parse_start = value + 2;
|
||||
}
|
||||
|
||||
if (offset > 0) {
|
||||
errno = 0;
|
||||
offset = strtoul(parse_start, &endptr, 16);
|
||||
|
||||
if (errno == 0 && endptr != parse_start && *endptr == '\0' && offset > 0) {
|
||||
LOGI("Parsed offset: 0x%x", offset);
|
||||
return offset;
|
||||
}
|
||||
|
||||
LOGE("Failed to parse offset from property value: %s", value);
|
||||
}
|
||||
|
||||
LOGI("Failed to read offset from property, using hardcoded fallback");
|
||||
LOGI("Using hardcoded fallback offset");
|
||||
return 0x00a55e30;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user