|
大家好,我是zhaohj999,一直来论坛混,感觉对不起大家。下面我就themida2.1.x的脱壳过程发表一下。
大家知道,themida的核心是esi表(解码表)和ebx表(dllbase),从这两个表分析配合脚本就ok了。
【软件地址】http://pan.baidu.com/share/home?uk=1931954324&view=share#category/type=0
【脱壳目的】只是感兴趣,相互交流
脱壳过程:
一:先找这两个表
我用脚本跑:
bpmc //删除内存断点
BPHWCALL //清所有硬件断点
BP 7c809b0a //在VirtualAlloc返回处下F2断点(bp VirtualAlloc+5)
run //执行F9后中断在VirtualAlloc返回处
BC 7c809b0a //删除F2断点
BPHWS eax+8ef1,"x" // 在新的VirtualAlloc处下硬件执行断点,这个8ef1就是GetProcAddress的偏移
run //F9
LOOP: //不是就断续运行
cmp eax,7C80AE40 //eax是不是GetProcAddress
JE IsGetProcAddress
run
jmp LOOP //中断在VirtualAlloc,并且eax=GetProcAddress,连续中断两次后,可得到esi和ebx的值
IsGetProcAddress:
log "IsGetProcAddress"
run //中断一次
run //中断第二次,此时刚好填充好esi表和ebx表
BPHWCALL
var tmp
mov tmp,[esp]
bp tmp //看堆栈返回地址
run
BC tmp
//上面是TMD2.1.x通用查找esi和ebx表脚本,本程序见下面语句
pause
得到:
00E4A018 8BB5 8D180015 mov esi,dword ptr ss:[ebp+0x1500188D] //ESI表
esi=00E35DEB~00E41EB6
00E35DEB 15 59 38 6D 50 8F 60 54 5E 1D 00 60 AF 1D 00 20 //esi表开头
00E35DFB 0F 9A 00 C0 FF FF FF FF DD DD DD DD 0F AD 27 DA
...
00E3603B FF FF FF FF DD DD DD DD 0C 34 90 1A BB BB BB BB
00E3604B 48 F5 60 F4 FF FF FF FF DD DD DD DD FB 74 19 07
00E3605B BB BB BB BB 49 F5 60 14 81 88 05 C0 AA AA AA AA
00E3606B FF FF FF FF DD DD DD DD 0C 34 20 6D BB BB BB BB
00E3607B 49 F5 60 34 82 88 05 80 AA AA AA AA FF FF FF FF
00E3608B DD DD DD DD FB 74 B1 07 BB BB BB BB 49 F5 60 54
00E3609B 83 88 05 40 AA AA AA AA FF FF FF FF DD DD DD DD
...
00E41E9B AA AA AA AA FF FF FF FF DD DD DD DD EE EE EE EE
00E41EAB DD DD DD DD 00 00 00 00 00 00 00 00 //以8个0结束esi表
00E4A031 8B9D C52D0015 mov ebx,dword ptr ss:[ebp+0x15002DC5] //EBX表
ebx=02F00000
02F00000 10000000 ADSEC.10000000
02F00004 76060000 SETUPAPI.76060000
02F00008 68BE0000 HID.68BE0000
02F0000C 73D30000 offset MFC42.Ordinal1482
02F00010 77BE0000 MSVCRT.77BE0000
02F00014 7C800000 kernel32.7C800000
02F00018 77D10000 USER32.77D10000
02F0001C 77EF0000 GDI32.77EF0000
02F00020 7D590000 offset SHELL32.Ordinal517
02F00024 76990000 ole32.76990000
02F00028 02FB0000 offset OG70AS.Ordinal3998
02F0002C 71A20000 offset WS2_32.Ordinal496
02F00030 00000000
=============================
二:得到这两个表后,开始分析:
esi=00E35DEB~00E41EB6
ebx=02F00000~002F0030
第一类:带0xbbbbbb api的处理
第二类:不带0xbbbbbb api的处理
第三类:加密api 的处理
第一类 第二类 第三类
带0xbbbbbbbb 不带0xbbbbbb 加密的api
GetApi1 GetApi2 GetApi2
GetIat1 GetIat1 GetIat2
FillCall1 FillCall1 FillCall2
对本程序,esi表第一项是不带0xbbbbbbbb的,也就是第二类
1:对ebx表第一个dword下内存访问断点,断在
00E4A086 FF33 push dword ptr ds:[ebx] ; ADSEC.10000000
00E4A088 812C24 F03C300F sub dword ptr ss:[esp],0xF303CF0
00E4A08F 59 pop ecx
GetBase=00E4A086 寄存器[ebx]
*******
2:找GetAPi2,对esi表第一个dword下内存访问断点,断在
00E4A9CF AD lods dword ptr ds:[esi]
F7,来到
00E4A9E0 BF 00000000 mov edi,0x0
00E4A9E5 897E FC mov dword ptr ds:[esi-0x4],edi //edi=0 读完esi表后清0
...
00E4AA15 3D EEEEEEEE cmp eax,0xEEEEEEEE //比较一大项是否结束
...
00E4AECB 3B02 cmp eax,dword ptr ds:[edx]
00E4AECD 0F84 1D010000 je 老虎YJK?00E4AFF0
比较函数名的hash值了,edx是函数名hash表,eax是本次函数名hash值
可以在00E4AFF0按F4,说明找到了api的索引表
....
00E4B019 3B8D 89130015 cmp ecx,dword ptr ss:[ebp+0x15001389] ; USER32.77D10000
00E4B01F 74 10 je short 老虎YJK?00E4B031
00E4B021 3B8D 252D0015 cmp ecx,dword ptr ss:[ebp+0x15002D25] ; ADVAPI32.77DA0000
00E4B027 74 08 je short 老虎YJK?00E4B031
00E4B029 3B8D C1190015 cmp ecx,dword ptr ss:[ebp+0x150019C1] ; kernel32.7C800000
00E4B02F 75 31 jnz short 老虎YJK?00E4B062
比较是否是3个加密的api
...
00E4B0FE 8B9D C52D0015 mov ebx,dword ptr ss:[ebp+0x15002DC5] //取基地址dllbase
...
00E4B13C 8B85 050D0015 mov eax,dword ptr ss:[ebp+0x15000D05] //eax=7,大概是dll的索引值
00E4B142 60 pushad
...
00E4B16C 0385 71170015 add eax,dword ptr ss:[ebp+0x15001771] ; ADSEC.10027088
00E4B172 E9 0E000000 jmp 老虎YJK?00E4B185
...
00E4B24A 8138 E8000000 cmp dword ptr ds:[eax],0xE8
执行到00E4B24A,eax=10021ee0 ADSEC._HKSEC+RUN@4 ecx=10000000 ADSEC.10000000
eax=func-addr ecx=imagebase
GetApi2=00E4B24A
*******
...
00E4B4AB 2BD9 sub ebx,ecx ;USER32.77D10000 //判断dllbase是否属于加密的api
00E4B4AD 0F84 CC000000 je 老虎YJK?00E4B57F //跳说明是加密的api
...
00E4E946 61 popad
00E4E947 0F85 12000000 jnz 老虎YJK?00E4E95F //
执行到00E4E947 ,eax=func-addr ecx=imagebase
....
00E4B638 3B85 81250015 cmp eax,dword ptr ss:[ebp+0x15002581] ; kernel32.ExitProcess
00E4B63E 0F85 9E000000 jnz 老虎YJK?00E4B6E2 //判断api是否是kernel32.ExitProcess
执行到00E4B63E ,eax=func-addr ecx=imagebase
...
00E4B6E2 3B85 81250015 cmp eax,dword ptr ss:[ebp+0x15002581] ; kernel32.ExitProcess
00E4B6E8 ^ 0F84 FFFDFFFF je 老虎YJK?00E4B4ED //判断api
执行到00E4B63E ,eax=func-addr ecx=imagebase
...
00E4CADC 3B85 2D100015 cmp eax,dword ptr ss:[ebp+0x1500102D] ; USER32.wsprintfA
00E4CAE2 0F85 2D000000 jnz 老虎YJK?00E4CB15 //判断api是否是USER32.wsprintfA
这里让它跳
执行到00E4CAE2 ,eax=func-addr ecx=imagebase
...
00E4CB15 3B85 CD0C0015 cmp eax,dword ptr ss:[ebp+0x15000CCD] ; kernel32.RaiseException
00E4CB1B 0F85 07010000 jnz 老虎YJK?00E4CC28
...
00E4CC28 3B85 3D8C0E15 cmp eax,dword ptr ss:[ebp+0x150E8C3D] ; ntdll.RtlEnterCriticalSection
00E4CC2E 0F84 27000000 je 老虎YJK?00E4CC5B
...
00E4CC35 3B85 418C0E15 cmp eax,dword ptr ss:[ebp+0x150E8C41] ; ntdll.RtlLeaveCriticalSection
00E4CC3B 0F85 20000000 jnz 老虎YJK?00E4CC61
...
3:找GetIat1和FillCall1
因为现在是第二类,先处理GetIat1和FillCall1
这时在代码段下“设置内存写入断点”,断在
00E4D9AF 8938 mov dword ptr ds:[eax],edi ; ADSEC._HKSEC_RUN@4
此时,[eax]=0,寄存器eax是IAT地址,即当eip=00E4D9AF而且[eax]=0时,是写入iat
GetIat1=00E4D9AF,eip=00E4D9AF [eax]=0,edi是原OrigFuncAddr
*******
...
f9几次
00E4DFE4 AB stos dword ptr es:[edi]
此时,[edi]=90909090,寄存器edi是代码段地址,即当eip=00E4DFE4而且[edi]=90909090时,是填充code
ECX是OrigFuncAddr
stos dword ptr es:[edi]
执行后(sti),需要
mov [edi-4],eax
mov [esp],ecx
FillCall1=00E4DFE4,eip=00E4DFE4 [edi]=90909090
*********
4:对ebx表对应项下内存写入断点,找 BaseZero
00E4E15C 8919 mov dword ptr ds:[ecx],ebx
BaseZero=00E4E15C,寄存器ecx是ebx表地址
********
5:找GetIat2
取消所有断点,在kernel32.dll的esi表第一个dword下内存访问断点:地址00E3D957
F9运行
00E4A9CF AD lods dword ptr ds:[esi] //esi=00E3D957,esi表
再在代码段下内存写入断点,F9
00D9AE64 8F02 pop dword ptr ds:[edx] ; 03540000
此时,[edx]=0,[esp]是加密的func addr
GetIat2=00D9AE64 eip=00D9AE64 [edx]=0 ,这时把func addr写入[esp]替换即可
*******
再F9,来到
00D9AE64 8F02 pop dword ptr ds:[edx]
此时,[edx]=90909090,[esp]是加密的func addr
FillCall2=00D9AE64 eip=00D9AE64 [edx]=90909090 ,这时把func addr写入[esp]替换即可
*********
6:找GetApi1
取消所有断点
对esi表含0xbbbbbbbb的下内存访问断点,地址:00E3EDC3
F9,来到
00E4A9CF AD lods dword ptr ds:[esi] //ESI表带bbbbbbbb的第一个dword
F7,来到
00E4A9E0 BF 00000000 mov edi,0x0
00E4A9E5 897E FC mov dword ptr ds:[esi-0x4],edi //esi表第一个dword读完清0
...
00E4AA15 3D EEEEEEEE cmp eax,0xEEEEEEEE //比较是否一个大项结束
...
00E4ABA9 813E BBBBBBBB cmp dword ptr ds:[esi],0xBBBBBBBB //比较是否是0xbbbbbbbb
此时[esi]=0xbbbbbbbb
...
00E4ABCB C700 00000000 mov dword ptr ds:[eax],0x0 //清bbbbbbbb对应的dword
...
00E4AC4E FF33 push dword ptr ds:[ebx] ; OG70AS.Ordinal3998
取dllbase,[ebx]=[02F00028]=02FB0000 offset OG70AS.Ordinal3998
...
00E4AC60 81E9 FB7ACA6E sub ecx,0x6ECA7AFB
00E4AC66 F5 cmc //此时ecx是dllbase
...
00E4AD05 0385 951F0015 add eax,dword ptr ss:[ebp+0x15001F95]
00E4AD0B F9 stc
...
00E4AD62 2D B75DCF30 sub eax,0x30CF5DB7
00E4AD67 60 pushad
此时,寄存器:
EAX 03020B40 OG70AS.#5462
ECX 02FB0000 offset OG70AS.Ordinal3998
esp 0012FF04 OG70AS.#5462
执行到00E4AD67,eax=func addr , ecx=dll base
...
00E4E946 61 popad
00E4E947 0F85 12000000 jnz 老虎YJK?00E4E95F
执行到00E4E947,eax=func addr , ecx=dll base
00E4B546 50 push eax
00E4B547 8B3C24 mov edi,dword ptr ss:[esp] ; OG70AS.#5462
执行到00E4B547,eax=func addr , ecx=dll base ,[esp]是func addr
GetApi1=00E4B547
*******
7:
GetApi1=00E4B547 GetApi2=00E4B24A BaseZero=00E4E15C GetBase=00E4A086
GetIat1=00E4D9AF GetIat2=00D9AE64
FillCall1=00E4DFE4 FillCall2=00D9AE64
===============================
三:修复oep
脚本运行到伪OEP了,也就是说OEP已经被偷了代码了。这时候看下参考程序的OEP头代码:
006C4F9A 55 push ebp
006C4F9B 8BEC mov ebp,esp
006C4F9D 6A FF push -0x1
006C4F9F 68 000C7000 push 老虎YJK?00700C00 //第一个push
006C4FA4 68 144F6C00 push 老虎YJK?006c4f14 //第二个push push <jmp.&MSVCRT._except_handler3>
006C4FA9 64:A1 00000000 mov eax,dword ptr fs:[0]
006C4FAF 50 push eax
006C4FB0 64:8925 0000000>mov dword ptr fs:[0],esp
006C4FB7 83EC 68 sub esp,0x68
006C4FBA 53 push ebx
006C4FBB 56 push esi
006C4FBC 57 push edi
006C4FBD 8965 E8 mov dword ptr ss:[ebp-0x18],esp
006C4FC0 33DB xor ebx,ebx
006C4FC2 895D FC mov dword ptr ss:[ebp-0x4],ebx
006C4FC5 6A 02 push 0x2 《==脚本停在此处
看EBP寄存器,这个地址在堆栈窗中跟随:
0012FF34 0012FFE0 指向下一个 SEH 记录的指针
0012FF38 006C4F14 SE处理程序 //第二个push
0012FF3C 00700C00 老虎YJK?00700C00 //第一个push
0012FF40 00000000
0012FF44 00000000
=====================
四:自校验
00E4A806 83BD 350D0015 6>cmp dword ptr ss:[ebp+0x15000D35],0x64 //超过0x64后加自校验
00E4A80D 0F82 5E010000 jb 老虎YJK?00E4A971 //改成jmp
[00E4A80D],E95F01000090 //修改后代码,脚本用
-------------
五:E8、E9改成FF15、FF25的处理
00E4DE2B 0BDB or ebx,ebx
00E4DE2D 0F84 15000000 je 老虎YJK?00E4DE48 //ebx=0 跳,此时edi是代码段地址
...
00E4DE48 83F8 50 cmp eax,0x50 //eax<50则跳 ,估计eax记录的是api的index号
00E4DE4B 0F82 88000000 jb 老虎YJK?00E4DED9
...
00E4DE8E AA stos byte ptr es:[edi] //eax>50时填充90的地址,就是说90在E8E9前面
...
00E4DEB7 AA stos byte ptr es:[edi] //eax>50时填充E8E9
...
00E4DF58 8803 mov byte ptr ds:[ebx],al //eax<50时填充非90的数据在E8(E9) XXXXXXXX YY中的YY
...
00E4DEFA AA stos byte ptr es:[edi] //当eax<50时的填充e8、e9
00E4DEFB FC cld
...
00E4DEFD 807F FF E9 cmp byte ptr ds:[edi-0x1],0xE9 //e8 e9不同情况处理
00E4DF01 0F85 8A000000 jnz 老虎YJK?00E4DF91 //e8跳
====================
脚本:
start:
var GetApi1
var GetIat1
var FillCall1
var GetApi2
var GetIat2
var FillCall2
var BaseZero
var GetBase
var CodeStart
var CodeSize
var ModBase //模块基址
var FuncAddr //未加密api地址
var FillAddr //fill地址
var IatMin
var IatMax
var IatCur //api所属对应iat地址
var OrigFuncAddr //壳填在iat中的地址
var NewCallValue
mov GetApi1,00E4B547
mov GetIat1,00E4D9AF
mov FillCall1,00E4DFE4
mov GetApi2,00E4B24A
mov GetIat2,00D9AE64
mov FillCall2,00D9AE64
mov BaseZero,00E4E15C
mov GetBase,00E4A086
mov CodeStart,00401000
mov CodeSize,0088b000
mov IatMin,ffffffff
mov IatMax,0
mov nFuncCount,0
mov nIatCount,0
BPHWCALL //删除所有硬件断点
BPHWS GetBase,"x" //设置硬件执行断点
BPHWS BaseZero,"x" //设置硬件执行断点
run //F9 (或用ESTO=SHIFT-F9)
pause
mov [00E4A80D],#E95F01000090# //校验
MOV [00E4DE4B],#909090909090# //填充E8、E9前让它统一填充90
jmp func
//暂停在从ebx表取值
PauseAt_GetBase:
BPHWS GetApi2,"x"
BPHWS GetApi1,"x"
BPWM CodeStart,CodeSize //代码断设置内存写入断点
run
jmp func
//函数8 暂停在ebx表清0处
PauseAt_BaseZero:
//{
log "BaseZero"
cmp [ecx+4],0
JE FINDOEP
run
jmp func
//}
//函数1,获取0xbbbbbbbb api地址
PauseAt_GetApi1:
//{
//pause
mov FuncAddr,eax //eax=func addr , ecx=dll base
mov ModBase,ecx
run
jmp func
//}
//函数2,fill 非加密iat
PauseAt_GetIat1:
//{
//pause
mov IatCur,eax //00E4D9AF mov dword ptr ds:[eax],edi
mov OrigFuncAddr,edi
cmp OrigFuncAddr,FuncAddr
JE FillIat1_Next
mov edi,FuncAddr
FillIat1_Next:
run
jmp
//}
//函数3 fill非加密call or jmp
PauseAt_FillCall1:
//{
//pause
sti
mov FillAddr,edi //00E4DFE4 stos dword ptr es:[edi]
sub FillAddr,5
//当前指针 || ||
find FillAddr,#E8#,2 //90 E8 xx xx xx xx 或者 90 E9 xx xx xx
cmp $RESULT,0
sub FillAddr,1
je Fillcall1FF25 //不是E8则跳转到E9
mov [FillAddr],#ff15#
jmp FillCall1_next
Fillcall1FF25:
mov [FillAddr],#ff25#
FillCall1_next:
add FillAddr,2
mov [FillAddr],IatCur
run
jmp func
//函数4,获取非0xbbbbbb api地址,00E4B172
PauseAt_GetApi2:
//{
//pause
mov FuncAddr,eax //执行到此,eax=func-addr ecx=imagebase
mov ModBase,ecx
cmp FuncAddr,77D1A8AD
jne PauseAt_GetApi2_next
GO 00E4CAE2
pause //修改USER32.wsprintfA,修改标志位让它跳转。本程序对此api特别处理的
PauseAt_GetApi2_next:
run
jmp func
//}
//函数5,填充加密iat 00D9AE64
PauseAt_GetIat2:
//{
//pause
mov IatCur,edx //00D9AE64 pop dword ptr ds:[edx]
mov OrigFuncAddr,[esp]
mov [esp],FuncAddr
GetIat2_next:
jmp GetMinMaxIat
//}
//函数6,填充加密call
PauseAt_FillCall2:
//{
sti
mov FillAddr,edx //00D9AE64 pop dword ptr ds:[edx]
sub FillAddr,1
//当前指针 || ||
find FillAddr,#E8#,2 // E8 xx xx xx xx 90 或者 E9 xx xx xx xx 90
cmp $RESULT,0
je Fillcall2FF25 //不是E8则跳转到E9
mov [FillAddr],#ff15#
jmp Fillcall2_next
Fillcall2FF25:
mov [FillAddr],#ff25#
Fillcall2_next:
add FillAddr,2
mov [FillAddr],IatCur //改成FuncAddr对应的IAT地址
run
jmp func
//}
//函数7,获取最大,最小iat
GetMinMaxIat:
//{
cmp IatCur,IatMin
ja Next //如果IatCur>IatMin 则跳
mov IatMin,IatCur
Next:
cmp IatCur,IatMax
jb Finish //如果IatCur<IatMax 则跳
mov IatMax,IatCur
Finish:
run
jmp func
//}
//函数9,开始找oep
FINDOEP:
//{
BPHWCALL //清除所有硬件断点
bpmc //清除所有内存断点
BPRM CodeStart,CodeSize //代码断内存访问断点
run
log "FINDOEP"
log IatMin
log IatMax
bpmc //清除所有内存断点
//下面对本程序修补oep
//006C4F9A是真正oep地址
mov [006C4F9A],#558BEC6AFF68000C700068144F6C0064A100000000506489250000000083EC685356578965E833DB895DFC#
//本程序OEP修补完成
ret
//结束脚本
//}
//函数10,eip switch case
func:
//{
mov flag,0
cmp eip,GetApi1 //分支1, 停在GetApi1
JE PauseAt_GetApi1
cmp eip,GetIat1 //分支2 停在GetIat1
JNE func_next1
cmp [eax],0
JE PauseAt_GetIat1
jmp NotAll
func_next1:
cmp eip,FillCall1 //分支3 停在FillCall1
JNE func_next2
cmp [edi],90909090
JE PauseAt_FillCall1
jmp NotAll
func_next2:
cmp eip,GetApi2 // 分支4 停在GetApi2
je PauseAt_GetApi2
cmp eip, GetIat2
JNE func_next3
cmp [edx],0
JE PauseAt_GetIat2 //分支5 停在GetIat2
cmp [edx],90909090
JE PauseAt_FillCall2 //分支6 停在FillCall2
jmp NotAll
func_next3:
cmp eip,BaseZero //分支7,停在BaseZero
je PauseAt_BaseZero
cmp eip,GetBase //分支8,停在GetBase
je PauseAt_GetBase
NotAll:
run
jmp func
//}
|
评分
-
参与人数 34 | 威望 +1 |
HB +57 |
THX +20 |
收起
理由
|
猫妖的故事
| |
+ 1 |
|
|
lies
| |
+ 1 |
|
|
24567
| |
|
+ 1 |
|
Jawon
| |
+ 2 |
|
|
sjtkxy
| |
+ 1 |
+ 1 |
|
bnjzzheng
| |
+ 1 |
|
[吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩! |
Soul1999
| |
+ 1 |
|
|
消逝的过去
| |
|
+ 1 |
|
冷亦飞
| |
|
+ 1 |
|
l278785481
| |
+ 1 |
|
|
车太震
| |
+ 1 |
|
|
jaunic
| |
+ 2 |
|
|
liugu0hai
| |
+ 1 |
|
[吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少! |
汇编先行
| |
+ 1 |
|
|
ldljlzw
| |
+ 1 |
|
|
hnymsh
| |
+ 2 |
|
|
oawxx
| |
+ 1 |
+ 1 |
[快捷评语] - 评分=感恩!简单却充满爱!感谢您的作品! |
s1986q
| |
+ 1 |
+ 1 |
好人有好报!你的热心我永远不忘!谢谢! |
Jrack泽
| |
+ 1 |
+ 1 |
膜拜脱TMD |
fzx118
| |
+ 1 |
+ 1 |
好人有好报!你的热心我永远不忘!谢谢! |
ningzhonghui
| |
+ 2 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
Shark恒
| + 1 |
+ 10 |
+ 1 |
如果配有图片讲解的话。我相信会帮助更多的人,赞! |
Journey
| |
+ 1 |
|
★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!! |
哎呦呦
| |
+ 5 |
+ 1 |
★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!! |
逍遥枷锁
| |
+ 4 |
+ 1 |
好人有好报!你的热心我永远不忘!谢谢! |
860269996
| |
+ 1 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
kangda666
| |
+ 1 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
有何不可
| |
+ 2 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
虚竹
| |
+ 5 |
+ 1 |
★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!! |
怕怕吓一跳
| |
+ 2 |
|
★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!! |
我爱张海强
| |
+ 1 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
mjsz
| |
+ 1 |
+ 1 |
★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!! |
yuzhiboqianyuan
| |
+ 1 |
+ 1 |
评分=感恩!简单却充满爱!感谢您的作品! |
1322317605
| |
+ 1 |
+ 1 |
★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!! |
查看全部评分
|