用 Xcode 开发 Cydia Substrate 插件(二)

上次介绍了一个如何用 Xcode 来构建 Substrate 插件,但是开发的具体过程还没有涉及,而这往往又正是初学者最难下手的地方,所以有了本文的后续。

不过在开始之前你要先做好思想准备,相比较开发一般的 App,开发插件的过程需要大量的探索、尝试,因为未知但又必须知道的东西很多很多,于是有时候运气甚至比技术更重要。

Hook?Substrate?插件?简明释义!

Hook 就是通过某种手段替换掉某个类或者对象的方法的实现,从而达到运行时注入代码的目的。

MobileSubstrate 则为开发者提供了一个方便快捷安全可靠的代码注入开发框架。

插件(这里当然是说 Substrate 插件了)就是指基于这个平台开发的动态库。

获取头文件

Class Dump 是一个用来研究 Objective-C 程序运行时的工具,它可以提取 Mach-O 文件中的类、类别、协议的声明文件。拿到了这些头文件,我们才能知道代码要注入到哪个类,哪个方法。

Class Dump 可以从 Cydia 中获得。

典型用法举例,将 SpringBoard 的头文件输出到 Headers 文件夹:

class-dump -H -o Headers SpringBoard

无参数运行 class-dump 可以查询可用参数及其说明。

又一个例子:SpringBoard.h

//SpringBoard.h

#import "_ABAddressBookCopyLocalizedLabel.h"
#import "UIApplicationDelegate-Protocol.h"

@class NSDate, NSDictionary, NSMutableArray, NSMutableSet, NSNumberFormatter, NSSet, NSString, NSTimer, NSURL, SBAppContextHostManager, SBApplication, SBDimmingWindow, SBUIController, UIWindow;

@interface SpringBoard : _ABAddressBookCopyLocalizedLabel
{
    SBUIController *_uiController;
    NSTimer *_menuButtonTimer;
    NSTimer *_lockButtonTimer;
    NSTimer *_idleTimer;
    NSTimer *_autoLockTimer;
    double _lastUndimEventTime;
    double _lastTimeIdleCausedDim;
    double _headsetButtonDownTime;
    struct __GSEvent *_headsetDownEvent;
    int _headsetClickCount;
    SBDimmingWindow *_simulatedBlankingWindow;
    unsigned int _headsetButtonClickCount:8;
    unsigned int _menuButtonClickCount:8;
    unsigned int _screenWasDimOnMenuDown:1;
    unsigned int _waitingForMenuDoubleTapAfterActingOnSingleTap:1;
    unsigned int _screenshotWasTaken:1;
    unsigned int _disableAutoDimming:1;
    unsigned int _dontLockOnNextLockUp:1;
    unsigned int _poweringDown:1;
    unsigned int _headsetDownDelayedActionPerformed:1;
    unsigned int _isSeekingInMedia:1;
    unsigned int _forcePortraitStatusBarOrientation:1;
    unsigned int _lockScreenCameraWantsIdleTimerDisabled:1;
    int _mediaSeekDirection;
    float _currentBacklightLevel;
    unsigned int _springBoardRequestsAccelerometerEvents;
    int _activeInterfaceOrientation;
    NSURL *_menuDoubleTapURL;
    int _notifyDontAnimateREOToken;
    int _notifyDontAllowMediaHUDToken;
    BOOL _expectsFaceContact;
    BOOL _expectsFaceContactInLandscape;
    BOOL _proximityEventsEnabled;
    NSSet *_restrictionDisabledApplications;
    double _sampleSystemStartTime;
    NSDictionary *_startAppsCPUTimes;
    struct __CFDictionary *_registeredSimpleRemoteAppToPriority;
    SBApplication *_registeredSimpleRemoteApp;
    SBApplication *_nowPlayingApp;
    SBApplication *_menuButtonInterceptApp;
    BOOL _menuButtonInterceptAppEnabledForever;
    NSString *_originatingOpenURLDisplayId;
    NSMutableArray *_disableNowPlayingHUDAssertionBundleIds;
    NSMutableArray *_appsRegisteredForVolumeEvents;
    NSNumberFormatter *_decimalFormatter;
    NSNumberFormatter *_percentFormatter;
    NSTimer *_midnightTimer;
    NSDate *_midnightFireDate;
    struct _opaque_pthread_t *_backgroundMIGServerThread;
    struct _opaque_pthread_t *_iconGenerationMIGServerThread;
    SBAppContextHostManager *_springBoardContextHostManager;
    UIWindow *_springBoardContextHostWindow;
    NSMutableSet *_displaysRequestingAggressiveJetsamMode;
}

