May
20
XenLab项目里我这一块有了新进展:从System.map里面找到了init_task的虚拟地址。
简而言之,init_task就是linux的第一个进程,在载入init以后,它就进入一个无限循环,然后就变成传说中的idle进程。
更详细的内容参考《深入理解Linux内核》等相关资料。
当然,init_task的地址本来是不用费心去找的,如果你写一个内核模块,这个符号是可以直接引用的:
但是我的目标是:从“Linux外”找到这个init_task的地址
因为我是要从Xen虚拟机的Dom0(类似宿主机的概念)去入侵DomU(类似客户机的概念)
找到init_task以后,我们就可以遍历Linux中的所有进程,然后就可以做一些ooxx的事情了。
因为宿主机是无法直接调用客户机的API,自然无法通过上述方式获得init_task地址。
本来是想通过某种方式直接从DomU中找出这个地址,但是毫无头绪
后来发现System.map可以挖出这个地址,虽然这个方法很挫,但是起码可以进行下一步的动作了。
简而言之,init_task就是linux的第一个进程,在载入init以后,它就进入一个无限循环,然后就变成传说中的idle进程。
更详细的内容参考《深入理解Linux内核》等相关资料。
当然,init_task的地址本来是不用费心去找的,如果你写一个内核模块,这个符号是可以直接引用的:
struct task_struct *task = &init_task;
但是我的目标是:从“Linux外”找到这个init_task的地址
因为我是要从Xen虚拟机的Dom0(类似宿主机的概念)去入侵DomU(类似客户机的概念)
找到init_task以后,我们就可以遍历Linux中的所有进程,然后就可以做一些ooxx的事情了。
因为宿主机是无法直接调用客户机的API,自然无法通过上述方式获得init_task地址。
本来是想通过某种方式直接从DomU中找出这个地址,但是毫无头绪
后来发现System.map可以挖出这个地址,虽然这个方法很挫,但是起码可以进行下一步的动作了。
May
20
本文包含一个很挫的算法和一个很赞的算法
-----------------------
24点是一个足够古老的游戏了:
给出四个一位数(可能重复),使用加减乘除和括号将这四个数字整合成一个算式,使得算式的结果等于24。
当然,不是所有的四个一位数都可以组合成24的,比如1,1,1,1显然就不能。
有两个经典的组合是 1, 5, 5, 5 和 3, 3, 8, 8 —— 你可以找出有效解吗?
对于任意给出的四个一位数,如果不考虑重复的情况(比如1,5,5,5,把三个5当成不同的数字)
那么可以算出,可能的算式有 (4*3*2*1) * (1*2+1*1+2*1) * (4 * 4 * 4) = 7680种。
这么大的数字用人脑去算是很不合理的,所以应该写一个程序来处理,嗯。
(中间的 1 * 2 + 1 * 1 + 2 * 1是什么?——下面再说)
这个程序的实现我大一的时候曾经想过,但是那时候对语言掌握都很差,更别说写出具体的回溯等算法来实现。
昨天又想到这个问题,于是拖了这么久,终于在今天把代码写出来了(一题两年出,一跑就郁闷)。
-----------------------
24点是一个足够古老的游戏了:
给出四个一位数(可能重复),使用加减乘除和括号将这四个数字整合成一个算式,使得算式的结果等于24。
当然,不是所有的四个一位数都可以组合成24的,比如1,1,1,1显然就不能。
有两个经典的组合是 1, 5, 5, 5 和 3, 3, 8, 8 —— 你可以找出有效解吗?
对于任意给出的四个一位数,如果不考虑重复的情况(比如1,5,5,5,把三个5当成不同的数字)
那么可以算出,可能的算式有 (4*3*2*1) * (1*2+1*1+2*1) * (4 * 4 * 4) = 7680种。
这么大的数字用人脑去算是很不合理的,所以应该写一个程序来处理,嗯。
(中间的 1 * 2 + 1 * 1 + 2 * 1是什么?——下面再说)
这个程序的实现我大一的时候曾经想过,但是那时候对语言掌握都很差,更别说写出具体的回溯等算法来实现。
昨天又想到这个问题,于是拖了这么久,终于在今天把代码写出来了(一题两年出,一跑就郁闷)。
May
18
网上可以搜到很多相关的资料,这里不具体说了,
大致就是,定义struct/class的时候 编译器会把其中的每个成员的存储位置对齐
对齐原则一般是和该成员大小一致,比如int的就从%4=0的地址开始存储,多余的空间就编译器随便填充了。
然后struct还要填充,直到整个struct的大小是最大成员大小的倍数(VC6.0)——为什么呢?
Felix觉得这样是为了保证连续存储的时候下一个struct的最大成员也是对齐的。
此外,编译器还会对struct的存储地址进行对齐。
我实际测试了一下,我发现32bit的gcc在对struct进行填充的时候
如果某成员的大小大于4Bytes(long long, double)的时候,实际上是以4字节对齐的。
如果在程序中指定了
#pragma pack(n)
那么对齐的时候就会把元素的大小和n进行比较,取较小的那个来对齐。
此外:
#pragma pack(push)
#program pack(pop)
可以成对使用,用来保存(push)当前的n和取出(pop)之前的n——当然,这是在编译过程中处理的。
下面是我的一段测试程序:
大致就是,定义struct/class的时候 编译器会把其中的每个成员的存储位置对齐
对齐原则一般是和该成员大小一致,比如int的就从%4=0的地址开始存储,多余的空间就编译器随便填充了。
然后struct还要填充,直到整个struct的大小是最大成员大小的倍数(VC6.0)——为什么呢?
Felix觉得这样是为了保证连续存储的时候下一个struct的最大成员也是对齐的。
此外,编译器还会对struct的存储地址进行对齐。
我实际测试了一下,我发现32bit的gcc在对struct进行填充的时候
如果某成员的大小大于4Bytes(long long, double)的时候,实际上是以4字节对齐的。
如果在程序中指定了
#pragma pack(n)
那么对齐的时候就会把元素的大小和n进行比较,取较小的那个来对齐。
此外:
#pragma pack(push)
#program pack(pop)
可以成对使用,用来保存(push)当前的n和取出(pop)之前的n——当然,这是在编译过程中处理的。
下面是我的一段测试程序:
May
16
早上参加了腾讯的笔试,做完以后自我感觉良好,但是后来和sandy讨论了一下,发现还是挫了,因为没用上Hash。
于是中午回去狠查了一些资料,看到了一点东西,充实了些。
看到一些字符串的Hash函数,想测试一下它们的实际性能
于是写了个程序来生成5w个字符串
用不同的hash函数计算hash值模9793(随便写的一个数字)
然后再用 sort 和 uniq 看了一下结果,发现 sdbmhash 是最好的, jshash其次,也很不错
然而很意外的是 elfhash 的性能则相当差,完全达不到可用的标准
——在对5w个数进行hash以后得到的结果里面,居然有700多个0和400多个1。
下面贴一些代码:
gen_data.cpp
hash.cpp
查看结果:
于是中午回去狠查了一些资料,看到了一点东西,充实了些。
下载文件 (已下载 1785 次)
看到一些字符串的Hash函数,想测试一下它们的实际性能
于是写了个程序来生成5w个字符串
用不同的hash函数计算hash值模9793(随便写的一个数字)
然后再用 sort 和 uniq 看了一下结果,发现 sdbmhash 是最好的, jshash其次,也很不错
然而很意外的是 elfhash 的性能则相当差,完全达不到可用的标准
——在对5w个数进行hash以后得到的结果里面,居然有700多个0和400多个1。
下面贴一些代码:
gen_data.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char tbl[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+=-?><:';,./][{}\\\"";
int main(){
char s[1024];
int i, l, m = strlen(tbl), j;
srand(732984);
freopen("str.txt", "w", stdout);
for (i = 0; i < 50000; ++i){
l = rand() % 100 + 1;
for (j = 0; j < l; ++j)
s[j] = tbl[rand() % m];
s[j] = 0;
printf("%s\n", s);
}
return 0;
}
#include <stdlib.h>
#include <string.h>
char tbl[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+=-?><:';,./][{}\\\"";
int main(){
char s[1024];
int i, l, m = strlen(tbl), j;
srand(732984);
freopen("str.txt", "w", stdout);
for (i = 0; i < 50000; ++i){
l = rand() % 100 + 1;
for (j = 0; j < l; ++j)
s[j] = tbl[rand() % m];
s[j] = 0;
printf("%s\n", s);
}
return 0;
}
hash.cpp
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
unsigned int elfhash(char *s){
int hash = 0, x = 0;
while (*s){
hash = (hash << 4) + (*s++);
if(((x = hash) & 0xf0000000l) != 0){
hash ^= (x >> 24);
hash &= x;
}
}
return hash & 0x7fffffffl;
}
unsigned int jshash(char *s){
int hash = 1315423911;
while (*s){
hash ^= (hash << 5) + *s++ + (hash >> 2);
}
return (hash & 0x7fffffffl);
}
unsigned int sdbmhash(char *s){
int hash = 0;
while (*s){
hash = (hash << 6) + (hash << 16) - hash + *s++;
}
return (hash & 0x7fffffffl);
}
int main(){
char s[1024];
freopen("str.txt", "r", stdin);
freopen("elf1.txt", "w", stdout);
while(true){
scanf("%s", s);
if(feof(stdin)) break;
printf("%d\n", elfhash(s) % 9793);
}
return 0;
}
#include <cstdlib>
#include <cstring>
using namespace std;
unsigned int elfhash(char *s){
int hash = 0, x = 0;
while (*s){
hash = (hash << 4) + (*s++);
if(((x = hash) & 0xf0000000l) != 0){
hash ^= (x >> 24);
hash &= x;
}
}
return hash & 0x7fffffffl;
}
unsigned int jshash(char *s){
int hash = 1315423911;
while (*s){
hash ^= (hash << 5) + *s++ + (hash >> 2);
}
return (hash & 0x7fffffffl);
}
unsigned int sdbmhash(char *s){
int hash = 0;
while (*s){
hash = (hash << 6) + (hash << 16) - hash + *s++;
}
return (hash & 0x7fffffffl);
}
int main(){
char s[1024];
freopen("str.txt", "r", stdin);
freopen("elf1.txt", "w", stdout);
while(true){
scanf("%s", s);
if(feof(stdin)) break;
printf("%d\n", elfhash(s) % 9793);
}
return 0;
}
查看结果:
引用
$ sort elf1.txt | less
$ sort elf1.txt | uniq | less
$ sort elf1.txt | uniq | less
May
16
把手头另外一个移动的号码开通了fetion
然后加上昨天发现的那个php的fetion处理了一下
现在大家可以在线免费给我发短信拉!
想自己架设一个?下载这个东西去玩儿吧:
然后加上昨天发现的那个php的fetion处理了一下
现在大家可以在线免费给我发短信拉!
想自己架设一个?下载这个东西去玩儿吧:
下载文件 (已下载 1728 次)
May
16
(参考网上的资料)用到了 ImageMagick 工具包。
@ Ubuntu
sudo apt-get install imagemagick
就可以把 1.jpg 的尺寸缩小到越来的1/4
就可以把 1.jpg 的尺寸缩小到400x300
注意,两个比率/数字之间的是字母x,不是乘号。
然后来个批量转换的东东(网上的教程是for,虽然我比较喜欢find)
如果要递归地转换当前目录以及子目录的图像就用find吧:
@ Ubuntu
sudo apt-get install imagemagick
引用
$ convert -resize 50%x50% 1.jpg 1_small.jpg
引用
$ convert -sample 400x300 1.jpg 1_small.jpg
注意,两个比率/数字之间的是字母x,不是乘号。
然后来个批量转换的东东(网上的教程是for,虽然我比较喜欢find)
引用
for img in `ls *.jpg`; do convert -resize 50%x50% $img small_$img; done
如果要递归地转换当前目录以及子目录的图像就用find吧:
引用
find -name "*.jpg" -exec convert -resize 50%x50% {} {}.small.jpg
May
15
这下方便了。。可以直接从网页上发短信了。。。
网上有现成的,比较常见的是 http://sms.api.bz ,应该是安全的,不过毕竟是别人搭建的,不放心。
如果自己搭建,可以用这个:
不过要求是安装了php5-curl模块的。
网上有现成的,比较常见的是 http://sms.api.bz ,应该是安全的,不过毕竟是别人搭建的,不放心。
如果自己搭建,可以用这个:
下载文件 (已下载 1728 次)
不过要求是安装了php5-curl模块的。
May
15
不知道从什么时候开始,发现当使用phpmailer发送邮件的时候
如果邮件标题长度超过16个字符,无论调整成什么编码,收到的邮件都是乱码。
昨天发现了别人的应用,却发现非常正常。
对比之下,发现原来我用的是phpmailer v2.3,别人用的是v2.0
降级成旧版本以后发现一切都正常了。。。Orz
原来是新版本的Bug,郁闷了我好久。。。。
于是把所有用到phpmailer的应用都替换了一下。。。
如果邮件标题长度超过16个字符,无论调整成什么编码,收到的邮件都是乱码。
昨天发现了别人的应用,却发现非常正常。
对比之下,发现原来我用的是phpmailer v2.3,别人用的是v2.0
降级成旧版本以后发现一切都正常了。。。Orz
原来是新版本的Bug,郁闷了我好久。。。。
于是把所有用到phpmailer的应用都替换了一下。。。