mirror of
https://github.com/StikDebug/StikDebug.git
synced 2026-10-15 20:10:30 +00:00
bulk page write & txm check (#216)
* bulk page write * txm check Co-authored-by: Stossy11 <stossy11@users.noreply.github.com> --------- Co-authored-by: Stossy11 <stossy11@users.noreply.github.com>
This commit is contained in:
parent
aa151dbba2
commit
1808dafed3
4 changed files with 123 additions and 0 deletions
|
|
@ -31,3 +31,96 @@ NSString* handleJSContextSendDebugCommand(JSContext* context, NSString* commandS
|
|||
idevice_string_free(attach_response);
|
||||
return commandResponse;
|
||||
}
|
||||
|
||||
// 0 <= val <= 15
|
||||
char u8toHexChar(uint8_t val) {
|
||||
if(val < 10) {
|
||||
return val + '0';
|
||||
} else {
|
||||
return val + 87;
|
||||
}
|
||||
}
|
||||
|
||||
void calcAndWriteCheckSum(char* commandStart) {
|
||||
uint8_t sum = 0;
|
||||
char* cur = commandStart;
|
||||
for(; *cur != '#'; ++cur) {
|
||||
sum += *cur;
|
||||
}
|
||||
cur[1] = u8toHexChar((sum & 0xf0) >> 4);
|
||||
cur[2] = u8toHexChar(sum & 0xf);
|
||||
}
|
||||
|
||||
// support up to 9 digit
|
||||
void writeAddress(char* writeStart, uint64_t addr) {
|
||||
writeStart[0] = u8toHexChar((addr & 0xf00000000) >> 32);
|
||||
writeStart[1] = u8toHexChar((addr & 0xf0000000) >> 28);
|
||||
writeStart[2] = u8toHexChar((addr & 0xf000000) >> 24);
|
||||
writeStart[3] = u8toHexChar((addr & 0xf00000) >> 20);
|
||||
writeStart[4] = u8toHexChar((addr & 0xf0000) >> 16);
|
||||
writeStart[5] = u8toHexChar((addr & 0xf000) >> 12);
|
||||
writeStart[6] = u8toHexChar((addr & 0xf00) >> 8);
|
||||
writeStart[7] = u8toHexChar((addr & 0xf0) >> 4);
|
||||
writeStart[8] = u8toHexChar((addr & 0xf));
|
||||
}
|
||||
|
||||
// you need to free generated buffer
|
||||
char* getBulkMemWriteCommand(uint64_t startAddr, uint64_t JITPagesSize, uint32_t* commandCountOut, uint32_t* bufferLengthOut) {
|
||||
// $M10c128000,1:69#12
|
||||
uint32_t commandCount = (uint32_t)(JITPagesSize >> 14);
|
||||
uint32_t commandBufferSize = commandCount * 19;
|
||||
*commandCountOut = commandCount;
|
||||
*bufferLengthOut = commandBufferSize;
|
||||
char* buffer = malloc(commandBufferSize + 1);
|
||||
char* bufferEnd = buffer + commandBufferSize;
|
||||
buffer[commandBufferSize] = 0;
|
||||
|
||||
uint64_t curAddr = startAddr;
|
||||
for(char* curBufferPtr = buffer; curBufferPtr < bufferEnd; curBufferPtr += 19) {
|
||||
curBufferPtr[0] = '$';
|
||||
curBufferPtr[1] = 'M';
|
||||
curBufferPtr[11] = ',';
|
||||
curBufferPtr[12] = '1';
|
||||
curBufferPtr[13] = ':';
|
||||
curBufferPtr[14] = '6';
|
||||
curBufferPtr[15] = '9';
|
||||
curBufferPtr[16] = '#';
|
||||
writeAddress(curBufferPtr + 2, curAddr);
|
||||
calcAndWriteCheckSum(curBufferPtr + 1);
|
||||
curAddr += 16384;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
NSString* handleJITPageWrite(JSContext* context, uint64_t startAddr, uint64_t JITPagesSize, DebugProxyHandle* debugProxy) {
|
||||
uint32_t bufferLength = 0;
|
||||
uint32_t commandCount = 0;
|
||||
char* commandBuffer = getBulkMemWriteCommand(startAddr, JITPagesSize, &commandCount, &bufferLength);
|
||||
// we send 1024 commands at a time
|
||||
for(int curCommand = 0; curCommand < commandCount; curCommand += 1024) {
|
||||
uint32_t commandsToSend = (commandCount - curCommand > 1024) ? 1024 : (commandCount - curCommand);
|
||||
IdeviceFfiError* err = debug_proxy_send_raw(debugProxy, (const uint8_t *)commandBuffer + curCommand * 19, commandsToSend * 19);
|
||||
if(err) {
|
||||
context.exception = [JSValue valueWithObject:[NSString stringWithFormat:@"error code %d, msg %s", err->code, err->message] inContext:context];
|
||||
free(commandBuffer);
|
||||
idevice_error_free(err);
|
||||
return nil;
|
||||
}
|
||||
|
||||
for(int i = 0; i < commandsToSend; ++i) {
|
||||
char* response = 0;
|
||||
IdeviceFfiError* err = debug_proxy_read_response(debugProxy, &response);
|
||||
if(response) {
|
||||
idevice_string_free(response);
|
||||
}
|
||||
if(err) {
|
||||
context.exception = [JSValue valueWithObject:[NSString stringWithFormat:@"error code %d, msg %s", err->code, err->message] inContext:context];
|
||||
free(commandBuffer);
|
||||
idevice_error_free(err);
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(commandBuffer);
|
||||
return @"OK";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,3 +9,4 @@
|
|||
#include "../idevice/jit.h"
|
||||
|
||||
NSString* handleJSContextSendDebugCommand(JSContext* context, NSString* commandStr, DebugProxyHandle* debugProxy);
|
||||
NSString* handleJITPageWrite(JSContext* context, uint64_t startAddr, uint64_t JITPagesSize, DebugProxyHandle* debugProxy);
|
||||
|
|
|
|||
|
|
@ -50,9 +50,19 @@ class RunJSViewModel: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
let prepareMemoryRegionFunction: @convention(block) (UInt64, UInt64) -> String = { startAddr, regionSize in
|
||||
return handleJITPageWrite(self.context, startAddr, regionSize, self.debugProxy) ?? ""
|
||||
}
|
||||
|
||||
let hasTXMFunction: @convention(block) () -> Bool = {
|
||||
return ProcessInfo.processInfo.hasTXM
|
||||
}
|
||||
|
||||
context = JSContext()
|
||||
context?.setObject(hasTXMFunction, forKeyedSubscript: "hasTXM" as NSString)
|
||||
context?.setObject(getPidFunction, forKeyedSubscript: "get_pid" as NSString)
|
||||
context?.setObject(sendCommandFunction, forKeyedSubscript: "send_command" as NSString)
|
||||
context?.setObject(prepareMemoryRegionFunction, forKeyedSubscript: "prepare_memory_region" as NSString)
|
||||
context?.setObject(logFunction, forKeyedSubscript: "log" as NSString)
|
||||
|
||||
context?.evaluateScript(scriptContent)
|
||||
|
|
|
|||
19
StikJIT/Utilities/Extensions.swift
Normal file
19
StikJIT/Utilities/Extensions.swift
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// Extensions.swift
|
||||
// StikDebug
|
||||
//
|
||||
// Created by s s on 2025/7/9.
|
||||
//
|
||||
|
||||
extension FileManager {
|
||||
func filePath(atPath path: String, withLength length: Int) -> String? {
|
||||
guard let file = try? contentsOfDirectory(atPath: path).filter({ $0.count == length }).first else { return nil }
|
||||
return "\(path)/\(file)"
|
||||
}
|
||||
}
|
||||
|
||||
public extension ProcessInfo {
|
||||
var hasTXM: Bool {
|
||||
{ if let boot = FileManager.default.filePath(atPath: "/System/Volumes/Preboot", withLength: 36), let file = FileManager.default.filePath(atPath: "\(boot)/boot", withLength: 96) { return access("\(file)/usr/standalone/firmware/FUD/Ap,TrustedExecutionMonitor.img4", F_OK) == 0 } else { return (FileManager.default.filePath(atPath: "/private/preboot", withLength: 96).map { access("\($0)/usr/standalone/firmware/FUD/Ap,TrustedExecutionMonitor.img4", F_OK) == 0 }) ?? false } }()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue