吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 14329|回复: 8
收起左侧

[iOS 分享] iOS下远程进程注入dylib源码

  [复制链接]
pipcc 发表于 2014-6-11 15:34
本帖最后由 pipcc 于 2014-6-12 10:15 编辑

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

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

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

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

[Asm] 纯文本查看 复制代码
//
// 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;
}




发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

小野 发表于 2014-6-12 00:39
// Created by rainyx on 13-7-24. 你仔细看代码了吗?还BY 。。唉
thanmmm 发表于 2014-6-11 15:46
ojp2008520 发表于 2015-3-9 23:53
// Created by rainyx on 13-7-24.
// Copyright (c) 2013年 __MyCompanyName__. All rights reserved.


真的是 ,兄弟啊。你能否认真一点呢?
Ty_rone 发表于 2015-7-21 15:19
厉害。..........
okhjwok 发表于 2016-5-24 19:49 来自手机
看看大神谢谢大神
zxs2015 发表于 2016-5-25 23:00
牛逼了!!!!
 楼主| pipcc 发表于 2016-8-27 14:55
22.JPG
wenzunling 发表于 2016-8-27 21:28 来自手机
不懂,,,,,,
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 01:32

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表