Skip to content

Instantly share code, notes, and snippets.

@esterTion
Last active April 12, 2018 14:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save esterTion/9eb39738b51b85d6d7c42d769c89c071 to your computer and use it in GitHub Desktop.
Save esterTion/9eb39738b51b85d6d7c42d769c89c071 to your computer and use it in GitHub Desktop.
redive-tech
shit title place holder

Use at your own risk

Dump app binary with Il2Cpp, fill in the corresponding field in plist

Compiled version at https://repo.estertion.win/ (not updated for latest version)

My account has been banned for three times by now

Package: puricone-redive-tech
Name: tech for プリコネR
Depends: mobilesubstrate
Version: 0.0.1
Architecture: iphoneos-arm
Description: 草
Author: esterTion
Section: Tweaks
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>entry</key>
<dict>
<key>cell</key>
<string>PSLinkCell</string>
<key>label</key>
<string>Redive科技</string>
</dict>
<key>items</key>
<array>
<dict>
<key>cell</key>
<string>PSSwitchCell</string>
<key>default</key>
<false/>
<key>defaults</key>
<string>redive-tech</string>
<key>key</key>
<string>enable</string>
<key>label</key>
<string>启用</string>
</dict>
<dict>
<key>cell</key>
<string>PSSwitchCell</string>
<key>default</key>
<false/>
<key>defaults</key>
<string>redive-tech</string>
<key>key</key>
<string>log</string>
<key>label</key>
<string>log</string>
</dict>
<dict>
<key>cell</key>
<string>PSGroupCell</string>
<key>label</key>
<string>攻击</string>
</dict>
<dict>
<key>cell</key>
<string>PSLinkListCell</string>
<key>default</key>
<string>off</string>
<key>defaults</key>
<string>redive-tech</string>
<key>detail</key>
<string>PSListItemsController</string>
<key>key</key>
<string>atk</string>
<key>label</key>
<string>修改模式</string>
<key>validTitles</key>
<array>
<string>关</string>
<string>开根号</string>
<string>固定值</string>
<string>百分比</string>
</array>
<key>validValues</key>
<array>
<string>off</string>
<string>sqrt</string>
<string>static</string>
<string>percent</string>
</array>
</dict>
<dict>
<key>cell</key>
<string>PSSliderCell</string>
<key>default</key>
<real>250</real>
<key>defaults</key>
<string>redive-tech</string>
<key>isSegmented</key>
<false/>
<key>key</key>
<string>atk_value</string>
<key>label</key>
<string>修改值</string>
<key>max</key>
<real>500</real>
<key>min</key>
<real>0</real>
<key>showValue</key>
<true/>
</dict>
<dict>
<key>cell</key>
<string>PSGroupCell</string>
<key>label</key>
<string>防御</string>
</dict>
<dict>
<key>cell</key>
<string>PSLinkListCell</string>
<key>default</key>
<string>off</string>
<key>defaults</key>
<string>redive-tech</string>
<key>detail</key>
<string>PSListItemsController</string>
<key>key</key>
<string>def</string>
<key>label</key>
<string>修改模式</string>
<key>validTitles</key>
<array>
<string>关</string>
<string>开根号</string>
<string>固定值</string>
<string>百分比</string>
</array>
<key>validValues</key>
<array>
<string>off</string>
<string>sqrt</string>
<string>static</string>
<string>percent</string>
</array>
</dict>
<dict>
<key>cell</key>
<string>PSSliderCell</string>
<key>default</key>
<real>250</real>
<key>defaults</key>
<string>redive-tech</string>
<key>isSegmented</key>
<false/>
<key>key</key>
<string>def_value</string>
<key>label</key>
<string>修改值</string>
<key>max</key>
<real>500</real>
<key>min</key>
<real>0</real>
<key>showValue</key>
<true/>
</dict>
<dict>
<key>cell</key>
<string>PSGroupCell</string>
<key>label</key>
<string>血量</string>
</dict>
<dict>
<key>cell</key>
<string>PSLinkListCell</string>
<key>default</key>
<string>off</string>
<key>defaults</key>
<string>redive-tech</string>
<key>detail</key>
<string>PSListItemsController</string>
<key>key</key>
<string>hp</string>
<key>label</key>
<string>修改模式</string>
<key>validTitles</key>
<array>
<string>关</string>
<string>开根号</string>
<string>固定值</string>
<string>百分比</string>
</array>
<key>validValues</key>
<array>
<string>off</string>
<string>sqrt</string>
<string>static</string>
<string>percent</string>
</array>
</dict>
<dict>
<key>cell</key>
<string>PSSliderCell</string>
<key>default</key>
<real>1000</real>
<key>defaults</key>
<string>redive-tech</string>
<key>isSegmented</key>
<false/>
<key>key</key>
<string>hp_value</string>
<key>label</key>
<string>修改值</string>
<key>max</key>
<real>2000</real>
<key>min</key>
<real>0</real>
<key>showValue</key>
<true/>
</dict>
</array>
<key>title</key>
<string>Redive科技</string>
</dict>
</plist>
include $(THEOS)/makefiles/common.mk
TWEAK_NAME = puriconeRtech
puriconeRtech_ARCHS = arm64
puriconeRtech_FILES = Tweak.xm
include $(THEOS_MAKE_PATH)/tweak.mk
after-install::
install.exec "killall -9 princessconnectredive >/dev/null"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Filter</key>
<dict>
<key>Bundles</key>
<array>
<string>jp.co.cygames.princessconnectredive</string>
</array>
</dict>
<key>ver</key>
<string>14</string>
<key>off</key>
<array>
<integer>0x10038B068</integer> <!-- EnemyParameter_Ctor -->
<integer>0x10007A878</integer> <!-- ObscuredInt_op_implicit -->
<integer>0x10076E76C</integer> <!-- UnitData_get_totalhp -->
<integer>0x10076E8A8</integer> <!-- UnitData_get_TotalAtk -->
<integer>0x10076E9E4</integer> <!-- UnitData_get_TotalDef -->
<integer>0x10076EB20</integer> <!-- UnitData_get_TotalMagicAtk -->
<integer>0x10076EC5C</integer> <!-- UnitData_get_TotalMagicDef -->
</array>
</dict>
</plist>
#import <substrate.h>
#import <dlfcn.h>
#import <mach-o/dyld.h>
//#import <sqlite3.h>
NSString* CSStringReader(char* stringPtr) {
int stringLen = *((int*)(stringPtr + 0x10));
char* cStringPtr = (char*)(stringPtr + 0x14);
//NSLog(@"[CSStringReader] ptr: %lx, stringLen: %d", (long)stringPtr, stringLen);
NSData *data = [[[NSData alloc] initWithBytesNoCopy:cStringPtr length: stringLen * 2 freeWhenDone:NO] autorelease];
NSString * string = [[[NSString alloc] initWithData:data encoding:NSUTF16LittleEndianStringEncoding] autorelease];
return string;
}
NSObject* RediveTechGetSettingValue(NSString *key, NSObject *defaultValue) {
NSDictionary *setting = [NSDictionary dictionaryWithContentsOfFile: @"/var/mobile/Library/Preferences/redive-tech.plist"];
if (setting == NULL) return defaultValue;
NSObject *value = [setting objectForKey:key];
if (value == NULL) return defaultValue;
return value;
}
long RediveTechApplySetting(NSString* key, long input, long defaultVal, long max) {
NSString *mode = (NSString*)RediveTechGetSettingValue(key, @"off");
long output;
if ([mode isEqualToString:@"off"]) {
output = input;
} else if ([mode isEqualToString:@"sqrt"]) {
output = (long)sqrt((int)input);
} else if ([mode isEqualToString:@"static"]) {
output = [(NSNumber*)RediveTechGetSettingValue([key stringByAppendingString:@"_value"], [NSNumber numberWithInt:defaultVal]) longLongValue];
} else if ([mode isEqualToString:@"percent"]) {
output = (long)((int)input * [(NSNumber*)RediveTechGetSettingValue([key stringByAppendingString:@"_value"], [NSNumber numberWithInt:defaultVal]) intValue] / (int)max);
} else {
output = defaultVal;
}
if (input != output && [(NSNumber*)RediveTechGetSettingValue(@"log", @0) isEqualToNumber:@1])
NSLog(@"%@ changed from %d to %ld", key, (int)input, output);
return output;
}
//static NSMutableArray *blackListMob = NULL;
long (*orig_EnemyParameter_Ctor)(long a1, long enemy_id, long unit_id, long name, long level, long rarity, long promotion_level, long hp, long atk, long magic_str, long def, long magic_def, long physical_critical, long magic_critical, long wave_hp_recovery, long wave_energy_recovery, long dodge, long physical_penetrate, long magic_penetrate, long life_steal, long hp_recovery_rate, long energy_recovery_rate, long energy_reduce_rate, long resist_status_id);
long hacked_EnemyParameter_Ctor(long a1, long enemy_id, long unit_id, long name, long level, long rarity, long promotion_level, long hp, long atk, long magic_str, long def, long magic_def, long physical_critical, long magic_critical, long wave_hp_recovery, long wave_energy_recovery, long dodge, long physical_penetrate, long magic_penetrate, long life_steal, long hp_recovery_rate, long energy_recovery_rate, long energy_reduce_rate, long resist_status_id) {
if (enemy_id > 300000000 && enemy_id < 500000000) {
NSLog(@"Disable modifing for clan battle boss, info %@", @{
@"enemy_id":[NSNumber numberWithInt:enemy_id],
@"unit_id":[NSNumber numberWithInt:unit_id],
@"name":CSStringReader((char*)name)
});
} else if ([(NSNumber*)RediveTechGetSettingValue(@"enable", @0) isEqualToNumber:@1]) {
NSNumber *log = (NSNumber*)RediveTechGetSettingValue(@"log", @0);
atk = RediveTechApplySetting(@"atk", atk, 250L, 500L);
magic_str = RediveTechApplySetting(@"atk", magic_str, 250L, 500L);
def = RediveTechApplySetting(@"def", def, 250L, 500L);
magic_def = RediveTechApplySetting(@"def", magic_def, 250L, 500L);
hp = RediveTechApplySetting(@"hp", hp, 1000L, 2000L);
if ([log isEqualToNumber:@1]) {
NSLog(@"[RediveTech] %@", @{
@"enemy_id":[NSNumber numberWithInt:enemy_id],
@"unit_id":[NSNumber numberWithInt:unit_id],
@"name":CSStringReader((char*)name),
@"level":[NSNumber numberWithInt:level],
@"rarity":[NSNumber numberWithInt:rarity],
@"promotion_level":[NSNumber numberWithInt:promotion_level],
@"hp":[NSNumber numberWithInt:hp],
@"atk":[NSNumber numberWithInt:atk],
@"magic_str":[NSNumber numberWithInt:magic_str],
@"def":[NSNumber numberWithInt:def],
@"magic_def":[NSNumber numberWithInt:magic_def],
@"physical_critical":[NSNumber numberWithInt:physical_critical],
@"magic_critical":[NSNumber numberWithInt:magic_critical],
@"wave_hp_recovery":[NSNumber numberWithInt:wave_hp_recovery],
@"wave_energy_recovery":[NSNumber numberWithInt:wave_energy_recovery],
@"dodge":[NSNumber numberWithInt:dodge],
@"physical_penetrate":[NSNumber numberWithInt:physical_penetrate],
@"magic_penetrate":[NSNumber numberWithInt:magic_penetrate],
@"life_steal":[NSNumber numberWithInt:life_steal],
@"hp_recovery_rate":[NSNumber numberWithInt:hp_recovery_rate],
@"energy_recovery_rate":[NSNumber numberWithInt:energy_recovery_rate],
@"energy_reduce_rate":[NSNumber numberWithInt:energy_reduce_rate],
@"resist_status_id":[NSNumber numberWithInt:resist_status_id]
});
}
}
return orig_EnemyParameter_Ctor(a1, enemy_id, unit_id, name, level, rarity, promotion_level, hp, atk, magic_str, def, magic_def, physical_critical, magic_critical, wave_hp_recovery, wave_energy_recovery, dodge, physical_penetrate, magic_penetrate, life_steal, hp_recovery_rate, energy_recovery_rate, energy_reduce_rate, resist_status_id);
}
long (*orig_ObscuredInt_op_implicit)(long a1, long a2);
/*
BOOL modifyEnemyValue(long a1) {
long enemy_id = orig_ObscuredInt_op_implicit(0, *(long*)(a1 + 0x10));
NSLog(@"%ld", enemy_id);
if ((enemy_id > 300000000 && enemy_id < 500000000) || enemy_id == 0) {
long unit_id = orig_ObscuredInt_op_implicit(0, *(long*)(a1 + 0x1c));
NSLog(@"Disable modifing EnemyParameter for clan battle boss, id %ld %ld", enemy_id, unit_id);
return false;
}
return [(NSNumber*)RediveTechGetSettingValue(@"enable", @0) isEqualToNumber:@1];
}
long (*orig_EnemyParameter_get_hp)(long a1);
long hacked_EnemyParameter_get_hp(long a1) {
long value = orig_EnemyParameter_get_hp(a1);
if (modifyEnemyValue(a1)) {
value = orig_ObscuredInt_op_implicit(0, RediveTechApplySetting(@"hp", value, 1000L, 2000L));
}
return value;
}
long (*orig_EnemyParameter_get_atk)(long a1);
long hacked_EnemyParameter_get_atk(long a1) {
long value = orig_EnemyParameter_get_atk(a1);
if (modifyEnemyValue(a1)) {
value = orig_ObscuredInt_op_implicit(0, RediveTechApplySetting(@"atk", value, 250L, 500L));
}
return value;
}
long (*orig_EnemyParameter_get_magic_str)(long a1);
long hacked_EnemyParameter_get_magic_str(long a1) {
long value = orig_EnemyParameter_get_magic_str(a1);
if (modifyEnemyValue(a1)) {
value = orig_ObscuredInt_op_implicit(0, RediveTechApplySetting(@"def", value, 250L, 500L));
}
return value;
}
long (*orig_EnemyParameter_get_def)(long a1);
long hacked_EnemyParameter_get_def(long a1) {
long value = orig_EnemyParameter_get_def(a1);
if (modifyEnemyValue(a1)) {
value = orig_ObscuredInt_op_implicit(0, RediveTechApplySetting(@"atk", value, 250L, 500L));
}
return value;
}
long (*orig_EnemyParameter_get_magic_def)(long a1);
long hacked_EnemyParameter_get_magic_def(long a1) {
long value = orig_EnemyParameter_get_magic_def(a1);
if (modifyEnemyValue(a1)) {
value = orig_ObscuredInt_op_implicit(0, RediveTechApplySetting(@"def", value, 250L, 500L));
}
return value;
}
*/
BOOL modifyUnitValue(long a1) {
long UnitExp = orig_ObscuredInt_op_implicit(0LL, *(long*)(a1 + 0x54));
long UnitId = orig_ObscuredInt_op_implicit(0LL, *(long*)(a1 + 0x10));
if (UnitId > 300000000 && UnitId < 500000000) {
NSLog(@"Disable modifing UnitData for clan battle boss, id %ld", UnitId);
return false;
}
return UnitExp == 0 && [(NSNumber*)RediveTechGetSettingValue(@"enable", @0) isEqualToNumber:@1];
}
long (*orig_UnitData_get_totalhp)(long a1);
long hacked_UnitData_get_totalhp(long a1) {
long value = orig_UnitData_get_totalhp(a1);
if (modifyUnitValue(a1)) {
value = RediveTechApplySetting(@"hp", value, 1000L, 2000L);
}
return value;
}
long (*orig_UnitData_get_TotalAtk)(long a1);
long hacked_UnitData_get_TotalAtk(long a1) {
long value = orig_UnitData_get_TotalAtk(a1);
if (modifyUnitValue(a1)) {
value = RediveTechApplySetting(@"atk", value, 250L, 500L);
}
return value;
}
long (*orig_UnitData_get_TotalDef)(long a1);
long hacked_UnitData_get_TotalDef(long a1) {
long value = orig_UnitData_get_TotalDef(a1);
if (modifyUnitValue(a1)) {
value = RediveTechApplySetting(@"def", value, 250L, 500L);
}
return value;
}
long (*orig_UnitData_get_TotalMagicAtk)(long a1);
long hacked_UnitData_get_TotalMagicAtk(long a1) {
long value = orig_UnitData_get_TotalMagicAtk(a1);
if (modifyUnitValue(a1)) {
value = RediveTechApplySetting(@"atk", value, 250L, 500L);
}
return value;
}
long (*orig_UnitData_get_TotalMagicDef)(long a1);
long hacked_UnitData_get_TotalMagicDef(long a1) {
long value = orig_UnitData_get_TotalMagicDef(a1);
if (modifyUnitValue(a1)) {
value = RediveTechApplySetting(@"def", value, 250L, 500L);
}
return value;
}
%hook NSDictionary
- (NSString *)descriptionWithLocale:(id)locale {
NSArray *allKeys = [self allKeys];
NSMutableString *str = [[NSMutableString alloc] initWithFormat:@"{\n "];
for (NSString *key in allKeys) {
id value= self[key];
[str appendFormat:@"\t \"%@\" = %@,\n",key, value];
}
[str appendString:@"}"];
return str;
}
%end
/*int db_callback(void *a, int argc, char **argv, char **colName) {
for (int i=0; i<argc; i++) {
NSLog(@"read db: %@", [NSString stringWithFormat:@"%s=%s", colName[i], argv[i]]);
}
[blackListMob addObject:[NSString stringWithFormat:@"%s", argv[0]]];
NSLog(@"blacklist %@", blackListMob);
return 0;
};*/
@interface ObscuredInt : NSObject
@end
@implementation ObscuredInt
+(long)implicit:(long)num {
return orig_ObscuredInt_op_implicit(NULL, num);
}
@end
static id observer;
%ctor
{
@autoreleasepool
{
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile: @"/Library/MobileSubstrate/DynamicLibraries/puriconeRtech.plist"];
if ([[[NSBundle mainBundle] infoDictionary][@"CFBundleVersion"] isEqualToString:dict[@"ver"]]){
unsigned long EnemyParameter_Ctor = _dyld_get_image_vmaddr_slide(0) + [dict[@"off"][0] longValue];
MSHookFunction((void *)EnemyParameter_Ctor, (void *)hacked_EnemyParameter_Ctor, (void **)&orig_EnemyParameter_Ctor);
//unsigned long ObscuredInt_op_implicit = _dyld_get_image_vmaddr_slide(0) + 0x10007BE88;
//MSHookFunction((void *)ObscuredInt_op_implicit, (void *)hacked_ObscuredInt_op_implicit, (void **)&orig_ObscuredInt_op_implicit);
orig_ObscuredInt_op_implicit = (long (*)(long, long))(_dyld_get_image_vmaddr_slide(0) + [dict[@"off"][1] longValue]);
/*
unsigned long EnemyParameter_get_hp = _dyld_get_image_vmaddr_slide(0) + [dict[@"off"][0] longValue];
unsigned long EnemyParameter_get_atk = EnemyParameter_get_hp + 0x10;
unsigned long EnemyParameter_get_magic_str = EnemyParameter_get_hp + 0x20;
unsigned long EnemyParameter_get_def = EnemyParameter_get_hp + 0x30;
unsigned long EnemyParameter_get_magic_def = EnemyParameter_get_hp + 0x40;
MSHookFunction((void *)EnemyParameter_get_hp, (void *)hacked_EnemyParameter_get_hp, (void **)&orig_EnemyParameter_get_hp);
MSHookFunction((void *)EnemyParameter_get_atk, (void *)hacked_EnemyParameter_get_atk, (void **)&orig_EnemyParameter_get_atk);
MSHookFunction((void *)EnemyParameter_get_magic_str, (void *)hacked_EnemyParameter_get_magic_str, (void **)&orig_EnemyParameter_get_magic_str);
MSHookFunction((void *)EnemyParameter_get_def, (void *)hacked_EnemyParameter_get_def, (void **)&orig_EnemyParameter_get_def);
MSHookFunction((void *)EnemyParameter_get_magic_def, (void *)hacked_EnemyParameter_get_magic_def, (void **)&orig_EnemyParameter_get_magic_def);
*/
unsigned long UnitData_get_totalhp = _dyld_get_image_vmaddr_slide(0) + [dict[@"off"][2] longValue];
unsigned long UnitData_get_TotalAtk = _dyld_get_image_vmaddr_slide(0) + [dict[@"off"][3] longValue];
unsigned long UnitData_get_TotalDef = _dyld_get_image_vmaddr_slide(0) + [dict[@"off"][4] longValue];
unsigned long UnitData_get_TotalMagicAtk = _dyld_get_image_vmaddr_slide(0) + [dict[@"off"][5] longValue];
unsigned long UnitData_get_TotalMagicDef = _dyld_get_image_vmaddr_slide(0) + [dict[@"off"][6] longValue];
MSHookFunction((void *)UnitData_get_totalhp, (void *)hacked_UnitData_get_totalhp, (void **)&orig_UnitData_get_totalhp);
MSHookFunction((void *)UnitData_get_TotalAtk, (void *)hacked_UnitData_get_TotalAtk, (void **)&orig_UnitData_get_TotalAtk);
MSHookFunction((void *)UnitData_get_TotalDef, (void *)hacked_UnitData_get_TotalDef, (void **)&orig_UnitData_get_TotalDef);
MSHookFunction((void *)UnitData_get_TotalMagicAtk, (void *)hacked_UnitData_get_TotalMagicAtk, (void **)&orig_UnitData_get_TotalMagicAtk);
MSHookFunction((void *)UnitData_get_TotalMagicDef, (void *)hacked_UnitData_get_TotalMagicDef, (void **)&orig_UnitData_get_TotalMagicDef);
/*NSString *dbFile = [[[[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] standardizedURL] path] stringByAppendingString:@"/manifest/7d2bdcfa272ce3dadad2c2094b496a0ab1176aeb"];
if ([[NSFileManager defaultManager] fileExistsAtPath:dbFile]) {
sqlite3 *master;
blackListMob = [[NSMutableArray alloc] init];
char *error = NULL;
sqlite3_open([dbFile cStringUsingEncoding:NSUTF8StringEncoding], &master);
sqlite3_exec(master, "SELECT unit_id FROM enemy_parameter WHERE enemy_id>400000000 AND enemy_id<500000000", db_callback, 0, &error);
sqlite3_close(master);
NSLog(@"blacklist mob %@", blackListMob);
}*/
} else {
observer = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidFinishLaunchingNotification object:nil queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *notification) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Redive Tech"
message:[NSString stringWithFormat:@"不支持的版本:%@[%@]", [[NSBundle mainBundle] infoDictionary ][@"CFBundleShortVersionString"], [[NSBundle mainBundle] infoDictionary ][@"CFBundleVersion"]]
delegate:nil
cancelButtonTitle:[[NSBundle bundleWithIdentifier:@"com.apple.UIKit"] localizedStringForKey:@"Dismiss" value:@"" table:nil]
otherButtonTitles:nil];
//[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alert animated:YES completion:nil];
[alert show];
[alert release];
NSLog(@"Version Unsupported!!!");
[[NSNotificationCenter defaultCenter] removeObserver:observer];
}
];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment