Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

preface

Before we begin with Theos, let’s review Logos grammar

Logos is part of Theos’s development component, which makes writing functional hook code very simple and clear with a special set of preprocessing instructions. Logos is shipped with Theos

  • %hook Specifies the name of the class that needs a hook, ending with %end
  • %log Is used to print logs and input information to syslog, for example, %log((NSString *)@”ZeluLi”)
  • %orig executes the raw code of the hook function, similar to the super.method function
  • %group this directive is used to group % hooks. %group is followed by the group name. %group must also end with %end, which can contain multiple % hooks
  • The %init directive is used to initialize a %group. A group cannot take effect until it is initialized, and init must be executed in a hook.
  • The %ctor tweak constructor, used to initialize. If not explicitly defined, Theos automatically generated a %ctor in which it called %init(_ungrouped). %ctor {%init(_ungrouped)}
  • %new This directive is used to add a new function to an existing class. Same as class_addMethod in Runtime.
  • %c This directive gets the name of a class, equivalent toobjc_getClass.

I Files in the project directory

New project command: $THEOS/bin/nic.pl

$ $THEOS/ bin/nic. Pl nic 2.0 - New Instance Creator -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- [1] iphone/activator_event [2] iphone/application_modern [3.] iphone/cydget [4.] iphone/flipswitch_switch [5.] iphone/framework [6.] iphone/ios7_notification_center_widget [7.] iphone/library [8.] iphone/notification_center_widget [9.] iphone/preference_bundle_modern [10.] iphone/tool [11.] iphone/tweak [12.] iphone/xpc_service Choose a Template (required): 11 Project Name (required): testTweakDemo Package Name [com.yourcompany.testtweakdemo]: Author/Maintainer Name [devzkn]: [iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]: com.apple.UIKit [iphone/tweak] List of applications to terminate upon installation (space-separated,The '-' for none) [SpringBoard]: 
Instantiating iphone/tweak in testtweakdemo/...
Done.

Copy the code

Package Name: deb Package Name Bundle filter: Tweak target app Bundle identifier

For example, the bundle Id of wechat is com.tentcent.xin

IOS desktop app bundle Id: com.apple.springboard tweak for all apps, then the bundle filter should be com.apple.UIKit ‘

When a new project is created, four files are generated: Control, plist, Makefile, tweake.xm. What are they used for?

$ ls -lrt
total 32
-rw-r--r--  1 devzkn  staff    51 Aug 10 17:07 testTweakDemo.plist
-rw-r--r--  1 devzkn  staff   223 Aug 10 17:07 control
-rw-r--r--  1 devzkn  staff  1045 Aug 10 17:07 Tweak.xm
-rw-r--r--  1 devzkn  staff   189 Aug 10 17:07 Makefile
Copy the code

1.1 the control file


Control information about the file store project: name, version, developer

Package: com. Yourcompany. Testtweakdemo Name: testtweakdemo Depends: mobilesubstrate Version: 0.0.1 Architecture: iphoneos-arm Description: An awesome MobileSubstrate tweak! Maintainer: devzkn Author: devzkn Section: TweaksCopy the code

1.2 file

devzkndeMacBook-Pro:testtweakdemo devzkn$ more  testTweakDemo.plist
{ Filter = { Bundles = ( "com.apple.UIKit" ); }; }
Copy the code

The plist file is used to set the bundle Id of the target app. If the tweak wants to inject multiple apps, the bundle Id is added to the Bundle array.

1.3 Makefile

$ more Makefile
include $(THEOS)/makefiles/common.mk

TWEAK_NAME = testTweakDemo
testTweakDemo_FILES = Tweak.xm

include $(THEOS_MAKE_PATH)/tweak.mk

after-install::
        install.exec "killall -9 SpringBoard"
devzkndeMacBook-Pro:testtweakdemo devzkn$
Copy the code

Makefile sets the files, frames, and libraries to use.

  1. testTweakDemo_FILES Sets the files that the project needs to reference, separated by Spaces. Format: Project name FILES = File name to compile
testTweakDemo_FILES = Tweak.xm MyClass1.m MyClass2.m
Copy the code
  1. include $(THEOS)/makefiles/common.mk

Many of the key variables are in common.mk

  1. Project name _FRAMEWORKS: sets the third-party libraries that the project needs to reference, separated by Spaces:

Project name _FRAMEWORKS = UIKit UIFoundation

4.after-install

Auxiliary tasks performed after tweak installation, such as killing the target process, allow CydiaSubstrate to load the corresponding dylib during the process restart.

1.4 Tweak. Xm

Used to write the injected code, where %hook,% ORIg, and %log are macroencapsulation of the functions provided by TheOS on Cydia Substrate. See Cydia_Substrate for an introduction to the methods provided by Cydia Substrate.

MobileHooker is used to replace system functions. This process is known as hooking. There are 2 APIs that one would use:

IMP MSHookMessage(Class class, SEL selector, IMP replacement, const char* prefix); // prefix should be NULL.
void MSHookMessageEx(Class class, SEL selector, IMP replacement, IMP *result);
void MSHookFunction(void* function, void* replacement, void** p_original);
Copy the code

Tweak. Xm file name suffix X

  1. Tweak. Xm file name suffix X stands for Logos syntax support,

If only one X means that the source file supports Logos and C syntax; If xM, the source file supports Logos and C/C++ syntax.

2. The %hook,%orig,%log, etc. are supported by Logos syntax

$ more  Tweak.xm
/* How to Hook with Logos
Hooks are written with syntax similar to that of an Objective-C @implementation.
You don't need to #include <substrate.h>, it will be done automatically, as will
the generation of a class list and an automatic constructor.

%hook ClassName

// Hooking a class method
+ (id)sharedInstance {
        return %orig;
}

// Hooking an instance method with an argument.
- (void)messageName:(int)argument {
        %log; // Write a message about this call, including its class, name and arguments, to the system log.

        %orig; // Call through to the original function with its original arguments.
        %orig(nil); // Call through to the original function with a custom argument.

        // If you use %orig(), you MUST supply all arguments (except for self and _cmd, the automatically generated ones.)
}

// Hooking an instance method with no arguments.
- (id)noArguments {
        %log;
        id awesome = %orig;
        [awesome doSomethingElse];

        return awesome;
}

// Always make sure you clean up after yourself; Not doing so could have grave consequences!
%end
*/

Copy the code

1.5 Compile and install the DEB

Use the make package command to compile, where the deb installation files generated for each successful compilation are kept in the Packages folder. When theOS is compiled, it generates a deb package that can be installed on your phone in several ways:

  1. Install using iFile

Use iTools and other tools to copy this deb package to your phone and install it using iFile browsing.

  1. Install using SSH.

To use the OpenSSH service, make sure you have it installed on your phone (search for Installing OpenSSH in Cydia). This setup requires adding your phone’s IP address ‘THEOS_DEVICE_IP = 10.200.201.22’ (phone’s local IP) at the beginning of the Makefile.

Make sure that the iOS device and Mac are on the same LAN and network segment, open the terminal, first CD to your project directory, and then type ‘make Package install’

`

‘3. Install from cydia source

Kunnan.blog.csdn.net/article/det…

`

1.6 SSH Without Entering a Password

Blog.csdn.net/z929118967/…

Use the make package install command to compile, package, and install all at once. This process may require you to enter the SSH root password twice (once to sign the package and once to install).

Brew Install openssh(brew install openssl) and ssh-copy-id(brew install ssh-copy-id) [Optional]

  1. To create an RSA file, run the following command: ssh-keygen -t rsa -b 2048 Enter the directory and file name for storing keygen as prompted

  2. Configure SSH config

# Private 192.168.2.125
Host iPhone
HostName  192.168.2.125
User root 
IdentityFile ~/.ssh/id_rsa_Theos125
Copy the code
  1. Add the corresponding public key to the corresponding remote server:ssh-copy-idNever give away your private key! Just copy the public key (*.pub file) to the remote server;ssh-copy-id root@<iP Address of your device>

Ssh-copy-id Specifies the authentication file. $ssh-copy-id -i id_rsa_Theos125 [email protected]

$ssh-copy-id [email protected] /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed:"/Users/devzkn/.ssh/id_rsa_Theos.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- ifYou are prompted now it is to install the new keys [email protected]'s password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.
Copy the code

II FaQs

2.1 Fault 1: The compression mode is not supported

The reason is that there are two different versions of DPKG and the latest version does not support LZMA.

$ make package
> Making all forTweak testTweakDemo... = = > Preprocessing Tweak. Xm... = = > the Compiling Tweak. Xm (armv7)... Linking tweak testTweakDemo (armv7)... clang: warning: libstdc++ is deprecated; Move to libc++ with a minimum deployment target of iOS 7 [-wdeprecated] ==> Preprocessing Tweak. Xm... = = > the Compiling Tweak. Xm (arm64)... Linking tweak testTweakDemo (arm64)... clang: warning: libstdc++ is deprecated; Move to libc++ with a minimum deployment target of iOS 7 [-wdeprecated] ==> Merging tweak testTweakDemo... = = > Signing testTweakDemo... > Making stageforTweak testTweakDemo... dpkg-deb: error: obsolete compressiontype 'lzma'; use xz instead

Type dpkg-deb --help for help about manipulating *.deb files;
Type dpkg --help for help about installing and deinstalling packages.
make: *** [internal-package] Error 2
Copy the code

Solution: Change LZMA to XZ

$ find /opt/theos -type f -name "*.mk" | xargs grep "lzma"/opt/theos/makefiles/package/deb.mk:_THEOS_PLATFORM_DPKG_DEB_COMPRESSION ? = lzmaCopy the code

Modify/opt/theos/makefiles/package/deb. Mk behavior _THEOS_PLATFORM_DPKG_DEB_COMPRESSION 6? = xz

  • Another option is to use the old version directly, with the following command:

Debian ‘DPKG’ Package Management Program Version 1.18.24 (Darwin – Amd64).

Brew Switch DPKG 1.18.10 Brew Link DPKG Brew PIN DPKG 1.18.10Copy the code

Verify repair

$ make package
> Making all forTweak testTweakDemo... make[2]: Nothing to bedone for `internal-library-compile'. > Making stage for tweak testTweakDemo... dpkg-deb: building package 'com.yourcompany.testtweakdemo' in '. / packages/com. Yourcompany. Testtweakdemo_0. 0.1 2 + debug_iphoneos - arm. Deb'.
Copy the code

If only XZ is changed, an error will still be reported during installation:

[email protected]'s password: 
Selecting previously unselected package com.yourcompany.testtweakdemo.
(Reading database ... 1848 files and directories currently installed.)
Preparing to unpack /tmp/_theos_install.deb ...
Unpacking com.yourcompany.testtweakdemo (0.0.1-8+debug) ...
dpkg-deb (subprocess): unable to execute decompressing archive member (xz): No such file or directory
dpkg-deb (subprocess): subprocess decompressing archive member returned error exit status 2
dpkg-deb: error: subprocess <decompress> returned error exit status 2
dpkg: error processing archive /tmp/_theos_install.deb (--install):
 subprocess dpkg-deb --fsys-tarfile returned error exit status 2
Errors were encountered while processing:
 /tmp/_theos_install.deb
make: *** [internal-install] Error 1
Copy the code

This error may occur if lzMA ->xz is used. The solution is lzMA ->gzip.

_THEOS_PLATFORM_DPKG_DEB_COMPRESSION ? =gzipCopy the code

Verify success

$ make package install
> Making all forTweak testTweakDemo... make[2]: Nothing to bedone for `internal-library-compile'. > Making stage for tweak testTweakDemo... dpkg-deb: building package 'com.yourcompany.testtweakdemo' in '. / packages/com. Yourcompany. Testtweakdemo_0. 0.1-9 + debug_iphoneos - arm. Deb'. = = > Installing... [email protected] 's password: (Reading database ... 1848 files and directories currently installed.) Preparing to unpack /tmp/_theos_install.deb ... Unpacking com. Yourcompany. Testtweakdemo (0.0.1-9 + debug)... Setting up com. Yourcompany. Testtweakdemo (0.0.1-9 + debug)... install.exec"killall -9 SpringBoard"
[email protected]'s password: 
Copy the code

2.2 Problem 2:THEOS_DEVICE_IP is incorrectly set

$ make package install
> Making all forTweak testTweakDemo... make[2]: Nothing to bedone for `internal-library-compile'. > Making stage for tweak testTweakDemo... dpkg-deb: building package 'com.yourcompany.testtweakdemo' in '. / packages/com. Yourcompany. Testtweakdemo_0. 0.1 3 + debug_iphoneos - arm. Deb'.
==> Error: /Applications/Xcode.app/Contents/Developer/usr/bin/make install requires that you set THEOS_DEVICE_IP in your environment.
==> Notice: It is also recommended that you have public-key authentication set up for root over SSH, or you will be entering your password a lot.

Copy the code

THEOS_DEVICE_IP = 10.200.201.22 (Mobile phone local IP address)

Make sure your iOS device and Mac are on the same network segment of the same LAN.

Open the terminal, type SSH [email protected] and enter the iOS device password, default alpine.

$ping 192.168.2.212 (192.168.2.212): 56 Data bytes 64 bytes from 192.168.2.212: Icmp_seq =0 TTL =64 time=34.303 ms 64 bytes from 192.168.2.212: Icmp_seq =1 TTL =64 time=28.949 ms 64 bytes from 192.168.2.212: Icmp_seq =2 TTL =64 time=25.753 ms 64 bytes from 192.168.2.212: Icmp_seq =3 TTL =64 time=5.306 ms 64 bytes from 192.168.2.212: Icmp_seq =4 TTL =64 time=106.028 ms 64 bytes from 192.168.2.212: Icmp_seq =5 TTL =64 time=84.643 ms 64 bytes from 192.168.2.212: Icmp_seq =6 TTL =64 time=44.845 ms ^C -- 192.168.2.394 ping statistics -- 7packets transmitted, 7packets received 0.0% packet loss round - trip min/avg/Max/stddev 106.028/32.913 = 5.306/47.118 / ms devzkndeMacBook - Pro: testtweakdemo Devzkn $SSH [email protected] The Authenticity of host'192.168.2.212 (192.168.2.212)' can't be established.
RSA key fingerprint is SHA256:/.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.2.212'(RSA) to the list of known hosts. [email protected]'S password: Permission denied, please try again. [email protected]'s password: iPhone:~ root#Copy the code

see also

For more, check out # Applets: iOS Reverse, which presents valuable information only for you, focusing on the mobile technology research field.