2015-08-17 10:09:14 u012681458 阅读数 820
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    5909 人正在学习 去看看 李文瀚

第一步:准备工作

1. 创建一个String File类型文件,如下。

2.1 点击这个文件,在右侧导航栏点击Localize这个按钮,如下,添加多语言比如:语言和汉语

2.2 添加后,右侧如下

左侧项目文件Localize变成下面这样。

2.3 如果要添加更多语言,打开PROJECT,如下:

第二步:代码工作:

新建一个文件,在代码中加入下面的内容

swift:let testLocalized = NSLocalizedString("test1", comment: "这个是测试")

oc    :   NSString *testLocalized = NSLocalizedString(@"test1", @"这个是测试");

 

第三步:逆向工作:

1. 打开终端(Terminal),cd到项目的根目录。

2. 生成最终文件

swift:

find ./ -name "*.swift" | xargs genstrings -o en.lproj

find ./ -name "*.swift" | xargs genstrings -o zh-Hans.lproj

find ./ -name "*.swift" | xargs genstrings -o ja.lproj

oc:

find ./ -name *.m -print0 | xargs -0 genstrings -o en.lproj

find ./ -name *.m -print0 | xargs -0 genstrings -o zh-Hans.lproj

find ./ -name *.m -print0 | xargs -0 genstrings -o ja.lproj

3. 打开项目文件查看

4. 把这个丢给翻译,让他去修改就好,当然注释要明确,不然又产生沟通成本等等问题。

 

 

更多:

1. NSLocalizedString(key,comment)的‘comment’是用来生成描述文字,便于查看,不至于一头雾水,因此‘comment’包含的信息需要尽可能准确,可以精确到具体的项目的文件名,比如某个controller、某个view。

例子:

string国际化

NSLocalizedString(@"cancel",@"string::::aController::UILabel:取消");

图片国际化

NSLocalizedString(@"homeBackground",@"picture::::bController::UIImageView:homeBackground_en.png");

说明:1.key最好以英文为主;2.可以直接将英文的string做为key这样英文就不需要改,只需改其它语言;3.如果是图片国际化,最好以图片名字做为key,如果key没有对应值,默认是以key为值,可以正确调用图片

如下

NSLocalizedString(@"this is a localizable file",@"string::::cController::UILabel:这是国际化文件");

或者下面这样,key使用关键字

NSLocalizedString(@"localizable file",@"string::::cController::UILabel:这是国际化文件~this is a localizable file");

 

2. 从代码中逆向生成国际化文件。这样就不需要每次加了一个本地化字符串,就得手动去Localizable.strings添加对应的key。方法是先按照上面1.2的方式写好调用,等项目差不多写好了,使用苹果提供的快捷生成本地化key的命令。

需要注意的是,NSLocalizedString(key,comment),用这个函数时,key不能是宏定义或者一些动态字符串,否则用上面的命令会报错。

 

3.1 到了这里其实关于iOS的国际化已经算是完成了,但你可能也发现一个问题了,上面两种方法全都是一次性生成文件,但我们的项目往往会不断地更新。重新照上面流程跑,生成的string文件会将之前翻译好的文件覆盖掉。

3.2 代码的国际化还好,毕竟一般面对新需求我们都会新建新的类和文件,只要把新代码文件脱到一个文件夹下,执行genstrings便可以得到一份对应的本地化文件,然后拿给翻译人员,最后将翻译好的键值对追加在初始的localizable.string文件尾部即可。

 

4. 参考:

https://www.bbsmax.com/A/MAzAWM8p59/    总结,GitHub仓库改写的国际化功能

https://www.jianshu.com/p/6a37f7f8cecd    用偷懒的方式

https://www.cnblogs.com/yanzheng216/p/8674722.html

https://www.cnblogs.com/levilinxi/p/4296712.html     脚本:添加没有的,去掉多于的

 

 

5. 下面是打印出当前设备支持的所有语言:(其中zh-Hans是简体中文,zh-Hant是繁体中文;en英文,ja日文

(

    en,  "zh-Hans",  fr, de, ja, nl, it, es,  pt,  "pt-PT", da, fi, nb, sv,  ko,  "zh-Hant", ru, pl,

    tr, uk,  ar, hr, cs,  el,  he,  ro, sk, th,  id,  ms,  "en-GB",  ca, hu,  vi

)

 

2016-03-22 13:56:30 u013029271 阅读数 147
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    5909 人正在学习 去看看 李文瀚

A页面 创建按钮,跳到B页面

let btn = UIButton(type: UIButtonType.Custom)
self.myBtn = btn
btn.frame = CGRectMake(50, 50, 50, 50)
btn.setTitle("nextVC", forState: UIControlState.Normal)
btn.addTarget(self, action: "nextVC", forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(btn)


func nextVC(){
     let nextVC = NextViewController()
     nextVC.nextPara = {(num:Int) -> Void in
         self.myBtn.setTitle("\(num)", forState: UIControlState.Normal)
        }
     self.navigationController?.pushViewController(nextVC, animated: true)
    }

B页面 返回A页面传值

  • 定义闭包
typealias loginClosure = (num:Int)->Void
  • 返回按钮
 let btn = UIButton(type: UIButtonType.Custom)
 btn.frame = CGRectMake(50, 100, 100, 50)
 btn.setTitle("preVC", forState: UIControlState.Normal)
 btn.addTarget(self, action: "preVC", forControlEvents:  UIControlEvents.TouchUpInside)
 self.view.addSubview(btn)
  • 传值
  func preVC(){
        nextPara(num:12)
    self.navigationController?.popViewControllerAnimated(true)
    }
2016-01-22 09:39:32 loveqcx123 阅读数 353
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    5909 人正在学习 去看看 李文瀚

/**

1.扩展语法

2.计算型属性

3.构造器

4.方法

5.下标

6.嵌套类型

扩展就是向一个已有的类、结构体或枚举类型添加新功能。包括在没有权限获取原始源代码的情况下扩展类型的能力(即逆向建模)。扩展和OC中的分类(category)类似。不过与OC不同的是,swift的扩展没有名字。

如果定义一个扩展向已有类型添加新功能,那么这个心功能对该类型的所有已有实例中都是可用的,即使他们是在换个扩展的前面定义的

*/



//扩展语法

/**

声明一个扩展使用关键字extension

extension SomeType {

    // 加到SomeType的新功能写到这

}

一个扩展可以扩展一个已有类型,使其能够适配一个或多个协议。当这种情况发生时,接口的名字应该完全按照类或结构体的名字的方式进行书写

extension SomeType: SomeProtocol, AnotherProctocol { 

    // 协议实现写到这

}

按照这种方式添加的协议遵循者被称之为在扩中添加协议遵循者

*/




//计算型属性

/**

扩展可以向已有类型添加计算型实例属性和计算型类型属性

*/

extension Double {

    var km: Double{

        return self * 1000.0;

    }

    var m: Double {

        return self;

    }

    var cm: Double {

        return self / 100.0;

    }

    var mm: Double {

        return self / 1000.0;

    }

    var ft: Double {

        return self / 3.28084;

    }

}

let oneInch = 25.4.mm;

print("One inch is \(oneInch) meters");

let threeFeet = 3.ft;

print("Three feet is \(threeFeet) meters");

let aMarathon = 42.km + 195.m;

print("a marathon is \(aMarathon) meters long");

/**

扩展可以添加新的计算属性,但是不可以添加存储属性,也不可以向已有属性添加属性观测器

*/


//构造器

/**

扩展可以向已有类型添加新的构造器。这可以让你扩展其它类型,将自己的定制类型作为构造器参数,或者提供该类型的原始实现中没有包含的额外初始化选项

如果使用扩展向一个值类型添加一个构造器,该构造器向所有的存储属性提供默认值,而且没有定义任何定制构造器,那么对于来自你的扩展构造器中的值类型,你可以调用默认构造器的成员级构造器,正如在值类型的构造器授权中描述的,如果你已经把构造器写成值类型原始实现的一部分,上述规则不再使用

*/

struct Size {

    var width = 0.0, height = 0.0;

}

struct Point {

    var x = 0.0, y = 0.0;

}

struct Rect {

    var origin = Point();

    var size = Size();

}

let defaultRect = Rect();

//let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0), size: Size(width: 5.0, height: 5.0));

extension Rect {

    

    init(center: Point, size: Size) {

        let originX = center.x - size.width / 2;

        let originY = center.y - size.height / 2;

        self.init(origin: Point(x: originX, y: originY), size: size);

    }

}

let centerRect = Rect(center: Point(x: 4.0, y: 4.0), size: Size(width: 3.0, height: 3.0));

print("X:\(centerRect.origin.x),Y:\(centerRect.origin.y)\nwidth:\(centerRect.size.width),height:\(centerRect.size.height)");

/**

如果你使用扩展提供了一个新的构造器,你依旧有责任保证构造过程能够让所有实例完全初始化

*/



//方法

/**

扩展可以向已有类型添加新的实例方法和类型方法

*/

extension Int {

    func repetitons(task: () -> ()) {//表明函数没有参数而且没有返回值

    for _ in 0..<self {

        task();

    }

    }

}


3.repetitons({

        print("hello~");

        });


4.repetitons({

            print("world!");

            });


//修改实例方法

/**

通过扩展添加实例方法也可以修改该实例本身。结构体和枚举类型中修改self或其属性的方法必须将该实例方法标注为mutating,正如来自原始实现的修改方法一样

*/

extension Int {

    mutating func square() -> Int {

    return self * self;

    }

}

var someInt = 3;

print(someInt.square());



//下标

/**

扩展可以向一个已有类型添加新下标

逆向下标

*/

extension Int {

    subscript(digitIndex: Int) -> Int {

    var decimalBase = 1;

    if digitIndex == 0 {

    return self % 10;

    }

    for _ in 1...digitIndex {

    decimalBase *= 10;

    }

    if self / decimalBase < 1 {

        return 0;

    }

    return (self / decimalBase) % 10;

    }

}

print(73456875885[6]);



//嵌套类型

/**

扩展可以向已有的类、结构体和枚举添加新的嵌套类型

*/

extension Character {

    enum Kind {

    case Vowel, Consonant, Other;

    }

    var kind: Kind {

        switch String(self).lowercaseString {

        case "a","e","i","o","u":

            return .Vowel;

        case "b","c","d","f","g","h","j","k","l","m","n","p","q":

            return .Consonant;

    default:

            return .Other;

        }

    }

}


func printLetterKinds(word: String) {

    print("\'\(word)' is made up of the following kinds of letters:");

    for character in word.characters {

    switch character.kind {

        case .Vowel:

                print("vowel");

        case .Consonant:

                print("Consonant");

        case .Other:

                print("other");

        }

    }

}


printLetterKinds("Hello");


2016-05-14 01:12:29 lovexieyuan520 阅读数 719
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    5909 人正在学习 去看看 李文瀚

扩展(Extensions)在Java中是没有的,这个是Swift中特有的,oc中应该也有吧,但是extends关键字是作为Java中的继承关系连接子类和父类的。
扩展 就是为一个已有的类、结构体、枚举类型或者协议类型添加新功能。这包括在没有权限获取原始源代码的情况下扩展类型的能力(即 逆向建模 )。在Java中有个功能叫反射,也能够做Swift扩展的功能,而且非常强大,Swift的扩展有很大的局限性,一定程度上在没有获得源代码的情况下扩展了类型的功能,但是局限性。下面两个要注意:

  • 比如扩展可以为一个类型添加新的功能,但是不能重写已有的功能
  • 如果你使用扩展为一个值类型添加构造器,且该值类型的原始实现中未定义任何定制的构造器时,你可以在扩展中的构造器里调用逐一成员构造器。如果该值类型为所有存储型属性提供了默认值,你还可以在扩展中的构造器里调用默认构造器。
    如果你把定制的构造器写在值类型的原始实现中,上述规则将不再适用。

扩展语法(Extension Syntax)

使用关键字 extension 来声明扩展:

extension SomeType {
    // 为 SomeType 添加的新功能写到这里
}

可以通过扩展来扩展一个已有类型,使其采纳一个或多个协议。在这种情况下,无论是类还是结构体,协议名字的书写方式完全一样:

extension SomeType: SomeProtocol, AnotherProctocol {
    // 协议实现写到这里
}

计算型属性(Computed Properties)

扩展可以为已有类型添加计算型实例属性和计算型类型属性。下面的例子为 Swift 的内建 Double 类型添加了五个计算型实例属性,从而提供与距离单位协作的基本支持:

extension Double {
    var km: Double { return self * 1_000.0 }
    var m : Double { return self }
    var cm: Double { return self / 100.0 }
    var mm: Double { return self / 1_000.0 }
    var ft: Double { return self / 3.28084 }
}
let oneInch = 25.4.mm
print("One inch is \(oneInch) meters")
let threeFeet = 3.ft
print("Three feet is \(threeFeet) meters")

构造器(Initializers)

扩展可以为已有类型添加新的构造器。这可以让你扩展其它类型,将你自己的定制类型作为其构造器参数,或者提供该类型的原始实现中未提供的额外初始化选项。

扩展能为类添加新的便利构造器,但是它们不能为类添加新的指定构造器或析构器。指定构造器和析构器必须总是由原始的类实现来提供。

struct Size {
    var width = 0.0, height = 0.0
}
struct Point {
    var x = 0.0, y = 0.0
}
struct Rect {
    var origin = Point()
    var size = Size()
}
extension Rect {
    init(center: Point, size: Size) {
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 2)
        self.init(origin: Point(x: originX, y: originY), size: size)
    }
}

方法(Methods)

扩展可以为已有类型添加新的实例方法和类型方法。

extension Int {
    func repetitions(task: () -> Void) {
        for _ in 0..<self {
            task()
        }
    }
}
3.repetitions({
    print("Hello!")
})

可变实例方法(Mutating Instance Methods)

通过扩展添加的实例方法也可以修改该实例本身。结构体和枚举类型中修改 self 或其属性的方法必须将该实例方法标注为 mutating,正如来自原始实现的可变方法一样。

extension Int {
    mutating func square() {
        self = self * self
    }
}
var someInt = 3
someInt.square()

下标(Subscripts)

扩展可以为已有类型添加新下标。

extension Int {
    subscript(var digitIndex: Int) -> Int {
        var decimalBase = 1
        while digitIndex > 0 {
            decimalBase *= 10
            --digitIndex
        }
        return (self / decimalBase) % 10
    }
}
746381295[0]
// 返回 5
746381295[1]
// 返回 9
746381295[2]
// 返回 2
746381295[8]
// 返回 7

嵌套类型(Nested Types)

扩展可以为已有的类、结构体和枚举添加新的嵌套类型:

extension Int {
    enum Kind {
        case Negative, Zero, Positive
    }
    var kind: Kind {
        switch self {
        case 0:
            return .Zero
        case let x where x > 0:
            return .Positive
        default:
            return .Negative
        }
    }
}
func printIntegerKinds(numbers: [Int]) {
    for number in numbers {
        switch number.kind {
        case .Negative:
            print("- ", terminator: "")
        case .Zero:
            print("0 ", terminator: "")
        case .Positive:
            print("+ ", terminator: "")
        }
    }
    print("")
}
printIntegerKinds([3, 19, -27, 0, -6, 0, 7])
2019-01-06 22:07:41 Jozione 阅读数 96
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    5909 人正在学习 去看看 李文瀚

方法一:变量传值

特点:模块耦合较高,不建议采用,但需要知道。

demo界面图示
分别在A界面和B界面定义对方的属性控制器对象
第一步:

class bViewController: UIViewController {
     //省略部分代码
       var aVC:aViewController?
    //省略部分代码
}

override func viewDidLoad() {
        //省略部分代码
        // 看看 contactTableVC 传递成功没有
        print(self.aVC as Any)
}

第二步:
创建一个需要在两个view controller中专递值的封装类模型item

class contactItem: NSObject {
    var name:String?
    var phone:String?    
}

第三步:
storyboard中b view中添加一个按钮,连线到bViewController内部生成IBAction方法

class bViewController: UIViewController {
     //省略部分代码
   @IBAction func bBtnClick(_ sender: Any) {
        var item = contactItem.init()
        item.name = nameTextF.text
        item.phone = phoneTextF.text
        self.aVC?.cItem = item
        //回传值
        self.navigationController?.popViewController(animated: true)
    }

}

第四步:

class aViewController: UIViewController {
      //拿着item模型
     var cItem:contactItem?
     //a中拿着b属性类
     var bVC:bViewController?

    //...省略部分代码

    // 把自己aViewController传到bViewController的aVC属性
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // A <-- B
        let destBVC = segue.destination as! bViewController
        // B <-- A
        destBVC.aVC = self
    }
}

方法二:代理模式

高内聚,低耦合

第一步:B界面中声明协议

protocol addContactVCDelegate:NSObjectProtocol {
    func addContactVC(addContactVC:addContactViewController,cItem:contactItem)
}

第二步:B界面VC中声明代理

class bViewController: UIViewController {

    // 第二步:声明代理,弱引用weak修饰
    weak var delegate:addContactVCDelegate?
    //省略部分代码
}
    

第三步:定义数据模型
创建一个需要在两个view controller中专递值的封装类模型item

class contactItem: NSObject {
    var name:String?
    var phone:String?    
}

第四步:逆传值,bVC中编码(B->A)

class bViewController: UIViewController {
	//...省略部分代码
	
    // 通过按钮’添加‘的action传值(姓名和电话)从B界面到上一个A界面控制器
    @IBAction func addContactAction(_ sender: Any) {
        var item = contactItem.init()
        item.name = nameTextF.text
        item.phone = phoneTextF.text
        
        //核心代码,根据实际情况是否判断nil
//        if self.delegate != nil  {
            self.delegate?.addContactVC(addContactVC: self, cItem: item)
//        }
        
        self.navigationController?.popViewController(animated: true)
    }
    
    //...省略部分代码
}

第五步:A界面中,定义回调B界面返回

  1. aVC遵守B中定义的协议addContactVCDelegate
  2. 实现代理方法func addContactVC
  3. 代理回调destAddVC.delegate = self
// 1.class遵守协议
class aViewController: UITableViewController,addContactVCDelegate {

	//2.接收值方法(代理回调方法)
    func addContactVC(addContactVC: addContactViewController, cItem: contactItem) {
        print("这是aVC内的实现协议方法,你要实现回调的功能在这里编写")
        print(cItem.name!)
    }
    
    //...省略部分代码

	//3.segue代理回调
	//把自己aViewController传到bViewController的delegate属性
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let destAddVC = segue.destination as! bViewController
        destAddVC.delegate = self
    }
}

逆向~

阅读数 6

Android 逆向实战

阅读数 485

Android逆向

博文 来自: Rozol

mybatis逆向工程

阅读数 739

没有更多推荐了,返回首页