关注Rust语言已经有段时间了,距离Rust 1.0发布也只剩一个月不到的时间了,所以就写篇Rust并发相关的文章吧。

Rust官方博客在几天前发布的一篇名为Fearless Concurrency with Rust的文章,从这篇文章可以看出Rust在并发的内存安全上做了很多努力,Rust通过在编译期对所有权(ownership)生命期(lifetime)等进行静态检查以确保并发安全。本文主要是记录博主对于这篇文章的一些见解。

使用Rust来写并发程序,可以受益于下面这些好处。

Read More

事实上早在2013年的时候博主就实现了不依赖任何第三方库在WP8上播放FLV格式的视频文件(见这篇文章),只不过当时没有将源代码开放出来。时间过去了将近两年,但是似乎在GitHub上依然没有开源的方便易用的这方面的库,所以博主决定将这个库重写一遍开源出来。代码托管在GitHub

这个库支持Windows Phone Silverlight应用和Windows Runtime Universal应用,前者面向Windows Phone 8+,后者面向Windows Phone 8.1+和Windows 8.1+。

如何使用

这个库以简单易用为设计目标,在你的项目中使用这个库只需要写数行代码。

Read More

DLL注入

向其他进程注入DLL通常的做法是通过调用CreateRemoteThread这个API在目标进程内创建一个远程线程,用这个线程来调用LoadLibraryALoadLibraryW(下文统称LoadLibrary)以实现让目标进程加载指定的DLL文件。使用CreateRemoteThread创建一个远程线程需要传入一个线程过程函数的地址,并且这个函数地址是需要在目标进程中有效的。由于LoadLibrary是kernel32.dll的导出函数,所以对于运行在同一个系统上的同为32位的进程或同为64位的进程可以假定彼此进程内的LoadLibrary函数的地址是相同的。并且CreateRemoteThread的线程过程函数和LoadLibrary的参数个数相同,且参数都是指针,因此通常都是直接将LoadLibrary作为CreateRemoteThread的过程函数。然后使用VirtualAllocEx在目标进程中分配内存,使用WriteProcessMemory往这块内存中写入DLL文件路径,将这块内存的地址作为线程过程函数(LoadLibrary)的参数。

在64位的Windows操作系统上32位进程中的LoadLibrary函数地址与64位进程的函数地址不同,因此如果想对64位进程注入DLL,简单的做法就是使用64位进程来执行注入工作。但是如果能让32位进程注入DLL到64位进程显然更好。

Read More

Lua是一个轻量级的脚本语言,其设计目标是容易嵌入其他编程语言中去,不依赖任何第3方库使用标准C写成,因此具有很好的可移植性,并且其性能在脚本类语言中也是首屈一指的。lua自身的标准库只提供了一些非常基本且有限的功能,因此单纯使用lua能做的事情并不多,但是lua被设计成很容易由C来扩展它的功能。

动机

在Windows下lua是不具备直接调用Windows API的能力,因此如果想在lua中使用Windows API就需要先在C或C++中对Windows API进行一次封装,然后lua才能够去调用。由于Windows API数量巨多,对其进行逐个封装的工作量也是不小的。作为程序员对这种重复性的劳动总是比较厌烦的,因此就想写一个库支持从lua中直接调用,一劳永逸。

Read More

最近在重构之前写的HTTP代理,这个代理是由代理客户端和代理服务端组成的,二者之前使用SSL保证通信内容不会受到中间人(MITM)攻击。而新的实现打算移除SSL,因为SSL握手的开销过大,尤其是客户端与服务端之间隔了个太平洋,另一方面本月中旬的时候Google安全团队证明了SSLv3已经是不安全的了,需要升级到TLS,但TLS同样有握手的开销。在新的实现中客户端和服务端之间的通信将使用AES加密,每个连接使用独立的随机生成的密钥和初始化向量。客户端在向服务端发起连接后使用非对称加密算法RSA将密钥和初始化向量加密后发送给服务端,服务端在收到密钥和初始化向量后就全部使用AES加密通信,这保证了通信内容不会被窃听(但可能被篡改)。
本文作为备忘记录了学习分组加密模式的一些体会和理解。AES作为一种分组加密算法为了适应不同的安全性要求和传输需求允许在多种不同的加密模式下工作,本文只涉及到ECB、CBC、CFB和OFB四种加密模式,以OpenSSL开源库和C++语言作为描述。

Read More

C++11之多线程系列文章目录

一、标准库的线程封装类Thread和Future
二、互斥对象(Mutex)和锁(Lock)
三、条件变量(Condition Variable)
四、原子操作(Atomic Operation)
五、内存序(Memory Order)

条件变量(Condition Variable)

条件变量是一种同步原语(Synchronization Primitive)用于多线程之间的通信,它可以阻塞一个或同时阻塞多个线程直到:

  • 收到来自其他线程的通知
  • 超时
  • 发生虚假唤醒(Spurious Wakeup)

Read More

使用网页看视频是非常不爽的,尤其是长视频,因为使用网页看视频就意味着你无法在不开多个浏览器窗口的条件下边看视频边浏览网页,而且最最重要的是有广告啊。如果获取到视频的地址就可以直接使用播放器播放了。

获取优酷的视频链接

对于优酷播放页面为

1
http://v.youku.com/v_show/id_XNzYwODQ3MTg0.html

的视频对应的mp4的真实地址为(这个视频被优酷切分成四段)

1
2
3
4
http://k.youku.com/player/getFlvPath/sid/3409483123616127f4226_00/st/mp4/fileid/030008040053F98A94E2631468DEFED15CC475-F07D-7762-1FA8-EB95B046B8B8?K=414595e722b677a42411ec29&hd=1&myp=0&ts=377&ypp=0&ctype=12&ev=1&token=7168&oip=2130706433&ep=cSaUE02FVc8C5iXejj8bYHrmdnUJXP4J9h%2bFidJmALshS562kU%2fYw%2biySPxDEv8RBldwZZ%2fwrqOUbkcRYYZDrhwQ2EmuO%2frhiIHr5dghzZVyZh0wAMWlvFSZQjb5
http://k.youku.com/player/getFlvPath/sid/3409483123616127f4226_00/st/mp4/fileid/030008040153F98A94E2631468DEFED15CC475-F07D-7762-1FA8-EB95B046B8B8?K=d4371bb9a461be672829d1b5&hd=1&myp=0&ts=401&ypp=0&ctype=12&ev=1&token=7168&oip=2130706433&ep=cSaUE02FVc8C5iXejj8bYHrmdnUJXP4J9h%2bFidJmALohS562kU%2fYw%2biySPxDEv8RBldwZZ%2fwrqOUbkcRYYZDrhwQ2EmuO%2frhiIHr5dghzZVyZh0wAMWlvFSZQjb5
http://k.youku.com/player/getFlvPath/sid/3409483123616127f4226_00/st/mp4/fileid/030008040253F98A94E2631468DEFED15CC475-F07D-7762-1FA8-EB95B046B8B8?K=f0197761ab939438261ddeef&hd=1&myp=0&ts=333&ypp=0&ctype=12&ev=1&token=7168&oip=2130706433&ep=cSaUE02FVc8C5iXejj8bYHrmdnUJXP4J9h%2bFidJmALkhS562kU%2fYw%2biySPxDEv8RBldwZZ%2fwrqOUbkcRYYZDrhwQ2EmuO%2frhiIHr5dghzZVyZh0wAMWlvFSZQjb5
http://k.youku.com/player/getFlvPath/sid/3409483123616127f4226_00/st/mp4/fileid/030008040353F98A94E2631468DEFED15CC475-F07D-7762-1FA8-EB95B046B8B8?K=9ee3d46ac50a40262411ec29&hd=1&myp=0&ts=311&ypp=0&ctype=12&ev=1&token=7168&oip=2130706433&ep=cSaUE02FVc8C5iXejj8bYHrmdnUJXP4J9h%2bFidJmALghS562kU%2fYw%2biySPxDEv8RBldwZZ%2fwrqOUbkcRYYZDrhwQ2EmuO%2frhiIHr5dghzZVyZh0wAMWlvFSZQjb5

Read More

C++11之多线程系列文章目录

一、标准库的线程封装类Thread和Future
二、互斥对象(Mutex)和锁(Lock)
三、条件变量(Condition Variable)
四、原子操作(Atomic Operation)
五、内存序(Memory Order)

互斥(Mutex: Mutual Exclusion)

下面的代码中两个线程连续的往int_set中插入多个随机产生的整数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
std::set<int> int_set;
auto f = [&int_set]() {
try {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 1000);
for(std::size_t i = 0; i != 100000; ++i) {
int_set.insert(dis(gen));
}
} catch(...) {}
};
std::thread td1(f), td2(f);
td1.join();
td2.join();

Read More

编译环境

此次编译使用的是Windows Azure的虚拟机,基本的配置信息是这样的。

项目 信息
操作系统 Ubuntu 14.04 LTS (GNU/Linux 3.13.0-27-generic x86_64)
处理器频率(MHz) 2094.651
处理器核心数 2
内存(GB) 3.5

准备工作

1.一个支持ISO C++98的C++编译器

Read More

我原先并不知道std::integer_sequence有什么用,直到我的膝盖中了一箭。

元组(Tuple)

元组是一种长度固定的允许有不同类型元素的集合,根据元素的个数不同又分别称作一元组、二元组、三元组等。C++11中标准库增加了一个叫std::tuple的类模板,用于表示元组。下面的代码演示了使用C++创建一个三元组。

1
2
3
4
5
6
7
8
auto tuple = std::make_tuple(1, 'A', "破晓的博客");
std::cout << std::get<0>(tuple) << std::endl;
std::cout << std::get<1>(tuple) << std::endl;
std::cout << std::get<2>(tuple) << std::endl;
// 下面是C++14的特性
std::cout << std::get<int>(tuple) << std::endl;
std::cout << std::get<char>(tuple) << std::endl;
std::cout << std::get<const char*>(tuple) << std::endl;

输出

1
2
3
4
5
6
1
A
破晓的博客
1
A
破晓的博客

许多编程语言如C#、Python等也有tuple的概念。下面的代码演示了使用Python创建一个三元组。

1
2
3
4
t = (1, 'A', "破晓的博客")
print(t[0])
print(t[1])
print(t[2])

输出

1
2
3
1
A
破晓的博客

Python从语言级别上支持将tuple展开为函数的参数,在Python中假设定义有这样一个函数func和一个元组t,下面的代码演示了将元组t的每个元素作为func函数的参数。

1
2
3
4
def func(arg1, arg2, arg3):
print(arg1, arg2, arg3)
t = (1, 'A', "破晓的博客")
func(*t)

Read More