方法一:白名單
網(wǎng)上搜反注入,關(guān)于這個方法的搜索結(jié)果是最多的丹弱,簡述下:
首先德撬,自己創(chuàng)建一個類,在類里檢索所有當前工程用到的動態(tài)庫躲胳,然后把檢索結(jié)果和自己預(yù)先設(shè)定的白名單進行對比蜓洪,如果有多余的動態(tài)庫,則判定坯苹,當前工程受到了注入隆檀,此時可以直接退出程序,亦或是上報服務(wù)器粹湃。
整體代碼邏輯如下:
1.打開自己的主工程恐仑,加入如下代碼:
//獲取動態(tài)庫個數(shù)
int count = _dyld_image_count();
for (int i = 1; i < count; i++) {
//打印所有動態(tài)庫名稱,用,隔開
printf("%s,",_dyld_get_image_name(i));
}
2.獲取到所有的主工程動態(tài)庫后,把字符串盡量保存在服務(wù)器再芋。
3.判斷應(yīng)用加載進入的時候,是否有不包含的庫(這里如果存在菊霜,就視為注入的庫)
for (int i = 1; i < count; i++) {
// printf("%s,",_dyld_get_image_name(i));
if (!strstr(libStr, _dyld_get_image_name(i))) {
//如果不包含,視為注入庫!
NSLog(@"注入庫济赎。采取防護措施~鉴逞!");
}
}
缺點:庫太多,不好維護司训,不同機型构捡、系統(tǒng)依賴的庫可能不一致,容易誤傷壳猜。
方法二:Ptrace
逆向APP的時候勾徽,有時候不僅僅是靜態(tài)分析,還可能會動態(tài)調(diào)試
而動態(tài)調(diào)試统扳,無論是終端調(diào)試喘帚,還是Xcode附加畅姊。都是通過debugserver監(jiān)測進程做到的!
Ptrace就是通過限制進程來阻止附加調(diào)試的吹由。
一般來說若未,新創(chuàng)建的iOS項目里沒有ptrace文件,我們此時可以自己創(chuàng)建下:
/*
* Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
/*-
* Copyright (c) 1984, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ptrace.h 8.2 (Berkeley) 1/4/94
*/
#ifndef _SYS_PTRACE_H_
#define _SYS_PTRACE_H_
#include <sys/appleapiopts.h>
#include <sys/cdefs.h>
enum {
ePtAttachDeprecated __deprecated_enum_msg("PT_ATTACH is deprecated. See PT_ATTACHEXC") = 10
};
#define PT_TRACE_ME 0 /* child declares it's being traced */
#define PT_READ_I 1 /* read word in child's I space */
#define PT_READ_D 2 /* read word in child's D space */
#define PT_READ_U 3 /* read word in child's user structure */
#define PT_WRITE_I 4 /* write word in child's I space */
#define PT_WRITE_D 5 /* write word in child's D space */
#define PT_WRITE_U 6 /* write word in child's user structure */
#define PT_CONTINUE 7 /* continue the child */
#define PT_KILL 8 /* kill the child process */
#define PT_STEP 9 /* single step the child */
#define PT_ATTACH ePtAttachDeprecated /* trace some running process */
#define PT_DETACH 11 /* stop tracing a process */
#define PT_SIGEXC 12 /* signals as exceptions for current_proc */
#define PT_THUPDATE 13 /* signal for thread# */
#define PT_ATTACHEXC 14 /* attach to running process with signal exception */
#define PT_FORCEQUOTA 30 /* Enforce quota for root */
#define PT_DENY_ATTACH 31
#define PT_FIRSTMACH 32 /* for machine-specific requests */
__BEGIN_DECLS
int ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);
__END_DECLS
#endif /* !_SYS_PTRACE_H_ */
引入頭文件后倾鲫,直接調(diào)用:
//告訴系統(tǒng)當前進程拒絕被debugserver附加
ptrace(PT_DENY_ATTACH, 0, 0, 0);//
注意粗合,ptrace在main函數(shù)之后調(diào)用App會直接閃退,main以及之前調(diào)用會停止進程附加乌昔,以第一次調(diào)用為準隙疚。正常打開App沒有問題,只影響LLDB調(diào)試磕道。
當然供屉,hook了這個函數(shù)后,就能破解這種反注入方案捅厂,既然ptrace
能夠被Hook
贯卦,那么自己先Hook
住ptrace
。調(diào)用的時候直接調(diào)用自己存儲的地址就可以了焙贷。我們可以在自己的項目中增加一個Framework
撵割。這個庫在Link Binary With Libraries
中盡可能的靠前。這與dyld
加載動態(tài)庫的順序有關(guān)辙芍。
這樣就可以不被ptrace
Hook
了啡彬。
創(chuàng)建個動態(tài)庫,在文件中加入如下代碼:
#import <dlfcn.h>
int (*ptrace_p)(int _request, pid_t pid, caddr_t _addr, int _data);
void ptrace() {
void * handle = dlopen("usr/lib/system/libsystem_kernel.dylib", RTLD_LAZY);
ptrace_p = dlsym(handle, "ptrace");
if (!ptrace_p) {
exit(0);
return;
}
//通過函數(shù)指針調(diào)用
ptrace_p(31, 0, 0, 0);
}
方法三:sysctl
#import <sys/sysctl.h>
bool isDebugServer(){
//控制碼
int name[4];//放字節(jié)碼-查詢信息
name[0] = CTL_KERN;//內(nèi)核查看
name[1] = KERN_PROC;//查詢進程
name[2] = KERN_PROC_PID; //通過進程id查進程
name[3] = getpid();//拿到自己進程的id
//查詢結(jié)果
struct kinfo_proc info;//進程查詢信息結(jié)果
size_t info_size = sizeof(info);//結(jié)構(gòu)體大小
int error = sysctl(name, sizeof(name)/sizeof(*name), &info, &info_size, 0, 0);
assert(error == 0);//0就是沒有錯誤,設(shè)置個斷言
//結(jié)果解析 p_flag的第12位為1就是有調(diào)試
//p_flag 與 P_TRACED =0 就是有調(diào)試
return ((info.kp_proc.p_flag & P_TRACED) !=0);
}
- (void)viewDidLoad {
[super viewDidLoad];
if (isDebugServer()) {
NSLog(@"在debugserver調(diào)試狀態(tài)!");
//自行處理
}else{
NSLog(@"在正常運行狀態(tài)!");
}
}
當前故硅,此方法也會被hook庶灿,所以最好也在動態(tài)庫里做相應(yīng)的處理。