mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-25 17:00:36 -09:00
Merge remote-tracking branch 'origin/GP-4380_ryanmkurtz_dyld-slide5'
This commit is contained in:
@@ -112,7 +112,7 @@ public class DyldCacheSlideInfo3 extends DyldCacheSlideInfoCommon {
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks the pointer chain at the given reader offset to find necessary {@link DyldFixup}s
|
||||
* Walks the pointer chain at the given reader offset to find necessary {@link DyldFixup}s
|
||||
*
|
||||
* @param segmentOffset The segment offset
|
||||
* @param pageOffset The page offset
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.macho.dyld;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.macho.MachConstants;
|
||||
import ghidra.app.util.bin.format.macho.dyld.DyldChainedPtr.DyldChainType;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Represents a dyld_cache_slide_info5 structure.
|
||||
* <p>
|
||||
* Seen in macOS 14.4 and later.
|
||||
*/
|
||||
public class DyldCacheSlideInfo5 extends DyldCacheSlideInfoCommon {
|
||||
|
||||
private static final int DYLD_CACHE_SLIDE_V5_PAGE_ATTR_NO_REBASE = 0xFFFF;
|
||||
private static final DyldChainType TYPE = DyldChainType.DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE;
|
||||
|
||||
private int pageSize;
|
||||
private int pageStartsCount;
|
||||
private long valueAdd;
|
||||
private short[] pageStarts;
|
||||
|
||||
/**
|
||||
* {@return The page size}
|
||||
*/
|
||||
public int getPageSize() {
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return The page starts count}
|
||||
*/
|
||||
public int getPageStartsCount() {
|
||||
return pageStartsCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return The "value add"}
|
||||
*/
|
||||
public long getValueAdd() {
|
||||
return valueAdd;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return The page starts array}
|
||||
*/
|
||||
public short[] getPageStarts() {
|
||||
return pageStarts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link DyldCacheSlideInfo5}.
|
||||
*
|
||||
* @param reader A {@link BinaryReader} positioned at the start of a DYLD slide info 5
|
||||
* @param mappingAddress The base address of where the slide fixups will take place
|
||||
* @param mappingSize The size of the slide fixups block
|
||||
* @param mappingFileOffset The base file offset of where the slide fixups will take place
|
||||
* @throws IOException if there was an IO-related problem creating the DYLD slide info 5
|
||||
*/
|
||||
public DyldCacheSlideInfo5(BinaryReader reader, long mappingAddress, long mappingSize,
|
||||
long mappingFileOffset) throws IOException {
|
||||
super(reader, mappingAddress, mappingSize, mappingFileOffset);
|
||||
pageSize = reader.readNextInt();
|
||||
pageStartsCount = reader.readNextInt();
|
||||
reader.readNextInt(); // padding
|
||||
valueAdd = reader.readNextLong();
|
||||
pageStarts = reader.readNextShortArray(pageStartsCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DyldFixup> getSlideFixups(BinaryReader reader, int pointerSize, MessageLog log,
|
||||
TaskMonitor monitor) throws IOException, CancelledException {
|
||||
List<DyldFixup> fixups = new ArrayList<>();
|
||||
|
||||
monitor.initialize(pageStartsCount, "Getting DYLD Cache V5 slide fixups...");
|
||||
for (int index = 0; index < pageStartsCount; index++) {
|
||||
monitor.increment();
|
||||
|
||||
long segmentOffset = pageSize * index;
|
||||
|
||||
int pageEntry = Short.toUnsignedInt(pageStarts[index]);
|
||||
if (pageEntry == DYLD_CACHE_SLIDE_V5_PAGE_ATTR_NO_REBASE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long pageOffset = (pageEntry / 8) * 8; // first entry byte based;
|
||||
fixups.addAll(processPointerChain(segmentOffset, pageOffset, reader, monitor));
|
||||
}
|
||||
|
||||
return fixups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks the pointer chain at the given reader offset to find necessary {@link DyldFixup}s
|
||||
*
|
||||
* @param segmentOffset The segment offset
|
||||
* @param pageOffset The page offset
|
||||
* @param reader A reader positioned at the start of the segment to fix
|
||||
* @param monitor A cancellable monitor
|
||||
* @return A {@link List} of {@link DyldFixup}s
|
||||
* @throws IOException If an IO-related error occurred
|
||||
* @throws CancelledException If the user cancelled the operation
|
||||
*/
|
||||
private List<DyldFixup> processPointerChain(long segmentOffset, long pageOffset,
|
||||
BinaryReader reader, TaskMonitor monitor) throws IOException, CancelledException {
|
||||
|
||||
List<DyldFixup> fixups = new ArrayList<>(1024);
|
||||
|
||||
int size = DyldChainedPtr.getSize(TYPE);
|
||||
long stride = DyldChainedPtr.getStride(TYPE);
|
||||
|
||||
for (long delta = -1; delta != 0; pageOffset += delta * stride) {
|
||||
monitor.checkCancelled();
|
||||
|
||||
long dataOffset = segmentOffset + pageOffset;
|
||||
long chainValue = DyldChainedPtr.getChainValue(reader, dataOffset, TYPE);
|
||||
long newPtrValue = DyldChainedPtr.getTarget(TYPE, chainValue) + valueAdd;
|
||||
delta = DyldChainedPtr.getNext(TYPE, chainValue);
|
||||
|
||||
if (!DyldChainedPtr.isAuthenticated(TYPE, chainValue)) {
|
||||
long high8 = (chainValue >>> 34) & 0xff;
|
||||
newPtrValue |= high8 << 56;
|
||||
}
|
||||
|
||||
fixups.add(new DyldFixup(dataOffset, newPtrValue, size, null, null));
|
||||
}
|
||||
|
||||
return fixups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType("dyld_cache_slide_info5", 0);
|
||||
struct.add(DWORD, "version", "currently 5");
|
||||
struct.add(DWORD, "page_size", "currently 4096 (may also be 16384)");
|
||||
struct.add(DWORD, "page_starts_count", "");
|
||||
struct.add(DWORD, "pad", "");
|
||||
struct.add(QWORD, "value_add", "");
|
||||
struct.add(new ArrayDataType(WORD, pageStartsCount, 1), "page_starts", "");
|
||||
struct.setCategoryPath(new CategoryPath(MachConstants.DATA_TYPE_CATEGORY));
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
@@ -81,6 +81,8 @@ public abstract class DyldCacheSlideInfoCommon implements StructConverter {
|
||||
mappingFileOffset);
|
||||
case 4 -> new DyldCacheSlideInfo4(reader, mappingAddress, mappingSize,
|
||||
mappingFileOffset);
|
||||
case 5 -> new DyldCacheSlideInfo5(reader, mappingAddress, mappingSize,
|
||||
mappingFileOffset);
|
||||
default -> throw new IOException(); // will be caught and version will be added to message
|
||||
};
|
||||
monitor.incrementProgress(1);
|
||||
|
||||
@@ -18,11 +18,6 @@ package ghidra.app.util.bin.format.macho.dyld;
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.reloc.Relocation.Status;
|
||||
import ghidra.program.model.reloc.RelocationResult;
|
||||
|
||||
/**
|
||||
* @see <a href="https://github.com/apple-oss-distributions/dyld/blob/main/include/mach-o/fixup-chains.h">mach-o/fixup-chains.h</a>
|
||||
@@ -42,6 +37,7 @@ public class DyldChainedPtr {
|
||||
DYLD_CHAINED_PTR_ARM64E_FIRMWARE(10), // stride 4, unauth target is vmaddr
|
||||
DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE(11), // stride 1, x86_64 kernel caches
|
||||
DYLD_CHAINED_PTR_ARM64E_USERLAND24(12), // stride 8, unauth target is vm offset, 24-bit bind
|
||||
DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE(13), // stride 8, regular/auth targets both vm offsets. Only A keys supported
|
||||
DYLD_CHAINED_PTR_TYPE_UNKNOWN(-1);
|
||||
|
||||
private final int val;
|
||||
@@ -53,33 +49,22 @@ public class DyldChainedPtr {
|
||||
}
|
||||
|
||||
public static DyldChainType lookupChainPtr(int val) {
|
||||
switch (val) {
|
||||
case 1:
|
||||
return DYLD_CHAINED_PTR_ARM64E;
|
||||
case 2:
|
||||
return DYLD_CHAINED_PTR_64;
|
||||
case 3:
|
||||
return DYLD_CHAINED_PTR_32;
|
||||
case 4:
|
||||
return DYLD_CHAINED_PTR_32_CACHE;
|
||||
case 5:
|
||||
return DYLD_CHAINED_PTR_32_FIRMWARE;
|
||||
case 6:
|
||||
return DYLD_CHAINED_PTR_64_OFFSET;
|
||||
case 7:
|
||||
return DYLD_CHAINED_PTR_ARM64E_KERNEL;
|
||||
case 8:
|
||||
return DYLD_CHAINED_PTR_64_KERNEL_CACHE;
|
||||
case 9:
|
||||
return DYLD_CHAINED_PTR_ARM64E_USERLAND;
|
||||
case 10:
|
||||
return DYLD_CHAINED_PTR_ARM64E_FIRMWARE;
|
||||
case 11:
|
||||
return DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE;
|
||||
case 12:
|
||||
return DYLD_CHAINED_PTR_ARM64E_USERLAND24;
|
||||
}
|
||||
return DYLD_CHAINED_PTR_TYPE_UNKNOWN;
|
||||
return switch (val) {
|
||||
case 1 -> DYLD_CHAINED_PTR_ARM64E;
|
||||
case 2 -> DYLD_CHAINED_PTR_64;
|
||||
case 3 -> DYLD_CHAINED_PTR_32;
|
||||
case 4 -> DYLD_CHAINED_PTR_32_CACHE;
|
||||
case 5 -> DYLD_CHAINED_PTR_32_FIRMWARE;
|
||||
case 6 -> DYLD_CHAINED_PTR_64_OFFSET;
|
||||
case 7 -> DYLD_CHAINED_PTR_ARM64E_KERNEL;
|
||||
case 8 -> DYLD_CHAINED_PTR_64_KERNEL_CACHE;
|
||||
case 9 -> DYLD_CHAINED_PTR_ARM64E_USERLAND;
|
||||
case 10 -> DYLD_CHAINED_PTR_ARM64E_FIRMWARE;
|
||||
case 11 -> DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE;
|
||||
case 12 -> DYLD_CHAINED_PTR_ARM64E_USERLAND24;
|
||||
case 13 -> DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE;
|
||||
default -> DYLD_CHAINED_PTR_TYPE_UNKNOWN;
|
||||
};
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
@@ -96,84 +81,55 @@ public class DyldChainedPtr {
|
||||
public static final int DYLD_CHAINED_PTR_START_LAST = 0x8000;
|
||||
|
||||
public static long getStride(DyldChainType ptrFormat) {
|
||||
switch (ptrFormat) {
|
||||
case DYLD_CHAINED_PTR_ARM64E:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
|
||||
return 8;
|
||||
case DYLD_CHAINED_PTR_64:
|
||||
case DYLD_CHAINED_PTR_64_OFFSET:
|
||||
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
|
||||
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
|
||||
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
|
||||
case DYLD_CHAINED_PTR_32:
|
||||
case DYLD_CHAINED_PTR_32_CACHE:
|
||||
case DYLD_CHAINED_PTR_32_FIRMWARE:
|
||||
return 4;
|
||||
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
|
||||
return 1;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getSize(DyldChainType ptrFormat) {
|
||||
return switch (ptrFormat) {
|
||||
case DYLD_CHAINED_PTR_ARM64E:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
|
||||
case DYLD_CHAINED_PTR_64:
|
||||
case DYLD_CHAINED_PTR_64_OFFSET:
|
||||
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
|
||||
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
|
||||
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
|
||||
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
|
||||
yield 8;
|
||||
|
||||
case DYLD_CHAINED_PTR_32:
|
||||
case DYLD_CHAINED_PTR_32_CACHE:
|
||||
case DYLD_CHAINED_PTR_32_FIRMWARE:
|
||||
yield 4;
|
||||
case DYLD_CHAINED_PTR_ARM64E:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
|
||||
case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
|
||||
yield 8;
|
||||
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
|
||||
default:
|
||||
yield 1;
|
||||
};
|
||||
}
|
||||
|
||||
public static int getSize(DyldChainType ptrFormat) {
|
||||
return switch (ptrFormat) {
|
||||
case DYLD_CHAINED_PTR_32:
|
||||
case DYLD_CHAINED_PTR_32_CACHE:
|
||||
case DYLD_CHAINED_PTR_32_FIRMWARE:
|
||||
yield 4;
|
||||
case DYLD_CHAINED_PTR_ARM64E:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
|
||||
case DYLD_CHAINED_PTR_64:
|
||||
case DYLD_CHAINED_PTR_64_OFFSET:
|
||||
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
|
||||
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
|
||||
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
|
||||
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
|
||||
case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
|
||||
default:
|
||||
yield 8;
|
||||
};
|
||||
}
|
||||
|
||||
public static RelocationResult setChainValue(Memory memory, Address chainLoc,
|
||||
DyldChainType ptrFormat,
|
||||
long value) throws MemoryAccessException {
|
||||
int byteLength;
|
||||
switch (ptrFormat) {
|
||||
case DYLD_CHAINED_PTR_ARM64E:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
|
||||
case DYLD_CHAINED_PTR_64:
|
||||
case DYLD_CHAINED_PTR_64_OFFSET:
|
||||
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
|
||||
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
|
||||
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
|
||||
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
|
||||
memory.setLong(chainLoc, value);
|
||||
byteLength = 8;
|
||||
break;
|
||||
|
||||
case DYLD_CHAINED_PTR_32:
|
||||
case DYLD_CHAINED_PTR_32_CACHE:
|
||||
case DYLD_CHAINED_PTR_32_FIRMWARE:
|
||||
memory.setInt(chainLoc, (int) (value & 0xFFFFFFFFL));
|
||||
byteLength = 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
return RelocationResult.UNSUPPORTED;
|
||||
}
|
||||
return new RelocationResult(Status.APPLIED_OTHER, byteLength);
|
||||
}
|
||||
|
||||
public static long getChainValue(BinaryReader reader, long chainLoc, DyldChainType ptrFormat)
|
||||
throws IOException {
|
||||
switch (ptrFormat) {
|
||||
return switch (ptrFormat) {
|
||||
case DYLD_CHAINED_PTR_32:
|
||||
case DYLD_CHAINED_PTR_32_CACHE:
|
||||
case DYLD_CHAINED_PTR_32_FIRMWARE:
|
||||
yield reader.readUnsignedInt(chainLoc);
|
||||
case DYLD_CHAINED_PTR_ARM64E:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
|
||||
@@ -183,104 +139,61 @@ public class DyldChainedPtr {
|
||||
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
|
||||
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
|
||||
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
|
||||
return reader.readLong(chainLoc);
|
||||
|
||||
case DYLD_CHAINED_PTR_32:
|
||||
case DYLD_CHAINED_PTR_32_CACHE:
|
||||
case DYLD_CHAINED_PTR_32_FIRMWARE:
|
||||
return reader.readUnsignedInt(chainLoc);
|
||||
case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
|
||||
yield reader.readLong(chainLoc);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
yield 0;
|
||||
};
|
||||
}
|
||||
|
||||
public static boolean isRelative(DyldChainType ptrFormat) {
|
||||
switch (ptrFormat) {
|
||||
return switch (ptrFormat) {
|
||||
case DYLD_CHAINED_PTR_64_OFFSET:
|
||||
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
|
||||
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
|
||||
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
|
||||
return true;
|
||||
case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
|
||||
yield true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
yield false;
|
||||
};
|
||||
}
|
||||
|
||||
public static boolean isBound(DyldChainType ptrFormat, long chainValue) {
|
||||
|
||||
switch (ptrFormat) {
|
||||
return switch (ptrFormat) {
|
||||
case DYLD_CHAINED_PTR_ARM64E:
|
||||
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
|
||||
return ((chainValue >>> 62) & 1) != 0;
|
||||
|
||||
yield ((chainValue >>> 62) & 1) != 0;
|
||||
case DYLD_CHAINED_PTR_64:
|
||||
case DYLD_CHAINED_PTR_64_OFFSET:
|
||||
return ((chainValue >>> 63) & 1) != 0;
|
||||
|
||||
yield ((chainValue >>> 63) & 1) != 0;
|
||||
case DYLD_CHAINED_PTR_32:
|
||||
return ((chainValue >>> 31) & 1) != 0;
|
||||
|
||||
// Never bound
|
||||
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
|
||||
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
|
||||
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
|
||||
case DYLD_CHAINED_PTR_32_CACHE:
|
||||
case DYLD_CHAINED_PTR_32_FIRMWARE:
|
||||
yield ((chainValue >>> 31) & 1) != 0;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
yield false;
|
||||
};
|
||||
}
|
||||
|
||||
public static boolean isAuthenticated(DyldChainType ptrFormat, long chainValue) {
|
||||
switch (ptrFormat) {
|
||||
return switch (ptrFormat) {
|
||||
case DYLD_CHAINED_PTR_64:
|
||||
case DYLD_CHAINED_PTR_64_OFFSET:
|
||||
case DYLD_CHAINED_PTR_32:
|
||||
case DYLD_CHAINED_PTR_32_CACHE:
|
||||
case DYLD_CHAINED_PTR_32_FIRMWARE:
|
||||
return false;
|
||||
yield false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
boolean isAuthenticated = ((chainValue >>> 63) & 1) != 0;
|
||||
|
||||
return isAuthenticated;
|
||||
}
|
||||
|
||||
public static long getDiversity(DyldChainType ptrFormat, long chainValue) {
|
||||
if (!isAuthenticated(ptrFormat, chainValue)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long diversityData = (chainValue >>> 32) & 0xFFFF;
|
||||
|
||||
return diversityData;
|
||||
}
|
||||
|
||||
public static boolean hasAddrDiversity(DyldChainType ptrFormat, long chainValue) {
|
||||
if (!isAuthenticated(ptrFormat, chainValue)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((chainValue >>> 48) & 1) == 1;
|
||||
}
|
||||
|
||||
public static long getKey(DyldChainType ptrFormat, long chainValue) {
|
||||
if (!isAuthenticated(ptrFormat, chainValue)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (chainValue >>> 49L) & 0x3;
|
||||
yield ((chainValue >>> 63) & 1) != 0;
|
||||
};
|
||||
}
|
||||
|
||||
public static long getTarget(DyldChainType ptrFormat, long chainValue) {
|
||||
|
||||
long target = 0;
|
||||
if (isBound(ptrFormat, chainValue)) {
|
||||
return -1;
|
||||
}
|
||||
@@ -295,12 +208,14 @@ public class DyldChainedPtr {
|
||||
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
|
||||
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
|
||||
return (chainValue & 0x3FFFFFFFL); // 30 bits
|
||||
case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
|
||||
return (chainValue & 0x3FFFFFFFFL); // 34 bits
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ptrFormat) {
|
||||
return switch (ptrFormat) {
|
||||
case DYLD_CHAINED_PTR_ARM64E:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
|
||||
@@ -311,8 +226,7 @@ public class DyldChainedPtr {
|
||||
if (top8Bits == 0x80) {
|
||||
top8Bits = 0;
|
||||
}
|
||||
target = (top8Bits << 56) | bottom43Bits;
|
||||
break;
|
||||
yield (top8Bits << 56) | bottom43Bits;
|
||||
|
||||
case DYLD_CHAINED_PTR_64:
|
||||
case DYLD_CHAINED_PTR_64_OFFSET:
|
||||
@@ -322,30 +236,27 @@ public class DyldChainedPtr {
|
||||
if (top8Bits == 0x80) {
|
||||
top8Bits = 0;
|
||||
}
|
||||
target = (top8Bits << 56) | bottom36Bits;
|
||||
break;
|
||||
yield (top8Bits << 56) | bottom36Bits;
|
||||
|
||||
case DYLD_CHAINED_PTR_32:
|
||||
target = (chainValue & 0x3FFFFF); // 26 bits
|
||||
break;
|
||||
yield (chainValue & 0x3FFFFF); // 26 bits
|
||||
|
||||
case DYLD_CHAINED_PTR_32_CACHE:
|
||||
target = (chainValue & 0x3FFFFFFF); // 30 bits
|
||||
break;
|
||||
yield (chainValue & 0x3FFFFFFF); // 30 bits
|
||||
|
||||
case DYLD_CHAINED_PTR_32_FIRMWARE:
|
||||
target = (chainValue & 0x3FFFFF); // 26 bits
|
||||
break;
|
||||
yield (chainValue & 0x3FFFFF); // 26 bits
|
||||
|
||||
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
|
||||
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
|
||||
target = (chainValue & 0x3FFFFFFF); // 30 bits
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
yield (chainValue & 0x3FFFFFFF); // 30 bits
|
||||
|
||||
return target;
|
||||
case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
|
||||
yield (chainValue & 0x3FFFFFFFFL); // 34 bits
|
||||
|
||||
default:
|
||||
yield 0;
|
||||
};
|
||||
}
|
||||
|
||||
public static long getAddend(DyldChainType ptrFormat, long chainValue) {
|
||||
@@ -354,103 +265,83 @@ public class DyldChainedPtr {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (ptrFormat) {
|
||||
return switch (ptrFormat) {
|
||||
case DYLD_CHAINED_PTR_ARM64E:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
|
||||
long addend = (chainValue >>> 32) & 0x7FFFF;
|
||||
addend = ((addend & 0x40000) != 0 ? (addend | 0xFFFFFFFFFFFC0000L) : addend);
|
||||
return addend;
|
||||
yield addend;
|
||||
|
||||
case DYLD_CHAINED_PTR_64:
|
||||
case DYLD_CHAINED_PTR_64_OFFSET:
|
||||
return (chainValue >>> 24) & 0xFF;
|
||||
yield (chainValue >>> 24) & 0xFF;
|
||||
|
||||
case DYLD_CHAINED_PTR_32:
|
||||
return (chainValue >>> 20) & 0x3F; // 6 bits
|
||||
yield (chainValue >>> 20) & 0x3F; // 6 bits
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
yield 0;
|
||||
};
|
||||
}
|
||||
|
||||
public static long getOrdinal(DyldChainType ptrFormat, long chainValue) {
|
||||
|
||||
long ordinal = -1;
|
||||
if (!isBound(ptrFormat, chainValue)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (ptrFormat) {
|
||||
return switch (ptrFormat) {
|
||||
case DYLD_CHAINED_PTR_ARM64E:
|
||||
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
|
||||
ordinal = chainValue & 0xFFFF;
|
||||
break;
|
||||
yield chainValue & 0xFFFF;
|
||||
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
|
||||
case DYLD_CHAINED_PTR_64:
|
||||
case DYLD_CHAINED_PTR_64_OFFSET:
|
||||
ordinal = chainValue & 0xFFFFFF;
|
||||
break;
|
||||
yield chainValue & 0xFFFFFF;
|
||||
|
||||
case DYLD_CHAINED_PTR_32:
|
||||
ordinal = chainValue & 0xFFFFF;
|
||||
break;
|
||||
yield chainValue & 0xFFFFF;
|
||||
|
||||
// Never Ordinal
|
||||
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
|
||||
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
|
||||
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
|
||||
case DYLD_CHAINED_PTR_32_CACHE:
|
||||
case DYLD_CHAINED_PTR_32_FIRMWARE:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ordinal;
|
||||
yield -1;
|
||||
};
|
||||
}
|
||||
|
||||
public static long getNext(DyldChainType ptrFormat, long chainValue) {
|
||||
|
||||
long next = 1;
|
||||
|
||||
switch (ptrFormat) {
|
||||
return switch (ptrFormat) {
|
||||
case DYLD_CHAINED_PTR_ARM64E:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
|
||||
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
|
||||
case DYLD_CHAINED_PTR_ARM64E_KERNEL:
|
||||
next = (chainValue >>> 51) & 0x7FF; // 11-bits
|
||||
break;
|
||||
yield (chainValue >>> 51) & 0x7FF; // 11-bits
|
||||
|
||||
case DYLD_CHAINED_PTR_64:
|
||||
case DYLD_CHAINED_PTR_64_OFFSET:
|
||||
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE:
|
||||
case DYLD_CHAINED_PTR_64_KERNEL_CACHE:
|
||||
next = (chainValue >>> 51) & 0xFFF; // 12 bits
|
||||
break;
|
||||
yield (chainValue >>> 51) & 0xFFF; // 12 bits
|
||||
|
||||
case DYLD_CHAINED_PTR_32:
|
||||
next = (chainValue >>> 26) & 0x1F; // 5 bits
|
||||
break;
|
||||
yield (chainValue >>> 26) & 0x1F; // 5 bits
|
||||
|
||||
// Never bound
|
||||
case DYLD_CHAINED_PTR_ARM64E_FIRMWARE:
|
||||
next = 0;
|
||||
break;
|
||||
yield 0;
|
||||
|
||||
case DYLD_CHAINED_PTR_32_CACHE:
|
||||
next = (chainValue >>> 30) & 0x3; // 2 bits
|
||||
break;
|
||||
yield (chainValue >>> 30) & 0x3; // 2 bits
|
||||
|
||||
case DYLD_CHAINED_PTR_32_FIRMWARE:
|
||||
next = (chainValue >>> 26) & 0x3F; // 6 bits
|
||||
break;
|
||||
yield (chainValue >>> 26) & 0x3F; // 6 bits
|
||||
|
||||
case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
|
||||
yield (chainValue >>> 52) & 0x7FF; // 11 bits
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return next;
|
||||
yield 1;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user