[iOS] A Study of task_info

koo00·2023년 9월 14일
0

I. Intro

iOS에서 task_info 함수를 통해 안티 디버깅, 메모리 보호 기능을 수행하는 보안 솔루션을 분석했다.

task_info 함수는 iOS 에서 메모리 정보를 가져올 수 있는 함수인데, 두번째 인자에 따라 얻어오는 정보가 달라진다.

본 포스팅에서 탐지 및 우회하는 방법은 다루지 않고, task_info 함수의 결과 값이 KERN_SUCCESS 일 때 세팅되는 info 구조체에 대해 정리할 예정이다.

시작에 앞서 task_info 함수의 리턴 값 및 파라미터 정보는 아래와 같다.

kern_return_t task_info ( 
	task_t					task,
	task_flavor_t			flavor,
	task_info_t				task_info,
	mach_msg_type_number_t	task_info_count
);

그럼 이제 가보자잇~


II. TASK_DYLD_INFO

TASK_DYLD_INFO 는 현재 메모리에 로드된 동적 라이브러리 관련 상수이며 해당 값이 두 번째 인자에 들어가면 세팅되는 info 구조체는 아래와 같다.

#define TASK_DYLD_INFO			17

struct task_dyld_info {
	mach_vm_address_t	all_image_info_addr;
	mach_vm_size_t		all_image_info_size;
	integer_t		    all_image_info_format;		
};

 
여기서 all_image_info_addr 멤버 변수는 dyld_all_image_infos 구조체이며, 구조는 아래와 같다.

struct dyld_all_image_infos {
	uint32_t						version;		/* 1 in Mac OS X 10.4 and 10.5 */
	uint32_t						infoArrayCount;
	const struct dyld_image_info*	infoArray;
	dyld_image_notifier				notification;		
	bool							processDetachedFromSharedRegion;
	/* the following fields are only in version 2 (Mac OS X 10.6, iPhoneOS 2.0) and later */
	bool							libSystemInitialized;
	const struct mach_header*		dyldImageLoadAddress;
	/* the following field is only in version 3 (Mac OS X 10.6, iPhoneOS 3.0) and later */
	void*							jitInfo;
	/* the following fields are only in version 5 (Mac OS X 10.6, iPhoneOS 3.0) and later */
	const char*						dyldVersion;
	const char*						errorMessage;
	uintptr_t						terminationFlags;
	/* the following field is only in version 6 (Mac OS X 10.6, iPhoneOS 3.1) and later */
	void*							coreSymbolicationShmPage;
	/* the following field is only in version 7 (Mac OS X 10.6, iPhoneOS 3.1) and later */
	uintptr_t						systemOrderFlag;
	/* the following field is only in version 8 (Mac OS X 10.7, iPhoneOS 3.1) and later */
	uintptr_t						uuidArrayCount;
	const struct dyld_uuid_info*	uuidArray;		/* only images not in dyld shared cache */
	/* the following field is only in version 9 (Mac OS X 10.7, iOS 4.0) and later */
	struct dyld_all_image_infos*	dyldAllImageInfosAddress;
	/* the following field is only in version 10 (Mac OS X 10.7, iOS 4.2) and later */
	uintptr_t						initialImageCount;
	/* the following field is only in version 11 (Mac OS X 10.7, iOS 4.2) and later */
	uintptr_t						errorKind;
	const char*						errorClientOfDylibPath;
	const char*						errorTargetDylibPath;
	const char*						errorSymbol;
	/* the following field is only in version 12 (Mac OS X 10.7, iOS 4.3) and later */
	uintptr_t						sharedCacheSlide;
};

 
여기서 infoArray 멤버 변수는 dyld_image_info 구조체이며, 구조는 아래와 같다.

struct dyld_image_info {
	const struct mach_header*	imageLoadAddress;	/* base address image is mapped into */
	const char*					imageFilePath;		/* path dyld used to load the image */
	uintptr_t					imageFileModDate;	/* time_t of image file */
													/* if stat().st_mtime of imageFilePath does not match imageFileModDate, */
													/* then file has been modified since dyld loaded it */
};

 
Frida 에서 사용할 수 있도록 삭 정리해두자.

Interceptor.attach(Module.findExportByName(null, 'task_info'), {
	onEnter: function(args) {
		this.flavor = args[1].toInt32();
		this.info = args[2];
	},
	onLeave: function(retval) {
		if(this.flavor == 17) {
			// console.log('[-] task_dyld_info : ' + this.info);
			var dyld_all_image_infos = this.info.readPointer();
			// console.log('[-] dyld_all_image_infos : ' + dyld_all_image_infos);
			var infoArrayCount = dyld_all_image_infos.add(4).readInt();
			var infoArray = dyld_all_image_infos.add(8).readPointer();
			// console.log('[-] infoArrayCount : ' + infoArrayCount);
			
			for(var i=0; i<infoArrayCount; i++) {
				var imageFilePath = infoArray.add(8).add(i*24).readPointer();
				console.log('[-] imageFilePath : ' + imageFilePath.readUtf8String());
			}
		}
	}
});

III. TASK_EXTMOD_INFO

TASK_EXTMOD_INFO 는 현재 삽입된 쓰레드나 하이재킹된 프로세스 관련 상수이며 해당 값이 두 번째 인자에 들어가면 세팅되는 info 구조체는 아래와 같다.

#define TASK_EXTMOD_INFO			19
struct task_extmod_info {
	unsigned char					task_uuid[16];
	vm_extmod_statistics_data_t		extmod_statistics;
};

 
여기서 extmod_statistics 멤버 변수는 vm_statistics 구조체이며, 구조는 아래와 같다.

struct vm_extmod_statistics {
	int64_t	task_for_pid_count;				/* # of times task port was looked up */
	int64_t task_for_pid_caller_count;		/* # of times this task called task_for_pid */
	int64_t	thread_creation_count;			/* # of threads created in task */
	int64_t	thread_creation_caller_count;	/* # of threads created by task */
	int64_t	thread_set_state_count;			/* # of register state sets in task */
	int64_t	thread_set_state_caller_count;	/* # of register state sets by task */
} __attribute__((aligned(8)));

 
마찬가지로 Frida 에서 사용할 수 있도록 삭 정리해두자.

Interceptor.attach(Module.findExportByName(null, 'task_info'), {
	onEnter: function(args) {
		this.flavor = args[1].toInt32();
		this.info = args[2];
	},
	onLeave: function(retval) {
		if(this.flavor == 19) {
			// console.log('[-] task_extmod_info : ' + this.info);
			var vm_extmod_statistics = this.info.add(16);
			var task_for_pid_count = vm_extmod_statistics;
			var task_for_pid_caller_count = vm_extmod_statistics.add(8);
			var thread_creation_count = vm_extmod_statistics.add(16);
			var thread_creation_caller_count = vm_extmod_statistics.add(24);
			var thread_set_state_count = vm_extmod_statistics.add(32);
			var thread_set_state_caller_count = vm_extmod_statistics.add(40);
			// console.log('[-] task_for_pid_count : ' + task_for_pid_count.readInt());
			// console.log('[-] task_for_pid_caller_count : ' + task_for_pid_caller_count.readInt());
			// console.log('[-] thread_creation_count : ' + thread_creation_count.readInt());
			// console.log('[-] thread_creation_caller_count : ' + thread_creation_caller_count.readInt());
			// console.log('[-] thread_set_state_count : ' + thread_set_state_count.readInt());
			// console.log('[-] thread_set_state_caller_count : ' + thread_set_state_caller_count.readInt());
		}
	}
});

IV. Outro

오랜만에 포스팅을 쓴다. 보안 솔루션을 분석하면서 발견하고 배웠던 것들이 있는데, 바쁘다는 핑계로 소홀했던 것 같다. 앞으로 여유로울 때마다 하나씩 정리해야겠다.


V. References

https://opensource.apple.com/source/xnu/xnu-4570.41.2/osfmk/mach/task_info.h
https://opensource.apple.com/source/xnu/xnu-792/osfmk/mach/kern_return.h
https://opensource.apple.com/source/dyld/dyld-195.6/include/mach-o/dyld_images.h
https://opensource.apple.com/source/xnu/xnu-3789.51.2/osfmk/mach/vm_statistics.h
https://knight.sc/reverse%20engineering/2019/04/15/detecting-task-modifications.html

profile
JFDI !

0개의 댓글