git回滚代码
有时我们需要回滚git上已经提交的代码,特别是已经提交到github上的代码。可以使用如下步骤:
1、 git reflog
$ git reflog
1bd6100 (HEAD -> master) HEAD@{0}: commit: Site updated: 2018-05-10 12:20:40
f681615 HEAD@{1}: commit: Site updated: 2018-04-25 19:31:25
78f096f HEAD@{2}: commit: Site updated: 2018-04-25 19:11:23
14b480b HEAD@{3}: commit: Site updated: 2018-04-24 20:01:27
2、 git reset --hard version
$ git reset --hard f681615
HEAD is now at f681615 Site updated: 2018-04-25 19:31:25
3、 git log
$ git log
commit f68161540b8c3400c4ab4a35eef67039c732781d (HEAD -> master)
Author: drunkdream <drunkdream@gmail.com>
Date: Wed Apr 25 19:31:53 2018 +0800
Site updated: 2018-04-25 19:31:25
4、 git push --force
$ git push --force
Total 0 (delta 0), reused 0 (delta 0)
To github.com:drunkdream/xxx.git
+ 1bd6100...f681615 master -> master (forced update)
编译Android版本的libjpeg-turbo
0x00 前言
libjpeg-turbo是一个JPEG编解码库,支持x86, x86-64, ARM等系统下的指令加速,其性能号称是libjpeg的2-6倍。官网地址是:https://libjpeg-turbo.org/。github地址是:https://github.com/libjpeg-turbo/libjpeg-turbo。
Android中默认提供了libjpeg实现的JPEG编解码接口,但是测试下来性能不是很好,无法满足实际使用需求。因此,准备编译Android版本来用。
修复Linux内核文件丢失问题
如果误操作了/boot目录下kernel文件,会导致无法进入系统,此时,必须要借助第三方系统来进行kernel的修复。

以下以 Ubuntu 16.04系统为例,介绍修复的方法。以下操作都需要root权限。
1、 使用Universal USB Installer制作Ubuntu的USB启动盘,重启进入Live模式
2、 使用mount命令查看系统分区挂载的路径

3、 进入挂载目录
1 | cd /media/ubuntu/c7b8708f-1e7a-4fd0-9815-97be053dad67 |
4、 绑定dev、proc、sys等目录
1 | mount --bind /dev dev |
5、 使用chroot将当前目录变为根目录(这样,之后的操作,都是针对待修复系统的分区)
1 | chroot . |

6、修复kernel
1 | apt update |

可以看到,新的kernel已经被安装到boot目录中了。
此时,重启系统可以正常进去了。
解决Android模拟器中修改IMSI后无法上网问题
0x00 前言
百度百科中对IMSI的介绍如下:
国际移动用户识别码(IMSI:International Mobile Subscriber Identification Number)是区别移动用户的标志,储存在SIM卡中,可用于区别移动用户的有效信息。其总长度不超过15位,同样使用0~9的数字。其中MCC是移动用户所属国家代号,占3位数字,中国的MCC规定为460;MNC是移动网号码,由两位或者三位数字组成,中国移动的移动网络编码(MNC)为00;用于识别移动用户所归属的移动通信网;MSIN是移动用户识别码,用以识别某一移动通信网中的移动用户。
通过IMSI可以知道移动用户所在的国家。在Android中可以通过以下方法获取设备的IMSI号:
TelephonyManager telephonyManager= (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String android_imsi = telephonyManager.getSubscriberId();
Android模拟器中默认使用的IMSI是:310260000000000。其中,310代表美国,260代表T-Mobile US。事实上,我们期望在模拟器上获取的IMSI应当以460开头(460代表中国)。
编译Android版本的OpenVPN
Ubuntu部署OpenVPN服务
编译可用的Android模拟器ranchu内核
0x00 前言
前几天在使用Android模拟器的时候,发现无法连接PPTP类型的VPN服务器,报如下的错误:
I/mtpd (30035): Creating PPPoX socket
F/mtpd (30035): Socket() Address family not supported by protocol
对应的代码如下:
static int create_pppox()
{
int pppox = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OPNS);
log_print(INFO, "Creating PPPoX socket");
if (pppox == -1) {
log_print(FATAL, "Socket() %s", strerror(errno));
exit(SYSTEM_ERROR);
} else {
struct sockaddr_pppopns address = {
.sa_family = AF_PPPOX,
.sa_protocol = PX_PROTO_OPNS,
.tcp_socket = the_socket,
.local = local,
.remote = remote,
};
if (connect(pppox, (struct sockaddr *)&address, sizeof(address))) {
log_print(FATAL, "Connect() %s", strerror(errno));
exit(SYSTEM_ERROR);
}
}
return pppox;
}
错误是在第7行报出来的,也就是说:在创建AF_PPPOX类型的socket时失败了。
网上说是因为kernel不支持的原因,需要重新编译kernel。
Ubuntu安装VNC Server
之前在ubuntu上一般都是用vnc4server,但是它只能打开一个窗口,无法像windows上那样操作本地桌面,只能说比ssh强大一点。
今天发现了一个强大的vnc服务端x11vnc,可以远程操作本地桌面。以下内容主要来自于:http://blog.csdn.net/longhr/article/details/51657610。
安装方法
以下命令都需要在root权限下运行,因此不单独加上sudo。
1. 安装 X11VNC
1 | apt install x11vnc -y |
2. 配置访问密码
1 | x11vnc -storepasswd /etc/x11vnc.pass |
3. 创建服务
Ubuntu 16.04
vi /lib/systemd/system/x11vnc.service
按i键进入编辑模式,粘贴如下代码,按esc键退出编辑模式,输入 :wq 保存。
1 | [Unit] |
Ubuntu 14.04
vi /etc/init/x11vnc.conf
按i键进入编辑模式,粘贴如下代码,按esc键退出编辑模式,输入 :wq 保存。
1 | start on login-session-start |
4. 配置防火墙,配置和启动服务
1 | ufw allow 5900 |
下面两行适用于16.04
1 | systemctl enable x11vnc.service |
5. 重启电脑
1 | reboot |

Linux上C语言写的简易telnet客户端
telnet.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <time.h>
#include <stdarg.h>
#define ERR_EXIT(m, ...) \
do { \
fprintf(stderr, m"\n", ##__VA_ARGS__); \
log(m"\n", ##__VA_ARGS__); \
exit(EXIT_FAILURE); \
} while (0)
#define MAX_BUFF_LEN 1024
void log(const char *fmt, ...)
{
char buffer[MAX_BUFF_LEN] = {0};
va_list args;
time_t timep;
time(&timep);
struct tm *p = gmtime(&timep);
FILE* fp = fopen("telnet.log", "a+");
if(fp){
snprintf(buffer, MAX_BUFF_LEN, "[%.4d-%.2d-%.2d %.2d:%.2d:%.2d][%d]", (1900+p->tm_year),(1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, getpid());
va_start(args, fmt);
vsnprintf(buffer + strlen(buffer), MAX_BUFF_LEN - strlen(buffer) - 1, fmt, args);
va_end(args);
fwrite(buffer, strlen(buffer), 1, fp);
fclose(fp);
}
}
ssize_t /* Write "n" bytes to a descriptor. */
writen(int fd, const void *vptr, size_t n){
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
if (nwritten < 0 && errno == EINTR)
nwritten = 0; /* and call write() again */
else
return(-1); /* error */
}
nleft -= nwritten;
ptr += nwritten;
}
return(n);
}
int main(int argc,char **argv){
if(argc < 3){
fprintf(stderr, "Usage: %s ServerIPAddress ServerPort\n",argv[0]);
return 0;
}
fd_set rset;
FD_ZERO(&rset);
int sock = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET; //internet协议族
struct hostent *h = gethostbyname(argv[1]);
server_addr.sin_addr = *((struct in_addr *)h->h_addr);
server_addr.sin_port = htons(atoi(argv[2]));
if(connect(sock,(struct sockaddr*)&server_addr, sizeof(struct sockaddr_in)) < 0){
ERR_EXIT("connect to %s:%s failed", argv[1], argv[2]);
}
fprintf(stdout, "% 9d\n", getpid());
fflush(stdout);
int nready;
int maxfd;
int fd_stdin = fileno(stdin);
int fd_stdout = fileno(stdout);
if (fd_stdin > sock)
maxfd = fd_stdin;
else
maxfd = sock;
char sendbuf[1024*4] = {0};
char recvbuf[1024*4] = {0};
while (1){
FD_SET(fd_stdin, &rset);
FD_SET(sock, &rset);
nready = select(maxfd + 1, &rset, NULL, NULL, NULL); //select返回表示检测到可读事件
if (nready == -1) ERR_EXIT("select error");
if (nready == 0) continue;
if (FD_ISSET(sock, &rset)){
int ret = read(sock, recvbuf, sizeof(recvbuf)); //按行读取
if (ret == -1) ERR_EXIT("read from socket error");
else if (ret == 0) ERR_EXIT("server close"); //服务器关闭
writen(fd_stdout, recvbuf, ret);
memset(recvbuf, 0, sizeof(recvbuf));
}
if (FD_ISSET(fd_stdin, &rset)){
int ret = read(fd_stdin, sendbuf, sizeof(sendbuf));
if(ret > 0) {
writen(sock, sendbuf, ret);
memset(sendbuf, 0, sizeof(sendbuf));
}else{
ERR_EXIT("read from stdin error");
}
}
}
close(sock);
exit(0);
}
编译方法:
gcc -o telnet telnet.c