MCPcopy Create free account
hub / github.com/WrBug/dumpDex / __fix_pcreladdr

Function __fix_pcreladdr

app/src/main/cpp/And64InlineHook.cpp:329–424  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

327//-------------------------------------------------------------------------
328
329static bool __fix_pcreladdr(instruction inpp, instruction outpp, context *ctxp) {
330 // Load a PC-relative address into a register
331 // http://infocenter.arm.com/help/topic/com.arm.doc.100069_0608_00_en/pge1427897645644.html
332 constexpr uint32_t msb = 8u;
333 constexpr uint32_t lsb = 5u;
334 constexpr uint32_t mask = 0x9f000000u; // 0b10011111000000000000000000000000
335 constexpr uint32_t rmask = 0x0000001fu; // 0b00000000000000000000000000011111
336 constexpr uint32_t lmask = 0xff00001fu; // 0b11111111000000000000000000011111
337 constexpr uint32_t fmask = 0x00ffffffu; // 0b00000000111111111111111111111111
338 constexpr uint32_t max_val = 0x001fffffu; // 0b00000000000111111111111111111111
339 constexpr uint32_t op_adr = 0x10000000u; // "adr" Rd, ADDR_PCREL21
340 constexpr uint32_t op_adrp = 0x90000000u; // "adrp" Rd, ADDR_ADRP
341
342 const uint32_t ins = *(*inpp);
343 intptr_t current_idx;
344 switch (ins & mask) {
345 case op_adr: {
346 current_idx = ctxp->get_and_set_current_index(*inpp, *outpp);
347 int64_t lsb_bytes = static_cast<uint32_t>(ins << 1u) >> 30u;
348 int64_t absolute_addr = reinterpret_cast<int64_t>(*inpp) +
349 (((static_cast<int32_t>(ins << msb) >> (msb + lsb - 2u)) &
350 ~3u) | lsb_bytes);
351 int64_t new_pc_offset = static_cast<int64_t>(absolute_addr -
352 reinterpret_cast<int64_t>(*outpp));
353 bool special_fix_type = ctxp->is_in_fixing_range(absolute_addr);
354 if (!special_fix_type && llabs(new_pc_offset) > max_val) {
355 if ((reinterpret_cast<uint64_t>(*outpp + 2) & 7u) != 0u) {
356 (*outpp)[0] = A64_NOP;
357 ctxp->reset_current_ins(current_idx, ++(*outpp));
358 } //if
359
360 (*outpp)[0] =
361 0x58000000u | (((8u >> 2u) << lsb) & ~mask) | (ins & rmask); // LDR #0x8
362 (*outpp)[1] = 0x14000003u; // B #0xc
363 memcpy(*outpp + 2, &absolute_addr, sizeof(absolute_addr));
364 *outpp += 4;
365 } else {
366 if (special_fix_type) {
367 intptr_t ref_idx = ctxp->get_ref_ins_index(absolute_addr & ~3ull);
368 if (ref_idx <= current_idx) {
369 new_pc_offset = static_cast<int64_t>(ctxp->dat[ref_idx].ins -
370 reinterpret_cast<int64_t>(*outpp));
371 } else {
372 ctxp->insert_fix_map(ref_idx, *outpp, lsb, fmask);
373 new_pc_offset = 0;
374 } //if
375 } //if
376
377 // the lsb_bytes will never be changed, so we can use lmask to keep it
378 (*outpp)[0] = (static_cast<uint32_t>(new_pc_offset << (lsb - 2u)) & fmask) |
379 (ins & lmask);
380 ++(*outpp);
381 } //if
382 }
383 break;
384 case op_adrp: {
385 current_idx = ctxp->get_and_set_current_index(*inpp, *outpp);
386 int32_t lsb_bytes = static_cast<uint32_t>(ins << 1u) >> 30u;

Callers 1

__fix_instructionsFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected