Skip to content

Commit

Permalink
Fixed(TabpePlus): Import Connection
Browse files Browse the repository at this point in the history
closed: #18
  • Loading branch information
marlkiller committed Jun 19, 2024
1 parent 3fa9dda commit a5fcc21
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 92 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,5 @@ fastlane/test_output
iOSInjectionProject/
cmake-build-debug
cmake-build-release

release/dylib_dobby_hook.dylib
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@

## Quick Start

```
git clone https://github.com/marlkiller/dylib_dobby_hook.git

[download latest release](https://github.com/marlkiller/dylib_dobby_hook/releases/download/latest/dylib_dobby_hook.tar.gz)
```shell
tar -xzvf dylib_dobby_hook.tar.gz
cd script
sudo sh auto_hack.sh
```
Expand Down
106 changes: 24 additions & 82 deletions dylib_dobby_hook/apps/TablePlusHack.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ @implementation TablePlusHack
static IMP urlWithStringSeletorIMP;
static IMP NSURLSessionClassIMP;
static IMP dataTaskWithRequestIMP;

static IMP decryptDataIMP;


- (NSString *)getAppName {
Expand All @@ -49,72 +49,6 @@ - (NSString *)getSupportAppVersion {
}


//__strong id _rbx;
//
//id hook_license(int arg0, int arg1, int arg2, int arg3){
// if (_rbx==nil){
//
// // 通过反射获取 Swift 类
// Class TBLicenseModelClass = NSClassFromString(@"_TtC9TablePlus14TBLicenseModel");
// if (!TBLicenseModelClass) {
// return nil;
// }
//
// id r12 = [TBLicenseModelClass alloc] ;
//
// [MemoryUtils listAllPropertiesMethodsAndVariables:TBLicenseModelClass];
// // LicenseModel *r12 = [[NSClassFromString(@"LicenseModel") alloc] init];
// NSString *deviceId = [EncryptionUtils generateTablePlusDeviceId];
//// [r12 setValue:deviceId forKey:@"deviceID"];
// [MemoryUtils setInstanceIvar:r12 ivarName:@"deviceID" value:deviceId];
// [MemoryUtils setInstanceIvar:r12 ivarName:@"sign" value:@"12345678901234567890123456789012345678901234567890"];
// [MemoryUtils setInstanceIvar:r12 ivarName:@"purchasedAt" value:@"2999-01-16"];
// [MemoryUtils setInstanceIvar:r12 ivarName:@"updatesAvailableUntil" value:@"2999-01-16"];
// [MemoryUtils setInstanceIvar:r12 ivarName:@"licenseKey" value:@"licenseKey"];
// [MemoryUtils setInstanceIvar:r12 ivarName:@"nextChargeAt" value:@"123456"];
// [MemoryUtils setInstanceIvar:r12 ivarName:@"email" value:[NSString stringWithCString:global_email_address encoding:NSUTF8StringEncoding]];
//
// // 获取属性名对应的 Ivar
// Ivar ivar = class_getInstanceVariable([TBLicenseModelClass class], "deviceID");
// // 如果 ivar 不为空,说明属性存在
// if (ivar != NULL) {
// // 获取属性的偏移量
// ptrdiff_t offset = ivar_getOffset(ivar);
//
// uintptr_t address = (uintptr_t)(__bridge void *)r12 + offset;
// // 计算属性在对象中的地址
// NSString * __autoreleasing *deviceIdPtr = (NSString * __autoreleasing *)(void *)address;
// *deviceIdPtr = deviceId;
// }
//
// Ivar sign = class_getInstanceVariable([TBLicenseModelClass class], "sign");
// if (sign != NULL) {
// ptrdiff_t offset = ivar_getOffset(sign);
// uintptr_t address = (uintptr_t)(__bridge void *)r12 + offset;
// NSString * __autoreleasing *deviceIdPtr = (NSString * __autoreleasing *)(void *)address;
// *deviceIdPtr = deviceId;
// }
//
// _rbx=r12;
// NSLog(@">>>>>> deviceId: %@",deviceId);
//// _rbx=r12;
//// return r12;
// // rax_12.b = rax_11 s>= 0x32
//// NSDictionary *propertyDictionary = @{
//// @"sign": @"12345678901234567890123456789012345678901234567890",
//// @"email": [NSString stringWithCString:global_email_address encoding:NSUTF8StringEncoding],
//// @"deviceID": deviceId,
//// @"licenseKey": @"licenseKey",
//// @"purchasedAt": @"2999-01-16",
//// @"nextChargeAt": @(9999999999999), // Replace with the actual double value
//// @"updatesAvailableUntil": @"2999-01-16" // Replace with the actual value
//// };
//// _rbx = [r12 initWithDictionary:propertyDictionary];;
// }
// return _rbx;
//}



- (BOOL)hack {

Expand Down Expand Up @@ -161,9 +95,14 @@ - (BOOL)hack {

// r12 = [[RNDecryptor decryptData:"file bytes" withPassword:"x" error:&var_48] retain];
// +[RNDecryptor decryptData:withPassword:error:]:
Class RNDecryptorClz = NSClassFromString(@"RNDecryptor");
SEL decryptDataSel = NSSelectorFromString(@"decryptData:withPassword:error:");
Method decryptDataMethod = class_getClassMethod(RNDecryptorClz, decryptDataSel);
decryptDataIMP = method_getImplementation(decryptDataMethod);

[MemoryUtils hookClassMethod:
NSClassFromString(@"RNDecryptor")
originalSelector: NSSelectorFromString(@"decryptData:withPassword:error:")
RNDecryptorClz
originalSelector:decryptDataSel
swizzledClass:[self class]
swizzledSelector:NSSelectorFromString(@"hk_decryptData:withPassword:error:")
];
Expand Down Expand Up @@ -263,19 +202,22 @@ - (id)hk_dataTaskWithHTTPMethod:(NSString *)method


+ (id) hk_decryptData:arg1 withPassword:(NSString *)withPassword error:(int)error{
NSDictionary *propertyDictionary = @{
@"sign": @"12345678901234567890123456789012345678901234567890",
@"email": [NSString stringWithCString:global_email_address encoding:NSUTF8StringEncoding],
@"deviceID":[EncryptionUtils generateTablePlusDeviceId],
@"licenseKey": @"licenseKey",
@"purchasedAt": @"2025-06-16",
@"nextChargeAt": @"2025-06-16",
@"updatesAvailableUntil": @"2025-06-16"
};
// Class TBLicenseModelClass = NSClassFromString(@"_TtC9TablePlus14TBLicenseModel");
// [MemoryUtils listAllPropertiesMethodsAndVariables:TBLicenseModelClass];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:propertyDictionary options:0 error:nil];
return jsonData;

if ([arg1 isKindOfClass:NSClassFromString(@"_NSInlineData")]) {
NSDictionary *propertyDictionary = @{
@"sign": @"12345678901234567890123456789012345678901234567890",
@"email": [NSString stringWithCString:global_email_address encoding:NSUTF8StringEncoding],
@"deviceID":[EncryptionUtils generateTablePlusDeviceId],
@"licenseKey": @"licenseKey",
@"purchasedAt": @"2025-06-16",
@"nextChargeAt": @"2025-06-16",
@"updatesAvailableUntil": @"2025-06-16"
};
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:propertyDictionary options:0 error:nil];
return jsonData;
}

return ((id(*)(id, SEL,id,NSString*,int))decryptDataIMP)(self, _cmd,arg1,withPassword,error);
}

+ (id)hk_URLWithString:arg1{
Expand Down
88 changes: 81 additions & 7 deletions dylib_dobby_hook/utils/common_ret.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,96 @@
#include <sys/types.h>
#include <stdio.h>

#import <Foundation/Foundation.h>
#import "Constant.h"
#import "dobby.h"
#import "MemoryUtils.h"
#import <objc/runtime.h>
#include <mach-o/dyld.h>
#import "HackProtocol.h"
#include <sys/ptrace.h>
#import <objc/message.h>
#import "common_ret.h"
#include <sys/xattr.h>
#import <CommonCrypto/CommonCrypto.h>
#import "encryp_utils.h"
#import <sys/ptrace.h>
#import <sys/sysctl.h>
#include <dlfcn.h>
#include <libproc.h>
#import <Foundation/Foundation.h>
#import <sys/sysctl.h>
#include <sys/ioctl.h>
#include <mach/mach.h>
#include <mach/thread_act.h>
#include <mach/mach_types.h>
#include <mach/i386/thread_status.h>

int ret2 (void);
int ret1 (void);
int ret0 (void);
void ret(void);

// ptrace hook 相关
// ptrace 函数指针
// AntiAntiDebug 反反调试相关
typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data);
int my_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);
extern ptrace_ptr_t orig_ptrace;

// TODO
// 1. hook SecCode
// 2, hook nop
// 3. hook svc80
// 4. dlopen/dlclose/sysctl....

typedef int (*sysctl_ptr_t)(int * name, u_int namelen, void * info, size_t * infosize, void * newinfo, size_t newinfosize);
int my_sysctl(int * name, u_int namelen, void * info, size_t * infosize, void * newinfo, size_t newinfosize);
extern sysctl_ptr_t orig_sysctl;

typedef kern_return_t (*task_get_exception_ports_ptr_t)(
task_inspect_t task,
exception_mask_t exception_mask,
exception_mask_array_t masks,
mach_msg_type_number_t *masksCnt,
exception_handler_array_t old_handlers,
exception_behavior_array_t old_behaviors,
exception_flavor_array_t old_flavors
);
kern_return_t my_task_get_exception_ports
(
task_inspect_t task,
exception_mask_t exception_mask,
exception_mask_array_t masks,
mach_msg_type_number_t *masksCnt,
exception_handler_array_t old_handlers,
exception_behavior_array_t old_behaviors,
exception_flavor_array_t old_flavors
);
extern task_get_exception_ports_ptr_t orig_task_get_exception_ports;


typedef kern_return_t (*task_swap_exception_ports_ptr_t)(
task_t task,
exception_mask_t exception_mask,
mach_port_t new_port,
exception_behavior_t new_behavior,
thread_state_flavor_t new_flavor,
exception_mask_array_t old_masks,
mach_msg_type_number_t *old_masks_count,
exception_port_array_t old_ports,
exception_behavior_array_t old_behaviors,
thread_state_flavor_array_t old_flavors
);
kern_return_t my_task_swap_exception_ports
(
task_t task,
exception_mask_t exception_mask,
mach_port_t new_port,
exception_behavior_t new_behavior,
thread_state_flavor_t new_flavor,
exception_mask_array_t old_masks,
mach_msg_type_number_t *old_masks_count,
exception_port_array_t old_ports,
exception_behavior_array_t old_behaviors,
thread_state_flavor_array_t old_flavors
);
extern task_swap_exception_ports_ptr_t orig_task_swap_exception_ports;



// 声明全局的邮件地址
extern char *global_email_address;
Expand Down
89 changes: 89 additions & 0 deletions dylib_dobby_hook/utils/common_ret.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@
//

#include "common_ret.h"
#import <Foundation/Foundation.h>
#import "Constant.h"
#import "MemoryUtils.h"
#include <mach-o/dyld.h>
#import "HackProtocol.h"
#include <sys/ptrace.h>
#import <sys/sysctl.h>
#include <mach/mach_types.h>
#include <mach/i386/thread_status.h>

int ret2 (void){
printf(">>>>>> ret2\n");
return 2;
Expand All @@ -23,6 +33,9 @@ void ret(void){
printf(">>>>>> ret\n");
}


// hook ptrace
// 通过 ptrace 来检测当前进程是否被调试,通过检查 PT_DENY_ATTACH 标记是否被设置来判断。如果检测到该标记,说明当前进程正在被调试,可以采取相应的反调试措施。
ptrace_ptr_t orig_ptrace = NULL;
int my_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data) {
if(_request != 31){
Expand All @@ -34,5 +47,81 @@ int my_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data) {
return 0;
}

// hook sysctl
// 通过 sysctl 去查看当前进程的信息,看有没有这个标记位即可检查当前调试状态。
sysctl_ptr_t orig_sysctl = NULL;
int my_sysctl(int * name, u_int namelen, void * info, size_t * infosize, void * newinfo, size_t newinfosize){
int ret = orig_sysctl(name,namelen,info,infosize,newinfo,newinfosize);
if(namelen == 4 && name[0] == 1 && name[1] == 14 && name[2] == 1){
struct kinfo_proc *info_ptr = (struct kinfo_proc *)info;
if(info_ptr && (info_ptr->kp_proc.p_flag & P_TRACED) != 0){
NSLog(@">>>>>> [AntiAntiDebug] - sysctl query trace status.");
info_ptr->kp_proc.p_flag ^= P_TRACED;
if((info_ptr->kp_proc.p_flag & P_TRACED) == 0){
NSLog(@">>>>>> [AntiAntiDebug] - trace status reomve success!");
}
}
}
return ret;
}

// hook task_get_exception_ports
// 通过 task_get_exception_ports 来检查当前任务的异常端口设置,以检测调试器的存在或者检查调试器是否修改了异常端口设置。如果发现异常端口被修改,可能表明调试器介入了目标进程的执行。
// some app will crash with _dyld_debugger_notification
task_get_exception_ports_ptr_t orig_task_get_exception_ports = NULL;
kern_return_t my_task_get_exception_ports
(
task_inspect_t task,
exception_mask_t exception_mask,
exception_mask_array_t masks,
mach_msg_type_number_t *masksCnt,
exception_handler_array_t old_handlers,
exception_behavior_array_t old_behaviors,
exception_flavor_array_t old_flavors
){
kern_return_t r = orig_task_get_exception_ports(task, exception_mask, masks, masksCnt, old_handlers, old_behaviors, old_flavors);
for (int i = 0; i < *masksCnt; i++)
{
if (old_handlers[i] != 0) {
old_handlers[i] = 0;
}
if (old_flavors[i] == THREAD_STATE_NONE) {
// x86_EXCEPTION_STATE
// x86_EXCEPTION_STATE64
// ARM_EXCEPTION_STATE
// #if defined(__arm64__) || defined(__aarch64__)
// #elif defined(__x86_64__)
// #endif
old_flavors[i] = 9;
NSLog(@">>>>>> [AntiAntiDebug] - my_task_get_exception_ports reset old_flavors[i]=9");
}
}
return r;
}

// hook task_swap_exception_ports
// 通过 task_swap_exception_ports 来动态修改异常处理端口设置,以防止调试器对异常消息进行拦截或修改。例如,恶意软件可以将异常端口设置为自定义的端口,从而阻止调试器捕获异常消息,使调试器无法获取目标进程的状态信息。
task_swap_exception_ports_ptr_t orig_task_swap_exception_ports = NULL;
kern_return_t my_task_swap_exception_ports(
task_t task,
exception_mask_t exception_mask,
mach_port_t new_port,
exception_behavior_t new_behavior,
thread_state_flavor_t new_flavor,
exception_mask_array_t old_masks,
mach_msg_type_number_t *old_masks_count,
exception_port_array_t old_ports,
exception_behavior_array_t old_behaviors,
thread_state_flavor_array_t old_flavors
) {

// 在这里实现反反调试逻辑,例如阻止特定的异常掩码或端口
if (exception_mask & EXC_MASK_BREAKPOINT) {
NSLog(@">>>>>> [AntiAntiDebug] - my_task_swap_exception_ports Breakpoint exception detected, blocking task_swap_exception_ports");
return KERN_FAILURE; // 返回错误码阻止调用
}
return orig_task_swap_exception_ports(task, exception_mask, new_port, new_behavior, new_flavor, old_masks, old_masks_count, old_ports, old_behaviors, old_flavors);
}


char *global_email_address = "K'ed by: [email protected]";
2 changes: 2 additions & 0 deletions release/EMPTY
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
## Develop
Compile dylib and link APP in this directory
Binary file removed release/libdylib_dobby_hook.dylib
Binary file not shown.
2 changes: 1 addition & 1 deletion tools/dtrace_kill.d
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/sbin/dtrace -qs
/* sudo dtrace -s kill.d
/* sudo dtrace -s dtrace_kill.d
* kill.d - watch process signals as they are sent (eg, kill -9).
* Written in DTrace (Solaris 10 3/05).
*
Expand Down

0 comments on commit a5fcc21

Please sign in to comment.