How to format C and C++ code in Sublime Text
I am writing some C code on my mac using Sublime Text and I needed a quick way to format the code for better readability.
I found this package for Sublime Text named SublimeAStyleFormatter:
https://packagecontrol.io/packages/SublimeAStyleFormatter
I’ve installed it with git by going on the packages folder and cloning the git repo:
cd ~/Library/Application\ Support/Sublime\ Text\ 3/Packages/
git clone git://github.com/timonwong/SublimeAStyleFormatter.git
And that was it! I can format my C code by pressing Ctrl + Alt + F.
虎牙滩
2015/10/29
2015/10/26
Cross-compiling a C application using the Android NDK
1 download ndk
export NDK=~/Downloads/android-ndk-r10e
2 Set cross-compiler for x86 (emulator)
mac:
export NDK_TOOLCHAIN=${NDK}/toolchains/x86-4.8/prebuilt/darwin-x86_64/bin/i686-linux-android-
export NDK_SYSROOT=${NDK}/platforms/android-19/arch-x86
Set cros-compiler for arm (device)
export NDK_TOOLCHAIN=${NDK}/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-
export NDK_SYSROOT=${NDK}/platforms/android-19/arch-arm
3 compile
// hello-world.c
#include <stdio.h>
int main(void)
{
printf("Hello world cross compiled on Android!\n");
return 0;
}
make CC=${NDK_TOOLCHAIN}gcc CFLAGS=--sysroot=${NDK_SYSROOT} hello-world
4 push to test
$ adb push hello-world /data/
$ adb shell
# /data/hello-world
Hello world cross compiled on Android!
reference:
https://yaapb.wordpress.com/2012/09/27/cross-compiling-a-c-application-using-the-android-ndk/
export NDK=~/Downloads/android-ndk-r10e
2 Set cross-compiler for x86 (emulator)
mac:
export NDK_TOOLCHAIN=${NDK}/toolchains/x86-4.8/prebuilt/darwin-x86_64/bin/i686-linux-android-
export NDK_SYSROOT=${NDK}/platforms/android-19/arch-x86
Set cros-compiler for arm (device)
export NDK_TOOLCHAIN=${NDK}/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-
export NDK_SYSROOT=${NDK}/platforms/android-19/arch-arm
3 compile
// hello-world.c
#include <stdio.h>
int main(void)
{
printf("Hello world cross compiled on Android!\n");
return 0;
}
make CC=${NDK_TOOLCHAIN}gcc CFLAGS=--sysroot=${NDK_SYSROOT} hello-world
4 push to test
$ adb push hello-world /data/
$ adb shell
# /data/hello-world
Hello world cross compiled on Android!
reference:
https://yaapb.wordpress.com/2012/09/27/cross-compiling-a-c-application-using-the-android-ndk/
2015/10/21
Linux ELF 文件操作的一些工具
Linux ELF 文件操作的一些工具
1 file yourlib.so 识别文件格式
2 nm -g yourlib.so 列举目标文件中的符号,
默认输出这个文件中声明的任何函数和全局变量的名称
nm -g yourlib.so 列出所有 extern & exported symbols
nm -gC yourlib.so #for C++
nm -t d -l -S -v ./a.out
nm -Ca lib.so 显示所有symbols and function names
nm -D lib.so # list symbols in the dynamic symbol table, which you can find its address by dlsym.
3 ldd yourlib.so 解析动态链接二进制文件所依赖的库文件
在OS X上,使用 otool -L yourlib.dylib 可实现类似的功能
4 objdump
Linux 自带, Mac OS 上类似为otool.
objdump -D lib.so #display assembler contents for all sections
objdump -tT /lib/i386-linux-gnu/libc.so.6 | grep fopen
objdump -Dslx lib.so
objdump -x lib.so
objdump -TC lib.so
5 readelf
readelf -Ws libc.so 显示所有symbol tables
readelf -s lib.so 显示所有symbol tables
readelf -h lib.so # elf header
readelf -S lib.so #sections
6 strings yourfile 用于提取文件中的字符串
strings —readix=x yourfile 显示字符串在文件中位置
-a 扫描整个文件
-e 也扫描Unicode字符
7 size
size /usr/sbin/httpd
Sample outputs:
text data bss dec hex filename
314213 12376 13304 339893 52fb5 /usr/sbin/httpd
Where,
text - Actual machine instructions that your CPU going to execute. Linux allows to share this data.
data - All initialized variables (declarations) declared in a program (e.g., float salary=123.45;).
bss - The BSS consists of uninitialized data such as arrays that you have not set any values to or null pointers.
8 elfedit
Linux 自带, 可修改machine type, file type, osabi信息
9 hexdump -C /bin/ls | more
linux command, 查看二进制信息
refer to:
http://www.tenouk.com/Module000linuxnm3.html
1 file yourlib.so 识别文件格式
2 nm -g yourlib.so 列举目标文件中的符号,
默认输出这个文件中声明的任何函数和全局变量的名称
nm -g yourlib.so 列出所有 extern & exported symbols
nm -gC yourlib.so #for C++
nm -t d -l -S -v ./a.out
nm -Ca lib.so 显示所有symbols and function names
nm -D lib.so # list symbols in the dynamic symbol table, which you can find its address by dlsym.
3 ldd yourlib.so 解析动态链接二进制文件所依赖的库文件
在OS X上,使用 otool -L yourlib.dylib 可实现类似的功能
4 objdump
Linux 自带, Mac OS 上类似为otool.
objdump -D lib.so #display assembler contents for all sections
objdump -tT /lib/i386-linux-gnu/libc.so.6 | grep fopen
objdump -Dslx lib.so
objdump -x lib.so
objdump -TC lib.so
5 readelf
readelf -Ws libc.so 显示所有symbol tables
readelf -s lib.so 显示所有symbol tables
readelf -h lib.so # elf header
readelf -S lib.so #sections
6 strings yourfile 用于提取文件中的字符串
strings —readix=x yourfile 显示字符串在文件中位置
-a 扫描整个文件
-e 也扫描Unicode字符
7 size
size /usr/sbin/httpd
Sample outputs:
text data bss dec hex filename
314213 12376 13304 339893 52fb5 /usr/sbin/httpd
Where,
text - Actual machine instructions that your CPU going to execute. Linux allows to share this data.
data - All initialized variables (declarations) declared in a program (e.g., float salary=123.45;).
bss - The BSS consists of uninitialized data such as arrays that you have not set any values to or null pointers.
8 elfedit
Linux 自带, 可修改machine type, file type, osabi信息
9 hexdump -C /bin/ls | more
linux command, 查看二进制信息
refer to:
http://www.tenouk.com/Module000linuxnm3.html
2015/07/29
T-OTP for Google Authenticator
Google Authenticator采用的算法是T-OTP(Time-Based One-Time Password),需要知道以下三点信息:
* Key: 共享密钥
* Current Time: 当前时间输入
* HMAC-SHA1函数
共享密钥
共享密码用于在手机端上建立账户。密码内容可以是通过手机拍照二维码或者手工输入,并会被进行base32加密。
手工密码的输入格式如下:
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
包含该令牌的二维码的内容是一个URL:
otpauth://totp/Google%3Ayourname@gmail.com?secret=xxxx&issuer=Google
时间输入(当前时间)
输入的时间值来自于手机,一旦注册获得密钥后,就无需与服务器再进行通信,所以要确保手机上的时间准确,因为往后的步骤服务器可能会验证多个收到的OTP token,但时间值服务器只会取当前时间: 服务器会比对所有提交的token以确认是否有正确输入。
Hash函数
验证所用的方法是HMAC-SHA1,以一个密钥和一个消息为输入,生成一个20字节消息摘要作为输出。其算法可以简单表示为:
hmac = SHA1(secret + SHA1(secret + input))
T-OTP与H-OTP的区别是T-OTP以当前时间作为输入,而H-OTP以自增counter(based on a seed)作为输入,该计数器使用时需要两边同步。
算法
首先,要进行密钥的base32加密。虽然谷歌上的密钥格式是带空格的,不过base32拒绝空格输入,并只允许大写。所以要作如下处理:
original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
第二步要获取当前时间值,这里使用的是UNIX time函数,或者可以用纪元秒。
input = CURRENT_UNIX_TIME()
在Google Authenticator中,input值拥有一个有效期。因为如果直接根据时间进行计算,结果将时刻发生改变,那么将很难进行复用。Google Authenticator默认使用30秒作为有效期(时间片),最后input的取值为从Unix epoch(1970年1月1日 00:00:00)来经历的30秒的个数。
input = CURRENT_UNIX_TIME() / 30
最后一步是进行HMAC-SHA1运算
1.original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
2.secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
3.input = CURRENT_UNIX_TIME() / 30
4.hmac = SHA1(secret + SHA1(secret + input))
HMAC运算后的结果会是20字节即40位16进制数,我们需要的是常规6位数字密码. 首先要对20字节的SHA1进行瘦身。我们把SHA1的最后4个比特数(每个数的取值是0~15)用来做索引号,然后使用从索引号开始的4个字节计算OTP。因此,索引号的操作范围是15+4=19,加上是以零开始,所以能完整表示20字节的信息。4字节的获取方法是:
1.然后将它转化为标准的32bit无符号整数(4 bytes = 32 bit):
2.large_integer = INT(four_bytes)
最后再进行7位数(1百万)取整,就可得到6位数字了:
1.large_integer = INT(four_bytes)
2.small_integer = large_integer % 1,000,000
这也是我们最后要的目标结果,整个过程总结如下:
1.original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
2.secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
3.input = CURRENT_UNIX_TIME() / 30
4.hmac = SHA1(secret + SHA1(secret + input))
5.four_bytes = hmac[LAST_BYTE(hmac):LAST_BYTE(hmac) + 4]
6.large_integer = INT(four_bytes)
7.small_integer = large_integer % 1,000,000
一个完整可执行的GO语言程序,可以这里进行查看:
http://garbagecollected.org/2014/09/14/how-google-authenticator-works/
* Key: 共享密钥
* Current Time: 当前时间输入
* HMAC-SHA1函数
共享密钥
共享密码用于在手机端上建立账户。密码内容可以是通过手机拍照二维码或者手工输入,并会被进行base32加密。
手工密码的输入格式如下:
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
包含该令牌的二维码的内容是一个URL:
otpauth://totp/Google%3Ayourname@gmail.com?secret=xxxx&issuer=Google
时间输入(当前时间)
输入的时间值来自于手机,一旦注册获得密钥后,就无需与服务器再进行通信,所以要确保手机上的时间准确,因为往后的步骤服务器可能会验证多个收到的OTP token,但时间值服务器只会取当前时间: 服务器会比对所有提交的token以确认是否有正确输入。
Hash函数
验证所用的方法是HMAC-SHA1,以一个密钥和一个消息为输入,生成一个20字节消息摘要作为输出。其算法可以简单表示为:
hmac = SHA1(secret + SHA1(secret + input))
T-OTP与H-OTP的区别是T-OTP以当前时间作为输入,而H-OTP以自增counter(based on a seed)作为输入,该计数器使用时需要两边同步。
算法
首先,要进行密钥的base32加密。虽然谷歌上的密钥格式是带空格的,不过base32拒绝空格输入,并只允许大写。所以要作如下处理:
original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
第二步要获取当前时间值,这里使用的是UNIX time函数,或者可以用纪元秒。
input = CURRENT_UNIX_TIME()
在Google Authenticator中,input值拥有一个有效期。因为如果直接根据时间进行计算,结果将时刻发生改变,那么将很难进行复用。Google Authenticator默认使用30秒作为有效期(时间片),最后input的取值为从Unix epoch(1970年1月1日 00:00:00)来经历的30秒的个数。
input = CURRENT_UNIX_TIME() / 30
最后一步是进行HMAC-SHA1运算
1.original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
2.secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
3.input = CURRENT_UNIX_TIME() / 30
4.hmac = SHA1(secret + SHA1(secret + input))
HMAC运算后的结果会是20字节即40位16进制数,我们需要的是常规6位数字密码. 首先要对20字节的SHA1进行瘦身。我们把SHA1的最后4个比特数(每个数的取值是0~15)用来做索引号,然后使用从索引号开始的4个字节计算OTP。因此,索引号的操作范围是15+4=19,加上是以零开始,所以能完整表示20字节的信息。4字节的获取方法是:
1.然后将它转化为标准的32bit无符号整数(4 bytes = 32 bit):
2.large_integer = INT(four_bytes)
最后再进行7位数(1百万)取整,就可得到6位数字了:
1.large_integer = INT(four_bytes)
2.small_integer = large_integer % 1,000,000
这也是我们最后要的目标结果,整个过程总结如下:
1.original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
2.secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
3.input = CURRENT_UNIX_TIME() / 30
4.hmac = SHA1(secret + SHA1(secret + input))
5.four_bytes = hmac[LAST_BYTE(hmac):LAST_BYTE(hmac) + 4]
6.large_integer = INT(four_bytes)
7.small_integer = large_integer % 1,000,000
一个完整可执行的GO语言程序,可以这里进行查看:
http://garbagecollected.org/2014/09/14/how-google-authenticator-works/
2015/06/11
Linux 32-bit和64-bit编译
Environment:
Ubuntu 14.04 64-bit desktop, as guest virtual machine in virtual box
Host: MacBook Pro
在64位机器上缺省编译或运行时查找的是64位程序,但如果编译32位程序通常会遇到一些问题,这里做一个说明。
Build 32-bit C/C++ program on 64-bit Linux
sudo apt-get install g++ #to build C++ source files
sudo apt-get install g++-multilib #to build 32-bit executable on 64-bit Linux
g++ -m32 -g -o a.out file1.cpp file2.cpp #specify 32-bit binary
Run 32-bit executable on 64-bit Linux
要运行32位legacy程序,则需要安装相应的32位库文件(ia32-libs)。
首先添加 i386 architecture,然后安装必要的32位库。
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386
sudo ./file-name
以下步骤可能也需要:
sudo apt-get update
sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0
特别的,比如需要libgc library,则需指定i386类型下载:
sudo apt-get install libgc1c2 (for 32-bit linux)
sudo apt-get install libgc1c2:i386 (for 64-bit linux)
可以用命令 “file file_name”查看执行文件类型:
file-name: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, not stripped
Ubuntu 14.04 64-bit desktop, as guest virtual machine in virtual box
Host: MacBook Pro
在64位机器上缺省编译或运行时查找的是64位程序,但如果编译32位程序通常会遇到一些问题,这里做一个说明。
Build 32-bit C/C++ program on 64-bit Linux
sudo apt-get install g++ #to build C++ source files
sudo apt-get install g++-multilib #to build 32-bit executable on 64-bit Linux
g++ -m32 -g -o a.out file1.cpp file2.cpp #specify 32-bit binary
Run 32-bit executable on 64-bit Linux
要运行32位legacy程序,则需要安装相应的32位库文件(ia32-libs)。
首先添加 i386 architecture,然后安装必要的32位库。
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386
sudo ./file-name
以下步骤可能也需要:
sudo apt-get update
sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0
特别的,比如需要libgc library,则需指定i386类型下载:
sudo apt-get install libgc1c2 (for 32-bit linux)
sudo apt-get install libgc1c2:i386 (for 64-bit linux)
可以用命令 “file file_name”查看执行文件类型:
file-name: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, not stripped
订阅:
博文 (Atom)