首页
论坛
课程
招聘
[原创]iOS下远程进程注入dylib源码
2014-5-15 14:16 31310

[原创]iOS下远程进程注入dylib源码

2014-5-15 14:16
31310
实现了iOS下远程进程注入dylib的功能,借鉴了一些资料,自己实现了下,写的很糙,拿出来供大家参考。

大致原理跟Win下的CreateRemoteThread类似,细节都在代码中。

其中一段是用汇编写的,找不到s文件了,其实很简单,作用是执行dlopen加载目标dylib。

注:在armv7、armv7s中测试有效。


//
//  main.c
//  swinjector
//
//  Created by rainyx on 13-7-24.
//  Copyright (c) 2013年 __MyCompanyName__. All rights reserved.
//

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <mach/mach.h>
#include <mach/machine/thread_status.h>
#include <pthread.h>

#define CPSR_T_MASK (1u<<5)

struct INJECT_CONTEXT
{
    unsigned int _pthreadStruct;
    void (*__pthread_set_self)(pthread_t);
    int (*pthread_create)(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *);
    int (*pthread_join)(pthread_t, void **);
    mach_port_t (*mach_thread_self)();
    kern_return_t (*thread_terminate)(thread_act_t);
    const char *library;
    void *(*dlopen)(const char *, int);
} INJECT_CONTEXT;


int main (int argc, const char * argv[])
{
    if(argc!=3)
    {
        printf("Usage: <PID> <Dynamic library path>\n");
        return 0;
    }
    
    const char *library = argv[2];
    
    mach_port_t self = mach_task_self();
    mach_port_t remoteTask;
    
    pid_t pid = (pid_t)strtoul(argv[1], NULL, 10);
    task_for_pid(mach_task_self(), pid, &remoteTask);
    
    if(!remoteTask)
    {
        printf("Failed: task_for_pid, pid: %d(0x%X).\n", pid, pid);
        return 0;
    }
    
    // 分配栈空间
    vm_address_t remoteStack;
    vm_size_t stackSize = 16*1024;
    vm_allocate(remoteTask, &remoteStack, stackSize, TRUE);
    
    // 写入library字符串
    vm_size_t libraryLen = strlen(library);
    vm_address_t remoteLibrary;
    vm_allocate(remoteTask, &remoteLibrary, libraryLen, TRUE);
    vm_write(remoteTask, remoteLibrary, library, (mach_msg_type_number_t)libraryLen);
    
    // 分配_pthread struct空间
    vm_address_t remotePthreadStruct;
    vm_size_t pthreadStructSize = 1024;
    vm_allocate(remoteTask, &remotePthreadStruct, pthreadStructSize, TRUE);
    
    // 写入Context
    struct INJECT_CONTEXT context;
    
    extern void __pthread_set_self(pthread_t);
    
    context.library = remoteLibrary;
    context._pthreadStruct = (unsigned int)remotePthreadStruct;
    context.__pthread_set_self = &__pthread_set_self;
    context.thread_terminate = &thread_terminate;
    context.mach_thread_self = &mach_thread_self;
    context.pthread_create = &pthread_create;
    context.pthread_join = &pthread_join;
    context.dlopen = &dlopen;
    
    vm_size_t contextSize = sizeof(INJECT_CONTEXT);
    vm_address_t remoteContext;
    vm_allocate(remoteTask, &remoteContext, contextSize, TRUE);
    vm_write(remoteTask, remoteContext, &context, (mach_msg_type_number_t)contextSize);
    
    // 写入Code
    unsigned char code[124] = {
        0x80, 0x40, 0x2D, 0xE9, 0x08, 0xD0, 0x4D, 0xE2, 0x00, 0x70, 0xA0, 0xE1, 0x00, 0x00, 0x97, 0xE5,
        0x00, 0x00, 0x80, 0xE5, 0x04, 0x10, 0x97, 0xE5, 0x31, 0xFF, 0x2F, 0xE1, 0x0D, 0x00, 0xA0, 0xE1,
        0x00, 0x10, 0xA0, 0xE3, 0x30, 0x20, 0x8F, 0xE2, 0x07, 0x30, 0xA0, 0xE1, 0x08, 0x40, 0x97, 0xE5,
        0x34, 0xFF, 0x2F, 0xE1, 0x00, 0x00, 0x9D, 0xE5, 0x04, 0x10, 0x8D, 0xE2, 0x0C, 0x20, 0x97, 0xE5,
        0x32, 0xFF, 0x2F, 0xE1, 0x10, 0x10, 0x97, 0xE5, 0x31, 0xFF, 0x2F, 0xE1, 0x14, 0x10, 0x97, 0xE5,
        0x31, 0xFF, 0x2F, 0xE1, 0x08, 0xD0, 0x8D, 0xE2, 0x80, 0x80, 0xBD, 0xE8, 0x80, 0x40, 0x2D, 0xE9,
        0x00, 0x70, 0xA0, 0xE1, 0x18, 0x00, 0x97, 0xE5, 0x02, 0x10, 0xA0, 0xE3, 0x1C, 0x20, 0x97, 0xE5,
        0x32, 0xFF, 0x2F, 0xE1, 0x00, 0x00, 0xA0, 0xE3, 0x80, 0x80, 0xBD, 0xE8
    };
    
    vm_size_t codeSize = 124;
    vm_address_t remoteCode;
    vm_allocate(remoteTask, &remoteCode, codeSize, TRUE);
    vm_write(remoteTask, remoteCode, &code, (mach_msg_type_number_t)codeSize);
    vm_protect(remoteTask, remoteCode, codeSize, FALSE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
    
    
    // 创建远程线程
    arm_thread_state_t state;
    memset(&state, 0, sizeof(state));
    
    state.__r[0] = (__uint32_t)remoteContext;
    state.__pc = (__uint32_t)remoteCode;
    state.__sp = (__uint32_t)(remoteStack + stackSize/2);
    
    if (state.__pc & 0x1)
    {
        state.__pc &= ~0x1;
        state.__cpsr |= CPSR_T_MASK;
    }
    else
    {
        state.__cpsr &= ~CPSR_T_MASK;
    }
    
    // 启动线程
    thread_act_t remoteThread;
    thread_create_running(remoteTask, ARM_THREAD_STATE, (thread_state_t) &state, ARM_THREAD_STATE_COUNT, &remoteThread);
    
    //printf("Remote thread is running.\n");
    
    // 等待线程结束,释放资源
    
    thread_state_flavor_t flavor;
    mach_msg_type_number_t count;
    flavor = ARM_THREAD_STATE;
    count = ARM_THREAD_STATE_COUNT;
    mach_msg_type_number_t read;
    kern_return_t status;
    
    while (true)
    {
        read = count;
        status = thread_get_state(remoteThread, flavor, (thread_state_t)&state, &read);
        if(status == KERN_SUCCESS)
        {
            usleep(10000);
            continue;
        }
        else if(status == KERN_TERMINATED || status == MACH_SEND_INVALID_DEST)
        {
            break;
        }
        else
        {
            // TODO on error.
        }
    }
    
    if(remoteThread)
        mach_port_deallocate(self, remoteThread);
    if(remoteCode)
        vm_deallocate(remoteTask, remoteCode, codeSize);
    if(remotePthreadStruct)
        vm_deallocate(remoteTask, remotePthreadStruct, pthreadStructSize);
    if(remoteLibrary)
        vm_deallocate(remoteTask, remoteLibrary, libraryLen);
    if(remoteContext)
        vm_deallocate(remoteTask, remoteContext, contextSize);
    if(remoteStack)
        vm_deallocate(remoteTask, remoteStack, stackSize);
    
    printf("Injected successfully!\n");
    
	return 0;
}




[看雪官方培训] Unicorn Trace还原Ollvm算法!《安卓高级研修班》2021年6月班火热招生!!

收藏
点赞1
打赏
分享
最新回复 (25)
雪    币: 325
活跃值: 活跃值 (30)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
地狱怪客 活跃值 2 2014-5-15 14:26
2
0
虽然不懂手机但是看上去好高端
雪    币: 170
活跃值: 活跃值 (43)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
rainyx 活跃值 1 2014-5-15 14:45
3
0
雪    币: 67
活跃值: 活跃值 (11)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
coltor 活跃值 2 2014-5-15 14:57
4
0
不错~~,mac's hacker handbook
雪    币: 175
活跃值: 活跃值 (52)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
stanford 活跃值 2014-5-15 15:06
5
0
确实不错,But,ios好像不太用的到,Mac还是有用的。
雪    币: 170
活跃值: 活跃值 (43)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
rainyx 活跃值 1 2014-5-15 15:13
6
0
没错,原理及代码都是通用到,目前iOS上有成熟的框架,无需另写。
雪    币: 184
活跃值: 活跃值 (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
whnet 活跃值 2014-5-15 17:11
7
0
记得有人问过我。 当时说用pthread. 那边回说pthread容易被处理掉。  改用 mac 上的 mach,可以无视调试器。
雪    币: 170
活跃值: 活跃值 (43)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
rainyx 活跃值 1 2014-5-15 18:11
8
0
mach线程无法直接调用dlopen。必须经过pthread。你确定你说的不是ptrace?
雪    币: 170
活跃值: 活跃值 (43)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
rainyx 活跃值 1 2014-5-15 18:17
9
0
绝对好书
雪    币: 9
活跃值: 活跃值 (15)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
kgxxx 活跃值 2014-5-15 20:03
10
0
高大上~
雪    币: 8671
活跃值: 活跃值 (651)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
cvcvxk 活跃值 10 2014-5-15 20:13
11
0
cool。thx
雪    币: 67
活跃值: 活跃值 (11)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
coltor 活跃值 2 2014-5-15 21:03
12
0
Chapter11: Injecting,Hooking and Swizzing.
呵呵~~
雪    币: 170
活跃值: 活跃值 (43)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
rainyx 活跃值 1 2014-5-15 22:10
13
0
大神轻虐!
雪    币: 252
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tiany 活跃值 2014-5-16 16:12
14
0
现在还在用XP的路过,不过确实高大帅富屌的代码感觉。
雪    币: 1781
活跃值: 活跃值 (46)
能力值: ( LV9,RANK:370 )
在线值:
发帖
回帖
粉丝
fosom 活跃值 8 2014-5-20 18:25
15
0
高端,留贴
雪    币: 8
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
brantb张 活跃值 2014-5-26 15:48
16
0
框架叫什么名字呢
雪    币: 170
活跃值: 活跃值 (43)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
rainyx 活跃值 1 2014-5-28 09:44
17
0
Cydia Substrate
雪    币: 186
活跃值: 活跃值 (17)
能力值: ( LV12,RANK:205 )
在线值:
发帖
回帖
粉丝
coolboyme 活跃值 2 2015-1-12 09:46
18
0
__pthread_set_self  这个符号找不到呢,在什么库里面呢。
雪    币: 153
活跃值: 活跃值 (214)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
人在塔在 活跃值 2016-4-11 15:32
19
0
dylib 类似dllmain的地方在哪。。
雪    币: 227
活跃值: 活跃值 (62)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
大王叫我挖坟 活跃值 3 2016-4-16 13:49
20
0
看了下标题,6的不要不要的,居然2014年就出来了,居然没有看到,遗憾啊,来晚了
雪    币: 2
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
computerboy 活跃值 2016-8-26 01:06
21
0
MARK一下
雪    币: 3
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小王fa 活跃值 2016-9-26 21:58
22
0
看起来很高端
雪    币: 581
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wx_铁牛 活跃值 2017-7-20 05:32
23
0
大神就喜欢玩这么高端的代码
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
满天星空 活跃值 2020-11-11 10:33
24
0

ios12.0如何实现啊

最后于 2020-11-11 15:37 被满天星空编辑 ,原因:
雪    币: 4617
活跃值: 活跃值 (1212)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
尐进 活跃值 2020-11-11 17:22
25
0
mark
游客
登录 | 注册 方可回帖
返回