NSString内容擦除相关

测试结论

  1. 常量字符串在正式赋值之前就存在,会保留到整个程序运行期间,无法清除。
  2. 在调用函数结束的时候NSString字符串才会自动清空,之前都能在内存中搜到。
  3. 非常量字符串可以通过念茜的CFStringGetCStringPtr的方式清空。(念茜方法详情
    只想了解怎么清除NSString的朋友看到这里就够了,下面是以上结论的测试过程。

引子

最近手头的iOS项目对安全性要求非常高。
某个敏感数据使用NSString存储,非常敏感,必须即用即清理。NSString对象会通过ARC自动释放,而并没有显式的清除方法,所以并不能确定自动释放之后内容是否自动清除。
找到念茜博主提供的NSString字符串清除。
为了验证方法有效性,我直接使用念茜的代码试验

_text = @"12dfavkasie";  
memset((__bridge voidvoid *)(_text), 0, _text.length - 1);  
NSString *myString = [[NSString alloc]initWithFormat:@"information"];  
NSLog(@"Origal text : %@ \n",myString);  //断点1

“Origal text :”没有显示字符串内容,但是在断点1进行内存扫描依然能搜到一个12dfavkasie。所以为了验证该方法有效性,需要解决如下几个问题。

  1. 断点1搜到的字符串是常量字符串还是NSString没擦除的结果。
  2. NSString是否在最后一次调用的时候自动擦除。
  3. 使用非常量字符串来排除常量字符串干扰,使用这种方法依然能够清除就能证明该方法可以有效清除NSString。

首先建立可以进行内存扫描的iOS环境。

iOS扫描内存过程

  1. 使用盘古越狱将手头iPhone 4s iOS 7.1.2 越狱。
  2. 在Cydia上下载OpenSSH。
  3. 在Cydia上添加源:http://grantdouglas.co.uk 下载 memscan。
  4. 在MAC上使用SSH连接OpenSSH。
    ssh root@192.168.2.199
    iPhone手机默认密码为 :alpine
    RA手机,修改为:Rongan1234
  5. 运行iOS中间件工具。
  6. 用工具名字, 获取iOS工具PID如下:
    ps-ax | grep SignTool
    ps-ax | grep Mgr
  7. 获取的PID对应进程的内存。
    memscan -p 64685 -d -o out4.bin
  8. 搜索获取内存中的数据
    grep -c 12345677 out4.bin
    得到数据为0,则内存中找不到该字符串。
    得到数据不为0,使用grep -a查看该字符串出现的具体位置。

测试过程

编写用于测试的程序验证如下三个问题:

  1. 断点1搜到的字符串是常量字符串还是NSString没擦除的结果。
    通过程序1确定常量字符串的特性。
  2. NSString是否在最后一次调用的时候自动擦除。
    建立两个NSString,确定两个字符串清除的时间。
  3. 使用非常量字符串来排除常量字符串干扰,使用这种方法依然能够清除就能证明该方法可以有效清除NSString。

常量字符串是否一直存在?

    NSString *testStr = [[NSString alloc] initWithFormat:@"14642334"];
    NSString *testStr1 = [[NSString alloc] initWithFormat:@"sdfsafd"];
    NSString *testStr2 = [[NSString alloc] initWithFormat:@"dsfdsafd"];
    NSString *testStr3 = [[NSString alloc] initWithFormat:@"dncmviwmaf"];
    
    NSLog(@"test1");
    NSLog(@"test2");
    NSLog(@"test1");
    NSLog(@"test2");
    [testStr compare:testStr1];
    [testStr compare:testStr2];
    [testStr compare:testStr3];

在该段代码运行之前,用memscan获取内存,用grep -C 10 14642334 获取该字符串附近的上下文,结果如下。

lengthOfBytesUsingEncoding:
getCString:maxLength:encoding:
keyEnumerator
nextObject
test
14642334
sdfsafd
dsfdsafd
dncmviwmaf
test1
test2

当该函数运行结束之后,查找14642334,结果一样。

结论

常量字符串特点如下:

  1. 集中存储在一个位置。
  2. 无论代码有没有运行到常量字符串所在位置,内存中都会包含这个字符串的内容。
    所以之前念茜代码最后搜到的测试字符串应该是常量字符串。

NSString是否自动清除

测试代码:

    unsigned char testByteStr[10];//断点0
    testByteStr[0] = '1';//14642334
    testByteStr[1] = '4';
    testByteStr[2] = '6';
    testByteStr[3] = '4';
    testByteStr[4] = '2';
    testByteStr[5] = '3';
    testByteStr[6] = '3';
    testByteStr[7] = '4';
    NSString *testStr = [[NSString alloc] initWithBytes:testByteStr length:8 encoding:NSASCIIStringEncoding];
    testByteStr[0] = '4';//47951438
    testByteStr[1] = '7';
    testByteStr[2] = '9';
    testByteStr[3] = '5';
    testByteStr[4] = '1';
    testByteStr[5] = '4';
    testByteStr[6] = '3';
    testByteStr[7] = '8';
    NSString *testStr2 =[[NSString alloc] initWithBytes:testByteStr length:8 encoding:NSASCIIStringEncoding];
    memset(testByteStr, 0, 8);
    NSLog(@"test");//断点1
    [testStr compare:testStr2];
    NSLog(@"test");//断点2
    NSLog(@"%l",testStr.length);
    NSLog(@"test");//断点3
    testStr = @"123";
    NSLog(@"test");//断点4

结果和分析:
断点0时,14642334出现0次,47951438出现0次。
断点1时,14642334出现1次,47951438出现1次。
testByteStr已经用memset清空,所以内存中唯一的14642334是testStr。唯一的47951438是testStr2。
断点2时,14642334出现1次,47951438出现1次。
之后testStr2最后一次调用在断点2前,然而testStr2依然能搜到。所以NSString并没有在最后一次调用时自我清除。
断点3时,14642334出现1次,47951438出现1次。
断点4时,14642334出现1次,47951438出现1次。
断点5为该函数执行结束之后的断点,14642334出现0次,47951438出现0次。

结论

NSString只会在所在函数段结束的时候自动清空。

排除常量字符串干扰,擦除字符串

    unsigned char testByteStr[10];//断点0
    testByteStr[0] = '1';//14642334
    testByteStr[1] = '4';
    testByteStr[2] = '6';
    testByteStr[3] = '4';
    testByteStr[4] = '2';
    testByteStr[5] = '3';
    testByteStr[6] = '3';
    testByteStr[7] = '4';
    NSString *testStr = [[NSString alloc] initWithBytes:testByteStr length:8 encoding:NSASCIIStringEncoding];
    memset(testByteStr , 0 , 8);
    char *str = malloc(9*sizeof(char));//断点1
    str = (char *)CFStringGetCStringPtr((CFStringRef)testStr,CFStringGetSystemEncoding());
    NSLog(@"test");//断点2
    memset(str , 0 , 7);
    NSLog(@"test");//断点3

在Xcode里运行测试程序,在程序运行到断点0,1,2,3的时候使用memscan扫描14642334的数量。
断点0结果:0
断点1结果:1
testByteStr已经清空。内存中唯一14642334是testStr。
断点2结果:1
执行CFStringGetCStringPtr之后,内存中依然只有一个14642334。而之前已经试验过testStr字符串在函数结束之后才会清空,所以str指向testStr存储14642334的内存位置。
断点3结果:0
清空str之后,testStr也清空了。

结论

念茜的方法可以有效清空NSString。

测试结论

  1. 常量字符串在正式赋值之前就存在,会保留到整个程序运行期间,无法清除。
  2. 在调用函数结束的时候NSString字符串才会自动清空,之前都能在内存中搜到。
  3. 非常量字符串可以通过CFStringGetCStringPtr的方式清空。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,183评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,850评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,766评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,854评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,871评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,457评论 1 311
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,999评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,914评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,465评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,543评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,675评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,354评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,029评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,514评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,616评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,091评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,685评论 2 360

推荐阅读更多精彩内容

  • 1、截取字符串”20 | http://www.baidu.com”中,”|”字符前面和后面的数据,分别输出它们 ...
    强子ly阅读 2,961评论 8 46
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young阅读 3,819评论 1 10
  • 喜欢故事,喜欢写故事,更喜欢写故事的人。 每一次听别人讲的故事,总是遗憾自己文笔不够,没有办法描述出别人的那种心情...
    木子不爱糖阅读 285评论 0 1
  • 我心不与仙道同, 顶天立地文骨在。 独行其道厌神过, 引领真谛向人浊。 自古大路皆为魔, 何处来得幸福和? 文坛独...
    火过留痕阅读 331评论 0 6