How to hook Apple's `os_log_with_type` method in Objective-C - ios

I want to hook "React Native" RCTLog logs method _RCTLogJavaScriptInternal , The source codes is:
void _RCTLogJavaScriptInternal(RCTLogLevel level, NSString *message)
{
RCTLogFunction logFunction = RCTGetLocalLogFunction();
BOOL log = RCT_DEBUG || (logFunction != nil);
if (log && level >= RCTGetLogThreshold()) {
if (logFunction) {
logFunction(level, RCTLogSourceJavaScript, nil, nil, message);
}
}
}
RCTLogFunction RCTDefaultLogFunction =
^(RCTLogLevel level,
RCTLogSource source,
__unused NSString *fileName,
__unused NSNumber *lineNumber,
NSString *message) {
os_log_with_type(RCTLogForLogSource(source), RCTLogTypeForLogLevel(level), "%{public}s", message.UTF8String);
};
So if I just hook Apple's os_log_with_type, I will get the RCTLog logs.
This is my codes, but not working. Please help me. Thanks!!!!
#import <os/log.h>
#import "fishhook.h"
static void (*original_oslog)((os_log_t log, os_log_type_t type, const char *format, ...));
void hook_oslog(os_log_t log, os_log_type_t type, const char *format, ...) {
NSLog(#"hook success!");
}
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
struct rebinding oslog_rebinding = { "os_log_with_type", hook_oslog, (void *)&original_oslog };
rebind_symbols((struct rebinding[1]){oslog_rebinding}, 1);
});
}

Final, I found solution. Not need to hook, Related API have been provided by React Native already.
RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
NSLog(#"%#", message);
});

Related

IOS development how to solve the capture signal handler by covering problems

