why I can't hook my private function with fishhook - ios

These days, I found that hook in an iOS application is hard, and found that there is a tool called "fishhook", created by facebook. I import the tool in my personal project, but it doesn't work. Am I wrong? Here are the source code:
#import <dlfcn.h>
#import <Foundation/Foundation.h>
#import "fishhook.h"
static void (*orig_testABC)(void);
void testABC()
{
NSLog(#"This is main log...");
}
void my_testABC()
{
NSLog(#"This is other log, not main log...");
}
void save_original_symbols()
{
// void *handle = dlopen("/Users/bianyiji/Library/Developer/Xcode/DerivedData/HookTest-ghlgmahvsgfbqeekbrouzdyoxgdw/Build/Intermediates/HookTest.build/Debug/HookTest.build/Objects-normal/x86_64/main.o", RTLD_LAZY);
// printf("%s\n", handle);
orig_testABC = dlsym(RTLD_DEFAULT, "testABC");
}
int main(int argc, const char * argv[]) {
#autoreleasepool {
// save_original_symbols();
int rebind_int = rebind_symbols((struct rebinding[1]){"testABC", my_testABC}, 1);
printf("%d\n", rebind_int);
}
testABC();
return 0;
}
Although I called the function "testABC()", but I use "rebind_symbols" before, why I can't get my expected result...

fishhook isn't meant to hook into private functions, because fishhook works by rebinding symbols that are present in the symbol table.
for hooking private functions you need read-write access in the executable memory pages of your running app, and this is obviously not possible for security reasons.
however, in jailbroken iOS, the kernel has a patch that allows this, so you can hook private functions with frameworks such as CydiaSubstrate or substitute. But fishhook does not support this and probably never will, also if it did would never be AppStore-friendly.
Source: our open-source SSL pinning library TrustKit uses fishhook and we introduced it at BlackHat 2015 elaborating an all these topics.

Related

Register for Darwin Notification and send event details via Callback - Codename One

I am trying to create a test App with Codename One that listens out for displayStatus change via Darwin Notifications and sends the events via callback to the Java side. I have very very little knowledge of C and almost no knowledge of objective C so most of the code i have for that part was lifted and joined from several places in the web. I have followed the developer guide but the build fails on the cloud. So far i have done the following:
In my start method i have this:
public void start() {
if(current != null){
current.show();
return;
}
Form hi = new Form("Xerveur", new LayeredLayout());
hi.add(buildRootContainer()).add(buildRootChildContainer());
Display.getInstance().callSerially(hi::show);
registerForNativeCallback();
}
This registers for the native interface:
private void registerForNativeCallback(){
NativeListener listener = NativeLookup.create(NativeListener.class);
if( listener != null && listener.isSupported() ){
Log.p("Setup Event Listener returned: " + listener.setupEventListener());
}
}
The above code snippets are in the main class file. The NativeListener interface is simple:
public interface NativeListener extends NativeInterface {
public boolean setupEventListener();
}
Now i have a simple callback class which is supposed to receive a string, having the required information from the native side:
public class NativeCallback {
public static void receive(String payload){
Log.p(payload);
}
}
These are the contents of the ".m" file that was generated (the ".h" file is unmodified from what was auto-generated) and i edited:
#import "ca_ratelsoft_testing_testapp2_NativeListenerImpl.h"
#include "ca_ratelsoft_testing_testapp2_NativeCallback.h"
#include "CodenameOne_GLViewController.h"
#include <unistd.h> // good idea in general
#include <stdlib.h> // good idea in general
#include <CoreFoundation/CoreFoundation.h>
#include <notify.h> // for all notifications
#implementation ca_ratelsoft_testing_testapp2_NativeListenerImpl
-(BOOL)setupEventListener{
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
NULL, // observer
displayStatusChanged, // callback
CFSTR("com.apple.springboard.displayStatus"), // event name
NULL, // object
CFNotificationSuspensionBehaviorDeliverImmediately);
return YES;
}
static void displayStatusChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
NSLog(#"event received!");
// you might try inspecting the `userInfo` dictionary, to see
// if it contains any useful info
if (userInfo != nil) {
const void * keys;
const void * values;
NSString *payload = #"displayStatus$$$"; //delimeter: $$$
CFDictionaryGetKeysAndValues(userInfo, &keys, &values);
//key1=value1;key2=value2;
for (int i = 0; i < CFDictionaryGetCount(userInfo); i++) {
const char * keyStr = CFStringGetCStringPtr((CFStringRef)&keys[i], CFStringGetSystemEncoding());
const char * valStr = CFStringGetCStringPtr((CFStringRef)&values[i], CFStringGetSystemEncoding());
if( i > 0 )
payload = [payload stringByAppendingString:#";"];
payload = [payload stringByAppendingString:#(keyStr)];
payload = [payload stringByAppendingString:#"="];
payload = [payload stringByAppendingString:#(valStr)];
}
ca_ratelsoft_testing_testapp2_NativeCallback_receive___java_lang_String(CN1_THREAD_GET_STATE_PASS_ARG fromNSString(CN1_THREAD_GET_STATE_PASS_ARG payload));
}
}
-(BOOL)isSupported{
return YES;
}
#end
I get the following error when building a debug iOS app: https://www.dropbox.com/s/sq8f00nzf445gp0/f9e35511-c43f-4bb6-854a-f513ec8e3820-1500397464685-error.txt?dl=0
First lets start with the error, if you scroll to the bottom you will see NativeListenerImpl.o is mentioned. If you search for NativeListenerImpl in the file you will see the compilation code for that and the actual error right below it:
src/ca_ratelsoft_testing_testapp2_NativeListenerImpl.m:2:10: fatal error: 'ca_ratelsoft_testing_testapp2_NativeCallback.h' file not found
#include "ca_ratelsoft_testing_testapp2_NativeCallback.h"
^
1 error generated.
This happens because our optimizer is over eager to remove unused code and can't find the usage of callback. You can solve this by adding the following code to your main class:
boolean fakeVariable;
public void init(Object o) {
// ... rest of code
if(fakeVariable) {
NativeCallback.receive(null);
}
}
This is important. Don't make the variable private!!!
The variable is package protected and will always be false so that code will never occur. In theory some code can change that flag so the optimizer can't detect that and will be forced to leave that code in place.

Which threading mode is Sqlite for iOS compiled in Swift?

The page http://www.sqlite.org/threadsafe.html mentions:
Single-thread
Multi-thread
Serialized
How can we implement that threads in Swift. Or how to use sqlite3_config(SQLITE_CONFIG_MULTITHREAD in Swift
Instead of sqlite3_config you can add the required options when opening the database. This is only available for sqlite3_open_v2, not for sqlite3_open or sqlite3_open16.
Here is an example:
let rc = sqlite3_open_v2(databasePath, &db, SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_FULLMUTEX, nil)
For anyone who ended up here looking for a way to call sqlite3_config (regardless of the threading question) using the built-in SQLite3 module...
The reason it's not available is that it uses ellipsis-style variadic arguments, which according to this are not supported in Swift. One way to get around this is to make your own C header with wrapper functions for calling sqlite3_config with whatever (non-variadic) argument arrangement you need.
For example, a "bridging header" with something like this covers all the valid call signatures you might need (as far as what the SQLite config options require):
#ifndef SqliteConfig_h
#define SqliteConfig_h
#import "sqlite3.h"
static inline int sqlite3_config_no_args(int op) {
return sqlite3_config(op);
}
static inline int sqlite3_config_ptr(int op, void* arg1) {
return sqlite3_config(op, arg1);
}
static inline int sqlite3_config_int(int op, int arg1) {
return sqlite3_config(op, arg1);
}
static inline int sqlite3_config_ptr_int_int(int op, void* arg1, int arg2, int arg3) {
return sqlite3_config(op, arg1, arg2, arg3);
}
static inline int sqlite3_config_int_int(int op, int arg1, int arg2) {
return sqlite3_config(op, arg1, arg2);
}
static inline int sqlite3_config_ptr_ptr(int op, void* arg1, void* arg2) {
return sqlite3_config(op, arg1, arg2);
}
#endif /* SqliteConfig_h */
Maybe there are cleaner or more idiomatic ways to create these kinds of wrappers (rather than static-inline functions in a bridging header). I'm not an expert in this area. But considering they're just wrapping calls, it seems like a good lightweight workaround.
You can search around for more info on bridging headers if you don't know how to create one. But in short: You can create a bridging header "manually" (after creating your .h file) by going to Build Settings/Swift Compiler - General/Objective-C Bridging Header and setting the value to the header filename you created. If you don't do that, your .h file is ignored. Or you could create one automatically (without going into the compiler settings) by dragging a dummy .c file into the project, deleting that file, and then editing the header it created. Or do that with a "real" C file if you prefer your code there rather than inline.
With that in place, here's an example of using sqlite3_config to install your own logging callback:
import SQLite3
func errorLogCallback(_: OpaquePointer?, iErrCode: Int, zMsg: UnsafePointer<CChar>)
{
let s = String(cString: zMsg)
print("LOG:", iErrCode, s)
}
let cCallbackPtr: #convention(c) (OpaquePointer?, Int, UnsafePointer<CChar>) -> () = errorLogCallback
let rawPtr = unsafeBitCast(cCallbackPtr, to: UnsafeMutableRawPointer.self)
sqlite3_config_ptr_ptr(SQLITE_CONFIG_LOG, rawPtr, nil)

How to implement PT_DENY_ATTACH (anti-debugging in iOS )

PT_DENY_ATTACH is an anti-debugging feature that helps prevent debuggers from attaching to the app. Following code can be implemented in main() to prevent GDB from attaching to the application. :
#import <dlfcn.h>
#import <sys/types.h>
typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data);
#define PT_DENY_ATTACH 31
void disable_gdb() {
void* handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW);
ptrace_ptr_t ptrace_ptr = dlsym(handle, "ptrace");
ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0);
dlclose(handle);
}
int main(int argc, char *argv[]) {
#autoreleasepool {
#ifdef DEBUG
//do nothing
#else
disable_gdb();
#endif
}}
Guys it is true that this trick has been worked around and can be bypassed by overriding but have a look at that
Here the guys from iphonedevwiki.net are showing another way to implement the same thing in assembly, making it much harder to be patched. So to bypass this assembly implementation one has to have the Mach-O binary decrypted and override the implementation of the function, for example an attacker could swap all assembly instructions from the function with only nop instructions which do nothing. But if you obfuscate your assembly routine, it will be much harder for attacker to recognise what is happening, so only the most experienced folks will be able bypass that.
For those of you who don't know how to write assembly in Swift 5 project, here is what you will need to do:
Create a new C File + Header
lets name them disable_debuggers_advanced.c and disable_debuggers_advanced.h
In disable_debuggers_advanced.c add the following:
#include "disable_debug_advanced.h"
void mRiYXNnZnZmZGF2Ym() {
// No Need to encode these strings, because they will be directly compiled, they are not going to be present in the 'DATA' segment of the binary.
__asm (
"mov r0, #31\n" // set #define PT_DENY_ATTACH (31) to r0
"mov r1, #0\n" // clear r1
"mov r2, #0\n" // clear r2
"mov r3, #0\n" // clear r3
"mov ip, #26\n" // set the instruction pointer to syscal 26
"svc #0x80\n" // SVC (formerly SWI) generates a supervisor call. Supervisor calls are normally used to request privileged operations or access to system resources from an operating system
);
}
In disable_debuggers_advanced.h add the following:
#ifndef disable_debug_advanced_h
#define disable_debug_advanced_h
#include <stdio.h>
/**
Original name: `disable_gdb_advanced()`
This function makes the process deny the attaching request by debugers by
simulating what is already available on macOS:
ptrace(PT_DENY_ATTACH, 0, 0, 0);
by implementing it directly in assembly language.
This method of disabling debugers is well known to attackers but there is nothing they can do to easily bypass it
because it is a part of the kernel memory space.
Please note that this will make XCode not being able to attach its debuger to the process too,
so run it only in release builds.
source: https://iphonedevwiki.net/index.php/Crack_prevention#PT_DENY_ATTACH
*/
void mRiYXNnZnZmZGF2Ym(void) __attribute__((always_inline));
#endif /* disable_debug_advanced_h */
Add #include "disable_debug_advanced.h" to your bridging header and a bridging header if your project does not already have one.
Now you can call this function to disable debuggers.
Note that this will break even the XCode debugger, so use it only on release builds
If you are wondering about the __attribute__((always_inline)) part and the weird name it is because we want our function to be hidden as much as possible. If you are not familiar with function inlining, you can watch my video about function inlining here where i describe it in depth or you can read in wikipedia about it. Even thought it is a speed compiler optimisation, it could give us benefits here because if you call it from multiple locations it will be harder for attacker to patch all function body copies in the app.
And the name is written like this, because this inlining is just a hint to the compiler, it is not guaranteed that it will happen. And if it does not happen and our function for disabling the debugger is clearly defined in the TEXT segment of our binary, we want it to be at least with obfuscated name, so that no one could guess what it does just by reading its assembly label.
In my opinion one should call this as a top level function even before the UIApplication object is created.
In order to do that:
Add a new file to your Swift project and name it 'main.swift' (NAME IS IMPORTANT)
Remove the #UIApplicationMain tag from your AppDelegates class definition.
In your main.swift file write the following:
mRiYXNnZnZmZGF2Ym() // disable debuggers
// initialises the UIApplication and fires the event loop.
// This function never returns!
UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(AppDelegate.self))
If you want to see a video of how to execute top level code in main.swift, you can see me doing it on this video
In attempt to make it even more obfuscated and harder to crack, one could use assembly obfuscators like this one Movfuscator so that only a few people would be able to recognise what these assembly instructions mean.
Note: according to the wiki page of this tool, it has been workearound and must not be used:
IMPORTANT NOTE: This trick has been worked around by pirates. Don't rely on it!
Assuming you are referring to a Hybrid application created in MobileFirst Studio 7.1 - this, well, is not different than any other iOS app.
The end result of a Hybrid app, is still an Xcode project that you open in Xcode in order to build the application. This means then that you need to place your code in the same place in the Xcode project as if this was a regular Xcode project (which, it is), per the wiki page for PT_DENY_ATTACH.
As noted by #Idan Adar - this trick is workedAround, but in case u want to try it in any education or some other purpose u can try do following:
add define for u'r app to allow u run and debug if needed
#define SOME
add following code in main.m
#define SOME
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#ifdef SOME
#import <dlfcn.h>
#import <sys/types.h>
typedef int (*ptrace_ptr_t)(int request, pid_t pid, caddr_t addr, int data);
#if !defined(PT_DENY_ATTACH)
#define PT_DENY_ATTACH 31
#endif // !defined(PT_DENY_ATTACH)
void disable_gdb();
int main(int argc, char *argv[])
{
// disable_gdb();
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
void disable_gdb()
{
void* handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW);
ptrace_ptr_t ptrace_ptr = dlsym(handle, "ptrace");
ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0);
dlclose(handle);
}
int main3(int argc, char *argv[])
{
return -1;
}
#else
int main(int argc, char *argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
#endif
Here - some good points to start about
I saw this question has not marked correct answered yet. I already use below code block to use anti-debugging. Please open your main.m file to added below code snipped.
#import "AppDelegate.h"
#import "Application.h"
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sysctl.h>
#include <stdlib.h>
typedef int (*PYStdWriter)(void *, const char *, int);
static PYStdWriter _oldStdWrite;
#define PT_DENY_ATTACH 31
int __pyStderrWrite(void *inFD, const char *buffer, int size)
{
if ( strncmp(buffer, "AssertMacros:", 13) == 0 ) {
return 0;
}
return _oldStdWrite(inFD, buffer, size);
}
static int is_debugger_present(void)
{
int name[4];
struct kinfo_proc info;
size_t info_size = sizeof(info);
info.kp_proc.p_flag = 0;
name[0] = CTL_KERN;
name[1] = KERN_PROC;
name[2] = KERN_PROC_PID;
name[3] = getpid();
if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) {
perror("sysctl");
exit(-1);
}
return ((info.kp_proc.p_flag & P_TRACED) != 0);
}
int main(int argc, char *argv[]) {
#ifdef DEBUG
_oldStdWrite = stderr->_write;
stderr->_write = __pyStderrWrite;
#autoreleasepool {
return UIApplicationMain(argc, argv, NSStringFromClass([Application class]), NSStringFromClass([AppDelegate class]));
}
#else
//Anti Debugging Code
//https://coredump.gr/articles/ios-anti-debugging-protections-part-2/
//ptrace(PT_DENY_ATTACH, 0, 0, 0);
printf("Looping forever");
fflush(stdout);
while (1)
{
sleep(1);
if (is_debugger_present())
{
//[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"isAntiDebug"];
printf("Debugger detected! Terminating...\n");
return -1;
}
printf(".");
fflush(stdout);
_oldStdWrite = stderr->_write;
stderr->_write = __pyStderrWrite;
#autoreleasepool {
//[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"isAntiDebug"];
int retVal = UIApplicationMain(argc, argv, NSStringFromClass([Application class]), NSStringFromClass([AppDelegate class]));
return retVal;
}
}
#endif
}
As pointed out by Stoyan. Your implementation could be easily bypassed. You should add an assembly code. Just one missing thing from the above answer is that you have to add arm64 macro or you will not be able to build your project on simulators (OS X are using x86_64 arch)
So add this:
#if defined (__arm64__)
__asm(
"mov x0, #26\n" // ptrace
"mov x1, #31\n" // PT_DENY_ATTACH
"mov x2, #0\n"
"mov x3, #0\n"
"mov x16, #0\n"
"svc #128\n"
);
I wrote a simple guide for this. Check it out

UnitySendMessage doesn't work on iOS

I was trying to send some data using UnitySendMessage in iOS plugin, but it seem like it doesn't do anything, i don't see any errors and response. I checked function where UnitySendMessage is located, and i'm 100% sure that it starts.
- (void) callback{
NSLog(#"UNITY test callback");
UnitySendMessage("PluginTest", "listener", "test callback");
}
On scene i have gameObject named PluginTest with pluginListener component which contains method:
public void listener(string parameter)
{
print(parameter);
}
I also added to UnityAppController.mm this line, which was recommended to add in some post:
extern void UnitySendMessage(const char *, const char *, const char *);
I have no idea what i'm doing wrong, unitySendMessage seems like it should work without much effort.
Any help will be appreciated

Is there a method to allow pure c file to use <Metal/Metah.h>?

In other words, could ios's metal be used in pure c file? Thanks for reviewing.
The Metal API is Objective-C, however that shouldn't present a problem as you can provide C functions within Objective-C implementation files so the rest of your C-based code can call these functions.
For example (I don't know the Metal API, so this is gibberish):
metalapi.h:
// This is a C function...
extern int doThingWithMetal(int someParam, const char *otherParam);
metalapi.m:
#import <Metal/Metal.h>
// ... implemented in Objective-C
int doThingWithMetal(int someParam, const char *otherParam)
{
return [someMetalClass someMethod:someParam] == SOME_VALUE ? 0 : 1;
}
otherfile.c
#include "metalapi.h"
....
if (doThingWithMetal(1, "Hello") == 0) {
...
}

Resources