+ (BOOL)registerForSystemEvents;
+ (BOOL)rendersLocally;
- (id)init;
- (void)_createLogFile;
- (void)writeLogFile;
- (void)handleKeyEvent:(struct __GSEvent *)fp8;
- (void)setHardwareKeyboardLayoutName:(id)fp8;
- (void)updateStackshotSettings;
- (void)updatePowerlog;
- (void)_performDeferredLaunchWork;
- (void)applicationDidFinishLaunching:(id)fp8;
- (void)appleIconViewRemoved;
- (BOOL)launchedAfterLanguageRestart;
- (void)clearLaunchedAfterLanguageRestart;
- (id)_settingLanguageStringForNewLanguage;
- (void)languageChanged;
- (void)_rotateView:(id)fp8 toOrientation:(int)fp12;
- (void)wipeDeviceNow;
- (void)checkPasscodeCompliance;
- (void)showEDGEActivationFailureAlert:(id)fp8 reason:(id)fp12 forMMS:(BOOL)fp16;
- (void)_effectiveSettingsDidChange;
- (void)_assistantPreferenceDidChange:(id)fp8;
- (void)_profileListDidChange;
- (void)userDefaultsDidChange:(id)fp8;
- (void)_lockdownActivationChanged:(id)fp8;
- (void)_testPhoneAlerts;
- (void)runFieldTestScript;
- (void)_significantTimeChange;
- (void)significantTimeChange;
- (void)batteryStatusDidChange:(id)fp8;
- (BOOL)shouldRunFieldTestScript;
- (BOOL)iapIsInExtendedMode;
- (BOOL)canShowLockScreenHUDControls;
- (BOOL)lockScreenCameraSupported;
- (BOOL)canShowLockScreenCameraKnob;
- (BOOL)canShowNowPlayingControls;
- (void)setAppDisabledNowPlayingHUD:(BOOL)fp8 bundleIdentifier:(id)fp12;
- (BOOL)respondImmediatelyToMenuSingleTapAllowingDoubleTap:(char *)fp8;
- (void)goToSpotlight:(BOOL)fp8;
- (BOOL)handleDoubleTapAction;
- (void)handleMenuDoubleTap;
- (void)_primeMenuButtonAssistant;
- (void)_setMenuButtonTimer:(id)fp8;
- (void)_setLockButtonTimer:(id)fp8;
- (void)cancelMenuButtonRequests;
- (void)clearMenuButtonTimer;
- (void)_menuButtonWasHeld;
- (double)_menuHoldTime;
- (void)menuButtonDown:(struct __GSEvent *)fp8;
- (void)menuButtonUp:(struct __GSEvent *)fp8;
- (void)_giveUpOnMenuDoubleTap;
- (void)_keyboardAvailabilityChanged;
- (void)_runActivateAssistantTest;
- (void)_activateAssistantWithEvent:(int)fp8 withCompletion:(id)fp(null);
- (void)activateAssistantWithOptions:(id)fp8 withCompletion:(id)fp(null);
- (void)_startSeekWithDirection:(id)fp8;
- (void)mediaKeyDown:(struct __GSEvent *)fp8;
- (void)mediaKeyUp:(struct __GSEvent *)fp8;
- (void)_handleMenuButtonEvent;
- (void)lockButtonDown:(struct __GSEvent *)fp8;
- (void)lockButtonWasHeld;
- (void)extendButtonTimersForWake;
- (void)_powerDownNow;
- (void)_rebootNow;
- (void)reboot;
- (void)powerDown;
- (BOOL)isPoweringDown;
- (void)powerDownRequested:(id)fp8;
- (void)powerDownCanceled:(id)fp8;
- (BOOL)relaunchingForSetupLanguageChange;
- (void)relaunchSpringBoard;
- (void)_relaunchSpringBoardNow;
- (void)lockButtonUp:(struct __GSEvent *)fp8;
- (void)_performDelayedHeadsetActionForAssistant;
- (void)_performDelayedHeadsetActionForVoiceControl;
- (void)_performDelayedHeadsetClickTimeout;
- (id)simpleRemoteDestinationApp;
- (void)sendSimpleRemoteActionToRegisteredApp:(int)fp8;
- (void)_iapServerConnectionDiedNotification:(id)fp8;
- (void)_iapExtendedModeReset;
- (void)_imagesMounted;
- (void)_setDeferredHeadsetButtonDownEvent:(struct __GSEvent *)fp8;
- (void)headsetButtonDown:(struct __GSEvent *)fp8;
- (void)headsetButtonUp:(struct __GSEvent *)fp8;
- (void)headsetAvailabilityChanged:(struct __GSEvent *)fp8;
- (void)smsPrefsChanged;
- (void)ALSPrefsChanged:(id)fp8;
- (void)profileConnectionDidReceiveEffectiveSettingsChangedNotification:(id)fp8 userInfo:(id)fp12;
- (void)updateCapabilitiesAndIconVisibility;
- (BOOL)isDisplayIdentifierRestrictionDisabled:(id)fp8;
- (void)loadDebuggingAndDemoPrefs;
- (void)debuggingAndDemoPrefsWereChanged;
- (void)_localeChanged;
- (void)localeChanged;
- (void)autoLockPrefsChanged;
- (void)pinPolicyChanged;
- (void)profileConnectionDidReceiveRestrictionChangedNotification:(id)fp8 userInfo:(id)fp12;
- (void)profileConnectionDidReceivePasscodePolicyChangedNotification:(id)fp8 userInfo:(id)fp12;
- (void)ringerChanged:(int)fp8;
- (void)_updateRingerStateWithVisuals:(BOOL)fp8 updatePreferenceRegister:(BOOL)fp12;
- (void)accessoryKeyStateChanged:(struct __GSEvent *)fp8;
- (unsigned int)_frontmostApplicationPort;
- (void)quitTopApplication:(struct __GSEvent *)fp8;
- (void)applicationExited:(struct __GSEvent *)fp8;
- (void)anotherApplicationFinishedLaunching:(struct __GSEvent *)fp8;
- (void)applicationSuspend:(struct __GSEvent *)fp8;
- (void)applicationSuspended:(struct __GSEvent *)fp8;
- (void)applicationSuspendedSettingsUpdated:(struct __GSEvent *)fp8;
- (void)statusBarReturnActionTap:(struct __GSEvent *)fp8;
- (int)statusBar:(id)fp8 styleForRequestedStyle:(int)fp12 overrides:(int)fp16;
- (void)hideSpringBoardStatusBar;
- (void)showSpringBoardStatusBar;
- (void)setMetaHostingEnabled:(BOOL)fp8;
- (BOOL)isMetaHostingEnabled;
- (id)metaHostView;
- (id)metaHostWindow;
- (void)showAlertForUnhandledURL:(id)fp8 error:(int)fp12;
- (void)_applicationOpenURL:(id)fp8 event:(struct __GSEvent *)fp12;
- (BOOL)applicationCanOpenURL:(id)fp8 publicURLsOnly:(BOOL)fp12;
- (void)applicationOpenURL:(id)fp8;
- (void)applicationOpenURL:(id)fp8 publicURLsOnly:(BOOL)fp12;
- (void)applicationOpenURL:(id)fp8 publicURLsOnly:(BOOL)fp12 animating:(BOOL)fp16;
- (void)applicationOpenURL:(id)fp8 publicURLsOnly:(BOOL)fp12 animating:(BOOL)fp16 sender:(id)fp20;
- (void)applicationOpenURL:(id)fp8 publicURLsOnly:(BOOL)fp12 animating:(BOOL)fp16 additionalActivationFlag:(unsigned int)fp20;
- (void)applicationOpenURL:(id)fp8 publicURLsOnly:(BOOL)fp12 animating:(BOOL)fp16 sender:(id)fp20 additionalActivationFlag:(unsigned int)fp24;
- (void)_openURLCore:(id)fp8 display:(id)fp12 publicURLsOnly:(BOOL)fp16 animating:(BOOL)fp20 additionalActivationFlag:(unsigned int)fp24;
- (BOOL)canOpenURL:(id)fp8;
- (BOOL)openURL:(id)fp8;
- (void)setMenuButtonInterceptApp:(id)fp8 forever:(BOOL)fp12;
- (id)menuButtonInterceptApp;
- (BOOL)menuButtonInterceptAppEnabledForever;
- (void)setWantsVolumeButtonEvents:(BOOL)fp8;
- (void)setAppRegisteredForVolumeEvents:(id)fp8 isActive:(BOOL)fp12;
- (id)appsRegisteredForVolumeEvents;
- (void)volumeChanged:(struct __GSEvent *)fp8;
- (void)setBacklightFactorPending:(float)fp8;
- (void)setBacklightFactor:(float)fp8 keepTouchOn:(BOOL)fp12;
- (void)setBacklightFactor:(float)fp8;
- (void)animateBacklightToFactor:(float)fp8 duration:(double)fp12 keepTouchOn:(BOOL)fp20 didFinishTarget:(id)fp24 selector:(SEL)fp28;
- (void)animateBacklightToFactor:(float)fp8 duration:(double)fp12 didFinishTarget:(id)fp20 selector:(SEL)fp24;
- (void)setBacklightLevel:(float)fp8;
- (void)setBacklightLevel:(float)fp8 permanently:(BOOL)fp12;
- (float)currentBacklightLevel;
- (float)systemBacklightLevel;
- (void)systemWillSleep;
- (void)setupMidnightTimer;
- (void)_midnightPassed;
- (void)_adjustMidnightTimerAfterSleep;
- (void)setBacklightFactorToZero;
- (void)cancelSetBacklightFactorToZeroAfterDelay;
- (void)setBacklightFactorToZeroAfterDelay;
- (void)showSimulatedScreenBlank;
- (void)hideSimulatedScreenBlank;
- (void)dimToBlackKeepingTouchOn;
- (void)undim;
- (void)lockAfterCall;
- (BOOL)shouldDimToBlackInsteadOfLock;
- (void)autoLock;
- (void)didIdle;
- (double)nextIdleTimeDuration;
- (double)nextLockTimeDuration;
- (void)clearIdleTimer;
- (void)resetIdleTimerAndUndim;
- (void)resetIdleTimerAndUndim:(BOOL)fp8;
- (void)_proximityChanged:(id)fp8;
- (BOOL)caseIsEnabledAndLatched;
- (BOOL)allowCaseLatchLockAndUnlock;
- (void)keyboardOrCaseLatchWantsToAttemptUnlock:(id)fp8;
- (void)noteCaseHardwarePresent;
- (void)caseLatchWantsToAttemptLock;
- (void)userEventOccurred;
- (void)_updateRejectedInputSettingsForInCallState:(BOOL)fp8 isOutgoing:(BOOL)fp12 triggeredbyRouteWillChangeToReceiverNotification:(BOOL)fp16;
- (void)updateRejectedInputSettingsForInCallState:(BOOL)fp8 isOutgoing:(BOOL)fp12;
- (void)updateRejectedInputSettings;
- (void)updateRejectedInputSettingsTriggeredByRouteChangeToReceiverNotification:(BOOL)fp8;
- (void)lockDevice:(struct __GSEvent *)fp8;
- (void)showThermalAlertIfNecessary;
- (void)respondToCurrentThermalCondition;
- (void)_beginThermalJetsamCPUSampling;
- (void)_killThermallyActiveApplication;
- (id)_newAppsCPUTimesDictionary;
- (void)didReceiveMemoryWarning;
- (void)noteSubstantialTransitionOccured;
- (void)updateMirroredDisplayOrientation;
- (void)noteInterfaceOrientationChanged:(int)fp8;
- (void)noteInterfaceOrientationChanged:(int)fp8 updateMirroredDisplays:(BOOL)fp12;
- (int)activeInterfaceOrientation;
- (int)activeInterfaceOrientationWithoutConsideringAlerts;
- (int)_frontMostAppOrientation;
- (int)interfaceOrientationForCurrentDeviceOrientation;
- (void)reportStatusBarOrientationAsPortrait:(BOOL)fp8;
- (int)statusBarOrientation;
- (void)_overrideDefaultInterfaceOrientationWithOrientation:(int)fp8;
- (void)_removeDefaultInterfaceOrientatationOverride;
- (id)displayIDForURLScheme:(id)fp8 isPublic:(BOOL)fp12;
- (BOOL)_alertWindowShouldRotate;
- (double)windowRotationDuration;
- (void)setSystemVolumeHUDEnabled:(BOOL)fp8 forAudioCategory:(id)fp12;
- (void)_migrateMenuDoubleTapSetting;
- (void)updateMenuDoubleTapSettings;
- (void)setZoomTouchEnabled:(BOOL)fp8;
- (BOOL)proximityEventsEnabled;
- (void)setProximityEventsEnabled:(BOOL)fp8;
- (BOOL)expectsFaceContact;
- (BOOL)expectsFaceContactInLandscape;
- (void)setExpectsFaceContact:(BOOL)fp8 inLandscape:(BOOL)fp12;
- (void)setExpectsFaceContact:(BOOL)fp8;
- (void)updateProximitySettings;
- (void)frontDisplayDidChange;
- (void)applicationWillOrderInContext:(id)fp8 windowLevel:(float)fp12 windowOutput:(int)fp16;
- (void)applicationDidOrderOutContext:(id)fp8;
- (void)didDismissMiniAlert;
- (void)willDisplayMiniAlert:(int *)fp8;
- (void)willDismissMiniAlert:(int *)fp8 andShowAnother:(BOOL)fp12;
- (void)setHasMiniAlerts:(BOOL)fp8;
- (BOOL)canShowAlerts;
- (BOOL)isLocked;
- (int)alertInterfaceOrientation;
- (void)launchMusicPlayerSuspended;
- (void)_launchMusicPlayerSuspendedAndStartMusic;
- (void)_tearDownNow;
- (void)tearDown;
- (void)_nowPlayingAppDidChangeNotification:(id)fp8;
- (BOOL)isMusicPlayerInNowPlayingView;
- (id)nowPlayingApp;
- (BOOL)isNowPlayingAppPlaying;
- (BOOL)isMusicPlayerPlaying;
- (void)setNowPlayingInfo:(id)fp8 forApplication:(id)fp12;
- (void)_updateRegisteredSimpleRemoteApp;
- (void)setSimpleRemoteRoutingPriority:(unsigned int)fp8 forApplication:(id)fp12;
- (unsigned int)simpleRemoteRoutingPriorityForApplication:(id)fp8;
- (unsigned int)simpleRemoteRoutingPriority;
- (void)setIdleTimerDisabled:(BOOL)fp8;
- (void)setSuspensionAnimationDelay:(double)fp8;
- (BOOL)isCameraApp;
- (id)formattedDecimalStringForNumber:(id)fp8;
- (id)formattedPercentStringForNumber:(id)fp8;
- (id)_accessibilityFrontMostApplication;
- (id)_accessibilityTopDisplay;
- (id)_accessibilityRunningApplications;
- (BOOL)_accessibilityIsSystemGestureActive;
- (BOOL)_accessibilityObjectWithinProximity;
- (void)_accessibilitySetEventTapCallback:(void *)fp8;
- (void *)_accessibilityEventTapCallback;
- (void)_accessibilityProcessHIDEvent:(struct __IOHIDEvent *)fp8;
- (BOOL)_accessibilityIsSBStealingEvents;
- (double)_accessibilityActivationAnimationStartDelay;
- (void)_accessibilityActivationAnimationWillBegin;
- (double)_accessibilityDeactivationAnimationStartDelay;
- (void)_accessibilityDeactivationAnimationWillBegin;
- (BOOL)_isSwitcherShowing;
- (void)_setStatusBarShowsProgress:(BOOL)fp8;
- (void)_spokenLanguageChanged;
- (void)beginListeningForAssistantActivationGesture;
- (void)stopListeningForAssistantActivationGesture;
- (void)setSystemAggressiveJetsamEnabled:(BOOL)fp8 forDisplay:(id)fp12;

