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

Function __fix_loadlit

app/src/main/cpp/And64InlineHook.cpp:248–325  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

246//-------------------------------------------------------------------------
247
248static bool __fix_loadlit(instruction inpp, instruction outpp, context *ctxp) {
249 const uint32_t ins = *(*inpp);
250
251 // memory prefetch("prfm"), just skip it
252 // http://infocenter.arm.com/help/topic/com.arm.doc.100069_0608_00_en/pge1427897420050.html
253 if ((ins & 0xff000000u) == 0xd8000000u) {
254 ctxp->process_fix_map(ctxp->get_and_set_current_index(*inpp, *outpp));
255 ++(*inpp);
256 return true;
257 } //if
258
259 constexpr uint32_t msb = 8u;
260 constexpr uint32_t lsb = 5u;
261 constexpr uint32_t mask_30 = 0x40000000u; // 0b01000000000000000000000000000000
262 constexpr uint32_t mask_31 = 0x80000000u; // 0b10000000000000000000000000000000
263 constexpr uint32_t lmask = 0xff00001fu; // 0b11111111000000000000000000011111
264 constexpr uint32_t mask_ldr = 0xbf000000u; // 0b10111111000000000000000000000000
265 constexpr uint32_t op_ldr = 0x18000000u; // 0b00011000000000000000000000000000 "LDR Wt/Xt, label" | ADDR_PCREL19
266 constexpr uint32_t mask_ldrv = 0x3f000000u; // 0b00111111000000000000000000000000
267 constexpr uint32_t op_ldrv = 0x1c000000u; // 0b00011100000000000000000000000000 "LDR St/Dt/Qt, label" | ADDR_PCREL19
268 constexpr uint32_t mask_ldrsw = 0xff000000u; // 0b11111111000000000000000000000000
269 constexpr uint32_t op_ldrsw = 0x98000000u; // "LDRSW Xt, label" | ADDR_PCREL19 | load register signed word
270 // LDR S0, #0 | 0b00011100000000000000000000000000 | 32-bit
271 // LDR D0, #0 | 0b01011100000000000000000000000000 | 64-bit
272 // LDR Q0, #0 | 0b10011100000000000000000000000000 | 128-bit
273 // INVALID | 0b11011100000000000000000000000000 | may be 256-bit
274
275 uint32_t mask = mask_ldr;
276 uintptr_t faligned = (ins & mask_30) ? 7u : 3u;
277 if ((ins & mask_ldr) != op_ldr) {
278 mask = mask_ldrv;
279 if (faligned != 7u)
280 faligned = (ins & mask_31) ? 15u : 3u;
281 if ((ins & mask_ldrv) != op_ldrv) {
282 if ((ins & mask_ldrsw) != op_ldrsw) {
283 return false;
284 } //if
285 mask = mask_ldrsw;
286 faligned = 7u;
287 } //if
288 } //if
289
290 intptr_t current_idx = ctxp->get_and_set_current_index(*inpp, *outpp);
291 int64_t absolute_addr = reinterpret_cast<int64_t>(*inpp) +
292 ((static_cast<int32_t>(ins << msb) >> (msb + lsb - 2u)) & ~3u);
293 int64_t new_pc_offset =
294 static_cast<int64_t>(absolute_addr - reinterpret_cast<int64_t>(*outpp)) >> 2; // shifted
295 bool special_fix_type = ctxp->is_in_fixing_range(absolute_addr);
296 // special_fix_type may encounter issue when there are mixed data and code
297 if (special_fix_type || (llabs(new_pc_offset) + (faligned + 1u - 4u)) > (~lmask >> lsb)) {
298 while ((reinterpret_cast<uint64_t>(*outpp + 2) & faligned) != 0u) {
299 *(*outpp)++ = A64_NOP;
300 }
301 ctxp->reset_current_ins(current_idx, *outpp);
302
303 // Note that if memory at absolute_addr is writeable (non-const), we will fail to fetch it.
304 // And what's worse, we may unexpectedly overwrite something if special_fix_type is true...
305 uint32_t ns = static_cast<uint32_t>((faligned + 1) / sizeof(uint32_t));

Callers 1

__fix_instructionsFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected