So Tired !_! 逆水行舟, 不进则退!

17Jul/14

SysBench系统性能基准测试工具

Posted by Nick Xu

1 CPU测试
sysbench采用寻找最大素数的方式来测试CPU的性能

[root@xx sysbench-0.4.12]# sysbench --test=cpu --cpu-max-prime=2000 run

sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Doing CPU performance benchmark

Threads started!
WARNING: Operation time (0.000000) is less than minimal counted value, counting as 1.000000
WARNING: Percentile statistics will be inaccurate
Done.

Maximum prime number checked in CPU test: 2000

Test execution summary:
total time:                          1.5034s
total number of events:              10000
total time taken by event execution: 1.4998
per-request statistics:
min:                                  0.00ms
avg:                                  0.15ms
max:                                  0.57ms
approx.  95 percentile:               0.31ms

Threads fairness:
events (avg/stddev):           10000.0000/0.00
execution time (avg/stddev):   1.4998/0.00

2 线程测试
sysbench --test=threads --num-threads=64 --thread-yields=100 --thread-locks=2 run

[root@xx sysbench-0.4.12]# sysbench --test=threads --num-threads=64 --thread-yields=100 --thread-locks=2 run
sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 64

Doing thread subsystem performance test
Thread yields per test: 100 Locks used: 2
Threads started!
WARNING: Operation time (0.000000) is less than minimal counted value, counting as 1.000000
WARNING: Percentile statistics will be inaccurate
Done.
Test execution summary:
total time:                          2.0189s
total number of events:              10000
total time taken by event execution: 128.2852
per-request statistics:
min:                                  0.00ms
avg:                                 12.83ms
max:                                108.17ms
approx.  95 percentile:              42.09ms

Threads fairness:
events (avg/stddev):           156.2500/12.16
execution time (avg/stddev):   2.0045/0.00

 

3 文件IO性能测试
首先生成需要的测试文件,文件总大小1000M,16个并发线程,随机读写模式。执行完后会在当前目录下生成一堆小文件。
3.1 准备测试文件:sysbench --test=fileio --num-threads=16 --file-total-size=1000M --file-test-mode=rndrw prepare
[root@xx sysbench-0.4.12]# sysbench --test=fileio --num-threads=16 --file-total-size=1000M --file-test-mode=rndrw prepare
sysbench 0.4.12:  multi-threaded system evaluation benchmark

128 files, 8000Kb each, 1000Mb total
Creating files for the test...
3.2 执行测试
sysbench --test=fileio --num-threads=16 --file-total-size=1000M --file-test-mode=rndrw run

[root@xx sysbench-0.4.12]# sysbench --test=fileio --num-threads=16 --file-total-size=1000M --file-test-mode=rndrw run
sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 16

Extra file open flags: 0
128 files, 7.8125Mb each
1000Mb total file size
Block size 16Kb
Number of random requests for random IO: 10000
Read/Write ratio for combined random IO test: 1.50
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing random r/w test
Threads started!
WARNING: Operation time (0.000000) is less than minimal counted value, counting as 1.000000
WARNING: Percentile statistics will be inaccurate
Done.

Operations performed:  6007 Read, 4005 Write, 12675 Other = 22687 Total
Read 93.859Mb  Written 62.578Mb  Total transferred 156.44Mb  (214.4Mb/sec)  看到这里发现write很高,我这里是SSD,普通机械磁盘可能就没有这么高了。
13721.48 Requests/sec executed

Test execution summary:
total time:                          0.7297s
total number of events:              10012
total time taken by event execution: 1.3667
per-request statistics:
min:                                  0.00ms
avg:                                  0.14ms
max:                                 20.50ms
approx.  95 percentile:               0.41ms

Threads fairness:
events (avg/stddev):           625.7500/159.20
execution time (avg/stddev):   0.0854/0.02

3.3 清理测试生成的临时文件
sysbench --test=fileio --num-threads=16 --file-total-size=1000M --file-test-mode=rndrw cleanup
sysbench 0.4.12:  multi-threaded system evaluation benchmark

Removing test files...
 4. mutex测试
sysbench --test=mutex --num-threads=16 \--mutex-num=1024 --mutex-locks=10000 --mutex-loops=5000 run
[root@xx sysbench-0.4.12]# sysbench --test=mutex --num-threads=16 \--mutex-num=1024 --mutex-locks=10000 --mutex-loops=5000 run
sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 16

Doing mutex performance test
Threads started!
Done.
Test execution summary:
total time:                          0.1167s
total number of events:              16
total time taken by event execution: 1.7472
per-request statistics:
min:                                 96.94ms
avg:                                109.20ms
max:                                114.26ms
approx.  95 percentile:             114.19ms

Threads fairness:
events (avg/stddev):           1.0000/0.00
execution time (avg/stddev):   0.1092/0.01

 

 5,内存测试
 sysbench --test=memory --num-threads=512 --memory-block-size=262144 --memory-total-size=32G run
[root@xx sysbench-0.4.12]#  sysbench --test=memory --num-threads=512 --memory-block-size=262144 --memory-total-size=32G run
sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 512