@end

这样我们就知道了 SpringBoard 中有一个 SpringBoard 类,以及这个类中声明的所有方法的名称、返回类型、参数类型和数量。然后就可以按照之前介绍的方法修改你想要修改的方法的实现了。

但为了实现既定目标到底该修改哪个方法的实现,又该如何修改,这就是需要不断尝试和探索的地方了。

冒险才刚刚开始

方法名称提供了很多的信息,让我们知道这个方法大概和什么有关,但是参数和返回值的意义就不太清晰了。这里给个小提示,可以通过注入 NSLog 输出参数和返回值来获取更多信息。

总之,想方设法获取需要的信息,而直接按照常理猜测原始实现的各种可能性来试验也不失为一个好方法。

最后的最后,再啰嗦一句,万一有同学不知道的话。编译好的动态库要放到 iOS 设备的这个目录:

/Library/MobileSubstrate/DynamicLibraries
时间: 2024-10-19 12:32:31

用 Xcode 开发 Cydia Substrate 插件(二)的相关文章

用 Xcode 开发 Cydia Substrate 插件(一)

关于这方面的中文资料太少了,以至于可能很多对插件开发感兴趣的孩子们都不知从何下手,于是呢我就写了这篇文章,希望对你能有所帮助.如果你觉得文章内容有什么错误呢也请提出来. 准备开发环境 1. 从 App Store 安装 Xcode,再安装 Command Line Tools.这个可以在 Xcode 的偏好设置里找到. 2. 安装 dpkg,用于 Debian 打包.先到 http://www.macports.org/install.php 下载安装对应操作系统版本的 MacPorts.然后在

利用Cydia Substrate进行Android HOOK

Cydia Substrate是一个代码修改平台.它可以修改任何主进程的代码,不管是用Java还是C/C++(native代码)编写的.而Xposed只支持HOOK app_process中的java函数,因此Cydia Substrate是一款强大而实用的HOOK工具. 官网地址:http://www.cydiasubstrate.com/ Demo地址:https://github.com/zencodex/cydia-android-hook 官方教程:http://www.cydiasu

Android HOOK工具Cydia Substrate使用详解

目录(?)[+] Substrate几个重要API介绍 MShookClassLoad MShookMethod 使用方法 短信监控实例 Cydia Substrate是一个代码修改平台.它可以修改任何主进程的代码,不管是用Java还是C/C++(native代码)编写的.而Xposed只支持HOOK app_process中的java函数,因此Cydia Substrate是一款强大而实用的HOOK工具. 官网地址:http://www.cydiasubstrate.com/ Demo地址:h

Android上玩玩Hook:Cydia Substrate实战

作者简介:周圣韬,百度高级Android开发工程师,博客地址:http://blog.csdn.net/yzzst 了解Hook 还没有接触过Hook技术读者一定会对Hook一词感觉到特别的陌生,Hook英文翻译过来就是“钩子”的意思,那我们在什么时候使用这个“钩子”呢? 我们知道,在Android操作系统中系统维护着自己的一套事件分发机制.应用程序,包括应用触发事件和后台逻辑处理,也是根据事件流程一步步的向下执行.而“钩子”的意思,就是在事件传送到终点前截获并监控事件的传输,像个钩子勾上事件一

(4.2.33)Android上玩玩Hook(1):Cydia Substrate初识

选自: Android上玩玩Hook? 跟着鬼哥学Android java hook (一) 摘要:Hook的出现为开发者希望通过一个程序改变其他程序的某些行为的想法开拓了解决道路,而作为一款基于Hook的代码修改框架,Cydia Substrate可以修改任何主进程的代码,本文作者以广告注入的实战详细介绍了Hook的过程. 了解Hook 还没有接触过Hook技术读者一定会对Hook一词感觉到特别的陌生,Hook英文翻译过来就是"钩子"的意思,那我们在什么时候使用这个"钩子&

使用PhoneGap开发基于Html5应用二:第一个PhoneGap应用:百度

上一篇博文使用PhoneGap开发基于Html5应用一:PhoneGap简介 中我介绍了如何从phonegap官网上下载源码并启动第一个应用,今天我们把phonegap的应用稍微改一下,让他实现几个比较牛叉的功能: 1.启动一个网页 2.启动摄像头 3.启动定位 老规矩,在实现这几个功能之前我们先讲一下原理性的东西: 首先我们先回顾一下上次说的,其实phonegap应用中有个特别的webview,它就是CDVViewController,关于这个类我们后面再详细描述,现在我们先了解这个类到底做了

Xcode好用的插件以及第三方

版权说明 本文首发于<程序员>杂志 2014 年 6 月刊,未经允许,请勿转载. 前言 从苹果发明 iPhone 起,AppStore 上的一个又一个类似 flappy bird 的一夜暴富的故事刺激着大量开发者加入移动开发大军.随着这些开发者出现的,还有大量方便 iOS 开发者的各种工具.这些工具作为整个应用开发生态链的重要一环,极大地方便了广大应用开发者,节省了应用开发的时间. 本文将从应用工具.命令行工具.插件工具 3 个方面,介绍这些优秀的应用. 图形应用工具 Charles Char

使用Cydia Substrate 从Native Hook Android Java世界

这里介绍了如何使用Cydia Substrate Hook安卓Java世界.这篇文章介绍如何从Native中Hook 安卓Java世界. 手机端配置见之前文章. 一.建立工程 建立一个Android工程.不需要创建默认的Activity.修改AndroidManifest.xml如下: <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.cyd

基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件[转]

上一篇文章介绍到怎么在自己的Java环境中搭建openfire插件开发的环境,同时介绍到怎样一步步简单的开发openfire插件.一步步很详细的介绍到简单插件开发,带Servlet的插件的开发.带JSP页面插件的开发,以及怎么样将开发好的插件打包.部署到openfire服务器. 如果你没有看上一篇文章的话,请你还是看看.http://www.cnblogs.com/hoojo/archive/2013/03/07/2947502.html 因为这篇文章是基于上篇文章讲叙的基础上完成插件开发.而且