[4.1.1例子][83页] iOSREHookTweak MSGetImageByName & MSFindSymbol 兩者皆失敗

环境:ios 8.1, iphone 5s, 64位元

大大们中午好,根据书上第4.1.1节的78 ~ 80页的tweak我在实作上始终失败。
发帖前已查过论坛内所有相关的文章,但是我是发现连最基本的%hook指令在我的这个tweak都抓不到目标class的viewDidLoad, 让我非常怀疑到底是哪裡设定错了?因为编译时可以成功。
在手机respring的时候会出现我自己添加的NSLog:
iOSRE: Not Found CPPFunction!
iOSRE: Not Found CFunction!
iOSRE: Not Found Short C Function!
之前有加过判断式log, 发现MSGetImageByName & MSFindSymbol都是失败的QQ但是我的/Applications/shortFunctionHookTest.app/shortFunctionHookTest是确实存在的啊

附圖:

烦请大大救救我了,感谢!

source code:

Makefile:

include $(THEOS)/makefiles/common.mk
ARCHS = armv7 arm64
TARGET = iphone:latest:8.1
THEOS_DEVICE_IP=127.0.0.1
THEOS_DEVICE_PORT=2222

APPLICATION_NAME = shortFunctionHookTest
shortFunctionHookTest_FILES = main.m XXAppDelegate.m XXRootViewController.mm
shortFunctionHookTest_FRAMEWORKS = UIKit CoreGraphics

include $(THEOS_MAKE_PATH)/application.mk

after-install::
	install.exec "su mobile -c uicache"
	install.exec "killall -9 SpringBoard"

XXRootViewController.mm:

#import "XXRootViewController.h"

class CPPClass
{
	public:
		void CPPFunction(const char *);
};

void CPPClass::CPPFunction(const char *arg0)
{
	for (int i = 0; i < 66; i++)
	{
		u_int32_t randomNumber;
		if (i % 3 == 0) randomNumber = arc4random_uniform(i);
		NSProcessInfo *processInfo = [NSProcessInfo processInfo];
		NSString *hostName = processInfo.hostName;
		int pid = processInfo.processIdentifier;
		NSString *globallyUniqueString = processInfo.globallyUniqueString;
		NSString *processName = processInfo.processName;
		NSArray *junks = @[hostName, globallyUniqueString, processName];
		NSString *junk = @"";
		for (int j = 0; j < pid; j++)
		{
			if (pid % 6 == 0) junk = junks[j % 3];
		}
		if (i % 68 == 1) NSLog(@"Junk %@", junk);
	}
	NSLog(@"iOSRE: CPPFunction: %s", arg0);
}

extern "C" void CFunction(const char *arg0)
{
	for (int i = 0; i < 66; i++)
	{
		u_int32_t randomNumber;
		if (i % 3 == 0) randomNumber = arc4random_uniform(i);
		NSProcessInfo *processInfo = [NSProcessInfo processInfo];
		NSString *hostName = processInfo.hostName;
		int pid = processInfo.processIdentifier;
		NSString *globallyUniqueString = processInfo.globallyUniqueString;
		NSString *processName = processInfo.processName;
		NSArray *junks = @[hostName, globallyUniqueString, processName];
		NSString *junk = @"";
		for (int j = 0; j < pid; j++)
		{
			if (pid % 6 == 0) junk = junks[j % 3];
		}
		if (i % 68 == 1) NSLog(@"Junk %@", junk);
	}
	NSLog(@"iOSRE: CFunction: %s", arg0);
}

extern "C" void ShortCFunction(const char *arg0)
{
	// ShortCFunction is too short to be hooked
	CPPClass cppClass;
	cppClass.CPPFunction(arg0);
}

@implementation XXRootViewController {
	NSMutableArray *_objects;
}

- (void)loadView {
	self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
	self.view.backgroundColor = [UIColor redColor];
}

- (void)viewDidLoad
{
	[super viewDidLoad];

	CPPClass cppClass;
	cppClass.CPPFunction("This is a c++ function!");
	CFunction("This is a C function!");
	ShortCFunction("This is a short C function!");
}

@end

Tweak.xm:

#import <substrate.h>

void (*old__ZN8CPPClass11CPPFunctionEPKc)(void *, const char *);
void new__ZN8CPPClass11CPPFunctionEPKc(void * hiddenThis, const char * arg0) {
    if (strcmp(arg0, "This is a short C function!") == 0) {
        old__ZN8CPPClass11CPPFunctionEPKc(hiddenThis, "This is a hijacked short C function from new__ZN8CPPClass11CPPFunctionEPKc");
    } else {
        old__ZN8CPPClass11CPPFunctionEPKc(hiddenThis, "This is a hijacked C++ function!");
    }
}


void (*old_CFunction) (const char *);
void new_CFunction(const char * arg0) {
    old_CFunction("This is a hijacked C function!");
}

void (*old_ShortCFunction)(const char *);
void new_ShortCFunction(const char *arg0) {
    old_CFunction("This is a hijacked short C function from new_ShortCFunction!");
}

// Test the hook function are work in very simple way, but not success.
%hook XXRootViewController
- (void)viewDidLoad
{
  %orig;
  NSLog(@"ZXXXX hook viewDidLoad success");
  old_CFunction("old_CFunction in viewDidLoad");
  new_CFunction("xxxxxxxx");
}
%end

%ctor
{
    @autoreleasepool {
        MSImageRef image = MSGetImageByName("/Applications/shortFunctionHookTest.app/shortFunctionHookTest");

        void *__ZN8CPPClass11CPPFunctionEPKc = MSFindSymbol(image, "__ZN8CPPClass11CPPFunctionEPKc");
        if(__ZN8CPPClass11CPPFunctionEPKc) {
            NSLog(@"iOSRE: Found CPPFunction!");
        } else {
            NSLog(@"iOSRE: Not Found CPPFunction!");
        }
        MSHookFunction((void *)__ZN8CPPClass11CPPFunctionEPKc, (void *)&new__ZN8CPPClass11CPPFunctionEPKc, (void **)&old__ZN8CPPClass11CPPFunctionEPKc);

        void *_CFunction = MSFindSymbol(image, "_CFunction");
        if (_CFunction) {
            NSLog(@"iOSRE: Found CFunction!");
        } else {
            NSLog(@"iOSRE: Not Found CFunction!");
        }
        MSHookFunction((void *)_CFunction, (void*)&new_CFunction, (void**)&old_CFunction);

        void *_ShortCFunction = MSFindSymbol(image, "_ShortCFunction");
        if (_ShortCFunction) {
            NSLog(@"iOSRE: Found Short C Function!");
        } else {
            NSLog(@"iOSRE: Not Found Short C Function!");
        }
        MSHookFunction((void *)_ShortCFunction, (void *)&new_ShortCFunction, (void **)&old_ShortCFunction);

    }
}

error log:

Oct 13 11:35:29 iPhone SpringBoard[15838]: LICreateIconForImage passed NULL CGImageRef image
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: MS:Notice: Injecting: com.yourcompany.shortfunctionhooktest [shortFunctionHookTest] (1141.16)
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: MS:Notice: Loading: /Library/MobileSubstrate/DynamicLibraries/0MobileGestaltFaker.dylib
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: MS:Notice: Loading: /Library/MobileSubstrate/DynamicLibraries/AppAnalyze.dylib
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: MS:Warning: nil class argument for selector configureWithApplicationID:
Oct 13 11:35:29 iPhone locationd[103]: Gesture EnabledForTopCLient: 0, EnabledInDaemonSettings: 0
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: MS:Warning: nil class argument for selector setAdUnitID:
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: MS:Warning: nil class argument for selector initWithAdUnitID:rootViewController:adTypes:options:
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: MS:Warning: nil class argument for selector setAdUnitID:
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: MS:Warning: nil class argument for selector initWithAdUnitID:
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: MS:Warning: nil class argument for selector loadRequest:withAdUnitID:
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: MS:Error: binary does not support this cpu type
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: MS:Error: failure to check GoldPPServer.dylib
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: MS:Notice: Loading: /Library/MobileSubstrate/DynamicLibraries/LamoClient.dylib
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: ZKSwizzle: Swizzling $_Lamo_UIApplication with UIApplication
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: MS:Notice: Loading: /Library/MobileSubstrate/DynamicLibraries/iGPasteBoard.dylib
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: MS:Notice: Loading: /Library/MobileSubstrate/DynamicLibraries/iGrimace.dylib
Oct 13 11:35:29 iPhone shortFunctionHookTest[15874]: assertion failed: 12B440: libxpc.dylib + 71820 [A4F17798-F3DE-3FBC-85E3-F569762F0EB9]: 0x7d
Oct 13 11:35:29 iPhone Unknown[15874]:
Oct 13 11:35:30 iPhone shortFunctionHookTest[15874]: Junk
Oct 13 11:35:30 iPhone shortFunctionHookTest[15874]: iOSRE: CPPFunction: This is a c++ function!
Oct 13 11:35:30 iPhone shortFunctionHookTest[15874]: Junk
Oct 13 11:35:30 iPhone shortFunctionHookTest[15874]: iOSRE: CFunction: This is a C function!
Oct 13 11:35:30 iPhone shortFunctionHookTest[15874]: Junk
Oct 13 11:35:30 iPhone shortFunctionHookTest[15874]: iOSRE: CPPFunction: This is a short C function!
Oct 13 11:35:30 iPhone locationd[103]: Gesture EnabledForTopCLient: 0, EnabledInDaemonSettings: 0
Oct 13 11:35:32 iPhone mstreamd[15868]: (Note ) mstreamd: Not monitoring for external power.
Oct 13 11:35:32 iPhone mstreamd[15868]: (Note ) PS: Media stream daemon stopping.
Oct 13 11:35:32 iPhone mstreamd[15868]: (Note ) AS: <MSIOSAlbumSharingDaemon: 0x13d57d4b0>: Shared Streams daemon has shut down.
Oct 13 11:35:32 iPhone mstreamd[15868]: (Warn ) mstreamd: mstreamd shutting down.
Oct 13 11:35:32 iPhone mstreamd[15876]: MS:Notice: Injecting: com.apple.mediastream.mstreamd [mstreamd] (1141.16)
Oct 13 11:35:32 iPhone mstreamd[15876]: MS:Notice: Loading: /Library/MobileSubstrate/DynamicLibraries/0MobileGestaltFaker.dylib
Oct 13 11:35:32 iPhone mstreamd[15876]: MS:Error: binary does not support this cpu type
Oct 13 11:35:32 iPhone mstreamd[15876]: MS:Error: failure to check GoldPPServer.dylib
Oct 13 11:35:32 iPhone mstreamd[15876]: (Note ) mstreamd: mstreamd starting up.
Oct 13 11:35:32 iPhone mstreamd[15876]: (Note ) PS: Media stream daemon starting...

@snakeninny 大神,能否給點方向,你有在其中一篇文章有提到對方應該要hook 目標app而不是spring board,但是在書本上並沒有%hook特定目標,而是直接在tweak裏 定義完old new function之後,直接使用%ctor去呼叫MSHooker系列方法。請問該如何調整呢?還是書上的程式碼已無法在arm64執行?

正确情况下,你的hook作用目标应是shortFunctionHookTest。你respring时,shortFunctionHookTest还未启动,但仍有输出,所以我猜测你把hook的作用目标误设定为了SpringBoard而不是shortFunctionHookTest

大神感谢您的回覆QQ

大大我的程式码 的确没有特别将作用目标hook在shortFunctionHooktest,因为书上只有写%ctor。

我如果在这个tweak特意加上以下的测试码:

%hook SpringBoard

// Hooking a class method

// Hooking an instance method with an argument.
- (void)applicationDidFinishLaunching:(id)application {
    %orig;

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hey, ZXXX new SUCCESS!!" message:nil delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    [alert release];
}
%end

他是可以正常运作的,我想表示这个hook可以正常地找到SpringBoard.h这个标头档。
大大您的意思是 我的%hook应该写成这样吗?

正确情况下,你的hook作用目标应是shortFunctionHookTest。你respring时,shortFunctionHookTest还未启动,但仍有输出,所以我猜测你把hook的作用目标误设定为了SpringBoard而不是shortFunctionHookTest

// Test the hook function are work in very simple way, but not success.
%hook shortFunctionHookTest
- (void)viewDidLoad
{
    %orig;
    NSLog(@"ZXXXX hook viewDidLoad success");

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hey, ZXXX SUCCESS in ZXSRootViewController!!" message:nil delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    [alert release];

    old_CFunction("old_CFunction in viewDidLoad");
    new_CFunction("xxxxxxxx");
}
%end

但是%hook shortFunctionHookTest没有成功,我记得%hook是写上该app裡的目标class档桉,所以我改回成他自己本身的class:

// Test the hook function are work in very simple way, but not success.
%hook ZXSRootViewController
- (void)viewDidLoad
{
    %orig;
    NSLog(@"ZXXXX hook viewDidLoad success");

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hey, ZXXX SUCCESS in ZXSRootViewController!!" message:nil delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    [alert release];

    old_CFunction("old_CFunction in viewDidLoad");
    new_CFunction("xxxxxxxx");
}
%end

以上的测试码都不成功,我该如何去哪裡修正hook的目标到正确的app上呢?

附上目前尝试修改的程式码 (但依然是失败的):

#import <substrate.h>

void (*old__ZN8CPPClass11CPPFunctionEPKc)(void *, const char *);
void new__ZN8CPPClass11CPPFunctionEPKc(void * hiddenThis, const char * arg0) {
    if (strcmp(arg0, "This is a short C function!") == 0) {
        old__ZN8CPPClass11CPPFunctionEPKc(hiddenThis, "This is a hijacked short C function from new__ZN8CPPClass11CPPFunctionEPKc");
    } else {
        old__ZN8CPPClass11CPPFunctionEPKc(hiddenThis, "This is a hijacked C++ function!");
    }
}

void (*old_CFunction) (const char *);
void new_CFunction(const char * arg0) {
    old_CFunction("This is a hijacked C function!");
}

void (*old_ShortCFunction)(const char *);
void new_ShortCFunction(const char *arg0) {
    old_CFunction("This is a hijacked short C function from new_ShortCFunction!");
}

// Test the hook function are work in very simple way, but not success.
%hook ZXSRootViewController
- (void)viewDidLoad
{
    %orig;
    NSLog(@"ZXXXX hook viewDidLoad success");

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hey, ZXXX SUCCESS in ZXSRootViewController!!" message:nil delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    [alert release];

    old_CFunction("old_CFunction in viewDidLoad");
    new_CFunction("xxxxxxxx");
}
%end

%ctor
{
    @autoreleasepool {
        MSImageRef image = MSGetImageByName("/Applications/shortFunctionHookTest.app/shortFunctionHookTest");

        void *__ZN8CPPClass11CPPFunctionEPKc = MSFindSymbol(image, "__ZN8CPPClass11CPPFunctionEPKc");
        if(__ZN8CPPClass11CPPFunctionEPKc) {
            NSLog(@"iOSRE: Found CPPFunction!");
        } else {
            NSLog(@"iOSRE: Not Found CPPFunction!");
        }
        MSHookFunction((void *)__ZN8CPPClass11CPPFunctionEPKc, (void *)&new__ZN8CPPClass11CPPFunctionEPKc, (void **)&old__ZN8CPPClass11CPPFunctionEPKc);

        void *_CFunction = MSFindSymbol(image, "_CFunction");
        if (_CFunction) {
            NSLog(@"iOSRE: Found CFunction!");
        } else {
            NSLog(@"iOSRE: Not Found CFunction!");
        }
        MSHookFunction((void *)_CFunction, (void*)&new_CFunction, (void**)&old_CFunction);

        void *_ShortCFunction = MSFindSymbol(image, "_ShortCFunction");
        if (_ShortCFunction) {
            NSLog(@"iOSRE: Found Short C Function!");
        } else {
            NSLog(@"iOSRE: Not Found Short C Function!");
        }
        MSHookFunction((void *)_ShortCFunction, (void *)&new_ShortCFunction, (void **)&old_ShortCFunction);

    }
}

@snakeninny 跪謝大神!!!!! 我懂你說的話了,在創建新的tweak的時候有一個選項可以填入[iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]:

我平常都是空白的,因為只是做練習在springboard 難怪都會成功,後來我去find一下找到plist可以修改當初的初始值,改成目標app之後,就成功拉拉啦啦啦,太感謝您了,折騰兩天。:)