吃了人家的免费午餐,照例应该专程为人做做广告,致致贺词。不济也不应该抱怨连连。不过MSN的空间的却引我腹诽。过去的文章找不到……不知道是我方法不对还是什么。如果真的如此我干脆另觅它处,好过我珍贵的文章白白无人看……

OK,先放下MSN空间的问题吧。本周我分析了UPX的压缩原理分析结果亦不外如是。不过话说回来UPX毕竟不是专业的防跟踪壳,仅仅是资源压缩程序而已。好分析也没有什么值得意外的。

源程序如下,是最最出名的Hello,World.:

#include "stdafx.h"
#include <windows.h>

#pragma comment(linker, "/ENTRY:main")
//#pragma comment(linker, "/ALIGN:0x1000")//这厮一上程序就变成3k党了,然后UPX就死气活样的不肯工作

#define put(x) WriteFile(hOutput, (x), sizeof(x), &amp;NumOfBytes, NULL)
#define get(x) ReadFile(hInput, (x), sizeof(x), &amp;NumOfBytes, NULL)

HANDLE hOutput, hInput;
DWORD NumOfBytes;

void main(){
	char tmp[1];
	hOutput=GetStdHandle(STD_OUTPUT_HANDLE);
	hInput=GetStdHandle(STD_INPUT_HANDLE);
	put("Hello,World.n");
	get(tmp);
	return ;
}

UPX压缩下来的程序,section会变成三个。UPX0,UPX1,UPX2。其中UPX0是虚段,具备实际的段名称和段地址,但是RawDateSize是0。所以这个段在载入后是全0数据。数据和解压代码合并在了UPX1段中,由UPX1的解压代码注入UPX0的段中。看样子解压代码是附在了最后,从入口点到段实际内容结束点之间的范围。而UPX3的段最是搞笑,是一个单独的ImportTable,仅仅导入了Kernel32.dll中ExitProcess,LoadLibrary和GetProcessAddr三个函数。UPX1在解压并且注入UPX0后,会调用这三个函数来分析和获得每个导入表项的地址,然后完成导入表的动作。

换言,程序在从UPX1段JMP入UPX0段的瞬间,从UPX0段DUMP出来的数据就是正常的数据,除了要重建Section,并且重建所有DateDirectory外。

OK,下面说说压缩算法的问题。上面可以看出,压缩动作不难,但是算法我可没有能力分析和实现。所以我脑筋就动到了zip算法上去。可是根据我以前看zip文档得到的经验,zip内部分多种格式。貌似rar也分多种格式。所以我不打算挑战极限,自行写出每种算法的代码。不过我打算做一个标准的扩展接口,可以让所有的压缩算法都容纳在这一个框架内。并且可以支持多种压缩文件的格式。对上可以封装成标准的文件读写函数,然后再写一个COM组件,让所有的人都可以任意的运用(嘿嘿,写网页的人估计最需要)。至于后面要不要写一个什么东西让整个windows可以把压缩文件无缝的当成文件夹处理,那就再说了。