Doing memory operations speed test
Memory block size: 256K

Memory transfer size: 32768M

Memory operations type: write
Memory scope type: global
Threads started!
WARNING: Operation time (0.000000) is less than minimal counted value, counting as 1.000000
(last message repeated 1 times)
WARNING: Percentile statistics will be inaccurate
(last message repeated 1 times)
Done.

Operations performed: 131072 (60730.95 ops/sec)

32768.00 MB transferred (15182.74 MB/sec)
Test execution summary:
total time:                          2.1582s
total number of events:              131072
total time taken by event execution: 643.2354
per-request statistics:
min:                                  0.00ms
avg:                                  4.91ms
max:                               1173.07ms
approx.  95 percentile:               0.42ms

Threads fairness:
events (avg/stddev):           256.0000/84.51
execution time (avg/stddev):   1.2563/0.32

 

6 MySQL数据库测试 select
首先需要创建默认的test数据库,或者使用–mysql-db指定一个已经存在的数据库生成测试数据,引擎为innodb,表大小为30000000条记录
6.1 准备数据
--oltp-test-mode
=STRING         test type to use {simple,complex,nontrx,sp} [complex]
--oltp-nontrx-mode=STRING       mode for non-transactional test {select, update_key, update_nokey, insert, delete} [select]
time sysbench --test=oltp --mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --mysql-db=test  --oltp-table-size=300000000 --oltp-table-name=t1 --oltp-nontrx-mode=insert --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock prepare

报错如下:

FATAL: no database driver specified
FATAL: failed to initialize database driver!

test库没有建立,去create database
mysql> create database test;
Query OK, 1 row affected (0.01 sec)

sysbench 0.4.12:  multi-threaded system evaluation benchmark

Creating table 't1'...
Creating 30000000 records in table 't1'...

real    13m49.102s
user    0m11.982s
sys     0m0.646s
6.2 执行测试
time sysbench --test=oltp --mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --mysql-db=test  --oltp-table-size=300000000 --oltp-table-name=t1  --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock run
Running the test with following options:
Number of threads: 1

Doing OLTP test.
Running mixed OLTP test
Using Special distribution (12 iterations,  1 pct of values are returned in 75 pct cases)
Using "BEGIN" for starting transactions
Using auto_inc on the id column
Maximum number of requests for OLTP test is limited to 10000
Threads started!
Done.

OLTP test statistics:
queries performed:
read:                            140000
write:                           50000
other:                           20000
total:                           210000
transactions:                        10000  (350.28 per sec.)
deadlocks:                           0      (0.00 per sec.)
read/write requests:                 190000 (6655.38 per sec.)
other operations:                    20000  (700.57 per sec.)

Test execution summary:
total time:                          28.5483s
total number of events:              10000
total time taken by event execution: 28.4897
per-request statistics:
min:                                  1.80ms
avg:                                  2.85ms
max:                                 47.35ms
approx.  95 percentile:               5.95ms

Threads fairness:
events (avg/stddev):           10000.0000/0.00
execution time (avg/stddev):   28.4897/0.00
real    0m28.646s
user    0m2.270s
sys     0m1.516s
6.3 clean test data
time sysbench --test=oltp --mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --mysql-db=test  --oltp-table-size=30000000 --oltp-table-name=t1   --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock clearup

 

7 MySQL数据库测试 insert 19304W

7.1 执行insert测试,数据准备参考6.1步骤
--oltp-nontrx-mode=insert
time sysbench --test=oltp --mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --oltp-nontrx-mode=insert --mysql-db=test  --oltp-table-size=193040000 --oltp-table-name=t1  --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock run

[root@xx bin]# time sysbench --test=oltp --mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --oltp-nontrx-mode=insert --mysql-db=test  --oltp-table-size=193040000 --oltp-table-name=t1  --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock run
sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Doing OLTP test.
Running mixed OLTP test
Using Special distribution (12 iterations,  1 pct of values are returned in 75 pct cases)
Using "BEGIN" for starting transactions
Using auto_inc on the id column
Maximum number of requests for OLTP test is limited to 10000
Threads started!
Done.

OLTP test statistics:
queries performed:
read:                            140000
write:                           50000
other:                           20000
total:                           210000
transactions:                        10000  (222.06 per sec.)
deadlocks:                           0      (0.00 per sec.)
 read/write requests:                 190000 (4219.22 per sec.)
    other operations:                    20000  (444.13 per sec.)

Test execution summary:
total time:                          45.0321s
total number of events:              10000
total time taken by event execution: 44.9398
per-request statistics:
min:                                  1.96ms
avg:                                  4.49ms
max:                                 37.26ms
approx.  95 percentile:               6.96ms

Threads fairness:
events (avg/stddev):           10000.0000/0.00
execution time (avg/stddev):   44.9398/0.00
real    0m45.063s
user    0m3.279s
sys     0m2.295s

 

7.2 --oltp-nontrx-mode=update_key 修改测试 带index
time sysbench --test=oltp --mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --oltp-nontrx-mode=update_key --mysql-db=test  --oltp-table-size=193040000 --oltp-table-name=t1  --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock run
[root@xx bin]# time sysbench --test=oltp --mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --oltp-nontrx-mode=update_key --mysql-db=test  --oltp-table-size=193040000 --oltp-table-name=t1  --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock run
sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Doing OLTP test.
Running mixed OLTP test
Using Special distribution (12 iterations,  1 pct of values are returned in 75 pct cases)
Using "BEGIN" for starting transactions
Using auto_inc on the id column
Maximum number of requests for OLTP test is limited to 10000
Threads started!
Done.

OLTP test statistics:
queries performed:
read:                            140000
write:                           50000
other:                           20000
total:                           210000
transactions:                        10000  (304.16 per sec.)
deadlocks:                           0      (0.00 per sec.)
read/write requests:                 190000 (5778.95 per sec.)
other operations:                    20000  (608.31 per sec.)

Test execution summary:
total time:                          32.8780s
total number of events:              10000
total time taken by event execution: 32.8053
per-request statistics:
min:                                  1.89ms
avg:                                  3.28ms
max:                                 28.03ms
approx.  95 percentile:               6.06ms

Threads fairness:
events (avg/stddev):           10000.0000/0.00
execution time (avg/stddev):   32.8053/0.00
real    0m32.909s
user    0m2.628s
sys     0m1.683s

 

7.3 --oltp-nontrx-mode=delete 删除测试
time sysbench --test=oltp --mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --oltp-nontrx-mode=delete --mysql-db=test  --oltp-table-size=193040000 --oltp-table-name=t1  --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock run
[root@xx bin]# time sysbench --test=oltp --mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --oltp-nontrx-mode=delete --mysql-db=test  --oltp-table-size=193040000 --oltp-table-name=t1  --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock run
sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Doing OLTP test.
Running mixed OLTP test
Using Special distribution (12 iterations,  1 pct of values are returned in 75 pct cases)
Using "BEGIN" for starting transactions
Using auto_inc on the id column
Maximum number of requests for OLTP test is limited to 10000
Threads started!
Done.

OLTP test statistics:
queries performed:
read:                            140000
write:                           50000
other:                           20000
total:                           210000
transactions:                        10000  (330.13 per sec.)
deadlocks:                           0      (0.00 per sec.)
read/write requests:                 190000 (6272.53 per sec.)
other operations:                    20000  (660.27 per sec.)

Test execution summary:
total time:                          30.2908s
total number of events:              10000
total time taken by event execution: 30.2212
per-request statistics:
min:                                  1.84ms
avg:                                  3.02ms
max:                                 13.14ms
approx.  95 percentile:               6.02ms

Threads fairness:
events (avg/stddev):           10000.0000/0.00
execution time (avg/stddev):   30.2212/0.00
real    0m30.328s
user    0m2.416s
sys     0m1.658s
7.4 --oltp-nontrx-mode=update_nokey 修改测试 No Index
--oltp-nontrx-mode=STRING       mode for non-transactional test {select, update_key, update_nokey, insert, delete} [select]
time sysbench --test=oltp --mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --oltp-nontrx-mode=update_nokey --mysql-db=test  --oltp-table-size=193040000 --max-requests --oltp-table-name=t1  --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock run 

[root@xx bin]# time sysbench --test=oltp --mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --oltp-nontrx-mode=update_nokey --mysql-db=test  --oltp-table-size=193040000 --oltp-table-name=t1  --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock run
sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Doing OLTP test.
Running mixed OLTP test
Using Special distribution (12 iterations,  1 pct of values are returned in 75 pct cases)
Using "BEGIN" for starting transactions
Using auto_inc on the id column
Maximum number of requests for OLTP test is limited to 10000
Threads started!
Done.

OLTP test statistics:
queries performed:
read:                            140000
write:                           50000
other:                           20000
total:                           210000
transactions:                        10000  (319.11 per sec.)
deadlocks:                           0      (0.00 per sec.)
read/write requests:                 190000 (6063.01 per sec.)
other operations:                    20000  (638.21 per sec.)

Test execution summary:
total time:                          31.3376s
total number of events:              10000
total time taken by event execution: 31.2650
per-request statistics:
min:                                  1.83ms
avg:                                  3.13ms
max:                                 13.44ms
approx.  95 percentile:               6.11ms

Threads fairness:
events (avg/stddev):           10000.0000/0.00
execution time (avg/stddev):   31.2650/0.00
real    0m31.367s
user    0m2.422s
sys     0m1.680s

7.4 总结
--oltp-nontrx-mode=STRING       mode for non-transactional test {select, update_key, update_nokey, insert, delete} [select]
--max-requests=N           limit for total number of requests [10000]
如果这里不指定--max-requests,默认为10000,就是执行1W次操作就结束了,如果要做压力测试的话,就需要手动设置此值。
--num-threads=N            number of threads to use [1] (clients to access mysql db)
这里指的是有多少个mysql clents来访问mysql服务器,用show full processlist就可以看到大概的记录数。

7.5 接下来重新压力测试,设置2000W request测试。

录入测试数据 2000W
time sysbench --test=oltp --oltp-test-mode=nontrx --mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --num-threads=500 --max-requests=20000000  --oltp-nontrx-mode=insert --mysql-db=test  --oltp-table-size=20000000 --oltp-table-name=t1  --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock prepare
Creating table 't1'...
Creating 20000000 records in table 't1'...

real    8m46.287s
user    0m8.048s
sys     0m0.428s

 

7.6开始测试 纯粹写
nohup time sysbench --test=oltp --oltp-test-mode=nontrx --mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --num-threads=500 --max-requests=20000000  --oltp-nontrx-mode=insert --mysql-db=test  --oltp-table-size=20000000 --oltp-table-name=t1  --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock run >3.log &
time sysbench --test=oltp --oltp-test-mode=nontrx --mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --num-threads=500 --max-requests=20000000  --oltp-nontrx-mode=insert --mysql-db=test  --oltp-table-size=20000000 --oltp-table-name=t1  --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock run  1> 2.log

OLTP test statistics:
queries performed:
read:                            0
write:                           20007732
other:                           0
total:                           20007732
transactions:                        20007732 (8556.00 per sec.)
deadlocks:                           0      (0.00 per sec.)
read/write requests:                 20007732 (8556.00 per sec.)
other operations:                    0      (0.00 per sec.)

Test execution summary:
total time:                          2338.4451s
total number of events:              20007732
total time taken by event execution: 1169095.8829
per-request statistics:
min:                                  0.35ms
avg:                                 58.43ms
max:                                317.35ms
approx.  95 percentile:              83.54ms

Threads fairness:
events (avg/stddev):           40015.4640/13.47
execution time (avg/stddev):   2338.1918/0.02

900.69user 667.19system 39:07.55elapsed 66%CPU (0avgtext+0avgdata 128176maxresident)k
0inputs+16outputs (0major+8251minor)pagefaults 0swaps
7.7 混合读写测试
nohup time sysbench --test=oltp --oltp-test-mode=complex --mysql-table-engine=innodb --mysql-user=root --db-driver=mysql --num-threads=500 --max-requests=20000000  --oltp-nontrx-mode=select --mysql-db=test  --oltp-table-size=20000000 --oltp-table-name=t1  --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock run >4.log &

sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 500

Doing OLTP test.
Running mixed OLTP test
Using Special distribution (12 iterations,  1 pct of values are returned in 75 pct cases)
Using "BEGIN" for starting transactions
Using auto_inc on the id column
Maximum number of requests for OLTP test is limited to 20000000
Threads started!
Done.

OLTP test statistics:
queries performed:
read:                            280001652
write:                           100000590
other:                           40000236
total:                           420002478
transactions:                        20000118 (1150.48 per sec.)
deadlocks:                           0      (0.00 per sec.)
read/write requests:                 380002242 (21859.10 per sec.)
other operations:                    40000236 (2300.96 per sec.)

Test execution summary:
total time:                          17384.1703s
total number of events:              20000118
total time taken by event execution: 8691857.1553
per-request statistics:
min:                                 28.97ms
avg:                                434.59ms
max:                              14634.16ms
approx.  95 percentile:             856.09ms

Threads fairness:
events (avg/stddev):           40000.2360/119.14
execution time (avg/stddev):   17383.7143/0.06

5142.95user 4422.48system 4:49:50elapsed 55%CPU (0avgtext+0avgdata 256224maxresident)k
2440inputs+16outputs (15major+16290minor)pagefaults 0swaps

 avg:    434.59ms

看到这里,大leader说这个数值偏高了,在game领域,最好<10ms,并且他猜测我是local测试的,local500个线程也许会
   对db server有一些压力的,建议我remote测试访问测试下看

7.8.1 混合读写测试 远程读写数据准备,远程跑后台进程准备数据。
nohup time sysbench --test=oltp --oltp-test-mode=nontrx --mysql-table-engine=innodb --mysql-host=xxxx.xx --mysql-user=xxxxx--mysql-password=hRhsYzbm  --db-driver=mysql --num-threads=500 --max-requests=20000000  --oltp-nontrx-mode=select --mysql-db=test  --oltp-table-size=20000000 --oltp-table-name=t1  --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock prepare > 6.log &
sysbench 0.4.12:  multi-threaded system evaluation benchmark

Creating table 't1'...
Creating 20000000 records in table 't1'...
8.48user 1.96system 40:23.30elapsed 0%CPU (0avgtext+0avgdata 12224maxresident)k
0inputs+8outputs (0major+854minor)pagefaults 0swaps

7.8.2 混合读写测试 远程读写
nohup time sysbench --test=oltp --oltp-test-mode=complex --mysql-table-engine=innodb --mysql-host=xxxxxx.xx.com --mysql-user=chunman --mysql-password=hRhsYzbm --db-driver=mysql --mysql-db=test --oltp-table-name=t1  --num-threads=500 --max-requests=20000000  --oltp-nontrx-mode=select --oltp-table-size=20000000  --mysql-socket=/opt/mysql/product/mysql/mysql3306.sock  run >5.log &

ALERT: Error: failed to determine table 't1' type!
ALERT: MySQL error:
FATAL: failed to get database capabilities!
0.00user 0.00system 0:00.01elapsed 64%CPU (0avgtext+0avgdata 9856maxresident)k
0inputs+8outputs (0major+706minor)pagefaults 0swaps

报这个错误,是因为数据没有,7.8.1没有执行,需要重新录入测试数据。

10Jul/14

Smali注入之打造属于自己的安卓crack利器

Posted by Nick Xu

关于Smali注入大家应该了解过,网上有不少教程。那些注入代码看上去简单,实际用起来得花不少功夫。

普通的注入就是在软件源代码中添加几行代码,用于改变软件的功能,或查看某个寄存器在运行中具体的值。

需要注意的地方是:添加的注入代码所使用的寄存器不影响其他代码的执行。当注入代码较多时,这个要求就变得很困难了。

在这里我的解决办法是:把注入代码写进自己专属的crack.smali,然后在要注入的地方调用crack.smali里的注入方法即可,只用一行注入代码,而且不影响其他寄存器。

举个例子说明下两种方法的区别,假设原软件中有以下代码:

.method public methodName()Ljava/lang/String;
.locals 4
.prologue
const-string v0, "test1"

const-string v3, "test2"

invoke-static {v0}, Lpackage/name/ObjectName;——>methodName1(Ljava/lang/String;)Ljava/lang/String;

move-result-object v1

invoke-static {v1}, Lpackage/name/ObjectName;——>methodName2(Ljava/lang/String;)Ljava/lang/String;

move-result-object v2

invoke-static {v3}, Lpackage/name/ObjectName;——>methodName3(Ljava/lang/String;)V

new-instance v3, Ljava/lang/StringBuilder;

invoke-direct {v0, v3}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V

