Darwin [dyld] Tips
jmpews opened this issue · 0 comments
Prologue
Somniloquy
1. Dyld 中有一些 Macho 文件格式描述的文件, 适合用来做 parser | Tag: [parser
]
dyld-519.2.1/launch-cache/MachOFileAbstraction.hpp
dyld-519.2.1/launch-cache/MachOLayout.hpp
dyld-519.2.1/launch-cache/FileAbstraction.hpp
dyld-519.2.1/launch-cache/Architectures.hpp
2. ARM64 下的 macho-segment 必须做 dyld_page_round
对齐, 也就是 0x4000 | Tag: [brute-force
]
具体参考:
// dyld-519.2.1/src/ImageLoaderMachO.cpp
intptr_t ImageLoaderMachO::assignSegmentAddresses(const LinkContext& context)
{
// preflight and calculate slide if needed
const bool inPIE = (fgNextPIEDylibAddress != 0);
intptr_t slide = 0;
if ( this->segmentsCanSlide() && this->segmentsMustSlideTogether() ) {
bool needsToSlide = false;
bool imageHasPreferredLoadAddress = segHasPreferredLoadAddress(0);
uintptr_t lowAddr = (unsigned long)(-1);
uintptr_t highAddr = 0;
for(unsigned int i=0, e=segmentCount(); i < e; ++i) {
const uintptr_t segLow = segPreferredLoadAddress(i);
// <<Tips>> set segment map end address with round(segSeize(i))
const uintptr_t segHigh = dyld_page_round(segLow + segSize(i));
if ( segLow < highAddr ) {
if ( dyld_page_size > 4096 )
dyld::throwf("can't map segments into 16KB pages");
else
dyld::throwf("overlapping segments");
}
if ( segLow < lowAddr )
lowAddr = segLow;
if ( segHigh > highAddr )
highAddr = segHigh;
if ( needsToSlide || !imageHasPreferredLoadAddress || inPIE || !reserveAddressRange(segPreferredLoadAddress(i), segSize(i)) )
needsToSlide = true;
}
if ( needsToSlide ) {
// find a chunk of address space to hold all segments
uintptr_t addr = reserveAnAddressRange(highAddr-lowAddr, context);
slide = addr - lowAddr;
}
}
3. 可以通过 removeImageFromAllImages
将一个 dylib 的信息从 dyld_all_image_infos
的 vector list 中逻辑删除 | Tag: [inject-detect-bypass
, jailbreak-detect-bypass
]
这是一个未保留的函数, 可以从两个角度进行调用.
- parse dyld, search symbol table
dyld_load_address
+function_offset
(hardcode)
4. Convert macho executable to dyld | Tag: [reverse
]
- remove
__PAGEZERO
ref: blog.imjun.net/posts/convert-iOS-app-to-dynamic-library/
- hook dyld load check Function
ref: http://iosre.com/t/pagezero/10249/7
5. dyld 的 lazy bind 函数 dyld_stub_binder
| Tag: [context-save
]
refer: /Users/jmpews/Downloads/dyld-433.5/src/dyld_stub_binder.s
#if __arm64__
/*
* sp+0 lazy binding info offset
* sp+8 address of ImageLoader cache
*/
.text
.align 2
.globl dyld_stub_binder
dyld_stub_binder:
stp fp, lr, [sp, #-16]!
mov fp, sp
sub sp, sp, #240
stp x0,x1, [fp, #-16] ; x0-x7 are int parameter registers
stp x2,x3, [fp, #-32]
stp x4,x5, [fp, #-48]
stp x6,x7, [fp, #-64]
stp x8,x9, [fp, #-80] ; x8 is used for struct returns
stp q0,q1, [fp, #-128] ; q0-q7 are vector/fp parameter registers
stp q2,q3, [fp, #-160]
stp q4,q5, [fp, #-192]
stp q6,q7, [fp, #-224]
ldr x0, [fp, #24] ; move address ImageLoader cache to 1st parameter
ldr x1, [fp, #16] ; move lazy info offset 2nd parameter
; call dyld::fastBindLazySymbol(loadercache, lazyinfo)
bl __Z21_dyld_fast_stub_entryPvl
mov x16,x0 ; save target function address in lr
; restore parameter registers
ldp x0,x1, [fp, #-16]
ldp x2,x3, [fp, #-32]
ldp x4,x5, [fp, #-48]
ldp x6,x7, [fp, #-64]
ldp x8,x9, [fp, #-80]
ldp q0,q1, [fp, #-128]
ldp q2,q3, [fp, #-160]
ldp q4,q5, [fp, #-192]
ldp q6,q7, [fp, #-224]
mov sp, fp
ldp fp, lr, [sp], #16
add sp, sp, #16 ; remove meta-parameters
br x16
#endif