I want to make both the existing singal handler in the project and my own singal handler co-exist so that both can properly capture singal.
typedef void (*signalHandler)(int signo, siginfo_t *info, void *context);
static signalHandler previousSignalHandler = NULL;
void signalExceptionHandler(int signal, siginfo_t* info, void* context)
{
NSMutableString *mstr = [[NSMutableString alloc] init];
[mstr appendString:#"Stack:\n"];
void* callstack[128];
int i, frames = backtrace(callstack, 128);
char** strs = backtrace_symbols(callstack, frames);
for (i = 0; i <frames; ++i) {
[mstr appendFormat:#"%s\n", strs[i]];
}
BYLOGI(#"%#",mstr);
[BYCrashCacheHelper saveAppCrashDataWithCrashInfo:mstr];
if (previousSignalHandler) {
previousSignalHandler(signal, info, context);
}
}
void signalRegister(int signal)
{
struct sigaction action;
action.sa_sigaction = signalExceptionHandler;
action.sa_flags = SA_NODEFER | SA_SIGINFO;
sigemptyset(&action.sa_mask);
sigaction(signal, &action, 0);
}
void judgePreviousSignalHandlerAndSignalRegister(int signal)
{
struct sigaction old_action;
sigaction(signal, NULL, &old_action);
if (old_action.sa_flags & SA_SIGINFO) {
previousSignalHandler = old_action.sa_sigaction;
}
signalRegister(signal);
}
void installSignalHandler(void)
{
judgePreviousSignalHandlerAndSignalRegister(SIGHUP);
judgePreviousSignalHandlerAndSignalRegister(SIGINT);
judgePreviousSignalHandlerAndSignalRegister(SIGQUIT);
judgePreviousSignalHandlerAndSignalRegister(SIGABRT);
judgePreviousSignalHandlerAndSignalRegister(SIGILL);
judgePreviousSignalHandlerAndSignalRegister(SIGSEGV);
judgePreviousSignalHandlerAndSignalRegister(SIGFPE);
judgePreviousSignalHandlerAndSignalRegister(SIGBUS);
judgePreviousSignalHandlerAndSignalRegister(SIGPIPE);
}
I found the above method in some blogs, but after debugging, I found that it can not get to the previous handler.
Excuse me, how to get the previous handler correctly, and avoid the handler coverage problem?

MobileInstallationInstall progress

I wanna install a ipa on a jailbreak i-device.I get this code bellow on google. Here is the code
#import "dlfcn.h"
typedef int (*MobileInstallationInstall)(NSString *path, NSDictionary *dict, void *na, NSString *path2_equal_path_maybe_no_use);
void *lib = dlopen("/System/Library/PrivateFrameworks/MobileInstallation.framework/MobileInstallation", RTLD_LOCAL);
if (lib)
{
MobileInstallationInstall pMobileInstallationInstall = (MobileInstallationInstall)dlsym(lib, "MobileInstallationInstall");
if (pMobileInstallationInstall)
{
int ret = pMobileInstallationInstall(path, [NSDictionary dictionaryWithObject:#"User" forKey:#"ApplicationType"], nil, path);
dlclose(lib);
return ret;
}
}
return -1;
But that's not enough.I wanna get the install progress.Just like download progress. Unfortunately,I get nothing on google.any ideas?
you have to specify a callback function on the third parameter of MobileInstallationInstall
void MobileInstallationCallback(CFDictionaryRef information){
NSLog(#"%#",information);
}
int ret = pMobileInstallationInstall(path, [NSDictionary dictionaryWithObject:#"User" forKey:#"ApplicationType"], & MobileInstallationCallback, path);
all the informations will be sent to MobileInstallationCallback via the parameter information

How to communicate between applications in iOS?

Before we can use CFMessagePort, but now it's invalid for iOS7 and above, is there any replaced methods? I tried CFMessagePort when hooking the constructor of UIApplication in the jailbreak environment, but in most of the apps, it can't CFMessagePortCreateLocal successfully, it just return NULL.Am I wrong somewhere?
static void setupUIApplicationMessagePort()
{
NSString *identifier = #"com.foo.foo.UIApplication";
CFMessagePortRef local = CFMessagePortCreateLocal(NULL, (__bridge CFStringRef)identifier, callBackForUIApplication, NULL, NULL);
if (local) {
NSLog(#"local OK: %#", local);
CFRunLoopSourceRef source = CFMessagePortCreateRunLoopSource(NULL, local, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes);
rocketbootstrap_cfmessageportexposelocal(local);
} else {
NSLog(#"local is NULL"); // in most of the apps it returns NULL
}
}
%ctor {
if(%c(UIApplication)) {
setupUIApplicationMessagePort();
}
}
try CFNotificationCenter using CFNotificationCenterGetDarwinNotifyCenter
#include <CoreFoundation/CFNotificationCenter.h>
/* This function will be called whatever a notification posted with the specified name */
void NotificationCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo){
}
void addObserver(){
CFStringRef name = CFSTR("NotificationName");
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),&NotificationCallback,name,NULL,CFNotificationSuspensionBehaviorDeliverImmediately);
}
This will listen to notifications named NotificationName
To post a notification
void postNotification(){
CFStringRef name = CFSTR("NotificationName");
/* You have to create the userInfo dictionary and add all the keys to it */
CFDictionaryRef userInfo;
CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), name, NULL, userInfo, true);
}

Parse whole pdf-page to NSString on an iPhone

I've been trying to parse a pdf-page of text to NSString for a while now and the only thing I can find are methods to search for specific stringvalues.
What I'd like to do is parse a single page of PDF without using any external libraries such as PDFKitten, PDFKit etc.
I'd like to have the data in an NSArray, NSString or NSDictionary if possible.
Thanks :D!
A piece of what I've tried so far.
CGPDFDocumentRef MyGetPDFDocumentRef (const char *filename) {
CFStringRef path;
CFURLRef url;
CGPDFDocumentRef document;
path = CFStringCreateWithCString (NULL, filename,kCFStringEncodingUTF8);
url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, 0);
CFRelease (path);
document = CGPDFDocumentCreateWithURL (url);// 2
CFRelease(url);
int count = CGPDFDocumentGetNumberOfPages (document);// 3
if (count == 0) {
printf("`%s' needs at least one page!", filename);
return NULL;
}
return document;
}
// table methods to parse pdf
static void op_MP (CGPDFScannerRef s, void *info) {
const char *name;
if (!CGPDFScannerPopName(s, &name))
return;
printf("MP /%s\n", name);
}
static void op_DP (CGPDFScannerRef s, void *info) {
const char *name;
if (!CGPDFScannerPopName(s, &name))
return;
printf("DP /%s\n", name);
}
static void op_BMC (CGPDFScannerRef s, void *info) {
const char *name;
if (!CGPDFScannerPopName(s, &name))
return;
printf("BMC /%s\n", name);
}
static void op_BDC (CGPDFScannerRef s, void *info) {
const char *name;
if (!CGPDFScannerPopName(s, &name))
return;
printf("BDC /%s\n", name);
}
static void op_EMC (CGPDFScannerRef s, void *info) {
const char *name;
if (!CGPDFScannerPopName(s, &name))
return;
printf("EMC /%s\n", name);
}
void MyDisplayPDFPage (CGContextRef myContext,size_t pageNumber,const char *filename) {
CGPDFDocumentRef document;
CGPDFPageRef page;
document = MyGetPDFDocumentRef (filename);// 1
totalPages=CGPDFDocumentGetNumberOfPages(document);
page = CGPDFDocumentGetPage (document, 1);// 2
CGPDFDictionaryRef d;
d = CGPDFPageGetDictionary(page);
CGPDFScannerRef myScanner;
CGPDFOperatorTableRef myTable;
myTable = CGPDFOperatorTableCreate();
CGPDFOperatorTableSetCallback (myTable, "MP", &op_MP);
CGPDFOperatorTableSetCallback (myTable, "DP", &op_DP);
CGPDFOperatorTableSetCallback (myTable, "BMC", &op_BMC);
CGPDFOperatorTableSetCallback (myTable, "BDC", &op_BDC);
CGPDFOperatorTableSetCallback (myTable, "EMC", &op_EMC);
CGPDFContentStreamRef myContentStream = CGPDFContentStreamCreateWithPage (page);// 3
myScanner = CGPDFScannerCreate (myContentStream, myTable, NULL);// 4
CGPDFScannerScan (myScanner);// 5
CGPDFStringRef str;
d = CGPDFPageGetDictionary(page);
if (CGPDFDictionaryGetString(d, "Lorem", &str)){
CFStringRef s;
s = CGPDFStringCopyTextString(str);
if (s != NULL) {
NSLog(#"%# testing it", s);
}
CFRelease(s);
}
}
- (void)viewDidLoad {
[super viewDidLoad];
MyDisplayPDFPage(UIGraphicsGetCurrentContext(), 1, [[[NSBundle mainBundle] pathForResource:#"TestPage" ofType:#"pdf"] UTF8String]);
}
Quartz provides functions that let you inspect the PDF document structure and the content stream. Inspecting the document structure lets you read the entries in the document catalog and the contents associated with each entry. By recursively traversing the catalog, you can inspect the entire document.
A PDF content stream is just what its name suggests—a sequential stream of data such as 'BT 12 /F71 Tf (draw this text) Tj . . . ' where PDF operators and their descriptors are mixed with the actual PDF content. Inspecting the content stream requires that you access it sequentially.
This developer.apple documentation shows how to examine the structure of a PDF document and parse the contents of a PDF document.

Parsing PDF documents with Quartz

I am trying to parse a PDF document with the Quartz framework and have copy & pasted the code snippets from the Apple documentation into my source code.
Unfortunately, it does not retrieve any data. It just iterates over the pages, logs the number of the current page to the console and crashes at the end.
Do you have any idea on what is wrong with the code?
static void op_MP (CGPDFScannerRef s, void *info)
{
const char *name;
if (!CGPDFScannerPopName(s, &name))
return;
printf("MP /%s\n", name);
}
static void op_DP (CGPDFScannerRef s, void *info)
{
const char *name;
if (!CGPDFScannerPopName(s, &name))
return;
NSLog(#"DP /%s\n", name);
}
static void op_BMC (CGPDFScannerRef s, void *info)
{
const char *name;
if (!CGPDFScannerPopName(s, &name))
return;
NSLog(#"BMC /%s\n", name);
}
static void op_BDC (CGPDFScannerRef s, void *info)
{
const char *name;
if (!CGPDFScannerPopName(s, &name))
return;
NSLog(#"BDC /%s\n", name);
}
static void op_EMC (CGPDFScannerRef s, void *info)
{
const char *name;
if (!CGPDFScannerPopName(s, &name))
return;
NSLog(#"EMC /%s\n", name);
}
static void op_TJ (CGPDFScannerRef s, void *info)
{
const char *name;
if (!CGPDFScannerPopName(s, &name))
return;
NSLog(#"TJ /%s\n", name);
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
CGPDFDocumentRef myDocument;
NSString *urlAddress = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"pdf"];
NSURL *fileUrl = [NSURL fileURLWithPath:urlAddress];
CFURLRef url = (__bridge CFURLRef)fileUrl;
myDocument = CGPDFDocumentCreateWithURL(url);
CFRelease (url);
if (myDocument == NULL) {// 2
NSLog(#"can't open `%#'.", fileUrl);
}
if (!CGPDFDocumentIsUnlocked (myDocument)) {// 4
CGPDFDocumentRelease(myDocument);
}
else if (CGPDFDocumentGetNumberOfPages(myDocument) == 0) {// 5
CGPDFDocumentRelease(myDocument);
}
else {
CGPDFOperatorTableRef myTable;
myTable = CGPDFOperatorTableCreate();
CGPDFOperatorTableSetCallback (myTable, "MP", &op_MP);
CGPDFOperatorTableSetCallback (myTable, "DP", &op_DP);
CGPDFOperatorTableSetCallback (myTable, "BMC", &op_BMC);
CGPDFOperatorTableSetCallback (myTable, "BDC", &op_BDC);
CGPDFOperatorTableSetCallback (myTable, "EMC", &op_EMC);
CGPDFOperatorTableSetCallback (myTable, "Tj", &op_TJ);
int k;
CGPDFPageRef myPage;
CGPDFScannerRef myScanner;
CGPDFContentStreamRef myContentStream;
int numOfPages = CGPDFDocumentGetNumberOfPages (myDocument);// 1
for (k = 0; k < numOfPages; k++) {
myPage = CGPDFDocumentGetPage (myDocument, k + 1 );// 2
myContentStream = CGPDFContentStreamCreateWithPage (myPage);// 3
myScanner = CGPDFScannerCreate (myContentStream, myTable, NULL);// 4
CGPDFScannerScan (myScanner);// 5
CGPDFPageRelease (myPage);// 6
CGPDFScannerRelease (myScanner);// 7
CGPDFContentStreamRelease (myContentStream);// 8
NSLog(#"processed page %i",k);
}
CGPDFOperatorTableRelease(myTable);
CGPDFDocumentRelease(myDocument);
}
return YES;
}
I did not run the code but the first 5 operators might not exist in your page content. Also some of them have a name operand, some of them do not have any operands (such as EMC). Also the Tj operator has a string operand, not a name.
Remove all the pop name methods and leave only the logging and you might get some output. Then look in the PDF specification to see the exact operands for each operator and update your code accordingly.
While I can't give you a solution to your example code crash, last time we needed to do this we based our parser on PDFKitten.
https://github.com/KurtCode/PDFKitten
If you are interested in the parsing code, the interesting stuff is located in Scanner.m:
https://github.com/KurtCode/PDFKitten/blob/master/PDFKitten/Scanner.m
Given the complexity of PDF parsing I would suggest working with this library as a base and moving from there. If you need a polished implementation on a deadline, then PSPDFKit is probably the most well-developed (but expensive) package.
It's about the CFRelease(url). Delete it and it will be okay.
"(__bridge T) op casts the operand to the destination type T. If T is a retainable object pointer type, then op must have a non-retainable pointer type."

Resources