invoke-virtual {v0, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

move-result-object v0

invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

move-result-object v0

return-object v0
.end method

假如我要查看move-result-object v1和move-result-object v2,两处中v1、v2的值该如何注入?

普通的log.d注入方法如下(可以用Logcat查看日志):

.method public methodName()Ljava/lang/String;
.locals 5
.prologue
const-string v0, "test1"

const-string v3, "test2"

invoke-static {v0}, Lpackage/name/ObjectName;——>methodName1(Ljava/lang/String;)Ljava/lang/String;

move-result-object v1

const-string v4, "info"

invoke-static {v4, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

invoke-static {v1}, Lpackage/name/ObjectName;——>methodName2(Ljava/lang/String;)Ljava/lang/String;

move-result-object v2

const-string v4, "info"

invoke-static {v4, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

invoke-static {v3}, Lpackage/name/ObjectName;——>methodName3(Ljava/lang/String;)V

new-instance v3, Ljava/lang/StringBuilder;

invoke-direct {v0, v3}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V

invoke-virtual {v0, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

move-result-object v0

invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

move-result-object v0

return-object v0
.end method

在上面的代码中,我先是修改了开头的“.locals 5”,表示使用的寄存器为v0-v4。然后我用v4作为log.d的第一个参数,寄存器v1、v2为第二个参数。

由于原代码中,v0、v1、v2、v3从头到尾都有使用,所以注入时使用这几个寄存器会影响软件的正常执行,所以我才修改“.locals”开辟新的寄存器v4。

明显这样注入很麻烦。而且刚好v1、v2都是字符串,符合log.d的要求。如果v1、v2为整数值,注入就更加复杂了。

下面看看创建了crack.smali的注入会如何。

假设我已经有了个crack.smali,代码如下:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
.class public Lcrack;
.super Ljava/lang/Object;
.source "crack.java"
.method public static log(Ljava/lang/String;)V
    .locals 1
    .prologue
    const-string v0, "info"
    invoke-static {v0, p0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    return-void
.end method

把crack.smali放到反编译后的smali根目录,在源代码中注入:

.method public methodName()Ljava/lang/String;
.locals 4
.prologue
const-string v0, "test1"

const-string v3, "test2"

invoke-static {v0}, Lpackage/name/ObjectName;——>methodName1(Ljava/lang/String;)Ljava/lang/String;

move-result-object v1

invoke-static {v1}, Lcrack;->log(Ljava/lang/String;)V

invoke-static {v1}, Lpackage/name/ObjectName;——>methodName2(Ljava/lang/String;)Ljava/lang/String;

move-result-object v2

invoke-static {v2}, Lcrack;->log(Ljava/lang/String;)V

invoke-static {v3}, Lpackage/name/ObjectName;——>methodName3(Ljava/lang/String;)V

new-instance v3, Ljava/lang/StringBuilder;

invoke-direct {v0, v3}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V

invoke-virtual {v0, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

move-result-object v0

invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

move-result-object v0

return-object v0
.end method

明显比前面的注入方式简单多了。crack.smali的方法可以不断丰富,需要用时信手拈来。

既然如此,就让我们打造属于自己的安卓crack利器吧!

最基本的crack.smali推荐加入log日志输出,代码如下:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
.class public Lcrack;
.super Ljava/lang/Object;
.source "crack.java"
.method public static log(Ljava/lang/String;)V
    .locals 1
    .prologue
    const-string v0, "info"
    invoke-static {v0, p0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    return-void
.end method

把crack.smali放进smali目录,在要查看的,保存了字符串的寄存器vx的下面,添加代码:

[Java] 纯文本查看 复制代码
1
invoke-static {vx}, Lcrack;->log(Ljava/lang/String;)V

保存并重新编译,在手机或模拟器上安装软件,连上电脑,打开cmd命令行:

<ignore_js_op>

cd到桌面,然后输入命令adb logcat>test.txt,然后在手机上运行软件,当软件执行了注入的代码(自行判断),按ctrl+c结束,然后回到桌面。

如无法识别adb命令,请先添加adb.exe所在位置的环境变量,如我安装了靠谱助手,我找到了它提供的adb.exe所在的路径,然后我照下面图设置:

<ignore_js_op>

打开test.txt,查找d/info,在找到的那一行的右边就是要查看的寄存器的值。

<ignore_js_op>

“info”是由“ const-string v0, "info" ”给出。可以自行修改。

上面的说的命令还可以添加过滤代码,有经验的人自行修改,使得test.txt的内容更简洁。

从上面test.txt的结果可以看出,如果需要注入的位置有多处,那么就很难分辨具体哪个结果对应哪个了。

解决办法是,给crack.smali的log方法加序号,并复制多份log方法,参照下面修改方式,如:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
.class public Lcrack;
.super Ljava/lang/Object;
.source "crack.java"
.method public static log1(Ljava/lang/String;)V
    .locals 1
    .prologue
    const-string v0, "info1"
    invoke-static {v0, p0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    return-void
.end method
.method public static log2(Ljava/lang/String;)V
    .locals 1
    .prologue
    const-string v0, "info2"
    invoke-static {v0, p0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    return-void
.end method

第一处注入调用log1,第二处注入调用log2,依次类推,然后根据序号对应结果。

上面说的注入,前提都是vx是String,如果vx是int型怎么办?

可以给crack.smali添加下面方法:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
.method public static I(I)V
    .locals 2
    .prologue
    const-string v0, "info_int"
    invoke-static {p0}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
    move-result-object v1
    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
    return-void
.end method

上面方法调用代码为:

[Java] 纯文本查看 复制代码
1
invoke-static {vx}, Lcrack;->I(I)V

vx为要查看的寄存器。

当vx保存的是long型的话,就比较麻烦了,稍微用错就会导致程序停止运行,所以尽量避免查看long型vx。

给crack.smali添加以下代码:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
.method public static J(J)V
.locals 2
.prologue
const-string v0, "info_long"
invoke-static {p0, p1}, Ljava/lang/String;->valueOf(J)Ljava/lang/String;
move-result-object v1
invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
return-void
.end method

上面方法调用代码为:

[Java] 纯文本查看 复制代码
1
invoke-static {vx, vx+1}, Lcrack;->J(J)V

vx为要查看的寄存器,同时确保vx+1在上面的代码中没有被使用过,且在.locals声明的可使用的寄存器范围内。

至于[C、[B、[Ljava/lang/String的查看,有机会再补上。

软件大部分时间都在跟字符串、数据打交道。很多时候就因为某个寄存器的值不知,导致软件代码很难分析下去。

因此在没有调试器的前提下,通过注入查看寄存器的值就变得非常重要了。

总是通过logcat查看寄存器值,多少有点不方便,所以下面讲下如何将字符串输出到文本。

直接用smali写有点麻烦,所以先用java写,编译后再反编译为smali,参考java代码如下:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.io.*;
import android.util.Log;
public class crack
{
/*将字符串s输出到/sdcard/debug.txt*/
public static void puts(String s)
{
  try
  {
          String path= "/sdcard/debug.txt";
           
                  FileOutputStream outStream = new FileOutputStream(path,false);
                  OutputStreamWriter writer = new OutputStreamWriter(outStream,"gb2312");
                  writer.write(s);
                  writer.flush();
                  writer.close();
                  outStream.close();
  }
                  catch (Exception e)
                  {
                          Log.e("debug", "file write error");
                  }
}
}

反编译后smali代码如下:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
.method public static puts(Ljava/lang/String;)V
    .locals 7
    .prologue
    :try_start_0
    const-string v3, "/sdcard/debug.txt"
    new-instance v2, Ljava/io/FileOutputStream;
    const/4 v5, 0x0
    invoke-direct {v2, v3, v5}, Ljava/io/FileOutputStream;-><init>(Ljava/lang/String;Z)V
    .line 19
    new-instance v4, Ljava/io/OutputStreamWriter;
    const-string v5, "gb2312"
    invoke-direct {v4, v2, v5}, Ljava/io/OutputStreamWriter;-><init>(Ljava/io/OutputStream;Ljava/lang/String;)V
    .line 21
    invoke-virtual {v4, p0}, Ljava/io/OutputStreamWriter;->write(Ljava/lang/String;)V
    .line 23
    invoke-virtual {v4}, Ljava/io/OutputStreamWriter;->flush()V
    .line 25
    invoke-virtual {v4}, Ljava/io/OutputStreamWriter;->close()V
    .line 27
    invoke-virtual {v2}, Ljava/io/FileOutputStream;->close()V
    :try_end_0
    .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0
    .line 37
    :cond_0
    :goto_0
    return-void
    .line 30
    :catch_0
    move-exception v0
    .line 34
    const-string v5, "debug"
    const-string v6, "file write error"
    invoke-static {v5, v6}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I
    goto :goto_0
.end method

使用方法为,在要查看的寄存器vx的下方换行添加代码:

[Java] 纯文本查看 复制代码
1
invoke-static {vx}, Lcrack;->puts(Ljava/lang/String;)V

至于输出整型变量到文本,请参考之前的例子,先将整型变量转为字符串,再输出,具体代码这里略过。。。

下面介绍通过注入,改变软件获得的imei号,让软件改为读取保存在 “/sdcard/deviceid/imei.txt” 里的串号。

参考java代码如下:

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import java.io.*;
public class crack {
        public static String getDeviceId()
        {
        String path = "/sdcard/deviceid/imei.txt";
        String str = null;
        File f = new File(path);
        if (f != null && f.exists()) 
        {
            FileInputStream fis = null;
            try {
                    fis = new FileInputStream(f);
            } catch (FileNotFoundException e1) {
            e1.printStackTrace(); 
        }
            InputStreamReader inputStreamReader = null;
            try {
                    inputStreamReader = new InputStreamReader(fis, "utf-8");
                    try {
                            BufferedReader reader = new BufferedReader(inputStreamReader);
                            StringBuffer sb = new StringBuffer("");
                            String line;
                            line = reader.readLine();
                            sb.append(line);
                            reader.close();       
                            fis.close();
                            str = sb.toString();
                    catch (IOException e) {  
                e.printStackTrace();  
            }
            } catch (UnsupportedEncodingException e) { 
                     e.printStackTrace();          
                 }  
        }
              return str;
        }
}

反编译后得到的smali代码如下:

[Java] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
.method public static getDeviceId()Ljava/lang/String;
    .locals 13
    .prologue
    const-string v8, "/sdcard/deviceid/imei.txt"
    const/4 v11, 0x0
    new-instance v2, Ljava/io/File;
    invoke-direct {v2, v8}, Ljava/io/File;-><init>(Ljava/lang/String;)V
    if-eqz v2, :cond_0
    invoke-virtual {v2}, Ljava/io/File;->exists()Z
    move-result v12
    if-eqz v12, :cond_0
    const/4 v3, 0x0
    :try_start_0
    new-instance v4, Ljava/io/FileInputStream;
    invoke-direct {v4, v2}, Ljava/io/FileInputStream;-><init>(Ljava/io/File;)V
    :try_end_0
    .catch Ljava/io/FileNotFoundException; {:try_start_0 .. :try_end_0} :catch_0
    move-object v3, v4
    :goto_0
    const/4 v5, 0x0
    :try_start_1
    new-instance v6, Ljava/io/InputStreamReader;
    const-string v12, "utf-8"
    invoke-direct {v6, v3, v12}, Ljava/io/InputStreamReader;-><init>(Ljava/io/InputStream;Ljava/lang/String;)V
    :try_end_1
    .catch Ljava/io/UnsupportedEncodingException; {:try_start_1 .. :try_end_1} :catch_3
    :try_start_2
    new-instance v9, Ljava/io/BufferedReader;
    invoke-direct {v9, v6}, Ljava/io/BufferedReader;-><init>(Ljava/io/Reader;)V
    new-instance v10, Ljava/lang/StringBuffer;
    const-string v12, ""
    invoke-direct {v10, v12}, Ljava/lang/StringBuffer;-><init>(Ljava/lang/String;)V
    invoke-virtual {v9}, Ljava/io/BufferedReader;->readLine()Ljava/lang/String;
    move-result-object v7
    invoke-virtual {v10, v7}, Ljava/lang/StringBuffer;->append(Ljava/lang/String;)Ljava/lang/StringBuffer;
    invoke-virtual {v9}, Ljava/io/BufferedReader;->close()V
    invoke-virtual {v3}, Ljava/io/FileInputStream;->close()V
    invoke-virtual {v10}, Ljava/lang/StringBuffer;->toString()Ljava/lang/String;
    :try_end_2
    .catch Ljava/io/IOException; {:try_start_2 .. :try_end_2} :catch_1
    .catch Ljava/io/UnsupportedEncodingException; {:try_start_2 .. :try_end_2} :catch_2
    move-result-object v11
    :cond_0
    :goto_1
    return-object v11
    :catch_0
    move-exception v1
    invoke-virtual {v1}, Ljava/io/FileNotFoundException;->printStackTrace()V
    goto :goto_0
    :catch_1
    move-exception v0
    :try_start_3
    invoke-virtual {v0}, Ljava/io/IOException;->printStackTrace()V
    :try_end_3
    .catch Ljava/io/UnsupportedEncodingException; {:try_start_3 .. :try_end_3} :catch_2
    goto :goto_1
    :catch_2
    move-exception v0
    move-object v5, v6
    :goto_2
    invoke-virtual {v0}, Ljava/io/UnsupportedEncodingException;->printStackTrace()V
    goto :goto_1
    :catch_3
    move-exception v0
    goto :goto_2
.end method

使用方法为:

查找

[Java] 纯文本查看 复制代码
1
Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String;

在下面换行添加

[Java] 纯文本查看 复制代码
1
invoke-static {}, Lcrack;->getDeviceId()Ljava/lang/String;

 

9Jul/14

Mac OS X安装Dnsmasq来加速网络

Posted by Nick Xu

众所周知的原因,在兲朝没有干净的DNS解析,使用国内运营商的DNS解析服务会出现被劫持的情况,使用国外公共DNS解析服务会被GFW污染。所以在Mac上使用Dnsmasq搭建一个DNS解析服务,同时把Buffalo路由刷上dd-wrt系统,dd-wrt系统自带Dnsmasq服务,可以使家里所有电脑的解析都一致。因为我的Mac经常外带,所以要本地也建一个Dnsmasq。

Dnsmasq是一个简单的DNS缓存和DHCP服务程序,为什么使用它而不使用hosts?因为每台电脑上都维护一个hosts是个很辛苦的工作,而且Dnsmasq与hosts相比最大的好处是支持泛解析。只要路由使用Dnsmasq服务,其他电脑不用设置就都可以使用了。

虽然使用Dnsmasq不能解决DNS污染的问题,但是简化了hosts的维护,而且关键它支持DNS缓存,解析过的地址会优先使用缓存,不需要再解析了,所以很大程度上,可以加速网络访问。

下面是Mac OS X上安装Dnsmasq和相关配置的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
$ brew install dnsmasq
$ cp /usr/local/opt/dnsmasq/dnsmasq.conf.example /usr/local/etc/dnsmasq.conf
$ vi /usr/local/etc/resolv.dnsmasq.conf
    # Google DNS
    nameserver 8.8.8.8
    nameserver 8.8.4.4
    # OpenDNS
    nameserver 208.67.222.222
    nameserver 208.67.220.220
$ vi /usr/local/etc/dnsmasq.conf
    resolv-file=/usr/local/etc/resolv.dnsmasq.conf
    strict-order
    listen-address=127.0.0.1 # 多个IP用逗号隔开
    no-hosts
    cache-size=32768
    address=/bitbucket.org/131.103.20.167
    address=/google.com/173.194.38.128
    address=/ggpht.com/173.194.38.128
    address=/googleapis.com/173.194.38.128
    address=/googleusercontent.com/173.194.38.128
    address=/gstatic.com/173.194.38.128
    address=/youtube.com/173.194.38.128
    address=/gmail.com/173.194.38.128
    address=/googlesource.com/173.194.38.128
    address=/googlelabs.com/173.194.38.128
    address=/googlecode.com/173.194.38.128
    address=/goo.gl/173.194.38.128
    address=/google.cn/203.208.46.210
    address=/google.com.hk/203.208.46.210
    address=/flickr.com/66.196.66.157
    address=/up.flickr.com/119.161.24.27
    address=/api.flickr.com/208.71.44.31
    address=/farm1.staticflickr.com/72.30.196.151
    address=/farm2.staticflickr.com/72.30.196.152
    address=/farm3.staticflickr.com/98.137.205.236
    address=/farm4.staticflickr.com/98.137.204.89
    address=/farm5.staticflickr.com/68.142.227.95
    address=/farm6.staticflickr.com/98.139.21.45
    address=/farm7.staticflickr.com/98.139.235.135
    address=/farm8.staticflickr.com/72.30.198.116
    address=/farm9.staticflickr.com/72.30.198.117
    address=/github.global.ssl.fastly.net/185.31.17.184
$ sudo cp -fv /usr/local/opt/dnsmasq/*.plist /Library/LaunchDaemons
$ sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist

设置完上面,把系统DNS设置为127.0.0.1就行了,使用dig看看结果

1
$ dig google.com

如果修改了配置文件,可以通过下面的命令重启Dnsmasq

1
2
$ sudo launchctl stop homebrew.mxcl.dnsmasq
$ sudo launchctl start homebrew.mxcl.dnsmasq

Mac OS X清除系统DNS缓存命令

1
$ sudo killall -HUP mDNSResponder

 

最后,问候GFW项目的全家,上到祖宗十八代,下到子孙十八代!!!

Tagged as: , Comments Off
3Jul/14

mac下设置nat

Posted by Nick Xu

$ sudo sysctl -w net.inet.ip.forwarding=1
$ sudo natd -interface en1
$ sudo ipfw add divert natd ip from any to any via en1
   
site
site